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/execute.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 PyObject
* Pakfire_execute_logging_callback
= NULL
;
780 static int __Pakfire_execute_logging_callback(struct pakfire
* pakfire
, void* data
,
781 int priority
, const char* line
, size_t length
) {
784 // Do nothing if callback isn't set
785 if (!Pakfire_execute_logging_callback
)
788 // Translate priority to Python logging priorities
799 // Remove the trailing newline
800 if (line
&& line
[length
- 1] == '\n')
803 // Create tuple with arguments for the callback function
804 PyObject
* args
= Py_BuildValue("(is#)", priority
, line
, (Py_ssize_t
)length
);
808 PyObject
* result
= PyObject_CallObject(Pakfire_execute_logging_callback
, args
);
809 if (result
&& PyLong_Check(result
)) {
810 r
= PyLong_AsLong(result
);
819 static PyObject
* Pakfire_execute(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
820 char* kwlist
[] = {"command", "environ", "enable_network", "interactive",
821 "logging_callback", NULL
};
823 PyObject
* command
= NULL
;
824 PyObject
* environ
= NULL
;
825 int enable_network
= 0;
827 PyObject
* logging_callback
= NULL
;
829 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "O|OppO", kwlist
, &command
, &environ
,
830 &enable_network
, &interactive
, &logging_callback
))
833 // Check if command is a list
834 if (!PyList_Check(command
)) {
835 PyErr_SetString(PyExc_TypeError
, "command must be a list");
839 ssize_t command_length
= PyList_Size(command
);
841 // Check if command is not empty
842 if (command_length
== 0) {
843 PyErr_SetString(PyExc_ValueError
, "command is empty");
847 // All arguments in command must be strings
848 for (unsigned int i
= 0; i
< command_length
; i
++) {
849 PyObject
* item
= PyList_GET_ITEM(command
, i
);
851 if (!PyUnicode_Check(item
)) {
852 PyErr_Format(PyExc_TypeError
, "Item %u in command is not a string", i
);
857 // Check if logging_callback is
858 if (logging_callback
&& !PyCallable_Check(logging_callback
)) {
859 PyErr_SetString(PyExc_TypeError
, "logging_callback must be callable\n");
863 ssize_t environ_length
= 0;
869 // Check if environ is a dictionary
870 if (!PyDict_Check(environ
)) {
871 PyErr_SetString(PyExc_TypeError
, "environ must be a dictionary");
875 // All keys and values must be strings
876 while (PyDict_Next(environ
, &p
, &key
, &value
)) {
877 if (!PyUnicode_Check(key
) || !PyUnicode_Check(value
)) {
878 PyErr_SetString(PyExc_TypeError
, "Environment contains a non-string object");
883 environ_length
= PyDict_Size(environ
);
886 // All inputs look fine
888 const char* argv
[command_length
+ 1];
889 char* envp
[environ_length
+ 1];
893 for (unsigned int i
= 0; i
< command_length
; i
++) {
894 PyObject
* item
= PyList_GET_ITEM(command
, i
);
895 argv
[i
] = PyUnicode_AsUTF8(item
);
903 while (PyDict_Next(environ
, &p
, &key
, &value
)) {
904 int r
= asprintf(&envp
[i
++], "%s=%s",
905 PyUnicode_AsUTF8(key
), PyUnicode_AsUTF8(value
));
910 for (i
= 0; envp
[i
]; i
++)
913 return PyErr_NoMemory();
918 // Terminate argv and envp
919 argv
[command_length
] = NULL
;
920 envp
[environ_length
] = NULL
;
924 flags
|= PAKFIRE_EXECUTE_ENABLE_NETWORK
;
928 flags
|= PAKFIRE_EXECUTE_INTERACTIVE
;
930 // Set logging callback
931 Pakfire_execute_logging_callback
= logging_callback
;
934 int r
= pakfire_execute(self
->pakfire
, argv
, envp
, flags
,
935 (logging_callback
) ? __Pakfire_execute_logging_callback
: NULL
, NULL
);
938 for (unsigned int i
= 0; envp
[i
]; i
++)
941 // Raise an OS error if r < 0
945 PyErr_SetFromErrno(PyExc_OSError
);
948 // Raise exception when the command failed
950 PyObject
* code
= PyLong_FromLong(r
);
952 PyErr_SetObject(PyExc_CommandExecutionError
, code
);
962 static PyObject
* Pakfire_dist(PakfireObject
* self
, PyObject
* args
) {
963 const char* path
= NULL
;
964 const char* target
= NULL
;
967 if (!PyArg_ParseTuple(args
, "s|z", &path
, &target
))
970 int r
= pakfire_dist(self
->pakfire
, path
, target
, &result
);
972 PyErr_SetFromErrno(PyExc_OSError
);
976 PyObject
* ret
= PyUnicode_FromString(result
);
982 static PyObject
* Pakfire_bind(PakfireObject
* self
, PyObject
* args
) {
983 const char* src
= NULL
;
984 const char* dst
= NULL
;
986 if (!PyArg_ParseTuple(args
, "s|z", &src
, &dst
))
989 int r
= pakfire_bind(self
->pakfire
, src
, dst
, 0);
991 PyErr_SetFromErrno(PyExc_OSError
);
998 static PyObject
* Pakfire_copy_in(PakfireObject
* self
, PyObject
* args
) {
999 const char* src
= NULL
;
1000 const char* dst
= NULL
;
1002 if (!PyArg_ParseTuple(args
, "ss", &src
, &dst
))
1005 int r
= pakfire_copy_in(self
->pakfire
, src
, dst
);
1007 PyErr_SetFromErrno(PyExc_OSError
);
1014 static PyObject
* Pakfire_copy_out(PakfireObject
* self
, PyObject
* args
) {
1015 const char* src
= NULL
;
1016 const char* dst
= NULL
;
1018 if (!PyArg_ParseTuple(args
, "ss", &src
, &dst
))
1021 int r
= pakfire_copy_out(self
->pakfire
, src
, dst
);
1023 PyErr_SetFromErrno(PyExc_OSError
);
1030 static PyObject
* Pakfire_get_repos(PakfireObject
* self
) {
1031 struct pakfire_repolist
* repos
= pakfire_get_repos(self
->pakfire
);
1033 PyErr_SetFromErrno(PyExc_OSError
);
1037 const size_t l
= pakfire_repolist_size(repos
);
1039 PyObject
* list
= PyList_New(l
);
1043 for (unsigned int i
= 0; i
< l
; i
++) {
1044 struct pakfire_repo
* repo
= pakfire_repolist_get(repos
, i
);
1048 PyObject
* obj
= new_repo(&RepoType
, repo
);
1049 PyList_SET_ITEM(list
, i
, obj
);
1051 pakfire_repo_unref(repo
);
1055 pakfire_repolist_unref(repos
);
1060 static PyObject
* execute_return_value(int r
) {
1061 // Raise an OS error if r < 0
1065 PyErr_SetFromErrno(PyExc_OSError
);
1068 // Raise exception when the command failed
1070 PyObject
* code
= PyLong_FromLong(r
);
1072 PyErr_SetObject(PyExc_CommandExecutionError
, code
);
1081 static PyObject
* Pakfire_build(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1089 const char* path
= NULL
;
1090 const char* build_id
= NULL
;
1091 PyObject
* logging_callback
= NULL
;
1093 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zO", kwlist
, &path
,
1094 &build_id
, &logging_callback
))
1097 // Check if logging_callback is
1098 if (logging_callback
&& !PyCallable_Check(logging_callback
)) {
1099 PyErr_SetString(PyExc_TypeError
, "logging_callback must be callable\n");
1103 // Set logging callback
1104 Pakfire_execute_logging_callback
= logging_callback
;
1107 int r
= pakfire_build(self
->pakfire
, path
, NULL
, build_id
, 0,
1108 (logging_callback
) ? __Pakfire_execute_logging_callback
: NULL
, NULL
);
1110 return execute_return_value(r
);
1113 static PyObject
* Pakfire_shell(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1118 char** packages
= NULL
;
1121 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|O&", kwlist
, convert_packages
, &packages
))
1124 int r
= pakfire_shell(self
->pakfire
, (const char**)packages
);
1126 return execute_return_value(r
);
1129 static PyObject
* Pakfire_clean(PakfireObject
* self
) {
1130 int r
= pakfire_clean(self
->pakfire
, 0);
1132 PyErr_SetFromErrno(PyExc_OSError
);
1139 static PyObject
* Pakfire_refresh(PakfireObject
* self
, PyObject
* args
) {
1142 if (!PyArg_ParseTuple(args
, "|p", &force
))
1145 int r
= pakfire_refresh(self
->pakfire
, force
);
1147 PyErr_SetFromErrno(PyExc_OSError
);
1154 static PyObject
* Pakfire_check(PakfireObject
* self
) {
1155 int r
= pakfire_check(self
->pakfire
);
1157 PyErr_SetFromErrno(PyExc_OSError
);
1164 static PyObject
* Pakfire_sync(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1170 int keep_orphaned
= 0;
1172 PyObject
* status_callback
= NULL
;
1174 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|$pO", kwlist
,
1175 &keep_orphaned
, &status_callback
))
1179 flags
|= PAKFIRE_REQUEST_KEEP_ORPHANED
;
1181 int r
= pakfire_sync(self
->pakfire
, 0, flags
, NULL
,
1182 Pakfire_status_callback
, status_callback
);
1184 PyErr_SetFromErrno(PyExc_OSError
);
1191 static PyObject
* Pakfire_open(PakfireObject
* self
, PyObject
* args
) {
1192 struct pakfire_archive
* archive
= NULL
;
1193 const char* path
= NULL
;
1195 if (!PyArg_ParseTuple(args
, "s", &path
))
1198 int r
= pakfire_archive_open(&archive
, self
->pakfire
, path
);
1200 PyErr_SetFromErrno(PyExc_OSError
);
1204 // Create Python object
1205 PyObject
* object
= new_archive(&ArchiveType
, archive
);
1206 pakfire_archive_unref(archive
);
1211 static PyObject
* Pakfire_repo_compose(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1212 char* kwlist
[] = { "path", "files", NULL
};
1213 const char* path
= NULL
;
1214 PyObject
* list
= NULL
;
1216 PyObject
* ret
= NULL
;
1218 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "sO", kwlist
, &path
, &list
))
1221 // List must be a sequence
1222 if (!PySequence_Check(list
)) {
1223 PyErr_SetString(PyExc_ValueError
, "Expected a sequence.");
1227 const int flags
= 0;
1229 // How many new files do we have?
1230 ssize_t num_files
= PySequence_Length(list
);
1234 // Allocate files array
1235 const char** files
= calloc(num_files
+ 1, sizeof(*files
));
1237 PyErr_SetFromErrno(PyExc_OSError
);
1241 for (int i
= 0; i
< num_files
; i
++) {
1242 PyObject
* file
= PySequence_GetItem(list
, i
);
1246 // Check if file is a Unicode object
1247 if (!PyUnicode_Check(file
)) {
1248 PyErr_SetString(PyExc_ValueError
, "Expected a string.");
1252 // Add pointer to string to files array
1253 files
[i
] = PyUnicode_AsUTF8(file
);
1260 int r
= pakfire_repo_compose(self
->pakfire
, path
, flags
, files
);
1262 PyErr_SetFromErrno(PyExc_OSError
);
1266 // Return None on success
1277 static struct PyMethodDef Pakfire_methods
[] = {
1280 (PyCFunction
)Pakfire_bind
,
1286 (PyCFunction
)Pakfire_build
,
1287 METH_VARARGS
|METH_KEYWORDS
,
1292 (PyCFunction
)Pakfire_check
,
1298 (PyCFunction
)Pakfire_clean
,
1304 (PyCFunction
)Pakfire_copy_in
,
1310 (PyCFunction
)Pakfire_copy_out
,
1316 (PyCFunction
)Pakfire_dist
,
1322 (PyCFunction
)Pakfire_erase
,
1323 METH_VARARGS
|METH_KEYWORDS
,
1328 (PyCFunction
)Pakfire_execute
,
1329 METH_VARARGS
|METH_KEYWORDS
,
1334 (PyCFunction
)Pakfire_fetch_key
,
1335 METH_VARARGS
|METH_KEYWORDS
,
1340 (PyCFunction
)Pakfire_generate_key
,
1341 METH_VARARGS
|METH_KEYWORDS
,
1346 (PyCFunction
)Pakfire_get_key
,
1352 (PyCFunction
)Pakfire_get_repo
,
1358 (PyCFunction
)Pakfire_import_key
,
1364 (PyCFunction
)Pakfire_install
,
1365 METH_VARARGS
|METH_KEYWORDS
,
1370 (PyCFunction
)Pakfire_open
,
1376 (PyCFunction
)Pakfire_refresh
,
1382 (PyCFunction
)Pakfire_repo_compose
,
1383 METH_VARARGS
|METH_KEYWORDS
,
1388 (PyCFunction
)Pakfire_search
,
1389 METH_VARARGS
|METH_KEYWORDS
,
1394 (PyCFunction
)Pakfire_shell
,
1395 METH_VARARGS
|METH_KEYWORDS
,
1400 (PyCFunction
)Pakfire_sync
,
1401 METH_VARARGS
|METH_KEYWORDS
,
1406 (PyCFunction
)Pakfire_update
,
1407 METH_VARARGS
|METH_KEYWORDS
,
1412 (PyCFunction
)Pakfire_version_compare
,
1418 (PyCFunction
)Pakfire_whatprovides
,
1424 (PyCFunction
)Pakfire_whatrequires
,
1431 static struct PyGetSetDef Pakfire_getsetters
[] = {
1434 (getter
)Pakfire_get_arch
,
1441 (getter
)Pakfire_get_keys
,
1448 (getter
)Pakfire_get_path
,
1455 (getter
)Pakfire_get_repos
,
1463 PyTypeObject PakfireType
= {
1464 PyVarObject_HEAD_INIT(NULL
, 0)
1465 tp_name
: "_pakfire.Pakfire",
1466 tp_basicsize
: sizeof(PakfireObject
),
1467 tp_flags
: Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
1468 tp_new
: Pakfire_new
,
1469 tp_dealloc
: (destructor
)Pakfire_dealloc
,
1470 tp_init
: (initproc
)Pakfire_init
,
1471 tp_doc
: "Pakfire object",
1472 tp_methods
: Pakfire_methods
,
1473 tp_getset
: Pakfire_getsetters
,
1474 tp_repr
: (reprfunc
)Pakfire_repr
,