diff --git a/lib/libarchive/Makefile b/lib/libarchive/Makefile index 00acf1fd68b3..cbc9a3c6c578 100644 --- a/lib/libarchive/Makefile +++ b/lib/libarchive/Makefile @@ -121,6 +121,8 @@ MLINKS+= archive_entry.3 archive_entry_copy_fflags_text_w.3 MLINKS+= archive_entry.3 archive_entry_copy_gname.3 MLINKS+= archive_entry.3 archive_entry_copy_gname_w.3 MLINKS+= archive_entry.3 archive_entry_copy_hardlink_w.3 +MLINKS+= archive_entry.3 archive_entry_copy_link.3 +MLINKS+= archive_entry.3 archive_entry_copy_link_w.3 MLINKS+= archive_entry.3 archive_entry_copy_pathname_w.3 MLINKS+= archive_entry.3 archive_entry_copy_stat.3 MLINKS+= archive_entry.3 archive_entry_copy_symlink_w.3 diff --git a/lib/libarchive/archive_entry.3 b/lib/libarchive/archive_entry.3 index 556cf18af6e2..ba9fd6c2ed83 100644 --- a/lib/libarchive/archive_entry.3 +++ b/lib/libarchive/archive_entry.3 @@ -45,6 +45,8 @@ .Nm archive_entry_copy_gname_w , .Nm archive_entry_copy_hardlink , .Nm archive_entry_copy_hardlink_w , +.Nm archive_entry_copy_link , +.Nm archive_entry_copy_link_w , .Nm archive_entry_copy_pathname_w , .Nm archive_entry_copy_stat , .Nm archive_entry_copy_symlink , diff --git a/lib/libarchive/archive_entry.c b/lib/libarchive/archive_entry.c index ccb7854f5593..8fbc0ac9d1ee 100644 --- a/lib/libarchive/archive_entry.c +++ b/lib/libarchive/archive_entry.c @@ -754,6 +754,28 @@ archive_entry_set_link(struct archive_entry *entry, const char *target) aes_set_mbs(&entry->ae_hardlink, target); } +/* 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_symlink.aes_mbs != NULL || + entry->ae_symlink.aes_wcs != NULL) + aes_copy_mbs(&entry->ae_symlink, target); + else + aes_copy_mbs(&entry->ae_hardlink, target); +} + +/* 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_symlink.aes_mbs != NULL || + entry->ae_symlink.aes_wcs != NULL) + aes_copy_wcs(&entry->ae_symlink, target); + else + aes_copy_wcs(&entry->ae_hardlink, target); +} + void archive_entry_set_mode(struct archive_entry *entry, mode_t m) { diff --git a/lib/libarchive/archive_entry.h b/lib/libarchive/archive_entry.h index cc2bed2996ab..8c61b9553b63 100644 --- a/lib/libarchive/archive_entry.h +++ b/lib/libarchive/archive_entry.h @@ -163,6 +163,8 @@ void archive_entry_copy_hardlink(struct archive_entry *, const char *); void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *); void archive_entry_set_ino(struct archive_entry *, unsigned long); void archive_entry_set_link(struct archive_entry *, const char *); +void archive_entry_copy_link(struct archive_entry *, const char *); +void archive_entry_copy_link_w(struct archive_entry *, const wchar_t *); void archive_entry_set_mode(struct archive_entry *, mode_t); void archive_entry_set_mtime(struct archive_entry *, time_t, long); void archive_entry_set_nlink(struct archive_entry *, unsigned int); diff --git a/lib/libarchive/test/test_entry.c b/lib/libarchive/test/test_entry.c index 3841ce4094d9..3fd1d06d5990 100644 --- a/lib/libarchive/test/test_entry.c +++ b/lib/libarchive/test/test_entry.c @@ -120,8 +120,37 @@ DEFINE_TEST(test_entry) #else skipping("archive_entry_ino()"); #endif + /* link */ - /* TODO: implement these tests. */ + archive_entry_set_hardlink(e, "hardlinkname"); + archive_entry_set_symlink(e, NULL); + archive_entry_set_link(e, "link"); + assertEqualString(archive_entry_hardlink(e), "link"); + assertEqualString(archive_entry_symlink(e), NULL); + archive_entry_copy_link(e, "link2"); + assertEqualString(archive_entry_hardlink(e), "link2"); + assertEqualString(archive_entry_symlink(e), NULL); + archive_entry_copy_link_w(e, L"link3"); + assertEqualString(archive_entry_hardlink(e), "link3"); + assertEqualString(archive_entry_symlink(e), NULL); + archive_entry_set_hardlink(e, NULL); + archive_entry_set_symlink(e, "symlink"); + archive_entry_set_link(e, "link"); + assertEqualString(archive_entry_hardlink(e), NULL); + assertEqualString(archive_entry_symlink(e), "link"); + archive_entry_copy_link(e, "link2"); + assertEqualString(archive_entry_hardlink(e), NULL); + assertEqualString(archive_entry_symlink(e), "link2"); + archive_entry_copy_link_w(e, L"link3"); + assertEqualString(archive_entry_hardlink(e), NULL); + assertEqualString(archive_entry_symlink(e), "link3"); + /* Arbitrarily override hardlink if both hardlink and symlink set. */ + archive_entry_set_hardlink(e, "hardlink"); + archive_entry_set_symlink(e, "symlink"); + archive_entry_set_link(e, "link"); + assertEqualString(archive_entry_hardlink(e), "hardlink"); + assertEqualString(archive_entry_symlink(e), "link"); + /* mode */ archive_entry_set_mode(e, 0123456); assertEqualInt(archive_entry_mode(e), 0123456);