void random_bytes(void *p, size_t n) {
        uint8_t *q;
        int r;

        r = dev_urandom(p, n);
        if (r >= 0)
                return;

        /* If some idiot made /dev/urandom unavailable to us, he'll
         * get a PRNG instead. */

        initialize_srand();

        for (q = p; q < (uint8_t*) p + n; q ++)
                *q = rand();
}
int main(int argc, char *argv[]) {
        struct udev *udev;
        static const struct option options[] = {
                { "lock-media", no_argument, NULL, 'l' },
                { "unlock-media", no_argument, NULL, 'u' },
                { "eject-media", no_argument, NULL, 'e' },
                { "debug", no_argument, NULL, 'd' },
                { "help", no_argument, NULL, 'h' },
                {}
        };
        bool eject = false;
        bool lock = false;
        bool unlock = false;
        const char *node = NULL;
        int fd = -1;
        int cnt;
        int rc = 0;

        log_set_target(LOG_TARGET_AUTO);
        udev_parse_config();
        log_parse_environment();
        log_open();

        udev = udev_new();
        if (udev == NULL)
                goto exit;

        for (;;) {
                int option;

                option = getopt_long(argc, argv, "deluh", options, NULL);
                if (option == -1)
                        break;

                switch (option) {
                case 'l':
                        lock = true;
                        break;
                case 'u':
                        unlock = true;
                        break;
                case 'e':
                        eject = true;
                        break;
                case 'd':
                        log_set_target(LOG_TARGET_CONSOLE);
                        log_set_max_level(LOG_DEBUG);
                        log_open();
                        break;
                case 'h':
                        printf("Usage: cdrom_id [options] <device>\n"
                               "  -l,--lock-media    lock the media (to enable eject request events)\n"
                               "  -u,--unlock-media  unlock the media\n"
                               "  -e,--eject-media   eject the media\n"
                               "  -d,--debug         debug to stderr\n"
                               "  -h,--help          print this help text\n\n");
                        goto exit;
                default:
                        rc = 1;
                        goto exit;
                }
        }

        node = argv[optind];
        if (!node) {
                log_error("no device");
                fprintf(stderr, "no device\n");
                rc = 1;
                goto exit;
        }

        initialize_srand();
        for (cnt = 20; cnt > 0; cnt--) {
                struct timespec duration;

                fd = open(node, O_RDONLY|O_NONBLOCK|O_CLOEXEC|(is_mounted(node) ? 0 : O_EXCL));
                if (fd >= 0 || errno != EBUSY)
                        break;
                duration.tv_sec = 0;
                duration.tv_nsec = (100 * 1000 * 1000) + (rand() % 100 * 1000 * 1000);
                nanosleep(&duration, NULL);
        }
        if (fd < 0) {
                log_debug("unable to open '%s'", node);
                fprintf(stderr, "unable to open '%s'\n", node);
                rc = 1;
                goto exit;
        }
        log_debug("probing: '%s'", node);

        /* same data as original cdrom_id */
        if (cd_capability_compat(udev, fd) < 0) {
                rc = 1;
                goto exit;
        }

        /* check for media - don't bail if there's no media as we still need to
         * to read profiles */
        cd_media_compat(udev, fd);

        /* check if drive talks MMC */
        if (cd_inquiry(udev, fd) < 0)
                goto work;

        /* read drive and possibly current profile */
        if (cd_profiles(udev, fd) != 0)
                goto work;

        /* at this point we are guaranteed to have media in the drive - find out more about it */

        /* get session/track info */
        cd_media_toc(udev, fd);

        /* get writable media state */
        cd_media_info(udev, fd);

work:
        /* lock the media, so we enable eject button events */
        if (lock && cd_media) {
                log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (lock)");
                media_lock(udev, fd, true);
        }

        if (unlock && cd_media) {
                log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)");
                media_lock(udev, fd, false);
        }

        if (eject) {
                log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)");
                media_lock(udev, fd, false);
                log_debug("START_STOP_UNIT (eject)");
                media_eject(udev, fd);
        }

        printf("ID_CDROM=1\n");
        if (cd_cd_rom)
                printf("ID_CDROM_CD=1\n");
        if (cd_cd_r)
                printf("ID_CDROM_CD_R=1\n");
        if (cd_cd_rw)
                printf("ID_CDROM_CD_RW=1\n");
        if (cd_dvd_rom)
                printf("ID_CDROM_DVD=1\n");
        if (cd_dvd_r)
                printf("ID_CDROM_DVD_R=1\n");
        if (cd_dvd_rw)
                printf("ID_CDROM_DVD_RW=1\n");
        if (cd_dvd_ram)
                printf("ID_CDROM_DVD_RAM=1\n");
        if (cd_dvd_plus_r)
                printf("ID_CDROM_DVD_PLUS_R=1\n");
        if (cd_dvd_plus_rw)
                printf("ID_CDROM_DVD_PLUS_RW=1\n");
        if (cd_dvd_plus_r_dl)
                printf("ID_CDROM_DVD_PLUS_R_DL=1\n");
        if (cd_dvd_plus_rw_dl)
                printf("ID_CDROM_DVD_PLUS_RW_DL=1\n");
        if (cd_bd)
                printf("ID_CDROM_BD=1\n");
        if (cd_bd_r)
                printf("ID_CDROM_BD_R=1\n");
        if (cd_bd_re)
                printf("ID_CDROM_BD_RE=1\n");
        if (cd_hddvd)
                printf("ID_CDROM_HDDVD=1\n");
        if (cd_hddvd_r)
                printf("ID_CDROM_HDDVD_R=1\n");
        if (cd_hddvd_rw)
                printf("ID_CDROM_HDDVD_RW=1\n");
        if (cd_mo)
                printf("ID_CDROM_MO=1\n");
        if (cd_mrw)
                printf("ID_CDROM_MRW=1\n");
        if (cd_mrw_w)
                printf("ID_CDROM_MRW_W=1\n");

        if (cd_media)
                printf("ID_CDROM_MEDIA=1\n");
        if (cd_media_mo)
                printf("ID_CDROM_MEDIA_MO=1\n");
        if (cd_media_mrw)
                printf("ID_CDROM_MEDIA_MRW=1\n");
        if (cd_media_mrw_w)
                printf("ID_CDROM_MEDIA_MRW_W=1\n");
        if (cd_media_cd_rom)
                printf("ID_CDROM_MEDIA_CD=1\n");
        if (cd_media_cd_r)
                printf("ID_CDROM_MEDIA_CD_R=1\n");
        if (cd_media_cd_rw)
                printf("ID_CDROM_MEDIA_CD_RW=1\n");
        if (cd_media_dvd_rom)
                printf("ID_CDROM_MEDIA_DVD=1\n");
        if (cd_media_dvd_r)
                printf("ID_CDROM_MEDIA_DVD_R=1\n");
        if (cd_media_dvd_ram)
                printf("ID_CDROM_MEDIA_DVD_RAM=1\n");
        if (cd_media_dvd_rw)
                printf("ID_CDROM_MEDIA_DVD_RW=1\n");
        if (cd_media_dvd_plus_r)
                printf("ID_CDROM_MEDIA_DVD_PLUS_R=1\n");
        if (cd_media_dvd_plus_rw)
                printf("ID_CDROM_MEDIA_DVD_PLUS_RW=1\n");
        if (cd_media_dvd_plus_rw_dl)
                printf("ID_CDROM_MEDIA_DVD_PLUS_RW_DL=1\n");
        if (cd_media_dvd_plus_r_dl)
                printf("ID_CDROM_MEDIA_DVD_PLUS_R_DL=1\n");
        if (cd_media_bd)
                printf("ID_CDROM_MEDIA_BD=1\n");
        if (cd_media_bd_r)
                printf("ID_CDROM_MEDIA_BD_R=1\n");
        if (cd_media_bd_re)
                printf("ID_CDROM_MEDIA_BD_RE=1\n");
        if (cd_media_hddvd)
                printf("ID_CDROM_MEDIA_HDDVD=1\n");
        if (cd_media_hddvd_r)
                printf("ID_CDROM_MEDIA_HDDVD_R=1\n");
        if (cd_media_hddvd_rw)
                printf("ID_CDROM_MEDIA_HDDVD_RW=1\n");

        if (cd_media_state != NULL)
                printf("ID_CDROM_MEDIA_STATE=%s\n", cd_media_state);
        if (cd_media_session_next > 0)
                printf("ID_CDROM_MEDIA_SESSION_NEXT=%u\n", cd_media_session_next);
        if (cd_media_session_count > 0)
                printf("ID_CDROM_MEDIA_SESSION_COUNT=%u\n", cd_media_session_count);
        if (cd_media_session_count > 1 && cd_media_session_last_offset > 0)
                printf("ID_CDROM_MEDIA_SESSION_LAST_OFFSET=%llu\n", cd_media_session_last_offset);
        if (cd_media_track_count > 0)
                printf("ID_CDROM_MEDIA_TRACK_COUNT=%u\n", cd_media_track_count);
        if (cd_media_track_count_audio > 0)
                printf("ID_CDROM_MEDIA_TRACK_COUNT_AUDIO=%u\n", cd_media_track_count_audio);
        if (cd_media_track_count_data > 0)
                printf("ID_CDROM_MEDIA_TRACK_COUNT_DATA=%u\n", cd_media_track_count_data);
exit:
        if (fd >= 0)
                close(fd);
        udev_unref(udev);
        log_close();
        return rc;
}