aboutsummaryrefslogtreecommitdiff
path: root/libarchive/archive_read_open_filename.c
diff options
context:
space:
mode:
Diffstat (limited to 'libarchive/archive_read_open_filename.c')
-rw-r--r--libarchive/archive_read_open_filename.c112
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