/*
*  V2STRIP v0.2.7  Removes ID3v2 tags from MP3 files
*
*  Copyright (C) 2000 Mats Peterson
*
*  Please send any comments/bug reports to
*  [email protected]  (Mats Peterson)
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dir.h>

#include "v2hdr.h"

#define PACKAGE "v2strip"
#define VERSION "0.2.7"

#define BLKSIZE 4096



static void strip(char *fname)
{
   FILE *in_f, *tmp_f;
   static char buf[BLKSIZE];
   char *tmpname, *s;
   int n;
   long hdrsize;
   ID3V2HDR hdr;

   if (! (in_f = fopen(fname, "rb"))) {
               perror("fopen");
               return;
   }

   fread(&hdr, sizeof(ID3V2HDR), 1, in_f);
   if (strncmp(hdr.id_str, "ID3", 3) ||
           (hdr.version[0] == 0xff) || (hdr.version[1] == 0xff) ||
           (hdr.size[0] >= 0x80) || (hdr.size[1] >= 0x80) ||
           (hdr.size[2] >= 0x80) || (hdr.size[3] >= 0x80)) {
               fprintf(stderr, "Error: file '%s' does not have any valid ID3v2 tag\n",
                       fname);
               fclose(in_f);
               return;
   }

   for (s = fname + strlen(fname) - 1; (s >= fname) && (*s != '\\'); s--);
   if (s < fname)
               tmpname = tempnam(".", "v2str");
   else {  /* *s == '\\' */
               if (s == fname) {
               tmpname = tempnam("\\", "v2str");
               } else {
               *s = '\0';
               tmpname = tempnam(fname, "v2str");
               *s = '\\';
               }
   }

   if (! tmpname) {
               fprintf(stderr, "Error: unable to generate temporary file name\n");
               fclose(in_f);
               return;
   }

   if (! (tmp_f = fopen(tmpname, "wb"))) {
               perror("fopen");
               free(tmpname);
               fclose(in_f);
               return;
   }

   printf("Stripping %s... ", fname);
   fflush(stdout);

   hdrsize = ((long)hdr.size[3] |
           ((long)hdr.size[2] << (8 - 1)) |
           ((long)hdr.size[1] << (16 - 2)) |
           ((long)hdr.size[0] << (24 - 3))) + sizeof(ID3V2HDR);

#ifdef DEBUG
   printf("header size: %lX\n", hdrsize);
#endif

   fseek(in_f, hdrsize, SEEK_SET);

   while (1) {
               n = fread(buf, 1, BLKSIZE, in_f);
               if (ferror(in_f)) {
               fprintf(stderr, "Read error\n");
               goto error;
               }
               fwrite(buf, 1, n, tmp_f);
               if (ferror(tmp_f)) {
               fprintf(stderr, "Write error\n");
               goto error;
               }
               if (n < BLKSIZE)
               break;
   }

   fclose(in_f);
   fclose(tmp_f);

   if (remove(fname) == -1) {
               perror("remove");
               goto error2;
   }

   if (rename(tmpname, fname) == -1) {
               perror("rename");
               goto error2;
   }

   free(tmpname);
   printf("Done\n");
   return;

error:
   fclose(in_f);
   fclose(tmp_f);
error2:
   remove(tmpname);
   free(tmpname);
}


static void usage(void)
{
   fprintf(stderr, "%s v%s\n", PACKAGE, VERSION);
   fprintf(stderr, "usage: %s <file ...>\n", PACKAGE);
   exit(0);
}


int main(int argc, char **argv)
{
       struct ffblk ffblk;
   int i, done;

   if (argc == 1)
       usage();

   for (i = 1; i < argc; i++) {
               if (strpbrk(argv[i], "?*")) {
                       done = findfirst(argv[i], &ffblk, 0);
                       if (done) {
                               fprintf(stderr, "Can't find any file matching '%s'\n",
                                               argv[i]);
                               continue;
                       }
                       while (! done) {
                               strip(ffblk.ff_name);
                               done = findnext(&ffblk);
                       }
               } else
                       strip(argv[i]);
       }

   return 0;
}