1 /*#############################################################################
3 # Pakfire - The IPFire package management system #
4 # Copyright (C) 2017 Pakfire development team #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 #############################################################################*/
21 #define PY_SSIZE_T_CLEAN
25 #include <pakfire/archive.h>
26 #include <pakfire/build.h>
27 #include <pakfire/constants.h>
28 #include <pakfire/dist.h>
29 #include <pakfire/jail.h>
30 #include <pakfire/logging.h>
31 #include <pakfire/mount.h>
32 #include <pakfire/packagelist.h>
33 #include <pakfire/pakfire.h>
34 #include <pakfire/key.h>
35 #include <pakfire/repo.h>
36 #include <pakfire/repolist.h>
37 #include <pakfire/request.h>
38 #include <pakfire/util.h>
47 static PyObject
* Pakfire_new(PyTypeObject
* type
, PyObject
* args
, PyObject
* kwds
) {
48 PakfireObject
* self
= (PakfireObject
*)type
->tp_alloc(type
, 0);
53 self
->callbacks
.log
= NULL
;
54 self
->callbacks
.confirm
= NULL
;
57 return (PyObject
*)self
;
60 static void Pakfire_log_callback(void* data
, int priority
, const char* file
, int line
,
61 const char* fn
, const char* format
, va_list args
) {
62 PyObject
* callback
= (PyObject
*)data
;
64 // Do nothing if callback isn't set
68 // Translate priority to Python logging priorities
82 // Drop messages of an unknown priority
87 PyObject
* tuple
= NULL
;
88 PyObject
* result
= NULL
;
92 int r
= vasprintf(&buffer
, format
, args
);
96 // Build a tuple with the priority and the log message
97 tuple
= Py_BuildValue("(is)", priority
, buffer
);
102 result
= PyObject_CallObject(callback
, tuple
);
111 static int Pakfire_confirm_callback(struct pakfire
* pakfire
, void* data
,
112 const char* message
, const char* question
) {
113 PyObject
* callback
= (PyObject
*)data
;
116 // Do nothing if callback isn't set
120 PyObject
* args
= Py_BuildValue("(ss)", message
, question
);
124 PyObject
* result
= PyObject_CallObject(callback
, args
);
126 // Extract return code
127 if (PyLong_Check(result
))
128 r
= PyLong_AsLong(result
);
136 static int Pakfire_init(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
150 const char* path
= NULL
;
151 const char* arch
= NULL
;
152 const char* conf
= NULL
;
156 int disable_ccache
= 1;
157 int disable_snapshot
= 1;
159 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "|zzOppzpppO", kwlist
,
160 &path
, &arch
, &self
->callbacks
.log
, &interactive
, &offline
, &conf
, &build
,
161 &disable_ccache
, &disable_snapshot
, &self
->callbacks
.confirm
))
164 // Check if log callback is callable
165 if (self
->callbacks
.log
&& !PyCallable_Check(self
->callbacks
.log
)) {
166 PyErr_SetString(PyExc_TypeError
, "logger must be callable\n");
170 // Check if confirm callback is callable
171 if (self
->callbacks
.confirm
&& !PyCallable_Check(self
->callbacks
.confirm
)) {
172 PyErr_SetString(PyExc_TypeError
, "Confirm callback is not callable");
178 // Enable interactive mode
180 flags
|= PAKFIRE_FLAGS_INTERACTIVE
;
182 // Enable offline mode
184 flags
|= PAKFIRE_FLAGS_OFFLINE
;
188 flags
|= PAKFIRE_FLAGS_BUILD
;
191 flags
|= PAKFIRE_FLAGS_DISABLE_CCACHE
;
193 if (disable_snapshot
)
194 flags
|= PAKFIRE_FLAGS_DISABLE_SNAPSHOT
;
197 // Configure callbacks
198 if (self
->callbacks
.log
)
199 Py_INCREF(self
->callbacks
.log
);
201 // Create a new Pakfire instance
202 int r
= pakfire_create(&self
->pakfire
, path
, arch
, conf
, flags
,
203 LOG_DEBUG
, Pakfire_log_callback
, self
->callbacks
.log
);
206 // Invalid architecture or path
208 PyErr_SetString(PyExc_ValueError
, "Invalid architecture or path");
213 PyErr_SetFromErrno(PyExc_OSError
);
219 // Configure confirm callback
220 if (self
->callbacks
.confirm
) {
221 pakfire_set_confirm_callback(self
->pakfire
,
222 Pakfire_confirm_callback
, self
->callbacks
.confirm
);
224 Py_INCREF(self
->callbacks
.confirm
);
230 static void Pakfire_dealloc(PakfireObject
* self
) {
232 // Reset log callback
233 if (self
->callbacks
.log
) {
234 pakfire_set_log_callback(self
->pakfire
, NULL
, NULL
);
235 Py_DECREF(self
->callbacks
.log
);
238 // Reset confirm callback
239 if (self
->callbacks
.confirm
) {
240 pakfire_set_confirm_callback(self
->pakfire
, NULL
, NULL
);
241 Py_DECREF(self
->callbacks
.confirm
);
244 pakfire_unref(self
->pakfire
);
247 Py_TYPE(self
)->tp_free((PyObject
*)self
);
250 static PyObject
* Pakfire_repr(PakfireObject
* self
) {
251 const char* path
= pakfire_get_path(self
->pakfire
);
252 const char* arch
= pakfire_get_arch(self
->pakfire
);
254 return PyUnicode_FromFormat("<_pakfire.Pakfire %s (%s)>", path
, arch
);
257 static PyObject
* Pakfire_get_path(PakfireObject
* self
) {
258 const char* path
= pakfire_get_path(self
->pakfire
);
260 return PyUnicode_FromString(path
);
263 static PyObject
* Pakfire_get_arch(PakfireObject
* self
) {
264 const char* arch
= pakfire_get_arch(self
->pakfire
);
266 return PyUnicode_FromString(arch
);
269 static PyObject
* Pakfire_get_repo(PakfireObject
* self
, PyObject
* args
) {
270 const char* name
= NULL
;
272 if (!PyArg_ParseTuple(args
, "s", &name
))
275 struct pakfire_repo
* repo
= pakfire_get_repo(self
->pakfire
, name
);
279 PyObject
* obj
= new_repo(&RepoType
, repo
);
280 pakfire_repo_unref(repo
);
285 static void Pakfire_status_callback(struct pakfire
* pakfire
, void* data
,
286 int progress
, const char* status
) {
287 PyObject
* callback
= (PyObject
*)data
;
289 // Do not attempt to call nothing
294 PyObject
* args
= Py_BuildValue("(is)", progress
, status
);
299 PyObject
* result
= PyObject_CallObject(callback
, args
);
305 static int convert_packages(PyObject
* object
, void* address
) {
306 char*** packages
= (char***)address
;
308 // Called for cleanup
312 // Nothing to do when object is None
313 if (object
== Py_None
)
314 return Py_CLEANUP_SUPPORTED
;
316 if (!PySequence_Check(object
)) {
317 PyErr_SetString(PyExc_ValueError
, "Packages must be a sequence");
321 const unsigned int length
= PySequence_Length(object
);
323 return Py_CLEANUP_SUPPORTED
;
326 *packages
= calloc(length
+ 1, sizeof(*packages
));
328 PyErr_SetFromErrno(PyExc_OSError
);
332 for (unsigned int i
= 0; i
< length
; i
++) {
333 PyObject
* item
= PySequence_GetItem(object
, i
);
335 // Check if input is a string
336 if (!PyUnicode_Check(item
)) {
339 PyErr_SetString(PyExc_AttributeError
, "Expected a string");
344 const char* package
= PyUnicode_AsUTF8(item
);
350 // Add package to array
351 (*packages
)[i
] = strdup(package
);
352 if (!(*packages
)[i
]) {
361 return Py_CLEANUP_SUPPORTED
;
365 for (char** package
= *packages
; *package
; package
++)
373 static PyObject
* Pakfire_install(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
377 "without_recommended",
383 char** packages
= NULL
;
385 int without_recommended
= 0;
386 int allow_uninstall
= 0;
387 int allow_downgrade
= 0;
388 int solver_flags
= 0;
389 int transaction_flags
= 0;
390 PyObject
* status_callback
= NULL
;
392 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O&|$ppppO", kwlist
,
393 convert_packages
, &packages
, &dryrun
, &without_recommended
, &allow_uninstall
,
394 &allow_downgrade
, &status_callback
))
397 // Check if callback is callable
398 if (status_callback
&& !PyCallable_Check(status_callback
)) {
399 PyErr_SetString(PyExc_TypeError
, "status_callback must be callable");
403 // Enable dry-run mode
405 transaction_flags
|= PAKFIRE_TRANSACTION_DRY_RUN
;
407 // Do not install recommended packages
408 if (without_recommended
)
409 solver_flags
|= PAKFIRE_REQUEST_WITHOUT_RECOMMENDED
;
411 // Can the solver uninstall packages?
413 solver_flags
|= PAKFIRE_REQUEST_ALLOW_UNINSTALL
;
415 // Can the solver downgrade packages?
417 solver_flags
|= PAKFIRE_REQUEST_ALLOW_DOWNGRADE
;
419 // Run pakfire_install
420 int r
= pakfire_install(self
->pakfire
, transaction_flags
, solver_flags
,
421 (const char**)packages
, NULL
, 0, NULL
, Pakfire_status_callback
, status_callback
);
423 PyErr_SetFromErrno(PyExc_OSError
);
426 for (char** package
= packages
; *package
; package
++)
437 static PyObject
* Pakfire_erase(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
445 char** packages
= NULL
;
447 int keep_dependencies
= 0;
448 int transaction_flags
= 0;
450 PyObject
* status_callback
= NULL
;
452 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O&|$ppO", kwlist
,
453 convert_packages
, &packages
, &dryrun
, &keep_dependencies
, &status_callback
))
456 // Check if callback is callable
457 if (status_callback
&& !PyCallable_Check(status_callback
)) {
458 PyErr_SetString(PyExc_TypeError
, "status_callback must be callable");
463 transaction_flags
|= PAKFIRE_TRANSACTION_DRY_RUN
;
465 if (keep_dependencies
)
466 flags
|= PAKFIRE_REQUEST_KEEP_DEPS
;
469 int r
= pakfire_erase(self
->pakfire
, transaction_flags
, 0, (const char**)packages
,
470 NULL
, flags
, NULL
, Pakfire_status_callback
, status_callback
);
472 PyErr_SetFromErrno(PyExc_OSError
);
475 for (char** package
= packages
; *package
; package
++)
486 static PyObject
* Pakfire_update(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
496 char** packages
= NULL
;
497 char** excludes
= NULL
;
499 int allow_uninstall
= 0;
500 int allow_downgrade
= 0;
501 int solver_flags
= 0;
502 int transaction_flags
= 0;
503 PyObject
* status_callback
= NULL
;
505 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O&|$O&ppO", kwlist
,
506 convert_packages
, &packages
, convert_packages
, &excludes
,
507 &allow_uninstall
, &allow_downgrade
, &status_callback
))
510 // Check if callback is callable
511 if (status_callback
&& !PyCallable_Check(status_callback
)) {
512 PyErr_SetString(PyExc_TypeError
, "status_callback must be callable");
517 transaction_flags
= PAKFIRE_TRANSACTION_DRY_RUN
;
519 // Can the solver uninstall packages?
521 solver_flags
|= PAKFIRE_REQUEST_ALLOW_UNINSTALL
;
523 // Can the solver downgrade packages?
525 solver_flags
|= PAKFIRE_REQUEST_ALLOW_DOWNGRADE
;
527 // Run pakfire_update
528 int r
= pakfire_update(self
->pakfire
, transaction_flags
, solver_flags
,
529 (const char**)packages
, (const char**)excludes
, 0, NULL
,
530 Pakfire_status_callback
, status_callback
);
532 PyErr_SetFromErrno(PyExc_OSError
);
535 for (char** package
= packages
; *package
; package
++)
541 for (char** exclude
= excludes
; *exclude
; exclude
++)
552 static PyObject
* Pakfire_keys_to_list(struct pakfire_key
** keys
) {
553 PyObject
* list
= PyList_New(0);
559 // Push all keys onto the list
560 for (struct pakfire_key
** key
= keys
; *key
; key
++) {
561 PyObject
* object
= new_key(&KeyType
, *key
);
565 PyList_Append(list
, object
);
576 static PyObject
* Pakfire_get_keys(PakfireObject
* self
) {
577 struct pakfire_key
** keys
= NULL
;
579 int r
= pakfire_list_keys(self
->pakfire
, &keys
);
581 PyErr_SetFromErrno(PyExc_OSError
);
585 // Convert keys to list
586 PyObject
* list
= Pakfire_keys_to_list(keys
);
590 for (struct pakfire_key
** key
= keys
; *key
; key
++)
591 pakfire_key_unref(*key
);
598 static PyObject
* Pakfire_get_key(PakfireObject
* self
, PyObject
* args
) {
599 const char* pattern
= NULL
;
601 if (!PyArg_ParseTuple(args
, "s", &pattern
))
604 // Try finding the key
605 struct pakfire_key
* key
= pakfire_key_get(self
->pakfire
, pattern
);
609 PyObject
* object
= new_key(&KeyType
, key
);
610 pakfire_key_unref(key
);
615 static PyObject
* Pakfire_generate_key(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
616 char* kwlist
[] = { "userid", "algorithm", NULL
};
617 struct pakfire_key
* key
= NULL
;
618 const char* userid
= NULL
;
619 const char* algo
= NULL
;
621 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s|$z", kwlist
, &userid
, &algo
))
624 // Generate a new key
625 int r
= pakfire_key_generate(&key
, self
->pakfire
, algo
, userid
);
627 PyErr_SetFromErrno(PyExc_OSError
);
631 PyObject
* object
= new_key(&KeyType
, key
);
632 pakfire_key_unref(key
);
637 static PyObject
* Pakfire_import_key(PakfireObject
* self
, PyObject
* args
) {
638 PyObject
* object
= NULL
;
640 if (!PyArg_ParseTuple(args
, "O", &object
))
643 // Get a file descriptor from object
644 int fd
= PyObject_AsFileDescriptor(object
);
649 FILE* f
= fdopen(fd
, "r");
651 PyErr_SetFromErrno(PyExc_OSError
);
655 struct pakfire_key
** keys
= NULL
;
657 // Import keys from f
658 int r
= pakfire_key_import(self
->pakfire
, f
, &keys
);
660 PyErr_SetFromErrno(PyExc_OSError
);
664 // Convert keys to list
665 PyObject
* list
= Pakfire_keys_to_list(keys
);
668 for (struct pakfire_key
** key
= keys
; *key
; key
++)
669 pakfire_key_unref(*key
);
675 static PyObject
* Pakfire_fetch_key(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
676 char* kwlist
[] = { "userid", "fingerprint", NULL
};
677 struct pakfire_key
* key
= NULL
;
678 const char* userid
= NULL
;
679 const char* fingerprint
= NULL
;
681 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "|$zz", kwlist
, &userid
, &fingerprint
))
685 int r
= pakfire_key_fetch(&key
, self
->pakfire
, userid
, fingerprint
);
687 PyErr_SetFromErrno(PyExc_OSError
);
693 PyObject
* object
= new_key(&KeyType
, key
);
694 pakfire_key_unref(key
);
702 static PyObject
* Pakfire_whatprovides(PakfireObject
* self
, PyObject
* args
) {
703 const char* provides
= NULL
;
704 struct pakfire_packagelist
* list
= NULL
;
706 if (!PyArg_ParseTuple(args
, "s", &provides
))
709 int r
= pakfire_whatprovides(self
->pakfire
, provides
, 0, &list
);
711 PyErr_SetFromErrno(PyExc_OSError
);
715 PyObject
* obj
= PyList_FromPackageList(list
);
716 pakfire_packagelist_unref(list
);
721 static PyObject
* Pakfire_whatrequires(PakfireObject
* self
, PyObject
* args
) {
722 const char* requires
= NULL
;
723 struct pakfire_packagelist
* list
= NULL
;
725 if (!PyArg_ParseTuple(args
, "s", &requires
))
728 int r
= pakfire_whatrequires(self
->pakfire
, requires
, 0, &list
);
730 PyErr_SetFromErrno(PyExc_OSError
);
734 PyObject
* obj
= PyList_FromPackageList(list
);
735 pakfire_packagelist_unref(list
);
740 static PyObject
* Pakfire_search(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
741 char* kwlist
[] = { "pattern", "name_only", NULL
};
742 struct pakfire_packagelist
* list
= NULL
;
743 const char* pattern
= NULL
;
747 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s|$p", kwlist
, &pattern
, &name_only
))
750 // Search for package names only
752 flags
|= PAKFIRE_SEARCH_NAME_ONLY
;
754 int r
= pakfire_search(self
->pakfire
, pattern
, flags
, &list
);
756 PyErr_SetFromErrno(PyExc_OSError
);
760 PyObject
* obj
= PyList_FromPackageList(list
);
761 pakfire_packagelist_unref(list
);
766 static PyObject
* Pakfire_version_compare(PakfireObject
* self
, PyObject
* args
) {
767 const char* evr1
= NULL
;
768 const char* evr2
= NULL
;
770 if (!PyArg_ParseTuple(args
, "ss", &evr1
, &evr2
))
773 int cmp
= pakfire_version_compare(self
->pakfire
, evr1
, evr2
);
775 return PyLong_FromLong(cmp
);
778 static int __Pakfire_logging_callback(struct pakfire
* pakfire
, void* data
,
779 int priority
, const char* line
, size_t length
) {
780 PyObject
* callback
= (PyObject
*)data
;
783 // Do nothing if callback isn't set
787 // Translate priority to Python logging priorities
798 // Remove the trailing newline
799 if (line
&& line
[length
- 1] == '\n')
802 // Create tuple with arguments for the callback function
803 PyObject
* args
= Py_BuildValue("(is#)", priority
, line
, (Py_ssize_t
)length
);
807 PyObject
* result
= PyObject_CallObject(callback
, args
);
808 if (result
&& PyLong_Check(result
)) {
809 r
= PyLong_AsLong(result
);
818 static PyObject
* Pakfire_execute(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
829 struct pakfire_jail
* jail
= NULL
;
830 const char** argv
= NULL
;
833 PyObject
* ret
= NULL
;
836 PyObject
* command
= NULL
;
837 PyObject
* environ
= NULL
;
839 PyObject
* logging_callback
= NULL
;
841 int return_output
= 0;
843 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "O|OpOip", kwlist
, &command
, &environ
,
844 &interactive
, &logging_callback
, &nice
, &return_output
))
847 // Check if command is a list
848 if (!PyList_Check(command
)) {
849 PyErr_SetString(PyExc_TypeError
, "command must be a list");
853 const ssize_t command_length
= PyList_Size(command
);
855 // Check if command is not empty
856 if (command_length
== 0) {
857 PyErr_SetString(PyExc_ValueError
, "command is empty");
862 argv
= calloc(command_length
+ 1, sizeof(*argv
));
866 // All arguments in command must be strings
867 for (unsigned int i
= 0; i
< command_length
; i
++) {
868 PyObject
* item
= PyList_GET_ITEM(command
, i
);
870 if (!PyUnicode_Check(item
)) {
871 PyErr_Format(PyExc_TypeError
, "Item %u in command is not a string", i
);
876 argv
[i
] = PyUnicode_AsUTF8(item
);
881 flags
|= PAKFIRE_JAIL_INTERACTIVE
;
884 r
= pakfire_jail_create(&jail
, self
->pakfire
, flags
);
886 PyErr_SetFromErrno(PyExc_OSError
);
890 // Set logging callback
891 if (logging_callback
) {
892 if (!PyCallable_Check(logging_callback
)) {
893 PyErr_SetString(PyExc_TypeError
, "logging_callback must be callable\n");
897 pakfire_jail_set_log_callback(jail
, __Pakfire_logging_callback
, logging_callback
);
902 r
= pakfire_jail_nice(jail
, nice
);
904 PyErr_SetFromErrno(PyExc_OSError
);
909 PyObject
* key
= NULL
;
910 PyObject
* value
= NULL
;
913 // Parse the environment
915 // Check if environ is a dictionary
916 if (!PyDict_Check(environ
)) {
917 PyErr_SetString(PyExc_TypeError
, "environ must be a dictionary");
921 // All keys and values must be strings
922 while (PyDict_Next(environ
, &p
, &key
, &value
)) {
923 if (!PyUnicode_Check(key
) || !PyUnicode_Check(value
)) {
924 PyErr_SetString(PyExc_TypeError
, "Environment contains a non-string object");
928 // Set environment value
929 r
= pakfire_jail_set_env(jail
, PyUnicode_AsUTF8(key
), PyUnicode_AsUTF8(value
));
931 PyErr_SetFromErrno(PyExc_OSError
);
938 r
= pakfire_jail_exec(jail
, argv
, (return_output
) ? &output
: NULL
);
940 // If the return code was negative, we had some internal error
942 PyErr_SetFromErrno(PyExc_OSError
);
945 // Otherwise the executed command returned some error code
947 PyObject
* code
= PyLong_FromLong(r
);
949 // Raise CommandExecutionError
950 PyErr_SetObject(PyExc_CommandExecutionError
, code
);
956 // The process has exited successfully
958 // Did the user request the output?
960 // Return the buffer as bytes
961 ret
= PyBytes_FromString(output
);
963 // Otherwise just return None
976 // Dereference the logging callback
977 // It might happen that the jail is not being freed because something else is
978 // holding a reference to it. We will however lose the reference to the logging
979 // function here which is why we reset it.
980 pakfire_jail_set_log_callback(jail
, NULL
, NULL
);
982 pakfire_jail_unref(jail
);
988 static PyObject
* Pakfire_dist(PakfireObject
* self
, PyObject
* args
) {
989 const char* path
= NULL
;
990 const char* target
= NULL
;
993 if (!PyArg_ParseTuple(args
, "s|z", &path
, &target
))
996 int r
= pakfire_dist(self
->pakfire
, path
, target
, &result
);
998 PyErr_SetFromErrno(PyExc_OSError
);
1002 PyObject
* ret
= PyUnicode_FromString(result
);
1008 static PyObject
* Pakfire_bind(PakfireObject
* self
, PyObject
* args
) {
1009 const char* src
= NULL
;
1010 const char* dst
= NULL
;
1012 if (!PyArg_ParseTuple(args
, "s|z", &src
, &dst
))
1015 int r
= pakfire_bind(self
->pakfire
, src
, dst
, 0);
1017 PyErr_SetFromErrno(PyExc_OSError
);
1024 static PyObject
* Pakfire_copy_in(PakfireObject
* self
, PyObject
* args
) {
1025 const char* src
= NULL
;
1026 const char* dst
= NULL
;
1028 if (!PyArg_ParseTuple(args
, "ss", &src
, &dst
))
1031 int r
= pakfire_copy_in(self
->pakfire
, src
, dst
);
1033 PyErr_SetFromErrno(PyExc_OSError
);
1040 static PyObject
* Pakfire_copy_out(PakfireObject
* self
, PyObject
* args
) {
1041 const char* src
= NULL
;
1042 const char* dst
= NULL
;
1044 if (!PyArg_ParseTuple(args
, "ss", &src
, &dst
))
1047 int r
= pakfire_copy_out(self
->pakfire
, src
, dst
);
1049 PyErr_SetFromErrno(PyExc_OSError
);
1056 static PyObject
* Pakfire_get_repos(PakfireObject
* self
) {
1057 struct pakfire_repolist
* repos
= pakfire_get_repos(self
->pakfire
);
1059 PyErr_SetFromErrno(PyExc_OSError
);
1063 const size_t l
= pakfire_repolist_size(repos
);
1065 PyObject
* list
= PyList_New(l
);
1069 for (unsigned int i
= 0; i
< l
; i
++) {
1070 struct pakfire_repo
* repo
= pakfire_repolist_get(repos
, i
);
1074 PyObject
* obj
= new_repo(&RepoType
, repo
);
1075 PyList_SET_ITEM(list
, i
, obj
);
1077 pakfire_repo_unref(repo
);
1081 pakfire_repolist_unref(repos
);
1086 static PyObject
* execute_return_value(int r
) {
1087 // Raise an OS error if r < 0
1091 PyErr_SetFromErrno(PyExc_OSError
);
1094 // Raise exception when the command failed
1096 PyObject
* code
= PyLong_FromLong(r
);
1098 PyErr_SetObject(PyExc_CommandExecutionError
, code
);
1107 static PyObject
* Pakfire_build(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1114 const char* path
= NULL
;
1115 const char* build_id
= NULL
;
1117 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|z", kwlist
, &path
, &build_id
))
1121 int r
= pakfire_build(self
->pakfire
, path
, NULL
, build_id
, 0);
1123 return execute_return_value(r
);
1126 static PyObject
* Pakfire_shell(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1131 char** packages
= NULL
;
1134 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|O&", kwlist
, convert_packages
, &packages
))
1137 int r
= pakfire_shell(self
->pakfire
, (const char**)packages
);
1139 return execute_return_value(r
);
1142 static PyObject
* Pakfire_clean(PakfireObject
* self
) {
1143 int r
= pakfire_clean(self
->pakfire
, 0);
1145 PyErr_SetFromErrno(PyExc_OSError
);
1152 static PyObject
* Pakfire_refresh(PakfireObject
* self
, PyObject
* args
) {
1155 if (!PyArg_ParseTuple(args
, "|p", &force
))
1158 int r
= pakfire_refresh(self
->pakfire
, force
);
1160 PyErr_SetFromErrno(PyExc_OSError
);
1167 static PyObject
* Pakfire_check(PakfireObject
* self
) {
1168 int r
= pakfire_check(self
->pakfire
);
1170 PyErr_SetFromErrno(PyExc_OSError
);
1177 static PyObject
* Pakfire_sync(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1183 int keep_orphaned
= 0;
1185 PyObject
* status_callback
= NULL
;
1187 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|$pO", kwlist
,
1188 &keep_orphaned
, &status_callback
))
1192 flags
|= PAKFIRE_REQUEST_KEEP_ORPHANED
;
1194 int r
= pakfire_sync(self
->pakfire
, 0, flags
, NULL
,
1195 Pakfire_status_callback
, status_callback
);
1197 PyErr_SetFromErrno(PyExc_OSError
);
1204 static PyObject
* Pakfire_open(PakfireObject
* self
, PyObject
* args
) {
1205 struct pakfire_archive
* archive
= NULL
;
1206 const char* path
= NULL
;
1208 if (!PyArg_ParseTuple(args
, "s", &path
))
1211 int r
= pakfire_archive_open(&archive
, self
->pakfire
, path
);
1213 PyErr_SetFromErrno(PyExc_OSError
);
1217 // Create Python object
1218 PyObject
* object
= new_archive(&ArchiveType
, archive
);
1219 pakfire_archive_unref(archive
);
1224 static PyObject
* Pakfire_repo_compose(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1225 char* kwlist
[] = { "path", "files", NULL
};
1226 const char* path
= NULL
;
1227 PyObject
* list
= NULL
;
1229 PyObject
* ret
= NULL
;
1231 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "sO", kwlist
, &path
, &list
))
1234 // List must be a sequence
1235 if (!PySequence_Check(list
)) {
1236 PyErr_SetString(PyExc_ValueError
, "Expected a sequence.");
1240 const int flags
= 0;
1242 // How many new files do we have?
1243 ssize_t num_files
= PySequence_Length(list
);
1247 // Allocate files array
1248 const char** files
= calloc(num_files
+ 1, sizeof(*files
));
1250 PyErr_SetFromErrno(PyExc_OSError
);
1254 for (int i
= 0; i
< num_files
; i
++) {
1255 PyObject
* file
= PySequence_GetItem(list
, i
);
1259 // Check if file is a Unicode object
1260 if (!PyUnicode_Check(file
)) {
1261 PyErr_SetString(PyExc_ValueError
, "Expected a string.");
1265 // Add pointer to string to files array
1266 files
[i
] = PyUnicode_AsUTF8(file
);
1273 int r
= pakfire_repo_compose(self
->pakfire
, path
, flags
, files
);
1275 PyErr_SetFromErrno(PyExc_OSError
);
1279 // Return None on success
1290 static struct PyMethodDef Pakfire_methods
[] = {
1293 (PyCFunction
)Pakfire_bind
,
1299 (PyCFunction
)Pakfire_build
,
1300 METH_VARARGS
|METH_KEYWORDS
,
1305 (PyCFunction
)Pakfire_check
,
1311 (PyCFunction
)Pakfire_clean
,
1317 (PyCFunction
)Pakfire_copy_in
,
1323 (PyCFunction
)Pakfire_copy_out
,
1329 (PyCFunction
)Pakfire_dist
,
1335 (PyCFunction
)Pakfire_erase
,
1336 METH_VARARGS
|METH_KEYWORDS
,
1341 (PyCFunction
)Pakfire_execute
,
1342 METH_VARARGS
|METH_KEYWORDS
,
1347 (PyCFunction
)Pakfire_fetch_key
,
1348 METH_VARARGS
|METH_KEYWORDS
,
1353 (PyCFunction
)Pakfire_generate_key
,
1354 METH_VARARGS
|METH_KEYWORDS
,
1359 (PyCFunction
)Pakfire_get_key
,
1365 (PyCFunction
)Pakfire_get_repo
,
1371 (PyCFunction
)Pakfire_import_key
,
1377 (PyCFunction
)Pakfire_install
,
1378 METH_VARARGS
|METH_KEYWORDS
,
1383 (PyCFunction
)Pakfire_open
,
1389 (PyCFunction
)Pakfire_refresh
,
1395 (PyCFunction
)Pakfire_repo_compose
,
1396 METH_VARARGS
|METH_KEYWORDS
,
1401 (PyCFunction
)Pakfire_search
,
1402 METH_VARARGS
|METH_KEYWORDS
,
1407 (PyCFunction
)Pakfire_shell
,
1408 METH_VARARGS
|METH_KEYWORDS
,
1413 (PyCFunction
)Pakfire_sync
,
1414 METH_VARARGS
|METH_KEYWORDS
,
1419 (PyCFunction
)Pakfire_update
,
1420 METH_VARARGS
|METH_KEYWORDS
,
1425 (PyCFunction
)Pakfire_version_compare
,
1431 (PyCFunction
)Pakfire_whatprovides
,
1437 (PyCFunction
)Pakfire_whatrequires
,
1444 static struct PyGetSetDef Pakfire_getsetters
[] = {
1447 (getter
)Pakfire_get_arch
,
1454 (getter
)Pakfire_get_keys
,
1461 (getter
)Pakfire_get_path
,
1468 (getter
)Pakfire_get_repos
,
1476 PyTypeObject PakfireType
= {
1477 PyVarObject_HEAD_INIT(NULL
, 0)
1478 tp_name
: "_pakfire.Pakfire",
1479 tp_basicsize
: sizeof(PakfireObject
),
1480 tp_flags
: Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
1481 tp_new
: Pakfire_new
,
1482 tp_dealloc
: (destructor
)Pakfire_dealloc
,
1483 tp_init
: (initproc
)Pakfire_init
,
1484 tp_doc
: "Pakfire object",
1485 tp_methods
: Pakfire_methods
,
1486 tp_getset
: Pakfire_getsetters
,
1487 tp_repr
: (reprfunc
)Pakfire_repr
,