#include #include #include #include #include #include struct vcdsector { u_char sync[12]; u_char header[4]; u_char subheader[8]; u_char data[2324]; u_char spare[4]; }; main(int argc, char **argv) { int fd; struct ioc_toc_header th; struct ioc_read_toc_entry te; struct cd_toc_entry *cte; struct ioc_read_cd rc; struct vcdsector sec; u_long start, end, i, s, e; int track, ntracks; int c; char *devf; start = end = 0; devf = "/dev/rwcd0c"; while ((c = getopt(argc, argv, "s:e:f:")) != EOF) { switch (c) { case 's': start = atoi(optarg); break; case 'e': end = atoi(optarg); break; case 'f': devf = optarg; break; case '?': default: fprintf(stderr, "usage: vcdread [-f device] track\n"); exit(1); } } argc -= optind; argv += optind; track = atoi(argv[0]); fd = open(devf, O_RDONLY); if (fd < 0) { perror("open"); exit(-1); } if (ioctl(fd, CDIOREADTOCHEADER, &th) < 0) { perror("CDIOREADTOCHEADER"); exit(-1); } ntracks = th.ending_track - th.starting_track + 2; cte = (struct cd_toc_entry *)malloc(sizeof(*cte) * ntracks); te.address_format = CD_LBA_FORMAT; te.starting_track = 0; te.data_len = ntracks * sizeof(struct cd_toc_entry); te.data = cte; if (ioctl(fd, CDIOREADTOCENTRYS, &te) < 0) { perror("CDIOREADTOCENTRYS"); exit(-1); } s = ntohl(cte[track-th.starting_track].addr.lba); e = ntohl(cte[track+1-th.starting_track].addr.lba); fprintf(stderr, "track %d of %d-%d: sector %d - %d\n", track, th.starting_track, th.ending_track, s, e - 1); if (start == 0) start = s; if (end == 0) end = e; for (i = start; i < end; i++) { rc.data_type = CDDATA_ANY; rc.address_format = CD_LBA_FORMAT; rc.address.lba = i; rc.nframes = 1; rc.buffer = (u_char *)&sec; if (ioctl(fd, CDIOCREADCD, &rc) < 0) { perror("read cd"); break; } write(1, sec.data, 2324); } close(fd); }