You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
300 lines
8.7 KiB
300 lines
8.7 KiB
#include <python2.7/Python.h>
|
|
|
|
#include "dpkg.h"
|
|
|
|
#define MAKE_PY_LIST(L,S,E,I,V) \
|
|
do { \
|
|
L = PyList_New(0); \
|
|
if (!L) break; \
|
|
for (S; E; I) { \
|
|
PyObject *EL; \
|
|
EL = Py_BuildValue V; \
|
|
if (!EL) { \
|
|
Py_DECREF(L); \
|
|
L = NULL; \
|
|
break; \
|
|
} \
|
|
PyList_Append(L, EL); \
|
|
Py_DECREF(EL); \
|
|
} \
|
|
if (L) PyList_Sort(L); \
|
|
} while(0)
|
|
|
|
/**************************************************************************
|
|
* britney.Packages -- dpkg_packages wrapper
|
|
*******************************************/
|
|
|
|
typedef enum { DONTFREE, FREE } dpkgpackages_freeme;
|
|
typedef struct {
|
|
PyObject_HEAD
|
|
dpkg_packages *pkgs;
|
|
PyObject *ref; /* object packages are "in" */
|
|
dpkgpackages_freeme freeme; /* free pkgs when deallocing? */
|
|
} dpkgpackages;
|
|
|
|
staticforward PyTypeObject Packages_Type;
|
|
|
|
static void dpkgpackages_dealloc(dpkgpackages *self) {
|
|
if (self->freeme == FREE) free_packages(self->pkgs);
|
|
Py_XDECREF(self->ref);
|
|
self->pkgs = NULL;
|
|
self->ref = NULL;
|
|
PyObject_DEL(self);
|
|
}
|
|
|
|
|
|
static PyObject *dpkgpackages_isinstallable(dpkgpackages *self, PyObject *args)
|
|
{
|
|
char *pkgname;
|
|
int r;
|
|
if (!PyArg_ParseTuple(args, "s", &pkgname)) return NULL;
|
|
if ((r=checkinstallable2(self->pkgs, pkgname))) {
|
|
return Py_BuildValue("i", r);
|
|
} else {
|
|
return Py_BuildValue("");
|
|
}
|
|
}
|
|
|
|
static PyObject *dpkgpackages_remove_binary(dpkgpackages *self, PyObject *args) {
|
|
char *pkg_name;
|
|
|
|
(void)self; /* unused */
|
|
|
|
if (!PyArg_ParseTuple(args, "s", &pkg_name))
|
|
return NULL;
|
|
|
|
dpkg_collected_package *cpkg = lookup_packagetbl(self->pkgs->packages, pkg_name);
|
|
if (cpkg == NULL) return Py_BuildValue("i", 0);
|
|
|
|
remove_package(self->pkgs, cpkg);
|
|
return Py_BuildValue("i", 1);
|
|
}
|
|
|
|
static PyObject *dpkgpackages_add_binary(dpkgpackages *self, PyObject *args) {
|
|
char *pkg_name;
|
|
PyObject *value, *pyString;
|
|
|
|
(void)self; /* unused */
|
|
|
|
if (!PyArg_ParseTuple(args, "sO", &pkg_name, &value) ||
|
|
!PyList_Check(value)) return NULL;
|
|
|
|
/* initialize the new package */
|
|
dpkg_package *pkg;
|
|
pkg = block_malloc(sizeof(dpkg_package));
|
|
pkg->package = strdup(pkg_name);
|
|
pkg->priority = 0;
|
|
pkg->details = NULL;
|
|
pkg->depends[1] = NULL;
|
|
pkg->depends[2] = NULL;
|
|
pkg->depends[3] = NULL;
|
|
|
|
pyString = PyList_GetItem(value, 0);
|
|
if (pyString == NULL) return NULL;
|
|
pkg->version = PyString_AsString(pyString);
|
|
|
|
pyString = PyList_GetItem(value, 2);
|
|
if (pyString == NULL) return NULL;
|
|
pkg->source = PyString_AsString(pyString);
|
|
|
|
pyString = PyList_GetItem(value, 3);
|
|
if (pyString == NULL) return NULL;
|
|
pkg->source_ver = PyString_AsString(pyString);
|
|
|
|
pyString = PyList_GetItem(value, 4);
|
|
if (pyString == NULL) return NULL;
|
|
pkg->arch_all = (pyString == Py_None || strcmp(PyString_AsString(pyString), "all") ? 0 : 1);
|
|
|
|
pyString = PyList_GetItem(value, 5);
|
|
if (pyString == NULL) return NULL;
|
|
if (pyString != Py_None) {
|
|
pkg->multiarch = PyString_AsString(pyString);
|
|
} else pkg->multiarch = NULL;
|
|
|
|
pyString = PyList_GetItem(value, 6);
|
|
if (pyString == NULL) return NULL;
|
|
if (pyString != Py_None) {
|
|
pkg->depends[0] = read_dep_andor(PyString_AsString(pyString));
|
|
} else pkg->depends[0] = NULL;
|
|
|
|
pyString = PyList_GetItem(value, 7);
|
|
if (pyString == NULL) return NULL;
|
|
if (pyString != Py_None) {
|
|
pkg->conflicts = read_dep_and(PyString_AsString(pyString));
|
|
} else pkg->conflicts = NULL;
|
|
|
|
pyString = PyList_GetItem(value, 8);
|
|
if (pyString == NULL) return NULL;
|
|
if (pyString != Py_None) {
|
|
pkg->provides = read_packagenames(PyString_AsString(pyString));
|
|
} else pkg->provides = NULL;
|
|
|
|
add_package(self->pkgs, pkg);
|
|
|
|
return Py_BuildValue("i", 1);
|
|
}
|
|
|
|
static PyObject *dpkgpackages_getattr(dpkgpackages *self, char *name) {
|
|
static struct PyMethodDef dpkgsources_methods[] = {
|
|
{ "is_installable", (binaryfunc) dpkgpackages_isinstallable,
|
|
METH_VARARGS, NULL },
|
|
{ "remove_binary", (binaryfunc) dpkgpackages_remove_binary,
|
|
METH_VARARGS, NULL },
|
|
{ "add_binary", (binaryfunc) dpkgpackages_add_binary,
|
|
METH_VARARGS, NULL },
|
|
|
|
{ NULL, NULL, 0, NULL }
|
|
};
|
|
|
|
if (strcmp(name, "packages") == 0) {
|
|
PyObject *packages;
|
|
packagetbl_iter it;
|
|
MAKE_PY_LIST(packages,
|
|
it = first_packagetbl(self->pkgs->packages),
|
|
!done_packagetbl(it), it = next_packagetbl(it),
|
|
("s", it.k)
|
|
);
|
|
return packages;
|
|
}
|
|
|
|
return Py_FindMethod(dpkgsources_methods, (PyObject *)self, name);
|
|
}
|
|
|
|
static PyTypeObject Packages_Type = {
|
|
PyObject_HEAD_INIT(&PyType_Type)
|
|
|
|
0, /* ob_size (0) */
|
|
"Packages", /* type name */
|
|
sizeof(dpkgpackages), /* basicsize */
|
|
0, /* itemsize (0) */
|
|
|
|
(destructor) dpkgpackages_dealloc,
|
|
(printfunc) 0,
|
|
(getattrfunc) dpkgpackages_getattr,
|
|
(setattrfunc) 0,
|
|
(cmpfunc) 0,
|
|
(reprfunc) 0,
|
|
|
|
0, /* number methods */
|
|
0, /* sequence methods */
|
|
0, /* mapping methods */
|
|
|
|
(hashfunc) 0, /* dict[x] ?? */
|
|
(ternaryfunc) 0, /* x() */
|
|
(reprfunc) 0 /* str(x) */
|
|
};
|
|
|
|
/**************************************************************************
|
|
* britney.buildSystem() -- build a fake package system, with the only purpose of
|
|
* calling the is_installable method on the packages.
|
|
******************************************************/
|
|
|
|
static PyObject *build_system(PyObject *self, PyObject *args) {
|
|
Py_ssize_t pos = 0;
|
|
char *arch;
|
|
PyObject *pkgs, *key, *value, *pyString;
|
|
|
|
(void)self; /* unused */
|
|
|
|
if (!PyArg_ParseTuple(args, "sO", &arch, &pkgs) ||
|
|
!PyDict_Check(pkgs)) return NULL;
|
|
|
|
/* Fields and positions for the binary package:
|
|
# VERSION = 0
|
|
# SECTION = 1
|
|
# SOURCE = 2
|
|
# SOURCEVER = 3
|
|
# ARCHITECTURE = 4
|
|
# MULTIARCH = 5
|
|
# DEPENDS = 6
|
|
# CONFLICTS = 7
|
|
# PROVIDES = 8
|
|
# RDEPENDS = 9
|
|
# RCONFLICTS = 10
|
|
*/
|
|
|
|
dpkg_packages *dpkg_pkgs = new_packages(arch);
|
|
|
|
/* loop on the dictionary keys to build the packages */
|
|
while (PyDict_Next(pkgs, &pos, &key, &value)) {
|
|
|
|
/* initialize the new package */
|
|
dpkg_package *pkg;
|
|
pkg = block_malloc(sizeof(dpkg_package));
|
|
pkg->package = strdup(PyString_AsString(key));
|
|
pkg->priority = 0;
|
|
pkg->details = NULL;
|
|
pkg->depends[1] = NULL;
|
|
pkg->depends[2] = NULL;
|
|
pkg->depends[3] = NULL;
|
|
|
|
pyString = PyList_GetItem(value, 0);
|
|
if (pyString == NULL) continue;
|
|
pkg->version = PyString_AsString(pyString);
|
|
|
|
pyString = PyList_GetItem(value, 2);
|
|
if (pyString == NULL) continue;
|
|
pkg->source = PyString_AsString(pyString);
|
|
|
|
pyString = PyList_GetItem(value, 3);
|
|
if (pyString == NULL) continue;
|
|
pkg->source_ver = PyString_AsString(pyString);
|
|
|
|
pyString = PyList_GetItem(value, 4);
|
|
if (pyString == NULL) continue;
|
|
pkg->arch_all = (pyString == Py_None || strcmp(PyString_AsString(pyString), "all") ? 0 : 1);
|
|
|
|
pyString = PyList_GetItem(value, 5);
|
|
if (pyString == NULL) continue;
|
|
if (pyString != Py_None) {
|
|
pkg->multiarch = PyString_AsString(pyString);
|
|
} else pkg->multiarch = NULL;
|
|
|
|
pyString = PyList_GetItem(value, 6);
|
|
if (pyString == NULL) continue;
|
|
if (pyString != Py_None) {
|
|
pkg->depends[0] = read_dep_andor(PyString_AsString(pyString));
|
|
} else pkg->depends[0] = NULL;
|
|
|
|
pyString = PyList_GetItem(value, 7);
|
|
if (pyString == NULL) continue;
|
|
if (pyString != Py_None) {
|
|
pkg->conflicts = read_dep_and(PyString_AsString(pyString));
|
|
} else pkg->conflicts = NULL;
|
|
|
|
pyString = PyList_GetItem(value, 8);
|
|
if (pyString == NULL) continue;
|
|
if (pyString != Py_None) {
|
|
pkg->provides = read_packagenames(PyString_AsString(pyString));
|
|
} else pkg->provides = NULL;
|
|
|
|
add_package(dpkg_pkgs, pkg);
|
|
}
|
|
|
|
dpkgpackages *res;
|
|
res = PyObject_NEW(dpkgpackages, &Packages_Type);
|
|
if (res == NULL) return NULL;
|
|
|
|
res->pkgs = dpkg_pkgs;
|
|
res->freeme = FREE;
|
|
res->ref = NULL;
|
|
|
|
return (PyObject *)res;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
* module initialisation
|
|
***********************/
|
|
|
|
static PyMethodDef britneymethods[] = {
|
|
{ "buildSystem", build_system, METH_VARARGS, NULL },
|
|
|
|
{ NULL, NULL, 0, NULL }
|
|
};
|
|
|
|
void initbritney(void) {
|
|
Py_InitModule("britney", britneymethods);
|
|
}
|
|
|