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 
00096 
00199 
00202 struct rpmtransObject_s {
00203     PyObject_HEAD;
00204     rpmdbObject * dbo;
00205     rpmTransactionSet ts;
00206     PyObject * keyList;                 /* keeps reference counts correct */
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     /* This should increment the usage count for me */
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     /* XXX: Copied hack from ../lib/rpminstall.c, rpmErase() */
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 { /* XXX: Note that we automatically choose to remove all matches */
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         /* XXX TODO: rpmlib-4.0.3 can return multiple suggested packages. */
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(isN)", rpmProblemString(myprob),
00461                              myprob->type,
00462                              myprob->str1,
00463                              PyLong_FromLongLong(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}           /* sentinel */
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     /* this will free the keyList, and decrement the ref count of all
00502        the items on the list as well :-) */
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,                              /* ob_size */
00535         "rpmtrans",                     /* tp_name */
00536         sizeof(rpmtransObject),         /* tp_size */
00537         0,                              /* tp_itemsize */
00538         (destructor) rpmtransDealloc,   /* tp_dealloc */
00539         0,                              /* tp_print */
00540         (getattrfunc) rpmtransGetAttr,  /* tp_getattr */
00541         (setattrfunc) rpmtransSetAttr,  /* tp_setattr */
00542         0,                              /* tp_compare */
00543         0,                              /* tp_repr */
00544         0,                              /* tp_as_number */
00545         0,                              /* tp_as_sequence */
00546         0,                              /* tp_as_mapping */
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     /* put packages w/o names at the end */
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 /*          Py_DECREF(list.packages[i]->data); */
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     /* if we're getting a void*, set the error callback to this. */
00797     /* also, we can possibly decref any python callbacks we had  */
00798     /* and set them to NULL.                                     */
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 /* hack to get the current header that's in the transaction set */
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 /*      { "Fopen", (PyCFunction) doFopen, METH_VARARGS, NULL }, */
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 /*      _rpmio_debug = -1; */
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 

Generated on Thu Apr 18 17:34:45 2002 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002