diff options
-rw-r--r-- | lib/libarchive/Makefile | 2 | ||||
-rw-r--r-- | lib/libarchive/archive_platform.h | 4 | ||||
-rw-r--r-- | lib/libarchive/archive_read_extract.c | 55 | ||||
-rw-r--r-- | lib/libarchive/configure.ac.in | 4 |
4 files changed, 52 insertions, 13 deletions
diff --git a/lib/libarchive/Makefile b/lib/libarchive/Makefile index dbe9dad..7c33278 100644 --- a/lib/libarchive/Makefile +++ b/lib/libarchive/Makefile @@ -7,7 +7,7 @@ LIB= archive -VERSION= 1.02.023 +VERSION= 1.02.026 ARCHIVE_API_FEATURE= 2 ARCHIVE_API_VERSION= 1 SHLIB_MAJOR= ${ARCHIVE_API_VERSION} diff --git a/lib/libarchive/archive_platform.h b/lib/libarchive/archive_platform.h index 4140df2..92dded3 100644 --- a/lib/libarchive/archive_platform.h +++ b/lib/libarchive/archive_platform.h @@ -57,11 +57,13 @@ #define HAVE_EILSEQ 1 #define HAVE_ERRNO_H 1 #define HAVE_FCHDIR 1 +#define HAVE_FCHFLAGS 1 #define HAVE_FCHMOD 1 #define HAVE_FCHOWN 1 #define HAVE_FCNTL_H 1 #define HAVE_FUTIMES 1 #define HAVE_INTTYPES_H 1 +#define HAVE_LCHFLAGS 1 #define HAVE_LCHMOD 1 #define HAVE_LCHOWN 1 #define HAVE_LIMITS_H 1 @@ -133,7 +135,7 @@ * for compatibility's sake, close files before trying to restore metadata. */ #if defined(HAVE_FCHMOD) || defined(HAVE_FUTIMES) || defined(HAVE_ACL_SET_FD) || defined(HAVE_ACL_SET_FD_NP) || defined(HAVE_FCHOWN) -#define CAN_RESTORE_METADATA_FD +#define CAN_RESTORE_METADATA_FD #endif /* Set up defaults for internal error codes. */ diff --git a/lib/libarchive/archive_read_extract.c b/lib/libarchive/archive_read_extract.c index 4a8f1d2..eb52e8e 100644 --- a/lib/libarchive/archive_read_extract.c +++ b/lib/libarchive/archive_read_extract.c @@ -1142,7 +1142,7 @@ set_perm(struct archive *a, int fd, struct archive_entry *entry, } -#if defined(HAVE_CHFLAGS) && !defined(__linux) +#if ( defined(HAVE_LCHFLAGS) || defined(HAVE_CHFLAGS) || defined(HAVE_FCHFLAGS) ) && !defined(__linux) static int set_fflags(struct archive *a, int fd, const char *name, mode_t mode, unsigned long set, unsigned long clear) @@ -1174,17 +1174,34 @@ set_fflags(struct archive *a, int fd, const char *name, mode_t mode, extract->st.st_flags &= ~clear; extract->st.st_flags |= set; +#ifdef HAVE_FCHFLAGS + /* If platform has fchflags() and we were given an fd, use it. */ + if (fd >= 0 && fchflags(fd, extract->st.st_flags) == 0) + return (ARCHIVE_OK); +#endif + /* + * If we can't use the fd to set the flags, we'll use the + * pathname to set flags. We prefer lchflags() but will use + * chflags() if we must. + */ +#ifdef HAVE_LCHFLAGS + if (lchflags(name, extract->st.st_flags) == 0) + return (ARCHIVE_OK); +#elif defined(HAVE_CHFLAGS) if (chflags(name, extract->st.st_flags) == 0) return (ARCHIVE_OK); - +#endif archive_set_error(a, errno, "Failed to set file flags"); return (ARCHIVE_WARN); } -#endif /* HAVE_CHFLAGS */ -#ifdef __linux -/* Linux has flags too, but uses ioctl() instead of chflags(). */ +#elif defined(__linux) + +/* + * Linux has flags too, but uses ioctl() to access them instead of + * having a separate chflags() system call. + */ static int set_fflags(struct archive *a, int fd, const char *name, mode_t mode, unsigned long set, unsigned long clear) @@ -1196,18 +1213,17 @@ set_fflags(struct archive *a, int fd, const char *name, mode_t mode, unsigned long newflags, oldflags; extract = a->extract; - ret = ARCHIVE_OK; if (set == 0 && clear == 0) - return (ret); + return (ARCHIVE_OK); /* Only regular files and dirs can have flags. */ if (!S_ISREG(mode) && !S_ISDIR(mode)) - return (ret); + return (ARCHIVE_OK); /* If we weren't given an fd, open it ourselves. */ if (myfd < 0) myfd = open(name, O_RDONLY|O_NONBLOCK); if (myfd < 0) - return (ret); + return (ARCHIVE_OK); /* * Linux has no define for the flags that are only settable @@ -1218,6 +1234,7 @@ set_fflags(struct archive *a, int fd, const char *name, mode_t mode, * XXX As above, this would be way simpler if we didn't have * to read the current flags from disk. XXX */ + ret = ARCHIVE_OK; /* Try setting the flags as given. */ if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) >= 0) { newflags = (oldflags & ~clear) | set; @@ -1244,6 +1261,26 @@ cleanup: close(myfd); return (ret); } + +#else /* Not HAVE_CHFLAGS && Not __linux */ + +/* + * Of course, some systems have neither BSD chflags() nor Linux' flags + * support through ioctl(). + */ +static int +set_fflags(struct archive *a, int fd, const char *name, mode_t mode, + unsigned long set, unsigned long clear) +{ + (void)a; + (void)fd; + (void)name; + (void)mode; + (void)set; + (void)clear; + return (ARCHIVE_OK); +} + #endif /* __linux */ #ifndef HAVE_POSIX_ACL diff --git a/lib/libarchive/configure.ac.in b/lib/libarchive/configure.ac.in index 09d8ed3..05a0b4c 100644 --- a/lib/libarchive/configure.ac.in +++ b/lib/libarchive/configure.ac.in @@ -73,8 +73,8 @@ AC_FUNC_MEMCMP AC_FUNC_STAT AC_FUNC_STRERROR_R AC_CHECK_FUNCS([acl_create_entry acl_init acl_set_fd acl_set_fd_np acl_set_file]) -AC_CHECK_FUNCS([chflags fchdir fchmod fchown futimes]) -AC_CHECK_FUNCS([lchmod lchown lutimes memmove]) +AC_CHECK_FUNCS([chflags fchdir fchflags fchmod fchown futimes]) +AC_CHECK_FUNCS([lchflags lchmod lchown lutimes memmove]) AC_CHECK_FUNCS([memset mkdir mkfifo strchr strdup strerror strrchr]) # Additional requirements |