00001
00005 #include <alloca.h>
00006 #include <errno.h>
00007 #include <fcntl.h>
00008 #include <time.h>
00009 #include <sys/stat.h>
00010 #include <sys/time.h>
00011 #include <unistd.h>
00012 #include <glob.h>
00013 #include <dirent.h>
00014 #include <locale.h>
00015 #include <time.h>
00016
00017 #include "Python.h"
00018 #include "rpmio_internal.h"
00019 #include "rpmcli.h"
00020 #include "misc.h"
00021 #include "header_internal.h"
00022 #include "upgrade.h"
00023
00024 #include "db-py.h"
00025 #include "header-py.h"
00026
00027 extern int _rpmio_debug;
00028
00029 #ifdef __LCLINT__
00030 #undef PyObject_HEAD
00031 #define PyObject_HEAD int _PyObjectHead
00032 #endif
00033
00034 extern int mdfile(const char *fn, unsigned char *digest);
00035
00036 void initrpm(void);
00037
00038
00039 int rpmvercmp(const char * one, const char * two);
00040
00043 typedef struct rpmtransObject_s rpmtransObject;
00044
00194
00197 struct rpmtransObject_s {
00198 PyObject_HEAD;
00199 rpmdbObject * dbo;
00200 rpmTransactionSet ts;
00201 PyObject * keyList;
00202 FD_t scriptFd;
00203 } ;
00204
00207 static PyObject * rpmtransAdd(rpmtransObject * s, PyObject * args) {
00208 hdrObject * h;
00209 PyObject * key;
00210 char * how = NULL;
00211 int isUpgrade = 0;
00212 PyObject * hObj;
00213
00214 if (!PyArg_ParseTuple(args, "OO|s", &h, &key, &how)) return NULL;
00215
00216 hObj = (PyObject *) h;
00217 if (hObj->ob_type != &hdrType) {
00218 PyErr_SetString(PyExc_TypeError, "bad type for header argument");
00219 return NULL;
00220 }
00221
00222 if (how && strcmp(how, "a") && strcmp(how, "u") && strcmp(how, "i")) {
00223 PyErr_SetString(PyExc_TypeError, "how argument must be \"u\", \"a\", or \"i\"");
00224 return NULL;
00225 } else if (how && !strcmp(how, "u"))
00226 isUpgrade = 1;
00227
00228 if (how && !strcmp(how, "a"))
00229 rpmtransAvailablePackage(s->ts, hdrGetHeader(h), key);
00230 else
00231 rpmtransAddPackage(s->ts, hdrGetHeader(h), NULL, key, isUpgrade, NULL);
00232
00233
00234 if (key) {
00235 PyList_Append(s->keyList, key);
00236 }
00237
00238 Py_INCREF(Py_None);
00239 return Py_None;
00240 }
00241
00244 static PyObject * rpmtransRemove(rpmtransObject * s, PyObject * args) {
00245 char * name;
00246 int count;
00247 rpmdbMatchIterator mi;
00248
00249 if (!PyArg_ParseTuple(args, "s", &name))
00250 return NULL;
00251
00252
00253 mi = rpmdbInitIterator(dbFromDb(s->dbo), RPMDBI_LABEL, name, 0);
00254 count = rpmdbGetIteratorCount(mi);
00255 if (count <= 0) {
00256 PyErr_SetString(pyrpmError, "package not installed");
00257 return NULL;
00258 } else {
00259 Header h;
00260 while ((h = rpmdbNextIterator(mi)) != NULL) {
00261 unsigned int recOffset = rpmdbGetIteratorOffset(mi);
00262 if (recOffset) {
00263 rpmtransRemovePackage(s->ts, recOffset);
00264 }
00265 }
00266 }
00267 rpmdbFreeIterator(mi);
00268
00269 Py_INCREF(Py_None);
00270 return Py_None;
00271 }
00272
00275 static PyObject * rpmtransDepCheck(rpmtransObject * s, PyObject * args) {
00276 rpmDependencyConflict conflicts;
00277 int numConflicts;
00278 PyObject * list, * cf, * suggestions;
00279 int i, j;
00280 int allSuggestions = 0;
00281
00282 if (!PyArg_ParseTuple(args, "|i", &allSuggestions)) return NULL;
00283
00284 rpmdepCheck(s->ts, &conflicts, &numConflicts);
00285 if (numConflicts) {
00286 list = PyList_New(0);
00287
00288
00289 for (i = 0; i < numConflicts; i++) {
00290 if (!conflicts[i].suggestedPackages)
00291 suggestions = Py_None;
00292 else if (!allSuggestions)
00293 suggestions = conflicts[i].suggestedPackages[0];
00294 else {
00295 suggestions = PyList_New(0);
00296
00297 for (j = 0; conflicts[i].suggestedPackages[j]; j++)
00298 PyList_Append(suggestions,
00299 conflicts[i].suggestedPackages[j]);
00300 }
00301
00302 cf = Py_BuildValue("((sss)(ss)iOi)", conflicts[i].byName,
00303 conflicts[i].byVersion, conflicts[i].byRelease,
00304
00305 conflicts[i].needsName,
00306 conflicts[i].needsVersion,
00307
00308 conflicts[i].needsFlags,
00309 suggestions,
00310 conflicts[i].sense);
00311 PyList_Append(list, (PyObject *) cf);
00312 Py_DECREF(cf);
00313 }
00314
00315 conflicts = rpmdepFreeConflicts(conflicts, numConflicts);
00316
00317 return list;
00318 }
00319
00320 Py_INCREF(Py_None);
00321 return Py_None;
00322 }
00323
00326 static PyObject * rpmtransOrder(rpmtransObject * s, PyObject * args) {
00327 if (!PyArg_ParseTuple(args, "")) return NULL;
00328
00329 rpmdepOrder(s->ts);
00330
00331 Py_INCREF(Py_None);
00332 return Py_None;
00333 }
00334
00337 static PyObject * py_rpmtransGetKeys(rpmtransObject * s, PyObject * args) {
00338 const void **data = NULL;
00339 int num, i;
00340 PyObject *tuple;
00341
00342 rpmtransGetKeys(s->ts, &data, &num);
00343 if (data == NULL || num <= 0) {
00344 data = _free(data);
00345 Py_INCREF(Py_None);
00346 return Py_None;
00347 }
00348
00349 tuple = PyTuple_New(num);
00350
00351 for (i = 0; i < num; i++) {
00352 PyObject *obj;
00353 obj = (data[i] ? (PyObject *) data[i] : Py_None);
00354 Py_INCREF(obj);
00355 PyTuple_SetItem(tuple, i, obj);
00356 }
00357
00358 data = _free(data);
00359
00360 return tuple;
00361 }
00362
00365 struct tsCallbackType {
00366 PyObject * cb;
00367 PyObject * data;
00368 int pythonError;
00369 };
00370
00374 static Header transactionSetHeader = NULL;
00375
00378 static void * tsCallback(const void * hd, const rpmCallbackType what,
00379 const unsigned long amount, const unsigned long total,
00380 const void * pkgKey, rpmCallbackData data) {
00381 struct tsCallbackType * cbInfo = data;
00382 PyObject * args, * result;
00383 int fd;
00384 static FD_t fdt;
00385 const Header h = (Header) hd;
00386
00387 if (cbInfo->pythonError) return NULL;
00388 if (cbInfo->cb == Py_None) return NULL;
00389
00390 if (!pkgKey) pkgKey = Py_None;
00391 transactionSetHeader = h;
00392
00393 args = Py_BuildValue("(illOO)", what, amount, total, pkgKey, cbInfo->data);
00394 result = PyEval_CallObject(cbInfo->cb, args);
00395 Py_DECREF(args);
00396
00397 if (!result) {
00398 cbInfo->pythonError = 1;
00399 return NULL;
00400 }
00401
00402 if (what == RPMCALLBACK_INST_OPEN_FILE) {
00403 if (!PyArg_Parse(result, "i", &fd)) {
00404 cbInfo->pythonError = 1;
00405 return NULL;
00406 }
00407 fdt = fdDup(fd);
00408
00409 Py_DECREF(result);
00410 return fdt;
00411 }
00412
00413 if (what == RPMCALLBACK_INST_CLOSE_FILE) {
00414 Fclose (fdt);
00415 }
00416
00417 Py_DECREF(result);
00418
00419 return NULL;
00420 }
00421
00424 static PyObject * rpmtransRun(rpmtransObject * s, PyObject * args) {
00425 int flags, ignoreSet;
00426 int rc, i;
00427 PyObject * list, * prob;
00428 rpmProblemSet probs;
00429 struct tsCallbackType cbInfo;
00430
00431 if (!PyArg_ParseTuple(args, "iiOO", &flags, &ignoreSet, &cbInfo.cb,
00432 &cbInfo.data))
00433 return NULL;
00434
00435 cbInfo.pythonError = 0;
00436
00437 rc = rpmRunTransactions(s->ts, tsCallback, &cbInfo, NULL, &probs, flags,
00438 ignoreSet);
00439
00440 if (cbInfo.pythonError) {
00441 if (rc > 0)
00442 rpmProblemSetFree(probs);
00443 return NULL;
00444 }
00445
00446 if (rc < 0) {
00447 list = PyList_New(0);
00448 return list;
00449 } else if (!rc) {
00450 Py_INCREF(Py_None);
00451 return Py_None;
00452 }
00453
00454 list = PyList_New(0);
00455 for (i = 0; i < probs->numProblems; i++) {
00456 rpmProblem myprob = probs->probs + i;
00457 prob = Py_BuildValue("s(isN)", rpmProblemString(myprob),
00458 myprob->type,
00459 myprob->str1,
00460 PyLong_FromLongLong(myprob->ulong1));
00461 PyList_Append(list, prob);
00462 Py_DECREF(prob);
00463 }
00464
00465 rpmProblemSetFree(probs);
00466
00467 return list;
00468 }
00469
00472 static struct PyMethodDef rpmtransMethods[] = {
00473 {"add", (PyCFunction) rpmtransAdd, 1 },
00474 {"remove", (PyCFunction) rpmtransRemove, 1 },
00475 {"depcheck", (PyCFunction) rpmtransDepCheck, 1 },
00476 {"order", (PyCFunction) rpmtransOrder, 1 },
00477 {"getKeys", (PyCFunction) py_rpmtransGetKeys, 1 },
00478 {"run", (PyCFunction) rpmtransRun, 1 },
00479 {NULL, NULL}
00480 };
00481
00484 static PyObject * rpmtransGetAttr(rpmtransObject * o, char * name) {
00485 return Py_FindMethod(rpmtransMethods, (PyObject *) o, name);
00486 }
00487
00490 static void rpmtransDealloc(PyObject * o) {
00491 rpmtransObject * trans = (void *) o;
00492
00493 rpmtransFree(trans->ts);
00494 if (trans->dbo) {
00495 Py_DECREF(trans->dbo);
00496 }
00497 if (trans->scriptFd) Fclose(trans->scriptFd);
00498
00499
00500 Py_DECREF(trans->keyList);
00501 PyMem_DEL(o);
00502 }
00503
00506 static int rpmtransSetAttr(rpmtransObject * o, char * name,
00507 PyObject * val) {
00508 int i;
00509
00510 if (!strcmp(name, "scriptFd")) {
00511 if (!PyArg_Parse(val, "i", &i)) return 0;
00512 if (i < 0) {
00513 PyErr_SetString(PyExc_TypeError, "bad file descriptor");
00514 return -1;
00515 } else {
00516 o->scriptFd = fdDup(i);
00517 rpmtransSetScriptFd(o->ts, o->scriptFd);
00518 }
00519 } else {
00520 PyErr_SetString(PyExc_AttributeError, name);
00521 return -1;
00522 }
00523
00524 return 0;
00525 }
00526
00529 static PyTypeObject rpmtransType = {
00530 PyObject_HEAD_INIT(NULL)
00531 0,
00532 "rpmtrans",
00533 sizeof(rpmtransObject),
00534 0,
00535 (destructor) rpmtransDealloc,
00536 0,
00537 (getattrfunc) rpmtransGetAttr,
00538 (setattrfunc) rpmtransSetAttr,
00539 0,
00540 0,
00541 0,
00542 0,
00543 0,
00544 };
00545
00552
00555 static PyObject * rpmtransCreate(PyObject * self, PyObject * args) {
00556 rpmtransObject * o;
00557 rpmdbObject * db = NULL;
00558 char * rootPath = "/";
00559
00560 if (!PyArg_ParseTuple(args, "|sO", &rootPath, &db)) return NULL;
00561 if (db && ((PyObject *) db)->ob_type != &rpmdbType) {
00562 PyErr_SetString(PyExc_TypeError, "bad type for database argument");
00563 return NULL;
00564 }
00565
00566 o = (void *) PyObject_NEW(rpmtransObject, &rpmtransType);
00567
00568 Py_XINCREF(db);
00569 o->dbo = db;
00570 o->scriptFd = NULL;
00571 o->ts = rpmtransCreateSet(db ? dbFromDb(db) : NULL, rootPath);
00572 o->keyList = PyList_New(0);
00573
00574 return (void *) o;
00575 }
00576
00579 static PyObject * doAddMacro(PyObject * self, PyObject * args) {
00580 char * name, * val;
00581
00582 if (!PyArg_ParseTuple(args, "ss", &name, &val))
00583 return NULL;
00584
00585 addMacro(NULL, name, NULL, val, RMIL_DEFAULT);
00586
00587 Py_INCREF(Py_None);
00588 return Py_None;
00589 }
00590
00593 static PyObject * doDelMacro(PyObject * self, PyObject * args) {
00594 char * name;
00595
00596 if (!PyArg_ParseTuple(args, "s", &name))
00597 return NULL;
00598
00599 delMacro(NULL, name);
00600
00601 Py_INCREF(Py_None);
00602 return Py_None;
00603 }
00604
00607 static PyObject * archScore(PyObject * self, PyObject * args) {
00608 char * arch;
00609 int score;
00610
00611 if (!PyArg_ParseTuple(args, "s", &arch))
00612 return NULL;
00613
00614 score = rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch);
00615
00616 return Py_BuildValue("i", score);
00617 }
00618
00621 static int psGetArchScore(Header h) {
00622 void * pkgArch;
00623 int type, count;
00624
00625 if (!headerGetEntry(h, RPMTAG_ARCH, &type, (void **) &pkgArch, &count) ||
00626 type == RPM_INT8_TYPE)
00627 return 150;
00628 else
00629 return rpmMachineScore(RPM_MACHTABLE_INSTARCH, pkgArch);
00630 }
00631
00634 static int pkgCompareVer(void * first, void * second) {
00635 struct packageInfo ** a = first;
00636 struct packageInfo ** b = second;
00637 int ret, score1, score2;
00638
00639
00640 if (!(*a)->name) return 1;
00641 if (!(*b)->name) return -1;
00642
00643 ret = xstrcasecmp((*a)->name, (*b)->name);
00644 if (ret) return ret;
00645 score1 = psGetArchScore((*a)->h);
00646 if (!score1) return 1;
00647 score2 = psGetArchScore((*b)->h);
00648 if (!score2) return -1;
00649 if (score1 < score2) return -1;
00650 if (score1 > score2) return 1;
00651 return rpmVersionCompare((*b)->h, (*a)->h);
00652 }
00653
00656 static void pkgSort(struct pkgSet * psp) {
00657 int i;
00658 char *name;
00659
00660 if (psp->numPackages <= 0)
00661 return;
00662
00663 qsort(psp->packages, psp->numPackages, sizeof(*psp->packages),
00664 (void *) pkgCompareVer);
00665
00666 name = psp->packages[0]->name;
00667 if (!name) {
00668 psp->numPackages = 0;
00669 return;
00670 }
00671 for (i = 1; i < psp->numPackages; i++) {
00672 if (!psp->packages[i]->name) break;
00673 if (!strcmp(psp->packages[i]->name, name))
00674 psp->packages[i]->name = NULL;
00675 else
00676 name = psp->packages[i]->name;
00677 }
00678
00679 qsort(psp->packages, psp->numPackages, sizeof(*psp->packages),
00680 (void *) pkgCompareVer);
00681
00682 for (i = 0; i < psp->numPackages; i++)
00683 if (!psp->packages[i]->name) break;
00684 psp->numPackages = i;
00685 }
00686
00689 static PyObject * findUpgradeSet(PyObject * self, PyObject * args) {
00690 PyObject * hdrList, * result;
00691 char * root = "/";
00692 int i;
00693 struct pkgSet list;
00694 hdrObject * hdr;
00695
00696 if (!PyArg_ParseTuple(args, "O|s", &hdrList, &root)) return NULL;
00697
00698 if (!PyList_Check(hdrList)) {
00699 PyErr_SetString(PyExc_TypeError, "list of headers expected");
00700 return NULL;
00701 }
00702
00703 list.numPackages = PyList_Size(hdrList);
00704 list.packages = alloca(sizeof(list.packages) * list.numPackages);
00705 for (i = 0; i < list.numPackages; i++) {
00706 hdr = (hdrObject *) PyList_GetItem(hdrList, i);
00707 if (((PyObject *) hdr)->ob_type != &hdrType) {
00708 PyErr_SetString(PyExc_TypeError, "list of headers expected");
00709 return NULL;
00710 }
00711 list.packages[i] = alloca(sizeof(struct packageInfo));
00712 list.packages[i]->h = hdrGetHeader(hdr);
00713 list.packages[i]->selected = 0;
00714 list.packages[i]->data = hdr;
00715
00716 headerGetEntry(list.packages[i]->h, RPMTAG_NAME, NULL,
00717 (void **) &list.packages[i]->name, NULL);
00718 }
00719
00720 pkgSort (&list);
00721
00722 if (ugFindUpgradePackages(&list, root)) {
00723 PyErr_SetString(pyrpmError, "error during upgrade check");
00724 return NULL;
00725 }
00726
00727 result = PyList_New(0);
00728 for (i = 0; i < list.numPackages; i++) {
00729 if (list.packages[i]->selected) {
00730 PyList_Append(result, list.packages[i]->data);
00731
00732 }
00733 }
00734
00735 return result;
00736 }
00737
00740 static PyObject * rpmInitDB(PyObject * self, PyObject * args) {
00741 char *root;
00742 int forWrite = 0;
00743
00744 if (!PyArg_ParseTuple(args, "i|s", &forWrite, &root)) return NULL;
00745
00746 if (rpmdbInit(root, forWrite ? O_RDWR | O_CREAT: O_RDONLY)) {
00747 char * errmsg = "cannot initialize database in %s";
00748 char * errstr = NULL;
00749 int errsize;
00750
00751 errsize = strlen(errmsg) + strlen(root);
00752 errstr = alloca(errsize);
00753 snprintf(errstr, errsize, errmsg, root);
00754 PyErr_SetString(pyrpmError, errstr);
00755 return NULL;
00756 }
00757
00758 Py_INCREF(Py_None);
00759 return(Py_None);
00760 }
00761
00762
00765 static PyObject * errorCB = NULL, * errorData = NULL;
00766
00769 static void errorcb (void)
00770 {
00771 PyObject * result, * args = NULL;
00772
00773 if (errorData)
00774 args = Py_BuildValue("(O)", errorData);
00775
00776 result = PyEval_CallObject(errorCB, args);
00777 Py_XDECREF(args);
00778
00779 if (result == NULL) {
00780 PyErr_Print();
00781 PyErr_Clear();
00782 }
00783 Py_DECREF (result);
00784 }
00785
00788 static PyObject * errorSetCallback (PyObject * self, PyObject * args) {
00789 PyObject *newCB = NULL, *newData = NULL;
00790
00791 if (!PyArg_ParseTuple(args, "O|O", &newCB, &newData)) return NULL;
00792
00793
00794
00795
00796 if (PyCObject_Check (newCB)) {
00797 rpmErrorSetCallback (PyCObject_AsVoidPtr(newCB));
00798
00799 Py_XDECREF (errorCB);
00800 Py_XDECREF (errorData);
00801
00802 errorCB = NULL;
00803 errorData = NULL;
00804
00805 Py_INCREF(Py_None);
00806 return Py_None;
00807 }
00808
00809 if (!PyCallable_Check (newCB)) {
00810 PyErr_SetString(PyExc_TypeError, "parameter must be callable");
00811 return NULL;
00812 }
00813
00814 Py_XDECREF(errorCB);
00815 Py_XDECREF(errorData);
00816
00817 errorCB = newCB;
00818 errorData = newData;
00819
00820 Py_INCREF (errorCB);
00821 Py_XINCREF (errorData);
00822
00823 return PyCObject_FromVoidPtr(rpmErrorSetCallback (errorcb), NULL);
00824 }
00825
00828 static PyObject * errorString (PyObject * self, PyObject * args) {
00829 return PyString_FromString(rpmErrorString ());
00830 }
00831
00834 static PyObject * checkSig (PyObject * self, PyObject * args) {
00835 char * filename;
00836 int flags;
00837 int rc = 255;
00838
00839 if (PyArg_ParseTuple(args, "si", &filename, &flags)) {
00840 const char *av[2];
00841 av[0] = filename;
00842 av[1] = NULL;
00843 rc = rpmCheckSig(flags, av);
00844 }
00845 return Py_BuildValue("i", rc);
00846 }
00847
00848
00851 static PyObject * getTsHeader (PyObject * self, PyObject * args) {
00852 if (!PyArg_ParseTuple(args, ""))
00853 return NULL;
00854
00855 if (transactionSetHeader) {
00856 return (PyObject *) createHeaderObject(transactionSetHeader);;
00857 }
00858 Py_INCREF(Py_None);
00859 return (PyObject *) Py_None;
00860 }
00861
00862
00863 static PyObject * setVerbosity (PyObject * self, PyObject * args) {
00864 int level;
00865
00866 if (!PyArg_ParseTuple(args, "i", &level))
00867 return NULL;
00868
00869 rpmSetVerbosity(level);
00870
00871 Py_INCREF(Py_None);
00872 return (PyObject *) Py_None;
00873 }
00874
00877 typedef struct FDlist_t FDlist;
00878
00881 struct FDlist_t {
00882 FILE *f;
00883 FD_t fd;
00884 char *note;
00885 FDlist *next;
00886 } ;
00887
00890 static FDlist *fdhead = NULL;
00891
00894 static FDlist *fdtail = NULL;
00895
00898 static int closeCallback(FILE * f) {
00899 FDlist *node, *last;
00900
00901 printf ("close callback on %p\n", f);
00902
00903 node = fdhead;
00904 last = NULL;
00905 while (node) {
00906 if (node->f == f)
00907 break;
00908 last = node;
00909 node = node->next;
00910 }
00911 if (node) {
00912 if (last)
00913 last->next = node->next;
00914 else
00915 fdhead = node->next;
00916 printf ("closing %s %p\n", node->note, node->fd);
00917 free (node->note);
00918 node->fd = fdLink(node->fd, "closeCallback");
00919 Fclose (node->fd);
00920 while (node->fd)
00921 node->fd = fdFree(node->fd, "closeCallback");
00922 free (node);
00923 }
00924 return 0;
00925 }
00926
00929 static PyObject * doFopen(PyObject * self, PyObject * args) {
00930 char * path, * mode;
00931 FDlist *node;
00932
00933 if (!PyArg_ParseTuple(args, "ss", &path, &mode))
00934 return NULL;
00935
00936 node = malloc (sizeof(FDlist));
00937
00938 node->fd = Fopen(path, mode);
00939 node->fd = fdLink(node->fd, "doFopen");
00940 node->note = strdup (path);
00941
00942 if (!node->fd) {
00943 PyErr_SetFromErrno(pyrpmError);
00944 free (node);
00945 return NULL;
00946 }
00947
00948 if (Ferror(node->fd)) {
00949 const char *err = Fstrerror(node->fd);
00950 free(node);
00951 if (err) {
00952 PyErr_SetString(pyrpmError, err);
00953 return NULL;
00954 }
00955 }
00956 node->f = fdGetFp(node->fd);
00957 printf ("opening %s fd = %p f = %p\n", node->note, node->fd, node->f);
00958 if (!node->f) {
00959 PyErr_SetString(pyrpmError, "FD_t has no FILE*");
00960 free(node);
00961 return NULL;
00962 }
00963
00964 node->next = NULL;
00965 if (!fdhead) {
00966 fdhead = fdtail = node;
00967 } else if (fdtail) {
00968 fdtail->next = node;
00969 } else {
00970 fdhead = node;
00971 }
00972 fdtail = node;
00973
00974 return PyFile_FromFile (node->f, path, mode, closeCallback);
00975 }
00976
00979 static PyMethodDef rpmModuleMethods[] = {
00980 { "TransactionSet", (PyCFunction) rpmtransCreate, METH_VARARGS, NULL },
00981 { "addMacro", (PyCFunction) doAddMacro, METH_VARARGS, NULL },
00982 { "delMacro", (PyCFunction) doDelMacro, METH_VARARGS, NULL },
00983 { "archscore", (PyCFunction) archScore, METH_VARARGS, NULL },
00984 { "findUpgradeSet", (PyCFunction) findUpgradeSet, METH_VARARGS, NULL },
00985 { "headerFromPackage", (PyCFunction) rpmHeaderFromPackage, METH_VARARGS, NULL },
00986 { "headerLoad", (PyCFunction) hdrLoad, METH_VARARGS, NULL },
00987 { "rhnLoad", (PyCFunction) rhnLoad, METH_VARARGS, NULL },
00988 { "initdb", (PyCFunction) rpmInitDB, METH_VARARGS, NULL },
00989 { "opendb", (PyCFunction) rpmOpenDB, METH_VARARGS, NULL },
00990 { "rebuilddb", (PyCFunction) rebuildDB, METH_VARARGS, NULL },
00991 { "mergeHeaderListFromFD", (PyCFunction) rpmMergeHeadersFromFD, METH_VARARGS, NULL },
00992 { "readHeaderListFromFD", (PyCFunction) rpmHeaderFromFD, METH_VARARGS, NULL },
00993 { "readHeaderListFromFile", (PyCFunction) rpmHeaderFromFile, METH_VARARGS, NULL },
00994 { "errorSetCallback", (PyCFunction) errorSetCallback, METH_VARARGS, NULL },
00995 { "errorString", (PyCFunction) errorString, METH_VARARGS, NULL },
00996 { "versionCompare", (PyCFunction) versionCompare, METH_VARARGS, NULL },
00997 { "labelCompare", (PyCFunction) labelCompare, METH_VARARGS, NULL },
00998 { "checksig", (PyCFunction) checkSig, METH_VARARGS, NULL },
00999 { "getTransactionCallbackHeader", (PyCFunction) getTsHeader, METH_VARARGS, NULL },
01000
01001 { "setVerbosity", (PyCFunction) setVerbosity, METH_VARARGS, NULL },
01002 { NULL }
01003 } ;
01004
01007 void initrpm(void) {
01008 PyObject * m, * d, *o, * tag = NULL, * dict;
01009 int i;
01010 const struct headerSprintfExtension_s * extensions = rpmHeaderFormats;
01011 struct headerSprintfExtension_s * ext;
01012
01013 m = Py_InitModule("rpm", rpmModuleMethods);
01014
01015 hdrType.ob_type = &PyType_Type;
01016 rpmdbMIType.ob_type = &PyType_Type;
01017 rpmdbType.ob_type = &PyType_Type;
01018 rpmtransType.ob_type = &PyType_Type;
01019
01020 if(!m)
01021 return;
01022
01023
01024 rpmReadConfigFiles(NULL, NULL);
01025
01026 d = PyModule_GetDict(m);
01027
01028 pyrpmError = PyString_FromString("rpm.error");
01029 PyDict_SetItemString(d, "error", pyrpmError);
01030 Py_DECREF(pyrpmError);
01031
01032 dict = PyDict_New();
01033
01034 for (i = 0; i < rpmTagTableSize; i++) {
01035 tag = PyInt_FromLong(rpmTagTable[i].val);
01036 PyDict_SetItemString(d, (char *) rpmTagTable[i].name, tag);
01037 Py_DECREF(tag);
01038 PyDict_SetItem(dict, tag, o=PyString_FromString(rpmTagTable[i].name + 7));
01039 Py_DECREF(o);
01040 }
01041
01042 while (extensions->name) {
01043 if (extensions->type == HEADER_EXT_TAG) {
01044 (const struct headerSprintfExtension *) ext = extensions;
01045 PyDict_SetItemString(d, extensions->name, o=PyCObject_FromVoidPtr(ext, NULL));
01046 Py_DECREF(o);
01047 PyDict_SetItem(dict, tag, o=PyString_FromString(ext->name + 7));
01048 Py_DECREF(o);
01049 }
01050 extensions++;
01051 }
01052
01053 PyDict_SetItemString(d, "tagnames", dict);
01054 Py_DECREF(dict);
01055
01056
01057 #define REGISTER_ENUM(val) \
01058 PyDict_SetItemString(d, #val, o=PyInt_FromLong( val )); \
01059 Py_DECREF(o);
01060
01061 REGISTER_ENUM(RPMFILE_STATE_NORMAL);
01062 REGISTER_ENUM(RPMFILE_STATE_REPLACED);
01063 REGISTER_ENUM(RPMFILE_STATE_NOTINSTALLED);
01064 REGISTER_ENUM(RPMFILE_STATE_NETSHARED);
01065
01066 REGISTER_ENUM(RPMFILE_CONFIG);
01067 REGISTER_ENUM(RPMFILE_DOC);
01068 REGISTER_ENUM(RPMFILE_MISSINGOK);
01069 REGISTER_ENUM(RPMFILE_NOREPLACE);
01070 REGISTER_ENUM(RPMFILE_GHOST);
01071 REGISTER_ENUM(RPMFILE_LICENSE);
01072 REGISTER_ENUM(RPMFILE_README);
01073
01074 REGISTER_ENUM(RPMDEP_SENSE_REQUIRES);
01075 REGISTER_ENUM(RPMDEP_SENSE_CONFLICTS);
01076
01077 REGISTER_ENUM(RPMSENSE_SERIAL);
01078 REGISTER_ENUM(RPMSENSE_LESS);
01079 REGISTER_ENUM(RPMSENSE_GREATER);
01080 REGISTER_ENUM(RPMSENSE_EQUAL);
01081 REGISTER_ENUM(RPMSENSE_PREREQ);
01082 REGISTER_ENUM(RPMSENSE_INTERP);
01083 REGISTER_ENUM(RPMSENSE_SCRIPT_PRE);
01084 REGISTER_ENUM(RPMSENSE_SCRIPT_POST);
01085 REGISTER_ENUM(RPMSENSE_SCRIPT_PREUN);
01086 REGISTER_ENUM(RPMSENSE_SCRIPT_POSTUN);
01087 REGISTER_ENUM(RPMSENSE_SCRIPT_VERIFY);
01088 REGISTER_ENUM(RPMSENSE_FIND_REQUIRES);
01089 REGISTER_ENUM(RPMSENSE_FIND_PROVIDES);
01090 REGISTER_ENUM(RPMSENSE_TRIGGERIN);
01091 REGISTER_ENUM(RPMSENSE_TRIGGERUN);
01092 REGISTER_ENUM(RPMSENSE_TRIGGERPOSTUN);
01093 REGISTER_ENUM(RPMSENSE_MULTILIB);
01094 REGISTER_ENUM(RPMSENSE_SCRIPT_PREP);
01095 REGISTER_ENUM(RPMSENSE_SCRIPT_BUILD);
01096 REGISTER_ENUM(RPMSENSE_SCRIPT_INSTALL);
01097 REGISTER_ENUM(RPMSENSE_SCRIPT_CLEAN);
01098 REGISTER_ENUM(RPMSENSE_RPMLIB);
01099 REGISTER_ENUM(RPMSENSE_TRIGGERPREIN);
01100
01101 REGISTER_ENUM(RPMTRANS_FLAG_TEST);
01102 REGISTER_ENUM(RPMTRANS_FLAG_BUILD_PROBS);
01103 REGISTER_ENUM(RPMTRANS_FLAG_NOSCRIPTS);
01104 REGISTER_ENUM(RPMTRANS_FLAG_JUSTDB);
01105 REGISTER_ENUM(RPMTRANS_FLAG_NOTRIGGERS);
01106 REGISTER_ENUM(RPMTRANS_FLAG_NODOCS);
01107 REGISTER_ENUM(RPMTRANS_FLAG_ALLFILES);
01108 REGISTER_ENUM(RPMTRANS_FLAG_KEEPOBSOLETE);
01109 REGISTER_ENUM(RPMTRANS_FLAG_MULTILIB);
01110
01111 REGISTER_ENUM(RPMPROB_FILTER_IGNOREOS);
01112 REGISTER_ENUM(RPMPROB_FILTER_IGNOREARCH);
01113 REGISTER_ENUM(RPMPROB_FILTER_REPLACEPKG);
01114 REGISTER_ENUM(RPMPROB_FILTER_FORCERELOCATE);
01115 REGISTER_ENUM(RPMPROB_FILTER_REPLACENEWFILES);
01116 REGISTER_ENUM(RPMPROB_FILTER_REPLACEOLDFILES);
01117 REGISTER_ENUM(RPMPROB_FILTER_OLDPACKAGE);
01118 REGISTER_ENUM(RPMPROB_FILTER_DISKSPACE);
01119 REGISTER_ENUM(RPMPROB_FILTER_DISKNODES);
01120
01121 REGISTER_ENUM(RPMCALLBACK_INST_PROGRESS);
01122 REGISTER_ENUM(RPMCALLBACK_INST_START);
01123 REGISTER_ENUM(RPMCALLBACK_INST_OPEN_FILE);
01124 REGISTER_ENUM(RPMCALLBACK_INST_CLOSE_FILE);
01125 REGISTER_ENUM(RPMCALLBACK_TRANS_PROGRESS);
01126 REGISTER_ENUM(RPMCALLBACK_TRANS_START);
01127 REGISTER_ENUM(RPMCALLBACK_TRANS_STOP);
01128 REGISTER_ENUM(RPMCALLBACK_UNINST_PROGRESS);
01129 REGISTER_ENUM(RPMCALLBACK_UNINST_START);
01130 REGISTER_ENUM(RPMCALLBACK_UNINST_STOP);
01131 REGISTER_ENUM(RPMCALLBACK_UNPACK_ERROR);
01132 REGISTER_ENUM(RPMCALLBACK_CPIO_ERROR);
01133
01134 REGISTER_ENUM(RPMPROB_BADARCH);
01135 REGISTER_ENUM(RPMPROB_BADOS);
01136 REGISTER_ENUM(RPMPROB_PKG_INSTALLED);
01137 REGISTER_ENUM(RPMPROB_BADRELOCATE);
01138 REGISTER_ENUM(RPMPROB_REQUIRES);
01139 REGISTER_ENUM(RPMPROB_CONFLICT);
01140 REGISTER_ENUM(RPMPROB_NEW_FILE_CONFLICT);
01141 REGISTER_ENUM(RPMPROB_FILE_CONFLICT);
01142 REGISTER_ENUM(RPMPROB_OLDPACKAGE);
01143 REGISTER_ENUM(RPMPROB_DISKSPACE);
01144 REGISTER_ENUM(RPMPROB_DISKNODES);
01145 REGISTER_ENUM(RPMPROB_BADPRETRANS);
01146
01147 REGISTER_ENUM(CHECKSIG_PGP);
01148 REGISTER_ENUM(CHECKSIG_GPG);
01149 REGISTER_ENUM(CHECKSIG_MD5);
01150
01151 REGISTER_ENUM(RPMLOG_EMERG);
01152 REGISTER_ENUM(RPMLOG_ALERT);
01153 REGISTER_ENUM(RPMLOG_CRIT);
01154 REGISTER_ENUM(RPMLOG_ERR);
01155 REGISTER_ENUM(RPMLOG_WARNING);
01156 REGISTER_ENUM(RPMLOG_NOTICE);
01157 REGISTER_ENUM(RPMLOG_INFO);
01158 REGISTER_ENUM(RPMLOG_DEBUG);
01159
01160 REGISTER_ENUM(RPMMIRE_DEFAULT);
01161 REGISTER_ENUM(RPMMIRE_STRCMP);
01162 REGISTER_ENUM(RPMMIRE_REGEX);
01163 REGISTER_ENUM(RPMMIRE_GLOB);
01164
01165 }
01166