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/packagelist.h>
32 #include <pakfire/pakfire.h>
33 #include <pakfire/key.h>
34 #include <pakfire/repo.h>
35 #include <pakfire/repolist.h>
36 #include <pakfire/request.h>
37 #include <pakfire/util.h>
46 static PyObject
* Pakfire_new(PyTypeObject
* type
, PyObject
* args
, PyObject
* kwds
) {
47 PakfireObject
* self
= (PakfireObject
*)type
->tp_alloc(type
, 0);
52 self
->callbacks
.log
= NULL
;
53 self
->callbacks
.status
= NULL
;
54 self
->callbacks
.progress
= 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 struct callbacks
* callbacks
= (struct callbacks
*)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(callbacks
->log
, tuple
);
111 static void Pakfire_status_callback(void* data
, const char* message
) {
112 struct callbacks
* callbacks
= (struct callbacks
*)data
;
114 // Do nothing if callback isn't set
115 if (!callbacks
->status
)
118 PyObject
* args
= NULL
;
119 PyObject
* result
= NULL
;
121 // Create arguments tuple
122 args
= Py_BuildValue("(s)", message
);
127 result
= PyObject_CallObject(callbacks
->status
, args
);
134 static void Pakfire_progress_callback(void* data
, int progress
) {
135 struct callbacks
* callbacks
= (struct callbacks
*)data
;
137 // Do nothing if callback isn't set
138 if (!callbacks
->progress
)
141 PyObject
* args
= NULL
;
142 PyObject
* result
= NULL
;
144 // Create arguments tuple
145 args
= Py_BuildValue("(i)", progress
);
150 result
= PyObject_CallObject(callbacks
->progress
, args
);
157 static int Pakfire_init(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
158 char* kwlist
[] = { "path", "arch", "logger", "interactive", "offline", "conf", "build",
159 "enable_ccache", "enable_snapshot", "status_callback", "progress_callback", NULL
};
160 const char* path
= NULL
;
161 const char* arch
= NULL
;
162 const char* conf
= NULL
;
166 int enable_ccache
= 1;
167 int enable_snapshot
= 1;
169 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "|zzOppzpppOO", kwlist
,
170 &path
, &arch
, &self
->callbacks
.log
, &interactive
, &offline
, &conf
, &build
,
171 &enable_ccache
, &enable_snapshot
, &self
->callbacks
.status
,
172 &self
->callbacks
.progress
))
175 // Check if log callback is callable
176 if (self
->callbacks
.log
&& !PyCallable_Check(self
->callbacks
.log
)) {
177 PyErr_SetString(PyExc_TypeError
, "logger must be callable\n");
181 // Check if status callback is callable
182 if (self
->callbacks
.status
&& !PyCallable_Check(self
->callbacks
.status
)) {
183 PyErr_SetString(PyExc_TypeError
, "status callback must be callable\n");
187 // Check if progress callback is callable
188 if (self
->callbacks
.progress
&& !PyCallable_Check(self
->callbacks
.progress
)) {
189 PyErr_SetString(PyExc_TypeError
, "progress callback must be callable\n");
195 // Enable interactive mode
197 flags
|= PAKFIRE_FLAGS_INTERACTIVE
;
199 // Enable offline mode
201 flags
|= PAKFIRE_FLAGS_OFFLINE
;
205 flags
|= PAKFIRE_FLAGS_BUILD
;
208 flags
|= PAKFIRE_FLAGS_DISABLE_CCACHE
;
210 if (!enable_snapshot
)
211 flags
|= PAKFIRE_FLAGS_DISABLE_SNAPSHOT
;
214 // Configure callbacks
215 struct pakfire_callbacks callbacks
= {
216 .data
= &self
->callbacks
,
219 if (self
->callbacks
.log
) {
220 callbacks
.log
= Pakfire_log_callback
;
221 Py_INCREF(self
->callbacks
.log
);
224 if (self
->callbacks
.status
) {
225 callbacks
.status
= Pakfire_status_callback
;
226 Py_INCREF(self
->callbacks
.status
);
229 if (self
->callbacks
.progress
) {
230 callbacks
.progress
= Pakfire_progress_callback
;
231 Py_INCREF(self
->callbacks
.progress
);
234 // Create a new Pakfire instance
235 int r
= pakfire_create(&self
->pakfire
, path
, arch
, conf
, flags
, &callbacks
);
238 // Invalid architecture or path
240 PyErr_SetString(PyExc_ValueError
, "Invalid architecture or path");
245 PyErr_SetFromErrno(PyExc_OSError
);
254 static void Pakfire_dealloc(PakfireObject
* self
) {
256 pakfire_unref(self
->pakfire
);
260 It might happen, that the Pakfire python object is deallocated but the
261 actual struct pakfire object isn't yet. However, it might still happen
262 that the logging function is called which will try to call the logging
263 callback which has already been deallocated.
265 TODO This has to move into struct pakfire or something similar.
267 Py_XDECREF(self
->callbacks
.log
);
268 Py_XDECREF(self
->callbacks
.status
);
269 Py_XDECREF(self
->callbacks
.progress
);
272 Py_TYPE(self
)->tp_free((PyObject
*)self
);
275 static PyObject
* Pakfire_repr(PakfireObject
* self
) {
276 const char* path
= pakfire_get_path(self
->pakfire
);
277 const char* arch
= pakfire_get_arch(self
->pakfire
);
279 return PyUnicode_FromFormat("<_pakfire.Pakfire %s (%s)>", path
, arch
);
282 static PyObject
* Pakfire_get_path(PakfireObject
* self
) {
283 const char* path
= pakfire_get_path(self
->pakfire
);
285 return PyUnicode_FromString(path
);
288 static PyObject
* Pakfire_get_arch(PakfireObject
* self
) {
289 const char* arch
= pakfire_get_arch(self
->pakfire
);
291 return PyUnicode_FromString(arch
);
294 static PyObject
* Pakfire_get_repo(PakfireObject
* self
, PyObject
* args
) {
295 const char* name
= NULL
;
297 if (!PyArg_ParseTuple(args
, "s", &name
))
300 struct pakfire_repo
* repo
= pakfire_get_repo(self
->pakfire
, name
);
304 PyObject
* obj
= new_repo(&RepoType
, repo
);
305 pakfire_repo_unref(repo
);
310 static int convert_packages(PyObject
* object
, void* address
) {
311 char*** packages
= (char***)address
;
313 // Called for cleanup
317 if (!PySequence_Check(object
)) {
318 PyErr_SetString(PyExc_ValueError
, "Packages must be a sequence");
322 const unsigned int length
= PySequence_Length(object
);
324 return Py_CLEANUP_SUPPORTED
;
327 *packages
= calloc(length
+ 1, sizeof(*packages
));
329 PyErr_SetFromErrno(PyExc_OSError
);
333 for (unsigned int i
= 0; i
< length
; i
++) {
334 PyObject
* item
= PySequence_GetItem(object
, i
);
336 // Check if input is a string
337 if (!PyUnicode_Check(item
)) {
340 PyErr_SetString(PyExc_AttributeError
, "Expected a string");
345 const char* package
= PyUnicode_AsUTF8(item
);
351 // Add package to array
352 (*packages
)[i
] = strdup(package
);
353 if (!(*packages
)[i
]) {
362 return Py_CLEANUP_SUPPORTED
;
366 for (char** package
= *packages
; *package
; package
++)
374 static PyObject
* Pakfire_install(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
377 "without_recommended",
382 char** packages
= NULL
;
383 int without_recommended
= 0;
384 int allow_uninstall
= 0;
385 int allow_downgrade
= 0;
386 int solver_flags
= 0;
388 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O&|$ppp", kwlist
,
389 convert_packages
, &packages
, &without_recommended
, &allow_uninstall
,
393 // Do not install recommended packages
394 if (without_recommended
)
395 solver_flags
|= PAKFIRE_REQUEST_WITHOUT_RECOMMENDED
;
397 // Can the solver uninstall packages?
399 solver_flags
|= PAKFIRE_REQUEST_ALLOW_UNINSTALL
;
401 // Can the solver downgrade packages?
403 solver_flags
|= PAKFIRE_REQUEST_ALLOW_DOWNGRADE
;
405 // Run pakfire_install
406 int r
= pakfire_install(self
->pakfire
, solver_flags
, (const char**)packages
, NULL
, 0, NULL
);
408 PyErr_SetFromErrno(PyExc_OSError
);
411 for (char** package
= packages
; *package
; package
++)
422 static PyObject
* Pakfire_erase(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
428 char** packages
= NULL
;
429 int keep_dependencies
= 0;
432 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O&|$p", kwlist
,
433 convert_packages
, &packages
, &keep_dependencies
))
436 if (keep_dependencies
)
437 flags
|= PAKFIRE_REQUEST_KEEP_DEPS
;
440 int r
= pakfire_erase(self
->pakfire
, 0, (const char**)packages
, NULL
, flags
, NULL
);
442 PyErr_SetFromErrno(PyExc_OSError
);
445 for (char** package
= packages
; *package
; package
++)
456 static PyObject
* Pakfire_update(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
464 char** packages
= NULL
;
465 char** excludes
= NULL
;
466 int allow_uninstall
= 0;
467 int allow_downgrade
= 0;
468 int solver_flags
= 0;
470 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O&|$O&pp", kwlist
,
471 convert_packages
, &packages
, convert_packages
, &excludes
,
472 &allow_uninstall
, &allow_downgrade
))
475 // Can the solver uninstall packages?
477 solver_flags
|= PAKFIRE_REQUEST_ALLOW_UNINSTALL
;
479 // Can the solver downgrade packages?
481 solver_flags
|= PAKFIRE_REQUEST_ALLOW_DOWNGRADE
;
483 // Run pakfire_update
484 int r
= pakfire_update(self
->pakfire
, solver_flags
, (const char**)packages
,
485 (const char**)excludes
, 0, NULL
);
487 PyErr_SetFromErrno(PyExc_OSError
);
490 for (char** package
= packages
; *package
; package
++)
496 for (char** exclude
= excludes
; *exclude
; exclude
++)
507 static PyObject
* Pakfire_keys_to_list(struct pakfire_key
** keys
) {
508 PyObject
* list
= PyList_New(0);
514 // Push all keys onto the list
515 for (struct pakfire_key
** key
= keys
; *key
; key
++) {
516 PyObject
* object
= new_key(&KeyType
, *key
);
520 PyList_Append(list
, object
);
531 static PyObject
* Pakfire_get_keys(PakfireObject
* self
) {
532 struct pakfire_key
** keys
= NULL
;
534 int r
= pakfire_list_keys(self
->pakfire
, &keys
);
536 PyErr_SetFromErrno(PyExc_OSError
);
540 // Convert keys to list
541 PyObject
* list
= Pakfire_keys_to_list(keys
);
545 for (struct pakfire_key
** key
= keys
; *key
; key
++)
546 pakfire_key_unref(*key
);
553 static PyObject
* Pakfire_get_key(PakfireObject
* self
, PyObject
* args
) {
554 const char* pattern
= NULL
;
556 if (!PyArg_ParseTuple(args
, "s", &pattern
))
559 // Try finding the key
560 struct pakfire_key
* key
= pakfire_key_get(self
->pakfire
, pattern
);
564 PyObject
* object
= new_key(&KeyType
, key
);
565 pakfire_key_unref(key
);
570 static PyObject
* Pakfire_generate_key(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
571 char* kwlist
[] = { "userid", "algorithm", NULL
};
572 struct pakfire_key
* key
= NULL
;
573 const char* userid
= NULL
;
574 const char* algo
= NULL
;
576 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s|$z", kwlist
, &userid
, &algo
))
579 // Generate a new key
580 int r
= pakfire_key_generate(&key
, self
->pakfire
, algo
, userid
);
582 PyErr_SetFromErrno(PyExc_OSError
);
586 PyObject
* object
= new_key(&KeyType
, key
);
587 pakfire_key_unref(key
);
592 static PyObject
* Pakfire_import_key(PakfireObject
* self
, PyObject
* args
) {
593 PyObject
* object
= NULL
;
595 if (!PyArg_ParseTuple(args
, "O", &object
))
598 // Get a file descriptor from object
599 int fd
= PyObject_AsFileDescriptor(object
);
604 FILE* f
= fdopen(fd
, "r");
606 PyErr_SetFromErrno(PyExc_OSError
);
610 struct pakfire_key
** keys
= NULL
;
612 // Import keys from f
613 int r
= pakfire_key_import(self
->pakfire
, f
, &keys
);
615 PyErr_SetFromErrno(PyExc_OSError
);
619 // Convert keys to list
620 PyObject
* list
= Pakfire_keys_to_list(keys
);
623 for (struct pakfire_key
** key
= keys
; *key
; key
++)
624 pakfire_key_unref(*key
);
630 static PyObject
* Pakfire_fetch_key(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
631 char* kwlist
[] = { "userid", "fingerprint", NULL
};
632 struct pakfire_key
* key
= NULL
;
633 const char* userid
= NULL
;
634 const char* fingerprint
= NULL
;
636 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "|$zz", kwlist
, &userid
, &fingerprint
))
640 int r
= pakfire_key_fetch(&key
, self
->pakfire
, userid
, fingerprint
);
642 PyErr_SetFromErrno(PyExc_OSError
);
648 PyObject
* object
= new_key(&KeyType
, key
);
649 pakfire_key_unref(key
);
657 static PyObject
* Pakfire_whatprovides(PakfireObject
* self
, PyObject
* args
) {
658 const char* provides
= NULL
;
659 struct pakfire_packagelist
* list
= NULL
;
661 if (!PyArg_ParseTuple(args
, "s", &provides
))
664 int r
= pakfire_whatprovides(self
->pakfire
, provides
, 0, &list
);
666 PyErr_SetFromErrno(PyExc_OSError
);
670 PyObject
* obj
= PyList_FromPackageList(list
);
671 pakfire_packagelist_unref(list
);
676 static PyObject
* Pakfire_whatrequires(PakfireObject
* self
, PyObject
* args
) {
677 const char* requires
= NULL
;
678 struct pakfire_packagelist
* list
= NULL
;
680 if (!PyArg_ParseTuple(args
, "s", &requires
))
683 int r
= pakfire_whatrequires(self
->pakfire
, requires
, 0, &list
);
685 PyErr_SetFromErrno(PyExc_OSError
);
689 PyObject
* obj
= PyList_FromPackageList(list
);
690 pakfire_packagelist_unref(list
);
695 static PyObject
* Pakfire_search(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
696 char* kwlist
[] = { "pattern", "name_only", NULL
};
697 struct pakfire_packagelist
* list
= NULL
;
698 const char* pattern
= NULL
;
702 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s|$p", kwlist
, &pattern
, &name_only
))
705 // Search for package names only
707 flags
|= PAKFIRE_SEARCH_NAME_ONLY
;
709 int r
= pakfire_search(self
->pakfire
, pattern
, flags
, &list
);
711 PyErr_SetFromErrno(PyExc_OSError
);
715 PyObject
* obj
= PyList_FromPackageList(list
);
716 pakfire_packagelist_unref(list
);
721 static PyObject
* Pakfire_version_compare(PakfireObject
* self
, PyObject
* args
) {
722 const char* evr1
= NULL
;
723 const char* evr2
= NULL
;
725 if (!PyArg_ParseTuple(args
, "ss", &evr1
, &evr2
))
728 int cmp
= pakfire_version_compare(self
->pakfire
, evr1
, evr2
);
730 return PyLong_FromLong(cmp
);
733 static PyObject
* Pakfire_execute_logging_callback
= NULL
;
735 static int __Pakfire_execute_logging_callback(struct pakfire
* pakfire
, void* data
,
736 int priority
, const char* line
, size_t length
) {
739 // Do nothing if callback isn't set
740 if (!Pakfire_execute_logging_callback
)
743 // Translate priority to Python logging priorities
754 // Remove the trailing newline
755 if (line
&& line
[length
- 1] == '\n')
758 // Create tuple with arguments for the callback function
759 PyObject
* args
= Py_BuildValue("(is#)", priority
, line
, (Py_ssize_t
)length
);
763 PyObject
* result
= PyObject_CallObject(Pakfire_execute_logging_callback
, args
);
764 if (result
&& PyLong_Check(result
)) {
765 r
= PyLong_AsLong(result
);
774 static PyObject
* Pakfire_execute(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
775 char* kwlist
[] = {"command", "environ", "enable_network", "interactive",
776 "logging_callback", NULL
};
778 PyObject
* command
= NULL
;
779 PyObject
* environ
= NULL
;
780 int enable_network
= 0;
782 PyObject
* logging_callback
= NULL
;
784 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "O|OppO", kwlist
, &command
, &environ
,
785 &enable_network
, &interactive
, &logging_callback
))
788 // Check if command is a list
789 if (!PyList_Check(command
)) {
790 PyErr_SetString(PyExc_TypeError
, "command must be a list");
794 ssize_t command_length
= PyList_Size(command
);
796 // Check if command is not empty
797 if (command_length
== 0) {
798 PyErr_SetString(PyExc_ValueError
, "command is empty");
802 // All arguments in command must be strings
803 for (unsigned int i
= 0; i
< command_length
; i
++) {
804 PyObject
* item
= PyList_GET_ITEM(command
, i
);
806 if (!PyUnicode_Check(item
)) {
807 PyErr_Format(PyExc_TypeError
, "Item %u in command is not a string", i
);
812 // Check if logging_callback is
813 if (logging_callback
&& !PyCallable_Check(logging_callback
)) {
814 PyErr_SetString(PyExc_TypeError
, "logging_callback must be callable\n");
818 ssize_t environ_length
= 0;
824 // Check if environ is a dictionary
825 if (!PyDict_Check(environ
)) {
826 PyErr_SetString(PyExc_TypeError
, "environ must be a dictionary");
830 // All keys and values must be strings
831 while (PyDict_Next(environ
, &p
, &key
, &value
)) {
832 if (!PyUnicode_Check(key
) || !PyUnicode_Check(value
)) {
833 PyErr_SetString(PyExc_TypeError
, "Environment contains a non-string object");
838 environ_length
= PyDict_Size(environ
);
841 // All inputs look fine
843 const char* argv
[command_length
+ 1];
844 char* envp
[environ_length
+ 1];
848 for (unsigned int i
= 0; i
< command_length
; i
++) {
849 PyObject
* item
= PyList_GET_ITEM(command
, i
);
850 argv
[i
] = PyUnicode_AsUTF8(item
);
858 while (PyDict_Next(environ
, &p
, &key
, &value
)) {
859 int r
= asprintf(&envp
[i
++], "%s=%s",
860 PyUnicode_AsUTF8(key
), PyUnicode_AsUTF8(value
));
865 for (unsigned int i
= 0; envp
[i
]; i
++)
868 return PyErr_NoMemory();
873 // Terminate argv and envp
874 argv
[command_length
] = NULL
;
875 envp
[environ_length
] = NULL
;
879 flags
|= PAKFIRE_EXECUTE_ENABLE_NETWORK
;
883 flags
|= PAKFIRE_EXECUTE_INTERACTIVE
;
885 // Set logging callback
886 Pakfire_execute_logging_callback
= logging_callback
;
889 int r
= pakfire_execute(self
->pakfire
, argv
, envp
, flags
,
890 (logging_callback
) ? __Pakfire_execute_logging_callback
: NULL
, NULL
);
893 for (unsigned int i
= 0; envp
[i
]; i
++)
896 // Raise an OS error if r < 0
900 PyErr_SetFromErrno(PyExc_OSError
);
903 // Raise exception when the command failed
905 PyObject
* code
= PyLong_FromLong(r
);
907 PyErr_SetObject(PyExc_CommandExecutionError
, code
);
917 static PyObject
* Pakfire_dist(PakfireObject
* self
, PyObject
* args
) {
918 const char* path
= NULL
;
919 const char* target
= NULL
;
922 if (!PyArg_ParseTuple(args
, "s|z", &path
, &target
))
925 int r
= pakfire_dist(self
->pakfire
, path
, target
, &result
);
927 PyErr_SetFromErrno(PyExc_OSError
);
931 PyObject
* ret
= PyUnicode_FromString(result
);
937 static PyObject
* Pakfire_bind(PakfireObject
* self
, PyObject
* args
) {
938 const char* src
= NULL
;
939 const char* dst
= NULL
;
941 if (!PyArg_ParseTuple(args
, "s|z", &src
, &dst
))
944 int r
= pakfire_bind(self
->pakfire
, src
, dst
, 0);
946 PyErr_SetFromErrno(PyExc_OSError
);
953 static PyObject
* Pakfire_copy_in(PakfireObject
* self
, PyObject
* args
) {
954 const char* src
= NULL
;
955 const char* dst
= NULL
;
957 if (!PyArg_ParseTuple(args
, "ss", &src
, &dst
))
960 int r
= pakfire_copy_in(self
->pakfire
, src
, dst
);
962 PyErr_SetFromErrno(PyExc_OSError
);
969 static PyObject
* Pakfire_copy_out(PakfireObject
* self
, PyObject
* args
) {
970 const char* src
= NULL
;
971 const char* dst
= NULL
;
973 if (!PyArg_ParseTuple(args
, "ss", &src
, &dst
))
976 int r
= pakfire_copy_out(self
->pakfire
, src
, dst
);
978 PyErr_SetFromErrno(PyExc_OSError
);
985 static PyObject
* Pakfire_get_repos(PakfireObject
* self
) {
986 struct pakfire_repolist
* repos
= pakfire_get_repos(self
->pakfire
);
988 PyErr_SetFromErrno(PyExc_OSError
);
992 const size_t l
= pakfire_repolist_size(repos
);
994 PyObject
* list
= PyList_New(l
);
998 for (unsigned int i
= 0; i
< l
; i
++) {
999 struct pakfire_repo
* repo
= pakfire_repolist_get(repos
, i
);
1003 PyObject
* obj
= new_repo(&RepoType
, repo
);
1004 PyList_SET_ITEM(list
, i
, obj
);
1006 pakfire_repo_unref(repo
);
1010 pakfire_repolist_unref(repos
);
1015 static PyObject
* execute_return_value(int r
) {
1016 // Raise an OS error if r < 0
1020 PyErr_SetFromErrno(PyExc_OSError
);
1023 // Raise exception when the command failed
1025 PyObject
* code
= PyLong_FromLong(r
);
1027 PyErr_SetObject(PyExc_CommandExecutionError
, code
);
1036 static PyObject
* Pakfire_build(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1037 char* kwlist
[] = { "path", "build_id", "logging_callback", "interactive", NULL
};
1039 const char* path
= NULL
;
1040 const char* build_id
= NULL
;
1041 PyObject
* logging_callback
= NULL
;
1042 int interactive
= 0;
1044 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zOp", kwlist
, &path
,
1045 &build_id
, &logging_callback
, &interactive
))
1050 // Enable interactive mode
1052 flags
|= PAKFIRE_BUILD_INTERACTIVE
;
1054 // Check if logging_callback is
1055 if (logging_callback
&& !PyCallable_Check(logging_callback
)) {
1056 PyErr_SetString(PyExc_TypeError
, "logging_callback must be callable\n");
1060 // Set logging callback
1061 Pakfire_execute_logging_callback
= logging_callback
;
1064 int r
= pakfire_build(self
->pakfire
, path
, NULL
, build_id
, flags
,
1065 (logging_callback
) ? __Pakfire_execute_logging_callback
: NULL
, NULL
);
1067 return execute_return_value(r
);
1070 static PyObject
* Pakfire_shell(PakfireObject
* self
) {
1071 int r
= pakfire_shell(self
->pakfire
);
1073 return execute_return_value(r
);
1076 static PyObject
* Pakfire_clean(PakfireObject
* self
) {
1077 int r
= pakfire_clean(self
->pakfire
, 0);
1079 PyErr_SetFromErrno(PyExc_OSError
);
1086 static PyObject
* Pakfire_refresh(PakfireObject
* self
, PyObject
* args
) {
1089 if (!PyArg_ParseTuple(args
, "|p", &force
))
1092 int r
= pakfire_refresh(self
->pakfire
, force
);
1094 PyErr_SetFromErrno(PyExc_OSError
);
1101 static PyObject
* Pakfire_check(PakfireObject
* self
) {
1102 int r
= pakfire_check(self
->pakfire
);
1104 PyErr_SetFromErrno(PyExc_OSError
);
1111 static PyObject
* Pakfire_sync(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1112 char* kwlist
[] = {"keep_orphaned", NULL
};
1113 int keep_orphaned
= 0;
1116 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|$p", kwlist
, &keep_orphaned
))
1120 flags
|= PAKFIRE_REQUEST_KEEP_ORPHANED
;
1122 int r
= pakfire_sync(self
->pakfire
, 0, flags
, NULL
);
1124 PyErr_SetFromErrno(PyExc_OSError
);
1131 static PyObject
* Pakfire_open(PakfireObject
* self
, PyObject
* args
) {
1132 struct pakfire_archive
* archive
= NULL
;
1133 const char* path
= NULL
;
1135 if (!PyArg_ParseTuple(args
, "s", &path
))
1138 int r
= pakfire_archive_open(&archive
, self
->pakfire
, path
);
1140 PyErr_SetFromErrno(PyExc_OSError
);
1144 // Create Python object
1145 PyObject
* object
= new_archive(&ArchiveType
, archive
);
1146 pakfire_archive_unref(archive
);
1151 static PyObject
* Pakfire_repo_compose(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1152 char* kwlist
[] = { "path", "files", NULL
};
1153 const char* path
= NULL
;
1154 PyObject
* list
= NULL
;
1156 PyObject
* ret
= NULL
;
1158 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "sO", kwlist
, &path
, &list
))
1161 // List must be a sequence
1162 if (!PySequence_Check(list
)) {
1163 PyErr_SetString(PyExc_ValueError
, "Expected a sequence.");
1167 const int flags
= 0;
1169 // How many new files do we have?
1170 ssize_t num_files
= PySequence_Length(list
);
1174 // Allocate files array
1175 const char** files
= calloc(num_files
+ 1, sizeof(*files
));
1177 PyErr_SetFromErrno(PyExc_OSError
);
1181 for (int i
= 0; i
< num_files
; i
++) {
1182 PyObject
* file
= PySequence_GetItem(list
, i
);
1186 // Check if file is a Unicode object
1187 if (!PyUnicode_Check(file
)) {
1188 PyErr_SetString(PyExc_ValueError
, "Expected a string.");
1192 // Add pointer to string to files array
1193 files
[i
] = PyUnicode_AsUTF8(file
);
1200 int r
= pakfire_repo_compose(self
->pakfire
, path
, flags
, files
);
1202 PyErr_SetFromErrno(PyExc_OSError
);
1206 // Return None on success
1217 static struct PyMethodDef Pakfire_methods
[] = {
1220 (PyCFunction
)Pakfire_bind
,
1226 (PyCFunction
)Pakfire_build
,
1227 METH_VARARGS
|METH_KEYWORDS
,
1232 (PyCFunction
)Pakfire_check
,
1238 (PyCFunction
)Pakfire_clean
,
1244 (PyCFunction
)Pakfire_copy_in
,
1250 (PyCFunction
)Pakfire_copy_out
,
1256 (PyCFunction
)Pakfire_dist
,
1262 (PyCFunction
)Pakfire_erase
,
1263 METH_VARARGS
|METH_KEYWORDS
,
1268 (PyCFunction
)Pakfire_execute
,
1269 METH_VARARGS
|METH_KEYWORDS
,
1274 (PyCFunction
)Pakfire_fetch_key
,
1275 METH_VARARGS
|METH_KEYWORDS
,
1280 (PyCFunction
)Pakfire_generate_key
,
1281 METH_VARARGS
|METH_KEYWORDS
,
1286 (PyCFunction
)Pakfire_get_key
,
1292 (PyCFunction
)Pakfire_get_repo
,
1298 (PyCFunction
)Pakfire_import_key
,
1304 (PyCFunction
)Pakfire_install
,
1305 METH_VARARGS
|METH_KEYWORDS
,
1310 (PyCFunction
)Pakfire_open
,
1316 (PyCFunction
)Pakfire_refresh
,
1322 (PyCFunction
)Pakfire_repo_compose
,
1323 METH_VARARGS
|METH_KEYWORDS
,
1328 (PyCFunction
)Pakfire_search
,
1329 METH_VARARGS
|METH_KEYWORDS
,
1334 (PyCFunction
)Pakfire_shell
,
1340 (PyCFunction
)Pakfire_sync
,
1341 METH_VARARGS
|METH_KEYWORDS
,
1346 (PyCFunction
)Pakfire_update
,
1347 METH_VARARGS
|METH_KEYWORDS
,
1352 (PyCFunction
)Pakfire_version_compare
,
1358 (PyCFunction
)Pakfire_whatprovides
,
1364 (PyCFunction
)Pakfire_whatrequires
,
1371 static struct PyGetSetDef Pakfire_getsetters
[] = {
1374 (getter
)Pakfire_get_arch
,
1381 (getter
)Pakfire_get_keys
,
1388 (getter
)Pakfire_get_path
,
1395 (getter
)Pakfire_get_repos
,
1403 PyTypeObject PakfireType
= {
1404 PyVarObject_HEAD_INIT(NULL
, 0)
1405 tp_name
: "_pakfire.Pakfire",
1406 tp_basicsize
: sizeof(PakfireObject
),
1407 tp_flags
: Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
1408 tp_new
: Pakfire_new
,
1409 tp_dealloc
: (destructor
)Pakfire_dealloc
,
1410 tp_init
: (initproc
)Pakfire_init
,
1411 tp_doc
: "Pakfire object",
1412 tp_methods
: Pakfire_methods
,
1413 tp_getset
: Pakfire_getsetters
,
1414 tp_repr
: (reprfunc
)Pakfire_repr
,