diff options
Diffstat (limited to 'src/input/vcd/libcdio/_cdio_linux.c')
-rw-r--r-- | src/input/vcd/libcdio/_cdio_linux.c | 142 |
1 files changed, 117 insertions, 25 deletions
diff --git a/src/input/vcd/libcdio/_cdio_linux.c b/src/input/vcd/libcdio/_cdio_linux.c index 51afb728e..e5dd47551 100644 --- a/src/input/vcd/libcdio/_cdio_linux.c +++ b/src/input/vcd/libcdio/_cdio_linux.c @@ -1,8 +1,8 @@ /* - $Id: _cdio_linux.c,v 1.1 2003/10/13 11:47:11 f1rmb Exp $ + $Id: _cdio_linux.c,v 1.2 2004/04/11 12:20:31 miguelfreitas Exp $ Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org> - Copyright (C) 2002,2003 Rocky Bernstein <rocky@panix.com> + Copyright (C) 2002, 2003, 2004 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 @@ -27,7 +27,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.1 2003/10/13 11:47:11 f1rmb Exp $"; +static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.2 2004/04/11 12:20:31 miguelfreitas Exp $"; #include <string.h> @@ -110,7 +110,7 @@ cdio_is_cdrom(char *drive, char *mnttype) } /* If it does exist, verify that it's an available CD-ROM */ - cdfd = open(drive, (O_RDONLY|O_EXCL|O_NONBLOCK), 0); + cdfd = open(drive, (O_RDONLY|O_NONBLOCK), 0); if ( cdfd >= 0 ) { if ( ioctl(cdfd, CDROMREADTOCHDR, &tochdr) != -1 ) { is_cd = true; @@ -177,10 +177,9 @@ cdio_check_mounts(const char *mtab) } if ( strcmp(mnt_type, "iso9660") == 0 ) { if (cdio_is_cdrom(mnt_dev, mnt_type) > 0) { - free(mnt_dev); free(mnt_type); endmntent(mntfp); - return strdup(mnt_dev); + return mnt_dev; } } free(mnt_dev); @@ -354,12 +353,109 @@ _read_packet_mode2_sectors (int fd, void *buf, lba_t lba, } /*! + Reads a single mode1 sector from cd device into data starting + from lsn. Returns 0 if no error. + */ +static int +_cdio_read_mode1_sector (void *env, void *data, lsn_t lsn, + bool b_form2) +{ + + char buf[M2RAW_SECTOR_SIZE] = { 0, }; +#if FIXED + struct cdrom_msf *msf = (struct cdrom_msf *) &buf; + msf_t _msf; + + _img_private_t *_obj = env; + + cdio_lba_to_msf (cdio_lsn_to_lba(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 mode1"); + return 1; + break; + + case _AM_IOCTL: + if (ioctl (_obj->gen.fd, CDROMREADMODE1, &buf) == -1) + { + perror ("ioctl()"); + return 1; + /* exit (EXIT_FAILURE); */ + } + break; + + case _AM_READ_CD: + case _AM_READ_10: + if (_read_packet_mode2_sectors (_obj->gen.fd, buf, lsn, 1, + (_obj->access_mode == _AM_READ_10))) + { + 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(CDROMREADMODE2) mode..."); + _obj->access_mode = _AM_IOCTL; + goto retry; + } + return 1; + } + break; + } + + memcpy (data, buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE, + b_form2 ? M2RAW_SECTOR_SIZE: CDIO_CD_FRAMESIZE); + +#else + if (0 > cdio_generic_lseek(env, CDIO_CD_FRAMESIZE*lsn, SEEK_SET)) + return -1; + if (0 > cdio_generic_read(env, buf, CDIO_CD_FRAMESIZE)) + return -1; + memcpy (data, buf, b_form2 ? M2RAW_SECTOR_SIZE: CDIO_CD_FRAMESIZE); +#endif + return 0; +} + +/*! + Reads nblocks of mode2 sectors from cd device into data starting + from lsn. + Returns 0 if no error. + */ +static int +_cdio_read_mode1_sectors (void *env, void *data, lsn_t lsn, + bool b_form2, unsigned int nblocks) +{ + _img_private_t *_obj = env; + unsigned int i; + int retval; + unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE; + + for (i = 0; i < nblocks; i++) { + if ( (retval = _cdio_read_mode1_sector (_obj, + ((char *)data) + (blocksize * i), + lsn + i, b_form2)) ) + return retval; + } + return 0; +} + +/*! Reads a single mode2 sector from cd device into data starting from lsn. Returns 0 if no error. */ static int _cdio_read_mode2_sector (void *env, void *data, lsn_t lsn, - bool mode2_form2) + bool b_form2) { char buf[M2RAW_SECTOR_SIZE] = { 0, }; struct cdrom_msf *msf = (struct cdrom_msf *) &buf; @@ -412,7 +508,7 @@ _cdio_read_mode2_sector (void *env, void *data, lsn_t lsn, break; } - if (mode2_form2) + if (b_form2) memcpy (data, buf, M2RAW_SECTOR_SIZE); else memcpy (((char *)data), buf + CDIO_CD_SUBHEADER_SIZE, CDIO_CD_FRAMESIZE); @@ -427,27 +523,18 @@ _cdio_read_mode2_sector (void *env, void *data, lsn_t lsn, */ static int _cdio_read_mode2_sectors (void *env, void *data, lsn_t lsn, - bool mode2_form2, unsigned int nblocks) + bool b_form2, unsigned int nblocks) { _img_private_t *_obj = env; unsigned int i; int retval; + unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE; for (i = 0; i < nblocks; i++) { - if (mode2_form2) { - if ( (retval = _cdio_read_mode2_sector (_obj, - ((char *)data) - + (M2RAW_SECTOR_SIZE * i), - lsn + i, true)) ) - return retval; - } else { - char buf[M2RAW_SECTOR_SIZE] = { 0, }; - if ( (retval = _cdio_read_mode2_sector (_obj, buf, lsn + i, true)) ) - return retval; - - memcpy (((char *)data) + (CDIO_CD_FRAMESIZE * i), - buf + CDIO_CD_SUBHEADER_SIZE, CDIO_CD_FRAMESIZE); - } + if ( (retval = _cdio_read_mode2_sector (_obj, + ((char *)data) + (blocksize * i), + lsn + i, b_form2)) ) + return retval; } return 0; } @@ -727,6 +814,7 @@ _cdio_get_mcn (void *env) { struct cdrom_mcn mcn; _img_private_t *_obj = env; + memset(&mcn, 0, sizeof(mcn)); if (ioctl(_obj->gen.fd, CDROM_GET_MCN, &mcn) != 0) return NULL; return strdup(mcn.medium_catalog_number); @@ -866,12 +954,14 @@ cdio_get_devices_linux (void) /* Now check the currently mounted CD drives */ if (NULL != (ret_drive = cdio_check_mounts("/etc/mtab"))) { - cdio_add_device_list(&drives, drive, &num_drives); + cdio_add_device_list(&drives, ret_drive, &num_drives); + free(ret_drive); } /* 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); + cdio_add_device_list(&drives, ret_drive, &num_drives); + free(ret_drive); } /* Scan the system for CD-ROM drives. @@ -980,6 +1070,8 @@ cdio_open_linux (const char *orig_source_name) .lseek = cdio_generic_lseek, .read = cdio_generic_read, .read_audio_sectors = _cdio_read_audio_sectors, + .read_mode1_sector = _cdio_read_mode1_sector, + .read_mode1_sectors = _cdio_read_mode1_sectors, .read_mode2_sector = _cdio_read_mode2_sector, .read_mode2_sectors = _cdio_read_mode2_sectors, .set_arg = _cdio_set_arg, |