diff --git a/include/cdio/util.h b/include/cdio/util.h index 6d40de85..654a7684 100644 --- a/include/cdio/util.h +++ b/include/cdio/util.h @@ -99,6 +99,12 @@ _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. */ +char * +_cdio_strdup_fixpath (const char path[]); + void _cdio_strfreev(char **strv); diff --git a/lib/driver/_cdio_stdio.c b/lib/driver/_cdio_stdio.c index d89625af..1865b35e 100644 --- a/lib/driver/_cdio_stdio.c +++ b/lib/driver/_cdio_stdio.c @@ -225,17 +225,27 @@ cdio_stdio_new(const char pathname[]) cdio_stream_io_functions funcs = { NULL, NULL, NULL, NULL, NULL, NULL }; _UserData *ud = NULL; struct CDIO_STAT statbuf; - - if (CDIO_STAT (pathname, &statbuf) == -1) + char* pathdup; + + if (pathname == NULL) + return NULL; + + /* MinGW may require a translated path */ + pathdup = _cdio_strdup_fixpath(pathname); + if (pathdup == NULL) + return NULL; + + if (CDIO_STAT (pathdup, &statbuf) == -1) { cdio_warn ("could not retrieve file info for `%s': %s", - pathname, strerror (errno)); + pathdup, strerror (errno)); + free(pathdup); return NULL; } ud = calloc (1, sizeof (_UserData)); - ud->pathname = strdup(pathname); + ud->pathname = pathdup; ud->st_size = statbuf.st_size; /* let's hope it doesn't change... */ funcs.open = _stdio_open; diff --git a/lib/driver/image/bincue.c b/lib/driver/image/bincue.c index b11b0c45..e939f1d0 100644 --- a/lib/driver/image/bincue.c +++ b/lib/driver/image/bincue.c @@ -251,7 +251,7 @@ parse_cuefile (_img_private_t *cd, const char *psz_cue_name) unsigned int i_line=0; /* line number in file of psz_line. */ int i = -1; /* Position in tocent. Same as cd->gen.i_tracks - 1 */ - char *psz_keyword, *psz_field; + char *psz_keyword, *psz_field, *psz_cue_name_dup; cdio_log_level_t log_level = (NULL == cd) ? CDIO_LOG_INFO : CDIO_LOG_WARN; cdtext_field_t cdtext_key; @@ -261,8 +261,13 @@ parse_cuefile (_img_private_t *cd, const char *psz_cue_name) if (NULL == psz_cue_name) return false; - - fp = fopen (psz_cue_name, "r"); + + psz_cue_name_dup = _cdio_strdup_fixpath(psz_cue_name); + if (NULL == psz_cue_name_dup) + return false; + + fp = fopen (psz_cue_name_dup, "r"); + free(psz_cue_name_dup); if (fp == NULL) { cdio_log(log_level, "error opening %s for reading: %s", psz_cue_name, strerror(errno)); diff --git a/lib/driver/image/cdrdao.c b/lib/driver/image/cdrdao.c index b075392f..658ab681 100644 --- a/lib/driver/image/cdrdao.c +++ b/lib/driver/image/cdrdao.c @@ -298,7 +298,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name) unsigned int i_line=0; /* line number in file of psz_line. */ int i = -1; /* Position in tocent. Same as cd->gen.i_tracks - 1 */ - char *psz_keyword, *psz_field; + char *psz_keyword, *psz_field, *psz_cue_name_dup; cdio_log_level_t log_level = (cd) ? CDIO_LOG_WARN : CDIO_LOG_INFO ; cdtext_field_t cdtext_key; @@ -307,8 +307,13 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name) if (NULL == psz_cue_name) return false; - - fp = fopen (psz_cue_name, "r"); + + psz_cue_name_dup = _cdio_strdup_fixpath(psz_cue_name); + if (NULL == psz_cue_name_dup) + return false; + + fp = fopen (psz_cue_name_dup, "r"); + free(psz_cue_name_dup); if (fp == NULL) { cdio_log(log_level, "error opening %s for reading: %s", psz_cue_name, strerror(errno)); diff --git a/lib/driver/util.c b/lib/driver/util.c index d2a295f6..bb170792 100644 --- a/lib/driver/util.c +++ b/lib/driver/util.c @@ -38,6 +38,8 @@ #include "inttypes.h" #endif +#include + #include "cdio_assert.h" #include #include @@ -136,6 +138,29 @@ _cdio_strdup_upper (const char str[]) return new_str; } +/* Convert MinGW/MSYS paths that start in "/c/..." to "c:/..." + so that they can be used with fopen(), stat(), etc. */ +char * +_cdio_strdup_fixpath (const char path[]) +{ + char *new_path = NULL; + + if (path) + { + new_path = strdup (path); +#if defined(_WIN32) + if (new_path && (strlen (new_path) >= 3) && (new_path[0] == '/') && + (new_path[2] == '/') && (isalpha (new_path[1]))) + { + new_path[0] = new_path[1]; + new_path[1] = ':'; + } +#endif + } + + return new_path; +} + uint8_t cdio_to_bcd8 (uint8_t n) {