return list;
}
+static PyObject* Archive_extract(ArchiveObject* self, PyObject* args) {
+ const char* target = NULL;
+
+ if (!PyArg_ParseTuple(args, "|z", &target))
+ return NULL;
+
+ // Make extraction path
+ char* prefix = pakfire_archive_extraction_path(self->archive, target);
+
+ // Extract payload
+ int r = pakfire_archive_extract(self->archive, prefix, PAKFIRE_ARCHIVE_USE_PAYLOAD);
+ pakfire_free(prefix);
+
+ // Throw an exception on error
+ if (r) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
static struct PyMethodDef Archive_methods[] = {
+ {
+ "extract",
+ (PyCFunction)Archive_extract,
+ METH_VARARGS,
+ NULL
+ },
{
"read",
(PyCFunction)Archive_read,
#include <pakfire/pakfire.h>
#include <pakfire/parser.h>
#include <pakfire/private.h>
+#include <pakfire/repo.h>
#include <pakfire/util.h>
#define BLOCKSIZE 1024 * 1024 // 1MB
return r;
}
+PAKFIRE_EXPORT char* pakfire_archive_extraction_path(PakfireArchive archive, const char* target) {
+ PakfireRepo repo = pakfire_repo_create(archive->pakfire, "dummy");
+
+ // Read package metadata
+ PakfirePackage pkg = pakfire_archive_make_package(archive, repo);
+ if (!pkg) {
+ pakfire_repo_unref(repo);
+ return NULL;
+ }
+
+ const char* arch = pakfire_package_get_arch(pkg);
+ int is_source = (strcmp(arch, "src") == 0);
+
+ // Use a good default for source packages
+ if (is_source && !target)
+ target = "/usr/src/packages";
+
+ char* nevra = pakfire_package_get_nevra(pkg);
+
+ // Append package name and version to path
+ char* prefix = pakfire_path_join(target, nevra);
+
+ // Cleanup
+ pakfire_package_unref(pkg);
+ pakfire_repo_unref(repo);
+ pakfire_free(nevra);
+
+ return prefix;
+}
+
PAKFIRE_EXPORT int pakfire_archive_extract(PakfireArchive archive, const char* prefix, int flags) {
struct archive* a;
struct archive* pa = NULL;
int use_payload = (flags & PAKFIRE_ARCHIVE_USE_PAYLOAD);
+ DEBUG(archive->pakfire, "Extracting %s to %s\n", archive->path, prefix);
+
if (use_payload)
pa = archive_open_payload(a);
} pakfire_archive_verify_status_t;
typedef enum pakfire_archive_flags {
- PAKFIRE_ARCHIVE_USE_PAYLOAD = 1 << 0,
+ PAKFIRE_ARCHIVE_USE_PAYLOAD = 1 << 0,
+ PAKFIRE_ARCHIVE_ADD_FILENAME_PREFIX = 1 << 1,
} pakfire_archive_flags_t;
PakfireArchive pakfire_archive_create(Pakfire pakfire);
int pakfire_archive_read(PakfireArchive archive, const char* filename,
void** data, size_t* data_size, int flags);
int pakfire_archive_extract(PakfireArchive archive, const char* prefix, int flags);
+char* pakfire_archive_extraction_path(PakfireArchive archive, const char* target);
const char* pakfire_archive_get_path(PakfireArchive archive);
pakfire_archive_count_signatures;
pakfire_archive_create;
pakfire_archive_extract;
+ pakfire_archive_extraction_path;
pakfire_archive_get_filelist;
pakfire_archive_get_format;
pakfire_archive_get_path;
def search(self, pattern):
return self.pakfire.search(pattern)
+ def extract(self, filenames, target=None):
+ if target and target == "/":
+ raise ValueError("Cannot extract to: %s" % target)
+
+ archives = []
+
+ # Open all archives
+ for filename in filenames:
+ a = _pakfire.Archive(self.pakfire, filename)
+ archives.append(a)
+
+ # Nothing to do when no archives where opened
+ if not archives:
+ return
+
+ # Extract them all
+ for archive in archives:
+ archive.extract(target)
+
# Transactions
def install(self, requires, **kwargs):
def handle_extract(self, ns):
with self.pakfire(ns) as p:
- # Open all packages.
- pkgs = []
- for pkg in ns.package:
- pkg = packages.open(self, None, pkg)
- pkgs.append(pkg)
-
- target_prefix = ns.target
-
- # Search for binary packages.
- binary_packages = any([p.type == "binary" for p in pkgs])
- source_packages = any([p.type == "source" for p in pkgs])
-
- if binary_packages and source_packages:
- raise Error(_("Cannot extract mixed package types"))
-
- if binary_packages and not target_prefix:
- raise Error(_("You must provide an install directory with --target=..."))
-
- elif source_packages and not target_prefix:
- target_prefix = "/usr/src/packages/"
-
- if target_prefix == "/":
- raise Error(_("Cannot extract to /."))
-
- for pkg in pkgs:
- if pkg.type == "binary":
- target_dir = target_prefix
- elif pkg.type == "source":
- target_dir = os.path.join(target_prefix, pkg.friendly_name)
-
- pkg.extract(message=_("Extracting"), prefix=target_dir)
+ p.extract(ns.package, target=ns.target)
class CliBuilder(Cli):