1 /*
2 * This file has been modified for the cdrkit suite.
3 *
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
6 *
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
10 *
11 */
12
13 /* @(#)auinfo.c 1.23 04/03/01 Copyright 1998-2004 J. Schilling */
14 /*
15 * Copyright (c) 1998-2004 J. Schilling
16 */
17 /*
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2
20 * as published by the Free Software Foundation.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License along with
28 * this program; see the file COPYING. If not, write to the Free Software
29 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */
31
32 #include <mconfig.h>
33 #include <stdxlib.h>
34 #include <unixstd.h>
35 #include <statdefs.h>
36 #include <stdio.h>
37 #include <standard.h>
38 #include <strdefs.h>
39 #include <deflts.h>
40 #include <utypes.h>
41 #include <schily.h>
42
43 #include "cdtext.h"
44 #include "wodim.h"
45
46 extern int debug;
47 extern int xdebug;
48
49 BOOL auinfosize(char *name, track_t *trackp);
50 void auinfo(char *name, int track, track_t *trackp);
51 textptr_t *gettextptr(int track, track_t *trackp);
52 static char *savestr(char *name);
53 static char *readtag(char *name);
54 static char *readtstr(char *name);
55 void setmcn(char *mcn, track_t *trackp);
56 static void isrc_illchar(char *isrc, int c);
57 void setisrc(char *isrc, track_t *trackp);
58 void setindex(char *tindex, track_t *trackp);
59
60 #ifdef XXX
61 int
main(int argc,char * argv[])62 main(int argc, char *argv[])
63 {
64 /* auinfo("/etc/default/cdrecord");*/
65 /* auinfo("/mnt2/CD3/audio_01.inf");*/
66 auinfo("/mnt2/CD3/audio_01.wav");
67 }
68 #endif
69
70 BOOL
auinfosize(char * name,track_t * trackp)71 auinfosize(char *name, track_t *trackp)
72 {
73 const char *p;
74 const char *tlp;
75 struct stat sb;
76 long secs;
77 long nsamples;
78 Llong tracksize;
79
80 if (!is_audio(trackp))
81 return (FALSE);
82
83 if ((trackp->flags & TI_USEINFO) == 0)
84 return (FALSE);
85
86 if ((p = strrchr(name, '.')) == NULL)
87 return (FALSE);
88 if (!streql(p, ".inf") && !streql(p, ".INF"))
89 return (FALSE);
90
91 /*
92 * First check if a bad guy tries to call auinfosize()
93 * while STDIN_FILENO is a TTY.
94 */
95 if (isatty(STDIN_FILENO)) {
96 errmsgno(EX_BAD,
97 "WARNING: Stdin is connected to a terminal.\n");
98 return (FALSE);
99 }
100
101 if (stat(name, &sb) < 0) /* *.inf file not found */
102 return (FALSE);
103
104 if (sb.st_size > 10000) /* Too large for a *.inf file */
105 return (FALSE);
106
107 if (cfg_open(name) < 0) /* Cannot open *.inf file */
108 return (FALSE);
109
110 tlp = p = readtag("Tracklength");
111 if (p == NULL) { /* Tracklength= Tag not found */
112 errmsgno(EX_BAD,
113 "WARNING: %s does not contain a 'Tracklength=' tag.\n",
114 name);
115 cfg_close();
116 return (FALSE);
117 }
118
119 p = astol(p, &secs);
120 if (*p != '\0' && *p != ',') {
121 errmsgno(EX_BAD,
122 "WARNING: %s: 'Tracklength=' contains illegal parameter '%s'.\n",
123 name, tlp);
124 cfg_close();
125 return (FALSE);
126 }
127 if (*p == ',')
128 p++;
129 p = astol(p, &nsamples);
130 if (*p != '\0') {
131 errmsgno(EX_BAD,
132 "WARNING: %s: 'Tracklength=' contains illegal parameter '%s'.\n",
133 name, tlp);
134 cfg_close();
135 return (FALSE);
136 }
137 tracksize = (secs * 2352) + (nsamples * 4);
138 if (xdebug > 0) {
139 fprintf(stderr, "%s: Tracksize %lld bytes (%ld sectors, %ld samples)\n",
140 name, tracksize, secs, nsamples);
141 }
142 trackp->itracksize = tracksize;
143 cfg_close();
144 return (TRUE);
145 }
146
147 void
auinfo(char * name,int track,track_t * trackp)148 auinfo(char *name, int track, track_t *trackp)
149 {
150 char infname[1024];
151 char *p;
152 track_t *tp = &trackp[track];
153 textptr_t *txp;
154 long l;
155 long tno = -1;
156 BOOL isdao = !is_tao(&trackp[0]);
157
158 strncpy(infname, name, sizeof (infname)-1);
159 infname[sizeof (infname)-1] = '\0';
160 p = strrchr(infname, '.');
161 if (p != 0 && &p[4] < &name[sizeof (infname)]) {
162 strcpy(&p[1], "inf");
163 }
164
165 if (cfg_open(infname) == 0) {
166
167 p = readtstr("CDINDEX_DISCID");
168 p = readtag("CDDB_DISKID");
169
170 p = readtag("MCN");
171 if (p && *p) {
172 setmcn(p, &trackp[0]);
173 txp = gettextptr(0, trackp); /* MCN is isrc for trk 0*/
174 txp->tc_isrc = savestr(p);
175 }
176
177 p = readtag("ISRC");
178 if (p && *p) {
179 setisrc(p, &trackp[track]);
180 txp = gettextptr(track, trackp);
181 txp->tc_isrc = savestr(p);
182 }
183
184 p = readtstr("Albumperformer");
185 if (p && *p) {
186 txp = gettextptr(0, trackp); /* Album perf. in trk 0*/
187 txp->tc_performer = savestr(p);
188 }
189 p = readtstr("Performer");
190 if (p && *p) {
191 txp = gettextptr(track, trackp);
192 txp->tc_performer = savestr(p);
193 }
194 p = readtstr("Albumtitle");
195 if (p && *p) {
196 txp = gettextptr(0, trackp); /* Album title in trk 0*/
197 txp->tc_title = savestr(p);
198 }
199 p = readtstr("Tracktitle");
200 if (p && *p) {
201 txp = gettextptr(track, trackp);
202 txp->tc_title = savestr(p);
203 }
204 p = readtstr("Songwriter");
205 if (p && *p) {
206 txp = gettextptr(track, trackp);
207 txp->tc_songwriter = savestr(p);
208 }
209 p = readtstr("Composer");
210 if (p && *p) {
211 txp = gettextptr(track, trackp);
212 txp->tc_composer = savestr(p);
213 }
214 p = readtstr("Arranger");
215 if (p && *p) {
216 txp = gettextptr(track, trackp);
217 txp->tc_arranger = savestr(p);
218 }
219 p = readtstr("Message");
220 if (p && *p) {
221 txp = gettextptr(track, trackp);
222 txp->tc_message = savestr(p);
223 }
224 p = readtstr("Diskid");
225 if (p && *p) {
226 txp = gettextptr(0, trackp); /* Disk id is in trk 0*/
227 txp->tc_title = savestr(p);
228 }
229 p = readtstr("Closed_info");
230 if (p && *p) {
231 txp = gettextptr(track, trackp);
232 txp->tc_closed_info = savestr(p);
233 }
234
235 p = readtag("Tracknumber");
236 if (p && isdao)
237 astol(p, &tno);
238
239 p = readtag("Trackstart");
240 if (p && isdao) {
241 l = -1L;
242 astol(p, &l);
243 if (track == 1 && tno == 1 && l > 0) {
244 trackp[1].pregapsize = 150 + l;
245 printf("Track1 Start: '%s' (%ld)\n", p, l);
246 }
247 }
248
249 p = readtag("Tracklength");
250
251 p = readtag("Pre-emphasis");
252 if (p && *p) {
253 if (strncmp(p, "yes", 3) == 0) {
254 tp->flags |= TI_PREEMP;
255 if ((tp->tracktype & TOC_MASK) == TOC_DA)
256 tp->sectype = SECT_AUDIO_PRE;
257
258 } else if (strncmp(p, "no", 2) == 0) {
259 tp->flags &= ~TI_PREEMP;
260 if ((tp->tracktype & TOC_MASK) == TOC_DA)
261 tp->sectype = SECT_AUDIO_NOPRE;
262 }
263 }
264
265 p = readtag("Channels");
266 p = readtag("Copy_permitted");
267 if (p && *p) {
268 /*
269 * -useinfo always wins
270 */
271 tp->flags &= ~(TI_COPY|TI_SCMS);
272
273 if (strncmp(p, "yes", 3) == 0)
274 tp->flags |= TI_COPY;
275 else if (strncmp(p, "no", 2) == 0)
276 tp->flags |= TI_SCMS;
277 else if (strncmp(p, "once", 2) == 0)
278 tp->flags &= ~(TI_COPY|TI_SCMS);
279 }
280 p = readtag("Endianess");
281 p = readtag("Index");
282 if (p && *p && isdao)
283 setindex(p, &trackp[track]);
284
285 p = readtag("Index0");
286 if (p && isdao) {
287 Llong ts;
288 Llong ps;
289
290 l = -2L;
291 astol(p, &l);
292 if (l == -1) {
293 trackp[track+1].pregapsize = 0;
294 } else if (l > 0) {
295 ts = tp->itracksize / tp->isecsize;
296 ps = ts - l;
297 if (ps > 0)
298 trackp[track+1].pregapsize = ps;
299 }
300 }
301 }
302
303 }
304
305 textptr_t *
gettextptr(int track,track_t * trackp)306 gettextptr(int track, track_t *trackp)
307 {
308 register textptr_t *txp;
309
310 txp = (textptr_t *)trackp[track].text;
311 if (txp == NULL) {
312 txp = malloc(sizeof (textptr_t));
313 if (txp == NULL)
314 comerr("Cannot malloc CD-Text structure.\n");
315 fillbytes(txp, sizeof (textptr_t), '\0');
316 trackp[track].text = txp;
317 }
318 return (txp);
319 }
320
321 static char *
savestr(char * str)322 savestr(char *str)
323 {
324 char *ret;
325
326 ret = malloc(strlen(str)+1);
327 if (ret)
328 strcpy(ret, str);
329 else
330 comerr("Cannot malloc auinfo string.\n");
331 return (ret);
332 }
333
334 static char *
readtag(char * name)335 readtag(char *name)
336 {
337 register char *p;
338
339 p = cfg_get(name);
340 if (debug)
341 printf("%s '%s'\n", name, p);
342 return (p);
343 }
344
345 static char *
readtstr(char * name)346 readtstr(char *name)
347 {
348 register char *p;
349 register char *p2;
350
351 p = readtag(name);
352 if (p && *p == '\'') {
353 p2 = ++p;
354 while (*p2 != '\0')
355 p2++;
356 while (p2 > p && *p2 != '\'')
357 p2--;
358 *p2 = '\0';
359 if (debug)
360 printf("%s '%s'\n", name, p);
361 }
362 return (p);
363 }
364
365 /*
366 * Media catalog number is a 13 digit number.
367 */
368 void
setmcn(char * mcn,track_t * trackp)369 setmcn(char *mcn, track_t *trackp)
370 {
371 register char *p;
372
373 if (strlen(mcn) != 13)
374 comerrno(EX_BAD, "MCN '%s' has illegal length.\n", mcn);
375
376 for (p = mcn; *p; p++) {
377 if (*p < '0' || *p > '9')
378 comerrno(EX_BAD, "MCN '%s' contains illegal character '%c'.\n", mcn, *p);
379 }
380 p = malloc(14);
381 strcpy(p, mcn);
382 trackp->isrc = p;
383
384 if (debug)
385 printf("Track %d MCN: '%s'\n", (int)trackp->trackno, trackp->isrc);
386 }
387
388 static char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
389
390 static void
isrc_illchar(char * isrc,int c)391 isrc_illchar(char *isrc, int c)
392 {
393 errmsgno(EX_BAD, "ISRC '%s' contains illegal character '%c'.\n", isrc, c);
394 }
395
396 /*
397 * ISRC is 12 Byte:
398 *
399 * Country code 'C' (alpha) 2 Bytes
400 * Owner code 'O' (alphanumeric) 3 Bytes
401 * Year of record 'Y' (numeric) 2 Bytes
402 * Serial number 'S' (numeric) 5 Bytes
403 *
404 * CC-OOO-YY-SSSSS
405 */
406 void
setisrc(char * isrc,track_t * trackp)407 setisrc(char *isrc, track_t *trackp)
408 {
409 char ibuf[13];
410 char *ip;
411 char *p;
412 int i;
413 int len;
414
415 if ((len = strlen(isrc)) != 12) {
416 for (p = isrc, i = 0; *p; p++) {
417 if (*p == '-')
418 i++;
419 }
420 if (((len - i) != 12) || i > 3)
421 comerrno(EX_BAD, "ISRC '%s' has illegal length.\n", isrc);
422 }
423
424 /*
425 * The country code.
426 */
427 for (p = isrc, ip = ibuf, i = 0; i < 2; p++, i++) {
428 *ip++ = *p;
429 if (!strchr(upper, *p)) {
430 /* goto illchar;*/
431 /*
432 * Flag numbers but accept them.
433 */
434 isrc_illchar(isrc, *p);
435 if (*p >= '0' && *p <= '9')
436 continue;
437 exit(EX_BAD);
438 }
439 }
440 if (*p == '-')
441 p++;
442
443 /*
444 * The owner code.
445 */
446 for (i = 0; i < 3; p++, i++) {
447 *ip++ = *p;
448 if (strchr(upper, *p))
449 continue;
450 if (*p >= '0' && *p <= '9')
451 continue;
452 goto illchar;
453 }
454 if (*p == '-')
455 p++;
456
457 /*
458 * The Year and the recording number (2 + 5 numbers).
459 */
460 for (i = 0; i < 7; p++, i++) {
461 *ip++ = *p;
462 if (*p >= '0' && *p <= '9')
463 continue;
464 if (*p == '-' && i == 2) {
465 ip--;
466 i--;
467 continue;
468 }
469 goto illchar;
470 }
471 *ip = '\0';
472 p = malloc(13);
473 strcpy(p, ibuf);
474 trackp->isrc = p;
475
476 if (debug)
477 printf("Track %d ISRC: '%s'\n", (int)trackp->trackno, trackp->isrc);
478 return;
479 illchar:
480 isrc_illchar(isrc, *p);
481 exit(EX_BAD);
482 }
483
484 void
setindex(char * tindex,track_t * trackp)485 setindex(char *tindex, track_t *trackp)
486 {
487 char *p;
488 int i;
489 int nindex;
490 long idx;
491 long *idxlist;
492
493 idxlist = malloc(100*sizeof (long));
494 p = tindex;
495 idxlist[0] = 0;
496 i = 0;
497 while (*p) {
498 p = astol(p, &idx);
499 if (*p != '\0' && *p != ' ' && *p != '\t' && *p != ',')
500 goto illchar;
501 i++;
502 if (i > 99)
503 comerrno(EX_BAD, "Too many indices for track %d\n", (int)trackp->trackno);
504 idxlist[i] = idx;
505 if (*p == ',')
506 p++;
507 while (*p == ' ' || *p == '\t')
508 p++;
509 }
510 nindex = i;
511
512 if (debug)
513 printf("Track %d %d Index: '%s'\n", (int)trackp->trackno, i, tindex);
514
515 if (debug) {
516 for (i = 0; i <= nindex; i++)
517 printf("%d: %ld\n", i, idxlist[i]);
518 }
519
520 trackp->nindex = nindex;
521 trackp->tindex = idxlist;
522 return;
523 illchar:
524 comerrno(EX_BAD, "Index '%s' contains illegal character '%c'.\n", tindex, *p);
525 }
526