/*
*  V2STRIP v0.2.10  Removes ID3v2 tags from MP3 files
*
*  Copyright (C) 2000 Mats Peterson
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
*  Please send any comments/bug reports to
*  [email protected]  (Mats Peterson)
*/


#include <config.h>
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#else
void free(void *ptr);
int strncmp(const char *s1, const char *s2, size_t n);
#endif
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#include <sys/types.h>
#else
int chown(const char *path, uid_t owner, gid_t group);
int chmod(const char *path, mode_t mode);
int mkstemp(char *template);
#endif
#include "v2hdr.h"


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

   if (stat(fname, &statbuf) < 0) {
       perror("stat");
       fprintf(stderr, "problem with file '%s'\n", fname);
       return;
   }

   if (! (in_f = fopen(fname, "rb"))) {
       perror("fopen");
       fprintf(stderr, "problem with file '%s'\n", fname);
       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, "File '%s' does not have any valid ID3v2 tag\n",
               fname);
       fclose(in_f);
       return;
   }

   tmpname = malloc(strlen(fname) + 30);

   if (tmpname) {
       int fd;
       strcpy(tmpname, fname);
       strcat(tmpname, "v2stripXXXXXX");
       fd = mkstemp(tmpname);
       if (fd < 0) {
           free(tmpname);
           tmpname = NULL;
       } else {
           if (! (tmp_f = fdopen(fd, "wb"))) {
               perror("fdopen");
               free(tmpname);
               fclose(in_f);
               return;
           }
       }
   }

   if (! tmpname) {
       fprintf(stderr, "Error: unable to generate temporary file name\n");
       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 (rename(tmpname, fname) < 0) {
       perror("rename");
       fprintf(stderr, "%s -> %s\n", tmpname, fname);
       goto error2;
   }

   free(tmpname);

   if (chown(fname, statbuf.st_uid, statbuf.st_gid) < 0) {
       perror("chown");
       fprintf(stderr, "problem with file '%s'\n", fname);
   }

   if (chmod(fname, statbuf.st_mode) < 0) {
       perror("chmod");
       fprintf(stderr, "problem with file '%s'\n", fname);
   }

   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(1);
}


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

   if (argc == 1)
       usage();

   for (i = 1; i < argc; i++)
       strip(argv[i]);

   exit(0);
}