Minor clean up for flags restoration: Use fchflags/lchflags when
available, stub out flags restore on platforms that don't support it, update autoconf to probe for fchflags and lchflags support.
This commit is contained in:
parent
48864d8c25
commit
495b0c0d52
@ -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}
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user