From a300fab1da39c0121027ae42e2d4f26b82c13d18 Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Thu, 16 Mar 2017 13:39:35 +0100 Subject: [PATCH] Deduplicate working path code in archive_read_disk_entry_from_file --- libarchive/archive_read_disk_acl_darwin.c | 15 +-- libarchive/archive_read_disk_acl_freebsd.c | 15 +-- libarchive/archive_read_disk_acl_linux.c | 18 +--- libarchive/archive_read_disk_acl_sunos.c | 18 +--- .../archive_read_disk_entry_from_file.c | 100 +++++++----------- libarchive/archive_read_disk_private.h | 5 +- 6 files changed, 54 insertions(+), 117 deletions(-) diff --git a/libarchive/archive_read_disk_acl_darwin.c b/libarchive/archive_read_disk_acl_darwin.c index dc332aceb..8de33b914 100644 --- a/libarchive/archive_read_disk_acl_darwin.c +++ b/libarchive/archive_read_disk_acl_darwin.c @@ -295,20 +295,9 @@ archive_read_disk_entry_setup_acls(struct archive_read_disk *a, accpath = NULL; if (*fd < 0) { - accpath = archive_entry_sourcepath(entry); - if (accpath == NULL || (a->tree != NULL && - a->tree_enter_working_dir(a->tree) != 0)) - accpath = archive_entry_pathname(entry); - if (accpath == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Couldn't determine file path to read ACLs"); + accpath = archive_read_disk_entry_setup_path(a, entry, fd); + if (accpath == NULL) return (ARCHIVE_WARN); - } - if (a->tree != NULL && (a->follow_symlinks || - archive_entry_filetype(entry) != AE_IFLNK)) { - *fd = a->open_on_current_dir(a->tree, - accpath, O_RDONLY | O_NONBLOCK); - } } archive_entry_acl_clear(entry); diff --git a/libarchive/archive_read_disk_acl_freebsd.c b/libarchive/archive_read_disk_acl_freebsd.c index ee87517ea..c09c3e1c2 100644 --- a/libarchive/archive_read_disk_acl_freebsd.c +++ b/libarchive/archive_read_disk_acl_freebsd.c @@ -275,20 +275,9 @@ archive_read_disk_entry_setup_acls(struct archive_read_disk *a, accpath = NULL; if (*fd < 0) { - accpath = archive_entry_sourcepath(entry); - if (accpath == NULL || (a->tree != NULL && - a->tree_enter_working_dir(a->tree) != 0)) - accpath = archive_entry_pathname(entry); - if (accpath == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Couldn't determine file path to read ACLs"); + accpath = archive_read_disk_entry_setup_path(a, entry, fd); + if (accpath == NULL) return (ARCHIVE_WARN); - } - if (a->tree != NULL && (a->follow_symlinks || - archive_entry_filetype(entry) != AE_IFLNK)) { - *fd = a->open_on_current_dir(a->tree, - accpath, O_RDONLY | O_NONBLOCK); - } } archive_entry_acl_clear(entry); diff --git a/libarchive/archive_read_disk_acl_linux.c b/libarchive/archive_read_disk_acl_linux.c index 3ddee2fef..033e68a1a 100644 --- a/libarchive/archive_read_disk_acl_linux.c +++ b/libarchive/archive_read_disk_acl_linux.c @@ -258,22 +258,10 @@ archive_read_disk_entry_setup_acls(struct archive_read_disk *a, r = ARCHIVE_OK; /* For default ACLs we need reachable accpath */ - if (*fd < 0 || S_ISDIR(archive_entry_mode(entry))) - { - accpath = archive_entry_sourcepath(entry); - if (accpath == NULL || (a->tree != NULL && - a->tree_enter_working_dir(a->tree) != 0)) - accpath = archive_entry_pathname(entry); - if (accpath == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Couldn't determine file path to read ACLs"); + if (*fd < 0 || S_ISDIR(archive_entry_mode(entry))) { + accpath = archive_read_disk_entry_setup_path(a, entry, fd); + if (accpath == NULL) return (ARCHIVE_WARN); - } - if (a->tree != NULL && *fd < 0 && (a->follow_symlinks || - archive_entry_filetype(entry) != AE_IFLNK)) { - *fd = a->open_on_current_dir(a->tree, - accpath, O_RDONLY | O_NONBLOCK); - } } archive_entry_acl_clear(entry); diff --git a/libarchive/archive_read_disk_acl_sunos.c b/libarchive/archive_read_disk_acl_sunos.c index 2bcdf0e34..066c30371 100644 --- a/libarchive/archive_read_disk_acl_sunos.c +++ b/libarchive/archive_read_disk_acl_sunos.c @@ -402,22 +402,10 @@ archive_read_disk_entry_setup_acls(struct archive_read_disk *a, accpath = NULL; - if (*fd < 0) - { - accpath = archive_entry_sourcepath(entry); - if (accpath == NULL || (a->tree != NULL && - a->tree_enter_working_dir(a->tree) != 0)) - accpath = archive_entry_pathname(entry); - if (accpath == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Couldn't determine file path to read ACLs"); + if (*fd < 0) { + accpath = archive_read_disk_entry_setup_path(a, entry, fd); + if (accpath == NULL) return (ARCHIVE_WARN); - } - if (a->tree != NULL && (a->follow_symlinks || - archive_entry_filetype(entry) != AE_IFLNK)) { - *fd = a->open_on_current_dir(a->tree, - accpath, O_RDONLY | O_NONBLOCK); - } } archive_entry_acl_clear(entry); diff --git a/libarchive/archive_read_disk_entry_from_file.c b/libarchive/archive_read_disk_entry_from_file.c index 181698a88..154dd0f65 100644 --- a/libarchive/archive_read_disk_entry_from_file.c +++ b/libarchive/archive_read_disk_entry_from_file.c @@ -124,6 +124,33 @@ archive_read_disk_entry_setup_acls(struct archive_read_disk *a, } #endif +/* + * Enter working directory and return working pathname of archive_entry. + * If a pointer to an integer is provided and its value is below zero + * open a file descriptor on this pahtname. + */ +const char * +archive_read_disk_entry_setup_path(struct archive_read_disk *a, + struct archive_entry *entry, int *fd) +{ + const char *path; + + path = archive_entry_sourcepath(entry); + + if (path == NULL || (a->tree != NULL && + a->tree_enter_working_dir(a->tree) != 0)) + path = archive_entry_pathname(entry); + if (path == NULL) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Couldn't determine path"); + } else if (fd != NULL && *fd < 0 && a->tree != NULL && + (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)) { + *fd = a->open_on_current_dir(a->tree, path, + O_RDONLY | O_NONBLOCK); + } + return (path); +} + int archive_read_disk_entry_from_file(struct archive *_a, struct archive_entry *entry, @@ -307,19 +334,10 @@ setup_mac_metadata(struct archive_read_disk *a, struct archive_string tempfile; (void)fd; /* UNUSED */ - name = archive_entry_sourcepath(entry); + + name = archive_read_disk_entry_setup_path(a, entry, NULL); if (name == NULL) - name = archive_entry_pathname(entry); - else if (a->tree != NULL && a->tree_enter_working_dir(a->tree) != 0) { - archive_set_error(&a->archive, errno, - "Can't change dir to read extended attributes"); - return (ARCHIVE_FAILED); - } - if (name == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't open file to read extended attributes: No name"); return (ARCHIVE_WARN); - } /* Short-circuit if there's nothing to do. */ have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK); @@ -494,21 +512,9 @@ setup_xattrs(struct archive_read_disk *a, path = NULL; if (*fd < 0) { - path = archive_entry_sourcepath(entry); - if (path == NULL || (a->tree != NULL && - a->tree_enter_working_dir(a->tree) != 0)) - path = archive_entry_pathname(entry); - if (path == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Couldn't determine file path to read " - "extended attributes"); + path = archive_read_disk_entry_setup_path(a, entry, fd); + if (path == NULL) return (ARCHIVE_WARN); - } - if (a->tree != NULL && (a->follow_symlinks || - archive_entry_filetype(entry) != AE_IFLNK)) { - *fd = a->open_on_current_dir(a->tree, - path, O_RDONLY | O_NONBLOCK); - } } #if HAVE_FLISTXATTR @@ -653,21 +659,9 @@ setup_xattrs(struct archive_read_disk *a, path = NULL; if (*fd < 0) { - path = archive_entry_sourcepath(entry); - if (path == NULL || (a->tree != NULL && - a->tree_enter_working_dir(a->tree) != 0)) - path = archive_entry_pathname(entry); - if (path == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Couldn't determine file path to read " - "extended attributes"); + path = archive_read_disk_entry_setup_path(a, entry, fd); + if (path == NULL) return (ARCHIVE_WARN); - } - if (a->tree != NULL && (a->follow_symlinks || - archive_entry_filetype(entry) != AE_IFLNK)) { - *fd = a->open_on_current_dir(a->tree, - path, O_RDONLY | O_NONBLOCK); - } } if (*fd >= 0) @@ -768,6 +762,7 @@ setup_sparse_fiemap(struct archive_read_disk *a, int64_t size; int count, do_fiemap, iters; int exit_sts = ARCHIVE_OK; + const char *path; if (archive_entry_filetype(entry) != AE_IFREG || archive_entry_size(entry) <= 0 @@ -775,11 +770,10 @@ setup_sparse_fiemap(struct archive_read_disk *a, return (ARCHIVE_OK); if (*fd < 0) { - const char *path; - - path = archive_entry_sourcepath(entry); + path = archive_read_disk_entry_setup_path(a, entry, NULL); if (path == NULL) - path = archive_entry_pathname(entry); + return (ARCHIVE_FAILED); + if (a->tree != NULL) *fd = a->open_on_current_dir(a->tree, path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); @@ -875,6 +869,7 @@ setup_sparse(struct archive_read_disk *a, off_t off_s, off_e; int exit_sts = ARCHIVE_OK; int check_fully_sparse = 0; + const char *path; if (archive_entry_filetype(entry) != AE_IFREG || archive_entry_size(entry) <= 0 @@ -882,19 +877,10 @@ setup_sparse(struct archive_read_disk *a, return (ARCHIVE_OK); /* Does filesystem support the reporting of hole ? */ - if (*fd < 0 && a->tree != NULL) { - const char *path; - - path = archive_entry_sourcepath(entry); + if (*fd < 0) { + path = archive_read_disk_entry_setup_path(a, entry, fd); if (path == NULL) - path = archive_entry_pathname(entry); - *fd = a->open_on_current_dir(a->tree, path, - O_RDONLY | O_NONBLOCK); - if (*fd < 0) { - archive_set_error(&a->archive, errno, - "Can't open `%s'", path); return (ARCHIVE_FAILED); - } } if (*fd >= 0) { @@ -906,12 +892,6 @@ setup_sparse(struct archive_read_disk *a, if (initial_off != 0) lseek(*fd, 0, SEEK_SET); } else { - const char *path; - - path = archive_entry_sourcepath(entry); - if (path == NULL) - path = archive_entry_pathname(entry); - #ifdef _PC_MIN_HOLE_SIZE if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0) return (ARCHIVE_OK); diff --git a/libarchive/archive_read_disk_private.h b/libarchive/archive_read_disk_private.h index 4996e161e..f03a0a9cc 100644 --- a/libarchive/archive_read_disk_private.h +++ b/libarchive/archive_read_disk_private.h @@ -88,8 +88,11 @@ struct archive_read_disk { void *excluded_cb_data; }; +const char * +archive_read_disk_entry_setup_path(struct archive_read_disk *, + struct archive_entry *, int *); + int archive_read_disk_entry_setup_acls(struct archive_read_disk *, struct archive_entry *, int *); - #endif -- 2.47.2