diff options
author | Michihiro NAKAJIMA <ggcueroad@gmail.com> | 2012-02-26 17:15:18 +0900 |
---|---|---|
committer | Michihiro NAKAJIMA <ggcueroad@gmail.com> | 2012-02-26 17:15:18 +0900 |
commit | 601ddcae23beb239e2edadf824b39f69ef572d76 (patch) | |
tree | 4d9f25415b29918243920521782af8e1ee8f22c8 /libarchive/archive_read_disk_windows.c | |
parent | 4c29991ab8739ba6e37669d7ea1491810c76f18c (diff) | |
download | libarchive-601ddcae23beb239e2edadf824b39f69ef572d76.tar.gz |
Improve directory traversals on Windows to surely clear an archive_entry
object when the entry is excluded as well as the POSIX version of this does.
Diffstat (limited to 'libarchive/archive_read_disk_windows.c')
-rw-r--r-- | libarchive/archive_read_disk_windows.c | 68 |
1 files changed, 36 insertions, 32 deletions
diff --git a/libarchive/archive_read_disk_windows.c b/libarchive/archive_read_disk_windows.c index b404d03b..6b6108ab 100644 --- a/libarchive/archive_read_disk_windows.c +++ b/libarchive/archive_read_disk_windows.c @@ -748,27 +748,14 @@ abort_read_data: } static int -_archive_read_next_header2(struct archive *_a, struct archive_entry *entry) +next_entry(struct archive_read_disk *a, struct tree *t, + struct archive_entry *entry) { - struct archive_read_disk *a = (struct archive_read_disk *)_a; - struct tree *t; const BY_HANDLE_FILE_INFORMATION *st; const BY_HANDLE_FILE_INFORMATION *lst; const char*name; int descend, r; - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_read_next_header2"); - - t = a->tree; - if (t->entry_fh != INVALID_HANDLE_VALUE) { - cancel_async(t); - close_and_restore_time(t->entry_fh, t, &t->restore_time); - t->entry_fh = INVALID_HANDLE_VALUE; - } - -next_entry: st = NULL; lst = NULL; t->descend = 0; @@ -818,8 +805,7 @@ next_entry: if (a->excluded_cb_func) a->excluded_cb_func(&(a->archive), a->excluded_cb_data, entry); - archive_entry_clear(entry); - goto next_entry; + return (ARCHIVE_RETRY); } } @@ -863,10 +849,8 @@ next_entry: if (t->initial_filesystem_id == -1) t->initial_filesystem_id = t->current_filesystem_id; if (!a->traverse_mount_points) { - if (t->initial_filesystem_id != t->current_filesystem_id) { - archive_entry_clear(entry); - goto next_entry; - } + if (t->initial_filesystem_id != t->current_filesystem_id) + return (ARCHIVE_RETRY); } t->descend = descend; @@ -893,16 +877,15 @@ next_entry: if (a->excluded_cb_func) a->excluded_cb_func(&(a->archive), a->excluded_cb_data, entry); - archive_entry_clear(entry); - goto next_entry; + return (ARCHIVE_RETRY); } } /* Lookup uname/gname */ - name = archive_read_disk_uname(_a, archive_entry_uid(entry)); + name = archive_read_disk_uname(&(a->archive), archive_entry_uid(entry)); if (name != NULL) archive_entry_copy_uname(entry, name); - name = archive_read_disk_gname(_a, archive_entry_gid(entry)); + name = archive_read_disk_gname(&(a->archive), archive_entry_gid(entry)); if (name != NULL) archive_entry_copy_gname(entry, name); @@ -920,8 +903,7 @@ next_entry: if (a->excluded_cb_func) a->excluded_cb_func(&(a->archive), a->excluded_cb_data, entry); - archive_entry_clear(entry); - goto next_entry; + return (ARCHIVE_RETRY); } } @@ -929,12 +911,11 @@ next_entry: * Invoke a meta data filter callback. */ if (a->metadata_filter_func) { - if (!a->metadata_filter_func(_a, - a->metadata_filter_data, entry)) { - archive_entry_clear(entry); - goto next_entry; - } + if (!a->metadata_filter_func(&(a->archive), + a->metadata_filter_data, entry)) + return (ARCHIVE_RETRY); } + archive_entry_copy_sourcepath_w(entry, tree_current_access_path(t)); r = ARCHIVE_OK; @@ -960,6 +941,29 @@ next_entry: (st->dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0) r = setup_sparse_from_disk(a, entry, t->entry_fh); } + return (r); +} + +static int +_archive_read_next_header2(struct archive *_a, struct archive_entry *entry) +{ + struct archive_read_disk *a = (struct archive_read_disk *)_a; + struct tree *t; + int r; + + archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, + ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, + "archive_read_next_header2"); + + t = a->tree; + if (t->entry_fh != INVALID_HANDLE_VALUE) { + cancel_async(t); + close_and_restore_time(t->entry_fh, t, &t->restore_time); + t->entry_fh = INVALID_HANDLE_VALUE; + } + + while ((r = next_entry(a, t, entry)) == ARCHIVE_RETRY) + archive_entry_clear(entry); /* * EOF and FATAL are persistent at this layer. By |