diff options
Diffstat (limited to 'libarchive/archive_read_open_filename.c')
-rw-r--r-- | libarchive/archive_read_open_filename.c | 112 |
1 files changed, 71 insertions, 41 deletions
diff --git a/libarchive/archive_read_open_filename.c b/libarchive/archive_read_open_filename.c index 561289b694be..dd2e16022844 100644 --- a/libarchive/archive_read_open_filename.c +++ b/libarchive/archive_read_open_filename.c @@ -24,7 +24,6 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_filename.c 201093 2009-12-28 02:28:44Z kientzle $"); #ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> @@ -155,55 +154,73 @@ no_memory: return (ARCHIVE_FATAL); } +/* + * This function is an implementation detail of archive_read_open_filename_w, + * which is exposed as a separate API on Windows. + */ +#if !defined(_WIN32) || defined(__CYGWIN__) +static +#endif int -archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename, +archive_read_open_filenames_w(struct archive *a, const wchar_t **wfilenames, size_t block_size) { - struct read_file_data *mine = (struct read_file_data *)calloc(1, - sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t)); - if (!mine) + struct read_file_data *mine; + const wchar_t *wfilename = NULL; + if (wfilenames) + wfilename = *(wfilenames++); + + archive_clear_error(a); + do { - archive_set_error(a, ENOMEM, "No memory"); - return (ARCHIVE_FATAL); - } - mine->fd = -1; - mine->block_size = block_size; + if (wfilename == NULL) + wfilename = L""; + mine = (struct read_file_data *)calloc(1, + sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t)); + if (mine == NULL) + goto no_memory; + mine->block_size = block_size; + mine->fd = -1; - if (wfilename == NULL || wfilename[0] == L'\0') { - mine->filename_type = FNT_STDIN; - } else { + if (wfilename == NULL || wfilename[0] == L'\0') { + mine->filename_type = FNT_STDIN; + } else { #if defined(_WIN32) && !defined(__CYGWIN__) - mine->filename_type = FNT_WCS; - wcscpy(mine->filename.w, wfilename); + mine->filename_type = FNT_WCS; + wcscpy(mine->filename.w, wfilename); #else - /* - * POSIX system does not support a wchar_t interface for - * open() system call, so we have to translate a wchar_t - * filename to multi-byte one and use it. - */ - struct archive_string fn; - - archive_string_init(&fn); - if (archive_string_append_from_wcs(&fn, wfilename, - wcslen(wfilename)) != 0) { - if (errno == ENOMEM) - archive_set_error(a, errno, - "Can't allocate memory"); - else - archive_set_error(a, EINVAL, - "Failed to convert a wide-character" - " filename to a multi-byte filename"); + /* + * POSIX system does not support a wchar_t interface for + * open() system call, so we have to translate a wchar_t + * filename to multi-byte one and use it. + */ + struct archive_string fn; + + archive_string_init(&fn); + if (archive_string_append_from_wcs(&fn, wfilename, + wcslen(wfilename)) != 0) { + if (errno == ENOMEM) + archive_set_error(a, errno, + "Can't allocate memory"); + else + archive_set_error(a, EINVAL, + "Failed to convert a wide-character" + " filename to a multi-byte filename"); + archive_string_free(&fn); + free(mine); + return (ARCHIVE_FATAL); + } + mine->filename_type = FNT_MBS; + strcpy(mine->filename.m, fn.s); archive_string_free(&fn); - free(mine); - return (ARCHIVE_FATAL); - } - mine->filename_type = FNT_MBS; - strcpy(mine->filename.m, fn.s); - archive_string_free(&fn); #endif - } - if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) - return (ARCHIVE_FATAL); + } + if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) + return (ARCHIVE_FATAL); + if (wfilenames == NULL) + break; + wfilename = *(wfilenames++); + } while (wfilename != NULL && wfilename[0] != '\0'); archive_read_set_open_callback(a, file_open); archive_read_set_read_callback(a, file_read); archive_read_set_skip_callback(a, file_skip); @@ -212,6 +229,19 @@ archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename, archive_read_set_seek_callback(a, file_seek); return (archive_read_open1(a)); +no_memory: + archive_set_error(a, ENOMEM, "No memory"); + return (ARCHIVE_FATAL); +} + +int +archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename, + size_t block_size) +{ + const wchar_t *wfilenames[2]; + wfilenames[0] = wfilename; + wfilenames[1] = NULL; + return archive_read_open_filenames_w(a, wfilenames, block_size); } static int |