int mb_disc_read_unportable(mb_disc_private *disc, const char *device) { int fd; unsigned long lba; int first, last; int i; if ( (fd = open(device, O_RDONLY | O_NONBLOCK)) < 0 ) { snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH, "cannot open device `%s'", device); return 0; } /* * Find the numbers of the first track (usually 1) and the last track. */ if ( read_toc_header(fd, &first, &last) < 0 ) { snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH, "cannot read table of contents"); close(fd); return 0; } /* basic error checking */ if ( last == 0 ) { snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH, "this disc has no tracks"); close(fd); return 0; } disc->first_track_num = first; disc->last_track_num = last; /* * Get the logical block address (lba) for the end of the audio data. * The "LEADOUT" track is the track beyond the final audio track, so * we're looking for the block address of the LEADOUT track. */ read_leadout(fd, &lba); disc->track_offsets[0] = lba + 150; /* * Now, for every track, find out the block address where it starts. */ for (i = first; i <= last; i++) { read_toc_entry(fd, i, &lba); disc->track_offsets[i] = lba + 150; } close(fd); return 1; }
static int read_leadout(int fd, unsigned long *lba) { struct cdrom_multisession ms; int ret; ms.addr_format = CDROM_LBA; ret = ioctl(fd, CDROMMULTISESSION, &ms); if ( ms.xa_flag ) { *lba = ms.addr.lba - XA_INTERVAL; return ret; } return read_toc_entry(fd, CDROM_LEADOUT, lba); }
static int read_leadout(int fd, unsigned long *lba) { struct ioc_toc_header th; struct ioc_read_toc_single_entry te; int ret; ret = ioctl(fd, CDIOREADTOCHEADER, &th); te.track = th.ending_track; te.address_format = CD_LBA_FORMAT; ret = ioctl(fd, CDIOREADTOCENTRY, &te); if (( te.entry.control & CD_DATA_TRACK) != 0 ) { *lba = ntohl(te.entry.addr.lba) - 11400; return ret; } return read_toc_entry(fd, CD_LEADOUT, lba); }
static int read_leadout(int fd, unsigned long *lba) { int ret; unsigned long ms_offset; struct cdrom_tocentry te; te.cdte_track = 1; te.cdte_format = CDROM_LBA; ret = ioctl(fd, CDROMREADTOCENTRY, &te); ret = ioctl(fd, CDROMREADOFFSET, &ms_offset); if ( ms_offset != te.cdte_addr.lba ) { *lba = ms_offset - XA_INTERVAL; return ret; } return read_toc_entry(fd, CDROM_LEADOUT, lba); }