aboutsummaryrefslogtreecommitdiff
path: root/libarchive/archive_write_disk_posix.c
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2017-03-02 21:02:17 +0000
committerMartin Matuska <mm@FreeBSD.org>2017-03-02 21:02:17 +0000
commit4b729aff5b4c807ecf8795452187ca06d5eb042d (patch)
treefefc76886e467f8a662770c4f394a8b76ebaf606 /libarchive/archive_write_disk_posix.c
parentb2ee1181b4555230a015f1b8f27a1e7ec3c2bb6e (diff)
Diffstat (limited to 'libarchive/archive_write_disk_posix.c')
-rw-r--r--libarchive/archive_write_disk_posix.c77
1 files changed, 62 insertions, 15 deletions
diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
index 49e79dc23e9d..5a01e8450cef 100644
--- a/libarchive/archive_write_disk_posix.c
+++ b/libarchive/archive_write_disk_posix.c
@@ -1712,7 +1712,8 @@ _archive_write_disk_finish_entry(struct archive *_a)
const void *metadata;
size_t metadata_size;
metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
- if (metadata == NULL || metadata_size == 0) {
+ if ((a->todo & TODO_MAC_METADATA) == 0 ||
+ metadata == NULL || metadata_size == 0) {
#endif
r2 = archive_write_disk_set_acls(&a->archive, a->fd,
archive_entry_pathname(a->entry),
@@ -2067,6 +2068,7 @@ create_filesystem_object(struct archive_write_disk *a)
int r;
/* these for check_symlinks_fsobj */
char *linkname_copy; /* non-const copy of linkname */
+ struct stat st;
struct archive_string error_string;
int error_number;
@@ -2131,11 +2133,20 @@ create_filesystem_object(struct archive_write_disk *a)
a->todo = 0;
a->deferred = 0;
} else if (r == 0 && a->filesize > 0) {
- a->fd = open(a->name, O_WRONLY | O_TRUNC | O_BINARY
- | O_CLOEXEC | O_NOFOLLOW);
- __archive_ensure_cloexec_flag(a->fd);
- if (a->fd < 0)
+#ifdef HAVE_LSTAT
+ r = lstat(a->name, &st);
+#else
+ r = stat(a->name, &st);
+#endif
+ if (r != 0)
r = errno;
+ else if ((st.st_mode & AE_IFMT) == AE_IFREG) {
+ a->fd = open(a->name, O_WRONLY | O_TRUNC |
+ O_BINARY | O_CLOEXEC | O_NOFOLLOW);
+ __archive_ensure_cloexec_flag(a->fd);
+ if (a->fd < 0)
+ r = errno;
+ }
}
return (r);
#endif
@@ -2283,7 +2294,8 @@ _archive_write_disk_close(struct archive *_a)
chmod(p->name, p->mode);
if (p->fixup & TODO_ACLS)
#ifdef HAVE_DARWIN_ACL
- if (p->mac_metadata == NULL ||
+ if ((p->fixup & TODO_MAC_METADATA) == 0 ||
+ p->mac_metadata == NULL ||
p->mac_metadata_size == 0)
#endif
archive_write_disk_set_acls(&a->archive,
@@ -3455,12 +3467,19 @@ set_fflags(struct archive_write_disk *a)
#ifdef UF_APPEND
critical_flags |= UF_APPEND;
#endif
-#ifdef EXT2_APPEND_FL
+#if defined(FS_APPEND_FL)
+ critical_flags |= FS_APPEND_FL;
+#elif defined(EXT2_APPEND_FL)
critical_flags |= EXT2_APPEND_FL;
#endif
-#ifdef EXT2_IMMUTABLE_FL
+#if defined(FS_IMMUTABLE_FL)
+ critical_flags |= FS_IMMUTABLE_FL;
+#elif defined(EXT2_IMMUTABLE_FL)
critical_flags |= EXT2_IMMUTABLE_FL;
#endif
+#ifdef FS_JOURNAL_DATA_FL
+ critical_flags |= FS_JOURNAL_DATA_FL;
+#endif
if (a->todo & TODO_FFLAGS) {
archive_entry_fflags(a->entry, &set, &clear);
@@ -3572,7 +3591,10 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
return (ARCHIVE_WARN);
}
-#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
+#elif (defined(FS_IOC_GETFLAGS) && defined(FS_IOC_SETFLAGS) && \
+ defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
+ (defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS) && \
+ defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
/*
* Linux uses ioctl() to read and write file flags.
*/
@@ -3585,7 +3607,7 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
int newflags, oldflags;
int sf_mask = 0;
- if (set == 0 && clear == 0)
+ if (set == 0 && clear == 0)
return (ARCHIVE_OK);
/* Only regular files and dirs can have flags. */
if (!S_ISREG(mode) && !S_ISDIR(mode))
@@ -3606,12 +3628,19 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
* defines. (?) The code below degrades reasonably gracefully
* if sf_mask is incomplete.
*/
-#ifdef EXT2_IMMUTABLE_FL
+#if defined(FS_IMMUTABLE_FL)
+ sf_mask |= FS_IMMUTABLE_FL;
+#elif defined(EXT2_IMMUTABLE_FL)
sf_mask |= EXT2_IMMUTABLE_FL;
#endif
-#ifdef EXT2_APPEND_FL
+#if defined(FS_APPEND_FL)
+ sf_mask |= FS_APPEND_FL;
+#elif defined(EXT2_APPEND_FL)
sf_mask |= EXT2_APPEND_FL;
#endif
+#if defined(FS_JOURNAL_DATA_FL)
+ sf_mask |= FS_JOURNAL_DATA_FL;
+#endif
/*
* XXX As above, this would be way simpler if we didn't have
* to read the current flags from disk. XXX
@@ -3619,12 +3648,24 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
ret = ARCHIVE_OK;
/* Read the current file flags. */
- if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) < 0)
+ if (ioctl(myfd,
+#ifdef FS_IOC_GETFLAGS
+ FS_IOC_GETFLAGS,
+#else
+ EXT2_IOC_GETFLAGS,
+#endif
+ &oldflags) < 0)
goto fail;
/* Try setting the flags as given. */
newflags = (oldflags & ~clear) | set;
- if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
+ if (ioctl(myfd,
+#ifdef FS_IOC_SETFLAGS
+ FS_IOC_SETFLAGS,
+#else
+ EXT2_IOC_SETFLAGS,
+#endif
+ &newflags) >= 0)
goto cleanup;
if (errno != EPERM)
goto fail;
@@ -3633,7 +3674,13 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
newflags &= ~sf_mask;
oldflags &= sf_mask;
newflags |= oldflags;
- if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
+ if (ioctl(myfd,
+#ifdef FS_IOC_SETFLAGS
+ FS_IOC_SETFLAGS,
+#else
+ EXT2_IOC_SETFLAGS,
+#endif
+ &newflags) >= 0)
goto cleanup;
/* We couldn't set the flags, so report the failure. */