|
|
@@ -25,7 +25,6 @@
|
|
|
*/
|
|
|
|
|
|
#include "archive_platform.h"
|
|
|
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry.c 201096 2009-12-28 02:41:27Z kientzle $");
|
|
|
|
|
|
#ifdef HAVE_SYS_STAT_H
|
|
|
#include <sys/stat.h>
|
|
|
@@ -119,7 +118,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_entry.c 201096 2009-12-28 02:41:
|
|
|
static char * ae_fflagstostr(unsigned long bitset, unsigned long bitclear);
|
|
|
static const wchar_t *ae_wcstofflags(const wchar_t *stringp,
|
|
|
unsigned long *setp, unsigned long *clrp);
|
|
|
-static const char *ae_strtofflags(const char *stringp,
|
|
|
+static const char *ae_strtofflags(const char *stringp, size_t length,
|
|
|
unsigned long *setp, unsigned long *clrp);
|
|
|
|
|
|
#ifndef HAVE_WCSCPY
|
|
|
@@ -158,10 +157,9 @@ archive_entry_clear(struct archive_entry *entry)
|
|
|
return (NULL);
|
|
|
archive_mstring_clean(&entry->ae_fflags_text);
|
|
|
archive_mstring_clean(&entry->ae_gname);
|
|
|
- archive_mstring_clean(&entry->ae_hardlink);
|
|
|
+ archive_mstring_clean(&entry->ae_linkname);
|
|
|
archive_mstring_clean(&entry->ae_pathname);
|
|
|
archive_mstring_clean(&entry->ae_sourcepath);
|
|
|
- archive_mstring_clean(&entry->ae_symlink);
|
|
|
archive_mstring_clean(&entry->ae_uname);
|
|
|
archive_entry_copy_mac_metadata(entry, NULL, 0);
|
|
|
archive_acl_clear(&entry->acl);
|
|
|
@@ -196,10 +194,9 @@ archive_entry_clone(struct archive_entry *entry)
|
|
|
* character sets are different? XXX */
|
|
|
archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text);
|
|
|
archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname);
|
|
|
- archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink);
|
|
|
+ archive_mstring_copy(&entry2->ae_linkname, &entry->ae_linkname);
|
|
|
archive_mstring_copy(&entry2->ae_pathname, &entry->ae_pathname);
|
|
|
archive_mstring_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath);
|
|
|
- archive_mstring_copy(&entry2->ae_symlink, &entry->ae_symlink);
|
|
|
entry2->ae_set = entry->ae_set;
|
|
|
archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
|
|
|
|
|
|
@@ -372,6 +369,12 @@ archive_entry_filetype(struct archive_entry *entry)
|
|
|
return (AE_IFMT & entry->acl.mode);
|
|
|
}
|
|
|
|
|
|
+int
|
|
|
+archive_entry_filetype_is_set(struct archive_entry *entry)
|
|
|
+{
|
|
|
+ return (entry->ae_set & AE_SET_FILETYPE);
|
|
|
+}
|
|
|
+
|
|
|
void
|
|
|
archive_entry_fflags(struct archive_entry *entry,
|
|
|
unsigned long *set, unsigned long *clear)
|
|
|
@@ -425,6 +428,12 @@ archive_entry_gid(struct archive_entry *entry)
|
|
|
return (entry->ae_stat.aest_gid);
|
|
|
}
|
|
|
|
|
|
+int
|
|
|
+archive_entry_gid_is_set(struct archive_entry *entry)
|
|
|
+{
|
|
|
+ return (entry->ae_set & AE_SET_GID);
|
|
|
+}
|
|
|
+
|
|
|
const char *
|
|
|
archive_entry_gname(struct archive_entry *entry)
|
|
|
{
|
|
|
@@ -466,6 +475,15 @@ _archive_entry_gname_l(struct archive_entry *entry,
|
|
|
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_gname, p, len, sc));
|
|
|
}
|
|
|
|
|
|
+void
|
|
|
+archive_entry_set_link_to_hardlink(struct archive_entry *entry)
|
|
|
+{
|
|
|
+ if ((entry->ae_set & AE_SET_SYMLINK) != 0) {
|
|
|
+ entry->ae_set &= ~AE_SET_SYMLINK;
|
|
|
+ }
|
|
|
+ entry->ae_set |= AE_SET_HARDLINK;
|
|
|
+}
|
|
|
+
|
|
|
const char *
|
|
|
archive_entry_hardlink(struct archive_entry *entry)
|
|
|
{
|
|
|
@@ -473,7 +491,7 @@ archive_entry_hardlink(struct archive_entry *entry)
|
|
|
if ((entry->ae_set & AE_SET_HARDLINK) == 0)
|
|
|
return (NULL);
|
|
|
if (archive_mstring_get_mbs(
|
|
|
- entry->archive, &entry->ae_hardlink, &p) == 0)
|
|
|
+ entry->archive, &entry->ae_linkname, &p) == 0)
|
|
|
return (p);
|
|
|
if (errno == ENOMEM)
|
|
|
__archive_errx(1, "No memory");
|
|
|
@@ -487,7 +505,7 @@ archive_entry_hardlink_utf8(struct archive_entry *entry)
|
|
|
if ((entry->ae_set & AE_SET_HARDLINK) == 0)
|
|
|
return (NULL);
|
|
|
if (archive_mstring_get_utf8(
|
|
|
- entry->archive, &entry->ae_hardlink, &p) == 0)
|
|
|
+ entry->archive, &entry->ae_linkname, &p) == 0)
|
|
|
return (p);
|
|
|
if (errno == ENOMEM)
|
|
|
__archive_errx(1, "No memory");
|
|
|
@@ -501,13 +519,19 @@ archive_entry_hardlink_w(struct archive_entry *entry)
|
|
|
if ((entry->ae_set & AE_SET_HARDLINK) == 0)
|
|
|
return (NULL);
|
|
|
if (archive_mstring_get_wcs(
|
|
|
- entry->archive, &entry->ae_hardlink, &p) == 0)
|
|
|
+ entry->archive, &entry->ae_linkname, &p) == 0)
|
|
|
return (p);
|
|
|
if (errno == ENOMEM)
|
|
|
__archive_errx(1, "No memory");
|
|
|
return (NULL);
|
|
|
}
|
|
|
|
|
|
+int
|
|
|
+archive_entry_hardlink_is_set(struct archive_entry *entry)
|
|
|
+{
|
|
|
+ return (entry->ae_set & AE_SET_HARDLINK) != 0;
|
|
|
+}
|
|
|
+
|
|
|
int
|
|
|
_archive_entry_hardlink_l(struct archive_entry *entry,
|
|
|
const char **p, size_t *len, struct archive_string_conv *sc)
|
|
|
@@ -517,7 +541,7 @@ _archive_entry_hardlink_l(struct archive_entry *entry,
|
|
|
*len = 0;
|
|
|
return (0);
|
|
|
}
|
|
|
- return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_hardlink, p, len, sc));
|
|
|
+ return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_linkname, p, len, sc));
|
|
|
}
|
|
|
|
|
|
la_int64_t
|
|
|
@@ -631,32 +655,56 @@ archive_entry_perm(struct archive_entry *entry)
|
|
|
return (~AE_IFMT & entry->acl.mode);
|
|
|
}
|
|
|
|
|
|
+int
|
|
|
+archive_entry_perm_is_set(struct archive_entry *entry)
|
|
|
+{
|
|
|
+ return (entry->ae_set & AE_SET_PERM);
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+archive_entry_rdev_is_set(struct archive_entry *entry)
|
|
|
+{
|
|
|
+ return (entry->ae_set & AE_SET_RDEV);
|
|
|
+}
|
|
|
+
|
|
|
dev_t
|
|
|
archive_entry_rdev(struct archive_entry *entry)
|
|
|
{
|
|
|
- if (entry->ae_stat.aest_rdev_is_broken_down)
|
|
|
- return ae_makedev(entry->ae_stat.aest_rdevmajor,
|
|
|
- entry->ae_stat.aest_rdevminor);
|
|
|
- else
|
|
|
- return (entry->ae_stat.aest_rdev);
|
|
|
+ if (archive_entry_rdev_is_set(entry)) {
|
|
|
+ if (entry->ae_stat.aest_rdev_is_broken_down)
|
|
|
+ return ae_makedev(entry->ae_stat.aest_rdevmajor,
|
|
|
+ entry->ae_stat.aest_rdevminor);
|
|
|
+ else
|
|
|
+ return (entry->ae_stat.aest_rdev);
|
|
|
+ } else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
dev_t
|
|
|
archive_entry_rdevmajor(struct archive_entry *entry)
|
|
|
{
|
|
|
- if (entry->ae_stat.aest_rdev_is_broken_down)
|
|
|
- return (entry->ae_stat.aest_rdevmajor);
|
|
|
- else
|
|
|
- return major(entry->ae_stat.aest_rdev);
|
|
|
+ if (archive_entry_rdev_is_set(entry)) {
|
|
|
+ if (entry->ae_stat.aest_rdev_is_broken_down)
|
|
|
+ return (entry->ae_stat.aest_rdevmajor);
|
|
|
+ else
|
|
|
+ return major(entry->ae_stat.aest_rdev);
|
|
|
+ } else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
dev_t
|
|
|
archive_entry_rdevminor(struct archive_entry *entry)
|
|
|
{
|
|
|
- if (entry->ae_stat.aest_rdev_is_broken_down)
|
|
|
- return (entry->ae_stat.aest_rdevminor);
|
|
|
- else
|
|
|
- return minor(entry->ae_stat.aest_rdev);
|
|
|
+ if (archive_entry_rdev_is_set(entry)) {
|
|
|
+ if (entry->ae_stat.aest_rdev_is_broken_down)
|
|
|
+ return (entry->ae_stat.aest_rdevminor);
|
|
|
+ else
|
|
|
+ return minor(entry->ae_stat.aest_rdev);
|
|
|
+ } else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
la_int64_t
|
|
|
@@ -700,13 +748,22 @@ archive_entry_symlink(struct archive_entry *entry)
|
|
|
if ((entry->ae_set & AE_SET_SYMLINK) == 0)
|
|
|
return (NULL);
|
|
|
if (archive_mstring_get_mbs(
|
|
|
- entry->archive, &entry->ae_symlink, &p) == 0)
|
|
|
+ entry->archive, &entry->ae_linkname, &p) == 0)
|
|
|
return (p);
|
|
|
if (errno == ENOMEM)
|
|
|
__archive_errx(1, "No memory");
|
|
|
return (NULL);
|
|
|
}
|
|
|
|
|
|
+void
|
|
|
+archive_entry_set_link_to_symlink(struct archive_entry *entry)
|
|
|
+{
|
|
|
+ if ((entry->ae_set & AE_SET_HARDLINK) != 0) {
|
|
|
+ entry->ae_set &= ~AE_SET_HARDLINK;
|
|
|
+ }
|
|
|
+ entry->ae_set |= AE_SET_SYMLINK;
|
|
|
+}
|
|
|
+
|
|
|
int
|
|
|
archive_entry_symlink_type(struct archive_entry *entry)
|
|
|
{
|
|
|
@@ -720,7 +777,7 @@ archive_entry_symlink_utf8(struct archive_entry *entry)
|
|
|
if ((entry->ae_set & AE_SET_SYMLINK) == 0)
|
|
|
return (NULL);
|
|
|
if (archive_mstring_get_utf8(
|
|
|
- entry->archive, &entry->ae_symlink, &p) == 0)
|
|
|
+ entry->archive, &entry->ae_linkname, &p) == 0)
|
|
|
return (p);
|
|
|
if (errno == ENOMEM)
|
|
|
__archive_errx(1, "No memory");
|
|
|
@@ -734,7 +791,7 @@ archive_entry_symlink_w(struct archive_entry *entry)
|
|
|
if ((entry->ae_set & AE_SET_SYMLINK) == 0)
|
|
|
return (NULL);
|
|
|
if (archive_mstring_get_wcs(
|
|
|
- entry->archive, &entry->ae_symlink, &p) == 0)
|
|
|
+ entry->archive, &entry->ae_linkname, &p) == 0)
|
|
|
return (p);
|
|
|
if (errno == ENOMEM)
|
|
|
__archive_errx(1, "No memory");
|
|
|
@@ -750,7 +807,7 @@ _archive_entry_symlink_l(struct archive_entry *entry,
|
|
|
*len = 0;
|
|
|
return (0);
|
|
|
}
|
|
|
- return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_symlink, p, len, sc));
|
|
|
+ return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_linkname, p, len, sc));
|
|
|
}
|
|
|
|
|
|
la_int64_t
|
|
|
@@ -759,6 +816,12 @@ archive_entry_uid(struct archive_entry *entry)
|
|
|
return (entry->ae_stat.aest_uid);
|
|
|
}
|
|
|
|
|
|
+int
|
|
|
+archive_entry_uid_is_set(struct archive_entry *entry)
|
|
|
+{
|
|
|
+ return (entry->ae_set & AE_SET_UID);
|
|
|
+}
|
|
|
+
|
|
|
const char *
|
|
|
archive_entry_uname(struct archive_entry *entry)
|
|
|
{
|
|
|
@@ -827,6 +890,7 @@ archive_entry_set_filetype(struct archive_entry *entry, unsigned int type)
|
|
|
entry->stat_valid = 0;
|
|
|
entry->acl.mode &= ~AE_IFMT;
|
|
|
entry->acl.mode |= AE_IFMT & type;
|
|
|
+ entry->ae_set |= AE_SET_FILETYPE;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
@@ -840,10 +904,17 @@ archive_entry_set_fflags(struct archive_entry *entry,
|
|
|
|
|
|
const char *
|
|
|
archive_entry_copy_fflags_text(struct archive_entry *entry,
|
|
|
- const char *flags)
|
|
|
+ const char *flags)
|
|
|
{
|
|
|
- archive_mstring_copy_mbs(&entry->ae_fflags_text, flags);
|
|
|
- return (ae_strtofflags(flags,
|
|
|
+ return archive_entry_copy_fflags_text_len(entry, flags, strlen(flags));
|
|
|
+}
|
|
|
+
|
|
|
+const char *
|
|
|
+archive_entry_copy_fflags_text_len(struct archive_entry *entry,
|
|
|
+ const char *flags, size_t flags_length)
|
|
|
+{
|
|
|
+ archive_mstring_copy_mbs_len(&entry->ae_fflags_text, flags, flags_length);
|
|
|
+ return (ae_strtofflags(flags, flags_length,
|
|
|
&entry->ae_fflags_set, &entry->ae_fflags_clear));
|
|
|
}
|
|
|
|
|
|
@@ -859,8 +930,12 @@ archive_entry_copy_fflags_text_w(struct archive_entry *entry,
|
|
|
void
|
|
|
archive_entry_set_gid(struct archive_entry *entry, la_int64_t g)
|
|
|
{
|
|
|
+ if (g < 0) {
|
|
|
+ g = 0;
|
|
|
+ }
|
|
|
entry->stat_valid = 0;
|
|
|
entry->ae_stat.aest_gid = g;
|
|
|
+ entry->ae_set |= AE_SET_GID;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
@@ -908,6 +983,9 @@ _archive_entry_copy_gname_l(struct archive_entry *entry,
|
|
|
void
|
|
|
archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
|
|
|
{
|
|
|
+ if (ino < 0) {
|
|
|
+ ino = 0;
|
|
|
+ }
|
|
|
entry->stat_valid = 0;
|
|
|
entry->ae_set |= AE_SET_INO;
|
|
|
entry->ae_stat.aest_ino = ino;
|
|
|
@@ -916,6 +994,9 @@ archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
|
|
|
void
|
|
|
archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
|
|
|
{
|
|
|
+ if (ino < 0) {
|
|
|
+ ino = 0;
|
|
|
+ }
|
|
|
entry->stat_valid = 0;
|
|
|
entry->ae_set |= AE_SET_INO;
|
|
|
entry->ae_stat.aest_ino = ino;
|
|
|
@@ -924,17 +1005,24 @@ archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
|
|
|
void
|
|
|
archive_entry_set_hardlink(struct archive_entry *entry, const char *target)
|
|
|
{
|
|
|
- archive_mstring_copy_mbs(&entry->ae_hardlink, target);
|
|
|
- if (target != NULL)
|
|
|
- entry->ae_set |= AE_SET_HARDLINK;
|
|
|
- else
|
|
|
+ if (target == NULL) {
|
|
|
entry->ae_set &= ~AE_SET_HARDLINK;
|
|
|
+ if (entry->ae_set & AE_SET_SYMLINK) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ entry->ae_set |= AE_SET_HARDLINK;
|
|
|
+ }
|
|
|
+ entry->ae_set &= ~AE_SET_SYMLINK;
|
|
|
+ archive_mstring_copy_mbs(&entry->ae_linkname, target);
|
|
|
}
|
|
|
|
|
|
void
|
|
|
archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target)
|
|
|
{
|
|
|
- archive_mstring_copy_utf8(&entry->ae_hardlink, target);
|
|
|
+ if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
|
|
|
+ return;
|
|
|
+ archive_mstring_copy_utf8(&entry->ae_linkname, target);
|
|
|
if (target != NULL)
|
|
|
entry->ae_set |= AE_SET_HARDLINK;
|
|
|
else
|
|
|
@@ -944,7 +1032,9 @@ archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target)
|
|
|
void
|
|
|
archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
|
|
|
{
|
|
|
- archive_mstring_copy_mbs(&entry->ae_hardlink, target);
|
|
|
+ if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
|
|
|
+ return;
|
|
|
+ archive_mstring_copy_mbs(&entry->ae_linkname, target);
|
|
|
if (target != NULL)
|
|
|
entry->ae_set |= AE_SET_HARDLINK;
|
|
|
else
|
|
|
@@ -954,7 +1044,9 @@ archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
|
|
|
void
|
|
|
archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target)
|
|
|
{
|
|
|
- archive_mstring_copy_wcs(&entry->ae_hardlink, target);
|
|
|
+ if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
|
|
|
+ return;
|
|
|
+ archive_mstring_copy_wcs(&entry->ae_linkname, target);
|
|
|
if (target != NULL)
|
|
|
entry->ae_set |= AE_SET_HARDLINK;
|
|
|
else
|
|
|
@@ -964,12 +1056,14 @@ archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target
|
|
|
int
|
|
|
archive_entry_update_hardlink_utf8(struct archive_entry *entry, const char *target)
|
|
|
{
|
|
|
+ if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
|
|
|
+ return (0);
|
|
|
if (target != NULL)
|
|
|
entry->ae_set |= AE_SET_HARDLINK;
|
|
|
else
|
|
|
entry->ae_set &= ~AE_SET_HARDLINK;
|
|
|
if (archive_mstring_update_utf8(entry->archive,
|
|
|
- &entry->ae_hardlink, target) == 0)
|
|
|
+ &entry->ae_linkname, target) == 0)
|
|
|
return (1);
|
|
|
if (errno == ENOMEM)
|
|
|
__archive_errx(1, "No memory");
|
|
|
@@ -982,7 +1076,9 @@ _archive_entry_copy_hardlink_l(struct archive_entry *entry,
|
|
|
{
|
|
|
int r;
|
|
|
|
|
|
- r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
|
|
|
+ if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
|
|
|
+ return (0);
|
|
|
+ r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
|
|
|
target, len, sc);
|
|
|
if (target != NULL && r == 0)
|
|
|
entry->ae_set |= AE_SET_HARDLINK;
|
|
|
@@ -1073,51 +1169,50 @@ archive_entry_set_devminor(struct archive_entry *entry, dev_t m)
|
|
|
void
|
|
|
archive_entry_set_link(struct archive_entry *entry, const char *target)
|
|
|
{
|
|
|
- if (entry->ae_set & AE_SET_SYMLINK)
|
|
|
- archive_mstring_copy_mbs(&entry->ae_symlink, target);
|
|
|
- else
|
|
|
- archive_mstring_copy_mbs(&entry->ae_hardlink, target);
|
|
|
+ archive_mstring_copy_mbs(&entry->ae_linkname, target);
|
|
|
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
|
|
|
+ entry->ae_set |= AE_SET_HARDLINK;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void
|
|
|
archive_entry_set_link_utf8(struct archive_entry *entry, const char *target)
|
|
|
{
|
|
|
- if (entry->ae_set & AE_SET_SYMLINK)
|
|
|
- archive_mstring_copy_utf8(&entry->ae_symlink, target);
|
|
|
- else
|
|
|
- archive_mstring_copy_utf8(&entry->ae_hardlink, target);
|
|
|
+ archive_mstring_copy_utf8(&entry->ae_linkname, target);
|
|
|
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
|
|
|
+ entry->ae_set |= AE_SET_HARDLINK;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* Set symlink if symlink is already set, else set hardlink. */
|
|
|
void
|
|
|
archive_entry_copy_link(struct archive_entry *entry, const char *target)
|
|
|
{
|
|
|
- if (entry->ae_set & AE_SET_SYMLINK)
|
|
|
- archive_mstring_copy_mbs(&entry->ae_symlink, target);
|
|
|
- else
|
|
|
- archive_mstring_copy_mbs(&entry->ae_hardlink, target);
|
|
|
+ archive_mstring_copy_mbs(&entry->ae_linkname, target);
|
|
|
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
|
|
|
+ entry->ae_set |= AE_SET_HARDLINK;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* Set symlink if symlink is already set, else set hardlink. */
|
|
|
void
|
|
|
archive_entry_copy_link_w(struct archive_entry *entry, const wchar_t *target)
|
|
|
{
|
|
|
- if (entry->ae_set & AE_SET_SYMLINK)
|
|
|
- archive_mstring_copy_wcs(&entry->ae_symlink, target);
|
|
|
- else
|
|
|
- archive_mstring_copy_wcs(&entry->ae_hardlink, target);
|
|
|
+ archive_mstring_copy_wcs(&entry->ae_linkname, target);
|
|
|
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
|
|
|
+ entry->ae_set |= AE_SET_HARDLINK;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
int
|
|
|
archive_entry_update_link_utf8(struct archive_entry *entry, const char *target)
|
|
|
{
|
|
|
int r;
|
|
|
- if (entry->ae_set & AE_SET_SYMLINK)
|
|
|
- r = archive_mstring_update_utf8(entry->archive,
|
|
|
- &entry->ae_symlink, target);
|
|
|
- else
|
|
|
- r = archive_mstring_update_utf8(entry->archive,
|
|
|
- &entry->ae_hardlink, target);
|
|
|
+ r = archive_mstring_update_utf8(entry->archive,
|
|
|
+ &entry->ae_linkname, target);
|
|
|
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
|
|
|
+ entry->ae_set |= AE_SET_HARDLINK;
|
|
|
+ }
|
|
|
if (r == 0)
|
|
|
return (1);
|
|
|
if (errno == ENOMEM)
|
|
|
@@ -1131,12 +1226,11 @@ _archive_entry_copy_link_l(struct archive_entry *entry,
|
|
|
{
|
|
|
int r;
|
|
|
|
|
|
- if (entry->ae_set & AE_SET_SYMLINK)
|
|
|
- r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
|
|
|
- target, len, sc);
|
|
|
- else
|
|
|
- r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
|
|
|
+ r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
|
|
|
target, len, sc);
|
|
|
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
|
|
|
+ entry->ae_set |= AE_SET_HARDLINK;
|
|
|
+ }
|
|
|
return (r);
|
|
|
}
|
|
|
|
|
|
@@ -1145,6 +1239,7 @@ archive_entry_set_mode(struct archive_entry *entry, mode_t m)
|
|
|
{
|
|
|
entry->stat_valid = 0;
|
|
|
entry->acl.mode = m;
|
|
|
+ entry->ae_set |= AE_SET_PERM | AE_SET_FILETYPE;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
@@ -1220,6 +1315,7 @@ archive_entry_set_perm(struct archive_entry *entry, mode_t p)
|
|
|
entry->stat_valid = 0;
|
|
|
entry->acl.mode &= AE_IFMT;
|
|
|
entry->acl.mode |= ~AE_IFMT & p;
|
|
|
+ entry->ae_set |= AE_SET_PERM;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
@@ -1228,6 +1324,9 @@ archive_entry_set_rdev(struct archive_entry *entry, dev_t m)
|
|
|
entry->stat_valid = 0;
|
|
|
entry->ae_stat.aest_rdev = m;
|
|
|
entry->ae_stat.aest_rdev_is_broken_down = 0;
|
|
|
+ entry->ae_stat.aest_rdevmajor = 0;
|
|
|
+ entry->ae_stat.aest_rdevminor = 0;
|
|
|
+ entry->ae_set |= AE_SET_RDEV;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
@@ -1235,7 +1334,9 @@ archive_entry_set_rdevmajor(struct archive_entry *entry, dev_t m)
|
|
|
{
|
|
|
entry->stat_valid = 0;
|
|
|
entry->ae_stat.aest_rdev_is_broken_down = 1;
|
|
|
+ entry->ae_stat.aest_rdev = 0;
|
|
|
entry->ae_stat.aest_rdevmajor = m;
|
|
|
+ entry->ae_set |= AE_SET_RDEV;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
@@ -1243,12 +1344,17 @@ archive_entry_set_rdevminor(struct archive_entry *entry, dev_t m)
|
|
|
{
|
|
|
entry->stat_valid = 0;
|
|
|
entry->ae_stat.aest_rdev_is_broken_down = 1;
|
|
|
+ entry->ae_stat.aest_rdev = 0;
|
|
|
entry->ae_stat.aest_rdevminor = m;
|
|
|
+ entry->ae_set |= AE_SET_RDEV;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
archive_entry_set_size(struct archive_entry *entry, la_int64_t s)
|
|
|
{
|
|
|
+ if (s < 0) {
|
|
|
+ s = 0;
|
|
|
+ }
|
|
|
entry->stat_valid = 0;
|
|
|
entry->ae_stat.aest_size = s;
|
|
|
entry->ae_set |= AE_SET_SIZE;
|
|
|
@@ -1276,11 +1382,14 @@ archive_entry_copy_sourcepath_w(struct archive_entry *entry, const wchar_t *path
|
|
|
void
|
|
|
archive_entry_set_symlink(struct archive_entry *entry, const char *linkname)
|
|
|
{
|
|
|
- archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
|
|
|
- if (linkname != NULL)
|
|
|
- entry->ae_set |= AE_SET_SYMLINK;
|
|
|
- else
|
|
|
+ if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
|
|
|
+ return;
|
|
|
+ archive_mstring_copy_mbs(&entry->ae_linkname, linkname);
|
|
|
+ entry->ae_set &= ~AE_SET_HARDLINK;
|
|
|
+ if (linkname == NULL)
|
|
|
entry->ae_set &= ~AE_SET_SYMLINK;
|
|
|
+ else
|
|
|
+ entry->ae_set |= AE_SET_SYMLINK;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
@@ -1292,42 +1401,54 @@ archive_entry_set_symlink_type(struct archive_entry *entry, int type)
|
|
|
void
|
|
|
archive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname)
|
|
|
{
|
|
|
- archive_mstring_copy_utf8(&entry->ae_symlink, linkname);
|
|
|
- if (linkname != NULL)
|
|
|
- entry->ae_set |= AE_SET_SYMLINK;
|
|
|
- else
|
|
|
+ if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
|
|
|
+ return;
|
|
|
+ archive_mstring_copy_utf8(&entry->ae_linkname, linkname);
|
|
|
+ entry->ae_set &= ~AE_SET_HARDLINK;
|
|
|
+ if (linkname == NULL)
|
|
|
entry->ae_set &= ~AE_SET_SYMLINK;
|
|
|
+ else
|
|
|
+ entry->ae_set |= AE_SET_SYMLINK;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
archive_entry_copy_symlink(struct archive_entry *entry, const char *linkname)
|
|
|
{
|
|
|
- archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
|
|
|
- if (linkname != NULL)
|
|
|
- entry->ae_set |= AE_SET_SYMLINK;
|
|
|
- else
|
|
|
+ if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
|
|
|
+ return;
|
|
|
+ archive_mstring_copy_mbs(&entry->ae_linkname, linkname);
|
|
|
+ entry->ae_set &= ~AE_SET_HARDLINK;
|
|
|
+ if (linkname == NULL)
|
|
|
entry->ae_set &= ~AE_SET_SYMLINK;
|
|
|
+ else
|
|
|
+ entry->ae_set |= AE_SET_SYMLINK;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
archive_entry_copy_symlink_w(struct archive_entry *entry, const wchar_t *linkname)
|
|
|
{
|
|
|
- archive_mstring_copy_wcs(&entry->ae_symlink, linkname);
|
|
|
- if (linkname != NULL)
|
|
|
- entry->ae_set |= AE_SET_SYMLINK;
|
|
|
- else
|
|
|
+ if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
|
|
|
+ return;
|
|
|
+ archive_mstring_copy_wcs(&entry->ae_linkname, linkname);
|
|
|
+ entry->ae_set &= ~AE_SET_HARDLINK;
|
|
|
+ if (linkname == NULL)
|
|
|
entry->ae_set &= ~AE_SET_SYMLINK;
|
|
|
+ else
|
|
|
+ entry->ae_set |= AE_SET_SYMLINK;
|
|
|
}
|
|
|
|
|
|
int
|
|
|
archive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkname)
|
|
|
{
|
|
|
- if (linkname != NULL)
|
|
|
- entry->ae_set |= AE_SET_SYMLINK;
|
|
|
- else
|
|
|
+ if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
|
|
|
+ return (0);
|
|
|
+ entry->ae_set &= ~AE_SET_HARDLINK;
|
|
|
+ if (linkname == NULL)
|
|
|
entry->ae_set &= ~AE_SET_SYMLINK;
|
|
|
+ else
|
|
|
+ entry->ae_set |= AE_SET_SYMLINK;
|
|
|
if (archive_mstring_update_utf8(entry->archive,
|
|
|
- &entry->ae_symlink, linkname) == 0)
|
|
|
+ &entry->ae_linkname, linkname) == 0)
|
|
|
return (1);
|
|
|
if (errno == ENOMEM)
|
|
|
__archive_errx(1, "No memory");
|
|
|
@@ -1340,20 +1461,27 @@ _archive_entry_copy_symlink_l(struct archive_entry *entry,
|
|
|
{
|
|
|
int r;
|
|
|
|
|
|
- r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
|
|
|
+ if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
|
|
|
+ return (0);
|
|
|
+ entry->ae_set &= ~AE_SET_HARDLINK;
|
|
|
+ r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
|
|
|
linkname, len, sc);
|
|
|
- if (linkname != NULL && r == 0)
|
|
|
- entry->ae_set |= AE_SET_SYMLINK;
|
|
|
- else
|
|
|
+ if (linkname == NULL || r != 0)
|
|
|
entry->ae_set &= ~AE_SET_SYMLINK;
|
|
|
+ else
|
|
|
+ entry->ae_set |= AE_SET_SYMLINK;
|
|
|
return (r);
|
|
|
}
|
|
|
|
|
|
void
|
|
|
archive_entry_set_uid(struct archive_entry *entry, la_int64_t u)
|
|
|
{
|
|
|
+ if (u < 0) {
|
|
|
+ u = 0;
|
|
|
+ }
|
|
|
entry->stat_valid = 0;
|
|
|
entry->ae_stat.aest_uid = u;
|
|
|
+ entry->ae_set |= AE_SET_UID;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
@@ -2003,7 +2131,7 @@ ae_fflagstostr(unsigned long bitset, unsigned long bitclear)
|
|
|
* provided string.
|
|
|
*/
|
|
|
static const char *
|
|
|
-ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
|
|
|
+ae_strtofflags(const char *s, size_t l, unsigned long *setp, unsigned long *clrp)
|
|
|
{
|
|
|
const char *start, *end;
|
|
|
const struct flag *flag;
|
|
|
@@ -2014,15 +2142,19 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
|
|
|
start = s;
|
|
|
failed = NULL;
|
|
|
/* Find start of first token. */
|
|
|
- while (*start == '\t' || *start == ' ' || *start == ',')
|
|
|
+ while (l > 0 && (*start == '\t' || *start == ' ' || *start == ',')) {
|
|
|
start++;
|
|
|
- while (*start != '\0') {
|
|
|
+ l--;
|
|
|
+ }
|
|
|
+ while (l > 0) {
|
|
|
size_t length;
|
|
|
/* Locate end of token. */
|
|
|
end = start;
|
|
|
- while (*end != '\0' && *end != '\t' &&
|
|
|
- *end != ' ' && *end != ',')
|
|
|
+ while (l > 0 && *end != '\t' &&
|
|
|
+ *end != ' ' && *end != ',') {
|
|
|
end++;
|
|
|
+ l--;
|
|
|
+ }
|
|
|
length = end - start;
|
|
|
for (flag = fileflags; flag->name != NULL; flag++) {
|
|
|
size_t flag_length = strlen(flag->name);
|
|
|
@@ -2046,8 +2178,10 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
|
|
|
|
|
|
/* Find start of next token. */
|
|
|
start = end;
|
|
|
- while (*start == '\t' || *start == ' ' || *start == ',')
|
|
|
+ while (l > 0 && (*start == '\t' || *start == ' ' || *start == ',')) {
|
|
|
start++;
|
|
|
+ l--;
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|