/* Code to get discid for a cddb query. *** FreeBSD Version *** $Id: discid.c,v 1.3 2001/04/14 17:55:24 jzawodn Exp proclus $ Copyright (c) 1998-2000 Jeremy D. Zawodny FreeBSD patch from: "NetForce" This software is covered by the GPL. Is is based on code found in: To: code-review@azure.humbug.org.au Subject: CDDB database reader From: Byron Ellacott Date: Fri, 5 Jun 1998 17:32:40 +1000 */ /* Stripped net code, 'cause I only care about the discid */ #include #include #include #include #include #include #include #include #include #include #include struct toc { int min, sec, frame; } cdtoc[100]; int read_toc(void) { int drive = open("/dev/acd0c", O_RDONLY | O_NONBLOCK); struct ioc_toc_header tochdr; struct ioc_read_toc_single_entry tocentry; int i; ioctl(drive, CDIOREADTOCHEADER, &tochdr); for (i = tochdr.starting_track; i <= tochdr.ending_track; i++) { tocentry.track = i; tocentry.address_format = CD_MSF_FORMAT; ioctl(drive, CDIOREADTOCENTRY, &tocentry); cdtoc[i-1].min = tocentry.entry.addr.msf.minute; cdtoc[i-1].sec = tocentry.entry.addr.msf.second; cdtoc[i-1].frame = tocentry.entry.addr.msf.frame; cdtoc[i-1].frame += cdtoc[i-1].min*60*75; cdtoc[i-1].frame += cdtoc[i-1].sec*75; } tocentry.track = 0xAA; tocentry.address_format = CD_MSF_FORMAT; ioctl(drive, CDIOREADTOCENTRY, &tocentry); cdtoc[tochdr.ending_track].min = tocentry.entry.addr.msf.minute; cdtoc[tochdr.ending_track].sec = tocentry.entry.addr.msf.second; cdtoc[tochdr.ending_track].frame = tocentry.entry.addr.msf.frame; cdtoc[tochdr.ending_track].frame += cdtoc[tochdr.ending_track].min*60*75; cdtoc[tochdr.ending_track].frame += cdtoc[tochdr.ending_track].sec*75; close(drive); return tochdr.ending_track; } unsigned int cddb_sum(int n) { unsigned int ret; ret = 0; while (n > 0) { ret += (n % 10); n /= 10; } return ret; } unsigned long cddb_discid(int tot_trks) { unsigned int i, t = 0, n = 0; i = 0; while (i < tot_trks) { n = n + cddb_sum((cdtoc[i].min * 60) + cdtoc[i].sec); i++; } t = ((cdtoc[tot_trks].min * 60) + cdtoc[tot_trks].sec) - ((cdtoc[0].min * 60) + cdtoc[0].sec); return ((n % 0xff) << 24 | t << 8 | tot_trks); } int main(void) { unsigned long discid; int tracks, i; tracks = read_toc(); discid = cddb_discid(tracks); printf("%08x %d", discid, tracks); for (i = 0; i < tracks; i++) printf(" %d", cdtoc[i].frame); printf(" %d\n", (cdtoc[tracks].frame)/75); printf("\n"); exit(0); }