static void Pakfire_log_callback(void* data, int priority, const char* file, int line,
const char* fn, const char* format, va_list args) {
- struct callbacks* callbacks = (struct callbacks*)data;
+ PyObject* callback = (PyObject*)data;
// Do nothing if callback isn't set
- if (!callbacks->log)
+ if (!callback)
return;
// Translate priority to Python logging priorities
goto ERROR;
// Call the callback
- result = PyObject_CallObject(callbacks->log, tuple);
+ result = PyObject_CallObject(callback, tuple);
ERROR:
if (buffer)
}
static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
- char* kwlist[] = { "path", "arch", "logger", "interactive", "offline", "conf", "build",
- "enable_ccache", "enable_snapshot", "status_callback", "progress_callback", NULL };
+ char* kwlist[] = {
+ "path",
+ "arch",
+ "logger",
+ "interactive",
+ "offline",
+ "conf",
+ "build",
+ "enable_ccache",
+ "enable_snapshot",
+ NULL,
+ };
const char* path = NULL;
const char* arch = NULL;
const char* conf = NULL;
int enable_ccache = 1;
int enable_snapshot = 1;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOppzpppOO", kwlist,
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOppzppp", kwlist,
&path, &arch, &self->callbacks.log, &interactive, &offline, &conf, &build,
- &enable_ccache, &enable_snapshot, &self->callbacks.status,
- &self->callbacks.progress))
+ &enable_ccache, &enable_snapshot))
return -1;
// Check if log callback is callable
return -1;
}
- // Check if status callback is callable
- if (self->callbacks.status && !PyCallable_Check(self->callbacks.status)) {
- PyErr_SetString(PyExc_TypeError, "status callback must be callable\n");
- return -1;
- }
-
- // Check if progress callback is callable
- if (self->callbacks.progress && !PyCallable_Check(self->callbacks.progress)) {
- PyErr_SetString(PyExc_TypeError, "progress callback must be callable\n");
- return -1;
- }
-
int flags = 0;
// Enable interactive mode
}
// Configure callbacks
- struct pakfire_callbacks callbacks = {
- .data = &self->callbacks,
- };
-
- if (self->callbacks.log) {
- callbacks.log = Pakfire_log_callback;
+ if (self->callbacks.log)
Py_INCREF(self->callbacks.log);
- }
-
- if (self->callbacks.status) {
- callbacks.status = Pakfire_status_callback;
- Py_INCREF(self->callbacks.status);
- }
-
- if (self->callbacks.progress) {
- callbacks.progress = Pakfire_progress_callback;
- Py_INCREF(self->callbacks.progress);
- }
// Create a new Pakfire instance
- int r = pakfire_create(&self->pakfire, path, arch, conf, flags, &callbacks);
+ int r = pakfire_create(&self->pakfire, path, arch, conf, flags,
+ Pakfire_log_callback, self->callbacks.log);
if (r) {
switch (errno) {
// Invalid architecture or path
static void Pakfire_dealloc(PakfireObject* self) {
if (self->pakfire) {
- // Drop references to all callbacks
- pakfire_reset_all_callbacks(self->pakfire);
+ // Reset log callback
+ pakfire_set_log_callback(self->pakfire, NULL, NULL);
pakfire_unref(self->pakfire);
}
};
// 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, int progress);
- void (*speed)(void* data, const char* speed);
-};
+typedef void (*pakfire_log_callback)(void* data, int priority, const char* file,
+ int line, const char* fn, const char* format, va_list args);
+void pakfire_set_log_callback(struct pakfire* pakfire,
+ pakfire_log_callback callback, void* data);
int pakfire_create(struct pakfire** pakfire, const char* path, const char* arch,
- const char* conf, int flags, const struct pakfire_callbacks* callbacks);
+ const char* conf, int flags, pakfire_log_callback log_callback, void* log_data);
struct pakfire* pakfire_ref(struct pakfire* pakfire);
struct pakfire* pakfire_unref(struct pakfire* pakfire);
-void pakfire_reset_all_callbacks(struct pakfire* pakfire);
const char* pakfire_get_path(struct pakfire* pakfire);
pakfire_list_keys;
pakfire_ref;
pakfire_refresh;
- pakfire_reset_all_callbacks;
pakfire_search;
+ pakfire_set_log_callback;
pakfire_sync;
pakfire_unref;
pakfire_update;
Pool* pool;
// Callbacks
- struct pakfire_callbacks callbacks;
+ struct pakfire_callbacks {
+ // Logging
+ pakfire_log_callback log;
+ void* log_data;
+
+ // Status
+ void (*status)(void* data, const char* message);
+ void* status_data;
+
+ // Progress
+ void (*progress)(void* data, int progress);
+ void* progress_data;
+
+ // Speed
+ void (*speed)(void* data, const char* speed);
+ void* speed_data;
+ } callbacks;
// Logging
int log_priority;
PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path,
const char* arch, const char* conf, int flags,
- const struct pakfire_callbacks* callbacks) {
+ pakfire_log_callback log_callback, void* log_data) {
char tempdir[PATH_MAX] = PAKFIRE_TMP_DIR "/XXXXXX";
int r = 1;
p->nrefs = 1;
p->flags = flags;
- // Initialize callbacks
- pakfire_reset_all_callbacks(p);
-
- // Copy callbacks
- if (callbacks) {
- if (callbacks->data)
- p->callbacks.data = callbacks->data;
-
- if (callbacks->log)
- p->callbacks.log = callbacks->log;
-
- if (callbacks->status)
- p->callbacks.status = callbacks->status;
-
- if (callbacks->progress)
- p->callbacks.progress = callbacks->progress;
- }
-
// Set architecture
pakfire_string_set(p->arch, arch);
// Setup logging
+ if (log_callback)
+ pakfire_set_log_callback(p, log_callback, log_data);
+ else
+ pakfire_set_log_callback(p, pakfire_log_syslog, NULL);
+
const char* env = secure_getenv("PAKFIRE_LOG");
if (env)
pakfire_log_set_priority(p, log_priority(env));
return NULL;
}
-/*
- Drops all callbacks.
-
- This is useful when Pakfire is being called from Python and we cannot
- determine the order when things are being freed.
-*/
-PAKFIRE_EXPORT void pakfire_reset_all_callbacks(struct pakfire* pakfire) {
- pakfire->callbacks.data = NULL;
-
- // Reset callbacks
- pakfire->callbacks.status = NULL;
- pakfire->callbacks.progress = NULL;
- pakfire->callbacks.speed = NULL;
-
- // Log to syslog by default
- pakfire->callbacks.log = pakfire_log_syslog;
-}
-
int pakfire_has_flag(struct pakfire* pakfire, int flag) {
return pakfire->flags & flag;
}
return;
// Call the callback
- pakfire->callbacks.status(pakfire->callbacks.data, buffer);
+ pakfire->callbacks.status(pakfire->callbacks.status_data, buffer);
// Cleanup
if (buffer)
if (!pakfire->callbacks.progress)
return;
- pakfire->callbacks.progress(pakfire->callbacks.data, progress);
+ pakfire->callbacks.progress(pakfire->callbacks.progress_data, progress);
}
const char* pakfire_get_keystore_path(struct pakfire* pakfire) {
return 0;
}
+// Logging
+
PAKFIRE_EXPORT int pakfire_log_get_priority(struct pakfire* pakfire) {
return pakfire->log_priority;
}
pakfire->log_priority = priority;
}
+PAKFIRE_EXPORT void pakfire_set_log_callback(struct pakfire* pakfire,
+ pakfire_log_callback callback, void* data) {
+ pakfire->callbacks.log = callback;
+ pakfire->callbacks.log_data = data;
+}
+
void pakfire_log(struct pakfire* pakfire, int priority, const char* file, int line,
const char* fn, const char* format, ...) {
va_list args;
int saved_errno = errno;
va_start(args, format);
- pakfire->callbacks.log(pakfire->callbacks.data, priority, file, line, fn, format, args);
+ pakfire->callbacks.log(pakfire->callbacks.log_data,
+ priority, file, line, fn, format, args);
va_end(args);
// Restore errno