]> git.ipfire.org Git - pakfire.git/commitdiff
pakfire: Introduce callbacks
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 9 Dec 2021 10:51:52 +0000 (10:51 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 9 Dec 2021 10:51:52 +0000 (10:51 +0000)
These can be used to inform any calling applications about the status
of Pakfire.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/pakfire.c
src/libpakfire/include/pakfire/pakfire.h
src/libpakfire/pakfire.c
tests/testsuite.c

index c6c2419ad834c000cecfd631a36fdf16bf86fc37..1cdf5a963dde763153dc7839854e957941197bd9 100644 (file)
@@ -144,9 +144,14 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
                        flags |= PAKFIRE_FLAGS_DISABLE_SNAPSHOT;
        }
 
+       // Configure callbacks
+       struct pakfire_callbacks callbacks = {
+               .data = logger,
+               .log  = (logger) ? Pakfire_logging_callback : NULL,
+       };
+
        // Create a new Pakfire instance
-       int r = pakfire_create(&self->pakfire, path, arch, conf, flags,
-                       (logger) ? Pakfire_logging_callback : NULL, logger);
+       int r = pakfire_create(&self->pakfire, path, arch, conf, flags, &callbacks);
        if (r) {
                switch (errno) {
                        // Invalid architecture or path
index 4b941cfb2fb84a275e503a409852e3170ba769c6..376a2558a16712718b30bfd50b6bca54437c0874 100644 (file)
@@ -51,11 +51,23 @@ enum pakfire_flags {
        PAKFIRE_FLAGS_DISABLE_RAMDISK   = (1 << 5),
 };
 
-typedef void (*pakfire_log_function_t)(void* data, int priority, const char* file,
+// Callbacks
+
+struct pakfire_callbacks {
+       void* data;
+
+       // Logging
+       void (*log)(void* data, int priority, const char* file,
                int line, const char* fn, const char* format, va_list args);
 
+       // Status, Progress & Speed
+       void (*status)(void* data, const char* message);
+       void (*progress)(void* data, double progress);
+       void (*speed)(void* data, const char* speed);
+};
+
 int pakfire_create(struct pakfire** pakfire, const char* path, const char* arch,
-       const char* conf, int flags, pakfire_log_function_t log, void* data);
+       const char* conf, int flags, const struct pakfire_callbacks* callbacks);
 
 struct pakfire* pakfire_ref(struct pakfire* pakfire);
 struct pakfire* pakfire_unref(struct pakfire* pakfire);
@@ -133,6 +145,9 @@ int pakfire_has_flag(struct pakfire* pakfire, int flag);
 struct pakfire_config* pakfire_get_config(struct pakfire* pakfire);
 int pakfire_is_mountpoint(struct pakfire* pakfire, const char* path);
 
+void pakfire_call_status_callback(struct pakfire* pakfire, const char* message, ...);
+void pakfire_call_progress_callback(struct pakfire* pakfire, double progress);
+
 gpgme_ctx_t pakfire_get_gpgctx(struct pakfire* pakfire);
 
 const char* pakfire_get_distro_name(struct pakfire* pakfire);
index 09c822cc64d12c5d53fdb82c2bff87a274071bb7..a9da59fe8ef61fa1f7e4f9ff0ce4b3ba59bbf81e 100644 (file)
@@ -70,6 +70,8 @@ struct mountpoint {
 };
 
 struct pakfire {
+       int nrefs;
+
        char path[PATH_MAX];
        char cache_path[PATH_MAX];
        char arch[ARCH_MAX];
@@ -80,13 +82,12 @@ struct pakfire {
        // Pool
        Pool* pool;
 
+       // Callbacks
+       struct pakfire_callbacks callbacks;
+
        // Logging
-       pakfire_log_function_t log_function;
-       void* log_data;
        int log_priority;
 
-       int nrefs;
-
        struct pakfire_config* config;
 
        STAILQ_HEAD(mountpoints, mountpoint) mountpoints;
@@ -355,12 +356,6 @@ static int pakfire_populate_dev(struct pakfire* pakfire) {
        return 0;
 }
 
-static void pakfire_log_set_function(struct pakfire* pakfire,
-               pakfire_log_function_t log_function, void* data) {
-       pakfire->log_function = log_function;
-       pakfire->log_data = data;
-}
-
 static int log_priority(const char* priority) {
        char* end;
 
@@ -837,8 +832,8 @@ ERROR:
 }
 
 PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path,
-               const char* arch, const char* conf, int flags, pakfire_log_function_t log,
-               void* data) {
+               const char* arch, const char* conf, int flags,
+               const struct pakfire_callbacks* callbacks) {
        char tempdir[PATH_MAX] = PAKFIRE_TMP_DIR "/XXXXXX";
        int r = 1;
 
@@ -875,15 +870,20 @@ PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path,
        p->nrefs = 1;
        p->flags = flags;
 
+       // Copy callbacks
+       if (callbacks) {
+               memcpy(&p->callbacks, callbacks, sizeof(p->callbacks));
+
+       // Set default callbacks
+       } else {
+               // Log to syslog by default
+               p->callbacks.log = pakfire_log_syslog;
+       }
+
        // Set architecture
        pakfire_string_set(p->arch, arch);
 
        // Setup logging
-       if (log)
-               pakfire_log_set_function(p, log, data);
-       else
-               pakfire_log_set_function(p, pakfire_log_syslog, NULL);
-
        const char* env = secure_getenv("PAKFIRE_LOG");
        if (env)
                pakfire_log_set_priority(p, log_priority(env));
@@ -1055,6 +1055,31 @@ PAKFIRE_EXPORT const char* pakfire_get_path(struct pakfire* pakfire) {
        return pakfire->path;
 }
 
+void pakfire_call_status_callback(struct pakfire* pakfire, const char* message, ...) {
+       char* buffer = NULL;
+       va_list args;
+       int r;
+
+       // Format the message
+       va_start(args, message);
+       r = vasprintf(&buffer, message, args);
+       va_end(args);
+
+       if (r < 0)
+               return;
+
+       // Call the callback
+       pakfire->callbacks.status(pakfire->callbacks.data, buffer);
+
+       // Cleanup
+       if (buffer)
+               free(buffer);
+}
+
+void pakfire_call_progress_callback(struct pakfire* pakfire, double progress) {
+       pakfire->callbacks.progress(pakfire->callbacks.data, progress);
+}
+
 const char* pakfire_get_keystore_path(struct pakfire* pakfire) {
        return pakfire->keystore_path;
 }
@@ -1578,7 +1603,7 @@ void pakfire_log(struct pakfire* pakfire, int priority, const char* file, int li
        int saved_errno = errno;
 
        va_start(args, format);
-       pakfire->log_function(pakfire->log_data, priority, file, line, fn, format, args);
+       pakfire->callbacks.log(pakfire->callbacks.data, priority, file, line, fn, format, args);
        va_end(args);
 
        // Restore errno
index cb9b395ce246d7d13da83b99e138b022b21dda6b..708d215f342d6597f07071fb6ef420d02c181246 100644 (file)
@@ -36,6 +36,10 @@ static int test_run(int i, struct test* t) {
        char root[PATH_MAX];
        int r;
 
+       struct pakfire_callbacks callbacks = {
+               .log = pakfire_log_stderr,
+       };
+
        // Create test root directory
        snprintf(root, PATH_MAX - 1, "%s/pakfire-test-XXXXXX", TEST_ROOTFS);
        char* tmp = pakfire_mkdtemp(root);
@@ -47,8 +51,8 @@ static int test_run(int i, struct test* t) {
        LOG("running %s (%s)\n", t->name, root);
 
        // Create a pakfire instance
-       r = pakfire_create(&t->pakfire, root, NULL, TEST_SRC_PATH "/pakfire.conf", 0,
-               pakfire_log_stderr, NULL);
+       r = pakfire_create(&t->pakfire, root, NULL, TEST_SRC_PATH "/pakfire.conf",
+               0, &callbacks);
        if (r) {
                LOG("ERROR: Could not initialize pakfire: %m\n");
                exit(1);