}
static PyObject* Archive_extract(ArchiveObject* self, PyObject* args) {
- const char* target = NULL;
+ const char* prefix = NULL;
- if (!PyArg_ParseTuple(args, "|z", &target))
+ if (!PyArg_ParseTuple(args, "|z", &prefix))
return NULL;
- // Make extraction path
- char* prefix = pakfire_archive_extraction_path(self->archive, target);
-
// Extract payload
int r = pakfire_archive_extract(self->archive, prefix);
- free(prefix);
-
- // Throw an exception on error
if (r) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
return r;
}
-PAKFIRE_EXPORT char* pakfire_archive_extraction_path(PakfireArchive archive, const char* target) {
- char prefix[PATH_MAX];
+static int pakfire_archive_extraction_path(PakfireArchive archive,
+ char* path, size_t length, const char* prefix) {
+ char buffer[PATH_MAX];
PakfirePackage pkg = pakfire_archive_get_package(archive);
if (!pkg)
- return NULL;
+ return 1;
- // Use a good default for source packages
- if (pakfire_package_is_source(pkg) && !target)
- target = "/usr/src/packages";
+ // Use a good default when no prefix is set
+ if (pakfire_package_is_source(pkg)) {
+ if (!prefix)
+ prefix = "/usr/src/packages";
- const char* nevra = pakfire_package_get_nevra(pkg);
+ pakfire_string_format(buffer, "%s/%s", prefix, pakfire_package_get_nevra(pkg));
+ } else {
+ if (!prefix)
+ prefix = "/";
+
+ pakfire_string_set(buffer, prefix);
+ }
- // Append package name and version to path
- int r = pakfire_path_join(prefix, target, nevra);
+ // Always prepend the root path
+ __pakfire_make_path(archive->pakfire, path, length, buffer);
// Cleanup
pakfire_package_unref(pkg);
- if (r < 0)
- return NULL;
-
- return strdup(prefix);
+ return 0;
}
struct pakfire_archive_extractor {
struct archive* writer;
- const char* prefix;
+ const char* path;
PakfireFilelist filelist;
struct pakfire_progressbar* progressbar;
};
DEBUG(archive->pakfire, "Extracting /%s\n", path);
// Prepend the prefix
- if (extractor->prefix) {
- r = pakfire_path_join(buffer, extractor->prefix, path);
+ if (extractor->path && *extractor->path) {
+ r = pakfire_path_join(buffer, extractor->path, path);
if (r < 0)
goto ERROR;
// Update hardlink destination
const char* link = archive_entry_hardlink(entry);
if (link) {
- r = pakfire_path_join(buffer, extractor->prefix, link);
+ r = pakfire_path_join(buffer, extractor->path, link);
if (r < 0)
goto ERROR;
PAKFIRE_EXPORT int pakfire_archive_extract(PakfireArchive archive, const char* prefix) {
struct pakfire_progressbar* progressbar = NULL;
+ char path[PATH_MAX];
struct archive* a = NULL;
struct archive* payload = NULL;
struct archive* writer = NULL;
size_t size;
- int r;
- // Use default path if nothing is set
- if (!prefix)
- prefix = pakfire_get_path(archive->pakfire);
+ int r = pakfire_archive_extraction_path(archive, path, sizeof(path) - 1, prefix);
+ if (r)
+ goto ERROR;
- DEBUG(archive->pakfire, "Extracting %s to %s\n", archive->path, prefix);
+ DEBUG(archive->pakfire, "Extracting %s to %s\n", archive->path, path);
// Create a filelist
if (!archive->filelist) {
struct pakfire_archive_extractor extractor = {
.writer = writer,
- .prefix = prefix,
+ .path = path,
.filelist = archive->filelist,
.progressbar = progressbar,
};