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