cdrom_id: replace with version which also exports media properties

This is a 12 track audio CD with additional data session:
  $ extras/cdrom_id/cdrom_id /dev/dvd
  ID_CDROM=1
  ID_CDROM_CD_R=1
  ID_CDROM_CD_RW=1
  ID_CDROM_DVD=1
  ID_CDROM_DVD_R=1
  ID_CDROM_DVD_RW=1
  ID_CDROM_DVD_RAM=1
  ID_CDROM_DVD_PLUS_R=1
  ID_CDROM_DVD_PLUS_RW=1
  ID_CDROM_DVD_PLUS_R_DL=1
  ID_CDROM_MEDIA_CD=1
  ID_CDROM_MEDIA_STATE=complete
  ID_CDROM_MEDIA_HAS_AUDIO=1
  ID_CDROM_MEDIA_SESSION_COUNT=2
  ID_CDROM_MEDIA_TRACK_COUNT=13
  ID_CDROM_MEDIA_SESSION_LAST_OFFSET=444508160
This commit is contained in:
Kay Sievers 2008-04-09 23:17:39 +02:00
parent 8b5238670d
commit fd7a285e62
3 changed files with 616 additions and 76 deletions

View File

@ -1,3 +1,3 @@
# import optical drive properties
KERNEL=="sr[0-9]*|hd[a-z]|pcd[0-9]*", IMPORT{program}="cdrom_id --export $tempnode"
ACTION=="add|change", KERNEL=="sr[0-9]*|hd[a-z]|pcd[0-9]*", IMPORT{program}="cdrom_id --export $tempnode"

View File

@ -1,17 +1,16 @@
.TH CDROM_ID 8 "November 2005" "" "Linux Administrator's Manual"
.TH CDROM_ID 8 "April 2008" "" "Linux Administrator's Manual"
.SH NAME
cdrom_id \- udev callout to determine the capabilities of cd/dvd drives
cdrom_id \- udev callout to determine the capabilities of optical drives and media
.SH SYNOPSIS
.BI cdrom_id
[\fI--export\fP] \fIblockdevice\fP
[\fI--export\fP] \fIdevice\fP
.SH "DESCRIPTION"
.B cdrom_id
is normally called from a udev rule, to provide udev with the capabilities
of a cdrom or dvdrom drive. Udev can use this information to create
symlinks like /dev/cdrom or /dev/dvd to the real device node.
is normally called from a udev rule, to provide udev with the list of
capabilities of a optical drive.
.SH USAGE
.B cdrom_id
opens the blockdevice node specified at the commandline and prints the
opens the device node specified at the commandline and prints the
discovered capabilities.
.SH OPTIONS
The following commandline switches are supported to specify what cdrom_id
@ -23,5 +22,5 @@ print all values (default)
.SH SEE ALSO
.BR udev (7)
.SH AUTHORS
Developed by Greg Kroah\-Hartman <greg@kroah.com>.
Developed by Kay Sievers <kay.sievers@vrfy.org>.

View File

@ -1,12 +1,21 @@
/*
* cdrom_id - determines the capabilities of cdrom drives
* cdrom_id - optical drive and media information prober
*
* Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.de>
* Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org>
*
* 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 version 2 of the License.
*
* 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.
*
*/
#ifndef _GNU_SOURCE
@ -14,50 +23,27 @@
#endif
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <getopt.h>
#include <scsi/sg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <linux/cdrom.h>
#include "../../udev.h"
/*
* Taken from the cdrom.h kernel include file.
* Included here as some distros don't have an updated version
* with all of the DVD flags. So we just include our own, aren't
* we so nice...
*/
#define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#endif
/* capability flags used with the uniform CD-ROM driver */
#define CDC_CLOSE_TRAY 0x1 /* caddy systems _can't_ close */
#define CDC_OPEN_TRAY 0x2 /* but _can_ eject. */
#define CDC_LOCK 0x4 /* disable manual eject */
#define CDC_SELECT_SPEED 0x8 /* programmable speed */
#define CDC_SELECT_DISC 0x10 /* select disc from juke-box */
#define CDC_MULTI_SESSION 0x20 /* read sessions>1 */
#define CDC_MCN 0x40 /* Medium Catalog Number */
#define CDC_MEDIA_CHANGED 0x80 /* media changed */
#define CDC_PLAY_AUDIO 0x100 /* audio functions */
#define CDC_RESET 0x200 /* hard reset device */
#define CDC_IOCTLS 0x400 /* driver has non-standard ioctls */
#define CDC_DRIVE_STATUS 0x800 /* driver implements drive status */
#define CDC_GENERIC_PACKET 0x1000 /* driver implements generic packets */
#define CDC_CD_R 0x2000 /* drive is a CD-R */
#define CDC_CD_RW 0x4000 /* drive is a CD-RW */
#define CDC_DVD 0x8000 /* drive is a DVD */
#define CDC_DVD_R 0x10000 /* drive can write DVD-R */
#define CDC_DVD_RAM 0x20000 /* drive can write DVD-RAM */
#define CDC_MO_DRIVE 0x40000 /* drive is an MO device */
#define CDC_MRW 0x80000 /* drive can read MRW */
#define CDC_MRW_W 0x100000 /* drive can write MRW */
#define CDC_RAM 0x200000 /* ok to open for WRITE */
static int debug;
#ifdef USE_LOG
void log_message(int priority, const char *format, ...)
@ -73,80 +59,635 @@ void log_message(int priority, const char *format, ...)
udev_log = log_priority(value);
else
udev_log = LOG_ERR;
if (debug && udev_log < LOG_INFO)
udev_log = LOG_INFO;
}
if (priority > udev_log)
return;
va_start(args, format);
vsyslog(priority, format, args);
if (debug) {
fprintf(stderr, "[%d] ", (int) getpid());
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
} else
vsyslog(priority, format, args);
va_end(args);
}
#endif
/* device info */
static unsigned int cd_cd_rom;
static unsigned int cd_cd_r;
static unsigned int cd_cd_rw;
static unsigned int cd_dvd_rom;
static unsigned int cd_dvd_r;
static unsigned int cd_dvd_rw;
static unsigned int cd_dvd_ram;
static unsigned int cd_dvd_plus_r;
static unsigned int cd_dvd_plus_rw;
static unsigned int cd_dvd_plus_r_dl;
static unsigned int cd_dvd_plus_rw_dl;
static unsigned int cd_bd;
static unsigned int cd_bd_r;
static unsigned int cd_bd_re;
static unsigned int cd_hddvd;
static unsigned int cd_hddvd_r;
static unsigned int cd_hddvd_rw;
static unsigned int cd_mo;
static unsigned int cd_mrw;
static unsigned int cd_mrw_w;
/* media info */
static unsigned int cd_media_cd_rom;
static unsigned int cd_media_cd_r;
static unsigned int cd_media_cd_rw;
static unsigned int cd_media_dvd_rom;
static unsigned int cd_media_dvd_r;
static unsigned int cd_media_dvd_rw;
static unsigned int cd_media_dvd_ram;
static unsigned int cd_media_dvd_plus_r;
static unsigned int cd_media_dvd_plus_rw;
static unsigned int cd_media_dvd_plus_r_dl;
static unsigned int cd_media_dvd_plus_rw_dl;
static unsigned int cd_media_bd;
static unsigned int cd_media_bd_r;
static unsigned int cd_media_bd_re;
static unsigned int cd_media_hddvd;
static unsigned int cd_media_hddvd_r;
static unsigned int cd_media_hddvd_rw;
static unsigned int cd_media_mo;
static unsigned int cd_media_mrw;
static unsigned int cd_media_mrw_w;
static const char *cd_media_state;
static unsigned int cd_media_has_audio;
static unsigned int cd_media_session_next;
static unsigned int cd_media_session_count;
static unsigned int cd_media_track_count;
static unsigned long long int cd_media_session_last_offset;
#define ERRCODE(s) ((((s)[2] & 0x0F) << 16) | ((s)[12] << 8) | ((s)[13]))
#define SK(errcode) (((errcode) >> 16) & 0xF)
#define ASC(errcode) (((errcode) >> 8) & 0xFF)
#define ASCQ(errcode) ((errcode) & 0xFF)
static void info_scsi_cmd_err(const char *cmd, int err)
{
if (err == -1) {
info("%s failed", cmd);
return;
}
info("%s failed with SK=%Xh/ASC=%02Xh/ACQ=%02Xh", cmd, SK(err), ASC(err), ASCQ(err));
}
struct scsi_cmd {
struct cdrom_generic_command cgc;
union {
struct request_sense s;
unsigned char u[18];
} _sense;
struct sg_io_hdr sg_io;
};
static void scsi_cmd_set(struct scsi_cmd *cmd, size_t i, int arg)
{
if (i == 0) {
memset(cmd, 0x00, sizeof(struct scsi_cmd));
cmd->cgc.quiet = 1;
cmd->cgc.sense = &cmd->_sense.s;
memset(&cmd->sg_io, 0, sizeof(cmd->sg_io));
cmd->sg_io.interface_id = 'S';
cmd->sg_io.mx_sb_len = sizeof(cmd->_sense);
cmd->sg_io.cmdp = cmd->cgc.cmd;
cmd->sg_io.sbp = cmd->_sense.u;
cmd->sg_io.flags = SG_FLAG_LUN_INHIBIT | SG_FLAG_DIRECT_IO;
}
cmd->sg_io.cmd_len = i + 1;
cmd->cgc.cmd[i] = arg;
}
#define CHECK_CONDITION 0x01
static int scsi_cmd_run(struct scsi_cmd *cmd, int fd, unsigned char *buf, size_t bufsize)
{
int ret = 0;
cmd->sg_io.dxferp = buf;
cmd->sg_io.dxfer_len = bufsize;
cmd->sg_io.dxfer_direction = SG_DXFER_FROM_DEV;
if (ioctl(fd, SG_IO, &cmd->sg_io))
return -1;
if ((cmd->sg_io.info & SG_INFO_OK_MASK) != SG_INFO_OK) {
errno = EIO;
ret = -1;
if (cmd->sg_io.masked_status & CHECK_CONDITION) {
ret = ERRCODE(cmd->_sense.u);
if (ret == 0)
ret = -1;
}
}
return ret;
}
static int cd_capability_compat(int fd)
{
int capabilty;
capabilty = ioctl(fd, CDROM_GET_CAPABILITY, NULL);
if (capabilty < 0) {
info("CDROM_GET_CAPABILITY failed");
return -1;
}
if (capabilty & CDC_CD_R)
cd_cd_r = 1;
if (capabilty & CDC_CD_RW)
cd_cd_rw = 1;
if (capabilty & CDC_DVD)
cd_dvd_rom = 1;
if (capabilty & CDC_DVD_R)
cd_dvd_r = 1;
if (capabilty & CDC_DVD_RAM)
cd_dvd_ram = 1;
if (capabilty & CDC_MRW)
cd_mrw = 1;
if (capabilty & CDC_MRW_W)
cd_mrw_w = 1;
return 0;
}
static int cd_inquiry(int fd) {
struct scsi_cmd sc;
unsigned char inq[128];
int err;
scsi_cmd_set(&sc, 0, 0x12);
scsi_cmd_set(&sc, 4, 36);
scsi_cmd_set(&sc, 5, 0);
err = scsi_cmd_run(&sc, fd, inq, 36);
if ((err < 0)) {
info_scsi_cmd_err("INQUIRY", err);
return -1;
}
if ((inq[0] & 0x1F) != 5) {
info("not an MMC unit");
return -1;
}
info("INQUIRY: [%.8s][%.16s][%.4s]", inq + 8, inq + 16, inq + 32);
return 0;
}
static int cd_profiles(int fd)
{
struct scsi_cmd sc;
unsigned char header[8];
unsigned char profiles[512];
unsigned int cur_profile;
unsigned int len;
unsigned int i;
int err;
scsi_cmd_set(&sc, 0, 0x46);
scsi_cmd_set(&sc, 1, 0);
scsi_cmd_set(&sc, 8, sizeof(header));
scsi_cmd_set(&sc, 9, 0);
err = scsi_cmd_run(&sc, fd, header, sizeof(header));
if ((err < 0)) {
info_scsi_cmd_err("GET CONFIGURATION", err);
return -1;
}
len = 4 + (header[0] << 24 | header[1] << 16 | header[2] << 8 | header[3]);
info("GET CONFIGURATION: number of profiles %i", len);
if (len > sizeof(profiles)) {
info("invalid number of profiles");
return -1;
}
scsi_cmd_set(&sc, 0, 0x46);
scsi_cmd_set(&sc, 1, 1);
scsi_cmd_set(&sc, 6, len >> 16);
scsi_cmd_set(&sc, 7, len >> 8);
scsi_cmd_set(&sc, 8, len);
scsi_cmd_set(&sc, 9, 0);
err = scsi_cmd_run(&sc, fd, profiles, len);
if ((err < 0)) {
info_scsi_cmd_err("GET CONFIGURATION", err);
return -1;
}
/* device profiles */
for (i = 12; i < profiles[11]; i += 4) {
unsigned int profile = (profiles[i] << 8 | profiles[i + 1]);
if (profile == 0)
continue;
info("profile 0x%02x", profile);
switch (profile) {
case 0x03:
case 0x04:
case 0x05:
cd_mo = 1;
break;
case 0x10:
cd_dvd_rom = 1;
break;
case 0x12:
cd_dvd_ram = 1;
break;
case 0x13:
case 0x14:
cd_dvd_rw = 1;
break;
case 0x1B:
cd_dvd_plus_r = 1;
break;
case 0x1A:
cd_dvd_plus_rw = 1;
break;
case 0x2A:
cd_dvd_plus_rw_dl = 1;
break;
case 0x2B:
cd_dvd_plus_r_dl = 1;
break;
case 0x40:
cd_bd = 1;
break;
case 0x41:
case 0x42:
cd_bd_r = 1;
break;
case 0x43:
cd_bd_re = 1;
break;
case 0x50:
cd_hddvd = 1;
break;
case 0x51:
cd_hddvd_r = 1;
break;
case 0x52:
cd_hddvd_rw = 1;
break;
default:
break;
}
}
/* current media profile */
cur_profile = header[6] << 8 | header[7];
info("current profile 0x%02x", cur_profile);
if (cur_profile == 0) {
info("no current profile, assuming no media");
return -1;
}
switch (cur_profile) {
case 0x03:
case 0x04:
case 0x05:
cd_media_mo = 1;
break;
case 0x08:
cd_media_cd_rom = 1;
break;
case 0x09:
cd_media_cd_r = 1;
break;
case 0x0a:
cd_media_cd_rw = 1;
break;
case 0x10:
cd_media_dvd_rom = 1;
break;
case 0x11:
cd_media_dvd_r = 1;
break;
case 0x12:
cd_media_dvd_ram = 1;
break;
case 0x13:
case 0x14:
cd_media_dvd_rw = 1;
break;
case 0x1B:
cd_media_dvd_plus_r = 1;
break;
case 0x1A:
cd_media_dvd_plus_rw = 1;
break;
case 0x2A:
cd_media_dvd_plus_rw_dl = 1;
break;
case 0x2B:
cd_media_dvd_plus_r_dl = 1;
break;
case 0x40:
cd_media_bd = 1;
break;
case 0x41:
case 0x42:
cd_media_bd_r = 1;
break;
case 0x43:
cd_media_bd_re = 1;
break;
case 0x50:
cd_media_hddvd = 1;
break;
case 0x51:
cd_media_hddvd_r = 1;
break;
case 0x52:
cd_media_hddvd_rw = 1;
break;
default:
break;
}
return 0;
}
static int cd_media_info(int fd)
{
struct scsi_cmd sc;
unsigned char header[32];
static const char *media_status[] = {
"blank",
"appendable",
"complete",
"other"
};
int err;
scsi_cmd_set(&sc, 0, 0x51);
scsi_cmd_set(&sc, 8, sizeof(header));
scsi_cmd_set(&sc, 9, 0);
err = scsi_cmd_run(&sc, fd, header, sizeof(header));
if ((err < 0)) {
info_scsi_cmd_err("READ DISC INFORMATION", err);
return -1;
};
info("disk type %02x", header[8]);
if ((header[2] & 3) < 4)
cd_media_state = media_status[header[2] & 3];
if ((header[2] & 3) != 2)
cd_media_session_next = header[10] << 8 | header[5];
cd_media_session_count = header[9] << 8 | header[4];
cd_media_track_count = header[11] << 8 | header[6];
return 0;
}
static int cd_media_toc(int fd)
{
struct scsi_cmd sc;
unsigned char header[12];
unsigned char toc[2048];
unsigned int len, i;
unsigned char *p;
int err;
scsi_cmd_set(&sc, 0, 0x43);
scsi_cmd_set(&sc, 6, 1);
scsi_cmd_set(&sc, 8, sizeof(header));
scsi_cmd_set(&sc, 9, 0);
err = scsi_cmd_run(&sc, fd, header, sizeof(header));
if ((err < 0)) {
info_scsi_cmd_err("READ TOC", err);
return -1;
}
len = (header[0] << 8 | header[1]) + 2;
info("READ TOC: len: %d", len);
if (len > sizeof(toc))
return -1;
/* check if we have a data track */
info("ctl %02x (0x04 is data/audio)", header[5]);
cd_media_has_audio = (header[5] & 0x04) == 0;
scsi_cmd_set(&sc, 0, 0x43);
scsi_cmd_set(&sc, 6, header[2]); /* First Track/Session Number */
scsi_cmd_set(&sc, 7, len >> 8);
scsi_cmd_set(&sc, 8, len);
scsi_cmd_set(&sc, 9, 0);
err = scsi_cmd_run(&sc, fd, toc, len);
if ((err < 0)) {
info_scsi_cmd_err("READ TOC (tracks)", err);
return -1;
}
for (p = toc+4, i = 4; i < len-8; i += 8, p += 8) {
unsigned int block;
block = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7];
info("track %u starts at block %u", p[2], block);
}
scsi_cmd_set(&sc, 0, 0x43);
scsi_cmd_set(&sc, 2, 1); /* Session Info */
scsi_cmd_set(&sc, 8, 12);
scsi_cmd_set(&sc, 9, 0);
err = scsi_cmd_run(&sc, fd, header, sizeof(header));
if ((err < 0)) {
info_scsi_cmd_err("READ TOC (multi session)", err);
return -1;
}
len = header[4+4] << 24 | header[4+5] << 16 | header[4+6] << 8 | header[4+7];
info("last track %u starts at block %u", header[4+2], len);
cd_media_session_last_offset = (unsigned long long int)len * 2048;
return 0;
}
int main(int argc, char *argv[])
{
static const struct option options[] = {
{ "export", 0, NULL, 'x' },
{ "debug", 0, NULL, 'd' },
{ "help", 0, NULL, 'h' },
{}
};
const char *node = NULL;
int i;
int export = 0;
int fd;
int fd = -1;
int rc = 0;
int result;
logging_init("cdrom_id");
for (i = 1 ; i < argc; i++) {
char *arg = argv[i];
while (1) {
int option;
if (strcmp(arg, "--export") == 0) {
option = getopt_long(argc, argv, "dxh", options, NULL);
if (option == -1)
break;
switch (option) {
case 'd':
debug = 1;
break;
case 'x':
export = 1;
} else
node = arg;
break;
case 'h':
printf("Usage: cdrom_id [options] <device>\n"
" --export export key/value pairs\n"
" --help\n\n");
goto exit;
default:
rc = 1;
goto exit;
}
}
node = argv[optind];
if (!node) {
info("no node specified");
err("no device");
fprintf(stderr, "no device\n");
rc = 1;
goto exit;
}
fd = open(node, O_RDONLY|O_NONBLOCK);
fd = open(node, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
info("unable to open '%s'", node);
rc = 1;
goto exit;
}
info("probing: '%s'", node);
result = ioctl(fd, CDROM_GET_CAPABILITY, NULL);
if (result < 0) {
info("CDROM_GET_CAPABILITY failed for '%s'", node);
rc = 3;
goto close;
/* same data as original cdrom_id */
if (cd_capability_compat(fd) < 0) {
rc = 1;
goto exit;
}
/* check drive */
if (cd_inquiry(fd) < 0) {
rc = 2;
goto exit;
}
/* read drive and possibly current profile */
if (cd_profiles(fd) < 0)
goto print;
/* get session/track info */
if (cd_media_toc(fd) < 0)
goto print;
/* get writable media state */
if (cd_media_info(fd) < 0)
goto print;
print:
printf("ID_CDROM=1\n");
if (result & CDC_CD_R)
if (cd_cd_rom)
printf("ID_CDROM_CD=1\n");
if (cd_cd_r)
printf("ID_CDROM_CD_R=1\n");
if (result & CDC_CD_RW)
if (cd_cd_rw)
printf("ID_CDROM_CD_RW=1\n");
if (result & CDC_DVD)
if (cd_dvd_rom)
printf("ID_CDROM_DVD=1\n");
if (result & CDC_DVD_R)
if (cd_dvd_r)
printf("ID_CDROM_DVD_R=1\n");
if (result & CDC_DVD_RAM)
if (cd_dvd_rw)
printf("ID_CDROM_DVD_RW=1\n");
if (cd_dvd_ram)
printf("ID_CDROM_DVD_RAM=1\n");
if (result & CDC_MRW)
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 (result & CDC_MRW_W)
if (cd_mrw_w)
printf("ID_CDROM_MRW_W=1\n");
if (result & CDC_RAM)
printf("ID_CDROM_RAM=1\n");
close:
close(fd);
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_has_audio)
printf("ID_CDROM_MEDIA_HAS_AUDIO=1\n");
if (cd_media_session_next > 0)
printf("ID_CDROM_MEDIA_SESSION_NEXT=%d\n", cd_media_session_next);
if (cd_media_session_count > 0)
printf("ID_CDROM_MEDIA_SESSION_COUNT=%d\n", cd_media_session_count);
if (cd_media_track_count > 0)
printf("ID_CDROM_MEDIA_TRACK_COUNT=%d\n", cd_media_track_count);
if (cd_media_session_last_offset)
printf("ID_CDROM_MEDIA_SESSION_LAST_OFFSET=%llu\n", cd_media_session_last_offset);
exit:
if (fd >= 0)
close(fd);
logging_close();
return rc;
}