#include #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 PyObject *dpkgpackages_new(dpkg_packages *pkgs, dpkgpackages_freeme freeme, PyObject *ref) { dpkgpackages *res; res = PyObject_NEW(dpkgpackages, &Packages_Type); if (res == NULL) return NULL; res->pkgs = pkgs; res->ref = ref; Py_INCREF(res->ref); res->freeme = freeme; return (PyObject *) res; } 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 dpkg_collected_package *dpkgpackages_lookuppkg(dpkgpackages *self, char *pkgname) { dpkg_collected_package *cpkg = NULL; cpkg = lookup_packagetbl(self->pkgs->packages, pkgname); if (!cpkg) { PyErr_SetString(PyExc_ValueError, "Not a valid package"); } return cpkg; } static PyObject *dpkgpackages_ispresent(dpkgpackages *self, PyObject *args) { dpkg_collected_package *cpkg; char *pkgname; if (!PyArg_ParseTuple(args, "s", &pkgname)) return NULL; cpkg = lookup_packagetbl(self->pkgs->packages, pkgname); return cpkg ? Py_BuildValue("i", 1) : Py_BuildValue("i", 0); } static PyObject *dpkgpackages_getversion(dpkgpackages *self, PyObject *args) { dpkg_collected_package *cpkg; char *pkgname; if (!PyArg_ParseTuple(args, "s", &pkgname)) return NULL; cpkg = lookup_packagetbl(self->pkgs->packages, pkgname); if (cpkg) return Py_BuildValue("s", cpkg->pkg->version); else return Py_BuildValue(""); } static PyObject *dpkgpackages_getsource(dpkgpackages *self, PyObject *args) { dpkg_collected_package *cpkg; char *pkgname; if (!PyArg_ParseTuple(args, "s", &pkgname)) return NULL; cpkg = lookup_packagetbl(self->pkgs->packages, pkgname); if (cpkg) return Py_BuildValue("s", cpkg->pkg->source); else return Py_BuildValue(""); } static PyObject *dpkgpackages_getsourcever(dpkgpackages *self, PyObject *args) { dpkg_collected_package *cpkg; char *pkgname; if (!PyArg_ParseTuple(args, "s", &pkgname)) return NULL; cpkg = lookup_packagetbl(self->pkgs->packages, pkgname); if (cpkg) return Py_BuildValue("s", cpkg->pkg->source_ver); else return Py_BuildValue(""); } static PyObject *dpkgpackages_isarchall(dpkgpackages *self, PyObject *args) { dpkg_collected_package *cpkg; char *pkgname; if (!PyArg_ParseTuple(args, "s", &pkgname)) return NULL; cpkg = lookup_packagetbl(self->pkgs->packages, pkgname); if (cpkg) return Py_BuildValue("i", cpkg->pkg->arch_all); else return Py_BuildValue(""); } static PyObject *dpkgpackages_isntarchall(dpkgpackages *self, PyObject *args) { dpkg_collected_package *cpkg; char *pkgname; if (!PyArg_ParseTuple(args, "s", &pkgname)) return NULL; cpkg = lookup_packagetbl(self->pkgs->packages, pkgname); if (cpkg) return Py_BuildValue("i", !cpkg->pkg->arch_all); else return Py_BuildValue(""); } static PyObject *dpkgpackages_getfield(dpkgpackages *self, PyObject *args) { char *field; char *pkgname; int i; dpkg_collected_package *cpkg; dpkg_paragraph *para; if (!PyArg_ParseTuple(args, "ss", &pkgname, &field)) return NULL; cpkg = dpkgpackages_lookuppkg(self, pkgname); if (!cpkg) return NULL; para = cpkg->pkg->details; for (i = 0; i < para->n_entries; i++) { if (strcasecmp(para->entry[i].name, field) == 0) { return Py_BuildValue("s", para->entry[i].value); } } return Py_BuildValue(""); } static PyObject *dpkgpackages_isinstallable(dpkgpackages *self, PyObject *args) { char *pkgname; if (!PyArg_ParseTuple(args, "s", &pkgname)) return NULL; if (checkinstallable2(self->pkgs, pkgname)) { return Py_BuildValue("i", 1); } else { return Py_BuildValue(""); } } static PyObject *dpkgpackages_isuninstallable(dpkgpackages *self, PyObject *args) { char *pkgname; if (!PyArg_ParseTuple(args, "s", &pkgname)) return NULL; if (!checkinstallable2(self->pkgs, pkgname)) { return Py_BuildValue("i", 1); } else { return Py_BuildValue(""); } } static PyObject *dpkgpackages_unsatdeps(dpkgpackages *self, PyObject *args) { /* arguments are: * testingpkgs[arch].unsatisfiable_deps(unstablepkgs[arch], "netbase", "Depends") * exciting, huh? */ dpkgpackages *pkgpkgs; char *pkgname, *fieldname; dpkg_collected_package *cpkg; int fieldidx; int buflen = 100; char *buf = malloc(buflen); const char *fields[] = { "Pre-Depends", "Depends", "Recommends", "Suggests", NULL }; satisfieddeplist *unsatdeps, *dl; PyObject *res = Py_BuildValue("[]"); if (!PyArg_ParseTuple(args, "O!ss", &Packages_Type, &pkgpkgs, &pkgname, &fieldname)) return NULL; cpkg = lookup_packagetbl(pkgpkgs->pkgs->packages, pkgname); if (!cpkg) { PyErr_SetString(PyExc_ValueError, "Not a valid package"); return NULL; } for (fieldidx = 0; fields[fieldidx]; fieldidx++) { if (strcmp(fields[fieldidx], fieldname) == 0) break; } if (!fields[fieldidx]) { PyErr_SetString(PyExc_ValueError, "Not a valid dependency field"); return NULL; } unsatdeps = checkunsatisfiabledeps(self->pkgs, cpkg->pkg->depends[fieldidx]); for (dl = unsatdeps; dl != NULL; dl = dl->next) { int len; packagelist *it; PyObject *pkglist; deplist *depl; dependency *dep; len = 0; buf[0] = '\0'; for (depl = dl->value->depl; depl; depl = depl->next) { dep = depl->value; len += strlen(dep->package) + 4; /* 4 = strlen(" | ") + 1 */ if (dep->op != dr_NOOP) { len += strlen(dep->version) + 6; /* 6 = strlen(" (>= )") */ } if (len >= buflen) { char *newbuf; newbuf = realloc(buf, len + 100); if (newbuf == NULL) { free_satisfieddeplist(unsatdeps); free(buf); Py_DECREF(res); PyErr_SetFromErrno(PyExc_MemoryError); return NULL; } buf = newbuf; buflen = len + 100; } if (buf[0] != '\0') strcat(buf, " | "); strcat(buf, dep->package); if (dep->op != dr_NOOP) { sprintf(buf + strlen(buf), " (%s %s)", dependency_relation_sym[dep->op], dep->version); } } MAKE_PY_LIST(pkglist, it = dl->value->pkgs, it, it = it->next, ("s", it->value->package) ); { PyObject *depel = Py_BuildValue("(sN)", buf, pkglist); PyList_Append(res, depel); Py_DECREF(depel); } } free_satisfieddeplist(unsatdeps); free(buf); return res; } 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[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->depends[0] = read_dep_andor(PyString_AsString(pyString)); } else pkg->depends[0] = NULL; pyString = PyList_GetItem(value, 6); if (pyString == NULL) return NULL; if (pyString != Py_None) { pkg->depends[1] = read_dep_andor(PyString_AsString(pyString)); } else pkg->depends[1] = 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_present", (binaryfunc) dpkgpackages_ispresent, METH_VARARGS, NULL }, { "get_version", (binaryfunc) dpkgpackages_getversion, METH_VARARGS, NULL }, { "get_source", (binaryfunc) dpkgpackages_getsource, METH_VARARGS, NULL }, { "get_sourcever", (binaryfunc) dpkgpackages_getsourcever, METH_VARARGS, NULL }, { "is_arch_all", (binaryfunc) dpkgpackages_isarchall, METH_VARARGS, NULL }, { "isnt_arch_all", (binaryfunc) dpkgpackages_isntarchall, METH_VARARGS, NULL }, { "get_field", (binaryfunc) dpkgpackages_getfield, METH_VARARGS, NULL }, { "is_installable", (binaryfunc) dpkgpackages_isinstallable, METH_VARARGS, NULL }, { "is_uninstallable", (binaryfunc)dpkgpackages_isuninstallable, METH_VARARGS, NULL }, { "unsatisfiable_deps", (binaryfunc) dpkgpackages_unsatdeps, 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.Sources -- dpkg_sources wrapper *****************************************/ typedef struct { PyObject_HEAD dpkg_sources *srcs; } dpkgsources; staticforward PyTypeObject Sources_Type; static PyObject *dpkgsources_new(PyObject *self, PyObject *args) { dpkgsources *res = NULL; char *dir; PyObject *arches; char **archesStr = NULL; int i, count; (void)self; /* unused */ if (!PyArg_ParseTuple(args, "sO!", &dir, &PyList_Type, &arches)) { goto end; } count = PyList_Size(arches); if (count <= 0) { PyErr_SetString(PyExc_TypeError, "No architectures specified"); goto end; } archesStr = malloc(sizeof(char *) * count); if (!archesStr) { PyErr_SetFromErrno(PyExc_MemoryError); goto end; } for (i = 0; i < count; i++) { PyObject *arch = PyList_GetItem(arches, i); if (!PyString_Check(arch)) { goto end; } archesStr[i] = PyString_AsString(arch); } res = PyObject_NEW(dpkgsources, &Sources_Type); if (res == NULL) goto end; res->srcs = read_directory(dir, count, archesStr); if (!res->srcs) { Py_DECREF(res); res = NULL; goto end; } end: if (archesStr) free(archesStr); return (PyObject *) res; } static void dpkgsources_dealloc(dpkgsources *self) { free_sources(self->srcs); self->srcs = NULL; PyObject_DEL(self); } static PyObject *dpkgsources_packages(dpkgsources *self, PyObject *args) { char *arch; dpkg_packages *pkgs; if (!PyArg_ParseTuple(args, "s", &arch)) return NULL; pkgs = get_architecture(self->srcs, arch); return dpkgpackages_new(pkgs, FREE, (PyObject *) self); } static PyObject *dpkgsources_isfake(dpkgsources *self, PyObject *args) { char *srcname; dpkg_source *src; if (!PyArg_ParseTuple(args, "s", &srcname)) return NULL; src = lookup_sourcetbl(self->srcs->sources, srcname); if (src) return Py_BuildValue("i", src->fake); else return Py_BuildValue(""); } static PyObject *dpkgsources_getversion(dpkgsources *self, PyObject *args) { char *srcname; dpkg_source *src; if (!PyArg_ParseTuple(args, "s", &srcname)) return NULL; src = lookup_sourcetbl(self->srcs->sources, srcname); if (src) return Py_BuildValue("s", src->version); else return Py_BuildValue(""); } static PyObject *dpkgsources_getfield(dpkgsources *self, PyObject *args) { char *srcname, *field; dpkg_source *src; int i; dpkg_paragraph *para; if (!PyArg_ParseTuple(args, "ss", &srcname, &field)) return NULL; src = lookup_sourcetbl(self->srcs->sources, srcname); if (!src) { PyErr_SetString(PyExc_ValueError, "Not a valid source package"); return NULL; } para = src->details; if (para) { for (i = 0; i < para->n_entries; i++) { if (strcasecmp(para->entry[i].name, field) == 0) { return Py_BuildValue("s", para->entry[i].value); } } } return Py_BuildValue(""); } static PyObject *dpkgsources_ispresent(dpkgsources *self, PyObject *args) { char *srcname; if (!PyArg_ParseTuple(args, "s", &srcname)) return NULL; if (lookup_sourcetbl(self->srcs->sources, srcname)) { return Py_BuildValue("i", 1); } else { return Py_BuildValue("i", 0); } } static PyObject *dpkgsources_binaries(dpkgsources *self, PyObject *args) { char *srcname, *arch; int archnum; dpkg_source *src; PyObject *res; ownedpackagelist *p; if (!PyArg_ParseTuple(args, "ss", &srcname, &arch)) return NULL; for (archnum = 0; archnum < self->srcs->n_arches; archnum++) { if (strcmp(arch, self->srcs->archname[archnum]) == 0) break; } if (archnum == self->srcs->n_arches) { PyErr_SetString(PyExc_ValueError, "Not a valid architecture"); return NULL; } src = lookup_sourcetbl(self->srcs->sources, srcname); if (src == NULL) { PyErr_SetString(PyExc_ValueError, "Not a valid source package"); return NULL; } MAKE_PY_LIST(res, p = src->packages[archnum], p, p = p->next, ("s", p->value->package) ); return res; } static PyObject *dpkgsources_getattr(dpkgsources *self, char *name) { static struct PyMethodDef dpkgsources_methods[] = { { "Packages", (binaryfunc) dpkgsources_packages, METH_VARARGS, NULL }, { "is_fake", (binaryfunc) dpkgsources_isfake, METH_VARARGS, NULL }, { "get_version", (binaryfunc) dpkgsources_getversion, METH_VARARGS, NULL }, { "get_field", (binaryfunc) dpkgsources_getfield, METH_VARARGS, NULL }, { "is_present", (binaryfunc) dpkgsources_ispresent, METH_VARARGS, NULL }, { "binaries", (binaryfunc) dpkgsources_binaries, METH_VARARGS, NULL }, { NULL, NULL, 0, NULL } }; if (strcmp(name, "arches") == 0) { PyObject *arches; int i; MAKE_PY_LIST(arches, i = 0, i < self->srcs->n_arches, i++, ("s", self->srcs->archname[i]) ); return arches; } else if (strcmp(name, "sources") == 0) { PyObject *sources; sourcetbl_iter it; MAKE_PY_LIST(sources, it = first_sourcetbl(self->srcs->sources), !done_sourcetbl(it), it = next_sourcetbl(it), ("s", it.k) ); return sources; } return Py_FindMethod(dpkgsources_methods, (PyObject *)self, name); } static PyTypeObject Sources_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size (0) */ "Sources", /* type name */ sizeof(dpkgsources), /* basicsize */ 0, /* itemsize (0) */ (destructor) dpkgsources_dealloc, (printfunc) 0, (getattrfunc) dpkgsources_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.SourcesNote -- dpkg_sourcesnote wrapper *************************************************/ typedef struct { PyObject_HEAD dpkg_sources_note *srcsn; PyObject *refs; /* list of referenced dpkgsources */ } dpkgsrcsn; staticforward PyTypeObject SourcesNote_Type; static PyObject *dpkgsrcsn_new(PyObject *self, PyObject *args) { dpkgsrcsn *res = NULL; PyObject *arches; char **archesStr = NULL; int i, count; (void)self; /* unused */ if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &arches)) { goto end; } count = PyList_Size(arches); if (count <= 0) { PyErr_SetString(PyExc_TypeError, "No architectures specified"); goto end; } archesStr = malloc(sizeof(char *) * count); if (!archesStr) { PyErr_SetFromErrno(PyExc_MemoryError); goto end; } for (i = 0; i < count; i++) { PyObject *arch = PyList_GetItem(arches, i); if (!PyString_Check(arch)) { goto end; } archesStr[i] = PyString_AsString(arch); } res = PyObject_NEW(dpkgsrcsn, &SourcesNote_Type); if (res == NULL) goto end; res->refs = PyList_New(0); res->srcsn = new_sources_note(count, archesStr); if (!res->refs || !res->srcsn) { Py_DECREF(res); res = NULL; goto end; } end: if (archesStr) free(archesStr); return (PyObject *) res; } static void dpkgsrcsn_dealloc(dpkgsrcsn *self) { if (self->srcsn) free_sources_note(self->srcsn); self->srcsn = NULL; Py_XDECREF(self->refs); self->refs = NULL; PyObject_DEL(self); } static PyObject *dpkgsrcsn_removesource(dpkgsrcsn *self, PyObject *args) { char *name; if (!PyArg_ParseTuple(args, "s", &name)) return NULL; remove_source(self->srcsn, name); return Py_BuildValue(""); } static PyObject *dpkgsrcsn_upgradesource(dpkgsrcsn *self, PyObject *args) { char *name; dpkgsources *srcs; dpkg_source *src; if (!PyArg_ParseTuple(args, "O!s", &Sources_Type, &srcs, &name)) return NULL; src = lookup_sourcetbl(srcs->srcs->sources, name); if (!src) { PyErr_SetString(PyExc_ValueError, "Source does not exist"); return NULL; } if (!PySequence_In(self->refs, (PyObject *)srcs)) PyList_Append(self->refs, (PyObject *)srcs); upgrade_source(self->srcsn, src); return Py_BuildValue(""); } static PyObject *dpkgsrcsn_upgradearch(dpkgsrcsn *self, PyObject *args) { char *name, *arch; dpkgsources *srcs; dpkg_source *src; if (!PyArg_ParseTuple(args, "O!ss", &Sources_Type, &srcs, &name, &arch)) return NULL; src = lookup_sourcetbl(srcs->srcs->sources, name); if (!src) { PyErr_SetString(PyExc_ValueError, "Source does not exist"); return NULL; } if (!PySequence_In(self->refs, (PyObject *)srcs)) PyList_Append(self->refs, (PyObject *)srcs); upgrade_arch(self->srcsn, src, arch); return Py_BuildValue(""); } static PyObject *dpkgsrcsn_undochange(dpkgsrcsn *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; undo_change(self->srcsn); return Py_BuildValue(""); } static PyObject *dpkgsrcsn_commitchanges(dpkgsrcsn *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; commit_changes(self->srcsn); return Py_BuildValue(""); } static PyObject *dpkgsrcsn_writenotes(dpkgsrcsn *self, PyObject *args) { char *dir; if (!PyArg_ParseTuple(args, "s", &dir)) return NULL; write_notes(dir, self->srcsn); return Py_BuildValue(""); } static PyObject *dpkgsrcsn_packages(dpkgsrcsn *self, PyObject *args) { char *arch; int archnum; if (!PyArg_ParseTuple(args, "s", &arch)) return NULL; for (archnum = 0; archnum < self->srcsn->n_arches; archnum++) { if (strcmp(arch, self->srcsn->archname[archnum]) == 0) break; } if (archnum == self->srcsn->n_arches) { PyErr_SetString(PyExc_ValueError, "Not a valid architecture"); return NULL; } return dpkgpackages_new(self->srcsn->pkgs[archnum], DONTFREE, (PyObject *) self); } static PyObject *dpkgsrcsn_getversion(dpkgsrcsn *self, PyObject *args) { char *srcname; dpkg_source_note *srcn; if (!PyArg_ParseTuple(args, "s", &srcname)) return NULL; srcn = lookup_sourcenotetbl(self->srcsn->sources, srcname); if (srcn) return Py_BuildValue("s", srcn->source->version); else return Py_BuildValue(""); } static PyObject *dpkgsrcsn_getfield(dpkgsrcsn *self, PyObject *args) { char *srcname, *field; dpkg_source_note *srcn; int i; dpkg_paragraph *para; if (!PyArg_ParseTuple(args, "ss", &srcname, &field)) return NULL; srcn = lookup_sourcenotetbl(self->srcsn->sources, srcname); if (!srcn) { PyErr_SetString(PyExc_ValueError, "Not a valid source package"); return NULL; } para = srcn->source->details; if (para) { for (i = 0; i < para->n_entries; i++) { if (strcasecmp(para->entry[i].name, field) == 0) { return Py_BuildValue("s", para->entry[i].value); } } } return Py_BuildValue(""); } static PyObject *dpkgsrcsn_ispresent(dpkgsrcsn *self, PyObject *args) { char *srcname; if (!PyArg_ParseTuple(args, "s", &srcname)) return NULL; if (lookup_sourcenotetbl(self->srcsn->sources, srcname)) { return Py_BuildValue("i", 1); } else { return Py_BuildValue("i", 0); } } static PyObject *dpkgsrcsn_isfake(dpkgsrcsn *self, PyObject *args) { char *srcname; dpkg_source_note *srcn; if (!PyArg_ParseTuple(args, "s", &srcname)) return NULL; srcn = lookup_sourcenotetbl(self->srcsn->sources, srcname); if (srcn) return Py_BuildValue("i", srcn->source->fake); else return Py_BuildValue(""); } static PyObject *dpkgsrcsn_binaries(dpkgsrcsn *self, PyObject *args) { char *srcname, *arch; int archnum; dpkg_source_note *srcn; PyObject *res; packagelist *p; if (!PyArg_ParseTuple(args, "ss", &srcname, &arch)) return NULL; for (archnum = 0; archnum < self->srcsn->n_arches; archnum++) { if (strcmp(arch, self->srcsn->archname[archnum]) == 0) break; } if (archnum == self->srcsn->n_arches) { PyErr_SetString(PyExc_ValueError, "Not a valid architecture"); return NULL; } srcn = lookup_sourcenotetbl(self->srcsn->sources, srcname); if (srcn == NULL) { PyErr_SetString(PyExc_ValueError, "Not a valid source package"); return NULL; } MAKE_PY_LIST(res, p = srcn->binaries[archnum], p, p = p->next, ("s", p->value->package) ); return res; } static PyObject *dpkgsrcsn_getattr(dpkgsrcsn *self, char *name) { static struct PyMethodDef dpkgsrcsn_methods[] = { { "remove_source", (binaryfunc) dpkgsrcsn_removesource, METH_VARARGS, NULL }, { "upgrade_source", (binaryfunc) dpkgsrcsn_upgradesource, METH_VARARGS, NULL }, { "upgrade_arch", (binaryfunc) dpkgsrcsn_upgradearch, METH_VARARGS, NULL }, { "undo_change", (binaryfunc) dpkgsrcsn_undochange, METH_VARARGS, NULL }, { "commit_changes", (binaryfunc) dpkgsrcsn_commitchanges, METH_VARARGS, NULL }, { "write_notes", (binaryfunc) dpkgsrcsn_writenotes, METH_VARARGS, NULL }, { "Packages", (binaryfunc) dpkgsrcsn_packages, METH_VARARGS, NULL }, { "get_version", (binaryfunc) dpkgsrcsn_getversion, METH_VARARGS, NULL }, { "get_field", (binaryfunc) dpkgsrcsn_getfield, METH_VARARGS, NULL }, { "is_present", (binaryfunc) dpkgsrcsn_ispresent, METH_VARARGS, NULL }, { "is_fake", (binaryfunc) dpkgsrcsn_isfake, METH_VARARGS, NULL }, { "binaries", (binaryfunc) dpkgsrcsn_binaries, METH_VARARGS, NULL }, { NULL, NULL, 0, NULL } }; if (strcmp(name, "arches") == 0) { PyObject *arches; int i; MAKE_PY_LIST(arches, i = 0, i < self->srcsn->n_arches, i++, ("s", self->srcsn->archname[i]) ); return arches; } else if (strcmp(name, "sources") == 0) { PyObject *sources; sourcenotetbl_iter it; MAKE_PY_LIST(sources, it = first_sourcenotetbl(self->srcsn->sources), !done_sourcenotetbl(it), it = next_sourcenotetbl(it), ("s", it.k) ); return sources; } else if (strcmp(name, "can_undo") == 0) { if (can_undo(self->srcsn)) { return Py_BuildValue("i", 1); } else { return Py_BuildValue(""); } } return Py_FindMethod(dpkgsrcsn_methods, (PyObject *)self, name); } static PyTypeObject SourcesNote_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size (0) */ "SourcesNote", /* type name */ sizeof(dpkgsrcsn), /* basicsize */ 0, /* itemsize (0) */ (destructor) dpkgsrcsn_dealloc, (printfunc) 0, (getattrfunc) dpkgsrcsn_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.versioncmp() -- apt version compare function ******************************************************/ static PyObject *apt_versioncmp(PyObject *self, PyObject *args) { char *l, *r; int res; (void)self; /* unused */ if (!PyArg_ParseTuple(args, "ss", &l, &r)) { return NULL; } res = versioncmp(l,r); return Py_BuildValue("i", res); } /************************************************************************** * 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 # PREDEPENDS = 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[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->depends[0] = read_dep_andor(PyString_AsString(pyString)); } else pkg->depends[0] = NULL; pyString = PyList_GetItem(value, 6); if (pyString == NULL) continue; if (pyString != Py_None) { pkg->depends[1] = read_dep_andor(PyString_AsString(pyString)); } else pkg->depends[1] = 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[] = { { "Sources", dpkgsources_new, METH_VARARGS, NULL }, { "SourcesNote", dpkgsrcsn_new, METH_VARARGS, NULL }, { "versioncmp", apt_versioncmp, METH_VARARGS, NULL }, { "buildSystem", build_system, METH_VARARGS, NULL }, { NULL, NULL, 0, NULL } }; void initbritney(void) { Py_InitModule("britney", britneymethods); }