Py_RETURN_NONE;
}
+static PyObject* Pakfire_execute_script(PakfireObject* self, PyObject* args, PyObject* kwds) {
+ char* kwlist[] = {"script", "environ", "enable_network", "interactive",
+ "logging_callback", NULL};
+
+ const char* script = NULL;
+ PyObject* environ = NULL;
+ int enable_network = 0;
+ int interactive = 0;
+ PyObject* logging_callback = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|OppO", kwlist, &script, &environ,
+ &enable_network, &interactive, &logging_callback))
+ return NULL;
+
+ // Check if logging_callback is
+ if (logging_callback && !PyCallable_Check(logging_callback)) {
+ PyErr_SetString(PyExc_TypeError, "logging_callback must be callable\n");
+ return NULL;
+ }
+
+ ssize_t environ_length = 0;
+ PyObject* key;
+ PyObject* value;
+ Py_ssize_t p = 0;
+
+ if (environ) {
+ // Check if environ is a dictionary
+ if (!PyDict_Check(environ)) {
+ PyErr_SetString(PyExc_TypeError, "environ must be a dictionary");
+ return NULL;
+ }
+
+ // All keys and values must be strings
+ while (PyDict_Next(environ, &p, &key, &value)) {
+ if (!PyUnicode_Check(key) || !PyUnicode_Check(value)) {
+ PyErr_SetString(PyExc_TypeError, "Environment contains a non-string object");
+ return NULL;
+ }
+ }
+
+ environ_length = PyDict_Size(environ);
+ }
+
+ // All inputs look fine
+
+ char* envp[environ_length + 1];
+ int flags = 0;
+
+ // Parse environ
+ if (environ) {
+ unsigned int i = 0;
+ p = 0;
+
+ while (PyDict_Next(environ, &p, &key, &value)) {
+ int r = asprintf(&envp[i++], "%s=%s",
+ PyUnicode_AsUTF8(key), PyUnicode_AsUTF8(value));
+
+ // Handle errors
+ if (r < 0) {
+ // Cleanup
+ for (unsigned int i = 0; envp[i]; i++)
+ free(envp[i]);
+
+ return PyErr_NoMemory();
+ }
+ }
+ }
+
+ // Terminate envp
+ envp[environ_length] = NULL;
+
+ // Enable network?
+ if (enable_network)
+ flags |= PAKFIRE_EXECUTE_ENABLE_NETWORK;
+
+ // Interactive?
+ if (interactive)
+ flags |= PAKFIRE_EXECUTE_INTERACTIVE;
+
+ // Set logging callback
+ Pakfire_execute_logging_callback = logging_callback;
+
+ // Execute script
+ int r = pakfire_execute_script(self->pakfire, script, strlen(script), envp, flags,
+ (logging_callback) ? __Pakfire_execute_logging_callback : NULL);
+
+ // Cleanup
+ for (unsigned int i = 0; envp[i]; i++)
+ free(envp[i]);
+
+ // Raise an OS error if r < 0
+ if (r < 0) {
+ errno = -r;
+
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+
+ // Raise exception when the command failed
+ } else if (r > 0) {
+ PyObject* code = PyLong_FromLong(r);
+
+ PyErr_SetObject(PyExc_CommandExecutionError, code);
+ Py_DECREF(code);
+
+ return NULL;
+ }
+
+ // Return nothing
+ Py_RETURN_NONE;
+}
+
static PyObject* Pakfire_read_makefile(PakfireObject* self, PyObject* args) {
const char* path = NULL;
METH_VARARGS|METH_KEYWORDS,
NULL
},
+ {
+ "execute_script",
+ (PyCFunction)Pakfire_execute_script,
+ METH_VARARGS|METH_KEYWORDS,
+ NULL
+ },
{
"generate_key",
(PyCFunction)Pakfire_generate_key,