First-cut to auto-scan for device capabilities

This commit is contained in:
rocky
2003-09-28 17:14:20 +00:00
parent 624ac3c529
commit 083f472570
11 changed files with 502 additions and 221 deletions

View File

@@ -1,4 +1,4 @@
all: sample1 sample2 sample3 sample4 dbg_read
all: sample1 sample2 sample3 sample4 sample5
sample1: sample1.c
gcc -g -Wall $< -l cdio -o $@
sample2: sample2.c
@@ -10,3 +10,6 @@ sample3: sample3.c
sample4: sample4.c
gcc -g -Wall $< -l cdio -o $@
sample5: sample5.c
gcc -g -Wall $< -l cdio -o $@

100
example/sample5.c Normal file
View File

@@ -0,0 +1,100 @@
/*
$Id: sample5.c,v 1.1 2003/09/28 17:14:20 rocky Exp $
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Simple program to show drivers installed and what the default
CD-ROM drive is and what CD drives are available. */
#include <stdio.h>
#include <sys/types.h>
#include <cdio/cdio.h>
#include <cdio/cd_types.h>
#include <cdio/logging.h>
static void
log_handler (cdio_log_level_t level, const char message[])
{
switch(level) {
case CDIO_LOG_DEBUG:
case CDIO_LOG_INFO:
return;
default:
printf("cdio %d message: %s\n", level, message);
}
}
int
main(int argc, const char *argv[])
{
char **cd_drives=NULL, **c;
cdio_log_set_handler (log_handler);
/* Print out a list of CD-drives */
cd_drives = cdio_get_devices(NULL);
for( c = cd_drives; *c != NULL; *c++ ) {
printf("Drive %s\n", *c);
}
cdio_free_device_list(cd_drives);
printf("-----\n");
cd_drives = NULL;
/* Print out a list of CD-drives the harder way. */
cd_drives = cdio_get_devices_with_cap(NULL, CDIO_FS_MATCH_ALL, false);
if (NULL != cd_drives) {
for( c = cd_drives; *c != NULL; *c++ ) {
printf("Drive %s\n", *c);
}
cdio_free_device_list(cd_drives);
}
printf("-----\n");
printf("CD-DA drives...\n");
cd_drives = NULL;
/* Print out a list of CD-drives with CD-DA's in them. */
cd_drives = cdio_get_devices_with_cap(NULL, CDIO_FS_AUDIO, true);
if (NULL != cd_drives) {
for( c = cd_drives; *c != NULL; *c++ ) {
printf("drive: %s\n", *c);
}
cdio_free_device_list(cd_drives);
}
printf("-----\n");
cd_drives = NULL;
printf("VCD drives...\n");
/* Print out a list of CD-drives with VCD's in them. */
cd_drives = cdio_get_devices_with_cap(NULL,
(CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD|CDIO_FS_UNKNOWN),
true);
if (NULL != cd_drives) {
for( c = cd_drives; *c != NULL; *c++ ) {
printf("drive: %s\n", *c);
}
}
cdio_free_device_list(cd_drives);
return 0;
}

View File

