diff --git a/doc/libcdio.texi b/doc/libcdio.texi index 9a477577..4ccb6093 100644 --- a/doc/libcdio.texi +++ b/doc/libcdio.texi @@ -46,7 +46,7 @@ development.'' @titlepage @title GNU libcdio library -@subtitle $Id: libcdio.texi,v 1.38 2005/02/01 03:35:43 rocky Exp $ +@subtitle $Id: libcdio.texi,v 1.39 2005/02/05 04:25:14 rocky Exp $ @author Rocky Bernstein et al. @page @@ -1471,7 +1471,7 @@ firmware revision number of a CD drive. For this command to work, usually a CD to be loaded into the drive; odd since the CD itself is not used. -This can be found in the distribution as @file{example/scsi-mmc1.c}. +This can be found in the distribution as @file{example/mmc1.c}. @smallexample #ifdef HAVE_CONFIG_H @@ -1721,11 +1721,11 @@ paranoia's open. I imagine in many cases such as media players this may be what will be done since, one may want to get CDDB/CD-Text info beforehand. -@item @code{scsi-mmc1.c} +@item @code{mmc1.c} A program to show issuing a simple MMC command (@code{INQUIRY}). -@item @code{scsi-mmc2.c} +@item @code{mmc2.c} A more involved MMC command to list CD and drive features from a SCSI-MMC @code{GET_CONFIGURATION} command. diff --git a/lib/driver/_cdio_stdio.c b/lib/driver/_cdio_stdio.c index 71799365..c7a19e94 100644 --- a/lib/driver/_cdio_stdio.c +++ b/lib/driver/_cdio_stdio.c @@ -1,5 +1,5 @@ /* - $Id: _cdio_stdio.c,v 1.3 2005/02/03 07:35:15 rocky Exp $ + $Id: _cdio_stdio.c,v 1.4 2005/02/05 04:25:14 rocky Exp $ Copyright (C) 2000 Herbert Valerio Riedel Copyright (C) 2003, 2004, 2005 Rocky Bernstein @@ -39,7 +39,7 @@ #include "_cdio_stream.h" #include "_cdio_stdio.h" -static const char _rcsid[] = "$Id: _cdio_stdio.c,v 1.3 2005/02/03 07:35:15 rocky Exp $"; +static const char _rcsid[] = "$Id: _cdio_stdio.c,v 1.4 2005/02/05 04:25:14 rocky Exp $"; #define CDIO_STDIO_BUFSIZE (128*1024) @@ -106,27 +106,26 @@ _stdio_free(void *user_data) of-file indicator for the stream and undoes any effects of the ungetc(3) function on the same stream. - RETURN VALUE - Upon successful completion, return 0, - Otherwise, -1 is returned and the global variable errno is set to indi- - cate the error. + @return upon successful completion, DRIVER_OP_SUCCESS, else, + DRIVER_OP_ERROR is returned and the global variable errno is set to + indicate the error. */ -static long -_stdio_seek(void *user_data, long offset, int whence) +static driver_return_code_t +_stdio_seek(void *p_user_data, long i_offset, int whence) { - _UserData *const ud = user_data; + _UserData *const ud = p_user_data; - if ( (offset=fseek (ud->fd, offset, whence)) ) { + if ( (i_offset=fseek (ud->fd, i_offset, whence)) ) { cdio_error ("fseek (): %s", strerror (errno)); } - return offset; + return i_offset; } static long int -_stdio_stat(void *user_data) +_stdio_stat(void *p_user_data) { - const _UserData *const ud = user_data; + const _UserData *const ud = p_user_data; return ud->st_size; } diff --git a/lib/driver/_cdio_stream.c b/lib/driver/_cdio_stream.c index 916d0893..abc75077 100644 --- a/lib/driver/_cdio_stream.c +++ b/lib/driver/_cdio_stream.c @@ -1,5 +1,5 @@ /* - $Id: _cdio_stream.c,v 1.5 2005/02/03 07:35:15 rocky Exp $ + $Id: _cdio_stream.c,v 1.6 2005/02/05 04:25:14 rocky Exp $ Copyright (C) 2000, 2004, 2005 Herbert Valerio Riedel Copyright (C) 2005 Rocky Bernstein @@ -35,7 +35,7 @@ #include #include "_cdio_stream.h" -static const char _rcsid[] = "$Id: _cdio_stream.c,v 1.5 2005/02/03 07:35:15 rocky Exp $"; +static const char _rcsid[] = "$Id: _cdio_stream.c,v 1.6 2005/02/05 04:25:14 rocky Exp $"; /* * DataSource implementations @@ -82,21 +82,20 @@ _cdio_stream_open_if_necessary(CdioDataSource_t *p_obj) of-file indicator for the stream and undoes any effects of the ungetc(3) function on the same stream. - RETURN VALUE - Upon successful completion, return 0, - Otherwise, -1 is returned and the global variable errno is set to indi- - cate the error. + @return unpon successful completion, DRIVER_OP_SUCCESS, else, + DRIVER_OP_ERROR is returned and the global variable errno is set to + indicate the error. */ -long int +driver_return_code_t cdio_stream_seek(CdioDataSource_t* p_obj, long int offset, int whence) { - if (!p_obj) return -1; + if (!p_obj) return DRIVER_OP_UNINIT; if (!_cdio_stream_open_if_necessary(p_obj)) /* errno is set by _cdio_stream_open_if necessary. */ - return -1; + return DRIVER_OP_ERROR; - if (offset < 0) return -1; + if (offset < 0) return DRIVER_OP_ERROR; if (p_obj->position != offset) { #ifdef STREAM_DEBUG diff --git a/lib/driver/_cdio_stream.h b/lib/driver/_cdio_stream.h index a85c6459..51ffabcb 100644 --- a/lib/driver/_cdio_stream.h +++ b/lib/driver/_cdio_stream.h @@ -1,8 +1,8 @@ /* - $Id: _cdio_stream.h,v 1.2 2005/01/20 01:00:52 rocky Exp $ + $Id: _cdio_stream.h,v 1.3 2005/02/05 04:25:14 rocky Exp $ Copyright (C) 2000 Herbert Valerio Riedel - Copyright (C) 2003, 2004 Rocky Bernstein + Copyright (C) 2003, 2004, 2005 Rocky Bernstein 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 @@ -36,7 +36,8 @@ extern "C" { typedef long(*cdio_data_read_t)(void *user_data, void *buf, long count); - typedef long(*cdio_data_seek_t)(void *user_data, long offset, int whence); + typedef driver_return_code_t(*cdio_data_seek_t)(void *user_data, long offset, + int whence); typedef long(*cdio_data_stat_t)(void *user_data); @@ -76,7 +77,7 @@ extern "C" { We do not distinguish between end-of-file and error, and callers must use feof(3) and ferror(3) to determine which occurred. */ - long cdio_stream_read(CdioDataSource_t* p_obj, void *ptr, long size, + long cdio_stream_read(CdioDataSource_t* p_obj, void *ptr, long i_size, long nmemb); /*! @@ -91,12 +92,12 @@ extern "C" { of-file indicator for the stream and undoes any effects of the ungetc(3) function on the same stream. - RETURN VALUE - Upon successful completion, return 0, - Otherwise, -1 is returned and the global variable errno is set to indi- - cate the error. + @return upon successful completion, DRIVER_OP_SUCCESS, else, + DRIVER_OP_ERROR is returned and the global variable errno is set to + indicate the error. */ - long int cdio_stream_seek(CdioDataSource_t *p_obj, long offset, int whence); + driver_return_code_t cdio_stream_seek(CdioDataSource_t *p_obj, long offset, + int whence); /*! Return whatever size of stream reports, I guess unit size is bytes. diff --git a/lib/driver/read.c b/lib/driver/read.c index 09190065..12260e26 100644 --- a/lib/driver/read.c +++ b/lib/driver/read.c @@ -1,5 +1,5 @@ /* - $Id: read.c,v 1.3 2005/01/23 19:16:58 rocky Exp $ + $Id: read.c,v 1.4 2005/02/05 04:25:14 rocky Exp $ Copyright (C) 2005 Rocky Bernstein @@ -104,7 +104,7 @@ cdio_read (const CdIo_t *p_cdio, void *p_buf, size_t size) /*! Reads an audio sector from cd device into data starting - from lsn. Returns 0 if no error. + from lsn. Returns DRIVER_OP_SUCCESS if no error. */ driver_return_code_t cdio_read_audio_sector (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn) @@ -117,7 +117,7 @@ cdio_read_audio_sector (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn) /*! Reads audio sectors from cd device into data starting - from lsn. Returns 0 if no error. + from lsn. Returns DRIVER_OP_SUCCESS if no error. */ driver_return_code_t cdio_read_audio_sectors (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, @@ -135,7 +135,7 @@ cdio_read_audio_sectors (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, /*! Reads a single mode1 form1 or form2 sector from cd device - into data starting from lsn. Returns 0 if no error. + into data starting from lsn. Returns DRIVER_OP_SUCCESS if no error. */ driver_return_code_t cdio_read_mode1_sector (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, diff --git a/lib/driver/sector.c b/lib/driver/sector.c index a284f07c..35c4d701 100644 --- a/lib/driver/sector.c +++ b/lib/driver/sector.c @@ -1,7 +1,7 @@ /* - $Id: sector.c,v 1.1 2004/12/18 17:29:32 rocky Exp $ + $Id: sector.c,v 1.2 2005/02/05 04:25:14 rocky Exp $ - Copyright (C) 2004 Rocky Bernstein + Copyright (C) 2004, 2005 Rocky Bernstein Copyright (C) 2000 Herbert Valerio Riedel This program is free software; you can redistribute it and/or modify @@ -35,8 +35,13 @@ #include -static const char _rcsid[] = "$Id: sector.c,v 1.1 2004/12/18 17:29:32 rocky Exp $"; +static const char _rcsid[] = "$Id: sector.c,v 1.2 2005/02/05 04:25:14 rocky Exp $"; +/*! String of bytes used to identify the beginning of a Mode 1 or + Mode 2 sector. */ +const uint8_t CDIO_SECTOR_SYNC_HEADER[CDIO_CD_SYNC_SIZE] = + {0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}; + lba_t cdio_lba_to_lsn (lba_t lba) { diff --git a/lib/iso9660/iso9660_fs.c b/lib/iso9660/iso9660_fs.c index 10e49e9e..5bb92d23 100644 --- a/lib/iso9660/iso9660_fs.c +++ b/lib/iso9660/iso9660_fs.c @@ -1,8 +1,8 @@ /* - $Id: iso9660_fs.c,v 1.5 2005/02/04 02:18:12 rocky Exp $ + $Id: iso9660_fs.c,v 1.6 2005/02/05 04:25:14 rocky Exp $ Copyright (C) 2001 Herbert Valerio Riedel - Copyright (C) 2003, 2004 Rocky Bernstein + Copyright (C) 2003, 2004, 2005 Rocky Bernstein 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 @@ -51,20 +51,127 @@ #include -static const char _rcsid[] = "$Id: iso9660_fs.c,v 1.5 2005/02/04 02:18:12 rocky Exp $"; +static const char _rcsid[] = "$Id: iso9660_fs.c,v 1.6 2005/02/05 04:25:14 rocky Exp $"; /* Implementation of iso9660_t type */ struct _iso9660 { CdioDataSource_t *stream; /* Stream pointer */ - bool b_xa; /* true if has XA attributes. */ - uint8_t i_joliet_level;/* 0 = no Joliet extensions. - 1-3: Joliet level. */ + bool b_xa; /* true if has XA attributes. */ + uint8_t i_joliet_level; /* 0 = no Joliet extensions. + 1-3: Joliet level. */ iso9660_pvd_t pvd; iso9660_svd_t svd; iso_extension_mask_t iso_extension_mask; /* What extensions we tolerate. */ + uint32_t i_datastart; /* Usually 0 when i_framesize is ISO_BLOCKSIZE. + This is the normal condition. But in a fuzzy + read we may be reading a CD-image + and not a true ISO 9660 image this might be + CDIO_CD_SYNC_SIZE + */ + uint32_t i_framesize; /* Usually ISO_BLOCKSIZE (2048), but in a + fuzzy read, we may be reading a CD-image + and not a true ISO 9660 image this might + be CDIO_CD_FRAMESIZE_RAW (2352) or + M2RAW_SECTOR_SIZE (2336). + */ + int i_fuzzy_offset; /* Adjustment in bytes to make ISO_STANDARD_ID + ("CD001") come out as ISO_PVD_SECTOR + (frame 16). Normally this should be 0 + for an ISO 9660 image, but if one is + say reading a BIN/CUE or cdrdao BIN/TOC + without having the CUE or TOC and + trying to extract an ISO-9660 + filesystem inside that it may be + different. + */ }; +static long int iso9660_seek_read_framesize (const iso9660_t *p_iso, + void *ptr, lsn_t start, + long int size, + uint16_t i_framesize); + +/* Adjust the p_iso's i_datastart, i_byte_offset and i_framesize + based on whether we find a frame header or not. +*/ +static void +adjust_fuzzy_pvd( iso9660_t *p_iso ) +{ + long int i_byte_offset; + + if (!p_iso) return; + + i_byte_offset = (ISO_PVD_SECTOR * p_iso->i_framesize) + + p_iso->i_fuzzy_offset + p_iso->i_datastart; + + /* If we have a raw 2352-byte frame then we should expect to see a sync + frame and a header. + */ + if (CDIO_CD_FRAMESIZE_RAW == p_iso->i_framesize) { + const int pre_user_data=CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE + + CDIO_CD_SUBHEADER_SIZE; + char buf[pre_user_data]; + + i_byte_offset -= pre_user_data; + + if ( DRIVER_OP_SUCCESS != cdio_stream_seek (p_iso->stream, i_byte_offset, + SEEK_SET) ) + return; + if (sizeof(buf) == cdio_stream_read (p_iso->stream, buf, sizeof(buf), 1)) { + if (memcmp(CDIO_SECTOR_SYNC_HEADER, buf, CDIO_CD_SYNC_SIZE) && + memcmp(CDIO_SECTOR_SYNC_HEADER, buf+CDIO_CD_SUBHEADER_SIZE, + CDIO_CD_SYNC_SIZE)) { + /* Has no frame header */ + p_iso->i_framesize = M2RAW_SECTOR_SIZE; + p_iso->i_fuzzy_offset = (CDIO_CD_FRAMESIZE_RAW - M2RAW_SECTOR_SIZE) + * ISO_PVD_SECTOR + p_iso->i_fuzzy_offset + p_iso->i_datastart; + p_iso->i_datastart = 0; + } + } + } + + +} + +/*! + Open an ISO 9660 image for reading in either fuzzy mode or not. +*/ +static iso9660_t * +iso9660_open_ext_private (const char *pathname, + iso_extension_mask_t iso_extension_mask, + uint16_t i_fuzz, bool b_fuzzy) +{ + iso9660_t *p_iso = (iso9660_t *) calloc(1, sizeof(struct _iso9660)) ; + bool b_have_superblock; + + if (!p_iso) return NULL; + + p_iso->stream = cdio_stdio_new( pathname ); + if (NULL == p_iso->stream) + goto error; + + p_iso->i_framesize = ISO_BLOCKSIZE; + + b_have_superblock = (b_fuzzy) + ? iso9660_ifs_fuzzy_read_superblock(p_iso, iso_extension_mask, i_fuzz) + : iso9660_ifs_read_superblock(p_iso, iso_extension_mask) ; + + if ( ! b_have_superblock ) goto error; + + /* Determine if image has XA attributes. */ + + p_iso->b_xa = !strncmp ((char *) &(p_iso->pvd) + ISO_XA_MARKER_OFFSET, + ISO_XA_MARKER_STRING, + strlen (ISO_XA_MARKER_STRING)); + p_iso->iso_extension_mask = iso_extension_mask; + return p_iso; + + error: + free(p_iso); + return NULL; +} + /*! Open an ISO 9660 image for reading. Maybe in the future we will have a mode. NULL is returned on error. @@ -80,34 +187,35 @@ iso9660_open (const char *pathname /*, mode*/) a mode. NULL is returned on error. */ iso9660_t * -iso9660_open_ext (const char *pathname, +iso9660_open_ext (const char *psz_path, iso_extension_mask_t iso_extension_mask) { - iso9660_t *p_iso = (iso9660_t *) calloc(1, sizeof(struct _iso9660)) ; - - if (NULL == p_iso) return NULL; - - p_iso->stream = cdio_stdio_new( pathname ); - if (NULL == p_iso->stream) - goto error; - - if ( !iso9660_ifs_read_superblock(p_iso, iso_extension_mask) ) - goto error; - - /* Determine if image has XA attributes. */ - - p_iso->b_xa = !strncmp ((char *) &(p_iso->pvd) + ISO_XA_MARKER_OFFSET, - ISO_XA_MARKER_STRING, - strlen (ISO_XA_MARKER_STRING)); - p_iso->iso_extension_mask = iso_extension_mask; - return p_iso; - - error: - free(p_iso); - return NULL; + return iso9660_open_ext_private(psz_path, iso_extension_mask, 0, false); } +/*! + Open an ISO 9660 image for reading. Maybe in the future we will have + a mode. NULL is returned on error. +*/ +iso9660_t * +iso9660_open_fuzzy (const char *psz_path, uint16_t i_fuzz /*, mode*/) +{ + return iso9660_open_fuzzy_ext(psz_path, ISO_EXTENSION_NONE, i_fuzz); +} + +/*! + Open an ISO 9660 image for reading. Maybe in the future we will have + a mode. NULL is returned on error. +*/ +iso9660_t * +iso9660_open_fuzzy_ext (const char *psz_path, + iso_extension_mask_t iso_extension_mask, + uint16_t i_fuzz) +{ + return iso9660_open_ext_private(psz_path, iso_extension_mask, i_fuzz, + true); +} /*! Close previously opened ISO 9660 image. @@ -125,16 +233,16 @@ iso9660_close (iso9660_t *p_iso) } static bool -check_pvd (const iso9660_pvd_t *p_pvd) +check_pvd (const iso9660_pvd_t *p_pvd, cdio_log_level_t log_level) { if ( ISO_VD_PRIMARY != from_711(p_pvd->type) ) { - cdio_warn ("unexpected PVD type %d", p_pvd->type); + cdio_log (log_level, "unexpected PVD type %d", p_pvd->type); return false; } if (strncmp (p_pvd->id, ISO_STANDARD_ID, strlen (ISO_STANDARD_ID))) { - cdio_warn ("unexpected ID encountered (expected `" + cdio_log (log_level, "unexpected ID encountered (expected `" ISO_STANDARD_ID "', got `%.5s'", p_pvd->id); return false; } @@ -386,6 +494,22 @@ bool iso9660_ifs_get_volumeset_id(iso9660_t *p_iso, } +/*! + Read the Primary Volume Descriptor for an ISO 9660 image. + True is returned if read, and false if there was an error. +*/ +static bool +iso9660_ifs_read_pvd_loglevel (const iso9660_t *p_iso, + /*out*/ iso9660_pvd_t *p_pvd, + cdio_log_level_t log_level) +{ + if (0 == iso9660_iso_seek_read (p_iso, p_pvd, ISO_PVD_SECTOR, 1)) { + cdio_log ( log_level, "error reading PVD sector (%d)", ISO_PVD_SECTOR ); + return false; + } + return check_pvd(p_pvd, log_level); +} + /*! Read the Primary Volume Descriptor for an ISO 9660 image. True is returned if read, and false if there was an error. @@ -393,11 +517,7 @@ bool iso9660_ifs_get_volumeset_id(iso9660_t *p_iso, bool iso9660_ifs_read_pvd (const iso9660_t *p_iso, /*out*/ iso9660_pvd_t *p_pvd) { - if (0 == iso9660_iso_seek_read (p_iso, p_pvd, ISO_PVD_SECTOR, 1)) { - cdio_warn ("error reading PVD sector (%d)", ISO_PVD_SECTOR); - return false; - } - return check_pvd(p_pvd); + return iso9660_ifs_read_pvd_loglevel(p_iso, p_pvd, CDIO_LOG_WARN); } @@ -448,7 +568,74 @@ iso9660_ifs_read_superblock (iso9660_t *p_iso, return true; } +/*! + Read the Super block of an ISO 9660 image but determine framesize + and datastart and a possible additional offset. Generally here we are + not reading an ISO 9660 image but a CD-Image which contains an ISO 9660 + filesystem. +*/ +bool +iso9660_ifs_fuzzy_read_superblock (iso9660_t *p_iso, + iso_extension_mask_t iso_extension_mask, + uint16_t i_fuzz) +{ + /* Got some work to do to find ISO_STANDARD_ID ("CD001") */ + unsigned int i; + + for (i=0; ii_framesize = framesizes[k]; + p_iso->i_datastart = (ISO_BLOCKSIZE == framesizes[k]) ? + 0 : CDIO_CD_SYNC_SIZE; + p_iso->i_fuzzy_offset = 0; + if (0 == iso9660_seek_read_framesize (p_iso, frame, lsn, 1, + p_iso->i_framesize)) { + return false; + } + + q = memchr(frame, 'C', p_iso->i_framesize); + for ( p=q; p && p < frame + p_iso->i_framesize ; p=q+1 ) { + q = memchr(p, 'C', p_iso->i_framesize - (p - frame)); + if ( !q || (pvd = strstr(q, ISO_STANDARD_ID)) ) + break; + } + + if (pvd) { + /* Yay! Found something */ + p_iso->i_fuzzy_offset = (pvd - frame - 1) - + ((ISO_PVD_SECTOR-lsn)*p_iso->i_framesize) ; + /* But is it *really* a PVD? */ + if ( iso9660_ifs_read_pvd_loglevel(p_iso, &(p_iso->pvd), + CDIO_LOG_DEBUG) ) { + adjust_fuzzy_pvd(p_iso); + return true; + } + + } + } + } + } + return false; +} + + /*! Read the Primary Volume Descriptor for of CD. */ @@ -491,7 +678,7 @@ iso9660_fs_read_pvd(const CdIo_t *p_cdio, /*out*/ iso9660_pvd_t *p_pvd) cdio_assert (sizeof(buf) >= sizeof (iso9660_pvd_t)); memcpy(p_pvd, buf, sizeof(iso9660_pvd_t)); - return check_pvd(p_pvd); + return check_pvd(p_pvd, CDIO_LOG_WARN); } @@ -578,6 +765,26 @@ iso9660_fs_read_superblock (CdIo_t *p_cdio, return true; } +/*! + Seek to a position and then read n blocks. Size read is returned. +*/ +static long int +iso9660_seek_read_framesize (const iso9660_t *p_iso, void *ptr, + lsn_t start, long int size, + uint16_t i_framesize) +{ + long int ret; + long int i_byte_offset; + + if (!p_iso) return 0; + i_byte_offset = (start * p_iso->i_framesize) + p_iso->i_fuzzy_offset + + p_iso->i_datastart; + + ret = cdio_stream_seek (p_iso->stream, i_byte_offset, SEEK_SET); + if (ret!=0) return 0; + return cdio_stream_read (p_iso->stream, ptr, i_framesize, size); +} + /*! Seek to a position and then read n blocks. Size read is returned. */ @@ -585,14 +792,11 @@ long int iso9660_iso_seek_read (const iso9660_t *p_iso, void *ptr, lsn_t start, long int size) { - long int ret; - if (NULL == p_iso) return 0; - ret = cdio_stream_seek (p_iso->stream, start * ISO_BLOCKSIZE, SEEK_SET); - if (ret!=0) return 0; - return cdio_stream_read (p_iso->stream, ptr, ISO_BLOCKSIZE, size); + return iso9660_seek_read_framesize(p_iso, ptr, start, size, ISO_BLOCKSIZE); } + static iso9660_stat_t * _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, bool b_mode2, uint8_t i_joliet_level) @@ -639,7 +843,11 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, iso9660_get_dtime(&(p_iso9660_dir->recording_time), true, &(stat->tm)); - cdio_assert (dir_len >= sizeof (iso9660_dir_t)); + if (dir_len < sizeof (iso9660_dir_t)) { + free(stat); + return NULL; + } + if (b_mode2) { int su_length = iso9660_get_dir_len(p_iso9660_dir) @@ -944,7 +1152,7 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root, Get file status for pathname into stat. NULL is returned on error. */ iso9660_stat_t * -iso9660_fs_stat (CdIo_t *p_cdio, const char pathname[]) +iso9660_fs_stat (CdIo_t *p_cdio, const char psz_path[]) { iso9660_stat_t *p_root; char **p_psz_splitpath; @@ -953,13 +1161,13 @@ iso9660_fs_stat (CdIo_t *p_cdio, const char pathname[]) bool b_mode2; if (!p_cdio) return NULL; - if (!pathname) return NULL; + if (!psz_path) return NULL; p_root = _fs_stat_root (p_cdio); if (!p_root) return NULL; b_mode2 = cdio_get_track_green(p_cdio, 1); - p_psz_splitpath = _cdio_strsplit (pathname, '/'); + p_psz_splitpath = _cdio_strsplit (psz_path, '/'); p_stat = _fs_stat_traverse (p_cdio, p_root, p_psz_splitpath, b_mode2, false); free(p_root); _cdio_strfreev (p_psz_splitpath); @@ -974,7 +1182,7 @@ iso9660_fs_stat (CdIo_t *p_cdio, const char pathname[]) are lowercased. */ iso9660_stat_t * -iso9660_fs_stat_translate (CdIo_t *p_cdio, const char pathname[], +iso9660_fs_stat_translate (CdIo_t *p_cdio, const char psz_path[], bool b_mode2) { iso9660_stat_t *p_root; @@ -982,12 +1190,12 @@ iso9660_fs_stat_translate (CdIo_t *p_cdio, const char pathname[], iso9660_stat_t *p_stat; if (!p_cdio) return NULL; - if (pathname) return NULL; + if (psz_path) return NULL; p_root = _fs_stat_root (p_cdio); if (!p_root) return NULL; - p_psz_splitpath = _cdio_strsplit (pathname, '/'); + p_psz_splitpath = _cdio_strsplit (psz_path, '/'); p_stat = _fs_stat_traverse (p_cdio, p_root, p_psz_splitpath, b_mode2, true); free(p_root); _cdio_strfreev (p_psz_splitpath); @@ -999,19 +1207,19 @@ iso9660_fs_stat_translate (CdIo_t *p_cdio, const char pathname[], Get file status for pathname into stat. NULL is returned on error. */ iso9660_stat_t * -iso9660_ifs_stat (iso9660_t *p_iso, const char pathname[]) +iso9660_ifs_stat (iso9660_t *p_iso, const char psz_path[]) { iso9660_stat_t *p_root; char **splitpath; iso9660_stat_t *stat; if (!p_iso) return NULL; - if (!pathname) return NULL; + if (!psz_path) return NULL; p_root = _fs_stat_iso_root (p_iso); if (!p_root) return NULL; - splitpath = _cdio_strsplit (pathname, '/'); + splitpath = _cdio_strsplit (psz_path, '/'); stat = _fs_iso_stat_traverse (p_iso, p_root, splitpath, false); free(p_root); /*** FIXME _cdio_strfreev (splitpath); ***/ @@ -1026,19 +1234,19 @@ iso9660_ifs_stat (iso9660_t *p_iso, const char pathname[]) are lowercased. */ iso9660_stat_t * -iso9660_ifs_stat_translate (iso9660_t *p_iso, const char pathname[]) +iso9660_ifs_stat_translate (iso9660_t *p_iso, const char psz_path[]) { iso9660_stat_t *p_root; char **p_psz_splitpath; iso9660_stat_t *p_stat; if (!p_iso) return NULL; - if (!pathname) return NULL; + if (!psz_path) return NULL; p_root = _fs_stat_iso_root (p_iso); if (NULL == p_root) return NULL; - p_psz_splitpath = _cdio_strsplit (pathname, '/'); + p_psz_splitpath = _cdio_strsplit (psz_path, '/'); p_stat = _fs_iso_stat_traverse (p_iso, p_root, p_psz_splitpath, true); free(p_root); _cdio_strfreev (p_psz_splitpath); @@ -1051,15 +1259,15 @@ iso9660_ifs_stat_translate (iso9660_t *p_iso, const char pathname[]) of the files inside that. The caller must free the returned result. */ CdioList_t * -iso9660_fs_readdir (CdIo_t *p_cdio, const char pathname[], bool b_mode2) +iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[], bool b_mode2) { iso9660_stat_t *p_stat; generic_img_private_t *p_env = (generic_img_private_t *) p_cdio->env; if (!p_cdio) return NULL; - if (!pathname) return NULL; + if (!psz_path) return NULL; - p_stat = iso9660_fs_stat (p_cdio, pathname); + p_stat = iso9660_fs_stat (p_cdio, psz_path); if (!p_stat) return NULL; if (p_stat->type != _STAT_DIR) { @@ -1122,14 +1330,14 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char pathname[], bool b_mode2) of the files inside that. The caller must free the returned result. */ CdioList_t * -iso9660_ifs_readdir (iso9660_t *p_iso, const char pathname[]) +iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[]) { iso9660_stat_t *p_stat; if (!p_iso) return NULL; - if (!pathname) return NULL; + if (!psz_path) return NULL; - p_stat = iso9660_ifs_stat (p_iso, pathname); + p_stat = iso9660_ifs_stat (p_iso, psz_path); if (!p_stat) return NULL; if (p_stat->type != _STAT_DIR) { @@ -1168,14 +1376,21 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char pathname[]) p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir, true, p_iso->i_joliet_level); - _cdio_list_append (retval, p_iso9660_stat); + + if (p_iso9660_stat) + _cdio_list_append (retval, p_iso9660_stat); offset += iso9660_get_dir_len(p_iso9660_dir); } - cdio_assert (offset == (p_stat->secsize * ISO_BLOCKSIZE)); - free (_dirbuf); + + if (offset != (p_stat->secsize * ISO_BLOCKSIZE)) { + free (p_stat); + _cdio_list_free (retval, true); + return NULL; + } + free (p_stat); return retval; } diff --git a/lib/iso9660/iso9660_private.h b/lib/iso9660/iso9660_private.h index 2f36f8a1..d2cbb690 100644 --- a/lib/iso9660/iso9660_private.h +++ b/lib/iso9660/iso9660_private.h @@ -1,5 +1,5 @@ /* - $Id: iso9660_private.h,v 1.1 2004/12/18 17:29:32 rocky Exp $ + $Id: iso9660_private.h,v 1.2 2005/02/05 04:25:14 rocky Exp $ Copyright (C) 2000 Herbert Valerio Riedel Copyright (C) 2003, 2004 Rocky Bernstein @@ -39,7 +39,7 @@ PRAGMA_BEGIN_PACKED struct iso_volume_descriptor { uint8_t type; /* 711 */ - char id[5]; + char id[5]; /* "CD001" (ISO_STANDARD_ID) */ uint8_t version; /* 711 */ char data[2041]; } GNUC_PACKED; diff --git a/lib/iso9660/libiso9660.sym b/lib/iso9660/libiso9660.sym index c18cade9..6cea1a6b 100644 --- a/lib/iso9660/libiso9660.sym +++ b/lib/iso9660/libiso9660.sym @@ -26,6 +26,7 @@ iso9660_get_system_id iso9660_get_volume_id iso9660_get_volumeset_id iso9660_get_xa_attr_str +iso9660_ifs_fuzzy_read_superblock iso9660_ifs_get_application_id iso9660_ifs_get_joliet_level iso9660_ifs_get_preparer_id @@ -46,6 +47,8 @@ iso9660_name_translate iso9660_name_translate_ext iso9660_open iso9660_open_ext +iso9660_open_fuzzy +iso9660_open_fuzzy_ext iso9660_pathname_isofy iso9660_pathname_valid_p iso9660_pathtable_get_size diff --git a/src/util.c b/src/util.c index 17e848b3..2a39a5bf 100644 --- a/src/util.c +++ b/src/util.c @@ -1,5 +1,5 @@ /* - $Id: util.c,v 1.31 2005/01/09 16:33:18 rocky Exp $ + $Id: util.c,v 1.32 2005/02/05 04:25:14 rocky Exp $ Copyright (C) 2003, 2004, 2005 Rocky Bernstein @@ -164,7 +164,7 @@ fillout_device_name(const char *device_name) if (0 == strncmp(device_name, DEV_PREFIX, prefix_len)) return strdup(device_name); else { - char *full_device_name = (char*) malloc(strlen(device_name)+prefix_len); + char *full_device_name = (char*) calloc(1, strlen(device_name)+prefix_len); report( stdout, full_device_name, DEV_PREFIX "%s", device_name); return full_device_name; }