1 /*
2 * mp3rename.c
3 *
4 * Sander Janssen <janssen@rendo.dekooi.nl>
5 *
6 * This software is covered by the GNU public license,
7 * which should be in a file named LICENSE acompanying
8 * this.
9 *
10 */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <ctype.h>
16 #include <string.h>
17 #include <signal.h>
18
19 void pad(char *string, int length);
20 void display_help();
21 void buildtag(char *buf, char *title, char *artist, char *album, char *year, char *comment, char *genre);
22 void set_filename(int argc,char *argv[]);
23
main(int argc,char * argv[])24 int main(int argc, char *argv[])
25 {
26 FILE *fp;
27 int verbose = 0, forced = 0, burn = 0, info = 0, all = 0;
28 unsigned char sig[2];
29 char genre[1];
30 char input_char;
31 int i=0,plaatsen = 0;
32 int ch,p;
33 char filenamelook[100];
34 char str[100];
35
36
37 if (argc < 2 ) /* If nothing is given */
38 {
39 fprintf(stderr,"Mp3rename\n\nusage: [-vfhsbia] [file ...]\n\n");
40 return 0;
41 }
42
43 /* Lets checkout the options */
44
45 while ((ch = getopt(argc, argv, "vfhsbia")) != -1)
46 switch (ch)
47 {
48 case 'v': /* Verbose mode */
49 verbose = 1;
50 break;
51 case 'f': /* Always ask mode */
52 forced = 1;
53 break;
54 case 'h': /* Display the help */
55 display_help();
56 exit(1);
57 case 's': /* Set the default look */
58 set_filename(argc,argv);
59 exit(1);
60 case 'b': /* Burn modus cut of at 32 chars */
61 burn = 1;
62 break;
63 case 'i': /* Just the id3tag */
64 info = 1;
65 break;
66 case 'a': /* Ask everything */
67 all = 1;
68 break;
69 default: /* If wrong option is given */
70 fprintf(stderr,"Mp3rename\n\nusage: [-vfh] [file ...]\n\n");
71 exit(1);
72 }
73 argv += optind;
74
75 if ( info == 1 && ( forced == 1 || verbose == 1))
76 {
77 printf("Info modus can not be used with other arguments.\n\n");
78 exit(1);
79 }
80 sprintf(str,"%s/.mp3rename",getenv("HOME")); /* Lets get the home dir */
81
82 if ( !( fp=fopen(str,"r") ) ) /* if we don't find our config file */
83 {
84 sprintf(filenamelook,"(&a)-&t");
85 printf("Using default look, please use the -s option to set your own look\n");
86 }
87 else /* found! */
88 fgets(filenamelook, 100, fp);
89
90 if(burn != 1) /* If burn is on we will add the .mp3 later */
91 strcat(filenamelook,".mp3"); /* add .mp3 so that the filename will be complete */
92
93 do {
94 char title[31]="", artist[31]="", album[31]="", year[5]="", comment[31]="", fbuf[4], newfilename[160]="",nieuw[150]="",dir[150]="",dirsource[200],fullline[228]="", burnname[29]="";
95 plaatsen = 0;
96
97 if ( !( fp=fopen(*argv,"rb+") ) ) /* If the file doesn exist */
98 {
99 perror("Error opening file");
100 ++argv; /* Prepare for the next file */
101 continue;
102 }
103
104 /* Lets check if we have a real mp3 file */
105
106 fread(sig,sizeof(sig),1,fp);
107 sig[0] &= 0xff;
108 sig[1] &= 0xf0;
109 if(!((sig[0] == 0xff) && (sig[1] == 0xf0)))
110 {
111 fprintf(stderr,"%s is not an MP3 file!\n",*argv);
112 fclose(fp);
113 ++argv;
114 continue;
115 }
116
117 /* Lets go to the beginning of the tag */
118 if ( fseek(fp, -128, SEEK_END ))
119 {
120 fclose(fp);
121 ++argv;
122 continue;
123 }
124
125 /* Lets see if we already have a id3 tag */
126 fread(fbuf,1,3,fp); fbuf[3] = '\0';
127 if (!strcmp("TAG",fbuf) && !forced)
128 {
129 fseek(fp, -125, SEEK_END);
130 fread(title,1,30,fp); title[30] = '\0';
131 fread(artist,1,30,fp); artist[30] = '\0';
132 fread(album,1,30,fp); album[30] = '\0';
133 fread(year,1,4,fp); year[4] = '\0';
134 fread(comment,1,30,fp); comment[30] = '\0';
135 fread(genre,1,1,fp);
136 fseek(fp, -128, SEEK_END); /* back to the beginning of the tag */
137 }
138 else
139 {
140 if (!strcmp("TAG",fbuf) ) /* go to the position to append one */
141 {
142 if(forced)
143 {
144 fseek(fp, -125, SEEK_END);
145 fread(title,1,30,fp); title[30] = '\0';
146 fread(artist,1,30,fp); artist[30] = '\0';
147 fread(album,1,30,fp); album[30] = '\0';
148 fread(year,1,4,fp); year[4] = '\0';
149 fread(comment,1,30,fp); comment[30] = '\0';
150 fread(genre,1,1,fp);
151 }
152 fseek(fp, -128, SEEK_END);
153 }
154 else
155 fseek(fp, 0, SEEK_END);
156 if(verbose || forced) /* Manual change of the name */
157 {
158 if(verbose)
159 printf("%s hasen't got a id3 tag. \n",*argv);
160 else
161 printf("%s:\n",*argv);
162 if(!all)
163 {
164 for( i=0 ; i!=(strlen(filenamelook)) ; i++)
165 {
166 p = 0;
167 if(filenamelook[i] == '&')
168 {
169 switch(filenamelook[i+1])
170 {
171 case 'a':
172 printf("Please enter the artist's name.\n");
173 do /* Lets get the artist */
174 {
175 input_char = getchar();
176 if (input_char != '\n' && p == 0)
177 strcpy(artist,"");
178 if (input_char != '\n' && input_char != EOF )
179 sprintf(artist,"%s%c",artist,input_char);
180 p++;
181 } while (input_char != '\n');
182 i++;
183 break;
184 case 't':
185 printf("Please enter the title.\n");
186 do /* Lets get the song title */
187 {
188 input_char = getchar();
189 if (input_char != '\n' && p == 0)
190 strcpy(title,"");
191 if (input_char != '\n' && input_char != EOF)
192 sprintf(title,"%s%c",title,input_char);
193 p++;
194 } while (input_char != '\n');
195 i++;
196 break;
197 case 'b':
198 printf("Please enter the album.\n");
199 do /* Lets get the album */
200 {
201 input_char = getchar();
202 if (input_char != '\n' && p == 0)
203 strcpy(album,"");
204 if (input_char != '\n' && input_char != EOF)
205 sprintf(album,"%s%c",album,input_char);
206 p++;
207 } while (input_char != '\n');
208 i++;
209 break;
210 case 'y':
211 printf("Please enter the year.\n");
212 do /* Lets get the year */
213 {
214 input_char = getchar();
215 if (input_char != '\n' && p == 0)
216 strcpy(year,"");
217 if (input_char != '\n' && input_char != EOF)
218 sprintf(year,"%s%c",year,input_char);
219 p++;
220 } while (input_char != '\n');
221 i++;
222 break;
223 default: /* the user has entered a character behind the & we don't know */
224 printf("Illegal char in config file please use the option '-s help' for more information");
225 exit(1);
226 }
227 }
228 }
229 }
230 else
231 {
232 p = 0;
233 printf("Please enter the artist's name.\n");
234 do /* Lets get the artist */
235 {
236 input_char = getchar();
237 if (input_char != '\n' && p == 0)
238 strcpy(artist,"");
239 if (input_char != '\n' && input_char != EOF )
240 sprintf(artist,"%s%c",artist,input_char);
241 p++;
242 } while (input_char != '\n');
243 p = 0;
244 printf("Please enter the title.\n");
245 do /* Lets get the song title */
246 {
247 input_char = getchar();
248 if (input_char != '\n' && p == 0)
249 strcpy(title,"");
250 if (input_char != '\n' && input_char != EOF)
251 sprintf(title,"%s%c",title,input_char);
252 p++;
253 } while (input_char != '\n');
254 i++;
255 p = 0;
256 printf("Please enter the album.\n");
257 do /* Lets get the album */
258 {
259 input_char = getchar();
260 if (input_char != '\n' && p == 0)
261 strcpy(album,"");
262 if (input_char != '\n' && input_char != EOF)
263 sprintf(album,"%s%c",album,input_char);
264 p++;
265 } while (input_char != '\n');
266 p = 0;
267 printf("Please enter the year.\n");
268 do /* Lets get the year */
269 {
270 input_char = getchar();
271 if (input_char != '\n' && p == 0)
272 strcpy(year,"");
273 if (input_char != '\n' && input_char != EOF)
274 sprintf(year,"%s%c",year,input_char);
275 p++;
276 } while (input_char != '\n');
277 }
278 }
279 else /* If we aren't in verbose or forced mode */
280 {
281 printf("%s hasen't got a id3 tag\n",*argv);
282 fclose(fp);
283 ++argv;
284 continue;
285 }
286
287 }
288
289 if(info == 1)
290 {
291 printf("Artist : %s\n",artist);
292 printf("Title : %s\n",title);
293 printf("Album : %s\n",album);
294 printf("Year : %s\n\n",year);
295 ++argv;
296 continue;
297 }
298
299 /* Remove trailing spaces */
300 i=strlen(artist)-1;
301 while (i && artist[i]==' ')
302 {
303 artist[i]='\0';
304 i--;
305 }
306
307 i=strlen(title)-1;
308 while (i && title[i]==' ')
309 {
310 title[i]='\0';
311 i--;
312 }
313 i=strlen(album)-1;
314 while (i && album[i]==' ')
315 {
316 album[i]='\0';
317 i--;
318 }
319 i=strlen(year)-1;
320 while (i && year[i]==' ')
321 {
322 year[i]='\0';
323 i--;
324 }
325
326 /* We go through the filenamelook until we find a &x combination
327 then we replace the &x with album/title/year/artis */
328 for( i=0 ; i!=(strlen(filenamelook)) ; i++)
329 {
330 if(filenamelook[i] == '&')
331 {
332 char tmp[100];
333 switch(filenamelook[i+1])
334 {
335 case 'a':
336 sprintf(tmp,"%s%s",newfilename,artist);
337 strcpy(newfilename,tmp);
338 i++;
339 break;
340 case 't':
341 sprintf(tmp,"%s%s",newfilename,title);
342 strcpy(newfilename,tmp);
343 i++;
344 break;
345 case 'b':
346 sprintf(tmp,"%s%s",newfilename,album);
347 strcpy(newfilename,tmp);
348 i++;
349 break;
350 case 'y':
351 sprintf(tmp,"%s%s",newfilename,year);
352 strcpy(newfilename,tmp);
353 i++;
354 break;
355 default:
356 printf("Illegal char in config file please use the option '-s help' for more information\n");
357 exit(1);
358
359 }
360 }
361 else /* otherwise we just print the character in the filenamelook in the newfilename */
362 {
363 char tmp[100];
364 sprintf(tmp,"%s%c",newfilename,filenamelook[i]);
365 strcpy(newfilename,tmp);
366 }
367 }
368
369 /* Lets find out what directory we are working in */
370
371 sprintf(dirsource,"%s",*argv);
372 i=strlen(dirsource)+1;
373 while (i>-1)
374 {
375 if(dirsource[i] == '/')
376 plaatsen = 1;
377 if(plaatsen)
378 dir[i] = dirsource[i];
379 else
380 dir[i] = '\0';
381 i--;
382 }
383
384 /* Build the new tag from the new names */
385
386 buildtag(fullline,title,artist,album,year,comment,genre);
387 fwrite(fullline,1,128,fp);
388
389 fclose(fp);
390
391 /* Lets catch illegal characters */
392 for (i=0; i < strlen(newfilename); i++)
393 {
394 switch (newfilename[i])
395 {
396 case '<': newfilename[i] = '[';
397 break;
398 case '>': newfilename[i] = ']';
399 break;
400 case '|': newfilename[i] = '_';
401 break;
402 case '/': newfilename[i] = '-';
403 break;
404 case '\\': newfilename[i]= '-';
405 break;
406 case '*': newfilename[i] = '_';
407 break;
408 case '?': newfilename[i] = '_';
409 break;
410 case ':': newfilename[i] = ';';
411 break;
412 case '"': newfilename[i] = '-';
413 break;
414 default: break;
415 }
416 }
417
418 /* Lets rename the file */
419 if(burn == 1) /* If burn is on the size */
420 { /* shouldn't be bigger than 32 chars including the .mp3 */
421 strncpy(burnname,newfilename,sizeof(burnname)-1);
422 sprintf(nieuw,"%s%s.mp3",dir,burnname);
423 }
424 else
425 {
426 sprintf(nieuw,"%s%s",dir,newfilename);
427 }
428 if(rename(*argv,nieuw))
429 printf("Error renaming %s\n",*argv);
430
431 ++argv; /* Prepare for the next */
432
433
434 } while (*argv);
435
436 return 0;
437 }
438
buildtag(char * buf,char * title,char * artist,char * album,char * year,char * comment,char * genre)439 void buildtag(char *buf, char *title, char *artist, char *album, char *year, char *comment, char *genre)
440 {
441
442 strcpy(buf,"TAG");
443 pad(title,30);
444 strncat(buf,title,30);
445 pad(artist,30);
446 strncat(buf,artist,30);
447 pad(album,30);
448 strncat(buf,album,30);
449 pad(year,4);
450 strncat(buf,year,4);
451 pad(comment,30);
452 strncat(buf,comment,30);
453 strncat(buf,genre,1);
454 }
455
pad(char * string,int length)456 void pad(char *string, int length)
457 {
458 int i;
459
460 i=strlen(string);
461 while(i<length)
462 {
463 string[i] = ' ';
464 i++;
465 }
466
467 string[i]='\0';
468 }
469
display_help()470 void display_help()
471 {
472 printf("Mp3rename 0.6\n\n");
473 printf("Options:\n");
474 printf("\t-f\t Force non id3 rename.\n");
475 printf("\t-v\t Verbose mode.\n");
476 printf("\t-h\t Display this help message.\n");
477 printf("\t-b\t Limit the file size to 32 chars.\n");
478 printf("\t-i\t Only show the id3tags.\n");
479 printf("\t-a\t Ask everything for the id3tag.\n\n");
480 printf("\t-s\t Set the default filename look.\n");
481 printf("\t \t for more help on this option: -s help\n\n");
482 printf("Sander Janssen <janssen@rendo.dekooi.nl>\n\n");
483
484 }
set_filename(int argc,char * argv[])485 void set_filename(int argc,char *argv[])
486 {
487 FILE *fp;
488 char str[100];
489
490 argv += 2;
491
492 if(*argv == NULL)
493 {
494 printf("No config format given\n\r");
495 return;
496 }
497
498 if(!strcmp(*argv,"help"))
499 {
500 printf("Mp3rename 0.6\n\n");
501 printf(" Use this option to set the default look of the file\n");
502 printf(" The information is saved in ~/.mp3rename\n");
503 printf(" You can use &t title, &b album, &y year and &a artist\n\n");
504 printf(" Example : mp3rename -s '(&a)-&t-&b'\n");
505 printf(" for (artist)-title-album.mp3\n\n");
506 return;
507 }
508 sprintf(str,"%s/.mp3rename",getenv("HOME"));
509
510 if ( !( fp=fopen(str,"w") ) )
511 {
512 printf("Error opening config file\n\r");
513 return;
514 }
515
516 if(!strcmp(*argv,""))
517 {
518 printf("No config format given\n\r");
519 return;
520 }
521 printf("Default is now set\n\n");
522
523 fprintf(fp,*argv);
524 fclose(fp);
525 }
526
527
528
529
530