/* * simple media event poller for cdroms implementing the GET_EVENT * interface * * Copyright (C) 2001 Jens Axboe */ #include #include #include #include #include #include #include #define INIT_CGC(cgc) memset((cgc), 0, sizeof(struct cdrom_generic_command)) void dump_cgc(struct cdrom_generic_command *cgc) { struct request_sense *sense = cgc->sense; int i; printf("cdb: "); for (i = 0; i < 12; i++) printf("%02x ", cgc->cmd[i]); printf("\n"); printf("buffer (%d): ", cgc->buflen); for (i = 0; i < cgc->buflen; i++) printf("%02x ", cgc->buffer[i]); printf("\n"); if (!sense) return; printf("sense: %02x.%02x.%02x\n", sense->sense_key, sense->asc, sense->ascq); } int wait_cmd(int fd, struct cdrom_generic_command *cgc, void *buffer, int len, int ddir, int timeout) { struct request_sense sense; int ret; memset(&sense, 0, sizeof(sense)); cgc->timeout = timeout; cgc->buffer = buffer; cgc->buflen = len; cgc->data_direction = ddir; cgc->sense = &sense; cgc->quiet = 1; ret = ioctl(fd, CDROM_SEND_PACKET, cgc); if (ret == -1) { perror("ioctl"); dump_cgc(cgc); } return ret; } int get_media_event(int fd) { struct cdrom_generic_command cgc; unsigned char buffer[8]; int ret; INIT_CGC(&cgc); memset(buffer, 0, sizeof(buffer)); cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION; cgc.cmd[1] = 1; cgc.cmd[4] = 16; cgc.cmd[8] = sizeof(buffer); ret = wait_cmd(fd, &cgc, buffer, sizeof(buffer), CGC_DATA_READ, 600); if (ret < 0) { perror("GET_EVENT"); return ret; } return buffer[4] & 0xf; } int poll_events(int fd) { int event, quit, first; quit = 0; first = 1; do { event = get_media_event(fd); if (event < 0) break; switch (event) { case 0: if (first) printf("no media change\n"); break; case 1: printf("eject request\n"); break; case 2: printf("new media\n"); break; case 3: printf("media removal\n"); break; case 4: printf("media change\n"); break; default: printf("unknown media event (%d)\n", event); break; } first = 0; if (event) continue; sleep(2); } while (!quit); return event; } int main(int argc, char *argv[]) { int fd; fd = open("/dev/cdrom", O_RDONLY | O_NONBLOCK); if (fd == -1) { perror("open"); return 1; } return poll_events(fd); }