@@ -1,5 +1,5 @@
/*
$Id: cd_types.h,v 1.1 2003/08/16 15:34:58 rocky Exp $
$Id: cd_types.h,v 1.2 2003/09/28 17:14:20 rocky Exp $
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1996,1997,1998 Gerd Knorr <kraxel@bytesex.org>
@@ -32,16 +32,16 @@
extern "C" {
#endif /* __cplusplus */
#define CDIO_FS_NO_DATA 0 /* audio only */
#define CDIO_FS_HIGH_SIERRA 1
#define CDIO_FS_ISO_9660 2
#define CDIO_FS_INTERACTIVE 3
#define CDIO_FS_HFS 4
#define CDIO_FS_UFS 5
#define CDIO_FS_EXT2 6
#define CDIO_FS_ISO_HFS 7 /* both hfs & isofs filesystem */
#define CDIO_FS_ISO_9660_INTERACTIVE 8 /* both CD-RTOS and isofs filesystem */
#define CDIO_FS_3DO 9
#define CDIO_FS_AUDIO 1 /* audio only - not really a fs */
#define CDIO_FS_HIGH_SIERRA 2
#define CDIO_FS_ISO_9660 3
#define CDIO_FS_INTERACTIVE 4
#define CDIO_FS_HFS 5
#define CDIO_FS_UFS 6
#define CDIO_FS_EXT2 7
#define CDIO_FS_ISO_HFS 8 /* both hfs & isofs filesystem */
#define CDIO_FS_ISO_9660_INTERACTIVE 9 /* both CD-RTOS and isofs filesystem */
#define CDIO_FS_3DO 10
#define CDIO_FS_MASK 15 /* Should be 2*n-1 and > above */
#define CDIO_FS_UNKNOWN CDIO_FS_MASK
@@ -60,14 +60,17 @@ extern "C" {
#define CDIO_FS_ANAL_HIDDEN_TRACK 128
#define CDIO_FS_ANAL_CDTV 256
#define CDIO_FS_ANAL_BOOTABLE 512
#define CDIO_FS_ANAL_VIDEOCDI 1024
#define CDIO_FS_ANAL_VIDEOCD 1024 /* VCD 1.1 */
#define CDIO_FS_ANAL_ROCKRIDGE 2048
#define CDIO_FS_ANAL_JOLIET 4096
#define CDIO_FS_ANAL_SVCD 8192 /* Super VCD or Choiji Video CD */
#define CDIO_FS_ANAL_CVD 16384 /* Choiji Video CD */
/* Pattern which can be used by cdio_get_devices to specify matching
any sort of CD.
*/
#define CDIO_FS_MATCH_ALL (cdio_fs_anal_t) (~CDIO_FS_MASK)
typedef int cdio_fs_anal_t;
typedef struct
{
@@ -82,7 +85,7 @@ typedef struct
have at track track_num. Return information about the CD image
is returned in cdio_analysis and the return value.
*/
cdio_fs_anal_t cdio_guess_cd_type(/*in*/ CdIo *cdio, int start_session,
cdio_fs_anal_t cdio_guess_cd_type(const CdIo *cdio, int start_session,
track_t track_num,
/*out*/ cdio_analysis_t *cdio_analysis);

View File

@@ -1,5 +1,5 @@
/* -*- c -*-
$Id: cdio.h,v 1.23 2003/09/28 01:04:57 rocky Exp $
$Id: cdio.h,v 1.24 2003/09/28 17:14:20 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
@@ -115,12 +115,43 @@ extern "C" {
*/
void cdio_destroy (CdIo *obj);
/*!
Free device list returned by cdio_get_devices or
cdio_get_devices_with_cap.
*/
void cdio_free_device_list (char * device_list[]);
/*!
Return the value associatied with key. NULL is returned if obj is NULL
or "key" does not exist.
*/
const char * cdio_get_arg (const CdIo *obj, const char key[]);
/*!
Return an array of device names in search_devices that have at
least the capabilities listed by cap. If search_devices is NULL,
then we'll search all possible CD drives.
If "any" is set false then every capability listed in the extended
portion of capabilities (i.e. not the basic filesystem) must be
satisified. If "any" is set true, then if any of the capabilities
matches, we call that a success.
To find a CD-drive of any type, use the mask CDIO_FS_MATCH_ALL.
NULL is returned if we couldn't get a default device.
*/
char ** cdio_get_devices_with_cap (char* search_devices[],
cdio_fs_anal_t capabilities, bool any);
/*!
Return an array of device names. if CdIo is NULL (we haven't
initialized a specific device driver), then find a suitable device
driver.
NULL is returned if we couldn't return a list of devices.
*/
char ** cdio_get_devices (const CdIo *obj);
/*!
Return a string containing the default CD device if none is specified.
if CdIo is NULL (we haven't initialized a specific device driver),

View File

@@ -1,5 +1,5 @@
/*
$Id: types.h,v 1.6 2003/09/06 02:51:29 rocky Exp $
$Id: types.h,v 1.7 2003/09/28 17:14:20 rocky Exp $
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002,2003 Rocky Bernstein <rocky@panix.com>
@@ -218,6 +218,8 @@ extern "C" {
*/
#define CDIO_INVALID_LSN 0xFFFFFFFF
typedef int cdio_fs_anal_t;
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_generic.c,v 1.10 2003/06/12 04:46:27 rocky Exp $
$Id: _cdio_generic.c,v 1.11 2003/09/28 17:14:20 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002,2003 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: _cdio_generic.c,v 1.10 2003/06/12 04:46:27 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_generic.c,v 1.11 2003/09/28 17:14:20 rocky Exp $";
#include <stdio.h>
#include <stdlib.h>
@@ -167,3 +167,29 @@ cdio_is_device_quiet_generic(const char *source_name)
}
return (S_ISBLK(buf.st_mode) || S_ISCHR(buf.st_mode));
}
/*!
Add/allocate a drive to the end of drives.
Use cdio_free_device_list() to free this device_list.
*/
void
cdio_add_device_list(char **device_list[], const char *drive, int *num_drives)
{
if (NULL != drive) {
unsigned int j;
for (j=0; j<*num_drives; j++) {
if (strcmp((*device_list)[j], drive) == 0) break;
}
if (j==*num_drives) {
(*num_drives)++;
*device_list = realloc(*device_list, (*num_drives) * sizeof(char *));
(*device_list)[*num_drives-1] = strdup(drive);
}
} else {
(*num_drives)++;
*device_list = realloc(*device_list, (*num_drives) * sizeof(char *));
(*device_list)[*num_drives-1] = NULL;
}
}

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_linux.c,v 1.23 2003/09/27 23:29:29 rocky Exp $
$Id: _cdio_linux.c,v 1.24 2003/09/28 17:14:20 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002,2003 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.23 2003/09/27 23:29:29 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.24 2003/09/28 17:14:20 rocky Exp $";
#include <string.h>
@@ -420,63 +420,6 @@ _cdio_read_mode2_sector (void *env, void *data, lsn_t lsn,
return 0;
}
/*!
Reads a single audio sector from CD device into data starting
from lsn. Returns 0 if no error.
*/
static int
_cdio_read_audio_sector (void *env, void *data, lsn_t lsn)
{
char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
struct cdrom_msf *msf = (struct cdrom_msf *) &buf;
msf_t _msf;
_img_private_t *_obj = env;
cdio_lsn_to_msf (lsn, &_msf);
msf->cdmsf_min0 = from_bcd8(_msf.m);
msf->cdmsf_sec0 = from_bcd8(_msf.s);
msf->cdmsf_frame0 = from_bcd8(_msf.f);
retry:
switch (_obj->access_mode)
{
case _AM_NONE:
cdio_error ("no way to read audio");
return 1;
break;
case _AM_IOCTL:
if (ioctl (_obj->gen.fd, CDROMREADRAW, &buf) == -1) {
perror ("ioctl()");
return 1;
/* exit (EXIT_FAILURE); */
}
break;
case _AM_READ_CD:
case _AM_READ_10:
if (_cdio_mmc_read_sectors (_obj->gen.fd, buf, lsn,
CDIO_MMC_READ_TYPE_ANY, 1)) {
perror ("ioctl()");
if (_obj->access_mode == _AM_READ_CD) {
cdio_info ("READ_CD failed; switching to READ_10 mode...");
_obj->access_mode = _AM_READ_10;
goto retry;
} else {
cdio_info ("READ_10 failed; switching to ioctl(CDROMREADAUDIO) mode...");
_obj->access_mode = _AM_IOCTL;
goto retry;
}
return 1;
}
break;
}
memcpy (data, buf, CDIO_CD_FRAMESIZE_RAW);
return 0;
}
/*!
Reads nblocks of mode2 sectors from cd device into data starting
from lsn.
@@ -886,6 +829,67 @@ _cdio_get_track_msf(void *env, track_t track_num, msf_t *msf)
}
}
/* checklist: /dev/cdrom, /dev/dvd /dev/hd?, /dev/scd? /dev/sr? */
static char checklist1[][40] = {
{"cdrom"}, {"dvd"}, {""}
};
static char checklist2[][40] = {
{"?a hd?"}, {"?0 scd?"}, {"?0 sr?"}, {""}
};
/*!
Return a string containing the default VCD device if none is specified.
*/
static char **
_cdio_get_devices (const CdIo *obj)
{
unsigned int i;
char drive[40];
char *ret_drive;
int exists;
char **drives = NULL;
unsigned int num_drives=0;
/* Scan the system for CD-ROM drives.
*/
for ( i=0; strlen(checklist1[i]) > 0; ++i ) {
sprintf(drive, "/dev/%s", checklist1[i]);
if ( (exists=cdio_is_cdrom(drive, NULL)) > 0 ) {
cdio_add_device_list(&drives, drive, &num_drives);
}
}
/* Now check the currently mounted CD drives */
if (NULL != (ret_drive = cdio_check_mounts("/etc/mtab"))) {
cdio_add_device_list(&drives, drive, &num_drives);
}
/* Finally check possible mountable drives in /etc/fstab */
if (NULL != (ret_drive = cdio_check_mounts("/etc/fstab"))) {
cdio_add_device_list(&drives, drive, &num_drives);
}
/* Scan the system for CD-ROM drives.
Not always 100% reliable, so use the USE_MNTENT code above first.
*/
for ( i=0; strlen(checklist2[i]) > 0; ++i ) {
unsigned int j;
char *insert;
exists = 1;
for ( j=checklist2[i][1]; exists; ++j ) {
sprintf(drive, "/dev/%s", &checklist2[i][3]);
insert = strchr(drive, '?');
if ( insert != NULL ) {
*insert = j;
}
if ( (exists=cdio_is_cdrom(drive, NULL)) > 0 ) {
cdio_add_device_list(&drives, drive, &num_drives);
}
}
}
cdio_add_device_list(&drives, NULL, &num_drives);
return drives;
}
#endif /* HAVE_LINUX_CDROM */
/*!
@@ -898,13 +902,6 @@ cdio_get_default_device_linux(void)
return NULL;
#else
/* checklist: /dev/cdrom, /dev/dvd /dev/hd?, /dev/scd? /dev/sr? */
static char checklist1[][40] = {
{"cdrom"}, {"dvd"}, {""}
};
static char checklist2[][40] = {
{"?a hd?"}, {"?0 scd?"}, {"?0 sr?"}, {""}
};
unsigned int i;
char drive[40];
int exists;
@@ -966,6 +963,7 @@ cdio_open_linux (const char *orig_source_name)
.eject_media = _cdio_eject_media,
.free = cdio_generic_free,
.get_arg = _cdio_get_arg,
.get_devices = _cdio_get_devices,
.get_default_device = cdio_get_default_device_linux,
.get_first_track_num= _cdio_get_first_track_num,
.get_mcn = _cdio_get_mcn,

View File

@@ -1,5 +1,5 @@
/*
$Id: cd_types.c,v 1.4 2003/09/14 07:05:34 rocky Exp $
$Id: cd_types.c,v 1.5 2003/09/28 17:14:20 rocky Exp $
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
@@ -117,8 +117,8 @@ static signature_t sigs[] =
analysis later.
*/
static int
_cdio_read_block(CdIo *cdio, int superblock, uint32_t offset, uint8_t bufnum,
track_t track_num)
_cdio_read_block(const CdIo *cdio, int superblock, uint32_t offset,
uint8_t bufnum, track_t track_num)
{
unsigned int track_sec_count = cdio_get_track_sec_count(cdio, track_num);
memset(buffer[bufnum], 0, CDIO_CD_FRAMESIZE);
@@ -207,11 +207,14 @@ _cdio_get_joliet_level( void )
is returned in cdio_analysis and the return value.
*/
cdio_fs_anal_t
cdio_guess_cd_type(/*in*/ CdIo *cdio, int start_session, track_t track_num,
cdio_guess_cd_type(const CdIo *cdio, int start_session, track_t track_num,
/*out*/ cdio_analysis_t *cdio_analysis)
{
int ret = 0;
if (TRACK_FORMAT_AUDIO == cdio_get_track_format(cdio, track_num))
return CDIO_FS_AUDIO;
if ( _cdio_read_block(cdio, ISO_PVD_SECTOR, start_session,
0, track_num) < 0 )
return CDIO_FS_UNKNOWN;
@@ -261,7 +264,7 @@ cdio_guess_cd_type(/*in*/ CdIo *cdio, int start_session, track_t track_num,
return ret;
if (_cdio_is_it(INDEX_BRIDGE) && _cdio_is_it(INDEX_CD_RTOS)) {
if (_cdio_is_it(INDEX_VIDEO_CD)) ret |= CDIO_FS_ANAL_VIDEOCDI;
if (_cdio_is_it(INDEX_VIDEO_CD)) ret |= CDIO_FS_ANAL_VIDEOCD;
else if (_cdio_is_it(INDEX_SVCD)) ret |= CDIO_FS_ANAL_SVCD;
} else if (_cdio_is_it(INDEX_SVCD)) ret |= CDIO_FS_ANAL_CVD;

View File

@@ -1,5 +1,5 @@
/*
$Id: cdio.c,v 1.27 2003/09/25 09:38:16 rocky Exp $
$Id: cdio.c,v 1.28 2003/09/28 17:14:20 rocky Exp $
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
@@ -31,11 +31,13 @@
#include <string.h>
#include "cdio_assert.h"
#include <cdio/cdio.h>
#include <cdio/cd_types.h>
#include <cdio/util.h>
#include <cdio/logging.h>
#include "cdio_private.h"
static const char _rcsid[] = "$Id: cdio.c,v 1.27 2003/09/25 09:38:16 rocky Exp $";
static const char _rcsid[] = "$Id: cdio.c,v 1.28 2003/09/28 17:14:20 rocky Exp $";
const char *track_format2str[6] =
@@ -99,8 +101,8 @@ CdIo_driver_t CdIo_all_drivers[CDIO_MAX_DRIVER+1] = {
{DRIVER_LINUX,
CDIO_SRC_IS_DEVICE_MASK|CDIO_SRC_IS_NATIVE_MASK,
"Linux",
"Linux ioctl and packet driver",
"GNU/Linux",
"GNU/Linux ioctl and MMC driver",
&cdio_have_linux,
&cdio_open_linux,
&cdio_get_default_device_linux,
@@ -159,6 +161,29 @@ CdIo_driver_t CdIo_all_drivers[CDIO_MAX_DRIVER+1] = {
};
static CdIo *
scan_for_driver(driver_id_t start, driver_id_t end, const char *source_name)
{
driver_id_t driver_id;
for (driver_id=start; driver_id<=end; driver_id++) {
if ((*CdIo_all_drivers[driver_id].have_driver)()) {
CdIo *ret=(*CdIo_all_drivers[driver_id].driver_open)(source_name);
if (ret != NULL) {
ret->driver_id = driver_id;
return ret;
}
}
}
return NULL;
}
const char *
cdio_driver_describe(driver_id_t driver_id)
{
return CdIo_all_drivers[driver_id].describe;
}
/*!
Eject media in CD drive if there is a routine to do so.
Return 0 if success and 1 for failure, and 2 if no routine.
@@ -184,6 +209,18 @@ cdio_eject_media (CdIo **obj)
}
}
/*!
Free device list returned by cdio_get_devices or
cdio_get_devices_with_cap.
*/
void cdio_free_device_list (char * device_list[])
{
if (NULL == device_list) return;
for ( ; *device_list != NULL ; *device_list++ )
free(*device_list);
}
/*!
Return the value associatied with key. NULL is returned if obj is NULL
or "key" does not exist.
@@ -229,10 +266,89 @@ cdio_get_default_device (const CdIo *obj)
}
}
const char *
cdio_driver_describe(driver_id_t driver_id)
/*!
Return an array of device names. if CdIo is NULL (we haven't
initialized a specific device driver), then find a suitable device
driver.
NULL is returned if we couldn't return a list of devices.
*/
char **
cdio_get_devices (const CdIo *cdio)
{
return CdIo_all_drivers[driver_id].describe;
const CdIo *c = (cdio == NULL)
? scan_for_driver(DRIVER_UNKNOWN, CDIO_MAX_DRIVER, NULL)
: cdio;
if (c == NULL) return NULL;
if (c->op.get_devices) {
return c->op.get_devices (c->env);
} else {
return NULL;
}
}
/*!
Return an array of device names in search_devices that have at
least the capabilities listed by cap. If search_devices is NULL,
then we'll search all possible CD drives.
If "any" is set false then every capability listed in the extended
portion of capabilities (i.e. not the basic filesystem) must be
satisified. If "any" is set true, then if any of the capabilities
matches, we call that a success.
To find a CD-drive of any type, use the mask CDIO_FS_MATCH_ALL.
NULL is returned if we couldn't get a default device.
*/
char **
cdio_get_devices_with_cap (char* search_devices[],
cdio_fs_anal_t capabilities, bool any)
{
char **drives=search_devices;
char **drives_ret=NULL;
int num_drives=0;
if (NULL == drives) drives=cdio_get_devices(NULL);
if (capabilities == CDIO_FS_MATCH_ALL) {
/* Duplicate drives into drives_ret. */
for( ; *drives != NULL; *drives++ ) {
cdio_add_device_list(&drives_ret, *drives, &num_drives);
}
} else {
cdio_fs_anal_t got_fs=0;
cdio_fs_anal_t need_fs = CDIO_FSTYPE(capabilities);
cdio_fs_anal_t need_fs_ext;
need_fs_ext = any
? capabilities | CDIO_FS_MASK
: capabilities & ~CDIO_FS_MASK;
for( ; *drives != NULL; drives++ ) {
CdIo *cdio = cdio_open(*drives, DRIVER_UNKNOWN);
if (NULL != cdio) {
track_t first_track = cdio_get_first_track_num(cdio);
cdio_analysis_t cdio_analysis;
got_fs = cdio_guess_cd_type(cdio, 0, first_track,
&cdio_analysis);
/* Match on fs and add */
if ( (CDIO_FS_UNKNOWN == need_fs || CDIO_FSTYPE(got_fs) == need_fs) )
{
bool doit = any
? (got_fs & need_fs_ext) != 0
: (got_fs | ~need_fs_ext) == -1;
if (doit)
cdio_add_device_list(&drives_ret, *drives, &num_drives);
}
cdio_destroy(cdio);
}
}
cdio_add_device_list(&drives_ret, NULL, &num_drives);
}
return drives_ret;
}
/*!
@@ -241,9 +357,9 @@ cdio_driver_describe(driver_id_t driver_id)
then return NULL.
*/
const char *
cdio_get_driver_name (const CdIo *obj)
cdio_get_driver_name (const CdIo *cdio)
{
return CdIo_all_drivers[obj->driver_id].name;
return CdIo_all_drivers[cdio->driver_id].name;
}
@@ -252,12 +368,12 @@ cdio_get_driver_name (const CdIo *obj)
CDIO_INVALID_TRACK is returned on error.
*/
track_t
cdio_get_first_track_num (const CdIo *obj)
cdio_get_first_track_num (const CdIo *cdio)
{
cdio_assert (obj != NULL);
cdio_assert (cdio != NULL);
if (obj->op.get_first_track_num) {
return obj->op.get_first_track_num (obj->env);
if (cdio->op.get_first_track_num) {
return cdio->op.get_first_track_num (cdio->env);
} else {
return CDIO_INVALID_TRACK;
}
@@ -269,10 +385,10 @@ cdio_get_first_track_num (const CdIo *obj)
then return NULL.
*/
char *
cdio_get_mcn (const CdIo *obj)
cdio_get_mcn (const CdIo *cdio)
{
if (obj->op.get_mcn) {
return obj->op.get_mcn (obj->env);
if (cdio->op.get_mcn) {
return cdio->op.get_mcn (cdio->env);
} else {
return NULL;
}
@@ -283,12 +399,12 @@ cdio_get_mcn (const CdIo *obj)
CDIO_INVALID_TRACK is returned on error.
*/
track_t
cdio_get_num_tracks (const CdIo *obj)
cdio_get_num_tracks (const CdIo *cdio)
{
if (obj == NULL) return CDIO_INVALID_TRACK;
if (cdio == NULL) return CDIO_INVALID_TRACK;
if (obj->op.get_num_tracks) {
return obj->op.get_num_tracks (obj->env);
if (cdio->op.get_num_tracks) {
return cdio->op.get_num_tracks (cdio->env);
} else {
return CDIO_INVALID_TRACK;
}
@@ -298,12 +414,12 @@ cdio_get_num_tracks (const CdIo *obj)
Get format of track.
*/
track_format_t
cdio_get_track_format(const CdIo *obj, track_t track_num)
cdio_get_track_format(const CdIo *cdio, track_t track_num)
{
cdio_assert (obj != NULL);
cdio_assert (cdio != NULL);
if (obj->op.get_track_format) {
return obj->op.get_track_format (obj->env, track_num);
if (cdio->op.get_track_format) {
return cdio->op.get_track_format (cdio->env, track_num);
} else {
return TRACK_FORMAT_ERROR;
}
@@ -318,12 +434,12 @@ cdio_get_track_format(const CdIo *obj, track_t track_num)
FIXME: there's gotta be a better design for this and get_track_format?
*/
bool
cdio_get_track_green(const CdIo *obj, track_t track_num)
cdio_get_track_green(const CdIo *cdio, track_t track_num)
{
cdio_assert (obj != NULL);
cdio_assert (cdio != NULL);
if (obj->op.get_track_green) {
return obj->op.get_track_green (obj->env, track_num);
if (cdio->op.get_track_green) {
return cdio->op.get_track_green (cdio->env, track_num);
} else {
return false;
}
@@ -331,22 +447,22 @@ cdio_get_track_green(const CdIo *obj, track_t track_num)
/*!
Return the starting LBA for track number
track_num in obj. Tracks numbers start at 1.
track_num in cdio. Tracks numbers start at 1.
The "leadout" track is specified either by
using track_num LEADOUT_TRACK or the total tracks+1.
CDIO_INVALID_LBA is returned on error.
*/
lba_t
cdio_get_track_lba(const CdIo *obj, track_t track_num)
cdio_get_track_lba(const CdIo *cdio, track_t track_num)
{
if (obj == NULL) return CDIO_INVALID_LBA;
if (cdio == NULL) return CDIO_INVALID_LBA;
if (obj->op.get_track_lba) {
return obj->op.get_track_lba (obj->env, track_num);
if (cdio->op.get_track_lba) {
return cdio->op.get_track_lba (cdio->env, track_num);
} else {
msf_t msf;
if (obj->op.get_track_msf)
if (cdio_get_track_msf(obj, track_num, &msf))
if (cdio->op.get_track_msf)
if (cdio_get_track_msf(cdio, track_num, &msf))
return cdio_msf_to_lba(&msf);
return CDIO_INVALID_LBA;
}
@@ -354,21 +470,21 @@ cdio_get_track_lba(const CdIo *obj, track_t track_num)
/*!
Return the starting LSN for track number
track_num in obj. Tracks numbers start at 1.
track_num in cdio. Tracks numbers start at 1.
The "leadout" track is specified either by
using track_num LEADOUT_TRACK or the total tracks+1.
CDIO_INVALID_LBA is returned on error.
*/
lsn_t
cdio_get_track_lsn(const CdIo *obj, track_t track_num)
cdio_get_track_lsn(const CdIo *cdio, track_t track_num)
{
if (obj == NULL) return CDIO_INVALID_LBA;
if (cdio == NULL) return CDIO_INVALID_LBA;
if (obj->op.get_track_lba) {
return cdio_lba_to_lsn(obj->op.get_track_lba (obj->env, track_num));
if (cdio->op.get_track_lba) {
return cdio_lba_to_lsn(cdio->op.get_track_lba (cdio->env, track_num));
} else {
msf_t msf;
if (cdio_get_track_msf(obj, track_num, &msf))
if (cdio_get_track_msf(cdio, track_num, &msf))
return cdio_msf_to_lsn(&msf);
return CDIO_INVALID_LSN;
}
@@ -376,20 +492,20 @@ cdio_get_track_lsn(const CdIo *obj, track_t track_num)
/*!
Return the starting MSF (minutes/secs/frames) for track number
track_num in obj. Track numbers start at 1.
track_num in cdio. Track numbers start at 1.
The "leadout" track is specified either by
using track_num LEADOUT_TRACK or the total tracks+1.
False is returned if there is no track entry.
*/
bool
cdio_get_track_msf(const CdIo *obj, track_t track_num, /*out*/ msf_t *msf)
cdio_get_track_msf(const CdIo *cdio, track_t track_num, /*out*/ msf_t *msf)
{
cdio_assert (obj != NULL);
cdio_assert (cdio != NULL);
if (obj->op.get_track_msf) {
return obj->op.get_track_msf (obj->env, track_num, msf);
} else if (obj->op.get_track_lba) {
lba_t lba = obj->op.get_track_lba (obj->env, track_num);
if (cdio->op.get_track_msf) {
return cdio->op.get_track_msf (cdio->env, track_num, msf);
} else if (cdio->op.get_track_lba) {
lba_t lba = cdio->op.get_track_lba (cdio->env, track_num);
if (lba == CDIO_INVALID_LBA) return false;
cdio_lba_to_msf(lba, msf);
return true;
@@ -405,13 +521,13 @@ cdio_get_track_msf(const CdIo *obj, track_t track_num, /*out*/ msf_t *msf)
0 is returned if there is an error.
*/
unsigned int
cdio_get_track_sec_count(const CdIo *obj, track_t track_num)
cdio_get_track_sec_count(const CdIo *cdio, track_t track_num)
{
track_t num_tracks = cdio_get_num_tracks(obj);
track_t num_tracks = cdio_get_num_tracks(cdio);
if (track_num >=1 && track_num <= num_tracks)
return ( cdio_get_track_lba(obj, track_num+1)
- cdio_get_track_lba(obj, track_num) );
return ( cdio_get_track_lba(cdio, track_num+1)
- cdio_get_track_lba(cdio, track_num) );
return 0;
}
@@ -460,28 +576,28 @@ cdio_init(void)
CdIo *
cdio_new (void *env, const cdio_funcs *funcs)
{
CdIo *new_obj;
CdIo *new_cdio;
new_obj = _cdio_malloc (sizeof (CdIo));
new_cdio = _cdio_malloc (sizeof (CdIo));
new_obj->env = env;
new_obj->op = *funcs;
new_cdio->env = env;
new_cdio->op = *funcs;
return new_obj;
return new_cdio;
}
/*!
Free any resources associated with obj.
Free any resources associated with cdio.
*/
void
cdio_destroy (CdIo *obj)
cdio_destroy (CdIo *cdio)
{
CdIo_last_driver = CDIO_DRIVER_UNINIT;
if (obj == NULL) return;
if (cdio == NULL) return;
if (obj->op.free != NULL)
obj->op.free (obj->env);
free (obj);
if (cdio->op.free != NULL)
cdio->op.free (cdio->env);
free (cdio);
}
/*!
@@ -490,12 +606,12 @@ cdio_destroy (CdIo *obj)
Similar to (if not the same as) libc's lseek()
*/
off_t
cdio_lseek (const CdIo *obj, off_t offset, int whence)
cdio_lseek (const CdIo *cdio, off_t offset, int whence)
{
if (obj == NULL) return -1;
if (cdio == NULL) return -1;
if (obj->op.lseek)
return obj->op.lseek (obj->env, offset, whence);
if (cdio->op.lseek)
return cdio->op.lseek (cdio->env, offset, whence);
return -1;
}
@@ -505,35 +621,35 @@ cdio_lseek (const CdIo *obj, off_t offset, int whence)
Similar to (if not the same as) libc's read()
*/
ssize_t
cdio_read (const CdIo *obj, void *buf, size_t size)
cdio_read (const CdIo *cdio, void *buf, size_t size)
{
if (obj == NULL) return -1;
if (cdio == NULL) return -1;
if (obj->op.read)
return obj->op.read (obj->env, buf, size);
if (cdio->op.read)
return cdio->op.read (cdio->env, buf, size);
return -1;
}
int
cdio_read_audio_sector (const CdIo *obj, void *buf, lsn_t lsn)
cdio_read_audio_sector (const CdIo *cdio, void *buf, lsn_t lsn)
{
cdio_assert (obj != NULL);
cdio_assert (cdio != NULL);
cdio_assert (buf != NULL);
if (obj->op.read_audio_sectors != NULL)
return obj->op.read_audio_sectors (obj->env, buf, lsn, 1);
if (cdio->op.read_audio_sectors != NULL)
return cdio->op.read_audio_sectors (cdio->env, buf, lsn, 1);
return -1;
}
int
cdio_read_audio_sectors (const CdIo *obj, void *buf, lsn_t lsn,
cdio_read_audio_sectors (const CdIo *cdio, void *buf, lsn_t lsn,
unsigned int nblocks)
{
cdio_assert (obj != NULL);
cdio_assert (cdio != NULL);
cdio_assert (buf != NULL);
if (obj->op.read_audio_sectors != NULL)
return obj->op.read_audio_sectors (obj->env, buf, lsn, nblocks);
if (cdio->op.read_audio_sectors != NULL)
return cdio->op.read_audio_sectors (cdio->env, buf, lsn, nblocks);
return -1;
}
@@ -542,24 +658,24 @@ cdio_read_audio_sectors (const CdIo *obj, void *buf, lsn_t lsn,
into data starting from lsn. Returns 0 if no error.
*/
int
cdio_read_mode1_sector (const CdIo *obj, void *data, lsn_t lsn, bool is_form2)
cdio_read_mode1_sector (const CdIo *cdio, void *data, lsn_t lsn, bool is_form2)
{
uint32_t size = is_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE ;
char buf[M2RAW_SECTOR_SIZE] = { 0, };
int ret;
cdio_assert (obj != NULL);
cdio_assert (cdio != NULL);
cdio_assert (data != NULL);
if (obj->op.lseek && obj->op.read) {
if (0 > cdio_lseek(obj, CDIO_CD_FRAMESIZE*lsn, SEEK_SET))
if (cdio->op.lseek && cdio->op.read) {
if (0 > cdio_lseek(cdio, CDIO_CD_FRAMESIZE*lsn, SEEK_SET))
return -1;
if (0 > cdio_read(obj, buf, CDIO_CD_FRAMESIZE))
if (0 > cdio_read(cdio, buf, CDIO_CD_FRAMESIZE))
return -1;
memcpy (data, buf, size);
return 0;
} else {
ret = cdio_read_mode2_sector(obj, data, lsn, is_form2);
ret = cdio_read_mode2_sector(cdio, data, lsn, is_form2);
if (ret == 0)
memcpy (data, buf+CDIO_CD_SUBHEADER_SIZE, size);
}
@@ -568,17 +684,17 @@ cdio_read_mode1_sector (const CdIo *obj, void *data, lsn_t lsn, bool is_form2)
}
int
cdio_read_mode1_sectors (const CdIo *obj, void *data, lsn_t lsn,
cdio_read_mode1_sectors (const CdIo *cdio, void *data, lsn_t lsn,
bool is_form2, unsigned int num_sectors)
{
uint32_t size = is_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE ;
int retval;
int i;
cdio_assert (obj != NULL);
cdio_assert (cdio != NULL);
for (i = 0; i < num_sectors; i++) {
if ( (retval = cdio_read_mode1_sector (obj,
if ( (retval = cdio_read_mode1_sector (cdio,
((char *)data) + (size * i),
lsn + i, is_form2)) )
return retval;
@@ -591,71 +707,54 @@ cdio_read_mode1_sectors (const CdIo *obj, void *data, lsn_t lsn,
from lsn. Returns 0 if no error.
*/
int
cdio_read_mode2_sector (const CdIo *obj, void *buf, lsn_t lsn,
cdio_read_mode2_sector (const CdIo *cdio, void *buf, lsn_t lsn,
bool is_form2)
{
cdio_assert (obj != NULL);
cdio_assert (cdio != NULL);
cdio_assert (buf != NULL);
cdio_assert (obj->op.read_mode2_sector != NULL
|| obj->op.read_mode2_sectors != NULL);
cdio_assert (cdio->op.read_mode2_sector != NULL
|| cdio->op.read_mode2_sectors != NULL);
if (obj->op.read_mode2_sector)
return obj->op.read_mode2_sector (obj->env, buf, lsn, is_form2);
if (cdio->op.read_mode2_sector)
return cdio->op.read_mode2_sector (cdio->env, buf, lsn, is_form2);
/* fallback */
if (obj->op.read_mode2_sectors != NULL)
return cdio_read_mode2_sectors (obj, buf, lsn, is_form2, 1);
if (cdio->op.read_mode2_sectors != NULL)
return cdio_read_mode2_sectors (cdio, buf, lsn, is_form2, 1);
return 1;
}
int
cdio_read_mode2_sectors (const CdIo *obj, void *buf, lsn_t lsn, bool mode2raw,
cdio_read_mode2_sectors (const CdIo *cdio, void *buf, lsn_t lsn, bool mode2raw,
unsigned num_sectors)
{
cdio_assert (obj != NULL);
cdio_assert (cdio != NULL);
cdio_assert (buf != NULL);
cdio_assert (obj->op.read_mode2_sectors != NULL);
cdio_assert (cdio->op.read_mode2_sectors != NULL);
return obj->op.read_mode2_sectors (obj->env, buf, lsn,
return cdio->op.read_mode2_sectors (cdio->env, buf, lsn,
mode2raw, num_sectors);
}
uint32_t
cdio_stat_size (const CdIo *obj)
cdio_stat_size (const CdIo *cdio)
{
cdio_assert (obj != NULL);
cdio_assert (cdio != NULL);
return obj->op.stat_size (obj->env);
return cdio->op.stat_size (cdio->env);
}
/*!
Set the arg "key" with "value" in the source device.
*/
int
cdio_set_arg (CdIo *obj, const char key[], const char value[])
cdio_set_arg (CdIo *cdio, const char key[], const char value[])
{
cdio_assert (obj != NULL);
cdio_assert (obj->op.set_arg != NULL);
cdio_assert (cdio != NULL);
cdio_assert (cdio->op.set_arg != NULL);
cdio_assert (key != NULL);
return obj->op.set_arg (obj->env, key, value);
}
static CdIo *
scan_for_driver(driver_id_t start, driver_id_t end, const char *source_name)
{
driver_id_t driver_id;
for (driver_id=start; driver_id<=end; driver_id++) {
if ((*CdIo_all_drivers[driver_id].have_driver)()) {
CdIo *ret=(*CdIo_all_drivers[driver_id].driver_open)(source_name);
if (ret != NULL) {
ret->driver_id = driver_id;
return ret;
}
}
}
return NULL;
return cdio->op.set_arg (cdio->env, key, value);
}
/*! Sets up to read from place specified by source_name and
@@ -680,7 +779,7 @@ cdio_open (const char *orig_source_name, driver_id_t driver_id)
if (CdIo_last_driver == -1) cdio_init();
if (NULL == orig_source_name)
if (NULL == orig_source_name || strlen(orig_source_name)==0)
source_name = cdio_get_default_device(NULL);
else
source_name = strdup(orig_source_name);

View File

@@ -1,5 +1,5 @@
/*
$Id: cdio_private.h,v 1.14 2003/09/25 09:38:16 rocky Exp $
$Id: cdio_private.h,v 1.15 2003/09/28 17:14:21 rocky Exp $
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
@@ -55,6 +55,15 @@ extern "C" {
*/
const char * (*get_arg) (void *env, const char key[]);
/*!
Return an array of device names. if CdIo is NULL (we haven't
initialized a specific device driver), then find a suitable device
driver.
NULL is returned if we couldn't return a list of devices.
*/
char ** (*get_devices) (const CdIo *obj);
/*!
Return a string containing the default CD device if none is specified.
*/
@@ -227,6 +236,13 @@ extern "C" {
on a particular host. */
extern CdIo_driver_t CdIo_all_drivers[CDIO_MAX_DRIVER+1];
/*!
Add/allocate a drive to the end of drives.
Use cdio_free_device_list() to free this device_list.
*/
void cdio_add_device_list(char **device_list[], const char *drive,
int *num_drives);
/*!
Bogus eject media when there is no ejectable media, e.g. a disk image
We always return 2. Should we also free resources?

View File

@@ -1,5 +1,5 @@
/*
$Id: cd-info.c,v 1.40 2003/09/28 14:16:01 rocky Exp $
$Id: cd-info.c,v 1.41 2003/09/28 17:14:21 rocky Exp $
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1996,1997,1998 Gerd Knorr <kraxel@bytesex.org>
@@ -596,7 +596,7 @@ print_analysis(int ms_offset, cdio_analysis_t cdio_analysis,
int need_lf;
switch(CDIO_FSTYPE(fs)) {
case CDIO_FS_NO_DATA:
case CDIO_FS_AUDIO:
if (num_audio > 0) {
printf("Audio CD, CDDB disc ID is %08lx\n",
cddb_discid(cdio, num_tracks));
@@ -670,7 +670,7 @@ print_analysis(int ms_offset, cdio_analysis_t cdio_analysis,
need_lf += printf("CD-Plus/Extra ");
if (fs & CDIO_FS_ANAL_BOOTABLE)
need_lf += printf("bootable CD ");
if (fs & CDIO_FS_ANAL_VIDEOCDI && num_audio == 0) {
if (fs & CDIO_FS_ANAL_VIDEOCD && num_audio == 0) {
need_lf += printf("Video CD ");
}
if (fs & CDIO_FS_ANAL_SVCD)
@@ -679,7 +679,7 @@ print_analysis(int ms_offset, cdio_analysis_t cdio_analysis,
need_lf += printf("Chaoji Video CD (CVD)");
if (need_lf) printf("\n");
#ifdef HAVE_VCDINFO
if (fs & (CDIO_FS_ANAL_VIDEOCDI|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_SVCD))
if (fs & (CDIO_FS_ANAL_VIDEOCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_SVCD))
if (!opts.no_vcd) {
printf("\n");
print_vcd_info();
@@ -729,7 +729,7 @@ main(int argc, const char *argv[])
{
CdIo *cdio=NULL;
cdio_fs_anal_t fs=0;
cdio_fs_anal_t fs=CDIO_FS_AUDIO;
int i;
lsn_t start_track_lsn; /* lsn of first track */
lsn_t data_start =0; /* start of data area */