[iso] update libcdio to latest

* Also clean up some of the code in iso.c
This commit is contained in:
Pete Batard 2018-06-04 12:20:14 +01:00
parent b274388f95
commit b80f7c0785
19 changed files with 930 additions and 300 deletions

View File

@ -94,7 +94,7 @@ static const char* stupid_antivirus = " NOTE: This is usually caused by a poorl
"look into using a *SMARTER* antivirus solution.";
const char* old_c32_name[NB_OLD_C32] = OLD_C32_NAMES;
static const int64_t old_c32_threshold[NB_OLD_C32] = OLD_C32_THRESHOLD;
static uint8_t i_joliet_level = 0;
static uint8_t joliet_level = 0;
static uint64_t total_blocks, nb_blocks;
static BOOL scan_only = FALSE;
static StrArray config_path, isolinux_path;
@ -140,7 +140,7 @@ static void log_handler (cdio_log_level_t level, const char *message)
* Scan and set ISO properties
* Returns true if the the current file does not need to be processed further
*/
static BOOL check_iso_props(const char* psz_dirname, int64_t i_file_length, const char* psz_basename,
static BOOL check_iso_props(const char* psz_dirname, int64_t file_length, const char* psz_basename,
const char* psz_fullpath, EXTRACT_PROPS *props)
{
size_t i, j, len;
@ -157,7 +157,7 @@ static BOOL check_iso_props(const char* psz_dirname, int64_t i_file_length, cons
// Check for an old incompatible c32 file anywhere
for (i=0; i<NB_OLD_C32; i++) {
if ((safe_stricmp(psz_basename, old_c32_name[i]) == 0) && (i_file_length <= old_c32_threshold[i]))
if ((safe_stricmp(psz_basename, old_c32_name[i]) == 0) && (file_length <= old_c32_threshold[i]))
props->is_old_c32[i] = TRUE;
}
@ -244,12 +244,12 @@ static BOOL check_iso_props(const char* psz_dirname, int64_t i_file_length, cons
if (props->is_old_c32[i])
img_report.has_old_c32[i] = TRUE;
}
if (i_file_length >= FOUR_GIGABYTES)
if (file_length >= FOUR_GIGABYTES)
img_report.has_4GB_file = TRUE;
// Compute projected size needed
total_blocks += i_file_length / ISO_BLOCKSIZE;
total_blocks += file_length / ISO_BLOCKSIZE;
// NB: ISO_BLOCKSIZE = UDF_BLOCKSIZE
if ((i_file_length != 0) && (i_file_length % ISO_BLOCKSIZE != 0))
if ((file_length != 0) && (file_length % ISO_BLOCKSIZE != 0))
total_blocks++;
return TRUE;
}
@ -315,7 +315,7 @@ static void fix_config(const char* psz_fullpath, const char* psz_path, const cha
free(src);
}
static void print_extracted_file(char* psz_fullpath, int64_t i_file_length)
static void print_extracted_file(char* psz_fullpath, int64_t file_length)
{
size_t i, nul_pos;
@ -325,9 +325,9 @@ static void print_extracted_file(char* psz_fullpath, int64_t i_file_length)
nul_pos = strlen(psz_fullpath);
for (i=0; i<nul_pos; i++)
if (psz_fullpath[i] == '/') psz_fullpath[i] = '\\';
safe_sprintf(&psz_fullpath[nul_pos], 24, " (%s)", SizeToHumanReadable(i_file_length, TRUE, FALSE));
safe_sprintf(&psz_fullpath[nul_pos], 24, " (%s)", SizeToHumanReadable(file_length, TRUE, FALSE));
uprintf("Extracting: %s\n", psz_fullpath);
safe_sprintf(&psz_fullpath[nul_pos], 24, " (%s)", SizeToHumanReadable(i_file_length, FALSE, FALSE));
safe_sprintf(&psz_fullpath[nul_pos], 24, " (%s)", SizeToHumanReadable(file_length, FALSE, FALSE));
PrintStatus(0, MSG_000, psz_fullpath); // MSG_000 is "%s"
// ISO9660 cannot handle backslashes
for (i=0; i<nul_pos; i++)
@ -368,13 +368,13 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
DWORD buf_size, wr_size, err;
EXTRACT_PROPS props;
BOOL r, is_identical;
int i_length;
int length;
size_t i;
char tmp[128], *psz_fullpath = NULL, *psz_sanpath = NULL;
const char* psz_basename;
udf_dirent_t *p_udf_dirent2;
uint8_t buf[UDF_BLOCKSIZE];
int64_t i_read, i_file_length;
int64_t read, file_length;
if ((p_udf_dirent == NULL) || (psz_path == NULL))
return 1;
@ -384,14 +384,14 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
psz_basename = udf_get_filename(p_udf_dirent);
if (strlen(psz_basename) == 0)
continue;
i_length = (int)(3 + strlen(psz_path) + strlen(psz_basename) + strlen(psz_extract_dir) + 24);
psz_fullpath = (char*)calloc(sizeof(char), i_length);
length = (int)(3 + strlen(psz_path) + strlen(psz_basename) + strlen(psz_extract_dir) + 24);
psz_fullpath = (char*)calloc(sizeof(char), length);
if (psz_fullpath == NULL) {
uprintf("Error allocating file name");
goto out;
}
i_length = _snprintf(psz_fullpath, i_length, "%s%s/%s", psz_extract_dir, psz_path, psz_basename);
if (i_length < 0) {
length = _snprintf(psz_fullpath, length, "%s%s/%s", psz_extract_dir, psz_path, psz_basename);
if (length < 0) {
goto out;
}
if (udf_is_dir(p_udf_dirent)) {
@ -410,12 +410,12 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
goto out;
}
} else {
i_file_length = udf_get_file_length(p_udf_dirent);
if (check_iso_props(psz_path, i_file_length, psz_basename, psz_fullpath, &props)) {
file_length = udf_get_file_length(p_udf_dirent);
if (check_iso_props(psz_path, file_length, psz_basename, psz_fullpath, &props)) {
safe_free(psz_fullpath);
continue;
}
print_extracted_file(psz_fullpath, i_file_length);
print_extracted_file(psz_fullpath, file_length);
for (i=0; i<NB_OLD_C32; i++) {
if (props.is_old_c32[i] && use_own_c32[i]) {
static_sprintf(tmp, "%s/syslinux-%s/%s", FILES_DIR, embedded_sl_version_str[0], old_c32_name[i]);
@ -440,21 +440,21 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
uprintf(stupid_antivirus);
else
goto out;
} else while (i_file_length > 0) {
} else while (file_length > 0) {
if (FormatStatus) goto out;
memset(buf, 0, UDF_BLOCKSIZE);
i_read = udf_read_block(p_udf_dirent, buf, 1);
if (i_read < 0) {
read = udf_read_block(p_udf_dirent, buf, 1);
if (read < 0) {
uprintf(" Error reading UDF file %s", &psz_fullpath[strlen(psz_extract_dir)]);
goto out;
}
buf_size = (DWORD)MIN(i_file_length, i_read);
buf_size = (DWORD)MIN(file_length, read);
ISO_BLOCKING(r = WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES));
if (!r) {
uprintf(" Error writing file: %s", WindowsErrorString());
goto out;
}
i_file_length -= i_read;
file_length -= read;
if (nb_blocks++ % PROGRESS_THRESHOLD == 0)
UpdateProgress(OP_DOS, 100.0f*nb_blocks/total_blocks);
}
@ -491,24 +491,24 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
DWORD buf_size, wr_size, err;
EXTRACT_PROPS props;
BOOL is_symlink, is_identical;
int i_length, r = 1;
int length, r = 1;
char tmp[128], psz_fullpath[MAX_PATH], *psz_basename, *psz_sanpath;
const char *psz_iso_name = &psz_fullpath[strlen(psz_extract_dir)];
unsigned char buf[ISO_BLOCKSIZE];
CdioListNode_t* p_entnode;
iso9660_stat_t *p_statbuf;
CdioList_t* p_entlist;
CdioISO9660FileList_t* p_entlist;
size_t i, j;
lsn_t lsn;
int64_t i_file_length;
int64_t file_length, extent_length;
if ((p_iso == NULL) || (psz_path == NULL))
return 1;
i_length = _snprintf(psz_fullpath, sizeof(psz_fullpath), "%s%s/", psz_extract_dir, psz_path);
if (i_length < 0)
length = _snprintf(psz_fullpath, sizeof(psz_fullpath), "%s%s/", psz_extract_dir, psz_path);
if (length < 0)
return 1;
psz_basename = &psz_fullpath[i_length];
psz_basename = &psz_fullpath[length];
p_entlist = iso9660_ifs_readdir(p_iso, psz_path);
if (!p_entlist) {
@ -526,7 +526,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
// Rock Ridge requires an exception
is_symlink = FALSE;
if ((p_statbuf->rr.b3_rock == yep) && enable_rockridge) {
safe_strcpy(psz_basename, sizeof(psz_fullpath)-i_length-1, p_statbuf->filename);
safe_strcpy(psz_basename, sizeof(psz_fullpath) - length - 1, p_statbuf->filename);
if (safe_strlen(p_statbuf->filename) > 64)
img_report.has_long_filename = TRUE;
// libcdio has a memleak for Rock Ridge symlinks. It doesn't look like there's an easy fix there as
@ -537,7 +537,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
if (scan_only)
safe_free(p_statbuf->rr.psz_symlink);
} else {
iso9660_name_translate_ext(p_statbuf->filename, psz_basename, i_joliet_level);
iso9660_name_translate_ext(p_statbuf->filename, psz_basename, joliet_level);
}
if (p_statbuf->type == _STAT_DIR) {
if (!scan_only) {
@ -552,11 +552,11 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
if (iso_extract_files(p_iso, psz_iso_name))
goto out;
} else {
i_file_length = p_statbuf->total_size;
if (check_iso_props(psz_path, i_file_length, psz_basename, psz_fullpath, &props)) {
file_length = p_statbuf->size;
if (check_iso_props(psz_path, file_length, psz_basename, psz_fullpath, &props)) {
continue;
}
print_extracted_file(psz_fullpath, i_file_length);
print_extracted_file(psz_fullpath, file_length);
for (i=0; i<NB_OLD_C32; i++) {
if (props.is_old_c32[i] && use_own_c32[i]) {
static_sprintf(tmp, "%s/syslinux-%s/%s", FILES_DIR, embedded_sl_version_str[0], old_c32_name[i]);
@ -573,7 +573,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
if (!is_identical)
uprintf(" File name sanitized to '%s'", psz_sanpath);
if (is_symlink) {
if (i_file_length == 0)
if (file_length == 0)
uprintf(" Ignoring Rock Ridge symbolic link to '%s'", p_statbuf->rr.psz_symlink);
safe_free(p_statbuf->rr.psz_symlink);
}
@ -587,8 +587,8 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
else
goto out;
} else for (j=0; j<p_statbuf->extents; j++) {
i_file_length = p_statbuf->size[j];
for (i=0; i_file_length>0; i++) {
extent_length = p_statbuf->extsize[j];
for (i=0; extent_length>0; i++) {
if (FormatStatus) goto out;
memset(buf, 0, ISO_BLOCKSIZE);
lsn = p_statbuf->lsn[j] + (lsn_t)i;
@ -597,13 +597,13 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
psz_iso_name, (long unsigned int)lsn);
goto out;
}
buf_size = (DWORD)MIN(i_file_length, ISO_BLOCKSIZE);
buf_size = (DWORD)MIN(extent_length, ISO_BLOCKSIZE);
ISO_BLOCKING(r = WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES));
if (!r) {
uprintf(" Error writing file: %s", WindowsErrorString());
goto out;
}
i_file_length -= ISO_BLOCKSIZE;
extent_length -= ISO_BLOCKSIZE;
if (nb_blocks++ % PROGRESS_THRESHOLD == 0)
UpdateProgress(OP_DOS, 100.0f*nb_blocks/total_blocks);
}
@ -623,7 +623,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
out:
ISO_BLOCKING(safe_closehandle(file_handle));
_cdio_list_free(p_entlist, true);
iso9660_filelist_free(p_entlist);
return r;
}
@ -738,7 +738,7 @@ try_iso:
goto out;
}
uprintf("%sImage is an ISO9660 image", spacing);
i_joliet_level = iso9660_ifs_get_joliet_level(p_iso);
joliet_level = iso9660_ifs_get_joliet_level(p_iso);
if (scan_only) {
if (iso9660_ifs_get_volume_id(p_iso, &tmp)) {
static_strcpy(img_report.label, tmp);
@ -949,7 +949,7 @@ int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_f
{
size_t i, j;
ssize_t read_size;
int64_t file_length, r = 0;
int64_t file_length, extent_length, r = 0;
char buf[UDF_BLOCKSIZE];
DWORD buf_size, wr_size;
iso9660_t* p_iso = NULL;
@ -1013,20 +1013,20 @@ try_iso:
}
for (j = 0; j < p_statbuf->extents; j++) {
file_length = p_statbuf->size[j];
for (i = 0; file_length > 0; i++) {
extent_length = p_statbuf->extsize[j];
for (i = 0; extent_length > 0; i++) {
memset(buf, 0, ISO_BLOCKSIZE);
lsn = p_statbuf->lsn[j] + (lsn_t)i;
if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) {
uprintf(" Error reading ISO9660 file %s at LSN %lu", iso_file, (long unsigned int)lsn);
goto out;
}
buf_size = (DWORD)MIN(file_length, ISO_BLOCKSIZE);
buf_size = (DWORD)MIN(extent_length, ISO_BLOCKSIZE);
if (!WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES)) {
uprintf(" Error writing file %s: %s", dest_file, WindowsErrorString());
goto out;
}
file_length -= ISO_BLOCKSIZE;
extent_length -= ISO_BLOCKSIZE;
r += ISO_BLOCKSIZE;
}
}

View File

@ -171,6 +171,20 @@ to_723(uint16_t i)
static CDIO_INLINE uint16_t
from_723 (uint32_t p)
{
uint8_t *u = (uint8_t *) &p;
/* Return the little-endian part always, to handle non-specs-compliant images */
return (u[0] | (u[1] << 8));
}
static CDIO_INLINE uint16_t
from_723_with_err (uint32_t p, bool *err)
{
if (uint32_swap_le_be (p) != p) {
cdio_warn ("from_723: broken byte order");
*err = true;
} else {
*err = false;
}
return (0xFFFF & p);
}
@ -197,7 +211,9 @@ to_733(uint32_t i)
static CDIO_INLINE uint32_t
from_733 (uint64_t p)
{
return (UINT32_C(0xFFFFFFFF) & p);
uint8_t *u = (uint8_t *) &p;
/* Return the little-endian part always, to handle non-specs-compliant images */
return (u[0] | (u[1] << 8) | (u[2] << 16) | (u[3] << 24));
}
static CDIO_INLINE uint32_t

View File

@ -1,2 +1,337 @@
/* Placeholder */
/*
Copyright (C) 2004, 2005, 2008, 2012 Rocky Bernstein <rocky@gnu.org>
adapted from cuetools
Copyright (C) 2003 Svend Sanjay Sorensen <ssorensen@fastmail.fm>
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 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, see <http://www.gnu.org/licenses/>.
*/
/*!
* \file cdtext.h
*
* \brief The top-level header for CD-Text information. Applications
* include this for CD-Text access.
*/
#ifndef CDIO_CDTEXT_H_
#define CDIO_CDTEXT_H_
#include <cdio/types.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define MIN_CDTEXT_FIELD 0
#define MAX_CDTEXT_FIELDS 10
/*! Enumeration of CD-TEXT text fields. */
typedef enum {
CDTEXT_FIELD_TITLE = 0, /**< title of album name or track titles */
CDTEXT_FIELD_PERFORMER = 1, /**< name(s) of the performer(s) */
CDTEXT_FIELD_SONGWRITER = 2, /**< name(s) of the songwriter(s) */
CDTEXT_FIELD_COMPOSER = 3, /**< name(s) of the composer(s) */
CDTEXT_FIELD_MESSAGE = 4, /**< message(s) from content provider or artist, ISO-8859-1 encoded*/
CDTEXT_FIELD_ARRANGER = 5, /**< name(s) of the arranger(s) */
CDTEXT_FIELD_ISRC = 6, /**< ISRC code of each track */
CDTEXT_FIELD_UPC_EAN = 7, /**< upc/european article number of disc, ISO-8859-1 encoded */
CDTEXT_FIELD_GENRE = 8, /**< genre identification and genre information, ASCII encoded */
CDTEXT_FIELD_DISCID = 9, /**< disc identification, ASCII encoded (may be non-printable) */
CDTEXT_FIELD_INVALID = MAX_CDTEXT_FIELDS /**< INVALID FIELD*/
} cdtext_field_t;
/*! Enumeration of possible genre codes. */
typedef enum {
CDTEXT_GENRE_UNUSED = 0, /**< field is not used. default */
CDTEXT_GENRE_UNDEFINED = 1, /**< not defined */
CDTEXT_GENRE_ADULT_CONTEMP = 2, /**< Adult Contemporary */
CDTEXT_GENRE_ALT_ROCK = 3, /**< Alternative Rock */
CDTEXT_GENRE_CHILDRENS = 4, /**< Childrens Music */
CDTEXT_GENRE_CLASSIC = 5, /**< Classical */
CDTEXT_GENRE_CHRIST_CONTEMP = 6, /**< Contemporary Christian */
CDTEXT_GENRE_COUNTRY = 7, /**< Country */
CDTEXT_GENRE_DANCE = 8, /**< Dance */
CDTEXT_GENRE_EASY_LISTENING = 9, /**< Easy Listening */
CDTEXT_GENRE_EROTIC = 10, /**< Erotic */
CDTEXT_GENRE_FOLK = 11, /**< Folk */
CDTEXT_GENRE_GOSPEL = 12, /**< Gospel */
CDTEXT_GENRE_HIPHOP = 13, /**< Hip Hop */
CDTEXT_GENRE_JAZZ = 14, /**< Jazz */
CDTEXT_GENRE_LATIN = 15, /**< Latin */
CDTEXT_GENRE_MUSICAL = 16, /**< Musical */
CDTEXT_GENRE_NEWAGE = 17, /**< New Age */
CDTEXT_GENRE_OPERA = 18, /**< Opera */
CDTEXT_GENRE_OPERETTA = 19, /**< Operetta */
CDTEXT_GENRE_POP = 20, /**< Pop Music */
CDTEXT_GENRE_RAP = 21, /**< RAP */
CDTEXT_GENRE_REGGAE = 22, /**< Reggae */
CDTEXT_GENRE_ROCK = 23, /**< Rock Music */
CDTEXT_GENRE_RYTHMANDBLUES = 24, /**< Rhythm & Blues */
CDTEXT_GENRE_SOUNDEFFECTS = 25, /**< Sound Effects */
CDTEXT_GENRE_SOUNDTRACK = 26, /**< Soundtrack */
CDTEXT_GENRE_SPOKEN_WORD = 27, /**< Spoken Word */
CDTEXT_GENRE_WORLD_MUSIC = 28 /**< World Music */
} cdtext_genre_t;
/*! Enumeration of possible CD-TEXT languages.
*
* The language code is encoded as specified in ANNEX 1 to part 5 of EBU
* Tech 32 58 -E (1991).
*/
typedef enum {
CDTEXT_LANGUAGE_UNKNOWN = 0x00,
CDTEXT_LANGUAGE_ALBANIAN = 0x01,
CDTEXT_LANGUAGE_BRETON = 0x02,
CDTEXT_LANGUAGE_CATALAN = 0x03,
CDTEXT_LANGUAGE_CROATIAN = 0x04,
CDTEXT_LANGUAGE_WELSH = 0x05,
CDTEXT_LANGUAGE_CZECH = 0x06,
CDTEXT_LANGUAGE_DANISH = 0x07,
CDTEXT_LANGUAGE_GERMAN = 0x08,
CDTEXT_LANGUAGE_ENGLISH = 0x09,
CDTEXT_LANGUAGE_SPANISH = 0x0A,
CDTEXT_LANGUAGE_ESPERANTO = 0x0B,
CDTEXT_LANGUAGE_ESTONIAN = 0x0C,
CDTEXT_LANGUAGE_BASQUE = 0x0D,
CDTEXT_LANGUAGE_FAROESE = 0x0E,
CDTEXT_LANGUAGE_FRENCH = 0x0F,
CDTEXT_LANGUAGE_FRISIAN = 0x10,
CDTEXT_LANGUAGE_IRISH = 0x11,
CDTEXT_LANGUAGE_GAELIC = 0x12,
CDTEXT_LANGUAGE_GALICIAN = 0x13,
CDTEXT_LANGUAGE_ICELANDIC = 0x14,
CDTEXT_LANGUAGE_ITALIAN = 0x15,
CDTEXT_LANGUAGE_LAPPISH = 0x16,
CDTEXT_LANGUAGE_LATIN = 0x17,
CDTEXT_LANGUAGE_LATVIAN = 0x18,
CDTEXT_LANGUAGE_LUXEMBOURGIAN = 0x19,
CDTEXT_LANGUAGE_LITHUANIAN = 0x1A,
CDTEXT_LANGUAGE_HUNGARIAN = 0x1B,
CDTEXT_LANGUAGE_MALTESE = 0x1C,
CDTEXT_LANGUAGE_DUTCH = 0x1D,
CDTEXT_LANGUAGE_NORWEGIAN = 0x1E,
CDTEXT_LANGUAGE_OCCITAN = 0x1F,
CDTEXT_LANGUAGE_POLISH = 0x20,
CDTEXT_LANGUAGE_PORTUGUESE = 0x21,
CDTEXT_LANGUAGE_ROMANIAN = 0x22,
CDTEXT_LANGUAGE_ROMANSH = 0x23,
CDTEXT_LANGUAGE_SERBIAN = 0x24,
CDTEXT_LANGUAGE_SLOVAK = 0x25,
CDTEXT_LANGUAGE_SLOVENIAN = 0x26,
CDTEXT_LANGUAGE_FINNISH = 0x27,
CDTEXT_LANGUAGE_SWEDISH = 0x28,
CDTEXT_LANGUAGE_TURKISH = 0x29,
CDTEXT_LANGUAGE_FLEMISH = 0x2A,
CDTEXT_LANGUAGE_WALLON = 0x2B,
CDTEXT_LANGUAGE_ZULU = 0x45,
CDTEXT_LANGUAGE_VIETNAMESE = 0x46,
CDTEXT_LANGUAGE_UZBEK = 0x47,
CDTEXT_LANGUAGE_URDU = 0x48,
CDTEXT_LANGUAGE_UKRAINIAN = 0x49,
CDTEXT_LANGUAGE_THAI = 0x4A,
CDTEXT_LANGUAGE_TELUGU = 0x4B,
CDTEXT_LANGUAGE_TATAR = 0x4C,
CDTEXT_LANGUAGE_TAMIL = 0x4D,
CDTEXT_LANGUAGE_TADZHIK = 0x4E,
CDTEXT_LANGUAGE_SWAHILI = 0x4F,
CDTEXT_LANGUAGE_SRANANTONGO = 0x50,
CDTEXT_LANGUAGE_SOMALI = 0x51,
CDTEXT_LANGUAGE_SINHALESE = 0x52,
CDTEXT_LANGUAGE_SHONA = 0x53,
CDTEXT_LANGUAGE_SERBO_CROAT = 0x54,
CDTEXT_LANGUAGE_RUTHENIAN = 0x55,
CDTEXT_LANGUAGE_RUSSIAN = 0x56,
CDTEXT_LANGUAGE_QUECHUA = 0x57,
CDTEXT_LANGUAGE_PUSHTU = 0x58,
CDTEXT_LANGUAGE_PUNJABI = 0x59,
CDTEXT_LANGUAGE_PERSIAN = 0x5A,
CDTEXT_LANGUAGE_PAPAMIENTO = 0x5B,
CDTEXT_LANGUAGE_ORIYA = 0x5C,
CDTEXT_LANGUAGE_NEPALI = 0x5D,
CDTEXT_LANGUAGE_NDEBELE = 0x5E,
CDTEXT_LANGUAGE_MARATHI = 0x5F,
CDTEXT_LANGUAGE_MOLDAVIAN = 0x60,
CDTEXT_LANGUAGE_MALAYSIAN = 0x61,
CDTEXT_LANGUAGE_MALAGASAY = 0x62,
CDTEXT_LANGUAGE_MACEDONIAN = 0x63,
CDTEXT_LANGUAGE_LAOTIAN = 0x64,
CDTEXT_LANGUAGE_KOREAN = 0x65,
CDTEXT_LANGUAGE_KHMER = 0x66,
CDTEXT_LANGUAGE_KAZAKH = 0x67,
CDTEXT_LANGUAGE_KANNADA = 0x68,
CDTEXT_LANGUAGE_JAPANESE = 0x69,
CDTEXT_LANGUAGE_INDONESIAN = 0x6A,
CDTEXT_LANGUAGE_HINDI = 0x6B,
CDTEXT_LANGUAGE_HEBREW = 0x6C,
CDTEXT_LANGUAGE_HAUSA = 0x6D,
CDTEXT_LANGUAGE_GURANI = 0x6E,
CDTEXT_LANGUAGE_GUJURATI = 0x6F,
CDTEXT_LANGUAGE_GREEK = 0x70,
CDTEXT_LANGUAGE_GEORGIAN = 0x71,
CDTEXT_LANGUAGE_FULANI = 0x72,
CDTEXT_LANGUAGE_DARI = 0x73,
CDTEXT_LANGUAGE_CHURASH = 0x74,
CDTEXT_LANGUAGE_CHINESE = 0x75,
CDTEXT_LANGUAGE_BURMESE = 0x76,
CDTEXT_LANGUAGE_BULGARIAN = 0x77,
CDTEXT_LANGUAGE_BENGALI = 0x78,
CDTEXT_LANGUAGE_BIELORUSSIAN = 0x79,
CDTEXT_LANGUAGE_BAMBORA = 0x7A,
CDTEXT_LANGUAGE_AZERBAIJANI = 0x7B,
CDTEXT_LANGUAGE_ASSAMESE = 0x7C,
CDTEXT_LANGUAGE_ARMENIAN = 0x7D,
CDTEXT_LANGUAGE_ARABIC = 0x7E,
CDTEXT_LANGUAGE_AMHARIC = 0x7F
} cdtext_lang_t;
/*!
Opaque type for CD-Text.
*/
typedef struct cdtext_s cdtext_t;
/*!
Return string representation of the given genre code.
*/
const char *cdtext_genre2str (cdtext_genre_t i);
/*!
Return string representation of the given language code.
*/
const char *cdtext_lang2str (cdtext_lang_t i);
/*!
Return string representation of given field type.
*/
const char *cdtext_field2str (cdtext_field_t i);
/*!
Initialize a new cdtext structure.
When the structure is no longer needed, release the
resources using cdtext_delete.
*/
cdtext_t *cdtext_init (void);
/*!
Read a binary CD-TEXT and fill a cdtext struct.
@param p_cdtext the CD-TEXT object
@param wdata the data
@param i_data size of wdata
@returns 0 on success, non-zero on failure
*/
int cdtext_data_init(cdtext_t *p_cdtext, uint8_t *wdata, size_t i_data);
/*!
Free memory associated with the given cdtext_t object.
@param p_cdtext the CD-TEXT object
*/
void cdtext_destroy (cdtext_t *p_cdtext);
/*!
Returns a copy of the return value of cdtext_get_const or NULL.
Must be freed using cdio_free() when done.
@see cdtext_get_const
*/
char *cdtext_get (const cdtext_t *p_cdtext, cdtext_field_t key, track_t track);
/*!
Returns value of the given field.
NULL is returned if key is CDTEXT_INVALID or the field is not set.
Strings are encoded in UTF-8.
@param p_cdtext the CD-TEXT object
@param field type of the field to return
@param track specifies the track, 0 stands for disc
*/
const char *cdtext_get_const (const cdtext_t *p_cdtext, cdtext_field_t field,
track_t track);
/*!
Returns the discs genre code.
@param p_cdtext the CD-TEXT object
*/
cdtext_genre_t cdtext_get_genre (const cdtext_t *p_cdtext);
/*!
Returns the currently active language.
@param p_cdtext the CD-TEXT object
*/
cdtext_lang_t cdtext_get_language (const cdtext_t *p_cdtext);
/*!
Returns the first track number.
@param p_cdtext the CD-TEXT object
*/
track_t cdtext_get_first_track(const cdtext_t *p_cdtext);
/*!
Returns the last track number.
@param p_cdtext the CD-TEXT object
*/
track_t cdtext_get_last_track(const cdtext_t *p_cdtext);
/*!
Try to select the given language.
@param p_cdtext the CD-TEXT object
@param language string representation of the language
@return true on success, false if language is not available
*/
bool cdtext_select_language(cdtext_t *p_cdtext, cdtext_lang_t language);
/*
Returns a list of available languages or NULL.
Internally the list is stored in a static array.
@param p_cdtext the CD-TEXT object
*/
cdtext_lang_t *cdtext_list_languages (const cdtext_t *p_cdtext);
/*!
Sets the given field at the given track to the given value.
Recodes to UTF-8 if charset is not NULL.
@param p_cdtext the CD-TEXT object
@param key field to set
@param value value to set
@param track track to work on
@param charset charset to convert from
*/
void cdtext_set (cdtext_t *p_cdtext, cdtext_field_t key, const uint8_t *value, track_t track, const char *charset);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CDIO_CDTEXT_H_ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

View File

@ -152,13 +152,11 @@ extern "C" {
DRIVER_UNKNOWN, /**< Used as input when we don't care what kind
of driver to use. */
DRIVER_AIX, /**< AIX driver */
DRIVER_BSDI, /**< BSDI driver */
DRIVER_FREEBSD, /**< FreeBSD driver - includes CAM and ioctl access */
DRIVER_NETBSD, /**< NetBSD Driver. */
DRIVER_LINUX, /**< GNU/Linux Driver */
DRIVER_SOLARIS, /**< Sun Solaris Driver */
DRIVER_OS2, /**< IBM OS/2 Driver */
DRIVER_OSX, /**< Apple OSX Driver */
DRIVER_OSX, /**< Apple OSX (or MacOS) Driver */
DRIVER_WIN32, /**< Microsoft Windows Driver. Includes ASPI and
ioctl access. */
DRIVER_CDRDAO, /**< cdrdao format CD image. This is listed
@ -192,18 +190,6 @@ extern "C" {
extern const driver_id_t cdio_os_driver;
/**
Those are deprecated; use cdio_drivers or cdio_device_drivers to
iterate over all drivers or only the device drivers.
Make sure what's listed for CDIO_MIN_DRIVER is the last
enumeration in driver_id_t. Since we have a bogus (but useful) 0th
entry above we don't have to add one.
*/
LIBCDIO_DEPRECATED(static const driver_id_t CDIO_MIN_DRIVER, "please use cdio_drivers") = DRIVER_AIX;
LIBCDIO_DEPRECATED(static const driver_id_t CDIO_MIN_DEVICE_DRIVER, "please use cdio_device_drivers") = DRIVER_AIX;
LIBCDIO_DEPRECATED(static const driver_id_t CDIO_MAX_DRIVER, "please use cdio_drivers") = DRIVER_NRG;
LIBCDIO_DEPRECATED(static const driver_id_t CDIO_MAX_DEVICE_DRIVER, "please use cdio_device_drivers") = DRIVER_WIN32;
/**
The following are status codes for completion of a given cdio
operation. By design 0 is successful completion and -1 is error

View File

@ -1,7 +1,5 @@
/*
$Id: ds.h,v 1.5 2008/03/25 15:59:09 karl Exp $
Copyright (C) 2005, 2008 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2005, 2008, 2017 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000, 2004 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify
@ -18,11 +16,11 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file ds.h
/** \file ds.h
* \brief The top-level header for list-related data structures.
Note: this header will is slated to get removed and libcdio will use
glib.h routines instead.
Note: this header will is slated to get removed and libcdio will use
glib.h routines instead.
*/
@ -38,13 +36,6 @@ typedef struct _CdioListNode CdioListNode_t;
typedef int (*_cdio_list_cmp_func_t) (void *p_data1, void *p_data2);
typedef int (*_cdio_list_iterfunc_t) (void *p_data, void *p_user_data);
/** The below are given compatibility with old code. Please use
the above type names, not these. */
#define CdioList CdioList_t
#define CdioListNode CdioListNode_t
#define _cdio_list_cmp_func _cdio_list_cmp_func_t
#define _cdio_list_iterfunc _cdio_list_iterfunc_t
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
@ -52,7 +43,7 @@ extern "C" {
/** methods */
CdioList_t *_cdio_list_new (void);
void _cdio_list_free (CdioList_t *p_list, int free_data);
void _cdio_list_free (CdioList_t *p_list, int free_data, CdioDataFree_t free_fn);
unsigned _cdio_list_length (const CdioList_t *list);
@ -60,11 +51,11 @@ void _cdio_list_prepend (CdioList_t *p_list, void *p_data);
void _cdio_list_append (CdioList_t *p_list, void *p_data);
void _cdio_list_foreach (CdioList_t *p_list, _cdio_list_iterfunc_t func,
void _cdio_list_foreach (CdioList_t *p_list, _cdio_list_iterfunc_t func,
void *p_user_data);
CdioListNode_t *_cdio_list_find (CdioList_t *p_list,
_cdio_list_iterfunc_t cmp_func,
CdioListNode_t *_cdio_list_find (CdioList_t *p_list,
_cdio_list_iterfunc_t cmp_func,
void *p_user_data);
#define _CDIO_LIST_FOREACH(node, list) \
@ -78,7 +69,8 @@ CdioListNode_t *_cdio_list_end (CdioList_t *p_list);
CdioListNode_t *_cdio_list_node_next (CdioListNode_t *p_node);
void _cdio_list_node_free (CdioListNode_t *p_node, int i_free_data);
void _cdio_list_node_free (CdioListNode_t *p_node, int i_free_data,
CdioDataFree_t free_fn);
void *_cdio_list_node_data (CdioListNode_t *p_node);
@ -88,11 +80,10 @@ void *_cdio_list_node_data (CdioListNode_t *p_node);
#endif /* CDIO_DS_H_ */
/*
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2003-2008, 2012-2013
Copyright (C) 2003-2008, 2012-2013, 2017
Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
@ -509,6 +509,18 @@ typedef struct iso9660_svd_s iso9660_svd_t;
PRAGMA_END_PACKED
/*! \brief A data type for a list of ISO9660
statbuf file pointers returned from the various
Cdio iso9660 readdir routines.
*/
typedef CdioList_t CdioISO9660FileList_t;
/*! \brief A data type for a list of ISO9660
statbuf drectory pointer returned from the variious
Cdio iso9660 readdir routines.
*/
typedef CdioList_t CdioISO9660DirList_t;
/*! \brief Unix stat-like version of iso9660_dir
The iso9660_stat structure is not part of the ISO-9660
@ -524,11 +536,14 @@ struct iso9660_stat_s { /* big endian!! */
struct tm tm; /**< time on entry - FIXME merge with
one of entries above, like ctime? */
uint64_t total_size; /**< total size in bytes */
uint64_t size; /**< total size in bytes */
uint8_t extents; /**< number of multiextents */
lsn_t lsn[ISO_MAX_MULTIEXTENT]; /**< start logical sector number for each extent */
uint32_t size[ISO_MAX_MULTIEXTENT]; /**< size of each extent */
uint32_t secsize[ISO_MAX_MULTIEXTENT]; /**< number of sectors allocated for each extent*/
/**⌵ start logical sector number for each extent */
lsn_t lsn[ISO_MAX_MULTIEXTENT];
/**⌵ size of each extent */
uint32_t extsize[ISO_MAX_MULTIEXTENT];
/**⌵ number of sectors allocated for each extent */
uint32_t secsize[ISO_MAX_MULTIEXTENT];
iso9660_xa_t xa; /**< XA attributes */
enum { _STAT_FILE = 1, _STAT_DIR = 2 } type;
bool b_xa;
@ -568,8 +583,11 @@ typedef struct _iso9660_s iso9660_t;
associated with the image. Call this when done using using an ISO
9660 image.
@param p_iso the ISO-9660 file image to get data from
@return true is unconditionally returned. If there was an error
false would be returned.
false would be returned. Resources associated with p_iso are
freed.
*/
bool iso9660_close (iso9660_t * p_iso);
@ -577,6 +595,12 @@ typedef struct _iso9660_s iso9660_t;
/*!
Open an ISO 9660 image for reading. Maybe in the future we will have
a mode. NULL is returned on error.
@param psz_path full path of ISO9660 file.
@return a IS9660 structure is unconditionally returned. The caller
should call iso9660_close() when done.
*/
iso9660_t *iso9660_open (const char *psz_path /*flags, mode */);
@ -863,6 +887,8 @@ iso9660_dir_calc_record_size (unsigned int namelen, unsigned int su_len);
Given a directory pointer, find the filesystem entry that contains
lsn and return information about it.
@param p_cdio the CD object to read from
@return stat_t of entry if we found lsn, or NULL otherwise.
Caller must free return value using iso9660_stat_free().
*/
@ -872,18 +898,31 @@ iso9660_stat_t *iso9660_fs_find_lsn(CdIo_t *p_cdio, lsn_t i_lsn);
/*!
Given a directory pointer, find the filesystem entry that contains
lsn and return information about it.
LSN and return information about it.
@param p_cdio the ISO-9660 file image to get data from.
@param i_lsn the LSN to find
@param ppsz_full_filename the place to store the name of the path that has LSN.
On entry this should point to NULL. If not, the value will be freed.
On exit a value is malloc'd and the caller is responsible for
freeing the result.
@return stat_t of entry if we found lsn, or NULL otherwise.
Caller must free return value using iso9660_stat_free().
*/
iso9660_stat_t *iso9660_fs_find_lsn_with_path(CdIo_t *p_cdio, lsn_t i_lsn,
/*out*/ char **ppsz_path);
/*out*/ char **ppsz_full_filename);
/*!
Given a directory pointer, find the filesystem entry that contains
lsn and return information about it.
@param p_iso the ISO-9660 file image to get data from.
@param i_lsn the LSN to find
@return stat_t of entry if we found lsn, or NULL otherwise.
Caller must free return value using iso9660_stat_free().
*/
@ -895,7 +934,9 @@ iso9660_stat_t *iso9660_ifs_find_lsn(iso9660_t *p_iso, lsn_t i_lsn);
lsn and return information about it.
@param p_iso pointer to iso_t
@param i_lsn LSN to find
@param ppsz_path full path of lsn filename. On entry *ppsz_path should be
NULL. On return it will be allocated an point to the full path of the
file at lsn or NULL if the lsn is not found. You should deallocate
@ -910,6 +951,9 @@ iso9660_stat_t *iso9660_ifs_find_lsn_with_path(iso9660_t *p_iso,
/*!
Free the passed iso9660_stat_t structure.
@param p_stat iso9660 stat buffer to free.
*/
void iso9660_stat_free(iso9660_stat_t *p_stat);
@ -920,7 +964,9 @@ void iso9660_stat_free(iso9660_stat_t *p_stat);
@param psz_path filename path to look up and get information about
@return ISO 9660 file information
@return ISO 9660 file information. The caller must free the returned
result using iso9660_stat_free().
Important note:
@ -939,49 +985,123 @@ iso9660_stat_t *iso9660_fs_stat (CdIo_t *p_cdio, const char psz_path[]);
pathname version numbers in the ISO 9660 name are dropped, i.e. ;1
is removed and if level 1 ISO-9660 names are lowercased.
b_mode2 is historical. It is not used.
@param p_cdio the CD object to read from
@param psz_path filename path to look up and get information about
@return ISO 9660 file information. The caller must free the
returned result using iso9660_stat_free().
*/
iso9660_stat_t *iso9660_fs_stat_translate (CdIo_t *p_cdio,
const char psz_path[],
bool b_mode2);
const char psz_path[]);
/*!
Return file status for pathname. NULL is returned on error.
@param p_iso the ISO-9660 file image to get data from
@param psz_path path the look up
@return file status for pathname. NULL is returned on error.
The caller must free the returned result using iso9660_stat_free().
*/
iso9660_stat_t *iso9660_ifs_stat (iso9660_t *p_iso, const char psz_path[]);
/*! Return file status for path name psz_path. NULL is returned on
/*!
@param p_iso the ISO-9660 file image to get data from
@param psz_path filename path translate
@return file status for path name psz_path. NULL is returned on
error. pathname version numbers in the ISO 9660 name are dropped,
i.e. ;1 is removed and if level 1 ISO-9660 names are lowercased.
The caller must free the returned result using iso9660_stat_free().
*/
iso9660_stat_t *iso9660_ifs_stat_translate (iso9660_t *p_iso,
const char psz_path[]);
/*! Read psz_path (a directory) and return a list of iso9660_stat_t
pointers for the files inside that directory. The caller must free the
returned result using _cdio_list_free().
b_mode2 is historical. It is not used.
/*!
Create a new data structure to hold a list of
ISO9660 statbuf-entry pointers for the files inside
a directory.
@return allocated list. Free with iso9660_filelist_free()
*/
CdioList_t * iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[],
bool b_mode2);
CdioISO9660FileList_t * iso9660_filelist_new(void);
/*! Read psz_path (a directory) and return a list of iso9660_stat_t
pointers for the files inside that directory. The caller must free
the returned result using _cdio_list_free().
/*!
Create a new data structure to hold a list of
ISO9660 statbuf entries for directory
pointers for the files inside a directory.
@return allocated list. Free with iso9660_dirlist_free()
*/
CdioISO9660DirList_t * iso9660_dirlist_new(void);
/*!
Free the passed CdioISOC9660FileList_t structure.
*/
void iso9660_filelist_free(CdioISO9660FileList_t *p_filelist);
/*!
Free the passed CdioISOC9660Dirlist_t structure.
*/
void iso9660_dirlist_free(CdioISO9660DirList_t *p_filelist);
/*!
Read psz_path (a directory) and return a list of iso9660_stat_t
pointers for the files inside that directory.
@param p_cdio the CD object to read from
@param psz_path path the read the directory from.
@return file status for psz_path. The caller must free the
The caller must free the returned result using iso9660_stat_free().
*/
CdioList_t * iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[]);
/*!
Read psz_path (a directory) and return a list of iso9660_stat_t
pointers for the files inside that directory.
@param p_iso the ISO-9660 file image to get data from
@param psz_path path the read the directory from.
@return file status for psz_path. The caller must free the
The caller must free the returned result using iso9660_stat_free().
*/
CdioList_t * iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[]);
/*!
Return the PVD's application ID.
@param p_pvd the PVD to get data from
@return the application id.
NULL is returned if there is some problem in getting this.
The caller must free the resturned result using free() if
not null.
*/
char * iso9660_get_application_id(iso9660_pvd_t *p_pvd);
/*!
Get the application ID. psz_app_id is set to NULL if there
is some problem in getting this and false is returned.
Return the PVD's application ID.
@param p_iso the ISO-9660 file image to get data from
@param p_psz_app_id the application id set on success.
NULL is returned if there is some problem in getting this.
The caller must free the resturned result using free() if
not null.
*/
bool iso9660_ifs_get_application_id(iso9660_t *p_iso,
/*out*/ cdio_utf8_t **p_psz_app_id);

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008, 2012
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008, 2012, 2017
Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
@ -155,7 +155,7 @@ typedef uint8_t ubyte;
# define PRAGMA_BEGIN_PACKED _Pragma("pack(push)") \
_Pragma("pack(1)")
# define PRAGMA_END_PACKED _Pragma("pack(pop)")
#elif __GNUC__ > 4 || (__STDC_VERSION__ >= 199901)
#elif __GNUC__ > 4 || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901)
/* should work with GCC > 4.0 clang and most EDG-frontend based C
and C++ compilers */
# define PRAGMA_BEGIN_PACKED _Pragma("pack(1)")
@ -335,6 +335,10 @@ typedef uint8_t ubyte;
CDIO_TRACK_FLAG_SCMS = 0x10 /**< SCMS (5.29.2.7) */
} cdio_track_flag;
/* Note that this matches the free() prototype.*/
typedef void (*CdioDataFree_t)(void *ptr);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -1,4 +1,4 @@
/*
/*
Copyright (C) 2005, 2008, 2012 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
@ -16,18 +16,18 @@
*/
/*!
* \file udf_time.h
* \file udf_time.h
*
* \brief UDF time conversion and access files.
*
*/
#ifndef UDF_TIME_H
#define UDF_TIME_H
#define UDF_TIME_H
#include <time.h>
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && !defined(__struct_timespec_defined)
struct timespec {
time_t tv_sec; /* Seconds */
long tv_nsec; /* Nanoseconds */
@ -61,7 +61,7 @@ extern "C" {
/*!
Return the modification timestamp of the file
*/
udf_timestamp_t *udf_get_modification_timestamp(const udf_dirent_t
udf_timestamp_t *udf_get_modification_timestamp(const udf_dirent_t
*p_udf_dirent);
/*!
@ -72,7 +72,7 @@ extern "C" {
/*!
Convert a UDF timestamp to a time_t. If microseconds are desired,
use dest_usec. The return value is the same as dest. */
time_t *udf_stamp_to_time(time_t *dest, long int *dest_usec,
time_t *udf_stamp_to_time(time_t *dest, long int *dest_usec,
const udf_timestamp_t src);
udf_timestamp_t *udf_timespec_to_stamp(const struct timespec ts,

View File

@ -21,8 +21,8 @@
#define CDIO_UTIL_H_
/*!
\file util.h
\brief Miscellaneous utility functions.
\file util.h
\brief Miscellaneous utility functions.
Warning: this will probably get removed/replaced by using glib.h
*/
@ -65,8 +65,14 @@ _cdio_len2blocks (uint32_t i_len, uint16_t i_blocksize)
return i_blocks;
}
/*! free() and NULL out p_obj it is not already null. */
#define CDIO_FREE_IF_NOT_NULL(p_obj) \
if (NULL != p_obj) { free(p_obj); p_obj=NULL; };
/* round up to next block boundary */
static CDIO_INLINE unsigned
static CDIO_INLINE unsigned
_cdio_ceil2block (unsigned offset, uint16_t i_blocksize)
{
return _cdio_len2blocks (offset, i_blocksize) * i_blocksize;
@ -99,11 +105,11 @@ _cdio_memdup (const void *mem, size_t count);
char *
_cdio_strdup_upper (const char str[]);
/* Duplicate path and make it platform compliant. Typically needed for
MinGW/MSYS where a "/c/..." path must be translated to "c:/..." for
use with fopen(), etc. Returned string must be freed by the caller
using cdio_free(). */
char *
/*! Duplicate path and make it platform compliant. Typically needed for
MinGW/MSYS where a "/c/..." path must be translated to "c:/..." for
use with fopen(), etc. Returned string must be freed by the caller
using cdio_free(). */
char *
_cdio_strdup_fixpath (const char path[]);
void
@ -125,7 +131,7 @@ char *cdio_realpath (const char *psz_src, char *psz_dst);
#ifdef WANT_FOLLOW_SYMLINK_COMPATIBILITY
# define cdio_follow_symlink cdio_realpath
#endif
#ifdef __cplusplus
}
#endif
@ -133,7 +139,7 @@ char *cdio_realpath (const char *psz_src, char *psz_dst);
#endif /* CDIO_UTIL_H_ */
/*
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8

View File

@ -1,19 +1,19 @@
/** \file version.h
*
* \brief A file containing the libcdio package version
* number (94) and OS build name.
* number (20000) and OS build name.
*/
/*! CDIO_VERSION is a C-Preprocessor macro of a string that shows what
version is used. cdio_version_string has the same value, but it is a
constant variable that can be accessed at run time. */
#define CDIO_VERSION "0.94 (Rufus)"
#define CDIO_VERSION "2.0.0 (Rufus)"
extern const char *cdio_version_string; /**< = CDIO_VERSION */
/*! LIBCDIO_VERSION_NUM is a C-Preprocessor macro that can be used for
testing in the C preprocessor. libcdio_version_num has the same
value, but it is a constant variable that can be accessed at run
time. */
#define LIBCDIO_VERSION_NUM 94
#define LIBCDIO_VERSION_NUM 20000
extern const unsigned int libcdio_version_num; /**< = LIBCDIO_VERSION_NUM */

View File

@ -73,7 +73,7 @@ cdio_stream_destroy(CdioDataSource_t *p_obj)
cdio_stream_close(p_obj);
p_obj->op.free(p_obj->user_data);
p_obj->user_data = NULL;
free(p_obj);
}

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2003-2005, 2008-2009, 2011-2012, 2016
Copyright (C) 2003-2005, 2008-2009, 2011-2012, 2016-2017
Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
@ -43,7 +43,9 @@ extern "C" {
#endif /* __cplusplus */
#ifndef HAVE_STRNDUP
static inline char *strndup(const char *s, size_t n)
#undef strndup
#define strndup libcdio_strndup
static inline char *libcdio_strndup(const char *s, size_t n)
{
char *result;
size_t len = strlen (s);
@ -528,7 +530,6 @@ extern "C" {
driver_return_code_t close_tray_freebsd (const char *psz_drive);
driver_return_code_t close_tray_linux (const char *psz_drive);
driver_return_code_t close_tray_netbsd (const char *psz_drive);
driver_return_code_t close_tray_os2 (const char *psz_drive);
driver_return_code_t close_tray_osx (const char *psz_drive);
driver_return_code_t close_tray_solaris (const char *psz_drive);
driver_return_code_t close_tray_win32 (const char *psz_drive);

View File

@ -61,10 +61,10 @@ _cdio_list_new (void)
}
void
_cdio_list_free (CdioList_t *p_list, int free_data)
_cdio_list_free (CdioList_t *p_list, int free_data, CdioDataFree_t free_fn)
{
while (_cdio_list_length (p_list))
_cdio_list_node_free (_cdio_list_begin (p_list), free_data);
_cdio_list_node_free (_cdio_list_begin (p_list), free_data, free_fn);
free (p_list);
}
@ -182,7 +182,8 @@ _cdio_list_node_next (CdioListNode_t *p_node)
}
void
_cdio_list_node_free (CdioListNode_t *p_node, int free_data)
_cdio_list_node_free (CdioListNode_t *p_node,
int free_data, CdioDataFree_t free_fn)
{
CdioList_t *p_list;
CdioListNode_t *prev_node;
@ -193,8 +194,8 @@ _cdio_list_node_free (CdioListNode_t *p_node, int free_data)
cdio_assert (_cdio_list_length (p_list) > 0);
if (free_data)
free (_cdio_list_node_data (p_node));
if (free_data && free_fn)
free_fn (_cdio_list_node_data (p_node));
if (_cdio_list_length (p_list) == 1)
{

View File

@ -346,4 +346,6 @@ bool cdio_charset_to_utf8(const char *src, size_t src_len, cdio_utf8_t **dst,
return (*dst != NULL);
}
#else
# error "The iconv library is needed to build drivers, but it is not detected"
#endif /* HAVE_ICONV */

View File

@ -1,5 +1,6 @@
/*
Copyright (C) 2003-2009, 2013-2014, 2016 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2003-2009, 2013-2014, 2016-2017 Rocky Bernstein
<rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify
@ -204,6 +205,11 @@ iso9660_get_dtime (const iso9660_dtime_t *idr_date, bool b_localtime,
p_tm->tm_sec = idr_date->dt_second - idr_date->dt_gmtoff * (15 * 60);
p_tm->tm_isdst = -1; /* information not available */
#ifdef HAVE_STRUCT_TM_TM_ZONE
/* Initialize everything */
p_tm->tm_zone = 0;
#endif
/* Recompute tm_wday and tm_yday via mktime. mktime will also renormalize
date values to account for the timezone offset. */
{
@ -271,6 +277,10 @@ iso9660_get_ltime (const iso9660_ltime_t *p_ldate,
#ifndef HAVE_TM_GMTOFF
p_tm->tm_sec += p_ldate->lt_gmtoff * (15 * 60);
#endif
#ifdef HAVE_STRUCT_TM_TM_ZONE
/* Initialize everything */
p_tm->tm_zone = 0;
#endif
/* Recompute tm_wday and tm_yday via mktime. mktime will also renormalize
date values to account for the timezone offset. */
@ -363,7 +373,7 @@ iso9660_set_ltime_with_timezone(const struct tm *p_tm,
if (!p_tm) return;
_snprintf(_pvd_date, 17,
snprintf(_pvd_date, 17,
"%4.4d%2.2d%2.2d" "%2.2d%2.2d%2.2d" "%2.2d",
p_tm->tm_year + 1900, p_tm->tm_mon + 1, p_tm->tm_mday,
p_tm->tm_hour, p_tm->tm_min, p_tm->tm_sec,
@ -776,7 +786,8 @@ iso9660_dir_add_entry_su(void *dir,
? strlen(filename) : 1); /* working hack! */
memcpy(&idr->filename.str[1], filename, from_711(idr->filename.len));
memcpy(&dir8[offset] + su_offset, su_data, su_size);
if (su_size > 0 && su_data)
memcpy(&dir8[offset] + su_offset, su_data, su_size);
}
void
@ -1111,7 +1122,7 @@ iso9660_pathname_isofy (const char pathname[], uint16_t version)
cdio_assert (strlen (pathname) < (sizeof (tmpbuf) - sizeof (";65535")));
_snprintf (tmpbuf, sizeof(tmpbuf), "%s;%d", pathname, version);
snprintf (tmpbuf, sizeof(tmpbuf), "%s;%d", pathname, version);
return strdup (tmpbuf);
}

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2003-2008, 2011-2015 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2003-2008, 2011-2015, 2017 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify
@ -16,6 +16,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* iso9660 filesystem-based routines */
/* FIXME: _cdio_list_free for iso9660 statbuf is insufficient because it doesn't
free bits that are allocated inside the data. */
#if defined(HAVE_CONFIG_H) && !defined(__CDIO_CONFIG_H__)
#include "config.h"
@ -202,6 +206,11 @@ iso9660_open_ext_private (const char *psz_path,
/*!
Open an ISO 9660 image for reading. Maybe in the future we will have
a mode. NULL is returned on error.
@param psz_path full path of ISO9660 file.
@return a IS9660 structure is unconditionally returned. The caller
should call iso9660_close() when done.
*/
iso9660_t *
iso9660_open (const char *psz_path /*, mode*/)
@ -210,8 +219,11 @@ iso9660_open (const char *psz_path /*, mode*/)
}
/*!
Open an ISO 9660 image for reading. Maybe in the future we will have
a mode. NULL is returned on error.
Open an ISO 9660 image for reading allowing various ISO 9660
extensions. Maybe in the future we will have a mode. NULL is
returned on error.
@see iso9660_open_fuzzy
*/
iso9660_t *
iso9660_open_ext (const char *psz_path,
@ -221,9 +233,19 @@ iso9660_open_ext (const char *psz_path,
}
/*!
Open an ISO 9660 image for reading. Maybe in the future we will have
a mode. NULL is returned on error.
/*! Open an ISO 9660 image for "fuzzy" reading. This means that we
will try to guess various internal offset based on internal
checks. This may be useful when trying to read an ISO 9660 image
contained in a file format that libiso9660 doesn't know natively
(or knows imperfectly.)
Some tolerence allowed for positioning the ISO 9660 image. We scan
for STANDARD_ID and use that to set the eventual offset to adjust
by (as long as that is <= i_fuzz).
Maybe in the future we will have a mode. NULL is returned on error.
@see iso9660_open, @see iso9660_fuzzy_ext
*/
iso9660_t *
iso9660_open_fuzzy (const char *psz_path, uint16_t i_fuzz /*, mode*/)
@ -232,8 +254,13 @@ iso9660_open_fuzzy (const char *psz_path, uint16_t i_fuzz /*, mode*/)
}
/*!
Open an ISO 9660 image for reading. Maybe in the future we will have
a mode. NULL is returned on error.
Open an ISO 9660 image for reading with some tolerence for positioning
of the ISO9660 image. We scan for ISO_STANDARD_ID and use that to set
the eventual offset to adjust by (as long as that is <= i_fuzz).
Maybe in the future we will have a mode. NULL is returned on error.
@see iso9660_open_ext @see iso9660_open_fuzzy
*/
iso9660_t *
iso9660_open_fuzzy_ext (const char *psz_path,
@ -244,16 +271,19 @@ iso9660_open_fuzzy_ext (const char *psz_path,
true);
}
/*!
Close previously opened ISO 9660 image.
True is unconditionally returned. If there was an error false would
be returned.
/*! Close previously opened ISO 9660 image and free resources
associated with the image. Call this when done using using an ISO
9660 image.
@return true is unconditionally returned. If there was an error
false would be returned.
*/
bool
iso9660_close (iso9660_t *p_iso)
{
if (NULL != p_iso) {
cdio_stdio_destroy(p_iso->stream);
p_iso->stream = NULL;
free(p_iso);
}
return true;
@ -708,6 +738,46 @@ iso9660_iso_seek_read (const iso9660_t *p_iso, void *ptr, lsn_t start,
/*!
Check for the end of a directory record list in a single directory
block. If at the end, set the offset to start of the next block and
return "true". The caller often skips actions only when at the end
of a record list.
*/
static bool
iso9660_check_dir_block_end(iso9660_dir_t *p_iso9660_dir, unsigned *offset)
{
if (!iso9660_get_dir_len(p_iso9660_dir))
{
/*
Length 0 indicates that no more directory records are in this
block. This matches how Linux and libburn's libisofs work.
Note that assignment below does not exactly round up.
If (offset % ISO_BLOCKSIZE) == 0 then offset is incremented
by ISO_BLOCKSIZE, i.e. the block is skipped.
*/
*offset += ISO_BLOCKSIZE - (*offset % ISO_BLOCKSIZE);
return true;
}
if ((*offset + iso9660_get_dir_len(p_iso9660_dir) - 1) / ISO_BLOCKSIZE
!= *offset / ISO_BLOCKSIZE)
{
/*
Directory record spans over block limit.
Hop to next block where a new record is supposed to begin,
if it is not after the end of the directory data.
*/
*offset += ISO_BLOCKSIZE - (*offset % ISO_BLOCKSIZE);
return true;
}
return false;
}
static iso9660_stat_t *
_iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
iso9660_stat_t *last_p_stat,
@ -738,9 +808,9 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
p_stat->type = (p_iso9660_dir->file_flags & ISO_DIRECTORY)
? _STAT_DIR : _STAT_FILE;
p_stat->lsn[p_stat->extents] = from_733 (p_iso9660_dir->extent);
p_stat->size[p_stat->extents] = from_733 (p_iso9660_dir->size);
p_stat->total_size += p_stat->size[p_stat->extents];
p_stat->secsize[p_stat->extents] = _cdio_len2blocks (p_stat->size[p_stat->extents], ISO_BLOCKSIZE);
p_stat->extsize[p_stat->extents] = from_733 (p_iso9660_dir->size);
p_stat->size += p_stat->extsize[p_stat->extents];
p_stat->secsize[p_stat->extents] = _cdio_len2blocks (p_stat->extsize[p_stat->extents], ISO_BLOCKSIZE);
p_stat->rr.b3_rock = dunno; /*FIXME should do based on mask */
p_stat->b_xa = false;
@ -806,19 +876,18 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
/* Use the plain ISO-9660 name when dealing with a multiextent file part */
strncpy(p_stat->filename, &p_iso9660_dir->filename.str[1], i_fname);
}
p_stat->extents++;
if (p_stat->extents > ISO_MAX_MULTIEXTENT) {
if (p_stat->extents >= ISO_MAX_MULTIEXTENT) {
cdio_warn("Warning: Too many multiextent file parts for '%s'", p_stat->filename);
free(p_stat->rr.psz_symlink);
free(p_stat);
return NULL;
}
p_stat->extents++;
iso9660_get_dtime(&(p_iso9660_dir->recording_time), true, &(p_stat->tm));
if (dir_len < sizeof (iso9660_dir_t)) {
free(p_stat->rr.psz_symlink);
free(p_stat);
iso9660_stat_free(p_stat);
return NULL;
}
@ -1006,11 +1075,8 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const iso9660_stat_t *_root,
iso9660_stat_t *p_iso9660_stat;
int cmp;
if (!iso9660_get_dir_len(p_iso9660_dir))
{
offset++;
continue;
}
if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
continue;
p_iso9660_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL,
dunno, p_env->u_joliet_level);
@ -1040,14 +1106,12 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const iso9660_stat_t *_root,
if (!cmp) {
iso9660_stat_t *ret_stat
= _fs_stat_traverse (p_cdio, p_iso9660_stat, &splitpath[1]);
free(p_iso9660_stat->rr.psz_symlink);
free(p_iso9660_stat);
iso9660_stat_free(p_iso9660_stat);
free (_dirbuf);
return ret_stat;
}
free(p_iso9660_stat->rr.psz_symlink);
free(p_iso9660_stat);
iso9660_stat_free(p_iso9660_stat);
offset += iso9660_get_dir_len(p_iso9660_dir);
}
@ -1063,9 +1127,9 @@ static iso9660_stat_t *
_fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
char **splitpath)
{
unsigned offset;
unsigned offset = 0;
uint8_t *_dirbuf = NULL;
int ret;
int ret, cmp;
iso9660_stat_t *p_stat = NULL;
iso9660_dir_t *p_iso9660_dir = NULL;
@ -1095,19 +1159,18 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
}
ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn[0], _root->secsize[0]);
if (ret!=ISO_BLOCKSIZE*_root->secsize[0]) return NULL;
if (ret!=ISO_BLOCKSIZE*_root->secsize[0]) {
free(_dirbuf);
return NULL;
}
for (offset = 0; offset < (_root->secsize[0] * ISO_BLOCKSIZE);
offset += iso9660_get_dir_len(p_iso9660_dir))
{
p_iso9660_dir = (void *) &_dirbuf[offset];
int cmp;
if (!iso9660_get_dir_len(p_iso9660_dir))
{
offset++;
continue;
}
if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
continue;
p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, p_stat,
p_iso->b_xa, p_iso->u_joliet_level);
@ -1120,7 +1183,7 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
/* If we have multiextent file parts, loop until the last one */
if (p_iso9660_dir->file_flags & ISO_MULTIEXTENT)
continue;
continue;
cmp = strcmp(splitpath[0], p_stat->filename);
@ -1147,14 +1210,11 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
if (!cmp) {
iso9660_stat_t *ret_stat
= _fs_iso_stat_traverse (p_iso, p_stat, &splitpath[1]);
free(p_stat->rr.psz_symlink);
free(p_stat);
iso9660_stat_free(p_stat);
free (_dirbuf);
return ret_stat;
}
free(p_stat->rr.psz_symlink);
free(p_stat);
iso9660_stat_free(p_stat);
p_stat = NULL;
}
@ -1166,7 +1226,22 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
}
/*!
Get file status for psz_path into stat. NULL is returned on error.
Return file status for psz_path. NULL is returned on error.
@param p_cdio the CD object to read from
@param psz_path filename path to look up and get information about
@return ISO 9660 file information
Important note:
You make get different results looking up "/" versus "/." and the
latter may give more complete information. "/" will take information
from the PVD only, whereas "/." will force a directory read of "/" and
find "." and in that Rock-Ridge information might be found which fills
in more stat information. Ideally iso9660_fs_stat should be fixed.
Patches anyone?
*/
iso9660_stat_t *
iso9660_fs_stat (CdIo_t *p_cdio, const char psz_path[])
@ -1223,9 +1298,21 @@ fs_stat_translate (void *p_image, stat_root_t stat_root,
return p_stat;
}
/*!
Return file status for path name psz_path. NULL is returned on error.
pathname version numbers in the ISO 9660 name are dropped, i.e. ;1
is removed and if level 1 ISO-9660 names are lowercased.
@param p_cdio the CD object to read from
@param psz_path filename path to look up and get information about
@return ISO 9660 file information. The caller must free the
returned result using iso9660_stat_free().
*/
iso9660_stat_t *
iso9660_fs_stat_translate (CdIo_t *p_cdio, const char psz_path[],
bool b_mode2)
iso9660_fs_stat_translate (CdIo_t *p_cdio, const char psz_path[])
{
return fs_stat_translate(p_cdio, (stat_root_t *) _fs_stat_root,
(stat_traverse_t *) _fs_stat_traverse,
@ -1233,10 +1320,14 @@ iso9660_fs_stat_translate (CdIo_t *p_cdio, const char psz_path[],
}
/*!
Get file status for psz_path into stat. NULL is returned on error.
pathname version numbers in the ISO 9660
name are dropped, i.e. ;1 is removed and if level 1 ISO-9660 names
are lowercased.
@param p_iso the ISO-9660 file image to get data from
@param psz_path filename path translate
@return file status for path name psz_path. NULL is returned on
error. pathname version numbers in the ISO 9660 name are dropped,
i.e. ;1 is removed and if level 1 ISO-9660 names are lowercased.
The caller must free the returned result using iso9660_stat_free().
*/
iso9660_stat_t *
iso9660_ifs_stat_translate (iso9660_t *p_iso, const char psz_path[])
@ -1248,7 +1339,13 @@ iso9660_ifs_stat_translate (iso9660_t *p_iso, const char psz_path[])
/*!
Get file status for psz_path into stat. NULL is returned on error.
@param p_cdio the CD object to read from
@param pzs_path path the look up
@return file status for pathname. NULL is returned on error.
The caller must free the returned result using iso9660_stat_free().
*/
iso9660_stat_t *
iso9660_ifs_stat (iso9660_t *p_iso, const char psz_path[])
@ -1273,12 +1370,17 @@ iso9660_ifs_stat (iso9660_t *p_iso, const char psz_path[])
/*!
Read psz_path (a directory) and return a list of iso9660_stat_t
of the files inside that. The caller must free the returned result.
pointers for the files inside that directory.
b_mode2 is historical. It is not used.
@param p_cdio the CD object to read from
@param pzs_path path the read the directory from.
@return file status for psz_path. The caller must free the
The caller must free the returned result using iso9660_stat_free().
*/
CdioList_t *
iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[], bool b_mode2)
CdioISO9660FileList_t *
iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[])
{
generic_img_private_t *p_env;
iso9660_dir_t *p_iso9660_dir;
@ -1294,27 +1396,28 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[], bool b_mode2)
if (!p_stat) return NULL;
if (p_stat->type != _STAT_DIR) {
free(p_stat->rr.psz_symlink);
free(p_stat);
iso9660_stat_free(p_stat);
return NULL;
}
{
unsigned offset = 0;
uint8_t *_dirbuf = NULL;
CdioList_t *retval = _cdio_list_new ();
CdioISO9660DirList_t *retval = _cdio_list_new ();
_dirbuf = calloc(1, p_stat->secsize[0] * ISO_BLOCKSIZE);
if (!_dirbuf)
{
cdio_warn("Couldn't calloc(1, %d)", p_stat->secsize[0] * ISO_BLOCKSIZE);
_cdio_list_free (retval, true);
iso9660_stat_free(p_stat);
iso9660_dirlist_free(retval);
return NULL;
}
if (cdio_read_data_sectors (p_cdio, _dirbuf, p_stat->lsn[0],
ISO_BLOCKSIZE, p_stat->secsize[0])) {
_cdio_list_free (retval, true);
iso9660_stat_free(p_stat);
iso9660_dirlist_free(retval);
return NULL;
}
@ -1322,11 +1425,8 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[], bool b_mode2)
{
p_iso9660_dir = (void *) &_dirbuf[offset];
if (!iso9660_get_dir_len(p_iso9660_dir))
{
offset++;
continue;
}
if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
continue;
p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir,
p_iso9660_stat, dunno,
@ -1343,8 +1443,8 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[], bool b_mode2)
cdio_assert (offset == (p_stat->secsize[0] * ISO_BLOCKSIZE));
free (_dirbuf);
free (p_stat);
free(_dirbuf);
iso9660_stat_free(p_stat);
return retval;
}
}
@ -1353,7 +1453,7 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[], bool b_mode2)
Read psz_path (a directory) and return a list of iso9660_stat_t
of the files inside that. The caller must free the returned result.
*/
CdioList_t *
CdioISO9660FileList_t *
iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
{
iso9660_dir_t *p_iso9660_dir;
@ -1367,8 +1467,7 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
if (!p_stat) return NULL;
if (p_stat->type != _STAT_DIR) {
free(p_stat->rr.psz_symlink);
free(p_stat);
iso9660_stat_free(p_stat);
return NULL;
}
@ -1383,9 +1482,8 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
if (!dirbuf_len)
{
cdio_warn("Invalid directory buffer sector size %u", p_stat->secsize[0]);
free(p_stat->rr.psz_symlink);
free(p_stat);
_cdio_list_free (retval, true);
iso9660_stat_free(p_stat);
_cdio_list_free (retval, true, NULL);
return NULL;
}
@ -1393,17 +1491,15 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
if (!_dirbuf)
{
cdio_warn("Couldn't calloc(1, %lu)", (unsigned long)dirbuf_len);
free(p_stat->rr.psz_symlink);
free(p_stat);
_cdio_list_free (retval, true);
iso9660_stat_free(p_stat);
_cdio_list_free (retval, true, NULL);
return NULL;
}
ret = iso9660_iso_seek_read (p_iso, _dirbuf, p_stat->lsn[0], p_stat->secsize[0]);
if (ret != dirbuf_len) {
_cdio_list_free (retval, true);
free(p_stat->rr.psz_symlink);
free(p_stat);
_cdio_list_free (retval, true, NULL);
iso9660_stat_free(p_stat);
free (_dirbuf);
return NULL;
}
@ -1412,11 +1508,8 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
{
p_iso9660_dir = (void *) &_dirbuf[offset];
if (!iso9660_get_dir_len(p_iso9660_dir))
{
offset++;
continue;
}
if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
continue;
p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir,
p_iso9660_stat,
@ -1433,11 +1526,10 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
}
free (_dirbuf);
free(p_stat->rr.psz_symlink);
free (p_stat);
iso9660_stat_free(p_stat);
if (offset != dirbuf_len) {
_cdio_list_free (retval, true);
_cdio_list_free (retval, true, (CdioDataFree_t) iso9660_stat_free);
return NULL;
}
@ -1445,16 +1537,26 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
}
}
typedef CdioList_t * (iso9660_readdir_t)
typedef CdioISO9660FileList_t * (iso9660_readdir_t)
(void *p_image, const char * psz_path);
CdioISO9660FileList_t *
iso9660_filelist_new(void) {
return (CdioISO9660FileList_t *) _cdio_list_new ();
}
CdioISO9660DirList_t *
iso9660_dirlist_new(void) {
return (CdioISO9660FileList_t *) _cdio_list_new ();
}
static iso9660_stat_t *
find_lsn_recurse (void *p_image, iso9660_readdir_t iso9660_readdir,
const char psz_path[], lsn_t lsn,
/*out*/ char **ppsz_full_filename)
{
CdioList_t *entlist = iso9660_readdir (p_image, psz_path);
CdioList_t *dirlist = _cdio_list_new ();
CdioISO9660FileList_t *entlist = iso9660_readdir (p_image, psz_path);
CdioISO9660DirList_t *dirlist = iso9660_filelist_new();
CdioListNode_t *entnode;
cdio_assert (entlist != NULL);
@ -1470,33 +1572,36 @@ find_lsn_recurse (void *p_image, iso9660_readdir_t iso9660_readdir,
if (*ppsz_full_filename != NULL) free(*ppsz_full_filename);
*ppsz_full_filename = calloc(1, len);
_snprintf (*ppsz_full_filename, len, "%s%s/", psz_path, psz_filename);
snprintf (*ppsz_full_filename, len, "%s%s/", psz_path, psz_filename);
if (statbuf->type == _STAT_DIR
&& strcmp ((char *) statbuf->filename, ".")
&& strcmp ((char *) statbuf->filename, "..")) {
snprintf (*ppsz_full_filename, len, "%s%s/", psz_path, psz_filename);
_cdio_list_append (dirlist, strdup(*ppsz_full_filename));
}
for (extent = 0; extent < statbuf->extents; extent++) {
if (statbuf->lsn[extent] == lsn) {
const unsigned int len2 = sizeof(iso9660_stat_t)+strlen(statbuf->filename)+1;
iso9660_stat_t *ret_stat = calloc(1, len2);
if (!ret_stat) {
_cdio_list_free (dirlist, true);
cdio_warn("Couldn't calloc(1, %d)", len2);
return NULL;
}
memcpy(ret_stat, statbuf, len2);
_cdio_list_free (entlist, true);
_cdio_list_free (dirlist, true);
if (statbuf->lsn[extent] == lsn) {
const unsigned int len2 = sizeof(iso9660_stat_t)+strlen(statbuf->filename)+1;
iso9660_stat_t *ret_stat = calloc(1, len2);
if (!ret_stat) {
iso9660_dirlist_free(dirlist);
cdio_warn("Couldn't calloc(1, %d)", len2);
free(*ppsz_full_filename);
*ppsz_full_filename = NULL;
return NULL;
}
memcpy(ret_stat, statbuf, len2);
iso9660_filelist_free (entlist);
iso9660_dirlist_free(dirlist);
return ret_stat;
}
}
}
}
_cdio_list_free (entlist, true);
iso9660_filelist_free (entlist);
/* now recurse/descend over directories encountered */
@ -1511,7 +1616,7 @@ find_lsn_recurse (void *p_image, iso9660_readdir_t iso9660_readdir,
ppsz_full_filename);
if (NULL != ret_stat) {
_cdio_list_free (dirlist, true);
iso9660_dirlist_free(dirlist);
return ret_stat;
}
}
@ -1520,7 +1625,7 @@ find_lsn_recurse (void *p_image, iso9660_readdir_t iso9660_readdir,
free(*ppsz_full_filename);
*ppsz_full_filename = NULL;
}
_cdio_list_free (dirlist, true);
iso9660_dirlist_free(dirlist);
return NULL;
}
@ -1534,15 +1639,27 @@ iso9660_stat_t *
iso9660_fs_find_lsn(CdIo_t *p_cdio, lsn_t i_lsn)
{
char *psz_full_filename = NULL;
return find_lsn_recurse (p_cdio, (iso9660_readdir_t *) iso9660_fs_readdir,
"/", i_lsn, &psz_full_filename);
iso9660_stat_t * p_statbuf;
p_statbuf = find_lsn_recurse (p_cdio, (iso9660_readdir_t *) iso9660_fs_readdir,
"/", i_lsn, &psz_full_filename);
if (psz_full_filename != NULL)
free(psz_full_filename);
return p_statbuf;
}
/*!
Given a directory pointer, find the filesystem entry that contains
lsn and return information about it.
LSN and return information about it.
Returns stat_t of entry if we found lsn, or NULL otherwise.
@param p_iso the ISO-9660 file image to get data from.
@param i_lsn the LSN to find
@param ppsz_full_filename the place to store the name of the path that has LSN.
On entry this should point to NULL. If not, the value will be freed.
On exit a value is malloc'd and the caller is responsible for
freeing the result.
@return stat_t of entry if we found lsn, or NULL otherwise.
Caller must free return value using iso9660_stat_free().
*/
iso9660_stat_t *
iso9660_fs_find_lsn_with_path(CdIo_t *p_cdio, lsn_t i_lsn,
@ -1556,21 +1673,40 @@ iso9660_fs_find_lsn_with_path(CdIo_t *p_cdio, lsn_t i_lsn,
Given a directory pointer, find the filesystem entry that contains
lsn and return information about it.
Returns stat_t of entry if we found lsn, or NULL otherwise.
@param p_iso the ISO-9660 file image to get data from.
@param i_lsn the LSN to find
@return stat_t of entry if we found lsn, or NULL otherwise.
Caller must free return value using iso9660_stat_free().
*/
iso9660_stat_t *
iso9660_ifs_find_lsn(iso9660_t *p_iso, lsn_t i_lsn)
{
char *psz_full_filename = NULL;
return find_lsn_recurse (p_iso, (iso9660_readdir_t *) iso9660_ifs_readdir,
"/", i_lsn, &psz_full_filename);
iso9660_stat_t *ret =
find_lsn_recurse (p_iso, (iso9660_readdir_t *) iso9660_ifs_readdir,
"/", i_lsn, &psz_full_filename);
if (psz_full_filename != NULL)
free(psz_full_filename);
return ret;
}
/*!
Given a directory pointer, find the filesystem entry that contains
lsn and return information about it.
Returns stat_t of entry if we found lsn, or NULL otherwise.
@param p_iso pointer to iso_t
@param i_lsn LSN to find
@param ppsz_path full path of lsn filename. On entry *ppsz_path should be
NULL. On return it will be allocated an point to the full path of the
file at lsn or NULL if the lsn is not found. You should deallocate
*ppsz_path when you are done using it.
@return stat_t of entry if we found lsn, or NULL otherwise.
Caller must free return value using iso9660_stat_free().
*/
iso9660_stat_t *
iso9660_ifs_find_lsn_with_path(iso9660_t *p_iso, lsn_t i_lsn,
@ -1582,14 +1718,38 @@ iso9660_ifs_find_lsn_with_path(iso9660_t *p_iso, lsn_t i_lsn,
/*!
Free the passed iso9660_stat_t structure.
@param p_stat iso9660 stat buffer to free.
*/
void
iso9660_stat_free(iso9660_stat_t *p_stat)
{
if (p_stat != NULL)
if (p_stat != NULL) {
if (p_stat->rr.psz_symlink) {
CDIO_FREE_IF_NOT_NULL(p_stat->rr.psz_symlink);
}
free(p_stat);
}
}
/*!
Free the passed CdioISOC9660FileList_t structure.
*/
void
iso9660_filelist_free(CdioISO9660FileList_t *p_filelist) {
_cdio_list_free(p_filelist, true, (CdioDataFree_t) iso9660_stat_free);
}
/*!
Free the passed CdioISOC9660DirList_t structure.
*/
void
iso9660_dirlist_free(CdioISO9660DirList_t *p_filelist) {
_cdio_list_free(p_filelist, true, free);
}
/*!
Return true if ISO 9660 image has extended attrributes (XA).
*/
@ -1624,36 +1784,41 @@ iso_have_rr_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
}
ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn[0], _root->secsize[0]);
if (ret!=ISO_BLOCKSIZE*_root->secsize[0]) return false;
if (ret!=ISO_BLOCKSIZE*_root->secsize[0]) {
free(_dirbuf);
return false;
}
while (offset < (_root->secsize[0] * ISO_BLOCKSIZE))
{
iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];
iso9660_stat_t *p_stat;
unsigned int i_last_component = 1;
if (!iso9660_get_dir_len(p_iso9660_dir))
{
offset++;
continue;
}
if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
continue;
p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL, p_iso->b_xa,
p_iso->u_joliet_level);
have_rr = p_stat->rr.b3_rock;
if ( have_rr != yep) {
have_rr = iso_have_rr_traverse (p_iso, p_stat, &splitpath[1], pu_file_limit);
if (strlen(splitpath[0]) == 0)
have_rr = false;
else
have_rr = iso_have_rr_traverse (p_iso, p_stat, &splitpath[i_last_component],
pu_file_limit);
}
free(p_stat);
if (have_rr != nope) {
free (_dirbuf);
return have_rr;
free (_dirbuf);
return have_rr;
}
offset += iso9660_get_dir_len(p_iso9660_dir);
*pu_file_limit = (*pu_file_limit)-1;
if ((*pu_file_limit) == 0) {
free (_dirbuf);
return dunno;
free (_dirbuf);
return dunno;
}
}
@ -1694,7 +1859,8 @@ iso9660_have_rr(iso9660_t *p_iso, uint64_t u_file_limit)
is_rr = iso_have_rr_traverse (p_iso, p_root, p_psz_splitpath, &u_file_limit);
free(p_root);
// _cdio_strfreev (p_psz_splitpath);
free(p_psz_splitpath[0]);
free(p_psz_splitpath[1]);
return is_rr;
}

View File

@ -1,5 +1,7 @@
/*
Copyright (C) 2005, 2008, 2010-2011, 2014 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2005, 2008, 2010-2011, 2014, 2017 Rocky Bernstein
<rocky@gnu.org>
Adapted from GNU/Linux fs/isofs/rock.c (C) 1992, 1993 Eric Youngdale
This program is free software: you can redistribute it and/or modify
@ -169,26 +171,12 @@ get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir,
while (len > 1){ /* There may be one byte for padding somewhere */
rr = (iso_extension_record_t *) chr;
sig = *chr+(*(chr+1) << 8);
switch(sig){
case SIG('S','P'):
case SIG('C','E'):
case SIG('E','R'):
case SIG('R','R'):
case SIG('P','X'):
case SIG('P','N'):
case SIG('S','L'):
case SIG('N','M'):
case SIG('C','L'):
case SIG('P','L'):
case SIG('T','F'):
case SIG('Z','F'):
case SIG('A','L'): // libburnia's AAIP extension (used by Kali Linux)
break;
default:
/* Warn about other Rock Ridge extensions */
cdio_warn("Unsupported Rock Ridge extension detected: '%c%c'\n", *chr, *(chr+1));
break;
}
/* We used to check for some vaid values of SIG, specifically
SP, CE, ER, RR, PX, PN, SL, NM, CL, PL, TF, and ZF.
However there are various extensions to this set. So we
skip checking now.
*/
if (rr->len == 0) goto out; /* Something got screwed up here */
chr += rr->len;
@ -434,8 +422,9 @@ parse_rock_ridge_stat_internal(iso9660_dir_t *p_iso9660_dir,
switch(p_sl->flags &~1){
case 0:
realloc_symlink(p_stat, p_sl->len);
memcpy(&(p_stat->rr.psz_symlink[p_stat->rr.i_symlink]),
p_sl->text, p_sl->len);
if (p_sl->text && p_sl->len)
memcpy(&(p_stat->rr.psz_symlink[p_stat->rr.i_symlink]),
p_sl->text, p_sl->len);
p_stat->rr.i_symlink += p_sl->len;
break;
case 4:

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2005-2006, 2008, 2011, 2013-2014
Copyright (C) 2005-2006, 2008, 2011, 2013-2014, 2017
Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
@ -47,6 +47,8 @@
# define __CDIO_CONFIG_H__ 1
#endif
#include <cdio/util.h>
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif
@ -634,7 +636,7 @@ udf_get_root (udf_t *p_udf, bool b_any_partition, partition_num_t i_partition)
}
#define free_and_null(x) \
free(x); \
CDIO_FREE_IF_NOT_NULL(x); \
x=NULL
/*!

View File

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 232, 326
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_ACCEPTFILES
CAPTION "Rufus 3.0.1306"
CAPTION "Rufus 3.0.1307"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@ -389,8 +389,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,0,1306,0
PRODUCTVERSION 3,0,1306,0
FILEVERSION 3,0,1307,0
PRODUCTVERSION 3,0,1307,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -407,13 +407,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "3.0.1306"
VALUE "FileVersion", "3.0.1307"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2018 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "3.0.1306"
VALUE "ProductVersion", "3.0.1307"
END
END
BLOCK "VarFileInfo"