aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-07-29 14:22:31 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-07-31 11:36:04 +0100
commit5ecd787d40d26729bd49ccb10e015030277cf01d (patch)
tree0c8f033bf81fd47363f47968525987da19ebee42
parent6ef97b0bd5fa6462bbd27ab28b753814518e1f2b (diff)
downloadpaludis-5ecd787d40d26729bd49ccb10e015030277cf01d.tar.gz
paludis-5ecd787d40d26729bd49ccb10e015030277cf01d.tar.xz
Support symlinks in tars
-rw-r--r--paludis/tar_extras.cc18
-rw-r--r--paludis/tar_extras.hh1
-rw-r--r--paludis/tar_merger.cc10
-rw-r--r--paludis/tar_merger_TEST.cc6
-rwxr-xr-xpaludis/tar_merger_TEST_setup.sh2
5 files changed, 36 insertions, 1 deletions
diff --git a/paludis/tar_extras.cc b/paludis/tar_extras.cc
index 4e7199b..76f27fd 100644
--- a/paludis/tar_extras.cc
+++ b/paludis/tar_extras.cc
@@ -70,6 +70,24 @@ paludis_tar_extras_add_file(PaludisTarExtras * const extras, const std::string &
extern "C"
void
+paludis_tar_extras_add_sym(PaludisTarExtras * const extras, const std::string & from, const std::string & path, const std::string & dest)
+{
+ struct archive_entry * entry(archive_entry_new());
+
+ struct stat st;
+ lstat(from.c_str(), &st);
+
+ archive_entry_copy_pathname(entry, path.c_str());
+ archive_entry_copy_stat(entry, &st);
+ archive_entry_copy_symlink(entry, dest.c_str());
+ archive_write_header(extras->archive, entry);
+
+ archive_write_finish_entry(extras->archive);
+ archive_entry_free(entry);
+}
+
+extern "C"
+void
paludis_tar_extras_cleanup(PaludisTarExtras * const extras)
{
archive_write_close(extras->archive);
diff --git a/paludis/tar_extras.hh b/paludis/tar_extras.hh
index 0643be1..64ad05c 100644
--- a/paludis/tar_extras.hh
+++ b/paludis/tar_extras.hh
@@ -27,6 +27,7 @@ struct PaludisTarExtras;
extern "C" PaludisTarExtras * paludis_tar_extras_init(const std::string &) PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
extern "C" void paludis_tar_extras_add_file(PaludisTarExtras * const, const std::string &, const std::string &) PALUDIS_VISIBLE;
+extern "C" void paludis_tar_extras_add_sym(PaludisTarExtras * const, const std::string &, const std::string &, const std::string &) PALUDIS_VISIBLE;
extern "C" void paludis_tar_extras_cleanup(PaludisTarExtras * const) PALUDIS_VISIBLE;
#endif
diff --git a/paludis/tar_merger.cc b/paludis/tar_merger.cc
index 5a79d7c..cfa5898 100644
--- a/paludis/tar_merger.cc
+++ b/paludis/tar_merger.cc
@@ -39,11 +39,13 @@ namespace
{
typedef PaludisTarExtras * (* InitPtr) (const std::string &);
typedef void (* AddFilePtr) (PaludisTarExtras * const, const std::string &, const std::string &);
+ typedef void (* AddSymPtr) (PaludisTarExtras * const, const std::string &, const std::string &, const std::string &);
typedef void (* CleanupPtr) (PaludisTarExtras * const);
void * handle;
InitPtr init;
AddFilePtr add_file;
+ AddSymPtr add_sym;
CleanupPtr cleanup;
TarMergerHandle()
@@ -60,6 +62,10 @@ namespace
if (! add_file)
throw MergerError("Unable to add_file from libpaludistarextras due to error '" + stringify(::dlerror()) + "' from dlsym");
+ add_sym = STUPID_CAST(AddSymPtr, ::dlsym(handle, "paludis_tar_extras_add_sym"));
+ if (! add_sym)
+ throw MergerError("Unable to add_sym from libpaludistarextras due to error '" + stringify(::dlerror()) + "' from dlsym");
+
cleanup = STUPID_CAST(CleanupPtr, ::dlsym(handle, "paludis_tar_extras_cleanup"));
if (! cleanup)
throw MergerError("Unable to cleanup from libpaludistarextras due to error '" + stringify(::dlerror()) + "' from dlsym");
@@ -121,8 +127,10 @@ TarMerger::on_dir_main(bool, const FSEntry &, const FSEntry &)
}
void
-TarMerger::on_sym_main(bool, const FSEntry &, const FSEntry &)
+TarMerger::on_sym_main(bool, const FSEntry & src, const FSEntry & dst)
{
+ (*TarMergerHandle::get_instance()->add_sym)(_imp->tar, stringify(src), strip_leading(stringify(dst / src.basename()), "/"),
+ stringify(src.readlink()));
}
void
diff --git a/paludis/tar_merger_TEST.cc b/paludis/tar_merger_TEST.cc
index 5ed583a..42b9d2f 100644
--- a/paludis/tar_merger_TEST.cc
+++ b/paludis/tar_merger_TEST.cc
@@ -119,6 +119,12 @@ namespace test_cases
TEST_CHECK((FSEntry("tar_merger_TEST_dir") / "simple_extract" / "subdir" / "subsubdir" / "script").is_regular_file());
TEST_CHECK((FSEntry("tar_merger_TEST_dir") / "simple_extract" / "subdir" / "subsubdir" / "script").has_permission(fs_ug_owner, fs_perm_execute));
+
+ TEST_CHECK((FSEntry("tar_merger_TEST_dir") / "simple_extract" / "goodsym").is_symbolic_link());
+ TEST_CHECK((FSEntry("tar_merger_TEST_dir") / "simple_extract" / "goodsym").readlink() == "file");
+
+ TEST_CHECK((FSEntry("tar_merger_TEST_dir") / "simple_extract" / "badsym").is_symbolic_link());
+ TEST_CHECK((FSEntry("tar_merger_TEST_dir") / "simple_extract" / "badsym").readlink() == "nothing");
}
} test_simple_tar_merger;
}
diff --git a/paludis/tar_merger_TEST_setup.sh b/paludis/tar_merger_TEST_setup.sh
index 19619ec..48f34e9 100755
--- a/paludis/tar_merger_TEST_setup.sh
+++ b/paludis/tar_merger_TEST_setup.sh
@@ -18,3 +18,5 @@ Woohoo
END
chmod +x simple/subdir/subsubdir/script
+ln -s file simple/goodsym
+ln -s nothing simple/badsym