/*
* 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);
}