aboutsummaryrefslogtreecommitdiff
path: root/paludis/repositories/e/ebuild/utils/unpaxinate.cc
diff options
context:
space:
mode:
Diffstat (limited to 'paludis/repositories/e/ebuild/utils/unpaxinate.cc')
-rw-r--r--paludis/repositories/e/ebuild/utils/unpaxinate.cc76
1 files changed, 76 insertions, 0 deletions
diff --git a/paludis/repositories/e/ebuild/utils/unpaxinate.cc b/paludis/repositories/e/ebuild/utils/unpaxinate.cc
new file mode 100644
index 000000000..4bd954418
--- /dev/null
+++ b/paludis/repositories/e/ebuild/utils/unpaxinate.cc
@@ -0,0 +1,76 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+#include <iostream>
+#include <string>
+#include <cstdlib>
+
+#include <archive.h>
+#include <archive_entry.h>
+#include <unistd.h>
+
+#include "config.h"
+
+int main(int argc, char *argv[])
+{
+ if (argc != 4)
+ return EXIT_FAILURE;
+
+ bool want_env(false);
+ if (argv[1] == std::string("env"))
+ want_env = true;
+ else if (argv[1] == std::string("img"))
+ want_env = false;
+ else
+ return EXIT_FAILURE;
+
+ std::string archive_file(argv[2]);
+
+ if (0 != chdir(argv[3]))
+ return EXIT_FAILURE;
+
+ archive * archive(archive_read_new());
+ archive_read_support_compression_all(archive);
+ archive_read_support_format_all(archive);
+
+ if (ARCHIVE_OK != archive_read_open_filename(archive, archive_file.c_str(), 10240))
+ {
+ std::cerr << "Could not open '" << archive_file << "'" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ archive_entry * entry;
+ while (ARCHIVE_OK == archive_read_next_header(archive, &entry))
+ {
+ std::string archive_filename(archive_entry_pathname(entry));
+ std::string out_filename;
+ if (archive_filename == "PBIN/environment" && want_env)
+ out_filename = "environment";
+ else if ((! want_env) && (0 != archive_filename.compare(0, 5, "PBIN/", 0, 5)))
+ out_filename = archive_filename;
+ else
+ {
+ archive_read_data_skip(archive);
+ continue;
+ }
+
+ std::cout << out_filename << std::endl;
+ archive_entry_set_pathname(entry, out_filename.c_str());
+
+ if (ARCHIVE_OK != archive_read_extract(archive, entry, ARCHIVE_EXTRACT_OWNER |
+ ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_ACL |
+ ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR | ARCHIVE_EXTRACT_SECURE_NODOTDOT))
+ {
+ std::cerr << "Could not extract '" << out_filename << "' from '" << archive_file << "'" << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (ARCHIVE_OK != archive_read_finish(archive))
+ {
+ std::cerr << "Could not finish reading '" << archive_file << "'" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+