/* Setcd.c: Set various flags to control the behaviour of your cdrom device. (c) 1997 David A. van Leeuwen $Id: setcd.c,v 1.1 1997/02/22 18:14:33 david Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include /* #include */ #include #include #define REVISION "$Revision: 1.1 $" void usage(FILE * f, char * s) { fprintf(f, "Usage: %s [-hirs] [-ceflot 0|1] [-dx arg] [device] ...\n\n\t" "-h print this message and copyright\n\t" "-i print information about cdrom device\n\t" "-s print status of cdrom device options\n\t" "-r reset option flags to preferred default\n\t" "-c * set auto-close flag: close tray if cdrom device is opened\n\t" "-e * set auto-eject/auto-close behaviour\n\t" "-f * use file flag O_NONBLOCK in open() call\n\t" "-l * lock door if cdrom device is opened\n\t" "-o * set auto_open flag: open tray if cdrom device is released\n\t" "-t * enable cdrom type checking (audio/data)\n\t" "-d n select disc number n in jukebox\n\t" "-x n set speed of cdrom n times 150 KB/s (normal audio)\n", s); } #define SHOW(bit, text) if(bit & mask) \ printf(" %-20s %s\n", text ":", (bit & flags) ? "set" : "cleared"); void print_options(int flags, int mask) { SHOW(CDO_AUTO_CLOSE, "Auto close tray"); SHOW(CDO_AUTO_EJECT, "Auto open tray"); SHOW(CDO_USE_FFLAGS, "Use O_NONBLOCK flag"); SHOW(CDO_LOCK, "Lock tray"); SHOW(CDO_CHECK_TYPE, "Check CD type"); } #undef SHOW void print_audio_info(int fd) { struct cdrom_tochdr head; struct cdrom_tocentry entry; int last, first; if (ioctl(fd, CDROMREADTOCHDR, &head)<0) { perror("Can't read Table of Contents header"); return; } last = head.cdth_trk1; first = head.cdth_trk0; printf(" %d Track%s, %d--%d\n", last-first+1, (last==first) ? "" : "s", first, last); entry.cdte_format=CDROM_MSF; entry.cdte_track = 0xAA; if (ioctl(fd, CDROMREADTOCENTRY, &entry)<0) { perror("can't read last track entry"); return; } printf(" Total playing time %d minutes and %d seconds\n", entry.cdte_addr.msf.minute, entry.cdte_addr.msf.second); } char * stripped(char * s, int size, int lower) { char *i, * end = s+size-1; while (*end == ' ') --end; if (end == s+size-1) *end='\0'; else *++end = '\0'; if (lower) for (i=s+1; iid, ISO_STANDARD_ID, sizeof vdp->id)) { /* found an iso-cdrom */ printf(" Volume name: %s\n", stripped(vdp->volume_id, 32, 1)); printf(" Publisher: %s\n", stripped(vdp->publisher_id, 128, 0)); printf(" Data preparer: %s\n", stripped(vdp->preparer_id, 128, 0)); break; } } } void print_info(int fd) { int status = ioctl(fd, CDROM_DRIVE_STATUS, 0); if (status<0) { perror("can't read drive status"); exit (-8); } switch(status) { case CDS_NO_INFO: printf(" No information on drive status is available\n"); break; case CDS_NO_DISC: printf(" No disc is inserted\n"); break; case CDS_TRAY_OPEN: printf(" CD tray is open\n"); break; case CDS_DRIVE_NOT_READY: printf(" Drive is not ready\n"); break; case CDS_DISC_OK: printf(" Disc found in drive:"); status=ioctl(fd, CDROM_DISC_STATUS); if (status < 0) break; switch (status) { case CDS_AUDIO: printf(" audio disc\n"); print_audio_info(fd); break; case CDS_DATA_1: case CDS_DATA_2: printf(" data disc type %d\n", status-CDS_DATA_1+1); print_data_info(fd); break; case CDS_XA_2_1: case CDS_XA_2_2: printf(" XA data disc type %d\n", status-CDS_XA_2_1+1); break; default: printf("\n"); } break; default: printf(" Unknow drive status return value %d\n", status); } } main(int ac, char ** av) { char * device = "/dev/cdrom"; int fd, c; int status=0, reset=0, info=0, typecheck=-1, speed=-1, auto_close=-1, auto_open=-1, fflags=-1, lock=-1, disc=-1; int set=0, clear=0, flags=0; FILE * errorfile = stderr; extern int optind, optopt; extern char * optarg; if (ac == 1) { usage(stderr, av[0]); exit(-1); } while((c=getopt(ac, av, "c:d:e:f:hil:o:rst:x:"))!=EOF) { switch(c) { case 'c': auto_close=atoi(optarg); break; case 'd': disc=atoi(optarg); break; case 'f': fflags=atoi(optarg); break; case 'e': auto_close=auto_open=atoi(optarg); break; case 'i': info=1; break; case 'l': lock=atoi(optarg); break; case 'o': auto_open=atoi(optarg); break; case 'r': reset=1; /* fall into next line */ case 's': status=1; break; case 't': typecheck=atoi(optarg); break; case 'x': speed=atoi(optarg); break; case 'h': printf("Setcd. Control the behaviour of a cdrom device.\n" "(c) 1997 David A. van Leeuwen\n" REVISION "\n\n"); usage(stdout, av[0]); exit(0); default: usage(stderr, av[0]); exit(-1); } } do { if (ac > optind) device = av[optind]; fd = open(device, O_RDONLY | O_NONBLOCK); if (fd < 0) { perror("Can't open device"); exit(-2); } printf("%s:\n", device); #define FLAG(i,opt) if (i>=0) { set += opt*(i>0); clear += opt*!i; } if (reset) { set = CDO_AUTO_CLOSE | CDO_USE_FFLAGS | CDO_LOCK | CDO_CHECK_TYPE; clear = CDO_AUTO_EJECT; /* nasty behaviour */ } FLAG(auto_close, CDO_AUTO_CLOSE); FLAG(auto_open, CDO_AUTO_EJECT); FLAG(fflags, CDO_USE_FFLAGS); FLAG(lock, CDO_LOCK); FLAG(typecheck, CDO_CHECK_TYPE); #undef FLAG if (set && (flags=ioctl(fd, CDROM_SET_OPTIONS, set))<0) { perror("can't set options"); exit(-3); } if (clear && (flags=ioctl(fd, CDROM_CLEAR_OPTIONS, clear))<0) { perror("can't clear options"); exit(-4); } if (!flags && status && (flags=ioctl(fd, CDROM_SET_OPTIONS, 0))<0) { perror("can't get options"); exit(-5); } if (set || clear || status) print_options(flags, set | clear | ~0 * status); if (speed>=0) { if (ioctl(fd, CDROM_SELECT_SPEED, speed)<0) { perror("can't set speed"); exit(-6); } else { printf(" Speed set at "); if (!speed) printf("maximum rate / normal audio rate\n"); else printf("%d KB/s (%dx)\n", 150*speed, speed); } } if (disc >= 0) { if ((disc=ioctl(fd, CDROM_SELECT_DISC, disc)) < 0) { perror("can't select disc"); exit(-7); } else printf(" Disc in slot %d selected\n", disc); } if (info) print_info(fd); close(fd); } while (ac > ++optind); } /* It was not easy to find variable `c-file-style' in emacs info. In fact, I found it in some other .c file. * Local variables: * c-file-style: "K&R" * compile-command: "make setcd" * End: */