diff options
| author | Martin Matuska <mm@FreeBSD.org> | 2020-12-01 10:36:46 +0000 |
|---|---|---|
| committer | Martin Matuska <mm@FreeBSD.org> | 2020-12-01 10:36:46 +0000 |
| commit | d5f2a5ff11474589cccacfc8e153d437f48530e2 (patch) | |
| tree | aeb7e201bfb2d629755c396db8001e39d116e852 /libarchive/archive_write_disk_posix.c | |
| parent | 4dd2ae60c22045bc4e4f53a0cf45028322168ec0 (diff) | |
Notes
Diffstat (limited to 'libarchive/archive_write_disk_posix.c')
| -rw-r--r-- | libarchive/archive_write_disk_posix.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c index 0168d0d411bd..7e32fca92918 100644 --- a/libarchive/archive_write_disk_posix.c +++ b/libarchive/archive_write_disk_posix.c @@ -546,6 +546,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry) { struct archive_write_disk *a = (struct archive_write_disk *)_a; struct fixup_entry *fe; + const char *linkname; int ret, r; archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, @@ -591,6 +592,17 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry) return (ret); /* + * Check if we have a hardlink that points to itself. + */ + linkname = archive_entry_hardlink(a->entry); + if (linkname != NULL && strcmp(a->name, linkname) == 0) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Skipping hardlink pointing to itself: %s", + a->name); + return (ARCHIVE_WARN); + } + + /* * Query the umask so we get predictable mode settings. * This gets done on every call to _write_header in case the * user edits their umask during the extraction for some @@ -4411,10 +4423,19 @@ set_xattrs(struct archive_write_disk *a) int e; int namespace; + namespace = EXTATTR_NAMESPACE_USER; + if (strncmp(name, "user.", 5) == 0) { /* "user." attributes go to user namespace */ name += 5; namespace = EXTATTR_NAMESPACE_USER; + } else if (strncmp(name, "system.", 7) == 0) { + name += 7; + namespace = EXTATTR_NAMESPACE_SYSTEM; + if (!strcmp(name, "nfs4.acl") || + !strcmp(name, "posix1e.acl_access") || + !strcmp(name, "posix1e.acl_default")) + continue; } else { /* Other namespaces are unsupported */ archive_strcat(&errlist, name); @@ -4425,8 +4446,29 @@ set_xattrs(struct archive_write_disk *a) } if (a->fd >= 0) { + /* + * On FreeBSD, extattr_set_fd does not + * return the same as + * extattr_set_file. It returns zero + * on success, non-zero on failure. + * + * We can detect the failure by + * manually setting errno prior to the + * call and checking after. + * + * If errno remains zero, fake the + * return value by setting e to size. + * + * This is a hack for now until I + * (Shawn Webb) get FreeBSD to fix the + * issue, if that's even possible. + */ + errno = 0; e = extattr_set_fd(a->fd, namespace, name, value, size); + if (e == 0 && errno == 0) { + e = size; + } } else { e = extattr_set_link( archive_entry_pathname(entry), namespace, |
