#include <pakfire/pakfire.h>
#include <pakfire/parser.h>
#include <pakfire/private.h>
+#include <pakfire/progressbar.h>
#include <pakfire/pwd.h>
#include <pakfire/repo.h>
#include <pakfire/scriptlet.h>
}
}
-static struct archive* pakfire_archive_open_payload(PakfireArchive archive, struct archive* a) {
+static struct archive* pakfire_archive_open_payload(PakfireArchive archive,
+ struct archive* a, size_t* size) {
// Find the payload
struct archive_entry* entry;
int r = find_archive_entry(&entry, a, PAKFIRE_ARCHIVE_FN_PAYLOAD);
if (r)
return NULL;
+ // Store size
+ if (size)
+ *size = archive_entry_size(entry);
+
// Allocate a new archive object
struct archive* payload = archive_read_new();
if (!payload)
if (r)
goto ERROR;
- payload = pakfire_archive_open_payload(archive, a);
+ payload = pakfire_archive_open_payload(archive, a, NULL);
if (!payload)
goto ERROR;
struct archive* writer;
const char* prefix;
PakfireFilelist filelist;
+ struct pakfire_progressbar* progressbar;
};
+static int pakfire_archive_extract_progressbar(
+ PakfireArchive archive, struct pakfire_progressbar** progressbar) {
+ char* name = pakfire_archive_get(archive, "package", "name");
+ char* arch = pakfire_archive_get(archive, "package", "arch");
+
+ char* e = pakfire_archive_get(archive, "package", "epoch");
+ char* v = pakfire_archive_get(archive, "package", "version");
+ char* r = pakfire_archive_get(archive, "package", "release");
+ char* evr = pakfire_package_join_evr(e, v, r);
+
+ int err = pakfire_progressbar_create(progressbar, NULL);
+ if (err)
+ goto ERROR;
+
+ // Add progressbar widgets
+ err = pakfire_progressbar_add_string(*progressbar, "%s-%s.%s", name, evr, arch);
+ if (err)
+ goto ERROR;
+
+ err = pakfire_progressbar_add_bar(*progressbar);
+ if (err)
+ goto ERROR;
+
+ err = pakfire_progressbar_add_percentage(*progressbar);
+ if (err)
+ goto ERROR;
+
+ // Success
+ err = 0;
+
+ERROR:
+ if (name)
+ free(name);
+ if (arch)
+ free(arch);
+ if (e)
+ free(e);
+ if (v)
+ free(v);
+ if (r)
+ free(r);
+ if (evr)
+ free(evr);
+
+ return err;
+}
+
static int pakfire_archive_extract_entry(PakfireArchive archive,
struct archive* a, struct archive_entry* entry, void* data) {
struct pakfire_archive_extractor* extractor = (struct pakfire_archive_extractor*)data;
char buffer[PATH_MAX];
int r = 1;
+ // How much of the archive has been read?
+ size_t bytes_read = archive_filter_bytes(a, -1);
+
+ // Update progress
+ if (extractor->progressbar)
+ pakfire_progressbar_update(extractor->progressbar, bytes_read);
+
// Create a new file object if there is a filelist
if (extractor->filelist) {
r = pakfire_file_create(&file, archive->pakfire);
}
PAKFIRE_EXPORT int pakfire_archive_extract(PakfireArchive archive, const char* prefix) {
+ struct pakfire_progressbar* progressbar = NULL;
struct archive* a = NULL;
struct archive* payload = NULL;
struct archive* writer = NULL;
+ size_t size;
int r;
// Use default path if nothing is set
goto ERROR;
}
+ // Create a progressbar
+ r = pakfire_archive_extract_progressbar(archive, &progressbar);
+ if (r)
+ goto ERROR;
+
// Open the archive
r = archive_open(archive, &a);
if (r)
goto ERROR;
// Open payload
- payload = pakfire_archive_open_payload(archive, a);
+ payload = pakfire_archive_open_payload(archive, a, &size);
if (!payload)
goto ERROR;
goto ERROR;
struct pakfire_archive_extractor extractor = {
- .writer = writer,
- .prefix = prefix,
- .filelist = archive->filelist,
+ .writer = writer,
+ .prefix = prefix,
+ .filelist = archive->filelist,
+ .progressbar = progressbar,
};
+ // Start the progressbar
+ r = pakfire_progressbar_start(progressbar, size);
+ if (r)
+ goto ERROR;
+
// Extract everything
r = pakfire_archive_walk_entries(archive, payload,
pakfire_archive_extract_entry, &extractor);
ERROR:
+ // Finish progressbar
+ if (progressbar)
+ pakfire_progressbar_finish(progressbar);
+
// Destroy the filelist on error
if (r) {
pakfire_filelist_unref(archive->filelist);
archive->filelist = NULL;
}
+ if (progressbar)
+ pakfire_progressbar_unref(progressbar);
if (writer)
archive_write_free(writer);
if (payload)