Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

python/rpmmodule.c

Go to the documentation of this file.
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>       /* XXX rpmio.h */
00013 #include <dirent.h>     /* XXX rpmio.h */
00014 #include <locale.h>
00015 #include <time.h>
00016 
00017 #include "Python.h"
00018 #include "rpmio_internal.h"
00019 #include "rpmcli.h"     /* XXX for rpmCheckSig */
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 /* from lib/misc.c */
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;                 /* keeps reference counts correct */
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     /* This should increment the usage count for me */
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     /* XXX: Copied hack from ../lib/rpminstall.c, rpmErase() */
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 { /* XXX: Note that we automatically choose to remove all matches */
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         /* XXX TODO: rpmlib-4.0.3 can return multiple suggested packages. */
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}           /* sentinel */
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     /* this will free the keyList, and decrement the ref count of all
00499        the items on the list as well :-) */
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,                              /* ob_size */
00532         "rpmtrans",                     /* tp_name */
00533         sizeof(rpmtransObject),         /* tp_size */
00534         0,                              /* tp_itemsize */
00535         (destructor) rpmtransDealloc,   /* tp_dealloc */
00536         0,                              /* tp_print */
00537         (getattrfunc) rpmtransGetAttr,  /* tp_getattr */
00538         (setattrfunc) rpmtransSetAttr,  /* tp_setattr */
00539         0,                              /* tp_compare */
00540         0,                              /* tp_repr */
00541         0,                              /* tp_as_number */
00542         0,                              /* tp_as_sequence */
00543         0,                              /* tp_as_mapping */
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     /* put packages w/o names at the end */
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 /*          Py_DECREF(list.packages[i]->data); */
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     /* if we're getting a void*, set the error callback to this. */
00794     /* also, we can possibly decref any python callbacks we had  */
00795     /* and set them to NULL.                                     */
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 /* hack to get the current header that's in the transaction set */
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 /*      { "Fopen", (PyCFunction) doFopen, METH_VARARGS, NULL }, */
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 /*      _rpmio_debug = -1; */
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 

Generated on Sun Feb 2 23:32:03 2003 for rpm by doxygen1.2.18