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/transaction.h>
39 #include <pakfire/util.h>
48 static PyObject
* Pakfire_new(PyTypeObject
* type
, PyObject
* args
, PyObject
* kwds
) {
49 PakfireObject
* self
= (PakfireObject
*)type
->tp_alloc(type
, 0);
54 self
->callbacks
.log
= NULL
;
55 self
->callbacks
.confirm
= NULL
;
58 return (PyObject
*)self
;
61 static void Pakfire_log_callback(void* data
, int priority
, const char* file
, int line
,
62 const char* fn
, const char* format
, va_list args
) {
63 PyObject
* callback
= (PyObject
*)data
;
64 PyObject
* exception
= NULL
;
66 // Do nothing if callback isn't set
70 // Translate priority to Python logging priorities
84 // Drop messages of an unknown priority
89 PyObject
* tuple
= NULL
;
90 PyObject
* result
= NULL
;
94 int r
= vasprintf(&buffer
, format
, args
);
98 // Build a tuple with the priority and the log message
99 tuple
= Py_BuildValue("(is)", priority
, buffer
);
104 result
= PyObject_CallObject(callback
, tuple
);
108 We cannot really catch any Python errors here, since we cannot send
109 any error codes up the chain.
111 So, in order to debug the problem, We will check if an exception has
112 occurred and if so, print it to the console.
114 exception
= PyErr_Occurred();
124 static int Pakfire_confirm_callback(struct pakfire
* pakfire
, void* data
,
125 const char* message
, const char* question
) {
126 PyObject
* callback
= (PyObject
*)data
;
129 // Do nothing if callback isn't set
133 PyObject
* args
= Py_BuildValue("(ss)", message
, question
);
137 PyObject
* result
= PyObject_CallObject(callback
, args
);
139 // If the callback raised an exception, we will ignore it and indicate
140 // that an error happened, but we cannot re-raise the exception
146 // Set the return code
147 if (result
== Py_True
)
159 static int Pakfire_init(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
169 const char* path
= NULL
;
170 const char* arch
= NULL
;
171 const char* conf
= NULL
;
174 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "|zzOpzO", kwlist
,
175 &path
, &arch
, &self
->callbacks
.log
, &offline
, &conf
, &self
->callbacks
.confirm
))
178 // Check if log callback is callable
179 if (self
->callbacks
.log
&& !PyCallable_Check(self
->callbacks
.log
)) {
180 PyErr_SetString(PyExc_TypeError
, "logger must be callable\n");
184 // Check if confirm callback is callable
185 if (self
->callbacks
.confirm
&& !PyCallable_Check(self
->callbacks
.confirm
)) {
186 PyErr_SetString(PyExc_TypeError
, "Confirm callback is not callable");
192 // Enable offline mode
194 flags
|= PAKFIRE_FLAGS_OFFLINE
;
196 // Configure callbacks
197 if (self
->callbacks
.log
)
198 Py_INCREF(self
->callbacks
.log
);
200 // Create a new Pakfire instance
201 int r
= pakfire_create(&self
->pakfire
, path
, arch
, conf
, flags
,
202 LOG_DEBUG
, Pakfire_log_callback
, self
->callbacks
.log
);
205 // Invalid architecture or path
207 PyErr_SetString(PyExc_ValueError
, "Invalid architecture or path");
212 PyErr_SetFromErrno(PyExc_OSError
);
218 // Configure confirm callback
219 if (self
->callbacks
.confirm
) {
220 pakfire_set_confirm_callback(self
->pakfire
,
221 Pakfire_confirm_callback
, self
->callbacks
.confirm
);
223 Py_INCREF(self
->callbacks
.confirm
);
229 static void Pakfire_dealloc(PakfireObject
* self
) {
231 // Reset log callback
232 if (self
->callbacks
.log
) {
233 pakfire_set_log_callback(self
->pakfire
, NULL
, NULL
);
234 Py_DECREF(self
->callbacks
.log
);
237 // Reset confirm callback
238 if (self
->callbacks
.confirm
) {
239 pakfire_set_confirm_callback(self
->pakfire
, NULL
, NULL
);
240 Py_DECREF(self
->callbacks
.confirm
);
243 pakfire_unref(self
->pakfire
);
246 Py_TYPE(self
)->tp_free((PyObject
*)self
);
249 static PyObject
* Pakfire_repr(PakfireObject
* self
) {
250 const char* path
= pakfire_get_path(self
->pakfire
);
251 const char* arch
= pakfire_get_arch(self
->pakfire
);
253 return PyUnicode_FromFormat("<_pakfire.Pakfire %s (%s)>", path
, arch
);
256 static PyObject
* Pakfire_get_path(PakfireObject
* self
) {
257 const char* path
= pakfire_get_path(self
->pakfire
);
259 return PyUnicode_FromString(path
);
262 static PyObject
* Pakfire_get_arch(PakfireObject
* self
) {
263 const char* arch
= pakfire_get_arch(self
->pakfire
);
265 return PyUnicode_FromString(arch
);
268 static PyObject
* Pakfire_get_repo(PakfireObject
* self
, PyObject
* args
) {
269 const char* name
= NULL
;
271 if (!PyArg_ParseTuple(args
, "s", &name
))
274 struct pakfire_repo
* repo
= pakfire_get_repo(self
->pakfire
, name
);
278 PyObject
* obj
= new_repo(&RepoType
, repo
);
279 pakfire_repo_unref(repo
);
284 static void Pakfire_status_callback(struct pakfire
* pakfire
, void* data
,
285 int progress
, const char* status
) {
286 PyObject
* callback
= (PyObject
*)data
;
288 // Do not attempt to call nothing
293 PyObject
* args
= Py_BuildValue("(is)", progress
, status
);
298 PyObject
* result
= PyObject_CallObject(callback
, args
);
304 static int convert_packages(PyObject
* object
, void* address
) {
305 char*** packages
= (char***)address
;
307 // Called for cleanup
311 // Nothing to do when object is None
312 if (object
== Py_None
)
313 return Py_CLEANUP_SUPPORTED
;
315 if (!PySequence_Check(object
)) {
316 PyErr_SetString(PyExc_ValueError
, "Packages must be a sequence");
320 const unsigned int length
= PySequence_Length(object
);
322 return Py_CLEANUP_SUPPORTED
;
325 *packages
= calloc(length
+ 1, sizeof(*packages
));
327 PyErr_SetFromErrno(PyExc_OSError
);
331 for (unsigned int i
= 0; i
< length
; i
++) {
332 PyObject
* item
= PySequence_GetItem(object
, i
);
334 // Check if input is a string
335 if (!PyUnicode_Check(item
)) {
338 PyErr_SetString(PyExc_AttributeError
, "Expected a string");
343 const char* package
= PyUnicode_AsUTF8(item
);
349 // Add package to array
350 (*packages
)[i
] = strdup(package
);
351 if (!(*packages
)[i
]) {
360 return Py_CLEANUP_SUPPORTED
;
364 for (char** package
= *packages
; *package
; package
++)
372 static PyObject
* Pakfire_install(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
376 "without_recommended",
382 char** packages
= NULL
;
384 int without_recommended
= 0;
385 int allow_uninstall
= 0;
386 int allow_downgrade
= 0;
387 int solver_flags
= 0;
388 int transaction_flags
= 0;
389 PyObject
* status_callback
= NULL
;
391 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O&|$ppppO", kwlist
,
392 convert_packages
, &packages
, &dryrun
, &without_recommended
, &allow_uninstall
,
393 &allow_downgrade
, &status_callback
))
396 // Check if callback is callable
397 if (status_callback
&& !PyCallable_Check(status_callback
)) {
398 PyErr_SetString(PyExc_TypeError
, "status_callback must be callable");
402 // Enable dry-run mode
404 transaction_flags
|= PAKFIRE_TRANSACTION_DRY_RUN
;
406 // Do not install recommended packages
407 if (without_recommended
)
408 solver_flags
|= PAKFIRE_REQUEST_WITHOUT_RECOMMENDED
;
410 // Can the solver uninstall packages?
412 solver_flags
|= PAKFIRE_REQUEST_ALLOW_UNINSTALL
;
414 // Can the solver downgrade packages?
416 solver_flags
|= PAKFIRE_REQUEST_ALLOW_DOWNGRADE
;
418 // Run pakfire_install
419 int r
= pakfire_install(self
->pakfire
, transaction_flags
, solver_flags
,
420 (const char**)packages
, NULL
, 0, NULL
, Pakfire_status_callback
, status_callback
);
422 PyErr_SetFromErrno(PyExc_OSError
);
425 for (char** package
= packages
; *package
; package
++)
436 static PyObject
* Pakfire_erase(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
444 char** packages
= NULL
;
446 int keep_dependencies
= 0;
447 int transaction_flags
= 0;
449 PyObject
* status_callback
= NULL
;
451 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O&|$ppO", kwlist
,
452 convert_packages
, &packages
, &dryrun
, &keep_dependencies
, &status_callback
))
455 // Check if callback is callable
456 if (status_callback
&& !PyCallable_Check(status_callback
)) {
457 PyErr_SetString(PyExc_TypeError
, "status_callback must be callable");
462 transaction_flags
|= PAKFIRE_TRANSACTION_DRY_RUN
;
464 if (keep_dependencies
)
465 flags
|= PAKFIRE_REQUEST_KEEP_DEPS
;
468 int r
= pakfire_erase(self
->pakfire
, transaction_flags
, 0, (const char**)packages
,
469 NULL
, flags
, NULL
, Pakfire_status_callback
, status_callback
);
471 PyErr_SetFromErrno(PyExc_OSError
);
474 for (char** package
= packages
; *package
; package
++)
485 static PyObject
* Pakfire_update(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
495 char** packages
= NULL
;
496 char** excludes
= NULL
;
498 int allow_uninstall
= 0;
499 int allow_downgrade
= 0;
500 int solver_flags
= 0;
501 int transaction_flags
= 0;
502 PyObject
* status_callback
= NULL
;
504 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O&|$pO&ppO", kwlist
,
505 convert_packages
, &packages
, &dryrun
, convert_packages
, &excludes
,
506 &allow_uninstall
, &allow_downgrade
, &status_callback
))
509 // Check if callback is callable
510 if (status_callback
&& !PyCallable_Check(status_callback
)) {
511 PyErr_SetString(PyExc_TypeError
, "status_callback must be callable");
516 transaction_flags
= PAKFIRE_TRANSACTION_DRY_RUN
;
518 // Can the solver uninstall packages?
520 solver_flags
|= PAKFIRE_REQUEST_ALLOW_UNINSTALL
;
522 // Can the solver downgrade packages?
524 solver_flags
|= PAKFIRE_REQUEST_ALLOW_DOWNGRADE
;
526 // Run pakfire_update
527 int r
= pakfire_update(self
->pakfire
, transaction_flags
, solver_flags
,
528 (const char**)packages
, (const char**)excludes
, 0, NULL
,
529 Pakfire_status_callback
, status_callback
);
531 PyErr_SetFromErrno(PyExc_OSError
);
534 for (char** package
= packages
; *package
; package
++)
540 for (char** exclude
= excludes
; *exclude
; exclude
++)
551 static PyObject
* Pakfire_keys_to_list(struct pakfire_key
** keys
) {
552 PyObject
* list
= PyList_New(0);
558 // Push all keys onto the list
559 for (struct pakfire_key
** key
= keys
; *key
; key
++) {
560 PyObject
* object
= new_key(&KeyType
, *key
);
564 PyList_Append(list
, object
);
575 static PyObject
* Pakfire_get_keys(PakfireObject
* self
) {
576 struct pakfire_key
** keys
= NULL
;
578 int r
= pakfire_list_keys(self
->pakfire
, &keys
);
580 PyErr_SetFromErrno(PyExc_OSError
);
584 // Convert keys to list
585 PyObject
* list
= Pakfire_keys_to_list(keys
);
589 for (struct pakfire_key
** key
= keys
; *key
; key
++)
590 pakfire_key_unref(*key
);
597 static PyObject
* Pakfire_get_key(PakfireObject
* self
, PyObject
* args
) {
598 const char* pattern
= NULL
;
600 if (!PyArg_ParseTuple(args
, "s", &pattern
))
603 // Try finding the key
604 struct pakfire_key
* key
= pakfire_key_get(self
->pakfire
, pattern
);
608 PyObject
* object
= new_key(&KeyType
, key
);
609 pakfire_key_unref(key
);
614 static PyObject
* Pakfire_generate_key(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
615 char* kwlist
[] = { "userid", "algorithm", NULL
};
616 struct pakfire_key
* key
= NULL
;
617 const char* userid
= NULL
;
618 const char* algo
= NULL
;
620 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s|$z", kwlist
, &userid
, &algo
))
623 // Generate a new key
624 int r
= pakfire_key_generate(&key
, self
->pakfire
, algo
, userid
);
626 PyErr_SetFromErrno(PyExc_OSError
);
630 PyObject
* object
= new_key(&KeyType
, key
);
631 pakfire_key_unref(key
);
636 static PyObject
* Pakfire_import_key(PakfireObject
* self
, PyObject
* args
) {
637 PyObject
* object
= NULL
;
639 if (!PyArg_ParseTuple(args
, "O", &object
))
642 // Get a file descriptor from object
643 int fd
= PyObject_AsFileDescriptor(object
);
648 FILE* f
= fdopen(fd
, "r");
650 PyErr_SetFromErrno(PyExc_OSError
);
654 struct pakfire_key
** keys
= NULL
;
656 // Import keys from f
657 int r
= pakfire_key_import(self
->pakfire
, f
, &keys
);
659 PyErr_SetFromErrno(PyExc_OSError
);
663 // Convert keys to list
664 PyObject
* list
= Pakfire_keys_to_list(keys
);
667 for (struct pakfire_key
** key
= keys
; *key
; key
++)
668 pakfire_key_unref(*key
);
674 static PyObject
* Pakfire_fetch_key(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
675 char* kwlist
[] = { "userid", "fingerprint", NULL
};
676 struct pakfire_key
* key
= NULL
;
677 const char* userid
= NULL
;
678 const char* fingerprint
= NULL
;
680 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "|$zz", kwlist
, &userid
, &fingerprint
))
684 int r
= pakfire_key_fetch(&key
, self
->pakfire
, userid
, fingerprint
);
686 PyErr_SetFromErrno(PyExc_OSError
);
692 PyObject
* object
= new_key(&KeyType
, key
);
693 pakfire_key_unref(key
);
701 static PyObject
* Pakfire_whatprovides(PakfireObject
* self
, PyObject
* args
) {
702 const char* provides
= NULL
;
703 struct pakfire_packagelist
* list
= NULL
;
704 PyObject
* ret
= NULL
;
707 if (!PyArg_ParseTuple(args
, "s", &provides
))
711 r
= pakfire_packagelist_create(&list
, self
->pakfire
);
713 PyErr_SetFromErrno(PyExc_OSError
);
717 r
= pakfire_whatprovides(self
->pakfire
, provides
, 0, list
);
719 PyErr_SetFromErrno(PyExc_OSError
);
723 // Create a Python list from the package list
724 ret
= PyList_FromPackageList(list
);
728 pakfire_packagelist_unref(list
);
733 static PyObject
* Pakfire_whatrequires(PakfireObject
* self
, PyObject
* args
) {
734 const char* requires
= NULL
;
735 struct pakfire_packagelist
* list
= NULL
;
736 PyObject
* ret
= NULL
;
739 if (!PyArg_ParseTuple(args
, "s", &requires
))
743 r
= pakfire_packagelist_create(&list
, self
->pakfire
);
745 PyErr_SetFromErrno(PyExc_OSError
);
749 r
= pakfire_whatrequires(self
->pakfire
, requires
, 0, list
);
751 PyErr_SetFromErrno(PyExc_OSError
);
755 // Create a Python list from the package list
756 ret
= PyList_FromPackageList(list
);
760 pakfire_packagelist_unref(list
);
765 static PyObject
* Pakfire_search(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
766 char* kwlist
[] = { "pattern", "name_only", NULL
};
767 struct pakfire_packagelist
* list
= NULL
;
768 const char* pattern
= NULL
;
771 PyObject
* ret
= NULL
;
774 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s|$p", kwlist
, &pattern
, &name_only
))
777 // Search for package names only
779 flags
|= PAKFIRE_SEARCH_NAME_ONLY
;
781 r
= pakfire_packagelist_create(&list
, self
->pakfire
);
783 PyErr_SetFromErrno(PyExc_OSError
);
787 r
= pakfire_search(self
->pakfire
, pattern
, flags
, list
);
789 PyErr_SetFromErrno(PyExc_OSError
);
793 ret
= PyList_FromPackageList(list
);
797 pakfire_packagelist_unref(list
);
802 static PyObject
* Pakfire_version_compare(PakfireObject
* self
, PyObject
* args
) {
803 const char* evr1
= NULL
;
804 const char* evr2
= NULL
;
806 if (!PyArg_ParseTuple(args
, "ss", &evr1
, &evr2
))
809 int cmp
= pakfire_version_compare(self
->pakfire
, evr1
, evr2
);
811 return PyLong_FromLong(cmp
);
814 static int Pakfire_execute_output_callback(struct pakfire
* pakfire
, void* data
,
815 int priority
, const char* line
, size_t length
) {
816 PyObject
* callback
= (PyObject
*)data
;
819 // Do nothing if callback isn't set
823 // Translate priority to Python logging priorities
834 // Remove the trailing newline
835 if (line
&& line
[length
- 1] == '\n')
838 // Create tuple with arguments for the callback function
839 PyObject
* args
= Py_BuildValue("(is#)", priority
, line
, (Py_ssize_t
)length
);
843 PyObject
* result
= PyObject_CallObject(callback
, args
);
844 if (result
&& PyLong_Check(result
)) {
845 r
= PyLong_AsLong(result
);
854 static PyObject
* Pakfire_execute(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
864 struct pakfire_jail
* jail
= NULL
;
865 const char** argv
= NULL
;
868 PyObject
* ret
= NULL
;
870 PyObject
* command
= NULL
;
871 PyObject
* environ
= NULL
;
872 PyObject
* bind
= NULL
;
873 PyObject
* callback
= NULL
;
876 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "O|OOOi", kwlist
, &command
, &environ
,
877 &bind
, &callback
, &nice
))
880 // Check if command is a list
881 if (!PyList_Check(command
)) {
882 PyErr_SetString(PyExc_TypeError
, "command must be a list");
886 const ssize_t command_length
= PyList_Size(command
);
888 // Check if command is not empty
889 if (command_length
== 0) {
890 PyErr_SetString(PyExc_ValueError
, "command is empty");
895 argv
= calloc(command_length
+ 1, sizeof(*argv
));
899 // All arguments in command must be strings
900 for (unsigned int i
= 0; i
< command_length
; i
++) {
901 PyObject
* item
= PyList_GET_ITEM(command
, i
);
903 if (!PyUnicode_Check(item
)) {
904 PyErr_Format(PyExc_TypeError
, "Item %u in command is not a string", i
);
909 argv
[i
] = PyUnicode_AsUTF8(item
);
912 // Check if bind is a sequence
913 if (bind
&& !PySequence_Check(bind
)) {
914 PyErr_SetString(PyExc_ValueError
, "bind is not a sequence");
919 if (callback
&& !PyCallable_Check(callback
)) {
920 PyErr_SetString(PyExc_TypeError
, "callback must be callable\n");
925 r
= pakfire_jail_create(&jail
, self
->pakfire
, flags
);
927 PyErr_SetFromErrno(PyExc_OSError
);
932 if (callback
&& !PyCallable_Check(callback
)) {
933 PyErr_SetString(PyExc_TypeError
, "callback must be callable\n");
939 r
= pakfire_jail_nice(jail
, nice
);
941 PyErr_SetFromErrno(PyExc_OSError
);
946 PyObject
* key
= NULL
;
947 PyObject
* value
= NULL
;
950 // Parse the environment
952 // Check if environ is a dictionary
953 if (!PyDict_Check(environ
)) {
954 PyErr_SetString(PyExc_TypeError
, "environ must be a dictionary");
958 // All keys and values must be strings
959 while (PyDict_Next(environ
, &p
, &key
, &value
)) {
960 if (!PyUnicode_Check(key
) || !PyUnicode_Check(value
)) {
961 PyErr_SetString(PyExc_TypeError
, "Environment contains a non-string object");
965 // Set environment value
966 r
= pakfire_jail_set_env(jail
, PyUnicode_AsUTF8(key
), PyUnicode_AsUTF8(value
));
968 PyErr_SetFromErrno(PyExc_OSError
);
974 const Py_ssize_t num_bind
= PySequence_Length(bind
);
977 for (unsigned int i
= 0; i
< num_bind
; i
++) {
978 PyObject
* b
= PySequence_ITEM(bind
, i
);
982 // Check if this is a Unicode object
983 if (!PyUnicode_Check(b
)) {
984 PyErr_SetString(PyExc_ValueError
, "bind contains a non-Unicode object");
989 const char* path
= PyUnicode_AsUTF8(b
);
992 r
= pakfire_jail_bind(jail
, path
, path
, 0);
994 PyErr_SetFromErrno(PyExc_OSError
);
1003 r
= pakfire_jail_exec(jail
, argv
,
1004 NULL
, Pakfire_execute_output_callback
, callback
);
1006 // If the return code was negative, we had some internal error
1008 PyErr_SetFromErrno(PyExc_OSError
);
1011 // Otherwise the executed command returned some error code
1013 PyObject
* code
= PyLong_FromLong(r
);
1015 // Raise CommandExecutionError
1016 PyErr_SetObject(PyExc_CommandExecutionError
, code
);
1022 // The process has exited successfully
1032 pakfire_jail_unref(jail
);
1037 static PyObject
* Pakfire_dist(PakfireObject
* self
, PyObject
* args
) {
1038 const char* path
= NULL
;
1039 const char* target
= NULL
;
1040 char* result
= NULL
;
1042 if (!PyArg_ParseTuple(args
, "s|z", &path
, &target
))
1045 int r
= pakfire_dist(self
->pakfire
, path
, target
, &result
);
1047 PyErr_SetFromErrno(PyExc_OSError
);
1051 PyObject
* ret
= PyUnicode_FromString(result
);
1057 static PyObject
* Pakfire_copy_in(PakfireObject
* self
, PyObject
* args
) {
1058 const char* src
= NULL
;
1059 const char* dst
= NULL
;
1061 if (!PyArg_ParseTuple(args
, "ss", &src
, &dst
))
1064 int r
= pakfire_copy_in(self
->pakfire
, src
, dst
);
1066 PyErr_SetFromErrno(PyExc_OSError
);
1073 static PyObject
* Pakfire_copy_out(PakfireObject
* self
, PyObject
* args
) {
1074 const char* src
= NULL
;
1075 const char* dst
= NULL
;
1077 if (!PyArg_ParseTuple(args
, "ss", &src
, &dst
))
1080 int r
= pakfire_copy_out(self
->pakfire
, src
, dst
);
1082 PyErr_SetFromErrno(PyExc_OSError
);
1089 static PyObject
* Pakfire_get_repos(PakfireObject
* self
) {
1090 struct pakfire_repolist
* repos
= pakfire_get_repos(self
->pakfire
);
1092 PyErr_SetFromErrno(PyExc_OSError
);
1096 const size_t l
= pakfire_repolist_size(repos
);
1098 PyObject
* list
= PyList_New(l
);
1102 for (unsigned int i
= 0; i
< l
; i
++) {
1103 struct pakfire_repo
* repo
= pakfire_repolist_get(repos
, i
);
1107 PyObject
* obj
= new_repo(&RepoType
, repo
);
1108 PyList_SET_ITEM(list
, i
, obj
);
1110 pakfire_repo_unref(repo
);
1114 pakfire_repolist_unref(repos
);
1119 static PyObject
* execute_return_value(int r
) {
1120 // Raise an OS error if r < 0
1124 PyErr_SetFromErrno(PyExc_OSError
);
1127 // Raise exception when the command failed
1129 PyObject
* code
= PyLong_FromLong(r
);
1131 PyErr_SetObject(PyExc_CommandExecutionError
, code
);
1140 static PyObject
* Pakfire_build(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1152 const char* path
= NULL
;
1153 const char* target
= NULL
;
1154 const char* build_id
= NULL
;
1155 int interactive
= 0;
1156 int disable_snapshot
= 0;
1157 int disable_ccache
= 0;
1158 int disable_tests
= 0;
1160 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zzpppp", kwlist
, &path
, &target
,
1161 &build_id
, &interactive
, &disable_snapshot
, &disable_ccache
, &disable_tests
))
1167 flags
|= PAKFIRE_BUILD_INTERACTIVE
;
1169 // Disable snapshot if requested
1170 if (disable_snapshot
)
1171 flags
|= PAKFIRE_BUILD_DISABLE_SNAPSHOT
;
1173 // Disable ccache if requested
1175 flags
|= PAKFIRE_BUILD_DISABLE_CCACHE
;
1177 // Disable tests if requested
1179 flags
|= PAKFIRE_BUILD_DISABLE_TESTS
;
1182 int r
= pakfire_build(self
->pakfire
, path
, target
, build_id
, flags
);
1184 return execute_return_value(r
);
1187 static PyObject
* Pakfire_shell(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1193 char** packages
= NULL
;
1194 int disable_snapshot
= 0;
1197 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|O&p", kwlist
,
1198 convert_packages
, &packages
, &disable_snapshot
))
1203 if (disable_snapshot
)
1204 flags
|= PAKFIRE_BUILD_DISABLE_SNAPSHOT
;
1206 int r
= pakfire_shell(self
->pakfire
, (const char**)packages
, flags
);
1208 return execute_return_value(r
);
1211 static PyObject
* Pakfire_clean(PakfireObject
* self
) {
1212 int r
= pakfire_clean(self
->pakfire
, 0);
1214 PyErr_SetFromErrno(PyExc_OSError
);
1221 static PyObject
* Pakfire_refresh(PakfireObject
* self
, PyObject
* args
) {
1224 if (!PyArg_ParseTuple(args
, "|p", &force
))
1227 int r
= pakfire_refresh(self
->pakfire
, force
);
1229 PyErr_SetFromErrno(PyExc_OSError
);
1236 static PyObject
* Pakfire_check(PakfireObject
* self
) {
1237 struct pakfire_filelist
* errors
= NULL
;
1240 // Allocate a filelist for errors
1241 r
= pakfire_filelist_create(&errors
, self
->pakfire
);
1246 r
= pakfire_check(self
->pakfire
, errors
);
1250 const size_t num_errors
= pakfire_filelist_length(errors
);
1252 // Did we find any errors?
1254 PyObject
* _errors
= PyList_FromFileList(errors
);
1258 pakfire_filelist_unref(errors
);
1260 // Raise CheckFileVerificationError
1261 PyErr_SetObject(PyExc_CheckFileVerificationError
, _errors
);
1266 pakfire_filelist_unref(errors
);
1272 pakfire_filelist_unref(errors
);
1274 // Raise exception from errno
1275 PyErr_SetFromErrno(PyExc_OSError
);
1279 static PyObject
* Pakfire_sync(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1285 int keep_orphaned
= 0;
1287 PyObject
* status_callback
= NULL
;
1289 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|$pO", kwlist
,
1290 &keep_orphaned
, &status_callback
))
1294 flags
|= PAKFIRE_REQUEST_KEEP_ORPHANED
;
1296 int r
= pakfire_sync(self
->pakfire
, 0, flags
, NULL
,
1297 Pakfire_status_callback
, status_callback
);
1299 PyErr_SetFromErrno(PyExc_OSError
);
1306 static PyObject
* Pakfire_open(PakfireObject
* self
, PyObject
* args
) {
1307 struct pakfire_archive
* archive
= NULL
;
1308 const char* path
= NULL
;
1310 if (!PyArg_ParseTuple(args
, "s", &path
))
1313 int r
= pakfire_archive_open(&archive
, self
->pakfire
, path
);
1315 PyErr_SetFromErrno(PyExc_OSError
);
1319 // Create Python object
1320 PyObject
* object
= new_archive(&ArchiveType
, archive
);
1321 pakfire_archive_unref(archive
);
1326 static PyObject
* Pakfire_repo_compose(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1327 char* kwlist
[] = { "path", "files", NULL
};
1328 const char* path
= NULL
;
1329 PyObject
* list
= NULL
;
1331 PyObject
* ret
= NULL
;
1333 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "sO", kwlist
, &path
, &list
))
1336 // List must be a sequence
1337 if (!PySequence_Check(list
)) {
1338 PyErr_SetString(PyExc_ValueError
, "Expected a sequence.");
1342 const int flags
= 0;
1344 // How many new files do we have?
1345 ssize_t num_files
= PySequence_Length(list
);
1349 // Allocate files array
1350 const char** files
= calloc(num_files
+ 1, sizeof(*files
));
1352 PyErr_SetFromErrno(PyExc_OSError
);
1356 for (int i
= 0; i
< num_files
; i
++) {
1357 PyObject
* file
= PySequence_GetItem(list
, i
);
1361 // Check if file is a Unicode object
1362 if (!PyUnicode_Check(file
)) {
1363 PyErr_SetString(PyExc_ValueError
, "Expected a string.");
1367 // Add pointer to string to files array
1368 files
[i
] = PyUnicode_AsUTF8(file
);
1375 int r
= pakfire_repo_compose(self
->pakfire
, path
, flags
, files
);
1377 PyErr_SetFromErrno(PyExc_OSError
);
1381 // Return None on success
1392 static struct PyMethodDef Pakfire_methods
[] = {
1395 (PyCFunction
)Pakfire_build
,
1396 METH_VARARGS
|METH_KEYWORDS
,
1401 (PyCFunction
)Pakfire_check
,
1407 (PyCFunction
)Pakfire_clean
,
1413 (PyCFunction
)Pakfire_copy_in
,
1419 (PyCFunction
)Pakfire_copy_out
,
1425 (PyCFunction
)Pakfire_dist
,
1431 (PyCFunction
)Pakfire_erase
,
1432 METH_VARARGS
|METH_KEYWORDS
,
1437 (PyCFunction
)Pakfire_execute
,
1438 METH_VARARGS
|METH_KEYWORDS
,
1443 (PyCFunction
)Pakfire_fetch_key
,
1444 METH_VARARGS
|METH_KEYWORDS
,
1449 (PyCFunction
)Pakfire_generate_key
,
1450 METH_VARARGS
|METH_KEYWORDS
,
1455 (PyCFunction
)Pakfire_get_key
,
1461 (PyCFunction
)Pakfire_get_repo
,
1467 (PyCFunction
)Pakfire_import_key
,
1473 (PyCFunction
)Pakfire_install
,
1474 METH_VARARGS
|METH_KEYWORDS
,
1479 (PyCFunction
)Pakfire_open
,
1485 (PyCFunction
)Pakfire_refresh
,
1491 (PyCFunction
)Pakfire_repo_compose
,
1492 METH_VARARGS
|METH_KEYWORDS
,
1497 (PyCFunction
)Pakfire_search
,
1498 METH_VARARGS
|METH_KEYWORDS
,
1503 (PyCFunction
)Pakfire_shell
,
1504 METH_VARARGS
|METH_KEYWORDS
,
1509 (PyCFunction
)Pakfire_sync
,
1510 METH_VARARGS
|METH_KEYWORDS
,
1515 (PyCFunction
)Pakfire_update
,
1516 METH_VARARGS
|METH_KEYWORDS
,
1521 (PyCFunction
)Pakfire_version_compare
,
1527 (PyCFunction
)Pakfire_whatprovides
,
1533 (PyCFunction
)Pakfire_whatrequires
,
1540 static struct PyGetSetDef Pakfire_getsetters
[] = {
1543 (getter
)Pakfire_get_arch
,
1550 (getter
)Pakfire_get_keys
,
1557 (getter
)Pakfire_get_path
,
1564 (getter
)Pakfire_get_repos
,
1572 PyTypeObject PakfireType
= {
1573 PyVarObject_HEAD_INIT(NULL
, 0)
1574 tp_name
: "_pakfire.Pakfire",
1575 tp_basicsize
: sizeof(PakfireObject
),
1576 tp_flags
: Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
1577 tp_new
: Pakfire_new
,
1578 tp_dealloc
: (destructor
)Pakfire_dealloc
,
1579 tp_init
: (initproc
)Pakfire_init
,
1580 tp_doc
: "Pakfire object",
1581 tp_methods
: Pakfire_methods
,
1582 tp_getset
: Pakfire_getsetters
,
1583 tp_repr
: (reprfunc
)Pakfire_repr
,