static PyObject * CD_open(PyObject *self, PyObject *args) { char *dev, *direction; CDPLAYER *cdp; /* * Variable number of args. * First defaults to "None", second defaults to "r". */ dev = NULL; direction = "r"; if (!PyArg_ParseTuple(args, "|zs:open", &dev, &direction)) return NULL; cdp = CDopen(dev, direction); if (cdp == NULL) { PyErr_SetFromErrno(CdError); return NULL; } return newcdplayerobject(cdp); }
int main(int argc, char *argv[]) { int len; int i, totaltime; long int cksum = 0; int musicbrainz = 0; unsigned char last = 1; char *devicename = DEVICE_NAME; struct cdrom_tocentry *TocEntry; #ifndef __sgi int drive; struct cdrom_tochdr hdr; #else CDPLAYER *drive; CDTRACKINFO info; cdrom_tochdr hdr; #endif char *command = argv[0]; #if defined(__OpenBSD__) || defined(__NetBSD__) struct ioc_read_toc_entry t; #elif defined(__APPLE__) dk_cd_read_disc_info_t discInfoParams; #endif if (argc == 2 && !strcmp(argv[1], "--help")) { usage(); exit(EXIT_SUCCESS); } if (argc == 2 && !strcmp(argv[1], "--version")) { fprintf(stderr, "cd-discid %s.\n", VERSION); exit(EXIT_SUCCESS); } if (argc >= 2 && !strcmp(argv[1], "--musicbrainz")) { musicbrainz = 1; argc--; argv++; } if (argc == 2) devicename = argv[1]; else if (argc > 2) { usage(); exit(EXIT_FAILURE); } #if defined(__sgi) drive = CDopen(devicename, "r"); if (drive == 0) { #else drive = open(devicename, O_RDONLY | O_NONBLOCK); if (drive < 0) { #endif fprintf(stderr, "%s: %s: ", command, devicename); perror("open"); exit(EXIT_FAILURE); } #if defined(__APPLE__) memset(&discInfoParams, 0, sizeof(discInfoParams)); discInfoParams.buffer = &hdr; discInfoParams.bufferLength = sizeof(hdr); if (ioctl(drive, DKIOCCDREADDISCINFO, &discInfoParams) < 0 || discInfoParams.bufferLength != sizeof(hdr)) { fprintf(stderr, "%s: %s: ", command, devicename); perror("DKIOCCDREADDISCINFO"); exit(EXIT_FAILURE); } #elif defined(__sgi) if (CDgetstatus(drive, &hdr) == 0) { perror("CDROMREADTOCHDR"); exit(EXIT_FAILURE); } #else if (ioctl(drive, CDROMREADTOCHDR, &hdr) < 0) { fprintf(stderr, "%s: %s: ", command, devicename); perror("CDROMREADTOCHDR"); exit(EXIT_FAILURE); } #endif last = hdr.cdth_trk1; len = (last + 1) * sizeof(struct cdrom_tocentry); TocEntry = malloc(len); if (!TocEntry) { fprintf(stderr, "%s: %s: Can't allocate memory for TOC entries\n", command, devicename); exit(EXIT_FAILURE); } #if defined(__OpenBSD__) t.starting_track = 0; #elif defined(__NetBSD__) t.starting_track = 1; #endif #if defined(__OpenBSD__) || defined(__NetBSD__) t.address_format = CDROM_LBA; t.data_len = len; t.data = TocEntry; memset(TocEntry, 0, len); if (ioctl(drive, CDIOREADTOCENTRYS, (char*)&t) < 0) { fprintf(stderr, "%s: %s: ", command, devicename); perror("CDIOREADTOCENTRYS"); } #elif defined(__APPLE__) dk_cd_read_track_info_t trackInfoParams; memset(&trackInfoParams, 0, sizeof(trackInfoParams)); trackInfoParams.addressType = kCDTrackInfoAddressTypeTrackNumber; trackInfoParams.bufferLength = sizeof(*TocEntry); for (i = 0; i < last; i++) { trackInfoParams.address = i + 1; trackInfoParams.buffer = &TocEntry[i]; if (ioctl(drive, DKIOCCDREADTRACKINFO, &trackInfoParams) < 0) { fprintf(stderr, "%s: %s: ", command, devicename); perror("DKIOCCDREADTRACKINFO"); } } /* MacOS X on G5-based systems does not report valid info for * TocEntry[last-1].lastRecordedAddress + 1, so we compute the start * of leadout from the start+length of the last track instead */ TocEntry[last].cdte_track_address = htonl(ntohl(TocEntry[last-1].trackSize) + ntohl(TocEntry[last-1].trackStartAddress)); #elif defined(__sgi) for (i = 0; i < last; i++) { if (CDgettrackinfo(drive, i + 1, &info) == 0) { fprintf(stderr, "CDgettrackinfo failed on track %i: %s\n", i + 1, devicename); } TocEntry[i].cdte_track_address = info.start_min*60*CD_FRAMES + info.start_sec*CD_FRAMES + info.start_frame; } TocEntry[last].cdte_track_address = TocEntry[last - 1].cdte_track_address + info.total_min*60*CD_FRAMES + info.total_sec*CD_FRAMES + info.total_frame; #else /* FreeBSD, Linux, Solaris */ for (i = 0; i < last; i++) { /* tracks start with 1, but I must start with 0 on OpenBSD */ TocEntry[i].cdte_track = i + 1; TocEntry[i].cdte_format = CDROM_LBA; if (ioctl(drive, CDROMREADTOCENTRY, &TocEntry[i]) < 0) { fprintf(stderr, "%s: %s: ", command, devicename); perror("CDROMREADTOCENTRY"); } } TocEntry[last].cdte_track = CDROM_LEADOUT; TocEntry[last].cdte_format = CDROM_LBA; if (ioctl(drive, CDROMREADTOCENTRY, &TocEntry[i]) < 0) { fprintf(stderr, "%s: %s: ", command, devicename); perror("CDROMREADTOCENTRY"); } #endif /* release file handle */ close(drive); #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) TocEntry[i].cdte_track_address = ntohl(TocEntry[i].cdte_track_address); #endif for (i = 0; i < last; i++) { #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) TocEntry[i].cdte_track_address = ntohl(TocEntry[i].cdte_track_address); #endif cksum += cddb_sum((TocEntry[i].cdte_track_address + CD_MSF_OFFSET) / CD_FRAMES); } totaltime = ((TocEntry[last].cdte_track_address + CD_MSF_OFFSET) / CD_FRAMES) - ((TocEntry[0].cdte_track_address + CD_MSF_OFFSET) / CD_FRAMES); /* print discid */ if (!musicbrainz) printf("%08lx ", (cksum % 0xff) << 24 | totaltime << 8 | last); /* print number of tracks */ printf("%d", last); /* print frame offsets of all tracks */ for (i = 0; i < last; i++) printf(" %d", TocEntry[i].cdte_track_address + CD_MSF_OFFSET); if (musicbrainz) printf(" %d\n", TocEntry[last].cdte_track_address + CD_MSF_OFFSET); else /* print length of disc in seconds */ printf(" %d\n", (TocEntry[last].cdte_track_address + CD_MSF_OFFSET) / CD_FRAMES); free(TocEntry); return 0; }