diff options
| author | Martin Matuska <mm@FreeBSD.org> | 2017-03-02 21:02:17 +0000 | 
|---|---|---|
| committer | Martin Matuska <mm@FreeBSD.org> | 2017-03-02 21:02:17 +0000 | 
| commit | 4b729aff5b4c807ecf8795452187ca06d5eb042d (patch) | |
| tree | fefc76886e467f8a662770c4f394a8b76ebaf606 /libarchive/archive_write_disk_posix.c | |
| parent | b2ee1181b4555230a015f1b8f27a1e7ec3c2bb6e (diff) | |
Diffstat (limited to 'libarchive/archive_write_disk_posix.c')
| -rw-r--r-- | libarchive/archive_write_disk_posix.c | 77 | 
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. */ | 
