id3ren-1.1b0/0042750000175000017500000000000007324203251011762 5ustar chrischrisid3ren-1.1b0/PORTS0100644000175000017500000000075107321313770012624 0ustar chrischris====== PORTS ====== - A BEOS port has been done by Shayne. See http://curvedspace.org/html/id3ren.html - Another BEOS port has been done by Scot Hacker See http://bebits.bebits.com/app/552 - A FreeBSD port has been done by Joao Carols Mendes Luis See http://www.geocrawler.com/archives/3/167/1999/2/0/540206/ You are welcome to port id3ren to any OS you like. Please let me know if you do. As id3ren only uses plain ANSI C, it should be rather straightforward. id3ren-1.1b0/Makefile0100644000175000017500000000020107251033166013420 0ustar chrischrisall: make -C src all debug: make -C src debug install: make -C src install make -C man install clean: make -C src clean id3ren-1.1b0/samples/0040755000175000017500000000000007324203251013431 5ustar chrischrisid3ren-1.1b0/samples/id3ren.rc0100640000175000017500000000031307015617406015141 0ustar chrischris########################################## # badcrc's id3ren config file # Win32 style ########################################## -edit -lower -remchar '`@%$^?! -space=_ -template=[$a]-[$s].mp3 id3ren-1.1b0/samples/id3renrc0100640000175000017500000000027307015617406015070 0ustar chrischris########################################## # arc's id3ren config file # Linux style ########################################## -quick -lower -remchar !'? -space=_ -template=[%a]-[%s].mp3 id3ren-1.1b0/src/0040755000175000017500000000000007324346556012574 5ustar chrischrisid3ren-1.1b0/src/id3misc.c0100640000175000017500000000547407322531627014267 0ustar chrischris/* id3 Renamer * id3misc.c - Miscellaneous functions for id3ren * Copyright (C) 1998 Robert Alto (badcrc@tscnet.com) * * 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. */ #include #include #include #include #include #include #include #include "id3file.h" #include "id3misc.h" #include "id3ren.h" extern FLAGS_struct flags; extern char *program_name; void alloc_string (char **dest, unsigned long size) { *dest = (char *)malloc(size); if (*dest == NULL) { print_error("alloc_string: Out of memory for malloc"); exit(ERRLEV_MALLOC); } } int strcase_search (char *in_s1, char *in_s2) { char *s1, *s2; int retflag = FALSE; s1 = (char *)malloc( (strlen(in_s1)+1) ); if (s1 == NULL) { print_error("strcase_search: Out of memory for malloc"); exit(ERRLEV_MALLOC); } s2 = (char *)malloc( (strlen(in_s2)+1) ); if (s2 == NULL) { free(s1); print_error("strcase_search: Out of memory for malloc"); exit(ERRLEV_MALLOC); } strcpy(s1, in_s1); strcpy(s2, in_s2); string_lower(s1); string_lower(s2); if (strstr(s1, s2) == NULL) retflag = FALSE; else retflag = TRUE; free(s1); free(s2); return retflag; } void string_lower (char *lowstr) { int i; for (i = 0; i < strlen(lowstr); i++) lowstr[i] = tolower(lowstr[i]); } int get_term_lines (void) { char *lines; lines = getenv("LINES"); if (lines == NULL || atoi(lines) < 1) return 25; return (int)atoi(lines); } void print_error (char *format, ...) { char buf[1024]; va_list msg; va_start(msg, format); vsprintf(buf, format, msg); va_end(msg); fprintf(stderr, "%s: %s: %s\n", program_name, buf, strerror(errno)); if (flags.logging == TRUE) { sprintf(buf, "%s: %s: %s\n", program_name, buf, strerror(errno)); add_to_log(buf); } } void user_message (int errflag, char *format, ...) { char buf[1024]; va_list msg; va_start(msg, format); vsprintf(buf, format, msg); va_end(msg); if (errflag) fprintf(stderr, "%s", buf); else if (flags.quiet == FALSE) printf("%s", buf); if (flags.logging == TRUE) add_to_log(buf); } id3ren-1.1b0/src/id3ren.c0100640000175000017500000006320507324155131014106 0ustar chrischris/* id3 Renamer * id3ren.c - Main functions * Copyright (C) 1998 Robert Alto (badcrc@tscnet.com) * Copyright (C) 2001 Christophe Bothamy (cbothamy@free.fr) * * 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. */ #include #include #include #include #include #include #include #include #include #include #ifdef __WIN32__ #include #endif #include "id3file.h" #include "id3misc.h" #include "id3tag.h" #include "id3ren.h" #define EXIT_PAUSE FALSE extern ID3_tag *ptrtag; extern const int genre_count; extern char *genre_table[]; extern const char logfile[]; char *def_artist = NULL; char *def_song = NULL; char *def_album = NULL; char *def_year = NULL; char *def_comment = NULL; int def_genre = -1; char def_track = -1; char *def_field = "unknown"; ID3_tag copytag; FILE *copyfp=NULL; FLAGS_struct flags = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0 }; /* * Default template * %a - artist * %c - comment * %g - genre * %s - song name * %t - album title * %y - year * %n - track * */ #ifdef __WIN32__ char filename_template[256] = "[$a]-[$s].mp3"; #else char filename_template[256] = "[%a]-[%s].mp3"; #endif #ifdef __WIN32__ char tag_template[256] = "[$a]-[$s].mp3"; #else char tag_template[256] = "[%a]-[%s].mp3"; #endif char *program_name = NULL; char *program_path = NULL; /* character to replace spaces with (defaults to " ") */ char replace_spacechar[32] = " "; char *replace_char = ""; char *remove_char = ""; /* template-applied filename */ char applied_filename[512]; void exit_function (void); void apply_template (char *); void show_usage (char *); void check_num_args (int, int); int read_config (char *, char *); void toggle_flag (short *); int check_option (int *, int , char *, char *, char *, char **, int ); void check_arg (int *, int, char *, char *); int check_args (int, char *[]); int main (int, char *[]); void exit_function (void) { if (EXIT_PAUSE) while(getc(stdin)!='\n') ; } void apply_template (char *origfile) { char *ptrNewfile; char tmpfile[512]; char strack[10]; int i, tcount = 0; applied_filename[0] = '\0'; ptrNewfile = applied_filename; while (filename_template[tcount] != '\0') { if (filename_template[tcount] == IDENT_CHAR) { tcount++; switch (filename_template[tcount]) { case 'a': if(strcmp(ptrtag->artist,"")!=0) strcat(applied_filename, ptrtag->artist); else if(def_field!=NULL) strcat(applied_filename, def_field); break; case 'c': if(strcmp(ptrtag->u.v10.comment,"")!=0) strcat(applied_filename, ptrtag->u.v10.comment); else if(def_field!=NULL) strcat(applied_filename, def_field); break; case 'g': if (ptrtag->genre < genre_count && ptrtag->genre >= 0) strcat(applied_filename, genre_table[ptrtag->genre]); else if(def_field!=NULL) strcat(applied_filename, def_field); break; case 's': if(strcmp(ptrtag->songname,"")!=0) strcat(applied_filename, ptrtag->songname); else if(def_field!=NULL) strcat(applied_filename, def_field); break; case 't': if(strcmp(ptrtag->album,"")!=0) strcat(applied_filename, ptrtag->album); else if(def_field!=NULL) strcat(applied_filename, def_field); break; case 'y': if(strcmp(ptrtag->year,"")!=0) strcat(applied_filename, ptrtag->year); else if(def_field!=NULL) strcat(applied_filename, def_field); break; case 'n': if (ptrtag->version >=1) {sprintf(strack,"%02d",ptrtag->u.v11.track); strcat(applied_filename, strack); } else if(def_field!=NULL) strcat(applied_filename, def_field); break; default: user_message(FALSE, "Unknown identifier in template: %c%c\n", IDENT_CHAR, filename_template[tcount]); break; } tcount++; } else { ptrNewfile = applied_filename; ptrNewfile += strlen(applied_filename); *ptrNewfile = filename_template[tcount]; ptrNewfile++; *ptrNewfile = '\0'; tcount++; } } strcpy(tmpfile, applied_filename); ptrNewfile = applied_filename; tcount = 0; while (tmpfile[tcount] != '\0') { for (i = 0; i < strlen(replace_char); i += 2) { if ( replace_char[i] == tmpfile[tcount] && ((i+1) < strlen(replace_char)) ) { *ptrNewfile = replace_char[i+1]; ptrNewfile++; i = 31335; } } if (i != 31337 && strchr(remove_char, tmpfile[tcount]) == NULL) { if (isalpha(tmpfile[tcount]) && flags.ulcase == 1) { *ptrNewfile = toupper(tmpfile[tcount]); ptrNewfile++; } else if (isalpha(tmpfile[tcount]) && flags.ulcase == 2) { *ptrNewfile = tolower(tmpfile[tcount]); ptrNewfile++; } else if (tmpfile[tcount] == ' ') { *ptrNewfile = '\0'; strcat(applied_filename, replace_spacechar); ptrNewfile = applied_filename; ptrNewfile += strlen(applied_filename); } else { *ptrNewfile = tmpfile[tcount]; ptrNewfile++; } } tcount++; } *ptrNewfile = '\0'; /* Convert illegal or bad filename characters to good characters */ for (i=0; i < strlen(applied_filename); i++) { switch (applied_filename[i]) { case '<': applied_filename[i] = '['; break; case '>': applied_filename[i] = ']'; break; case '|': applied_filename[i] = '_'; break; // this is now used to create dirs //case '/': applied_filename[i] = '-'; break; case '\\': applied_filename[i]= '-'; break; case '*': applied_filename[i] = '_'; break; case '?': applied_filename[i] = '_'; break; case ':': applied_filename[i] = ';'; break; case '"': applied_filename[i] = '-'; break; default: break; } } } void show_usage (char *myname) { user_message(TRUE, "GPL'd id3 Renamer & Tagger version %s\n", APP_VERSION); user_message(TRUE, "(C) Copyright 1998 by Robert Alto (badcrc@tscnet.com)\n"); user_message(TRUE, "(C) Copyright 2001 by Christophe Bothamy (cbothamy@free.fr)\n"); user_message(TRUE, "Usage: %s [-help]\n",myname); user_message(TRUE, " [-song=SONG_NAME] [-artist=ARTIST_NAME] [-album=ALBUM_NAME]\n"); user_message(TRUE, " [-year=YEAR] [-genre={# | GENRE}] [-comment=COMMENT] [-track=TRACK]\n"); user_message(TRUE, " [-showgen] [-searchgen={# | GENRE}] [-default=DEFAULT]\n"); user_message(TRUE, " [-copytagfrom=FILE [-copysong] [-copyartist] [-copyalbum]\n"); user_message(TRUE, " [-copyyear] [-copygenre] [-copycomment] [-copytrack] [-copyall] ]\n"); user_message(TRUE, " [-quick] [-noalbum] [-nocomment] [-noyear] [-nogenre] [-notrack]\n"); user_message(TRUE, " [-tag] [-edit] [-notagprompt | -showtag | -striptag | -tagonly]\n"); user_message(TRUE, " [-nocfg] [-log] [-quiet] [-verbose] [-defcase | -lower | -upper]\n"); user_message(TRUE, " [-remchar=CHARS] [-repchar=CHARS] [-space=STRING]\n"); user_message(TRUE, " [-tagfromfilename | -tagffn] [-tagtemplate=TAGTEMPLATE]\n"); user_message(TRUE, " [-template=TEMPLATE] [FILE1 FILE2.. | WILDCARDS]\n\n"); user_message(TRUE, "When logging is enabled, most normal output is also sent to %s.\n", logfile); user_message(TRUE, "To disable all output except for the usage screen on errors, use -quiet.\n\n"); user_message(TRUE, "The templates can contain the following identifiers from the id3 tag:\n"); user_message(TRUE, " %ca - Artist %cc - Comment %cg - Genre %cs - Song Name\n",IDENT_CHAR, IDENT_CHAR, IDENT_CHAR, IDENT_CHAR); user_message(TRUE, " %ct - Album title %cy - Year %cn - Track ##\n",IDENT_CHAR,IDENT_CHAR,IDENT_CHAR); user_message(TRUE, "The tagtemplate can also contain the dummy identifier %cd.\n",IDENT_CHAR); } void check_num_args (int current, int total) { if (current >= total) { user_message(TRUE, "%s: Not enough arguments\n", program_name); exit(ERRLEV_ARGS); } } int read_config (char *path, char *filename) { FILE *fp; char buffer[1024]; char *cfile; char *p1, *p2; int i; char first[1024]; char second[1024]; char insingle,indouble; if (path == NULL || strlen(path) < 1) return FALSE; if (filename == NULL || strlen(filename) < 1) { alloc_string(&cfile, (strlen(path) + 1)); strcpy(cfile, path); } else { alloc_string(&cfile, (strlen(path) + strlen(filename) + 2)); sprintf(cfile, "%s%c%s", path, PATH_CHAR, filename); } if (flags.verbose) user_message(FALSE, "%s: Checking for config file %s...", program_name, cfile); if (access(cfile, F_OK) != 0) { if (flags.verbose) user_message(FALSE, "not found\n"); free(cfile); return FALSE; } else if (flags.verbose) user_message(FALSE, "found\n"); fp = fopen(cfile, "rt"); if (fp == NULL) { print_error("Couldn't open config file %s", cfile); free(cfile); return FALSE; } if (flags.verbose) user_message(FALSE, "%s: Reading config file %s\n", program_name, cfile); fgets(buffer, sizeof(buffer), fp); while (!feof(fp)) { if (buffer[strlen(buffer)-1] == '\n') buffer[strlen(buffer)-1] = '\0'; p1 = buffer; while (*p1 == ' ') p1++; if (*p1 != '\0' && *p1 != '#') { p2 = p1; while (*p2 != '=' && *p2 != ' ' && *p2 != '\0') p2++; if (*p2 == ' ' || *p2 == '=') { *p2 = '\0'; p2++; } // Go to next non space while (*p2 == ' ' && *p2 != '\0') p2++; // Handle double and simple quotes strcpy(first,p1); strcpy(second,""); insingle=0;indouble=0; while(*p2!='\0') { if(insingle) {if(*p2=='\'')insingle=0; else strncat(second,p2,1); } else if(indouble) {if(*p2=='"')indouble=0; else strncat(second,p2,1); } else if(*p2=='"')indouble=1; else if(*p2=='\'')insingle=1; else if(*p2!=' ')strncat(second,p2,1); else break; p2++; } i = 0; check_arg (&i, ((second[0] == '\0') ? 1 : 2), first, ((second[0] == '\0') ? "" : second)); } fgets(buffer, sizeof(buffer), fp); } fclose(fp); free(cfile); return TRUE; } void toggle_flag (short *flag) { if (*flag == TRUE) { *flag = FALSE; } else { *flag = TRUE; } } int check_option (int *count, int argc, char *arg1, char *arg2, char *name, char **option, int nb) {char *stmp; char found=0; *option=NULL; // Single option if(nb==0) { if(strcmp(name,arg1)==0) found=1; } else // Option with param { // Option with next arg if(strcmp(name,arg1)==0) { (*count)++; check_num_args(*count, argc); *option=arg2; found=1; } else {// option with = alloc_string(&stmp, (strlen(name)+2)); sprintf(stmp,"%s=",name); if(strncmp(stmp,arg1,strlen(stmp))==0) {// Option begins next char *option=strchr(arg1,'=')+1; found=1; } free(stmp); } } if(found)return 1; else return 0; } void check_arg (int *count, int argc, char *arg1, char *arg2) { char *option; int i; if(check_option(count,argc,arg1,arg2,"-help",&option,0)!=0) { show_usage(program_name); exit(ERRLEV_SUCCESS); } else if(check_option(count,argc,arg1,arg2,"-song",&option,1)!=0) { alloc_string(&def_song, (strlen(option)+1)); strcpy(def_song, option); } else if(check_option(count,argc,arg1,arg2,"-artist",&option,1)!=0) { alloc_string(&def_artist, (strlen(option)+1)); strcpy(def_artist, option); } else if(check_option(count,argc,arg1,arg2,"-album",&option,1)!=0) { alloc_string(&def_album, (strlen(option)+1)); strcpy(def_album, option); } else if(check_option(count,argc,arg1,arg2,"-year",&option,1)!=0) { alloc_string(&def_year, (strlen(option)+1)); strcpy(def_year, option); } else if(check_option(count,argc,arg1,arg2,"-track",&option,1)!=0) { def_track=0; for(i=0;i99) { user_message(TRUE, "%s: track %s is > 99\n", program_name,option); exit(ERRLEV_ARGS); } } else if(check_option(count,argc,arg1,arg2,"-comment",&option,1)!=0) { alloc_string(&def_comment, (strlen(option)+1)); strcpy(def_comment, option); } else if(check_option(count,argc,arg1,arg2,"-genre",&option,1)!=0) { if (search_genre(1, &def_genre, option) == FALSE) { user_message(TRUE, "%s: No genre selected\n", program_name); exit(ERRLEV_ARGS); } } else if(check_option(count,argc,arg1,arg2,"-default",&option,1)!=0) { alloc_string(&def_field, (strlen(option)+1)); strcpy(def_field, option); } else if(check_option(count,argc,arg1,arg2,"-log",&option,0)!=0) toggle_flag((short*)&flags.logging); else if(check_option(count,argc,arg1,arg2,"-notagprompt",&option,0)!=0) toggle_flag((short*)&flags.no_tag_prompt); else if(check_option(count,argc,arg1,arg2,"-noalbum",&option,0)!=0) toggle_flag((short*)&flags.no_album); else if(check_option(count,argc,arg1,arg2,"-nocomment",&option,0)!=0) toggle_flag((short*)&flags.no_comment); else if(check_option(count,argc,arg1,arg2,"-noyear",&option,0)!=0) toggle_flag((short*)&flags.no_year); else if(check_option(count,argc,arg1,arg2,"-notrack",&option,0)!=0) toggle_flag((short*)&flags.no_track); else if(check_option(count,argc,arg1,arg2,"-nogenre",&option,0)!=0) toggle_flag((short*)&flags.no_genre); else if(check_option(count,argc,arg1,arg2,"-nocfg",&option,0)!=0) toggle_flag((short*)&flags.no_config); else if(check_option(count,argc,arg1,arg2,"-quick",&option,0)!=0) { flags.no_album = TRUE; flags.no_comment = TRUE; flags.no_year = TRUE; } else if(check_option(count,argc,arg1,arg2,"-quiet",&option,0)!=0) toggle_flag((short*)&flags.quiet); else if(check_option(count,argc,arg1,arg2,"-verbose",&option,0)!=0) toggle_flag((short*)&flags.verbose); else if(check_option(count,argc,arg1,arg2,"-searchgen",&option,1)!=0) { search_genre(2, &def_genre, option); exit(ERRLEV_SUCCESS); } else if(check_option(count,argc,arg1,arg2,"-showgen",&option,0)!=0) { show_genres(FALSE); exit(ERRLEV_SUCCESS); } else if(check_option(count,argc,arg1,arg2,"-showtag",&option,0)!=0) { flags.show_tag = TRUE; flags.no_tag_prompt = TRUE; } else if(check_option(count,argc,arg1,arg2,"-striptag",&option,0)!=0) toggle_flag((short*)&flags.strip_tag); else if(check_option(count,argc,arg1,arg2,"-tag",&option,0)!=0) toggle_flag((short*)&flags.force_tag); else if(check_option(count,argc,arg1,arg2,"-tagonly",&option,0)!=0) toggle_flag((short*)&flags.tag_only); else if(check_option(count,argc,arg1,arg2,"-tagfromfilename",&option,0)!=0) toggle_flag((short*)&flags.tag_ffn); else if(check_option(count,argc,arg1,arg2,"-tagffn",&option,0)!=0) toggle_flag((short*)&flags.tag_ffn); else if(check_option(count,argc,arg1,arg2,"-edit",&option,0)!=0) toggle_flag((short*)&flags.edit_tag); else if(check_option(count,argc,arg1,arg2,"-defcase",&option,0)!=0) flags.ulcase = 0; else if(check_option(count,argc,arg1,arg2,"-upper",&option,0)!=0) flags.ulcase = 1; else if(check_option(count,argc,arg1,arg2,"-lower",&option,0)!=0) flags.ulcase = 2; else if(check_option(count,argc,arg1,arg2,"-space",&option,1)!=0) { if (option == NULL) strcpy(replace_spacechar, ""); else strncpy(replace_spacechar, option, (sizeof(replace_spacechar)-1)); } else if(check_option(count,argc,arg1,arg2,"-remchar",&option,1)!=0) { alloc_string(&remove_char, (strlen(option)+1)); strcpy(remove_char, option); } else if(check_option(count,argc,arg1,arg2,"-repchar",&option,1)!=0) { if ( (strlen(option) % 2) != 0 ) { user_message(TRUE, "%s: Replace characters must be in pairs\n", program_name); exit(ERRLEV_ARGS); } alloc_string(&replace_char, (strlen(option)+1)); strcpy(replace_char, option); } else if(check_option(count,argc,arg1,arg2,"-template",&option,1)!=0) { if (option == NULL) { user_message(TRUE, "%s: Empty template specified (%s)\n", program_name, arg1); exit(ERRLEV_ARGS); } else strncpy(filename_template, option, (sizeof(filename_template)-1)); } else if(check_option(count,argc,arg1,arg2,"-tagtemplate",&option,1)!=0) { if (option == NULL) { user_message(TRUE, "%s: Empty tagtemplate specified (%s)\n", program_name, arg1); exit(ERRLEV_ARGS); } else strncpy(tag_template, option, (sizeof(tag_template)-1)); } else if(check_option(count,argc,arg1,arg2,"-copytagfrom",&option,1)!=0) { if (option == NULL) { user_message(TRUE, "%s: Empty file name to copy from specified (%s)\n", program_name, arg1); exit(ERRLEV_ARGS); } else { if(id3_open_file(©fp,option,"rb")==FALSE) { user_message(TRUE, "%s: Can not copy from file (%s)\n", program_name, arg1); exit(ERRLEV_ARGS); } memset(©tag,0,sizeof(ID3_tag)); if(id3_seek_header(copyfp, option) != FALSE) id3_read_file(copytag.tag, (sizeof(copytag.tag)-1), copyfp, option); if (strcmp(copytag.tag, "TAG") != 0) { user_message(TRUE, "%s: Can not find any tag in file (%s)\n", program_name, arg1); id3_close_file(copyfp); exit(ERRLEV_ARGS); } id3_read_tag(©tag,copyfp,option); id3_close_file(copyfp); } } else if(check_option(count,argc,arg1,arg2,"-copysong",&option,0)!=0) { if(copyfp==NULL) {user_message(TRUE, "%s: No copytagfrom file specified\n", program_name); exit(ERRLEV_ARGS); } alloc_string(&def_song, strlen(copytag.songname)+1); strcpy(def_song, copytag.songname); } else if(check_option(count,argc,arg1,arg2,"-copyartist",&option,0)!=0) { if(copyfp==NULL) {user_message(TRUE, "%s: No copytagfrom file specified\n", program_name); exit(ERRLEV_ARGS); } alloc_string(&def_artist, (strlen(copytag.artist)+1)); strcpy(def_artist, copytag.artist); } else if(check_option(count,argc,arg1,arg2,"-copyalbum",&option,0)!=0) { if(copyfp==NULL) {user_message(TRUE, "%s: No copytagfrom file specified\n", program_name); exit(ERRLEV_ARGS); } alloc_string(&def_album, (strlen(copytag.album)+1)); strcpy(def_album, copytag.album); } else if(check_option(count,argc,arg1,arg2,"-copyyear",&option,0)!=0) { if(copyfp==NULL) {user_message(TRUE, "%s: No copytagfrom file specified\n", program_name); exit(ERRLEV_ARGS); } alloc_string(&def_year, (strlen(copytag.year)+1)); strcpy(def_year, copytag.year); } else if(check_option(count,argc,arg1,arg2,"-copytrack",&option,0)!=0) { if(copyfp==NULL) {user_message(TRUE, "%s: No copytagfrom file specified\n", program_name); exit(ERRLEV_ARGS); } if(copytag.version==0) {user_message(TRUE, "%s: Copied tag is not id3v1.1\n", program_name); exit(ERRLEV_ARGS); } def_track=copytag.u.v11.track; } else if(check_option(count,argc,arg1,arg2,"-copycomment",&option,0)!=0) { if(copyfp==NULL) {user_message(TRUE, "%s: No copytagfrom file specified\n", program_name); exit(ERRLEV_ARGS); } alloc_string(&def_comment, (strlen(copytag.u.v10.comment)+1)); strcpy(def_comment, copytag.u.v10.comment); } else if(check_option(count,argc,arg1,arg2,"-copygenre",&option,0)!=0) { if(copyfp==NULL) {user_message(TRUE, "%s: No copytagfrom file specified\n", program_name); exit(ERRLEV_ARGS); } def_genre=copytag.genre; } else if(check_option(count,argc,arg1,arg2,"-copyall",&option,0)!=0) { if(copyfp==NULL) {user_message(TRUE, "%s: No copytagfrom file specified\n", program_name); exit(ERRLEV_ARGS); } alloc_string(&def_song, strlen(copytag.songname)+1); strcpy(def_song, copytag.songname); alloc_string(&def_artist, (strlen(copytag.artist)+1)); strcpy(def_artist, copytag.artist); alloc_string(&def_album, (strlen(copytag.album)+1)); strcpy(def_album, copytag.album); alloc_string(&def_year, (strlen(copytag.year)+1)); strcpy(def_year, copytag.year); if(copytag.version>0)def_track=copytag.u.v11.track; alloc_string(&def_comment, (strlen(copytag.u.v10.comment)+1)); strcpy(def_comment, copytag.u.v10.comment); def_genre=copytag.genre; } else { user_message(TRUE, "%s: Unknown option: %s\n", program_name, arg1); exit(ERRLEV_ARGS); } } int check_args (int argc, char *argv[]) { int i; for (i = 1; i < argc && argv[i][0] == '-'; i++) { check_arg (&i, argc, argv[i], (((i+1) < argc) ? argv[i+1] : "")); } if (flags.no_config == FALSE) { if (!read_config(getenv("ID3REN"), "")) if (!read_config(getenv("HOME"), CONFIG_HOME)) #ifdef __WIN32__ read_config(program_path, CONFIG_GLOBAL); #else read_config("/etc", CONFIG_GLOBAL); #endif } return i; } int main (int argc, char *argv[]) { char arg[256]; char *p; int i; int count = 0; int errcount = 0; char tempname[512],*d,*s; int okflag; #ifdef WIN32_FIND WIN32_FIND_DATA *lpwfd; HANDLE hSearch; #endif atexit(exit_function); p = strrchr(argv[0], PATH_CHAR); if (p == NULL) { p = argv[0]; alloc_string(&program_path, 2); strcpy(program_path, "."); } else { p++; alloc_string(&program_path, (strlen(argv[0]) - strlen(p))); strncpy(program_path, argv[0], ((strlen(argv[0]) - strlen(p)) - 1)); } alloc_string(&program_name, (strlen(p)+1)); strcpy(program_name, p); if (argc <= 1) { show_usage(argv[0]); return ERRLEV_ARGS; } if ( (ptrtag = (ID3_tag*)malloc(sizeof(*ptrtag)) ) == NULL) { print_error("Out of memory for malloc"); exit(ERRLEV_MALLOC); } #ifdef WIN32_FIND if ( (lpwfd = (WIN32_FIND_DATA*)malloc(sizeof(*lpwfd)) ) == NULL) { print_error("Out of memory for malloc"); exit(ERRLEV_MALLOC); } #endif i = check_args (argc, argv); if (i >= argc) { user_message(TRUE, "%s: Not enough arguments specified\n", program_name); exit(ERRLEV_ARGS); } for (; i < argc; i++) { count++; #ifdef WIN32_FIND hSearch = FindFirstFile(argv[i], lpwfd); if (hSearch != INVALID_HANDLE_VALUE) { do { strncpy(arg, lpwfd->cFileName, (sizeof(arg)-1)); if (tag_file(arg)) { #else strncpy(arg, argv[i], (sizeof(arg)-1)); if (access(arg, F_OK) != 0) { user_message(TRUE, "%s: File not found: %s\n", program_name, arg); } else if (tag_file(arg)) { #endif if (flags.show_tag) { id3_show_tag(ptrtag, arg); } else if (!flags.tag_only && !flags.strip_tag) { apply_template(arg); if (access(applied_filename, F_OK) == 0) { user_message(TRUE, "%s: File already exists: %s\n", program_name, applied_filename); } else { // We create the dirs if needed. okflag=1; strcpy(tempname,applied_filename); s=tempname; while(okflag==1) { d=strchr(s,PATH_CHAR); if(d==NULL)break; // Set to 0 *d=0; if(strcmp(tempname,"")!=0) if(mkdir(tempname,0777)!=0) { if(errno!=EEXIST) { print_error("Create dir failed on %s", tempname); okflag=0; } } // Reset to what it was *d=PATH_CHAR; s=d+1; } if(okflag==1) { if (rename(arg, applied_filename) == 0) user_message(FALSE, "%-38s => %-37s\n", arg, applied_filename); else print_error("Rename failed on %s", arg); } else { count--; errcount++; } } } } else { count--; errcount++; } #ifdef WIN32_FIND } while (FindNextFile(hSearch, lpwfd)); /* End do */ } /* end of FindFirstFile */ else { user_message(TRUE, "%s: File not found: %s\n", program_name, argv[i]); } #endif } /* end for loop */ user_message(FALSE, "Processed: %d Failed: %d Total: %d\n", count, errcount, count+errcount); return ERRLEV_SUCCESS; } /* end main */ id3ren-1.1b0/src/id3ren.h0100640000175000017500000000456007311773275014125 0ustar chrischris/* id3 Renamer * id3ren.h - Header for main functions * Copyright (C) 1998 Robert Alto (badcrc@tscnet.com) * Copyright (C) 2001 Christophe Bothamy (cbothamy@free.fr) * * 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. */ #ifndef __ID3REN_H__ #define __ID3REN_H__ #define SHORTVERSION "1.1b0" #ifdef __WIN32__ #define APP_VERSION SHORTVERSION" for Win32" #define IDENT_CHAR '$' #define PATH_CHAR '\\' #define CONFIG_HOME "id3ren.rc" #define CONFIG_GLOBAL "id3ren.rc" #else #define APP_VERSION SHORTVERSION" for *nix" #define IDENT_CHAR '%' #define PATH_CHAR '/' #define CONFIG_HOME ".id3renrc" #define CONFIG_GLOBAL "id3renrc" #endif #undef WIN32_FIND #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define ERRLEV_SUCCESS (0) #define ERRLEV_MALLOC (1) #define ERRLEV_ARGS (2) #define ERRLEV_OTHER (3) typedef struct { /* Log normal output to a file */ short logging; /* Don't prompt for tags on files without tags */ short no_tag_prompt; /* Don't read config files */ short no_config; /* Run silently */ short quiet; /* Show lots of stuff */ short verbose; /* Only display tags */ short show_tag; /* Tag from file name */ short tag_ffn; /* Strip tag */ short strip_tag; /* Always prompt for tag info, even when renaming files with tags */ short force_tag; /* Don't do any renaming, only prompt for tags */ short tag_only; /* If a tag field already has info, don't prompt for that */ short edit_tag; /* Skip asking for these tag items? */ short no_year; short no_album; short no_comment; short no_genre; short no_track; /* 0-default 1-upper 2-lower */ short ulcase; } FLAGS_struct; #endif /* __ID3REN_H__ */ id3ren-1.1b0/src/id3tag.c0100640000175000017500000003476407322535555014117 0ustar chrischris/* id3 Renamer * id3tag.c - id3 tag manipulation functions * Copyright (C) 1998 Robert Alto (badcrc@tscnet.com) * Copyright (C) 2001 Christophe Bothamy (cbothamy@free.fr) * * 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. */ #include #include #include #include #include "id3file.h" #include "id3misc.h" #include "id3ren.h" #include "id3tag.h" #define MIN(a,b) ((a)<(b))?(a):(b) extern FLAGS_struct flags; extern char *program_name; extern char tag_template[256]; extern char *def_artist; extern char *def_song; extern char *def_album; extern char *def_year; extern char *def_comment; extern int def_genre; extern char def_track; extern const int genre_count; extern char *genre_table[]; ID3_tag *ptrtag = NULL; void show_genres (int pause_flag) { int i, count, lines; for (i=0, count=1, lines=1; i= 4) { printf("\n"); count = 0; lines++; if (lines >= (get_term_lines()-1)) { if (pause_flag) { printf("-MORE- Press ENTER"); if (getc(stdin) != '\n') while (getc(stdin) != '\n'); lines = 0; } } } } if (count > 1) printf("\n"); } /* flag_search_only: * 0 - Display & prompt for genres, exact match returns TRUE * 1 - Prompt, exact match returns TRUE * 2 - No prompt, show only sub string matches */ int search_genre (int flag_search_only, int *dest, char *search_gen) { int i; int digit; int substring_matches; char c = 'z'; i = 0; while (i < strlen(search_gen) && isdigit(search_gen[i])) i++; if (i >= strlen(search_gen)) { digit = (atoi(search_gen) - 1); if (digit >= 0 && digit < genre_count) { if (flag_search_only == 2) user_message(FALSE, "%s\n", genre_table[digit]); *dest = digit; return TRUE; } user_message(TRUE, "%s: search_genre: Invalid genre type: %d\n", program_name, digit); *dest = -1; return FALSE; } substring_matches = 0; for (i = 0; i < genre_count; i++) { if (flag_search_only != 2 && strcasecmp(search_gen, genre_table[i]) == 0) { *dest = i; if (flag_search_only == 0 && flags.verbose) printf("Found exact genre match [%s]\n", genre_table[i]); return TRUE; } /* keep track of substring matches for later */ if (strcase_search(genre_table[i], search_gen)) { substring_matches++; if (flag_search_only == 0 && flags.verbose) printf("Found matching genre [%s]\n", genre_table[i]); if (flag_search_only == 2) printf("%3d: %s\n", substring_matches, genre_table[i]); } } if (substring_matches == 0) { user_message(FALSE, "Genre not found: %s\n", search_gen); *dest = -1; return FALSE; } if (flag_search_only == 2) return TRUE; /* HMMMM....didn't find an exact match, now search for sub strings */ for (i = 0; i < genre_count && c != 'q'; i++) { if (strcase_search(genre_table[i], search_gen)) { if (substring_matches == 1) { *dest = i; return TRUE; } do { printf("[%s] use this genre? (Y/n/q) ", genre_table[i]); c = tolower(getchar()); if (c == '\n') { c = 'y'; } else { while (getchar() != '\n') ; } } while (c != 'n' && c != 'y' && c != 'q'); if (c == 'y') { *dest = i; return TRUE; } } } if (flag_search_only == 0) user_message(FALSE, "No genre selected...tough choice isn't it?\n"); *dest = -1; return FALSE; } void resize_tag_field (char *field) { int i; i = strlen(field); while (field[i-1] == ' ') i--; field[i] = '\0'; } int get_tag_genre (int *genre, int def_genre) { char buffer[64]; char c; int flag_got_genre = FALSE; if (def_genre >= 0 && def_genre < genre_count) { *genre = def_genre; printf("Genre of music: %s\n", genre_table[*genre]); return TRUE; } if (flags.edit_tag && *genre >= 0 && *genre < genre_count) { printf("Genre of music: %s\n", genre_table[*genre]); return TRUE; } do { printf("Genre of music (blank to cancel, 'l' to list): "); fgets(buffer, sizeof(buffer), stdin); if (buffer[strlen(buffer)-1] == '\n') { buffer[strlen(buffer)-1] = '\0'; } else { while (getc(stdin) != '\n'); } if (tolower(buffer[0]) == 'l') show_genres(TRUE); else if (strlen(buffer) < 1) flag_got_genre = TRUE; else if (search_genre(FALSE, &(*genre), buffer) == TRUE) flag_got_genre = TRUE; else { do { printf("Would you like to see a list? (Y/n) "); c = tolower(getchar()); } while (c != 'n' && c != 'y' && c != '\n'); if (c == '\n') c = 'y'; else while (getchar() != '\n') ; if (c == 'y') show_genres(TRUE); } } while (flag_got_genre == FALSE); if (*genre != -1) printf("\"%s\" selected.\n", genre_table[*genre]); return TRUE; } int get_tag_track (char *track, char def_track, char *version) { char buffer[64]; char tracktmp; int i; *version=0; if (def_track >= 0 && def_track<=99) { *track = def_track; printf("Track: %02d\n", *track); *version=1; return TRUE; } if (flags.edit_tag && *track >= 0 && *track <=99) { printf("Track: %02d\n", *track); *version=1; return TRUE; } do { printf("Track (1 to 99, blank for none): "); fgets(buffer, sizeof(buffer), stdin); if (buffer[strlen(buffer)-1] == '\n') { buffer[strlen(buffer)-1] = '\0'; } else { while (getc(stdin) != '\n'); } if(strcmp(buffer,"")==0) return TRUE; else { tracktmp=0; for(i=0;i'9')) {tracktmp=0; break; } else tracktmp=tracktmp*10+buffer[i]-'0'; } } if((tracktmp>0)&&(tracktmp<100)) {*track=tracktmp; *version=1; } else {tracktmp=0; } } while (tracktmp==0); return TRUE; } int get_tag_string (int size, char *def_string, char *string, char *desc) { printf("%s (%d chars): ", desc, (size-1)); if (def_string != NULL && strlen(def_string) > 0) { strcpy(string, def_string); printf("%s\n", string); return TRUE; } if (flags.edit_tag && string != NULL && strlen(string) > 0) { printf("%s\n", string); return TRUE; } fgets(string, size, stdin); if (string[strlen(string)-1] == '\n') string[strlen(string)-1] = '\0'; else while (getc(stdin) != '\n'); return TRUE; } int ask_tag (char *fn) { ID3_tag fntag; char track[20],genre[20],*t,*w,*p,*f,*pfntmp,*ptagtmp; char tagtmp[256],fntmp[256]; int length; /* If tag from file name, we grab the fields */ memset(&fntag,0,sizeof(ID3_tag)); if (flags.tag_ffn == TRUE) { strcpy(tagtmp,tag_template);p=ptagtmp=tagtmp; strcpy(fntmp,fn);pfntmp=fntmp; w=NULL; while(p!=NULL) { p=strchr(ptagtmp,IDENT_CHAR); /* if it's the last char */ if(p!=NULL) { *p=0; if(*(p+1)==0)break; } f=strstr(pfntmp,ptagtmp); if(f==NULL)break; if(w!=NULL) { switch(*w) { case 'a' : /* artist */ length=MIN(f-pfntmp,sizeof(fntag.artist)); strncpy(fntag.artist,pfntmp,length); break; case 'c' : /* comment */ if(fntag.version==0) {length=MIN(f-pfntmp,sizeof(fntag.u.v10.comment)); strncpy(fntag.u.v10.comment,pfntmp,length); } else {length=MIN(f-pfntmp,sizeof(fntag.u.v11.comment)); strncpy(fntag.u.v11.comment,pfntmp,length); } break; case 's' : /* song */ length=MIN(f-pfntmp,sizeof(fntag.songname)); strncpy(fntag.songname,pfntmp,length); break; case 't' : /* title */ length=MIN(f-pfntmp,sizeof(fntag.album)); strncpy(fntag.album,pfntmp,length); break; case 'y' : /* year */ length=MIN(f-pfntmp,sizeof(fntag.year)); strncpy(fntag.year,pfntmp,length); break; case 'd' : /* dummy */ break; case 'g' : /* Genre */ memset(genre,0,sizeof(genre)); length=MIN(f-pfntmp,sizeof(genre)-1); strncpy(genre,pfntmp,length); search_genre (2, &fntag.genre, genre); break; case 'n' : /* Track */ memset(track,0,sizeof(track)); length=MIN(f-pfntmp,sizeof(track)-1); strncpy(track,pfntmp,length); fntag.version=1; fntag.u.v11.track=0; t=track; while(*t!=0) {fntag.u.v11.track*=10; fntag.u.v11.track+=*t-'0'; t++; } break; } w=NULL; } f+=strlen(ptagtmp); if(p!=NULL) { w=p+1; p+=2; ptagtmp=p; pfntmp=f; } } } if (strcmp(fntag.songname,"")==0) get_tag_string(sizeof(ptrtag->songname), def_song, ptrtag->songname, "Song Name"); else get_tag_string(sizeof(ptrtag->songname), fntag.songname, ptrtag->songname, "Song Name"); if (strcmp(fntag.artist,"")==0) get_tag_string(sizeof(ptrtag->artist), def_artist, ptrtag->artist, "Artist Name"); else get_tag_string(sizeof(ptrtag->artist), fntag.artist, ptrtag->artist, "Artist Name"); if (flags.no_album == FALSE) { if (strcmp(fntag.album,"")==0) get_tag_string(sizeof(ptrtag->album), def_album, ptrtag->album, "Album Name"); else get_tag_string(sizeof(ptrtag->album), fntag.album, ptrtag->album, "Album Name"); } if (flags.no_year == FALSE) { if (strcmp(fntag.year,"")==0) get_tag_string(sizeof(ptrtag->year), def_year, ptrtag->year, "Year"); else get_tag_string(sizeof(ptrtag->year), fntag.year, ptrtag->year, "Year"); } if (flags.no_track == FALSE) { if (fntag.version==1&&fntag.u.v11.track!=0) get_tag_track(&ptrtag->u.v11.track, fntag.u.v11.track,&ptrtag->version); else get_tag_track(&ptrtag->u.v11.track, def_track,&ptrtag->version); } if (flags.no_comment == FALSE) { if (ptrtag->version==0) { if (strcmp(fntag.u.v10.comment,"")==0) get_tag_string(sizeof(ptrtag->u.v10.comment), def_comment, ptrtag->u.v10.comment, "Comment"); else get_tag_string(sizeof(ptrtag->u.v10.comment), fntag.u.v10.comment, ptrtag->u.v10.comment, "Comment"); } else { if (strcmp(fntag.u.v11.comment,"")==0) get_tag_string(sizeof(ptrtag->u.v11.comment), def_comment, ptrtag->u.v11.comment, "Comment"); else get_tag_string(sizeof(ptrtag->u.v11.comment), fntag.u.v11.comment, ptrtag->u.v11.comment, "Comment"); } } if (flags.no_genre == FALSE) { if (fntag.genre==0) get_tag_genre(&ptrtag->genre, def_genre); else get_tag_genre(&ptrtag->genre, fntag.genre); } if (strlen(ptrtag->songname) < 1 ) /*|| strlen(ptrtag->artist) < 1)*/ /* || ptrtag->genre < 0 || ptrtag->genre >= genre_count) */ { user_message(FALSE, "Not enough info entered to tag %s\n", fn); return FALSE; } return TRUE; } int tag_file (char *fn) { FILE *fp; long sizelesstag; short found_tag; if (id3_open_file(&fp, fn, "rb") == FALSE) return FALSE; memset(ptrtag,0,sizeof(ID3_tag)); if (id3_seek_header(fp, fn) == FALSE) return FALSE; sizelesstag = ftell(fp); if (!id3_read_file(ptrtag->tag, (sizeof(ptrtag->tag)-1), fp, fn)) return FALSE; /* fread(&ptrtag->tag, (sizeof(ptrtag->tag)-1), 1, fp); */ if (strcmp(ptrtag->tag, "TAG") != 0) found_tag = FALSE; else {found_tag = TRUE; } if (found_tag == FALSE) { id3_close_file(fp); user_message(FALSE, "*** No ID3 tag found in %s\n", fn); if (flags.strip_tag == TRUE) return TRUE; /* return FALSE so no renaming is performed on files without a tag */ if (flags.no_tag_prompt == TRUE) return FALSE; printf("\n===> Entering new tag info for %s:\n", fn); if (ask_tag(fn) == FALSE) return FALSE; if(id3_write_tag(ptrtag,TRUE, fn) == FALSE) return FALSE; if (flags.tag_only == TRUE) return TRUE; if (id3_open_file(&fp, fn, "rb") == FALSE) return FALSE; if (id3_seek_header(fp, fn) == FALSE) return FALSE; if (!id3_read_file(ptrtag->tag, (sizeof(ptrtag->tag)-1), fp, fn)) return FALSE; } /*** Found a tag ****/ else if (flags.force_tag == TRUE) /* Always ask for a tag enabled? */ { if (id3_read_tag(ptrtag,fp, fn) == FALSE) return FALSE; id3_close_file(fp); printf("\n===> Changing old tag info for %s:\n", fn); if (ask_tag(fn) == FALSE) return FALSE; if (id3_write_tag(ptrtag,FALSE, fn) == FALSE) return FALSE; if (flags.tag_only == TRUE) return TRUE; if (id3_open_file(&fp, fn, "rb") == FALSE) return FALSE; if (id3_seek_header(fp, fn) == FALSE) return FALSE; if (!id3_read_file(ptrtag->tag, (sizeof(ptrtag->tag)-1), fp, fn)) return FALSE; } else if (flags.tag_only == TRUE) { id3_close_file(fp); user_message(FALSE, "===> Already has a tag: %s\n", fn); return TRUE; } else if (flags.strip_tag == TRUE) { id3_close_file(fp); if (id3_strip_tag(sizelesstag, fn) == FALSE) return FALSE; user_message(FALSE, "===> Removed ID3 tag from %s\n", fn); return TRUE; } if (id3_read_tag(ptrtag,fp, fn) == FALSE) return FALSE; resize_tag_field(ptrtag->songname); resize_tag_field(ptrtag->artist); resize_tag_field(ptrtag->album); resize_tag_field(ptrtag->year); resize_tag_field(ptrtag->u.v10.comment); // v1.1 tag handled id3_close_file(fp); return TRUE; } id3ren-1.1b0/src/id3tag.h0100640000175000017500000000217207322532341014076 0ustar chrischris/* id3 Renamer * id3tag.h - Header for id3 tag manipulation functions * Copyright (C) 1998 Robert Alto (badcrc@tscnet.com) * * 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. */ #ifndef __ID3TAG_H__ #define __ID3TAG_H__ void show_genres (int); int search_genre (int, int *, char *); void resize_tag_field (char *); int get_tag_genre (int *, int); int get_tag_string (int, char *, char *, char *); int ask_tag (char *); int tag_file (char *); #endif /* __ID3TAG_H__ */ id3ren-1.1b0/src/Makefile0100640000175000017500000000106107323526500014207 0ustar chrischrisCFLAGSDEBUG = -g -O2 -Wall -DDEBUG CFLAGS = -s -O2 -Wall CC = gcc RM = rm -f INSTALL = install -s -m 755 INSTALL_DIR = /usr/bin INSTALL_NAME = id3ren SOURCES = id3ren.c id3tag.c id3file.c id3misc.c INCLUDES = id3ren.h id3tag.h id3file.h id3misc.h id3genre.h all: ${INSTALL_NAME} ${INSTALL_NAME}: ${SOURCES} ${INCLUDES} ${CC} ${CFLAGS} -o ${INSTALL_NAME} ${SOURCES} debug: ${CC} ${CFLAGSDEBUG} -o ${INSTALL_NAME} ${SOURCES} install: ${INSTALL_NAME} ${INSTALL} ${INSTALL_NAME} ${INSTALL_DIR}/${INSTALL_NAME} clean: ${RM} ${INSTALL_NAME} *.o *.bak core id3ren-1.1b0/src/Makefile.win320100640000175000017500000000047107015617406015160 0ustar chrischrisCFLAGS = -O2 -s -Wall CC = gcc RM = rm -f INSTALL_DIR = .. INSTALL_NAME = id3ren.exe SOURCES = id3ren.c id3tag.c file.c misc.c all: ${CC} ${CFLAGS} -o ${INSTALL_NAME} ${SOURCES} install: all copy /y ${INSTALL_NAME} ${INSTALL_DIR}\${INSTALL_NAME} clean: ${RM} ${INSTALL_NAME} *.o *.bak core id3ren-1.1b0/src/id3genre.h0100640000175000017500000000567107251042375014436 0ustar chrischris/* id3 Renamer * genre.h - Header for music genres * Copyright (C) 1998 Robert Alto (badcrc@tscnet.com) * modified by Scot Hacker : beos@birdhouse.org * * 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. */ #ifndef __GENRE_H__ #define __GENRE_H__ char *genre_table[] = { "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrum. Pop", "Instrum. Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk-Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Prog. Rock", "Psychedel. Rock", "Symph. Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "Acapella", "Euro-House", "Dance Hall", }; const int genre_count = 125; #endif /* __GENRE_H__ */ id3ren-1.1b0/src/win32.bat0100640000175000017500000000011507015617406014204 0ustar chrischris@echo off echo make -f Makefile.win32 install make -f Makefile.win32 install id3ren-1.1b0/src/id3file.c0100640000175000017500000001310207322535323014233 0ustar chrischris/* id3 Renamer * id3file.c - File i/o functions * Copyright (C) 1998 Robert Alto (badcrc@tscnet.com) * Copyright (C) 2001 Christophe Bothamy (cbothamy@free.fr) * * 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. */ #include /* open */ #include #include #include #include #include "id3file.h" #include "id3genre.h" #include "id3ren.h" #include "id3misc.h" /* todo: add option to change log filename */ const char logfile[] = "id3ren.log"; int add_to_log (char *data) { FILE *fp; if (id3_open_file(&fp, (char*)logfile, "at") == FALSE) return FALSE; fprintf(fp, "%s", data); fclose(fp); return TRUE; } int id3_read_file (char *dest, unsigned long size, FILE *fp, char *fn) { if (fread(dest, size, 1, fp) != 1) { print_error("id3_read_file: Error reading %s", fn); fclose(fp); return FALSE; } if (ferror(fp) != 0) { print_error("id3_read_file: Error reading %s", fn); clearerr(fp); fclose(fp); return FALSE; } if (feof(fp)) { print_error("id3_read_file: Premature end of file in %s", fn); fclose(fp); return FALSE; } return TRUE; } int id3_write_file(char *src, unsigned long size, FILE *fp, char *fn) { if (fwrite(src, size, 1, fp) != 1) { print_error("id3_write_file: Error writing to %s", fn); fclose(fp); return FALSE; } if (ferror(fp) != 0) { print_error("id3_write_file: Error writing to %s", fn); clearerr(fp); fclose(fp); return FALSE; } return TRUE; } int id3_open_file (FILE **fp, char *fn, char *mode) { *fp = fopen(fn, mode); if (*fp == NULL) { print_error("id3_open_file: Error opening file %s", fn); return FALSE; } return TRUE; } int id3_close_file (FILE *fp) { return fclose(fp); } int id3_seek_header (FILE *fp, char *fn) { if (fseek(fp, -128, SEEK_END) < 0) { fclose(fp); print_error("id3_seek_header: Error reading file %s", fn); return FALSE; } return TRUE; } int id3_strip_tag (long sizelesstag, char *fn) { int fd; fd = open(fn, O_RDWR); if (fd == -1) { print_error("strip_tag: Error opening %s", fn); return FALSE; } #ifdef __WIN32__ chsize(fd, sizelesstag); #else ftruncate(fd, sizelesstag); #endif close(fd); return TRUE; } int id3_write_tag (ID3_tag *tag, int append_flag, char *fn) { FILE *fp; if (append_flag == TRUE) { if (id3_open_file(&fp, fn, "ab") == FALSE) return FALSE; } else { if (id3_open_file(&fp, fn, "r+b") == FALSE) return FALSE; if (id3_seek_header(fp, fn) == FALSE) return FALSE; } strcpy(tag->tag, "TAG"); if (!id3_write_file(tag->tag, (sizeof(tag->tag)-1), fp, fn)) return FALSE; if (!id3_write_file(tag->songname, (sizeof(tag->songname)-1), fp, fn)) return FALSE; if (!id3_write_file(tag->artist, (sizeof(tag->artist)-1), fp, fn)) return FALSE; if (!id3_write_file(tag->album, (sizeof(tag->album)-1), fp, fn)) return FALSE; if (!id3_write_file(tag->year, (sizeof(tag->year)-1), fp, fn)) return FALSE; if (!id3_write_file(tag->u.v10.comment, (sizeof(tag->u.v10.comment)-1), fp, fn)) return FALSE; /* fwrite(tag->genre, 1, 1, fp);*/ if (fputc(tag->genre, fp) == EOF) { fclose(fp); print_error("write_tag: Error writing to %s", fn); return FALSE; } fclose(fp); return TRUE; } int id3_read_tag (ID3_tag *tag, FILE *fp, char *fn) { if (!id3_read_file(tag->songname, (sizeof(tag->songname)-1), fp, fn)) return FALSE; if (!id3_read_file(tag->artist, (sizeof(tag->artist)-1), fp, fn)) return FALSE; if (!id3_read_file(tag->album, (sizeof(tag->album)-1), fp, fn)) return FALSE; if (!id3_read_file(tag->year, (sizeof(tag->year)-1), fp, fn)) return FALSE; if (!id3_read_file(tag->u.v10.comment, (sizeof(tag->u.v10.comment)-1), fp, fn)) return FALSE; /* Detect v1.1 tag */ if((tag->u.v10.comment[28]==0) &&(tag->u.v10.comment[29]!=0)) tag->version=1; /* fread(&tag->genre, 1, 1, fp); */ tag->genre = fgetc(fp); if (tag->genre == EOF) { fclose(fp); print_error("tag_file: Error reading %s", fn); return FALSE; } return TRUE; } void id3_show_tag (ID3_tag *tag, char *fn) { user_message(FALSE, "===> %s:\n", fn); if (strlen(tag->songname) > 0) user_message(FALSE, "Song Name: %s\n", tag->songname); if (strlen(tag->artist) > 0) user_message(FALSE, " Artist: %s\n", tag->artist); if (strlen(tag->album) > 0) user_message(FALSE, " Album: %s\n", tag->album); if (strlen(tag->year) > 0) user_message(FALSE, " Year: %s\n", tag->year); if (strlen(tag->u.v10.comment) > 0) user_message(FALSE, " Comment: %s\n", tag->u.v10.comment); if (tag->version == 1 && tag->u.v11.track !=0) user_message(FALSE, " Track: %02d\n", tag->u.v11.track); if (tag->genre >= 0 && tag->genre < genre_count) user_message(FALSE, " Genre: %s\n", genre_table[tag->genre]); user_message(FALSE, "\n"); } id3ren-1.1b0/src/id3file.h0100640000175000017500000000373207322535345014254 0ustar chrischris/* id3 Renamer * file.h - Header for file i/o functions * Copyright (C) 1998 Robert Alto (badcrc@tscnet.com) * Copyright (C) 2001 Christophe Bothamy (cbothamy@free.fr) * * 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. */ #ifndef __FILE_H__ #define __FILE_H__ #define TAGLEN_TAG 3 #define TAGLEN_SONG 30 #define TAGLEN_ARTIST 30 #define TAGLEN_ALBUM 30 #define TAGLEN_YEAR 4 #define TAGLEN_COMMENT_V10 30 #define TAGLEN_COMMENT_V11 28 #define TAGLEN_GENRE 1 typedef struct ID3_struct { // version: 0 is v1.0 - 1 is v1.1 char version; char tag[TAGLEN_TAG+1]; char songname[TAGLEN_SONG+1]; char artist[TAGLEN_ARTIST+1]; char album[TAGLEN_ALBUM+1]; char year[TAGLEN_YEAR+1]; union { struct { char comment[TAGLEN_COMMENT_V10+1]; }v10; struct { char comment[TAGLEN_COMMENT_V11+1]; char track; }v11; }u; int genre; } ID3_tag; int add_to_log (char *); int id3_read_file (char *, unsigned long, FILE *, char *); int id3_write_file (char *, unsigned long, FILE *, char *); int id3_open_file (FILE **, char *, char *); int id3_close_file (FILE *); int id3_seek_header (FILE *, char *); int id3_strip_tag (long, char *); int id3_write_tag (ID3_tag *,int, char *); int id3_read_tag (ID3_tag *,FILE *, char *); void id3_show_tag (ID3_tag *, char *); #endif /* __FILE_H__ */ id3ren-1.1b0/src/id3misc.h0100640000175000017500000000214507251031225014252 0ustar chrischris/* id3 Renamer * misc.h - Header for miscellaneous functions for id3ren * Copyright (C) 1998 Robert Alto (badcrc@tscnet.com) * * 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. */ #ifndef __MISC_H__ #define __MISC_H__ void alloc_string (char **, unsigned long); int strcase_search (char *, char *); void string_lower (char *); int get_term_lines (void); void print_error (char *, ...); void user_message (int, char *, ...); #endif /* __MISC_H__ */ id3ren-1.1b0/src/id3ren0100755000175000017500000006607007324346556013714 0ustar chrischrisELF4h4 (444^^^^`^``X, d /lib/ld-linux.so.2GNU%4%*2 -0 /3'1() ,  # "!&$+.,;6<8!L\;l<||(gc<}"̊8܊7*D1 /X ,Q<;hL\l3|"=]Kő;܋D /!//, <L=\[il|:nt$'*J̌ ܌ __gmon_start__libc.so.6strcpyprintfvsprintfstrerror__ctype_bgetenv__strtol_internalfgetsfeofmalloc__ctype_toupperftruncaterenamestrrchrfprintfstrcat__deregister_frame_infofseekstdinferrorstrstrstrncmpstrncpystrcasecmp_IO_getcstrncatfreadftellclearerrstrcmpfgetcsprintffcloseatexitstderrfputcfwriteaccess__errno_locationexitfopen_IO_stdin_used__libc_start_mainopenstrchrmkdir__ctype_tolower__register_frame_infoclosefreeGLIBC_2.1GLIBC_2.0ii ii 2 *+dhlptx|     !"#$%&'(),-/0 13US[dituvg<[5\%`%dh%hh%lh%ph%th %xh(%|h0%h8p%h@`%hHP%hP@%hX0%h` %hh%hp%hx%h%h%h%h%h%h%h%hp%h`%hP%h@%h0%h %h%h%h%h%h%h%h%h %h(%h0%h8p%h@`%hHP% hP@%hX01^PTRhhQVhU=hu>dPdСd8u|t hDhÐUUthhD#ÐUÐUÍvU,WVSDž֍=%9A$Hx$t$PhPhHxgtgPhPhiH;}|4Lh9awPhAHxtPh &/PhHxCtCPhPhHxbtbPhoPhOwH8~4PhISSh at&tSPh &2Pj%h`j5эA<hPTDžDžt&5@1ۋBtn83u0SэA9sDBgz5@эA9rizP5D-DPt:fu svfuA`< u=h hэB<eװ1ۃ<t8t&<\t,<|t*[]t&_;t&-CװэA9r[^_ÉUS]hhj3h@j3 hj2Shj2 hj2h@j2 hj2hj2 h@j2hj2 hjx2h`ji2 hjW2hjH2 h@j62hhj"2 hj2h@j2 j%j%j%j%hj1 j%j%j%hj1 j%h@j1]ÉUE 9E|5h|j1jÐU WVSu] bMt߰u8QP.VLv҉э PP.Sj/Vh60f=t5hj0jtf=tchjj0Of=thjL0hu(h/L1f=t5hj/PhSр uш u &B: t<# ӍC<=t< tu< t<=uC; tRVƅƅ;tp&t;'uFƅLt;"u/ƅ5<"u ƅ$<'u ƅv< tjSWC;uDžHtRVuRPQhPQ[PC[^_ÍvUEf8uffÐUWVS}u]EE} uVS5EVS u#Pu PEUE{߰эAPEP*Shu UװэAPVRuj=Vc@UEu+}u 1 t&e[^_ÍvUWVSu}j]ShWVE PMQ t5Kjt&jShWVE PMQ t/}Qh)u t&jSh!WVM QEP> t/}Qh)u= t&jSh)WVM QEP t/}QhR)u| t&jSh0WVM QEP t/}Qh)u t&jSh6WVM QEPN tUװ1ۃt0ТCװэA9rҀ=c5u5h=j*jjShSWVM QEP t/}Qh(u t&jSh\WVM QEP^ t?uhj 5hcj)jvjShzWVM QEP t6}Qhb'u5: jShWVM QEP thw jShWVM QEPn th> jShWVM QEP; th j jShWVM QEP th7 &jShWVM QEP th jShWVM QEP thk jShWVM QEPh th8 &jShWVM QEP. th] jShWVM QEP t fff jShWVM QEP th jShWVM QEP thW jShWVM QEPN tuhjj/vjShWVM QEP tjjjShWVM QEP tff vjShWVM QEP thn jShWVM QEPk th; jSh WVM QEP8 thg &jShWVM QEP u!jSh'WVM QEP th jSh/WVM QEP thzjSh5WVM QEPw tfjSh>WVM QEPH tf{jShEWVM QEP tfLjShLWVM QEP t+Eu  jPh vjShSWVM QEP t6}QhD"u5DjSh\WVM QEPG tmUװu"5hj#jvװQh@t!u5@LjShWVM QEP tBEu#V5hjh#jhPhjShWVM QEPVE tW5 WSSxWoe[^_ÐUWVSu1ۃt%33CэA9r[^_ÉUShIÃtjj jS3 jj jS]UVSE PuSH6/PS5hO5@f=u,6PS5hOS0S[^UVS]EPu V0tVh[5u&f=uVh[f=u Vr[^ÐUSH=Ht Ѓ;u[UUS[`,[unknown%02dUnknown identifier in template: %c%c & g             @    1.1b0 for *nixGPL'd id3 Renamer & Tagger version %s (C) Copyright 1998 by Robert Alto (badcrc@tscnet.com) (C) Copyright 2001 by Christophe Bothamy (cbothamy@free.fr) Usage: %s [-help] [-song=SONG_NAME] [-artist=ARTIST_NAME] [-album=ALBUM_NAME] [-year=YEAR] [-genre={# | GENRE}] [-comment=COMMENT] [-track=TRACK] [-showgen] [-searchgen={# | GENRE}] [-default=DEFAULT] [-copytagfrom=FILE [-copysong] [-copyartist] [-copyalbum] [-copyyear] [-copygenre] [-copycomment] [-copytrack] [-copyall] ] [-quick] [-noalbum] [-nocomment] [-noyear] [-nogenre] [-notrack] [-tag] [-edit] [-notagprompt | -showtag | -striptag | -tagonly] [-nocfg] [-log] [-quiet] [-verbose] [-defcase | -lower | -upper] [-remchar=CHARS] [-repchar=CHARS] [-space=STRING] [-tagfromfilename | -tagffn] [-tagtemplate=TAGTEMPLATE] [-template=TEMPLATE] [FILE1 FILE2.. | WILDCARDS] When logging is enabled, most normal output is also sent to %s. To disable all output except for the usage screen on errors, use -quiet. The templates can contain the following identifiers from the id3 tag: %ca - Artist %cc - Comment %cg - Genre %cs - Song Name %ct - Album title %cy - Year %cn - Track ## The tagtemplate can also contain the dummy identifier %cd. %s: Not enough arguments %s%c%s%s: Checking for config file %s...not found found rtCouldn't open config file %s%s: Reading config file %s %s=-help-song-artist-album-year-track%s: track %s is > 99 -comment-genre%s: No genre selected -default-log-notagprompt-noalbum-nocomment-noyear-notrack-nogenre-nocfg-quick-quiet-verbose-searchgen-showgen-showtag-striptag-tag-tagonly-tagfromfilename-tagffn-edit-defcase-upper-lower-space-remchar-repchar%s: Replace characters must be in pairs -template%s: Empty template specified (%s) -tagtemplate%s: Empty tagtemplate specified (%s) -copytagfrom%s: Empty file name to copy from specified (%s) rb%s: Can not copy from file (%s) TAG%s: Can not find any tag in file (%s) -copysong%s: No copytagfrom file specified -copyartist-copyalbum-copyyear-copytrack%s: Copied tag is not id3v1.1 -copycomment-copygenre-copyall%s: Unknown option: %s ID3REN.id3renrcHOMEid3renrc/etc.Out of memory for malloc%s: Not enough arguments specified %s: File not found: %s %s: File already exists: %s Create dir failed on %s%-38s => %-37s Rename failed on %sProcessed: %d Failed: %d Total: %d %3d:%-15s -MORE- Press ENTER%s %s: search_genre: Invalid genre type: %d Found exact genre match [%s] Found matching genre [%s] %3d: %s Genre not found: %s [%s] use this genre? (Y/n/q) No genre selected...tough choice isn't it? Genre of music: %s Genre of music (blank to cancel, 'l' to list): Would you like to see a list? (Y/n) "%s" selected. Track: %02d Track (1 to 99, blank for none): %s (%d chars): Song NameArtist NameAlbum NameYearCommentNot enough info entered to tag %s жDDDDDDDDDDDDDD1PDDDDprbTAG*** No ID3 tag found in %s ===> Entering new tag info for %s: ===> Changing old tag info for %s: ===> Already has a tag: %s ===> Removed ID3 tag from %s Dance HallEuro-HouseAcapellaDrum SoloPunk RockDuetFreestyleRhythmic SoulPower BalladBalladFolkloreSambaTangoClubSlow JamSatirePorn GroovePrimusBooty BassSymphonySonataChamber MusicOperaChansonSpeechHumourAcousticEasy ListeningChorusBig BandSlow RockSymph. RockPsychedel. RockProg. RockGothic RockAvantgardeBluegrassCelticRevivalLatinBebobFast FusionSwingNational FolkFolk-RockFolkHard RockRock & RollMusicalRetroPolkaAcid JazzAcid PunkTribalLo-FiTrailerShowtunesRavePsychadelicNew WaveCabaretNative AmericanJunglePop/FunkChristian RapTopGangstaCultComedySouthern RockDreamEurodancePop-FolkElectronicTechno-IndustrialDarkwaveGothicEthnicInstrum. RockInstrum. PopMeditativeSpacePunkSoulBassAlternRockNoiseGospelSound ClipGameHouseAcidInstrumentalClassicalTranceFusionJazz+FunkVocalTrip-HopAmbientEuro-TechnoSoundtrackPranksDeath MetalSkaAlternativeIndustrialTechnoRockReggaeRapR&BPopOtherOldiesNew AgeMetalJazzHip-HopGrungeFunkDiscoDanceCountryClassic RockBlues}id3ren.logat%sid3_read_file: Error reading %sid3_read_file: Premature end of file in %sid3_write_file: Error writing to %sid3_open_file: Error opening file %sid3_seek_header: Error reading file %sstrip_tag: Error opening %sabr+bTAGwrite_tag: Error writing to %stag_file: Error reading %s===> %s: Song Name: %s Artist: %s Album: %s Year: %s Comment: %s Track: %02d Genre: %s alloc_string: Out of memory for mallocstrcase_search: Out of memory for mallocLINES%s: %s: %s %sT@[%a]-[%s].mp3[%a]-[%s].mp3 HH}wohb^ZVOJC8,( {vpeXJC<3! }uoh^TNH@4*% ~of_XPJ<5,!2BRbrŠҊ"2BRbr‹ҋ"2BRbrŒҌ  (ԅ  X`X0o(ooGCC: (GNU) 2.95.2 20000220 (Debian GNU/Linux)GCC: (GNU) 2.95.2 20000220 (Debian GNU/Linux)GCC: (GNU) 2.95.2 20000220 (Debian GNU/Linux)GCC: (GNU) 2.95.2 20000220 (Debian GNU/Linux)GCC: (GNU) 2.95.2 20000220 (Debian GNU/Linux)GCC: (GNU) 2.95.2 20000220 (Debian GNU/Linux)GCC: (GNU) 2.95.2 20000220 (Debian GNU/Linux)GCC: (GNU) 2.95.2 20000220 (Debian GNU/Linux)GCC: (GNU) 2.95.2 20000220 (Debian GNU/Linux)01.0101.0101.0101.0101.0101.0101.0101.0101.01.symtab.strtab.shstrtab.interp.note.ABI-tag.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.got.rel.bss.rel.plt.init.plt.text.fini.rodata.data.eh_frame.ctors.dtors.got.dynamic.sbss.bss.comment.note# 1((l7 @?ԅGohTo((0c XXl ``(u ` ~ 1  9F  G> ``^ DDcHHcPPcXXcddd dgfgid3ren-1.1b0/TODO0100644000175000017500000000023107321312422012444 0ustar chrischris===== TO DO ===== * Use a "mv" style renaming, to be able to span filesystems * Use autoconf * id3 tags v2 * Would be nice to have a graphical frontend id3ren-1.1b0/USAGE0100644000175000017500000001345407324345605012572 0ustar chrischris============== id3ren Options ============== Please note that the syntax of the option can use the "=" sign or the next argument, with or without quotes. So -option ARGUMENT, -option "ARGUMENT", -option=ARGUMENT, -option="ARGUMENT" have all the same meaning. -album=ALBUM_NAME Sets the album name to use when tagging files. All files will be tagged with this album name without prompting. -artist=ARTIST_NAME Sets the artist name to use when tagging files. All files will be tagged with this artist name without prompting. -comment=COMMENT Sets the comment to use when tagging files. All files will be tagged with this comment without prompting. -copyalbum Copies the album field from the source file tag set by -copytagfrom -copyall Copies all the fields from the source file tag set by -copytagfrom -copyartist Copies the artist field from the source file tag set by -copytagfrom -copycomment Copies the comment field from the source file tag set by -copytagfrom -copygenre Copies the genre field from the source file tag set by -copytagfrom -copysong Copies the song field from the source file tag set by -copytagfrom -copytagfrom=FILE Sets the filename to copy tag field from. -copytrack Copies the track field from the source file tag set by -copytagfrom -copyyear Copies the year field from the source file tag set by -copytagfrom -defcase Use the default case of characters from the ID3 tag when renaming files. This is default. -default=DEFAULT Sets the default field to be used only when renaming if a field is blank. Useful when renaming and creating "unknown" subdirectories. Defaults to "unknown". -edit If a file already has a tag and you want to change just one specific field of the tag, use this option in conjunction with -tag and the option for the field you want to change. For example to change just the album name of a file: id3ren -tag -edit -album="New Album Name" sample.mp3 * This option is a toggle. -genre=[# | GENRE_NAME] Sets the genre to use when tagging files. All files will be tagged with this genre without prompting. To see a list of allowable genres use the -showgen argument. -genre accepts either the number of the genre as displayed with -showgen, or the name of the genre. -help Displays the help screen. -log Log most output to id3ren.log. * This option is a toggle. -lower Convert file names to lowercase characters. -noalbum Don't prompt for the album when adding a tag. * This option is a toggle. -nocfg Don't try reading any config files, even if they exist. * This option is a toggle. -nocomment Don't prompt for a comment when adding a tag. * This option is a toggle. -nogenre Don't prompt for a genre when adding a tag. * This option is a toggle. -notagprompt Never prompt for tag information. Files without tags are skipped. * This option is a toggle. -notrack Don't prompt for the track number when adding a tag. * This option is a toggle. -noyear Don't prompt for the year when adding a tag. * This option is a toggle. -quick Automatically sets -noalbum, -nocomment, and -noyear. -quiet Run quietly, displaying only errors or prompts. * This option is a toggle. -remchar=CHARS CHARS indicates a string of characters that will be removed from the filename if found. -repchar=CHARS CHARS indicates a string of characters, EACH followed by the character to replace it with. For example, to replace all plus '+' signs with a hyphen '-', you would use '-repchar +-'. To do the previous, and also replace all '&' with '_', you would use '-repchar +-&_'. -searchgen=# | GENRE Searches the list of genres and displays either the genre name corresponding to #, or shows all substring matches of GENRE. -showgen Displays all the music genres currently in the program. -showtag Display the tags for the specified files. No renaming is performed. -song=SONG_NAME Sets the song name to use when tagging files. All files will be tagged with this song name without prompting. -space=STRING Change all spaces in the renamed file to STRING. To remove all spaces, use '-space=' or '-space=""'. The default space character is ' '. -striptag Remove the tags for the specified files. * This option is a toggle. -tag Always ask for a tag, even if the file already has one. * This option is a toggle. -tagfromfilename, -tagffn Use informations from the filename when tagging. See tagtemplate. * This option is a toggle. -tagonly Don't rename any files, just ask for tag information. Note that -tagonly only asks for tag information on files that don't have a tag already. To have it ask for a tag on all files, use with -tag. * This option is a toggle. -tagtemplate=TEMPLATE Use TEMPLATE as the basis for tagging files. The default template used is '[%a]-[%s].mp3'. Identifiers that can be used in the template are: %a - Artist name %c - Comment %s - Song name %t - Album title %n - Track Number %y - Year %g - Genre %d - Dummy It is a VERY good idea to have fixed separators between fields. -template=TEMPLATE Use TEMPLATE as the basis for renaming files. The default template used is '[%a]-[%s].mp3'. Identifiers that can be used in the template are: %a - Artist name %c - Comment %s - Song name %t - Album title %n - Track Number %y - Year %g - Genre -track=TRACK Sets the track number to use when tagging files. All files will be tagged with this track number without prompting. TRACK must be an integer between 1 and 99. -upper Convert file names to uppercase characters. -verbose Display more messages than usual. * This option is a toggle. -year=YEAR Sets the year to use when tagging files. All files will be tagged with this year without prompting. And of course the program accepts wildcards for filenames. id3ren-1.1b0/FEEDBACK0100644000175000017500000000020707324346365013046 0ustar chrischris========= FEEDBACK ========= For any patches, bug reports, comments, questions or ideas, feel free to contact me id3ren-1.1b0/ChangeLog0100644000175000017500000000537207324155466013561 0ustar chrischris1.1b0 2001-07-14 Christophe Bothamy ================ - Added support for id3 v1.1 - Added automatic directory creation when renaming. - Added a "-default" option to handle blank fields when renaming. - Added the possibility to copy tags from other files. - Changed the default "space" char to a more sensible " " when renaming. - Uniformisation of the syntaxes of the different options. (all options can use = or next arg, with or without quotes) - Different handling of the options in the resource file (same as commandline). Existing .id3renrc files might need an update. 1.0b2 2000-02-01 Christophe Bothamy ================ - Correction of a display bug in the help screen 1.0b1 2000-12-15 Christophe Bothamy ================ - Reorganisation of directories and files - Sources tar ball does not contain executable any more. I will set up a debian package. - Due to lack of compiler, Windows support is discontinued. If i get enough feed back, i'll consider install Visual C++ somewhere In the meantime, use id3ren 0.97a which contains win32 executable. The sources compiles fine under cygwin, maybe you could give it a try - Tagging a file can be done with informations from the file name. Added -tagfromfilename and -tagffn (synonymns) and -tagtemplate. It's a good idea to use it with the -tagonly option. 0.97a Robert Alto ===== - Fixed a short->int screw up on my part that was causing weird things to happen...Solaris got a bus error, 95 and Linux didn't read certain options correctly. - Changed usage screen for Linux to "for *nix" cause ascii doesn't like things for Linux on his Solaris box. 0.97 Robert Alto ==== - Added -edit option. - Several options are now toggles. For example if you specify -verbose in a config file, then you want to disable verbose mode one time, you can specify -verbose on the command line and it will disable it for that one use. Options that aren't toggles: -quick, -showtag, -defcase, -upper, -lower....and any other option that accepts a second argument, or displays info (i.e., -showgen, -help, -template, -space, etc). - Included some sample rc files in the samples directory. 0.96 Robert Alto ==== - Included source in archive, with a Makefile for both Linux and Win32. - Added -nocfg, -nogenre, -remchar, -repchar, -verbose options. - Added support for config files. See id3ren.txt for info. - You can now change specific parts of a tag if a file already has a tag. For example, if you have a file that has a tag and only want to change the album name, you can use -tag in conjunction with -album. You will still be prompted for other tag info if they are blank unless you use the -noalbum id3ren-1.1b0/COPYING0100644000175000017500000004307707250746324013043 0ustar chrischris GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. id3ren-1.1b0/INSTALL0100644000175000017500000000110307324160424013012 0ustar chrischris============ Installation ============ Grab the latest version of id3ren from http://cbothamy.free.fr/projects/id3ren Unpack it : % tar xzvf id3ren-Version.tgz Install it : % cd id3ren-Version % su % make install id3ren gets installed in /usr/bin. Man page gets installed in /usr/man ================ More information ================ See the "ChangeLog" file. See the "README" file for guidelines on config files See the "USAGE" file for guidelines on command line options. See the "FEATURES" file for guidelines on new Features. See the "FEEDBACK" file for bug reports. id3ren-1.1b0/README0100644000175000017500000000551107324160440012646 0ustar chrischrisid3ren (C) Copyright 1998 by Robert Alto (badcrc@tscnet.com) (C) Copyright 2001 Christophe Bothamy (cbothamy@free.fr) ======= License ======= 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., 675 Mass Ave, Cambridge, MA 02139, USA. ============ Introduction ============ id3ren is used to rename batches of mp3 files by reading the ID3 tag at the end of the file which contains the song name, artist, album, year, and a comment. The secondary function of id3ren is a tagger, which can create, modify, or remove ID3 tags. The id3 fields can be set on the command line, entered interactively, or "guessed" from the path and the filename. If you have questions, comments, or bug reports, contact cbothamy@free.fr To get the latest version please visit http://cbothamy.free.fr/projects/id3ren/ Please refer to the USAGE file for the meaning of the different options. Please refer to the FEATURES file to learn more on new features of id3ren. ===== Notes ===== - id3ren is developed and tested on linux, but it should work as is on any unix system. - Windows support is discontinued. It may still work, but it has not been tested id3ren is known to compile fine with cygwin. - Config files should only contain the exact same options as specified on the command line. You can use # at the beginning of a line for a comment. Spaces at the beginning of a line are ignored. NOTE: There is no more syntax difference between a config file option and a command line option. - id3ren first reads all command line options. If it doesn't find the "-nocfg" command line option, it looks for config files in this order: 1) Reads environment variable ID3REN which should contain the complete path to a config file. If variable doesn't exist or file not found then... 2) Reads environment variable HOME and look for $HOME/.id3renrc. If variable doesn't exist or file not found then... 3) It looks for /etc/id3renrc. ===== Ports ===== - a BEOS port has been made by Shayne. See http://curvedspave.org/html/id3ren.html - another BEOS port has been made by Scot Hacker. See at http://bebits.com/app/552 - a FreeBSD port has been made by Joao Carlos Mendes Luis. See http://www.geocrawler.com/archives/3/167/1999/2/0/540206/ id3ren-1.1b0/THANKS0100644000175000017500000000116307324417246012711 0ustar chrischris============================ Big Thanks to all these guys ============================ - The original author of id3ren Robert Alto - The man page was generated by Frederic Bothamy . - A debian package is maintained by Michael D. Ivey - A BEOS port has been done by Shayne. See http://curvedspace.org/html/id3ren.html - Another BEOS port has been done by Scot Hacker . See http://bebits.bebits.com/app/552 - A FreeBSD port has been done by Joao Carols Mendes Luis See http://www.geocrawler.com/archives/3/167/1999/2/0/540206/ id3ren-1.1b0/AUTHORS0100644000175000017500000000033107251230520013025 0ustar chrischris======= AUTHORS ======= Robert Alto Christophe Bothamy Scot Hacker updated the genre list Frederic Bothamy generated the man page id3ren-1.1b0/FEATURES0100644000175000017500000000547007323631156013141 0ustar chrischris===================== Tagging from Filename ===================== I added this feature to id3ren, because i never found a good utility to set tags to my untagged mp3s. Nearly all useful informations were already available in the filenames, and i didn't want to do the job twice. The tagtemplate can contain the following identifiers : %a - Artist %c - Comment %g - Genre %s - Song Name %t - Album title %y - Year %d - Dummy Example : My mp3s are stored in a directory for each album. Each song is prefixed by the track number. bash-2.01$ find "/mp3/vast - visual audio sensory theater" /mp3/vast - visual audio sensory theater/ /mp3/vast - visual audio sensory theater/01 here.mp3 /mp3/vast - visual audio sensory theater/02 touched.mp3 /mp3/vast - visual audio sensory theater/03 dirty hole.mp3 /mp3/vast - visual audio sensory theater/04 pretty when you cry.mp3 /mp3/vast - visual audio sensory theater/05 i'm dying.mp3 /mp3/vast - visual audio sensory theater/06 flames.mp3 /mp3/vast - visual audio sensory theater/07 temptation.mp3 /mp3/vast - visual audio sensory theater/08 three doors.mp3 /mp3/vast - visual audio sensory theater/09 the niles edge.mp3 /mp3/vast - visual audio sensory theater/10 somewhere else to be.mp3 /mp3/vast - visual audio sensory theater/11 .mp3 /mp3/vast - visual audio sensory theater/12 you.mp3 I want to tag all thoses mp3s : id3ren -tagonly -tag -tagfromfilename -tagtemplate="/mp3/%a - %t/%n %s.mp3" \ -genre Alernative -nocomment -year 1998 \ "/mp3/vast - visual audio sensory theater/*.mp3" If your mp3s are stored in a directory for the artist and a subdirectory for the album name you could use the following tagtemplate : "%a/%t/%n %s.mp3". As long as you have a fixed separators between fields, you should be ok. =================================== Creating Directories while renaming =================================== id3ren can now automatically create directory entries if the template contains "/". You could use a template like "%a/%t/%n %s.mp3" to create a tree for your mp3s, the first level would be the artist, the second the album title, and then each file would be composed of the track and the song name. It is useful to set a default field to handle blank fields (for example -default="unknown"). ================ id3 v1.1 Support ================ id3ren, from version 1.1 and up supports id3 v1.1 transparently. An id3 v1.1 tag will be created only if a track number is present. ============================== Copying tags from another file ============================== id3ren can import tags from another tagged file. Use the -copytagfrom option along with one or several -copy... (tag field) options. Several source files can be used in sequence, like in this example : -copytagfrom=/my/first.mp3 -copysong -copyartist \ -copytagfrom=/my/second.mp3 -copyalbum -copycomment id3ren-1.1b0/man/0040755000175000017500000000000007324203251012540 5ustar chrischrisid3ren-1.1b0/man/id3ren.1.gz0100640000175000017500000000474607324155343014441 0ustar chrischrisP;id3ren.1Y_o8קuMs 븉(hJwofHJ0`"g7`qx 'pt7Rx'G`~q%Zps 3)LNgV V ZPTf4w?LytqDnkxy *Wݤ34/͌7b2_4"|/_]yk#ÙZR |<⿈NBdtx{W^̆?Y;$F 8ئ_T9=\xcUmPU(zvr9vڠOٝy~:bxg 03O@37[*G;[K!_*G 4#/lj SYT'|CYr(dJR/^0vNjzJj"eG\iSX-f鹷i) ELӒ/VVU.,o\ wחEpn=!<8l4d.6FWfɢ#x6z#4Vk '^Ul)Xǿ[ЀoZ+j-፲kQlYtOZA;ylr\M53P2NcKa5Jۈ'5f\Ev>1DPbHnkUiEVO^r~DYGA-)$Bo f$& d%uqbQBZT$K7}P/m#KasḅҏVҺ> u|1} ђ]KY3F:$xK&UmEܓ^NF*<4/ոωӚf%/r;0BkyxU34p'DzBq%2@ M˺@/I h2.mh:Zf4sh8$nYv"징jU۪fpF~1;>q¯9W7@,*{Ac1-ўqҶƢPw>[dj7 h%)DB}h>@ݻi7#џ 0 AT(UHrW0_3 ن:]E1 .<Vnb *Su>'e/6ɚ% &g Za}U4fO)}p#~@&(5 kbUα9MtMY#`Ȥ.-a<] MJ а!\ ߮`}!6&[wzx{}WU呲y/~9(6SqiEĨSQ}!џ>:jxB%r%IBThJ [tP ה (+ޕբ:6YDqJd(NmjEC C+BtTuJjLz ؽlBsq dh//usb 4.v-rA-aDnzd08:b f[^o 99V"e!Ot߱ǘr1T-Cҩdnd]O\=Pn#꠆vt7 Ͼʛ*p KnhzO䝽s[˪cdJ_ 5ޖEOOMOL5䔡bѭbh }T5d 0loh.+464(˻J)7]g4G0˜T!G]?V;[myև-yص6_%9NK:[µ'\_ꘚ|on-mʥ\|U%#ê)C-#V=MÍtXy{H.grtHt=}90_E9RxvߊCQN^e. n뛫s"<ȁg- נ~ e"84ȲL󱈲J.!4A`_[[~"/PU_dl 'ւid3ren-1.1b0/man/Makefile0100640000175000017500000000026707321174636014211 0ustar chrischrisRM = rm -f INSTALL = install -m 755 INSTALL_DIR = /usr/man/man1 INSTALL_NAME = id3ren.1.gz all: debug: install: ${INSTALL} ${INSTALL_NAME} ${INSTALL_DIR}/${INSTALL_NAME} clean: