/*
* libexplain - Explain errno values returned by libc functions
* Copyright (C) 2009, 2010 Peter Miller
*
* 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 3 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
* ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULesser
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef CDROMREADTOCHDR
static void
cdromreadtochdr(int fildes)
{
struct cdrom_tochdr data;
data.cdth_trk0 = 0;
data.cdth_trk1 = 99;
if (ioctl(fildes, CDROMREADTOCHDR, &data) >= 0)
{
report_uint64("CDROMREADTOCHDR", "First Track", data.cdth_trk0, 0);
report_uint64("CDROMREADTOCHDR", "Last Track", data.cdth_trk1, 0);
}
}
#endif
#ifdef CDROMREADTOCENTRY
static void
cdromreadtocentry(int fildes)
{
struct cdrom_tochdr header;
int j;
header.cdth_trk0 = 0;
header.cdth_trk1 = 99;
if (ioctl(fildes, CDROMREADTOCHDR, &header) < 0)
return;
for (j = header.cdth_trk0; j <= header.cdth_trk1; ++j)
{
struct cdrom_tocentry entry;
entry.cdte_track = j;
entry.cdte_format = CDROM_LBA;
fflush(stdout);
if (explain_ioctl_on_error(fildes, CDROMREADTOCENTRY, &entry) >= 0)
{
report_int("CDROMREADTOCENTRY", "Track", entry.cdte_track, 0);
report_int("CDROMREADTOCENTRY", " Adr", entry.cdte_adr, 0);
report_int("CDROMREADTOCENTRY", " Ctrl", entry.cdte_ctrl, 0);
switch (entry.cdte_format)
{
case CDROM_MSF:
{
char buf[100];
snprintf
(
buf,
sizeof(buf),
" %d, %d, %d",
entry.cdte_addr.msf.minute,
entry.cdte_addr.msf.second,
entry.cdte_addr.msf.frame
);
report("CDROMREADTOCENTRY", " Address", buf);
}
break;
case CDROM_LBA:
report_int
(
"CDROMREADTOCENTRY",
" Address",
entry.cdte_addr.lba,
0
);
break;
default:
report_int
(
"CDROMREADTOCENTRY",
" Format",
entry.cdte_format,
0
);
break;
}
report_int
(
"CDROMREADTOCENTRY",
" Data Mode",
entry.cdte_datamode,
0
);
}
}
}
#endif
#ifdef CDROM_DRIVE_STATUS
static void
cdrom_drive_status(int fildes)
{
int status;
status = ioctl(fildes, CDROM_DRIVE_STATUS, CDSL_CURRENT);
if (status >= 0)
{
static const explain_parse_bits_table_t table[] =
{
{ "CDS_NO_INFO", CDS_NO_INFO },
{ "CDS_NO_DISC", CDS_NO_DISC },
{ "CDS_TRAY_OPEN", CDS_TRAY_OPEN },
{ "CDS_DRIVE_NOT_READY", CDS_DRIVE_NOT_READY },
{ "CDS_DISC_OK", CDS_DISC_OK },
};
explain_string_buffer_t buf;
char text[30];
explain_string_buffer_init(&buf, text, sizeof(text));
explain_parse_bits_print_single(&buf, status, table, SIZEOF(table));
report("CDROM_DRIVE_STATUS", "Drive status", text);
}
}
#endif
#ifdef CDROM_DISC_STATUS
static void
cdrom_disc_status(int fildes)
{
int status;
status = ioctl(fildes, CDROM_DISC_STATUS, 0);
if (status >= 0)
{
static const explain_parse_bits_table_t table[] =
{
{ "CDS_NO_INFO", CDS_NO_INFO },
{ "CDS_NO_DISC", CDS_NO_DISC },
{ "CDS_AUDIO", CDS_AUDIO },
{ "CDS_DATA_1", CDS_DATA_1 },
{ "CDS_DATA_2", CDS_DATA_2 },
{ "CDS_XA_2_1", CDS_XA_2_1 },
{ "CDS_XA_2_2", CDS_XA_2_2 },
{ "CDS_MIXED", CDS_MIXED },
};
explain_string_buffer_t buf;
char text[30];
explain_string_buffer_init(&buf, text, sizeof(text));
explain_parse_bits_print_single(&buf, status, table, SIZEOF(table));
report("CDROM_DISC_STATUS", "Disc status", text);
}
}
#endif
#ifdef CDROM_CHANGER_NSLOTS
static void
cdrom_changer_nslots(int fildes)
{
int capacity;
capacity = ioctl(fildes, CDROM_CHANGER_NSLOTS, 0);
if (capacity >= 0)
{
report_int("CDROM_CHANGER_NSLOTS", "Changer slots", capacity, 0);
}
}
#endif
#ifdef CDROM_GET_CAPABILITY
static void
cdrom_get_capability(int fildes)
{
int capability;
capability = ioctl(fildes, CDROM_GET_CAPABILITY, 0);
if (capability >= 0)
{
static const explain_parse_bits_table_t table[] =
{
{ "CDC_CLOSE_TRAY", CDC_CLOSE_TRAY },
{ "CDC_OPEN_TRAY", CDC_OPEN_TRAY },
{ "CDC_LOCK", CDC_LOCK },
{ "CDC_SELECT_SPEED", CDC_SELECT_SPEED },
{ "CDC_SELECT_DISC", CDC_SELECT_DISC },
{ "CDC_MULTI_SESSION", CDC_MULTI_SESSION },
{ "CDC_MCN", CDC_MCN },
{ "CDC_MEDIA_CHANGED", CDC_MEDIA_CHANGED },
{ "CDC_PLAY_AUDIO", CDC_PLAY_AUDIO },
{ "CDC_RESET", CDC_RESET },
{ "CDC_DRIVE_STATUS", CDC_DRIVE_STATUS },
{ "CDC_GENERIC_PACKET", CDC_GENERIC_PACKET },
{ "CDC_CD_R", CDC_CD_R },
{ "CDC_CD_RW", CDC_CD_RW },
{ "CDC_DVD", CDC_DVD },
{ "CDC_DVD_R", CDC_DVD_R },
{ "CDC_DVD_RAM", CDC_DVD_RAM },
{ "CDC_MO_DRIVE", CDC_MO_DRIVE },
{ "CDC_MRW", CDC_MRW },
{ "CDC_MRW_W", CDC_MRW_W },
{ "CDC_RAM", CDC_RAM },
};
explain_string_buffer_t buf;
char text[1000];
explain_string_buffer_init(&buf, text, sizeof(text));
explain_parse_bits_print(&buf, capability, table, SIZEOF(table));
report("CDROM_GET_CAPABILITY", "Capability", text);
}
}
#endif
#ifdef DVD_READ_STRUCT
static void
dvd_read_struct(int fildes)
{
dvd_struct data;
int j;
data.type = DVD_STRUCT_PHYSICAL;
for (j = 0; j < DVD_LAYERS; ++j)
{
data.physical.layer_num = 0;
if (ioctl(fildes, DVD_READ_STRUCT, &data) >= 0)
{
struct dvd_layer *p;
p = &data.physical.layer[j];
report_int("DVD_READ_STRUCT", "Physcial Layer", j, 0);
report_int("DVD_READ_STRUCT", " Book version", p->book_version,
0);
report_int("DVD_READ_STRUCT", " Book type", p->book_type, 0);
report_int("DVD_READ_STRUCT", " Mininimum rate", p->min_rate, 0);
report_int("DVD_READ_STRUCT", " Disc size", p->disc_size, 0);
report_int("DVD_READ_STRUCT", " Layer type", p->layer_type, 0);
report_int("DVD_READ_STRUCT", " Track path", p->track_path, 0);
report_int("DVD_READ_STRUCT", " Number of layers", p->nlayers,
0);
report_int("DVD_READ_STRUCT", " Track density", p->track_density,
0);
report_int("DVD_READ_STRUCT", " Linear density",
p->linear_density, 0);
report_int("DVD_READ_STRUCT", " Start sector", p->start_sector,
0);
report_int("DVD_READ_STRUCT", " End sector", p->end_sector, 0);
report_int("DVD_READ_STRUCT", " End sector L0", p->end_sector_l0,
0);
report_int("DVD_READ_STRUCT", " Bca", p->bca, 0);
}
}
data.type = DVD_STRUCT_COPYRIGHT;
for (j = 0; j < DVD_LAYERS; ++j)
{
data.copyright.layer_num = 0;
if (ioctl(fildes, DVD_READ_STRUCT, &data) >= 0)
{
report_int("DVD_READ_STRUCT", "Copyright Layer", j, 0);
report_int("DVD_READ_STRUCT", " cpst", data.copyright.cpst, 0);
report_int("DVD_READ_STRUCT", " rmi", data.copyright.rmi, 0);
}
}
data.type = DVD_STRUCT_DISCKEY;
for (j = 0; j < 4; ++j)
{
data.disckey.agid = j;
if (ioctl(fildes, DVD_READ_STRUCT, &data) >= 0)
{
char text[sizeof(data.disckey.value) * 3 + 1];
explain_string_buffer_t sb;
report_int("DVD_READ_STRUCT", "Disc Key", j, 0);
explain_string_buffer_init(&sb, text, sizeof(text));
explain_buffer_hexdump(&sb, data.disckey.value,
sizeof(data.disckey.value));
report("DVD_READ_STRUCT", " Value", text);
}
}
data.type = DVD_STRUCT_BCA;
if (ioctl(fildes, DVD_READ_STRUCT, &data) >= 0)
{
int n;
explain_string_buffer_t sb;
char text[sizeof(data.bca.value) * 3 + 2];
explain_string_buffer_init(&sb, text, sizeof(text));
n = data.bca.len;
if (n > (int)sizeof(data.bca.value))
n = sizeof(data.bca.value);
if (n > 0)
explain_buffer_hexdump(&sb, data.bca.value, n);
report("DVD_READ_STRUCT", "BCA", text);
}
data.type = DVD_STRUCT_MANUFACT;
for (j = 0; j < DVD_LAYERS; ++j)
{
data.manufact.layer_num = j;
if (ioctl(fildes, DVD_READ_STRUCT, &data) >= 0)
{
int n;
explain_string_buffer_t sb;
char text[sizeof(data.manufact.value) * 3 + 1];
report_int("DVD_READ_STRUCT", "Manufacturer", j, 0);
explain_string_buffer_init(&sb, text, sizeof(text));
n = data.manufact.len;
if (n > (int)sizeof(data.manufact.value))
n = sizeof(data.manufact.value);
if (n > 0)
explain_buffer_hexdump(&sb, data.disckey.value, n);
report("DVD_READ_STRUCT", " Value", text);
}
}
}
#endif
void
scan_linux_cdrom(int fildes)
{
(void)fildes;
#ifndef HAVE_LINUX_CDROM_H
(void)fildes;
#endif
#ifdef CDROMGETSPINDOWN
report_semi_auto(fildes, CDROMGETSPINDOWN);
#endif
#ifdef CDROMREADTOCHDR
cdromreadtochdr(fildes);
#endif
#ifdef CDROMREADTOCENTRY
cdromreadtocentry(fildes);
#endif
#ifdef CDROMVOLREAD
report_semi_auto(fildes, CDROMVOLREAD);
#endif
#ifdef CDROM_CHANGER_NSLOTS
cdrom_changer_nslots(fildes);
#endif
#ifdef CDROM_DISC_STATUS
cdrom_disc_status(fildes);
#endif
#ifdef CDROM_DRIVE_STATUS
cdrom_drive_status(fildes);
#endif
#ifdef CDROM_GET_CAPABILITY
cdrom_get_capability(fildes);
#endif
#ifdef CDROM_GET_MCN
report_semi_auto(fildes, CDROM_GET_MCN);
#endif
#ifdef CDROM_LAST_WRITTEN
report_semi_auto(fildes, CDROM_LAST_WRITTEN);
#endif
#ifdef CDROM_MEDIA_CHANGED
report_semi_auto(fildes, CDROM_MEDIA_CHANGED);
#endif
#ifdef CDROM_NEXT_WRITABLE
report_semi_auto(fildes, CDROM_NEXT_WRITABLE);
#endif
#ifdef DVD_READ_STRUCT
dvd_read_struct(fildes);
#endif
}