diff options
Diffstat (limited to 'wodim/auinfo.c')
-rw-r--r-- | wodim/auinfo.c | 525 |
1 files changed, 525 insertions, 0 deletions
diff --git a/wodim/auinfo.c b/wodim/auinfo.c new file mode 100644 index 0000000..8cf8aef --- /dev/null +++ b/wodim/auinfo.c @@ -0,0 +1,525 @@ +/* + * This file has been modified for the cdrkit suite. + * + * The behaviour and appearence of the program code below can differ to a major + * extent from the version distributed by the original author(s). + * + * For details, see Changelog file distributed with the cdrkit package. If you + * received this file from another source then ask the distributing person for + * a log of modifications. + * + */ + +/* @(#)auinfo.c 1.23 04/03/01 Copyright 1998-2004 J. Schilling */ +/* + * Copyright (c) 1998-2004 J. Schilling + */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * 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; see the file COPYING. If not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <mconfig.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <statdefs.h> +#include <stdio.h> +#include <standard.h> +#include <strdefs.h> +#include <deflts.h> +#include <utypes.h> +#include <schily.h> + +#include "cdtext.h" +#include "wodim.h" + +extern int debug; +extern int xdebug; + +BOOL auinfosize(char *name, track_t *trackp); +void auinfo(char *name, int track, track_t *trackp); +textptr_t *gettextptr(int track, track_t *trackp); +static char *savestr(char *name); +static char *readtag(char *name); +static char *readtstr(char *name); +void setmcn(char *mcn, track_t *trackp); +static void isrc_illchar(char *isrc, int c); +void setisrc(char *isrc, track_t *trackp); +void setindex(char *tindex, track_t *trackp); + +#ifdef XXX +int +main(int argc, char *argv[]) +{ +/* auinfo("/etc/default/cdrecord");*/ +/* auinfo("/mnt2/CD3/audio_01.inf");*/ + auinfo("/mnt2/CD3/audio_01.wav"); +} +#endif + +BOOL +auinfosize(char *name, track_t *trackp) +{ + const char *p; + const char *tlp; + struct stat sb; + long secs; + long nsamples; + Llong tracksize; + + if (!is_audio(trackp)) + return (FALSE); + + if ((trackp->flags & TI_USEINFO) == 0) + return (FALSE); + + if ((p = strrchr(name, '.')) == NULL) + return (FALSE); + if (!streql(p, ".inf") && !streql(p, ".INF")) + return (FALSE); + + /* + * First check if a bad guy tries to call auinfosize() + * while STDIN_FILENO is a TTY. + */ + if (isatty(STDIN_FILENO)) { + errmsgno(EX_BAD, + "WARNING: Stdin is connected to a terminal.\n"); + return (FALSE); + } + + if (stat(name, &sb) < 0) /* *.inf file not found */ + return (FALSE); + + if (sb.st_size > 10000) /* Too large for a *.inf file */ + return (FALSE); + + if (cfg_open(name) < 0) /* Cannot open *.inf file */ + return (FALSE); + + tlp = p = readtag("Tracklength"); + if (p == NULL) { /* Tracklength= Tag not found */ + errmsgno(EX_BAD, + "WARNING: %s does not contain a 'Tracklength=' tag.\n", + name); + cfg_close(); + return (FALSE); + } + + p = astol(p, &secs); + if (*p != '\0' && *p != ',') { + errmsgno(EX_BAD, + "WARNING: %s: 'Tracklength=' contains illegal parameter '%s'.\n", + name, tlp); + cfg_close(); + return (FALSE); + } + if (*p == ',') + p++; + p = astol(p, &nsamples); + if (*p != '\0') { + errmsgno(EX_BAD, + "WARNING: %s: 'Tracklength=' contains illegal parameter '%s'.\n", + name, tlp); + cfg_close(); + return (FALSE); + } + tracksize = (secs * 2352) + (nsamples * 4); + if (xdebug > 0) { + fprintf(stderr, "%s: Tracksize %lld bytes (%ld sectors, %ld samples)\n", + name, tracksize, secs, nsamples); + } + trackp->itracksize = tracksize; + cfg_close(); + return (TRUE); +} + +void +auinfo(char *name, int track, track_t *trackp) +{ + char infname[1024]; + char *p; + track_t *tp = &trackp[track]; + textptr_t *txp; + long l; + long tno = -1; + BOOL isdao = !is_tao(&trackp[0]); + + strncpy(infname, name, sizeof (infname)-1); + infname[sizeof (infname)-1] = '\0'; + p = strrchr(infname, '.'); + if (p != 0 && &p[4] < &name[sizeof (infname)]) { + strcpy(&p[1], "inf"); + } + + if (cfg_open(infname) == 0) { + + p = readtstr("CDINDEX_DISCID"); + p = readtag("CDDB_DISKID"); + + p = readtag("MCN"); + if (p && *p) { + setmcn(p, &trackp[0]); + txp = gettextptr(0, trackp); /* MCN is isrc for trk 0*/ + txp->tc_isrc = savestr(p); + } + + p = readtag("ISRC"); + if (p && *p) { + setisrc(p, &trackp[track]); + txp = gettextptr(track, trackp); + txp->tc_isrc = savestr(p); + } + + p = readtstr("Albumperformer"); + if (p && *p) { + txp = gettextptr(0, trackp); /* Album perf. in trk 0*/ + txp->tc_performer = savestr(p); + } + p = readtstr("Performer"); + if (p && *p) { + txp = gettextptr(track, trackp); + txp->tc_performer = savestr(p); + } + p = readtstr("Albumtitle"); + if (p && *p) { + txp = gettextptr(0, trackp); /* Album title in trk 0*/ + txp->tc_title = savestr(p); + } + p = readtstr("Tracktitle"); + if (p && *p) { + txp = gettextptr(track, trackp); + txp->tc_title = savestr(p); + } + p = readtstr("Songwriter"); + if (p && *p) { + txp = gettextptr(track, trackp); + txp->tc_songwriter = savestr(p); + } + p = readtstr("Composer"); + if (p && *p) { + txp = gettextptr(track, trackp); + txp->tc_composer = savestr(p); + } + p = readtstr("Arranger"); + if (p && *p) { + txp = gettextptr(track, trackp); + txp->tc_arranger = savestr(p); + } + p = readtstr("Message"); + if (p && *p) { + txp = gettextptr(track, trackp); + txp->tc_message = savestr(p); + } + p = readtstr("Diskid"); + if (p && *p) { + txp = gettextptr(0, trackp); /* Disk id is in trk 0*/ + txp->tc_title = savestr(p); + } + p = readtstr("Closed_info"); + if (p && *p) { + txp = gettextptr(track, trackp); + txp->tc_closed_info = savestr(p); + } + + p = readtag("Tracknumber"); + if (p && isdao) + astol(p, &tno); + + p = readtag("Trackstart"); + if (p && isdao) { + l = -1L; + astol(p, &l); + if (track == 1 && tno == 1 && l > 0) { + trackp[1].pregapsize = 150 + l; + printf("Track1 Start: '%s' (%ld)\n", p, l); + } + } + + p = readtag("Tracklength"); + + p = readtag("Pre-emphasis"); + if (p && *p) { + if (strncmp(p, "yes", 3) == 0) { + tp->flags |= TI_PREEMP; + if ((tp->tracktype & TOC_MASK) == TOC_DA) + tp->sectype = SECT_AUDIO_PRE; + + } else if (strncmp(p, "no", 2) == 0) { + tp->flags &= ~TI_PREEMP; + if ((tp->tracktype & TOC_MASK) == TOC_DA) + tp->sectype = SECT_AUDIO_NOPRE; + } + } + + p = readtag("Channels"); + p = readtag("Copy_permitted"); + if (p && *p) { + /* + * -useinfo always wins + */ + tp->flags &= ~(TI_COPY|TI_SCMS); + + if (strncmp(p, "yes", 3) == 0) + tp->flags |= TI_COPY; + else if (strncmp(p, "no", 2) == 0) + tp->flags |= TI_SCMS; + else if (strncmp(p, "once", 2) == 0) + tp->flags &= ~(TI_COPY|TI_SCMS); + } + p = readtag("Endianess"); + p = readtag("Index"); + if (p && *p && isdao) + setindex(p, &trackp[track]); + + p = readtag("Index0"); + if (p && isdao) { + Llong ts; + Llong ps; + + l = -2L; + astol(p, &l); + if (l == -1) { + trackp[track+1].pregapsize = 0; + } else if (l > 0) { + ts = tp->itracksize / tp->isecsize; + ps = ts - l; + if (ps > 0) + trackp[track+1].pregapsize = ps; + } + } + } + +} + +textptr_t * +gettextptr(int track, track_t *trackp) +{ + register textptr_t *txp; + + txp = (textptr_t *)trackp[track].text; + if (txp == NULL) { + txp = malloc(sizeof (textptr_t)); + if (txp == NULL) + comerr("Cannot malloc CD-Text structure.\n"); + fillbytes(txp, sizeof (textptr_t), '\0'); + trackp[track].text = txp; + } + return (txp); +} + +static char * +savestr(char *str) +{ + char *ret; + + ret = malloc(strlen(str)+1); + if (ret) + strcpy(ret, str); + else + comerr("Cannot malloc auinfo string.\n"); + return (ret); +} + +static char * +readtag(char *name) +{ + register char *p; + + p = cfg_get(name); + if (debug) + printf("%s '%s'\n", name, p); + return (p); +} + +static char * +readtstr(char *name) +{ + register char *p; + register char *p2; + + p = readtag(name); + if (p && *p == '\'') { + p2 = ++p; + while (*p2 != '\0') + p2++; + while (p2 > p && *p2 != '\'') + p2--; + *p2 = '\0'; + if (debug) + printf("%s '%s'\n", name, p); + } + return (p); +} + +/* + * Media catalog number is a 13 digit number. + */ +void +setmcn(char *mcn, track_t *trackp) +{ + register char *p; + + if (strlen(mcn) != 13) + comerrno(EX_BAD, "MCN '%s' has illegal length.\n", mcn); + + for (p = mcn; *p; p++) { + if (*p < '0' || *p > '9') + comerrno(EX_BAD, "MCN '%s' contains illegal character '%c'.\n", mcn, *p); + } + p = malloc(14); + strcpy(p, mcn); + trackp->isrc = p; + + if (debug) + printf("Track %d MCN: '%s'\n", (int)trackp->trackno, trackp->isrc); +} + +static char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +static void +isrc_illchar(char *isrc, int c) +{ + errmsgno(EX_BAD, "ISRC '%s' contains illegal character '%c'.\n", isrc, c); +} + +/* + * ISRC is 12 Byte: + * + * Country code 'C' (alpha) 2 Bytes + * Owner code 'O' (alphanumeric) 3 Bytes + * Year of record 'Y' (numeric) 2 Bytes + * Serial number 'S' (numeric) 5 Bytes + * + * CC-OOO-YY-SSSSS + */ +void +setisrc(char *isrc, track_t *trackp) +{ + char ibuf[13]; + char *ip; + char *p; + int i; + int len; + + if ((len = strlen(isrc)) != 12) { + for (p = isrc, i = 0; *p; p++) { + if (*p == '-') + i++; + } + if (((len - i) != 12) || i > 3) + comerrno(EX_BAD, "ISRC '%s' has illegal length.\n", isrc); + } + + /* + * The country code. + */ + for (p = isrc, ip = ibuf, i = 0; i < 2; p++, i++) { + *ip++ = *p; + if (!strchr(upper, *p)) { +/* goto illchar;*/ + /* + * Flag numbers but accept them. + */ + isrc_illchar(isrc, *p); + if (*p >= '0' && *p <= '9') + continue; + exit(EX_BAD); + } + } + if (*p == '-') + p++; + + /* + * The owner code. + */ + for (i = 0; i < 3; p++, i++) { + *ip++ = *p; + if (strchr(upper, *p)) + continue; + if (*p >= '0' && *p <= '9') + continue; + goto illchar; + } + if (*p == '-') + p++; + + /* + * The Year and the recording number (2 + 5 numbers). + */ + for (i = 0; i < 7; p++, i++) { + *ip++ = *p; + if (*p >= '0' && *p <= '9') + continue; + if (*p == '-' && i == 2) { + ip--; + i--; + continue; + } + goto illchar; + } + *ip = '\0'; + p = malloc(13); + strcpy(p, ibuf); + trackp->isrc = p; + + if (debug) + printf("Track %d ISRC: '%s'\n", (int)trackp->trackno, trackp->isrc); + return; +illchar: + isrc_illchar(isrc, *p); + exit(EX_BAD); +} + +void +setindex(char *tindex, track_t *trackp) +{ + char *p; + int i; + int nindex; + long idx; + long *idxlist; + + idxlist = malloc(100*sizeof (long)); + p = tindex; + idxlist[0] = 0; + i = 0; + while (*p) { + p = astol(p, &idx); + if (*p != '\0' && *p != ' ' && *p != '\t' && *p != ',') + goto illchar; + i++; + if (i > 99) + comerrno(EX_BAD, "Too many indices for track %d\n", (int)trackp->trackno); + idxlist[i] = idx; + if (*p == ',') + p++; + while (*p == ' ' || *p == '\t') + p++; + } + nindex = i; + + if (debug) + printf("Track %d %d Index: '%s'\n", (int)trackp->trackno, i, tindex); + + if (debug) { + for (i = 0; i <= nindex; i++) + printf("%d: %ld\n", i, idxlist[i]); + } + + trackp->nindex = nindex; + trackp->tindex = idxlist; + return; +illchar: + comerrno(EX_BAD, "Index '%s' contains illegal character '%c'.\n", tindex, *p); +} |