#include #include #include #include #include #include struct toc { int min; int sec; int frame; }; struct toc cdtoc[100]; int cdrom_read_tochdr(int cdrom_fd, struct ioc_toc_header *tochdr) { if (cdrom_fd == -1) return(-1); if (ioctl(cdrom_fd, CDIOREADTOCHEADER, (char *) tochdr) == -1) { perror("ioctl(cdromreadtochdr): "); return(-1); } return(0); } int cdrom_read_tocentry(int cdrom_fd, unsigned int track, struct cd_toc_entry *data) { struct ioc_read_toc_entry tocentry; if (cdrom_fd == -1) return(-1); tocentry.starting_track = (unsigned char)track; tocentry.address_format = CD_MSF_FORMAT; tocentry.data_len = sizeof(struct cd_toc_entry); tocentry.data = data; if (ioctl(cdrom_fd, CDIOREADTOCENTRYS, (char *) &tocentry) == -1) { perror("ioctl(cdromreadtocentry)"); return(-1); } return(0); } int read_cdtoc_from_drive(void) { /* Do whatever is appropriate to read the TOC of the CD * * into the cdtoc[] structure array. * */ int cdrom; int tot_trks,i; struct ioc_toc_header toc_header; struct cd_toc_entry toc_entry; if ((cdrom = open("/dev/cd0d", O_RDONLY, NULL)) < 0) { printf("could not open cd device\n"); exit(1); } cdrom_read_tochdr(cdrom, &toc_header); tot_trks = toc_header.ending_track; #ifdef DEBUG printf("start track: %d end track: %d len: %d\n",toc_header.starting_track, toc_header.ending_track, toc_header.len); printf("total number of tracks: %d\n",tot_trks); #endif for ( i = toc_header.starting_track ; i <= toc_header.ending_track ; i++ ) { cdrom_read_tocentry(cdrom, i, &toc_entry); #ifdef DEBUG printf("track: %d - %dm %ds %df\n",i,toc_entry.addr.msf.minute,toc_entry.addr.msf.second,toc_entry.addr.msf.frame); #endif cdtoc[i-1].min = toc_entry.addr.msf.minute; cdtoc[i-1].sec = toc_entry.addr.msf.second; cdtoc[i-1].frame = toc_entry.addr.msf.frame; cdtoc[i-1].frame += cdtoc[i-1].min*60*75; cdtoc[i-1].frame += cdtoc[i-1].sec*75; } cdrom_read_tocentry(cdrom, 0xAA, &toc_entry); cdtoc[toc_header.ending_track].min = toc_entry.addr.msf.minute; cdtoc[toc_header.ending_track].sec = toc_entry.addr.msf.second; cdtoc[toc_header.ending_track].frame = toc_entry.addr.msf.frame; cdtoc[toc_header.ending_track].frame += cdtoc[toc_header.ending_track].min*60*75; cdtoc[toc_header.ending_track].frame += cdtoc[toc_header.ending_track].sec*75; #ifdef DEBUG printf("leadout %d - %dm %ds %df\n",toc_header.ending_track,toc_entry.addr.msf.minute,toc_entry.addr.msf.second,toc_entry.addr.msf.frame); #endif return (tot_trks); } int cddb_sum(int n) { int ret; /* For backward compatibility this algorithm must not change */ ret = 0; while (n > 0) { ret = ret + (n % 10); n = n / 10; } return (ret); } unsigned long cddb_discid(int tot_trks) { int i, t = 0, n = 0; /* For backward compatibility this algorithm must not change */ 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); } main() { int tot_trks,i; tot_trks = read_cdtoc_from_drive(); printf("%08x %d",cddb_discid(tot_trks),tot_trks); for (i = 0; i < tot_trks; i++) printf(" %d", cdtoc[i].frame); printf(" %d\n", (cdtoc[tot_trks].frame-cdtoc[0].frame)/75); printf("\n"); exit(0); }