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", "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
;
165 int enable_ccache
= 1;
166 int enable_snapshot
= 1;
168 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "|zzOpzpppOO", kwlist
,
169 &path
, &arch
, &self
->callbacks
.log
, &offline
, &conf
, &build
,
170 &enable_ccache
, &enable_snapshot
, &self
->callbacks
.status
,
171 &self
->callbacks
.progress
))
174 // Check if log callback is callable
175 if (self
->callbacks
.log
&& !PyCallable_Check(self
->callbacks
.log
)) {
176 PyErr_SetString(PyExc_TypeError
, "logger must be callable\n");
180 // Check if status callback is callable
181 if (self
->callbacks
.status
&& !PyCallable_Check(self
->callbacks
.status
)) {
182 PyErr_SetString(PyExc_TypeError
, "status callback must be callable\n");
186 // Check if progress callback is callable
187 if (self
->callbacks
.progress
&& !PyCallable_Check(self
->callbacks
.progress
)) {
188 PyErr_SetString(PyExc_TypeError
, "progress callback must be callable\n");
194 // Enable offline mode
196 flags
|= PAKFIRE_FLAGS_OFFLINE
;
200 flags
|= PAKFIRE_FLAGS_BUILD
;
203 flags
|= PAKFIRE_FLAGS_DISABLE_CCACHE
;
205 if (!enable_snapshot
)
206 flags
|= PAKFIRE_FLAGS_DISABLE_SNAPSHOT
;
209 // Configure callbacks
210 struct pakfire_callbacks callbacks
= {
211 .data
= &self
->callbacks
,
214 if (self
->callbacks
.log
) {
215 callbacks
.log
= Pakfire_log_callback
;
216 Py_INCREF(self
->callbacks
.log
);
219 if (self
->callbacks
.status
) {
220 callbacks
.status
= Pakfire_status_callback
;
221 Py_INCREF(self
->callbacks
.status
);
224 if (self
->callbacks
.progress
) {
225 callbacks
.progress
= Pakfire_progress_callback
;
226 Py_INCREF(self
->callbacks
.progress
);
229 // Create a new Pakfire instance
230 int r
= pakfire_create(&self
->pakfire
, path
, arch
, conf
, flags
, &callbacks
);
233 // Invalid architecture or path
235 PyErr_SetString(PyExc_ValueError
, "Invalid architecture or path");
240 PyErr_SetFromErrno(PyExc_OSError
);
249 static void Pakfire_dealloc(PakfireObject
* self
) {
251 pakfire_unref(self
->pakfire
);
255 It might happen, that the Pakfire python object is deallocated but the
256 actual struct pakfire object isn't yet. However, it might still happen
257 that the logging function is called which will try to call the logging
258 callback which has already been deallocated.
260 TODO This has to move into struct pakfire or something similar.
262 Py_XDECREF(self
->callbacks
.log
);
263 Py_XDECREF(self
->callbacks
.status
);
264 Py_XDECREF(self
->callbacks
.progress
);
267 Py_TYPE(self
)->tp_free((PyObject
*)self
);
270 static PyObject
* Pakfire_repr(PakfireObject
* self
) {
271 const char* path
= pakfire_get_path(self
->pakfire
);
272 const char* arch
= pakfire_get_arch(self
->pakfire
);
274 return PyUnicode_FromFormat("<_pakfire.Pakfire %s (%s)>", path
, arch
);
277 static PyObject
* Pakfire_get_path(PakfireObject
* self
) {
278 const char* path
= pakfire_get_path(self
->pakfire
);
280 return PyUnicode_FromString(path
);
283 static PyObject
* Pakfire_get_arch(PakfireObject
* self
) {
284 const char* arch
= pakfire_get_arch(self
->pakfire
);
286 return PyUnicode_FromString(arch
);
289 static PyObject
* Pakfire_get_repo(PakfireObject
* self
, PyObject
* args
) {
290 const char* name
= NULL
;
292 if (!PyArg_ParseTuple(args
, "s", &name
))
295 struct pakfire_repo
* repo
= pakfire_get_repo(self
->pakfire
, name
);
299 PyObject
* obj
= new_repo(&RepoType
, repo
);
300 pakfire_repo_unref(repo
);
305 static int convert_packages(PyObject
* object
, void* address
) {
306 char*** packages
= (char***)address
;
308 // Called for cleanup
312 if (!PySequence_Check(object
)) {
313 PyErr_SetString(PyExc_ValueError
, "Packages must be a sequence");
317 const unsigned int length
= PySequence_Length(object
);
319 return Py_CLEANUP_SUPPORTED
;
322 *packages
= calloc(length
+ 1, sizeof(*packages
));
324 PyErr_SetFromErrno(PyExc_OSError
);
328 for (unsigned int i
= 0; i
< length
; i
++) {
329 PyObject
* item
= PySequence_GetItem(object
, i
);
331 // Check if input is a string
332 if (!PyUnicode_Check(item
)) {
335 PyErr_SetString(PyExc_AttributeError
, "Expected a string");
340 const char* package
= PyUnicode_AsUTF8(item
);
346 // Add package to array
347 (*packages
)[i
] = strdup(package
);
348 if (!(*packages
)[i
]) {
357 return Py_CLEANUP_SUPPORTED
;
361 for (char** package
= *packages
; *package
; package
++)
369 static PyObject
* Pakfire_install(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
372 "without_recommended",
377 char** packages
= NULL
;
378 int without_recommended
= 0;
379 int allow_uninstall
= 0;
380 int allow_downgrade
= 0;
381 int solver_flags
= 0;
383 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O&|$ppp", kwlist
,
384 convert_packages
, &packages
, &without_recommended
, &allow_uninstall
,
388 // Do not install recommended packages
389 if (without_recommended
)
390 solver_flags
|= PAKFIRE_REQUEST_WITHOUT_RECOMMENDED
;
392 // Can the solver uninstall packages?
394 solver_flags
|= PAKFIRE_REQUEST_ALLOW_UNINSTALL
;
396 // Can the solver downgrade packages?
398 solver_flags
|= PAKFIRE_REQUEST_ALLOW_DOWNGRADE
;
400 // Run pakfire_install
401 int r
= pakfire_install(self
->pakfire
, solver_flags
, (const char**)packages
, NULL
, 0, NULL
);
403 PyErr_SetFromErrno(PyExc_OSError
);
406 for (char** package
= packages
; *package
; package
++)
417 static PyObject
* Pakfire_erase(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
423 char** packages
= NULL
;
424 int keep_dependencies
= 0;
427 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O&|$p", kwlist
,
428 convert_packages
, &packages
, &keep_dependencies
))
431 if (keep_dependencies
)
432 flags
|= PAKFIRE_REQUEST_KEEP_DEPS
;
435 int r
= pakfire_erase(self
->pakfire
, 0, (const char**)packages
, NULL
, flags
, NULL
);
437 PyErr_SetFromErrno(PyExc_OSError
);
440 for (char** package
= packages
; *package
; package
++)
451 static PyObject
* Pakfire_update(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
459 char** packages
= NULL
;
460 char** excludes
= NULL
;
461 int allow_uninstall
= 0;
462 int allow_downgrade
= 0;
463 int solver_flags
= 0;
465 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O&|$O&pp", kwlist
,
466 convert_packages
, &packages
, convert_packages
, &excludes
,
467 &allow_uninstall
, &allow_downgrade
))
470 // Can the solver uninstall packages?
472 solver_flags
|= PAKFIRE_REQUEST_ALLOW_UNINSTALL
;
474 // Can the solver downgrade packages?
476 solver_flags
|= PAKFIRE_REQUEST_ALLOW_DOWNGRADE
;
478 // Run pakfire_update
479 int r
= pakfire_update(self
->pakfire
, solver_flags
, (const char**)packages
,
480 (const char**)excludes
, 0, NULL
);
482 PyErr_SetFromErrno(PyExc_OSError
);
485 for (char** package
= packages
; *package
; package
++)
491 for (char** exclude
= excludes
; *exclude
; exclude
++)
502 static PyObject
* Pakfire_keys_to_list(struct pakfire_key
** keys
) {
503 PyObject
* list
= PyList_New(0);
509 // Push all keys onto the list
510 for (struct pakfire_key
** key
= keys
; *key
; key
++) {
511 PyObject
* object
= new_key(&KeyType
, *key
);
515 PyList_Append(list
, object
);
526 static PyObject
* Pakfire_get_keys(PakfireObject
* self
) {
527 struct pakfire_key
** keys
= NULL
;
529 int r
= pakfire_list_keys(self
->pakfire
, &keys
);
531 PyErr_SetFromErrno(PyExc_OSError
);
535 // Convert keys to list
536 PyObject
* list
= Pakfire_keys_to_list(keys
);
540 for (struct pakfire_key
** key
= keys
; *key
; key
++)
541 pakfire_key_unref(*key
);
548 static PyObject
* Pakfire_get_key(PakfireObject
* self
, PyObject
* args
) {
549 const char* pattern
= NULL
;
551 if (!PyArg_ParseTuple(args
, "s", &pattern
))
554 // Try finding the key
555 struct pakfire_key
* key
= pakfire_key_get(self
->pakfire
, pattern
);
559 PyObject
* object
= new_key(&KeyType
, key
);
560 pakfire_key_unref(key
);
565 static PyObject
* Pakfire_generate_key(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
566 char* kwlist
[] = { "userid", "algorithm", NULL
};
567 struct pakfire_key
* key
= NULL
;
568 const char* userid
= NULL
;
569 const char* algo
= NULL
;
571 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s|$z", kwlist
, &userid
, &algo
))
574 // Generate a new key
575 int r
= pakfire_key_generate(&key
, self
->pakfire
, algo
, userid
);
577 PyErr_SetFromErrno(PyExc_OSError
);
581 PyObject
* object
= new_key(&KeyType
, key
);
582 pakfire_key_unref(key
);
587 static PyObject
* Pakfire_import_key(PakfireObject
* self
, PyObject
* args
) {
588 PyObject
* object
= NULL
;
590 if (!PyArg_ParseTuple(args
, "O", &object
))
593 // Get a file descriptor from object
594 int fd
= PyObject_AsFileDescriptor(object
);
599 FILE* f
= fdopen(fd
, "r");
601 PyErr_SetFromErrno(PyExc_OSError
);
605 struct pakfire_key
** keys
= NULL
;
607 // Import keys from f
608 int r
= pakfire_key_import(self
->pakfire
, f
, &keys
);
610 PyErr_SetFromErrno(PyExc_OSError
);
614 // Convert keys to list
615 PyObject
* list
= Pakfire_keys_to_list(keys
);
618 for (struct pakfire_key
** key
= keys
; *key
; key
++)
619 pakfire_key_unref(*key
);
625 static PyObject
* Pakfire_fetch_key(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
626 char* kwlist
[] = { "userid", "fingerprint", NULL
};
627 struct pakfire_key
* key
= NULL
;
628 const char* userid
= NULL
;
629 const char* fingerprint
= NULL
;
631 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "|$zz", kwlist
, &userid
, &fingerprint
))
635 int r
= pakfire_key_fetch(&key
, self
->pakfire
, userid
, fingerprint
);
637 PyErr_SetFromErrno(PyExc_OSError
);
643 PyObject
* object
= new_key(&KeyType
, key
);
644 pakfire_key_unref(key
);
652 static PyObject
* Pakfire_whatprovides(PakfireObject
* self
, PyObject
* args
) {
653 const char* provides
= NULL
;
654 struct pakfire_packagelist
* list
= NULL
;
656 if (!PyArg_ParseTuple(args
, "s", &provides
))
659 int r
= pakfire_whatprovides(self
->pakfire
, provides
, 0, &list
);
661 PyErr_SetFromErrno(PyExc_OSError
);
665 PyObject
* obj
= PyList_FromPackageList(list
);
666 pakfire_packagelist_unref(list
);
671 static PyObject
* Pakfire_whatrequires(PakfireObject
* self
, PyObject
* args
) {
672 const char* requires
= NULL
;
673 struct pakfire_packagelist
* list
= NULL
;
675 if (!PyArg_ParseTuple(args
, "s", &requires
))
678 int r
= pakfire_whatrequires(self
->pakfire
, requires
, 0, &list
);
680 PyErr_SetFromErrno(PyExc_OSError
);
684 PyObject
* obj
= PyList_FromPackageList(list
);
685 pakfire_packagelist_unref(list
);
690 static PyObject
* Pakfire_search(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
691 char* kwlist
[] = { "pattern", "name_only", NULL
};
692 struct pakfire_packagelist
* list
= NULL
;
693 const char* pattern
= NULL
;
697 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s|$p", kwlist
, &pattern
, &name_only
))
700 // Search for package names only
702 flags
|= PAKFIRE_SEARCH_NAME_ONLY
;
704 int r
= pakfire_search(self
->pakfire
, pattern
, flags
, &list
);
706 PyErr_SetFromErrno(PyExc_OSError
);
710 PyObject
* obj
= PyList_FromPackageList(list
);
711 pakfire_packagelist_unref(list
);
716 static PyObject
* Pakfire_version_compare(PakfireObject
* self
, PyObject
* args
) {
717 const char* evr1
= NULL
;
718 const char* evr2
= NULL
;
720 if (!PyArg_ParseTuple(args
, "ss", &evr1
, &evr2
))
723 int cmp
= pakfire_version_compare(self
->pakfire
, evr1
, evr2
);
725 return PyLong_FromLong(cmp
);
728 static PyObject
* Pakfire_execute_logging_callback
= NULL
;
730 static int __Pakfire_execute_logging_callback(struct pakfire
* pakfire
, void* data
,
731 int priority
, const char* line
, size_t length
) {
734 // Do nothing if callback isn't set
735 if (!Pakfire_execute_logging_callback
)
738 // Translate priority to Python logging priorities
749 // Remove the trailing newline
750 if (line
&& line
[length
- 1] == '\n')
753 // Create tuple with arguments for the callback function
754 PyObject
* args
= Py_BuildValue("(is#)", priority
, line
, (Py_ssize_t
)length
);
758 PyObject
* result
= PyObject_CallObject(Pakfire_execute_logging_callback
, args
);
759 if (result
&& PyLong_Check(result
)) {
760 r
= PyLong_AsLong(result
);
769 static PyObject
* Pakfire_execute(PakfireObject
* self
, PyObject
* args
, PyObject
* kwds
) {
770 char* kwlist
[] = {"command", "environ", "enable_network", "interactive",
771 "logging_callback", NULL
};
773 PyObject
* command
= NULL
;
774 PyObject
* environ
= NULL
;
775 int enable_network
= 0;
777 PyObject
* logging_callback
= NULL
;
779 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "O|OppO", kwlist
, &command
, &environ
,
780 &enable_network
, &interactive
, &logging_callback
))
783 // Check if command is a list
784 if (!PyList_Check(command
)) {
785 PyErr_SetString(PyExc_TypeError
, "command must be a list");
789 ssize_t command_length
= PyList_Size(command
);
791 // Check if command is not empty
792 if (command_length
== 0) {
793 PyErr_SetString(PyExc_ValueError
, "command is empty");
797 // All arguments in command must be strings
798 for (unsigned int i
= 0; i
< command_length
; i
++) {
799 PyObject
* item
= PyList_GET_ITEM(command
, i
);
801 if (!PyUnicode_Check(item
)) {
802 PyErr_Format(PyExc_TypeError
, "Item %u in command is not a string", i
);
807 // Check if logging_callback is
808 if (logging_callback
&& !PyCallable_Check(logging_callback
)) {
809 PyErr_SetString(PyExc_TypeError
, "logging_callback must be callable\n");
813 ssize_t environ_length
= 0;
819 // Check if environ is a dictionary
820 if (!PyDict_Check(environ
)) {
821 PyErr_SetString(PyExc_TypeError
, "environ must be a dictionary");
825 // All keys and values must be strings
826 while (PyDict_Next(environ
, &p
, &key
, &value
)) {
827 if (!PyUnicode_Check(key
) || !PyUnicode_Check(value
)) {
828 PyErr_SetString(PyExc_TypeError
, "Environment contains a non-string object");
833 environ_length
= PyDict_Size(environ
);
836 // All inputs look fine
838 const char* argv
[command_length
+ 1];
839 char* envp
[environ_length
+ 1];
843 for (unsigned int i
= 0; i
< command_length
; i
++) {
844 PyObject
* item
= PyList_GET_ITEM(command
, i
);
845 argv
[i
] = PyUnicode_AsUTF8(item
);
853 while (PyDict_Next(environ
, &p
, &key
, &value
)) {
854 int r
= asprintf(&envp
[i
++], "%s=%s",
855 PyUnicode_AsUTF8(key
), PyUnicode_AsUTF8(value
));
860 for (unsigned int i
= 0; envp
[i
]; i
++)
863 return PyErr_NoMemory();
868 // Terminate argv and envp
869 argv
[command_length
] = NULL
;
870 envp
[environ_length
] = NULL
;
874 flags
|= PAKFIRE_EXECUTE_ENABLE_NETWORK
;
878 flags
|= PAKFIRE_EXECUTE_INTERACTIVE
;
880 // Set logging callback
881 Pakfire_execute_logging_callback
= logging_callback
;
884 int r
= pakfire_execute(self
->pakfire
, argv
, envp
, flags
,
885 (logging_callback
) ? __Pakfire_execute_logging_callback
: NULL
, NULL
);
888 for (unsigned int i
= 0; envp
[i
]; i
++)
891 // Raise an OS error if r < 0
895 PyErr_SetFromErrno(PyExc_OSError
);
898 // Raise exception when the command failed
900 PyObject
* code
= PyLong_FromLong(r
);
902 PyErr_SetObject(PyExc_CommandExecutionError
, code
);
912 static PyObject
* Pakfire_dist(PakfireObject
* self
, PyObject
* args
) {
913 const char* path
= NULL
;
914 const char* target
= NULL
;
917 if (!PyArg_ParseTuple(args
, "s|z", &path
, &target
))
920 int r
= pakfire_dist(self
->pakfire
, path
, target
, &result
);
922 PyErr_SetFromErrno(PyExc_OSError
);
926 PyObject
* ret
= PyUnicode_FromString(result
);
932 static PyObject
* Pakfire_bind(PakfireObject
* self
, PyObject
* args
) {
933 const char* src
= NULL
;
934 const char* dst
= NULL
;
936 if (!PyArg_ParseTuple(args
, "s|z", &src
, &dst
))
939 int r
= pakfire_bind(self
->pakfire
, src
, dst
, 0);
941 PyErr_SetFromErrno(PyExc_OSError
);
948 static PyObject
* Pakfire_copy_in(PakfireObject
* self
, PyObject
* args
) {
949 const char* src
= NULL
;
950 const char* dst
= NULL
;
952 if (!PyArg_ParseTuple(args
, "ss", &src
, &dst
))
955 int r
= pakfire_copy_in(self
->pakfire
, src
, dst
);
957 PyErr_SetFromErrno(PyExc_OSError
);
964 static PyObject
* Pakfire_copy_out(PakfireObject
* self
, PyObject
* args
) {
965 const char* src
= NULL
;
966 const char* dst
= NULL
;
968 if (!PyArg_ParseTuple(args
, "ss", &src
, &dst
))
971 int r
= pakfire_copy_out(self
->pakfire
, src
, dst
);
973 PyErr_SetFromErrno(PyExc_OSError
);
980 static PyObject
* Pakfire_get_repos(PakfireObject
* self
) {
981 struct pakfire_repolist
* repos
= pakfire_get_repos(self
->pakfire
);
983 PyErr_SetFromErrno(PyExc_OSError
);
987 const size_t l
= pakfire_repolist_size(repos
);
989 PyObject
* list
= PyList_New(l
);
993 for (unsigned int i
= 0; i
< l
; i
++) {
994 struct pakfire_repo
* repo
= pakfire_repolist_get(repos
, i
);
998 PyObject
* obj
= new_repo(&RepoType
, repo
);
999 PyList_SET_ITEM(list
, i
, obj
);
1001 pakfire_repo_unref(repo
);
1005 pakfire_repolist_unref(repos
);
1010 static PyObject
* execute_return_value(int r
) {
1011 // Raise an OS error if r < 0
1015 PyErr_SetFromErrno(PyExc_OSError
);
1018 // Raise exception when the command failed
1020 PyObject
* code
= PyLong_FromLong(r
);
1022 PyErr_SetObject(PyExc_CommandExecutionError
, code
);
1031 static PyObject
* Pakfire_build(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1032 char* kwlist
[] = { "path", "build_id", "logging_callback", "interactive", NULL
};
1034 const char* path
= NULL
;
1035 const char* build_id
= NULL
;
1036 PyObject
* logging_callback
= NULL
;
1037 int interactive
= 0;
1039 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zOp", kwlist
, &path
,
1040 &build_id
, &logging_callback
, &interactive
))
1045 // Enable interactive mode
1047 flags
|= PAKFIRE_BUILD_INTERACTIVE
;
1049 // Check if logging_callback is
1050 if (logging_callback
&& !PyCallable_Check(logging_callback
)) {
1051 PyErr_SetString(PyExc_TypeError
, "logging_callback must be callable\n");
1055 // Set logging callback
1056 Pakfire_execute_logging_callback
= logging_callback
;
1059 int r
= pakfire_build(self
->pakfire
, path
, NULL
, build_id
, flags
,
1060 (logging_callback
) ? __Pakfire_execute_logging_callback
: NULL
, NULL
);
1062 return execute_return_value(r
);
1065 static PyObject
* Pakfire_shell(PakfireObject
* self
) {
1066 int r
= pakfire_shell(self
->pakfire
);
1068 return execute_return_value(r
);
1071 static PyObject
* Pakfire_clean(PakfireObject
* self
) {
1072 int r
= pakfire_clean(self
->pakfire
, 0);
1074 PyErr_SetFromErrno(PyExc_OSError
);
1081 static PyObject
* Pakfire_refresh(PakfireObject
* self
, PyObject
* args
) {
1084 if (!PyArg_ParseTuple(args
, "|p", &force
))
1087 int r
= pakfire_refresh(self
->pakfire
, force
);
1089 PyErr_SetFromErrno(PyExc_OSError
);
1096 static PyObject
* Pakfire_check(PakfireObject
* self
) {
1097 int r
= pakfire_check(self
->pakfire
);
1099 PyErr_SetFromErrno(PyExc_OSError
);
1106 static PyObject
* Pakfire_sync(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1107 char* kwlist
[] = {"keep_orphaned", NULL
};
1108 int keep_orphaned
= 0;
1111 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|$p", kwlist
, &keep_orphaned
))
1115 flags
|= PAKFIRE_REQUEST_KEEP_ORPHANED
;
1117 int r
= pakfire_sync(self
->pakfire
, 0, flags
, NULL
);
1119 PyErr_SetFromErrno(PyExc_OSError
);
1126 static PyObject
* Pakfire_open(PakfireObject
* self
, PyObject
* args
) {
1127 struct pakfire_archive
* archive
= NULL
;
1128 const char* path
= NULL
;
1130 if (!PyArg_ParseTuple(args
, "s", &path
))
1133 int r
= pakfire_archive_open(&archive
, self
->pakfire
, path
);
1135 PyErr_SetFromErrno(PyExc_OSError
);
1139 // Create Python object
1140 PyObject
* object
= new_archive(&ArchiveType
, archive
);
1141 pakfire_archive_unref(archive
);
1146 static PyObject
* Pakfire_repo_compose(PakfireObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
1147 char* kwlist
[] = { "path", "files", NULL
};
1148 const char* path
= NULL
;
1149 PyObject
* list
= NULL
;
1151 PyObject
* ret
= NULL
;
1153 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "sO", kwlist
, &path
, &list
))
1156 // List must be a sequence
1157 if (!PySequence_Check(list
)) {
1158 PyErr_SetString(PyExc_ValueError
, "Expected a sequence.");
1162 const int flags
= 0;
1164 // How many new files do we have?
1165 ssize_t num_files
= PySequence_Length(list
);
1169 // Allocate files array
1170 const char** files
= calloc(num_files
+ 1, sizeof(*files
));
1172 PyErr_SetFromErrno(PyExc_OSError
);
1176 for (int i
= 0; i
< num_files
; i
++) {
1177 PyObject
* file
= PySequence_GetItem(list
, i
);
1181 // Check if file is a Unicode object
1182 if (!PyUnicode_Check(file
)) {
1183 PyErr_SetString(PyExc_ValueError
, "Expected a string.");
1187 // Add pointer to string to files array
1188 files
[i
] = PyUnicode_AsUTF8(file
);
1195 int r
= pakfire_repo_compose(self
->pakfire
, path
, flags
, files
);
1197 PyErr_SetFromErrno(PyExc_OSError
);
1201 // Return None on success
1212 static struct PyMethodDef Pakfire_methods
[] = {
1215 (PyCFunction
)Pakfire_bind
,
1221 (PyCFunction
)Pakfire_build
,
1222 METH_VARARGS
|METH_KEYWORDS
,
1227 (PyCFunction
)Pakfire_check
,
1233 (PyCFunction
)Pakfire_clean
,
1239 (PyCFunction
)Pakfire_copy_in
,
1245 (PyCFunction
)Pakfire_copy_out
,
1251 (PyCFunction
)Pakfire_dist
,
1257 (PyCFunction
)Pakfire_erase
,
1258 METH_VARARGS
|METH_KEYWORDS
,
1263 (PyCFunction
)Pakfire_execute
,
1264 METH_VARARGS
|METH_KEYWORDS
,
1269 (PyCFunction
)Pakfire_fetch_key
,
1270 METH_VARARGS
|METH_KEYWORDS
,
1275 (PyCFunction
)Pakfire_generate_key
,
1276 METH_VARARGS
|METH_KEYWORDS
,
1281 (PyCFunction
)Pakfire_get_key
,
1287 (PyCFunction
)Pakfire_get_repo
,
1293 (PyCFunction
)Pakfire_import_key
,
1299 (PyCFunction
)Pakfire_install
,
1300 METH_VARARGS
|METH_KEYWORDS
,
1305 (PyCFunction
)Pakfire_open
,
1311 (PyCFunction
)Pakfire_refresh
,
1317 (PyCFunction
)Pakfire_repo_compose
,
1318 METH_VARARGS
|METH_KEYWORDS
,
1323 (PyCFunction
)Pakfire_search
,
1324 METH_VARARGS
|METH_KEYWORDS
,
1329 (PyCFunction
)Pakfire_shell
,
1335 (PyCFunction
)Pakfire_sync
,
1336 METH_VARARGS
|METH_KEYWORDS
,
1341 (PyCFunction
)Pakfire_update
,
1342 METH_VARARGS
|METH_KEYWORDS
,
1347 (PyCFunction
)Pakfire_version_compare
,
1353 (PyCFunction
)Pakfire_whatprovides
,
1359 (PyCFunction
)Pakfire_whatrequires
,
1366 static struct PyGetSetDef Pakfire_getsetters
[] = {
1369 (getter
)Pakfire_get_arch
,
1376 (getter
)Pakfire_get_keys
,
1383 (getter
)Pakfire_get_path
,
1390 (getter
)Pakfire_get_repos
,
1398 PyTypeObject PakfireType
= {
1399 PyVarObject_HEAD_INIT(NULL
, 0)
1400 tp_name
: "_pakfire.Pakfire",
1401 tp_basicsize
: sizeof(PakfireObject
),
1402 tp_flags
: Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
1403 tp_new
: Pakfire_new
,
1404 tp_dealloc
: (destructor
)Pakfire_dealloc
,
1405 tp_init
: (initproc
)Pakfire_init
,
1406 tp_doc
: "Pakfire object",
1407 tp_methods
: Pakfire_methods
,
1408 tp_getset
: Pakfire_getsetters
,
1409 tp_repr
: (reprfunc
)Pakfire_repr
,