python/rpmts-py.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #include <rpmcli.h>
00008 #include <rpmpgp.h>
00009 #include <rpmdb.h>
00010 #include <rpmbuild.h>
00011 
00012 #include "header-py.h"
00013 #include "rpmds-py.h"   /* XXX for rpmdsNew */
00014 #include "rpmfi-py.h"   /* XXX for rpmfiNew */
00015 #include "rpmmi-py.h"
00016 #include "rpmps-py.h"
00017 #include "rpmte-py.h"
00018 #include "spec-py.h"
00019 
00020 #define _RPMTS_INTERNAL /* XXX for ts->rdb, ts->availablePackage */
00021 #include "rpmts-py.h"
00022 
00023 #include "debug.h"
00024 
00025 /*@unchecked@*/
00026 /*@-shadow@*/
00027 extern int _rpmts_debug;
00028 /*@=shadow@*/
00029 
00030 /*@access alKey @*/
00031 /*@access FD_t @*/
00032 /*@access Header @*/
00033 /*@access rpmal @*/
00034 /*@access rpmdb @*/
00035 /*@access rpmds @*/
00036 /*@access rpmts @*/
00037 /*@access rpmtsi @*/
00038 
00159 struct rpmtsCallbackType_s {
00160     PyObject * cb;
00161     PyObject * data;
00162     rpmtsObject * tso;
00163     int pythonError;
00164     PyThreadState *_save;
00165 };
00166 
00169 /*@null@*/
00170 static PyObject *
00171 rpmts_Debug(/*@unused@*/ rpmtsObject * s, PyObject * args, PyObject * kwds)
00172         /*@globals _Py_NoneStruct @*/
00173         /*@modifies _Py_NoneStruct @*/
00174 {
00175     char * kwlist[] = {"debugLevel", NULL};
00176 
00177     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Debug", kwlist,
00178             &_rpmts_debug))
00179         return NULL;
00180 
00181 if (_rpmts_debug < 0)
00182 fprintf(stderr, "*** rpmts_Debug(%p) ts %p\n", s, s->ts);
00183 
00184     Py_INCREF(Py_None);
00185     return Py_None;
00186 }
00187 
00194 static void rpmtsAddAvailableElement(rpmts ts, Header h,
00195                 /*@exposed@*/ /*@null@*/ fnpyKey key)
00196         /*@globals rpmGlobalMacroContext @*/
00197         /*@modifies h, ts, rpmGlobalMacroContext @*/
00198 {
00199     int scareMem = 0;
00200     rpmds provides = rpmdsNew(h, RPMTAG_PROVIDENAME, scareMem);
00201     rpmfi fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
00202 
00203     /* XXX FIXME: return code RPMAL_NOMATCH is error */
00204     (void) rpmalAdd(&ts->availablePackages, RPMAL_NOMATCH, key,
00205                 provides, fi, rpmtsColor(ts));
00206     fi = rpmfiFree(fi);
00207     provides = rpmdsFree(provides);
00208 
00209 if (_rpmts_debug < 0)
00210 fprintf(stderr, "\tAddAvailable(%p) list %p\n", ts, ts->availablePackages);
00211 
00212 }
00213 
00216 /*@null@*/
00217 static PyObject *
00218 rpmts_AddInstall(rpmtsObject * s, PyObject * args, PyObject * kwds)
00219         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00220         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00221 {
00222     hdrObject * h;
00223     PyObject * key;
00224     char * how = "u";   /* XXX default to upgrade element if missing */
00225     int isUpgrade = 0;
00226     char * kwlist[] = {"header", "key", "how", NULL};
00227 
00228     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O|s:AddInstall", kwlist,
00229             &hdr_Type, &h, &key, &how))
00230         return NULL;
00231 
00232     {   PyObject * hObj = (PyObject *) h;
00233         if (hObj->ob_type != &hdr_Type) {
00234             PyErr_SetString(PyExc_TypeError, "bad type for header argument");
00235             return NULL;
00236         }
00237     }
00238 
00239 if (_rpmts_debug < 0 || (_rpmts_debug > 0 && *how != 'a'))
00240 fprintf(stderr, "*** rpmts_AddInstall(%p,%p,%p,%s) ts %p\n", s, h, key, how, s->ts);
00241 
00242     if (how && strcmp(how, "a") && strcmp(how, "u") && strcmp(how, "i")) {
00243         PyErr_SetString(PyExc_TypeError, "how argument must be \"u\", \"a\", or \"i\"");
00244         return NULL;
00245     } else if (how && !strcmp(how, "u"))
00246         isUpgrade = 1;
00247 
00248     if (how && !strcmp(how, "a"))
00249         rpmtsAddAvailableElement(s->ts, hdrGetHeader(h), key);
00250     else
00251         rpmtsAddInstallElement(s->ts, hdrGetHeader(h), key, isUpgrade, NULL);
00252 
00253     /* This should increment the usage count for me */
00254     if (key)
00255         PyList_Append(s->keyList, key);
00256 
00257     Py_INCREF(Py_None);
00258     return Py_None;
00259 }
00260 
00264 /*@null@*/
00265 static PyObject *
00266 rpmts_AddErase(rpmtsObject * s, PyObject * args, PyObject * kwds)
00267         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00268         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00269 {
00270     PyObject * o;
00271     int count;
00272     rpmdbMatchIterator mi;
00273     char * kwlist[] = {"name", NULL};
00274 
00275 if (_rpmts_debug)
00276 fprintf(stderr, "*** rpmts_AddErase(%p) ts %p\n", s, s->ts);
00277 
00278     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:AddErase", kwlist, &o))
00279         return NULL;
00280 
00281     if (PyString_Check(o)) {
00282         char * name = PyString_AsString(o);
00283 
00284         mi = rpmtsInitIterator(s->ts, RPMDBI_LABEL, name, 0);
00285         count = rpmdbGetIteratorCount(mi);
00286         if (count <= 0) {
00287             mi = rpmdbFreeIterator(mi);
00288             PyErr_SetString(pyrpmError, "package not installed");
00289             return NULL;
00290         } else { /* XXX: Note that we automatically choose to remove all matches */
00291             Header h;
00292             while ((h = rpmdbNextIterator(mi)) != NULL) {
00293                 unsigned int recOffset = rpmdbGetIteratorOffset(mi);
00294                 if (recOffset)
00295                     rpmtsAddEraseElement(s->ts, h, recOffset);
00296             }
00297         }
00298         mi = rpmdbFreeIterator(mi);
00299     } else
00300     if (PyInt_Check(o)) {
00301         uint_32 instance = PyInt_AsLong(o);
00302 
00303         mi = rpmtsInitIterator(s->ts, RPMDBI_PACKAGES, &instance, sizeof(instance));
00304         if (instance == 0 || mi == NULL) {
00305             mi = rpmdbFreeIterator(mi);
00306             PyErr_SetString(pyrpmError, "package not installed");
00307             return NULL;
00308         } else {
00309             Header h;
00310             while ((h = rpmdbNextIterator(mi)) != NULL) {
00311                 uint_32 recOffset = rpmdbGetIteratorOffset(mi);
00312                 if (recOffset)
00313                     rpmtsAddEraseElement(s->ts, h, recOffset);
00314                 break;
00315             }
00316         }
00317         mi = rpmdbFreeIterator(mi);
00318     }
00319 
00320     Py_INCREF(Py_None);
00321     return Py_None;
00322 }
00323 
00326 static int
00327 rpmts_SolveCallback(rpmts ts, rpmds ds, const void * data)
00328         /*@*/
00329 {
00330     struct rpmtsCallbackType_s * cbInfo = (struct rpmtsCallbackType_s *) data;
00331     PyObject * args, * result;
00332     int res = 1;
00333 
00334 if (_rpmts_debug)
00335 fprintf(stderr, "*** rpmts_SolveCallback(%p,%p,%p) \"%s\"\n", ts, ds, data, rpmdsDNEVR(ds));
00336 
00337     if (cbInfo->tso == NULL) return res;
00338     if (cbInfo->pythonError) return res;
00339     if (cbInfo->cb == Py_None) return res;
00340 
00341     PyEval_RestoreThread(cbInfo->_save);
00342 
00343     args = Py_BuildValue("(Oissi)", cbInfo->tso,
00344                 rpmdsTagN(ds), rpmdsN(ds), rpmdsEVR(ds), rpmdsFlags(ds));
00345     result = PyEval_CallObject(cbInfo->cb, args);
00346     Py_DECREF(args);
00347 
00348     if (!result) {
00349         cbInfo->pythonError = 1;
00350     } else {
00351         if (PyInt_Check(result))
00352             res = PyInt_AsLong(result);
00353         Py_DECREF(result);
00354     }
00355 
00356     cbInfo->_save = PyEval_SaveThread();
00357 
00358     return res;
00359 }
00360 
00363 /*@null@*/
00364 static PyObject *
00365 rpmts_Check(rpmtsObject * s, PyObject * args, PyObject * kwds)
00366         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00367         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00368 {
00369     rpmps ps;
00370     rpmProblem p;
00371     PyObject * list, * cf;
00372     struct rpmtsCallbackType_s cbInfo;
00373     int i;
00374     int xx;
00375     char * kwlist[] = {"callback", NULL};
00376 
00377     memset(&cbInfo, 0, sizeof(cbInfo));
00378     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:Check", kwlist,
00379             &cbInfo.cb))
00380         return NULL;
00381 
00382     if (cbInfo.cb != NULL) {
00383         if (!PyCallable_Check(cbInfo.cb)) {
00384             PyErr_SetString(PyExc_TypeError, "expected a callable");
00385             return NULL;
00386         }
00387         xx = rpmtsSetSolveCallback(s->ts, rpmts_SolveCallback, (void *)&cbInfo);
00388     }
00389 
00390 if (_rpmts_debug)
00391 fprintf(stderr, "*** rpmts_Check(%p) ts %p cb %p\n", s, s->ts, cbInfo.cb);
00392 
00393     cbInfo.tso = s;
00394     cbInfo.pythonError = 0;
00395     cbInfo._save = PyEval_SaveThread();
00396 
00397     /* XXX resurrect availablePackages one more time ... */
00398     rpmalMakeIndex(s->ts->availablePackages);
00399 
00400     xx = rpmtsCheck(s->ts);
00401     ps = rpmtsProblems(s->ts);
00402 
00403     if (cbInfo.cb)
00404         xx = rpmtsSetSolveCallback(s->ts, rpmtsSolve, NULL);
00405 
00406     PyEval_RestoreThread(cbInfo._save);
00407 
00408     if (ps != NULL) {
00409         list = PyList_New(0);
00410 
00411         /* XXX TODO: rpmlib >= 4.0.3 can return multiple suggested keys. */
00412         for (i = 0; i < ps->numProblems; i++) {
00413 #ifdef  DYING
00414             cf = Py_BuildValue("((sss)(ss)iOi)", conflicts[i].byName,
00415                                conflicts[i].byVersion, conflicts[i].byRelease,
00416 
00417                                conflicts[i].needsName,
00418                                conflicts[i].needsVersion,
00419 
00420                                conflicts[i].needsFlags,
00421                                conflicts[i].suggestedPkgs ?
00422                                    conflicts[i].suggestedPkgs[0] : Py_None,
00423                                conflicts[i].sense);
00424 #else
00425             char * byName, * byVersion, * byRelease, *byArch;
00426             char * needsName, * needsOP, * needsVersion;
00427             int needsFlags, sense;
00428             fnpyKey key;
00429 
00430             p = ps->probs + i;
00431 
00432             /* XXX autorelocated i386 on ia64, fix system-config-packages! */
00433             if (p->type == RPMPROB_BADRELOCATE)
00434                 continue;
00435 
00436             byName = p->pkgNEVR;
00437             if ((byArch= strrchr(byName, '.')) != NULL)
00438                 *byArch++ = '\0';
00439             if ((byRelease = strrchr(byName, '-')) != NULL)
00440                 *byRelease++ = '\0';
00441             if ((byVersion = strrchr(byName, '-')) != NULL)
00442                 *byVersion++ = '\0';
00443 
00444             key = p->key;
00445 
00446             needsName = p->altNEVR;
00447             if (needsName[1] == ' ') {
00448                 sense = (needsName[0] == 'C')
00449                         ? RPMDEP_SENSE_CONFLICTS : RPMDEP_SENSE_REQUIRES;
00450                 needsName += 2;
00451             } else
00452                 sense = RPMDEP_SENSE_REQUIRES;
00453             if ((needsVersion = strrchr(needsName, ' ')) != NULL)
00454                 *needsVersion++ = '\0';
00455 
00456             needsFlags = 0;
00457             if ((needsOP = strrchr(needsName, ' ')) != NULL) {
00458                 for (*needsOP++ = '\0'; *needsOP != '\0'; needsOP++) {
00459                     if (*needsOP == '<')        needsFlags |= RPMSENSE_LESS;
00460                     else if (*needsOP == '>')   needsFlags |= RPMSENSE_GREATER;
00461                     else if (*needsOP == '=')   needsFlags |= RPMSENSE_EQUAL;
00462                 }
00463             }
00464 
00465             cf = Py_BuildValue("((sss)(ss)iOi)", byName, byVersion, byRelease,
00466                                needsName, needsVersion, needsFlags,
00467                                (key != NULL ? key : Py_None),
00468                                sense);
00469 #endif
00470             PyList_Append(list, (PyObject *) cf);
00471             Py_DECREF(cf);
00472         }
00473 
00474         ps = rpmpsFree(ps);
00475 
00476         return list;
00477     }
00478 
00479     Py_INCREF(Py_None);
00480     return Py_None;
00481 }
00482 
00485 /*@null@*/
00486 static PyObject *
00487 rpmts_Order(rpmtsObject * s)
00488         /*@globals rpmGlobalMacroContext @*/
00489         /*@modifies s, rpmGlobalMacroContext @*/
00490 {
00491     int rc;
00492 
00493 if (_rpmts_debug)
00494 fprintf(stderr, "*** rpmts_Order(%p) ts %p\n", s, s->ts);
00495 
00496     Py_BEGIN_ALLOW_THREADS
00497     rc = rpmtsOrder(s->ts);
00498     Py_END_ALLOW_THREADS
00499 
00500     return Py_BuildValue("i", rc);
00501 }
00502 
00505 /*@null@*/
00506 static PyObject *
00507 rpmts_Clean(rpmtsObject * s)
00508         /*@globals _Py_NoneStruct @*/
00509         /*@modifies s, _Py_NoneStruct @*/
00510 {
00511 if (_rpmts_debug)
00512 fprintf(stderr, "*** rpmts_Clean(%p) ts %p\n", s, s->ts);
00513 
00514     rpmtsClean(s->ts);
00515 
00516     Py_INCREF(Py_None);
00517     return Py_None;
00518 }
00519 
00522 /*@null@*/
00523 static PyObject *
00524 rpmts_IDTXload(rpmtsObject * s)
00525         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00526         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00527 {
00528     PyObject * result = NULL;
00529     rpmTag tag = RPMTAG_INSTALLTID;
00530     IDTX idtx;
00531 
00532 if (_rpmts_debug)
00533 fprintf(stderr, "*** rpmts_IDTXload(%p) ts %p\n", s, s->ts);
00534 
00535     Py_BEGIN_ALLOW_THREADS
00536     idtx = IDTXload(s->ts, tag);
00537     Py_END_ALLOW_THREADS
00538 
00539 /*@-branchstate@*/
00540     if (idtx == NULL || idtx->nidt <= 0) {
00541         Py_INCREF(Py_None);
00542         result = Py_None;
00543     } else {
00544         PyObject * tuple;
00545         PyObject * ho;
00546         IDT idt;
00547         int i;
00548 
00549         result = PyTuple_New(idtx->nidt);
00550         for (i = 0; i < idtx->nidt; i++) {
00551             idt = idtx->idt + i;
00552             ho = (PyObject *) hdr_Wrap(idt->h);
00553             tuple = Py_BuildValue("(iOi)", idt->val.u32, ho, idt->instance);
00554             PyTuple_SET_ITEM(result,  i, tuple);
00555             Py_DECREF(ho);
00556         }
00557     }
00558 /*@=branchstate@*/
00559 
00560     idtx = IDTXfree(idtx);
00561 
00562     return result;
00563 }
00564 
00567 /*@null@*/
00568 static PyObject *
00569 rpmts_IDTXglob(rpmtsObject * s)
00570         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00571         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00572 {
00573     PyObject * result = NULL;
00574     rpmTag tag = RPMTAG_REMOVETID;
00575     const char * globstr;
00576     IDTX idtx;
00577 
00578 if (_rpmts_debug)
00579 fprintf(stderr, "*** rpmts_IDTXglob(%p) ts %p\n", s, s->ts);
00580 
00581     Py_BEGIN_ALLOW_THREADS
00582     globstr = rpmExpand("%{_repackage_dir}/*.rpm", NULL);
00583     idtx = IDTXglob(s->ts, globstr, tag);
00584     globstr = _free(globstr);
00585     Py_END_ALLOW_THREADS
00586 
00587 /*@-branchstate@*/
00588     if (idtx == NULL || idtx->nidt <= 0) {
00589         Py_INCREF(Py_None);
00590         result = Py_None;
00591     } else {
00592         PyObject * tuple;
00593         PyObject * ho;
00594         IDT idt;
00595         int i;
00596 
00597         result = PyTuple_New(idtx->nidt);
00598         for (i = 0; i < idtx->nidt; i++) {
00599             idt = idtx->idt + i;
00600             ho = (PyObject *) hdr_Wrap(idt->h);
00601             tuple = Py_BuildValue("(iOs)", idt->val.u32, ho, idt->key);
00602             PyTuple_SET_ITEM(result,  i, tuple);
00603             Py_DECREF(ho);
00604         }
00605     }
00606 /*@=branchstate@*/
00607 
00608     idtx = IDTXfree(idtx);
00609 
00610     return result;
00611 }
00612 
00615 /*@null@*/
00616 static PyObject *
00617 rpmts_Rollback(rpmtsObject * s, PyObject * args, PyObject * kwds)
00618         /*@globals rpmGlobalMacroContext @*/
00619         /*@modifies s, rpmGlobalMacroContext @*/
00620 {
00621     struct rpmInstallArguments_s * ia = alloca(sizeof(*ia));
00622     rpmtransFlags transFlags;
00623     const char ** av = NULL;
00624     uint_32 rbtid;
00625     int rc;
00626     char * kwlist[] = {"transactionId", NULL};
00627 
00628 if (_rpmts_debug)
00629 fprintf(stderr, "*** rpmts_Rollback(%p) ts %p\n", s, s->ts);
00630 
00631     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Rollback", kwlist, &rbtid))
00632         return NULL;
00633 
00634     Py_BEGIN_ALLOW_THREADS
00635     memset(ia, 0, sizeof(*ia));
00636     ia->qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE|VERIFY_HDRCHK);
00637     ia->transFlags |= (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL);
00638     ia->transFlags |= RPMTRANS_FLAG_NOMD5;
00639     ia->installInterfaceFlags = (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL);
00640     ia->rbtid = rbtid;
00641     ia->relocations = NULL;
00642     ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
00643 
00644     transFlags = rpmtsSetFlags(s->ts, ia->transFlags);
00645     rc = rpmRollback(s->ts, ia, av);
00646     transFlags = rpmtsSetFlags(s->ts, transFlags);
00647     Py_END_ALLOW_THREADS
00648 
00649     return Py_BuildValue("i", rc);
00650 }
00651 
00654 /*@null@*/
00655 static PyObject *
00656 rpmts_OpenDB(rpmtsObject * s)
00657         /*@globals rpmGlobalMacroContext @*/
00658         /*@modifies s, rpmGlobalMacroContext @*/
00659 {
00660 
00661 if (_rpmts_debug)
00662 fprintf(stderr, "*** rpmts_OpenDB(%p) ts %p\n", s, s->ts);
00663 
00664     if (s->ts->dbmode == -1)
00665         s->ts->dbmode = O_RDONLY;
00666 
00667     return Py_BuildValue("i", rpmtsOpenDB(s->ts, s->ts->dbmode));
00668 }
00669 
00672 /*@null@*/
00673 static PyObject *
00674 rpmts_CloseDB(rpmtsObject * s)
00675         /*@modifies s @*/
00676 {
00677     int rc;
00678 
00679 if (_rpmts_debug)
00680 fprintf(stderr, "*** rpmts_CloseDB(%p) ts %p\n", s, s->ts);
00681 
00682     rc = rpmtsCloseDB(s->ts);
00683     s->ts->dbmode = -1;         /* XXX disable lazy opens */
00684 
00685     return Py_BuildValue("i", rc);
00686 }
00687 
00690 /*@null@*/
00691 static PyObject *
00692 rpmts_InitDB(rpmtsObject * s)
00693         /*@globals rpmGlobalMacroContext @*/
00694         /*@modifies s, rpmGlobalMacroContext @*/
00695 {
00696     int rc;
00697 
00698 if (_rpmts_debug)
00699 fprintf(stderr, "*** rpmts_InitDB(%p) ts %p\n", s, s->ts);
00700 
00701     rc = rpmtsInitDB(s->ts, O_RDONLY);
00702     if (rc == 0)
00703         rc = rpmtsCloseDB(s->ts);
00704 
00705     return Py_BuildValue("i", rc);
00706 }
00707 
00710 /*@null@*/
00711 static PyObject *
00712 rpmts_RebuildDB(rpmtsObject * s)
00713         /*@globals rpmGlobalMacroContext @*/
00714         /*@modifies s, rpmGlobalMacroContext @*/
00715 {
00716     int rc;
00717 
00718 if (_rpmts_debug)
00719 fprintf(stderr, "*** rpmts_RebuildDB(%p) ts %p\n", s, s->ts);
00720 
00721     Py_BEGIN_ALLOW_THREADS
00722     rc = rpmtsRebuildDB(s->ts);
00723     Py_END_ALLOW_THREADS
00724 
00725     return Py_BuildValue("i", rc);
00726 }
00727 
00730 /*@null@*/
00731 static PyObject *
00732 rpmts_VerifyDB(rpmtsObject * s)
00733         /*@globals rpmGlobalMacroContext @*/
00734         /*@modifies s, rpmGlobalMacroContext @*/
00735 {
00736     int rc;
00737 
00738 if (_rpmts_debug)
00739 fprintf(stderr, "*** rpmts_VerifyDB(%p) ts %p\n", s, s->ts);
00740 
00741     Py_BEGIN_ALLOW_THREADS
00742     rc = rpmtsVerifyDB(s->ts);
00743     Py_END_ALLOW_THREADS
00744 
00745     return Py_BuildValue("i", rc);
00746 }
00747 
00750 /*@null@*/
00751 static PyObject *
00752 rpmts_HdrFromFdno(rpmtsObject * s, PyObject * args, PyObject * kwds)
00753         /*@globals rpmGlobalMacroContext, fileSystem @*/
00754         /*@modifies s, rpmGlobalMacroContext, fileSystem @*/
00755 {
00756     PyObject * result = NULL;
00757     Header h;
00758     FD_t fd;
00759     int fdno;
00760     rpmRC rpmrc;
00761     char * kwlist[] = {"fd", NULL};
00762 
00763     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:HdrFromFdno", kwlist,
00764             &fdno))
00765         return NULL;
00766 
00767     fd = fdDup(fdno);
00768     rpmrc = rpmReadPackageFile(s->ts, fd, "rpmts_HdrFromFdno", &h);
00769     Fclose(fd);
00770 
00771 if (_rpmts_debug)
00772 fprintf(stderr, "*** rpmts_HdrFromFdno(%p) ts %p rc %d\n", s, s->ts, rpmrc);
00773 
00774 /*@-branchstate@*/
00775     switch (rpmrc) {
00776     case RPMRC_OK:
00777         if (h)
00778             result = Py_BuildValue("N", hdr_Wrap(h));
00779         h = headerFree(h);      /* XXX ref held by result */
00780         break;
00781 
00782     case RPMRC_NOKEY:
00783         PyErr_SetString(pyrpmError, "public key not available");
00784         break;
00785 
00786     case RPMRC_NOTTRUSTED:
00787         PyErr_SetString(pyrpmError, "public key not trusted");
00788         break;
00789 
00790     case RPMRC_NOTFOUND:
00791     case RPMRC_FAIL:
00792     default:
00793         PyErr_SetString(pyrpmError, "error reading package header");
00794         break;
00795     }
00796 /*@=branchstate@*/
00797 
00798     return result;
00799 }
00800 
00803 /*@null@*/
00804 static PyObject *
00805 rpmts_HdrCheck(rpmtsObject * s, PyObject * args, PyObject * kwds)
00806         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00807         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00808 {
00809     PyObject * blob;
00810     PyObject * result = NULL;
00811     const char * msg = NULL;
00812     const void * uh;
00813     int uc;
00814     rpmRC rpmrc;
00815     char * kwlist[] = {"headers", NULL};
00816 
00817 if (_rpmts_debug)
00818 fprintf(stderr, "*** rpmts_HdrCheck(%p) ts %p\n", s, s->ts);
00819 
00820     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:HdrCheck", kwlist, &blob))
00821         return NULL;
00822 
00823     if (blob == Py_None) {
00824         Py_INCREF(Py_None);
00825         return Py_None;
00826     }
00827     if (!PyString_Check(blob)) {
00828         PyErr_SetString(pyrpmError, "hdrCheck takes a string of octets");
00829         return result;
00830     }
00831     uh = PyString_AsString(blob);
00832     uc = PyString_Size(blob);
00833 
00834     rpmrc = headerCheck(s->ts, uh, uc, &msg);
00835 
00836     switch (rpmrc) {
00837     case RPMRC_OK:
00838         Py_INCREF(Py_None);
00839         result = Py_None;
00840         break;
00841 
00842     case RPMRC_NOKEY:
00843         PyErr_SetString(pyrpmError, "public key not availaiable");
00844         break;
00845 
00846     case RPMRC_NOTTRUSTED:
00847         PyErr_SetString(pyrpmError, "public key not trusted");
00848         break;
00849 
00850     case RPMRC_FAIL:
00851     default:
00852         PyErr_SetString(pyrpmError, msg);
00853         break;
00854     }
00855     msg = _free(msg);
00856 
00857     return result;
00858 }
00859 
00862 /*@null@*/
00863 static PyObject *
00864 rpmts_SetVSFlags(rpmtsObject * s, PyObject * args, PyObject * kwds)
00865         /*@modifies s @*/
00866 {
00867     rpmVSFlags vsflags;
00868     char * kwlist[] = {"flags", NULL};
00869 
00870 if (_rpmts_debug)
00871 fprintf(stderr, "*** rpmts_SetVSFlags(%p) ts %p\n", s, s->ts);
00872 
00873     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetVSFlags", kwlist,
00874             &vsflags))
00875         return NULL;
00876 
00877     /* XXX FIXME: value check on vsflags, or build pure python object 
00878      * for it, and require an object of that type */
00879 
00880     return Py_BuildValue("i", rpmtsSetVSFlags(s->ts, vsflags));
00881 }
00882 
00885 /*@null@*/
00886 static PyObject *
00887 rpmts_SetColor(rpmtsObject * s, PyObject * args, PyObject * kwds)
00888         /*@modifies s @*/
00889 {
00890     uint_32 tscolor;
00891     char * kwlist[] = {"color", NULL};
00892 
00893 if (_rpmts_debug)
00894 fprintf(stderr, "*** rpmts_SetColor(%p) ts %p\n", s, s->ts);
00895 
00896     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Color", kwlist, &tscolor))
00897         return NULL;
00898 
00899     /* XXX FIXME: value check on tscolor, or build pure python object
00900      * for it, and require an object of that type */
00901 
00902     return Py_BuildValue("i", rpmtsSetColor(s->ts, tscolor));
00903 }
00904 
00907 /*@null@*/
00908 static PyObject *
00909 rpmts_PgpPrtPkts(rpmtsObject * s, PyObject * args, PyObject * kwds)
00910         /*@globals _Py_NoneStruct @*/
00911         /*@modifies _Py_NoneStruct @*/
00912 {
00913     PyObject * blob;
00914     unsigned char * pkt;
00915     unsigned int pktlen;
00916     int rc;
00917     char * kwlist[] = {"octets", NULL};
00918 
00919 if (_rpmts_debug)
00920 fprintf(stderr, "*** rpmts_PgpPrtPkts(%p) ts %p\n", s, s->ts);
00921 
00922     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:PgpPrtPkts", kwlist, &blob))
00923         return NULL;
00924 
00925     if (blob == Py_None) {
00926         Py_INCREF(Py_None);
00927         return Py_None;
00928     }
00929     if (!PyString_Check(blob)) {
00930         PyErr_SetString(pyrpmError, "pgpPrtPkts takes a string of octets");
00931         return NULL;
00932     }
00933     pkt = PyString_AsString(blob);
00934     pktlen = PyString_Size(blob);
00935 
00936     rc = pgpPrtPkts(pkt, pktlen, NULL, 1);
00937 
00938     return Py_BuildValue("i", rc);
00939 }
00940 
00943 /*@null@*/
00944 static PyObject *
00945 rpmts_PgpImportPubkey(rpmtsObject * s, PyObject * args, PyObject * kwds)
00946         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00947         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00948 {
00949     PyObject * blob;
00950     unsigned char * pkt;
00951     unsigned int pktlen;
00952     int rc;
00953     char * kwlist[] = {"pubkey", NULL};
00954 
00955 if (_rpmts_debug)
00956 fprintf(stderr, "*** rpmts_PgpImportPubkey(%p) ts %p\n", s, s->ts);
00957 
00958     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:PgpImportPubkey",
00959             kwlist, &blob))
00960         return NULL;
00961 
00962     if (blob == Py_None) {
00963         Py_INCREF(Py_None);
00964         return Py_None;
00965     }
00966     if (!PyString_Check(blob)) {
00967         PyErr_SetString(pyrpmError, "PgpImportPubkey takes a string of octets");
00968         return NULL;
00969     }
00970     pkt = PyString_AsString(blob);
00971     pktlen = PyString_Size(blob);
00972 
00973     rc = rpmcliImportPubkey(s->ts, pkt, pktlen);
00974 
00975     return Py_BuildValue("i", rc);
00976 }
00977 
00980 /*@null@*/
00981 static PyObject *
00982 rpmts_GetKeys(rpmtsObject * s)
00983         /*@globals _Py_NoneStruct @*/
00984         /*@modifies s, _Py_NoneStruct @*/
00985 {
00986     const void **data = NULL;
00987     int num, i;
00988     PyObject *tuple;
00989 
00990 if (_rpmts_debug)
00991 fprintf(stderr, "*** rpmts_GetKeys(%p) ts %p\n", s, s->ts);
00992 
00993     rpmtsGetKeys(s->ts, &data, &num);
00994     if (data == NULL || num <= 0) {
00995         data = _free(data);
00996         Py_INCREF(Py_None);
00997         return Py_None;
00998     }
00999 
01000     tuple = PyTuple_New(num);
01001 
01002     for (i = 0; i < num; i++) {
01003         PyObject *obj;
01004         obj = (data[i] ? (PyObject *) data[i] : Py_None);
01005         Py_INCREF(obj);
01006         PyTuple_SetItem(tuple, i, obj);
01007     }
01008 
01009     data = _free(data);
01010 
01011     return tuple;
01012 }
01013 
01016 /*@null@*/
01017 static void *
01018 rpmtsCallback(/*@unused@*/ const void * hd, const rpmCallbackType what,
01019                          const unsigned long amount, const unsigned long total,
01020                          const void * pkgKey, rpmCallbackData data)
01021         /*@globals _Py_NoneStruct @*/
01022         /*@modifies _Py_NoneStruct @*/
01023 {
01024 /*@-castexpose@*/
01025     Header h = (Header) hd;
01026 /*@=castexpose@*/
01027     struct rpmtsCallbackType_s * cbInfo = data;
01028     PyObject * pkgObj = (PyObject *) pkgKey;
01029     PyObject * args, * result;
01030     static FD_t fd;
01031 
01032     if (cbInfo->pythonError) return NULL;
01033     if (cbInfo->cb == Py_None) return NULL;
01034 
01035     /* Synthesize a python object for callback (if necessary). */
01036     if (pkgObj == NULL) {
01037         if (h) {
01038             const char * n = NULL;
01039             (void) headerNVR(h, &n, NULL, NULL);
01040             pkgObj = Py_BuildValue("s", n);
01041         } else {
01042             pkgObj = Py_None;
01043             Py_INCREF(pkgObj);
01044         }
01045     } else
01046         Py_INCREF(pkgObj);
01047 
01048     PyEval_RestoreThread(cbInfo->_save);
01049 
01050     args = Py_BuildValue("(illOO)", what, amount, total, pkgObj, cbInfo->data);
01051     result = PyEval_CallObject(cbInfo->cb, args);
01052     Py_DECREF(args);
01053     Py_DECREF(pkgObj);
01054 
01055     if (!result) {
01056         cbInfo->pythonError = 1;
01057         cbInfo->_save = PyEval_SaveThread();
01058         return NULL;
01059     }
01060 
01061     if (what == RPMCALLBACK_INST_OPEN_FILE) {
01062         int fdno;
01063 
01064         if (!PyArg_Parse(result, "i", &fdno)) {
01065             cbInfo->pythonError = 1;
01066             cbInfo->_save = PyEval_SaveThread();
01067             return NULL;
01068         }
01069         Py_DECREF(result);
01070         cbInfo->_save = PyEval_SaveThread();
01071 
01072         fd = fdDup(fdno);
01073 if (_rpmts_debug)
01074 fprintf(stderr, "\t%p = fdDup(%d)\n", fd, fdno);
01075 
01076         fcntl(Fileno(fd), F_SETFD, FD_CLOEXEC);
01077 
01078         return fd;
01079     } else
01080     if (what == RPMCALLBACK_INST_CLOSE_FILE) {
01081 if (_rpmts_debug)
01082 fprintf(stderr, "\tFclose(%p)\n", fd);
01083         Fclose (fd);
01084     } else {
01085 if (_rpmts_debug)
01086 fprintf(stderr, "\t%ld:%ld key %p\n", amount, total, pkgKey);
01087     }
01088 
01089     Py_DECREF(result);
01090     cbInfo->_save = PyEval_SaveThread();
01091 
01092     return NULL;
01093 }
01094 
01097 static PyObject *
01098 rpmts_SetFlags(rpmtsObject * s, PyObject * args, PyObject * kwds)
01099         /*@modifies s @*/
01100 {
01101     rpmtransFlags transFlags = 0;
01102     char * kwlist[] = {"flags", NULL};
01103 
01104     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetFlags", kwlist,
01105             &transFlags))
01106         return NULL;
01107 
01108 if (_rpmts_debug)
01109 fprintf(stderr, "*** rpmts_SetFlags(%p) ts %p transFlags %x\n", s, s->ts, transFlags);
01110 
01111     /* XXX FIXME: value check on flags, or build pure python object 
01112      * for it, and require an object of that type */
01113 
01114     return Py_BuildValue("i", rpmtsSetFlags(s->ts, transFlags));
01115 }
01116 
01119 static PyObject *
01120 rpmts_SetProbFilter(rpmtsObject * s, PyObject * args, PyObject * kwds)
01121         /*@modifies s @*/
01122 {
01123     rpmprobFilterFlags ignoreSet = 0;
01124     rpmprobFilterFlags oignoreSet;
01125     char * kwlist[] = {"ignoreSet", NULL};
01126 
01127     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:ProbFilter", kwlist,
01128             &ignoreSet))
01129         return NULL;
01130 
01131 if (_rpmts_debug)
01132 fprintf(stderr, "*** rpmts_SetProbFilter(%p) ts %p ignoreSet %x\n", s, s->ts, ignoreSet);
01133 
01134     oignoreSet = s->ignoreSet;
01135     s->ignoreSet = ignoreSet;
01136 
01137     return Py_BuildValue("i", oignoreSet);
01138 }
01139 
01142 /*@null@*/
01143 static rpmpsObject *
01144 rpmts_Problems(rpmtsObject * s)
01145         /*@modifies s @*/
01146 {
01147 
01148 if (_rpmts_debug)
01149 fprintf(stderr, "*** rpmts_Problems(%p) ts %p\n", s, s->ts);
01150 
01151     return rpmps_Wrap( rpmtsProblems(s->ts) );
01152 }
01153 
01156 static PyObject *
01157 rpmts_Run(rpmtsObject * s, PyObject * args, PyObject * kwds)
01158         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
01159         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
01160 {
01161     int rc, i;
01162     PyObject * list;
01163     rpmps ps;
01164     struct rpmtsCallbackType_s cbInfo;
01165     char * kwlist[] = {"callback", "data", NULL};
01166 
01167     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO:Run", kwlist,
01168             &cbInfo.cb, &cbInfo.data))
01169         return NULL;
01170 
01171     cbInfo.tso = s;
01172     cbInfo.pythonError = 0;
01173     cbInfo._save = PyEval_SaveThread();
01174 
01175     if (cbInfo.cb != NULL) {
01176         if (!PyCallable_Check(cbInfo.cb)) {
01177             PyErr_SetString(PyExc_TypeError, "expected a callable");
01178             return NULL;
01179         }
01180         (void) rpmtsSetNotifyCallback(s->ts, rpmtsCallback, (void *) &cbInfo);
01181     }
01182 
01183     /* Initialize security context patterns (if not already done). */
01184     if (!(s->ts->transFlags & RPMTRANS_FLAG_NOCONTEXTS)) {
01185         const char *fn = rpmGetPath("%{?_install_file_context_path}", NULL);
01186         if (fn != NULL && *fn != '\0') {
01187                 matchpathcon_init(fn);
01188         }
01189         fn = _free(fn);
01190     } 
01191 
01192 if (_rpmts_debug)
01193 fprintf(stderr, "*** rpmts_Run(%p) ts %p ignore %x\n", s, s->ts, s->ignoreSet);
01194 
01195     rc = rpmtsRun(s->ts, NULL, s->ignoreSet);
01196     ps = rpmtsProblems(s->ts);
01197 
01198     if (cbInfo.cb)
01199         (void) rpmtsSetNotifyCallback(s->ts, NULL, NULL);
01200 
01201     PyEval_RestoreThread(cbInfo._save);
01202 
01203     if (cbInfo.pythonError) {
01204         ps = rpmpsFree(ps);
01205         return NULL;
01206     }
01207 
01208     if (rc < 0) {
01209         list = PyList_New(0);
01210         return list;
01211     } else if (!rc) {
01212         Py_INCREF(Py_None);
01213         return Py_None;
01214     }
01215 
01216     list = PyList_New(0);
01217     for (i = 0; i < ps->numProblems; i++) {
01218         rpmProblem p = ps->probs + i;
01219         PyObject * prob = Py_BuildValue("s(isN)", rpmProblemString(p),
01220                              p->type,
01221                              p->str1,
01222                              PyLong_FromLongLong(p->ulong1));
01223         PyList_Append(list, prob);
01224         Py_DECREF(prob);
01225     }
01226 
01227     ps = rpmpsFree(ps);
01228 
01229     return list;
01230 }
01231 
01232 #if Py_TPFLAGS_HAVE_ITER
01233 static PyObject *
01234 rpmts_iter(rpmtsObject * s)
01235         /*@*/
01236 {
01237 if (_rpmts_debug)
01238 fprintf(stderr, "*** rpmts_iter(%p) ts %p\n", s, s->ts);
01239 
01240     Py_INCREF(s);
01241     return (PyObject *)s;
01242 }
01243 #endif
01244 
01248 /*@null@*/
01249 static PyObject *
01250 rpmts_iternext(rpmtsObject * s)
01251         /*@modifies s @*/
01252 {
01253     PyObject * result = NULL;
01254     rpmte te;
01255 
01256 if (_rpmts_debug)
01257 fprintf(stderr, "*** rpmts_iternext(%p) ts %p tsi %p %d\n", s, s->ts, s->tsi, s->tsiFilter);
01258 
01259     /* Reset iterator on 1st entry. */
01260     if (s->tsi == NULL) {
01261         s->tsi = rpmtsiInit(s->ts);
01262         if (s->tsi == NULL)
01263             return NULL;
01264         s->tsiFilter = 0;
01265     }
01266 
01267     te = rpmtsiNext(s->tsi, s->tsiFilter);
01268 /*@-branchstate@*/
01269     if (te != NULL) {
01270         result = (PyObject *) rpmte_Wrap(te);
01271     } else {
01272         s->tsi = rpmtsiFree(s->tsi);
01273         s->tsiFilter = 0;
01274     }
01275 /*@=branchstate@*/
01276 
01277     return result;
01278 }
01279 
01283 static PyObject *
01284 rpmts_Next(rpmtsObject * s)
01285         /*@globals _Py_NoneStruct @*/
01286         /*@modifies s, _Py_NoneStruct @*/
01287 {
01288     PyObject * result;
01289 
01290 if (_rpmts_debug)
01291 fprintf(stderr, "*** rpmts_Next(%p) ts %p\n", s, s->ts);
01292 
01293     result = rpmts_iternext(s);
01294 
01295     if (result == NULL) {
01296         Py_INCREF(Py_None);
01297         return Py_None;
01298     }
01299 
01300     return result;
01301 }
01302 
01305 /*@null@*/
01306 static specObject *
01307 spec_Parse(rpmtsObject * s, PyObject * args, PyObject * kwds)
01308         /*@globals rpmGlobalMacroContext @*/
01309         /*@modifies s, rpmGlobalMacroContext @*/
01310 {
01311     const char * specfile;
01312     Spec spec;
01313     char * buildRoot = NULL;
01314     int recursing = 0;
01315     char * passPhrase = "";
01316     char *cookie = NULL;
01317     int anyarch = 1;
01318     int force = 1;
01319     char * kwlist[] = {"specfile", NULL};
01320 
01321     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:Parse", kwlist, &specfile))
01322         return NULL;
01323 
01324     if (parseSpec(s->ts, specfile,"/", buildRoot,recursing, passPhrase,
01325              cookie, anyarch, force)!=0) {
01326              PyErr_SetString(pyrpmError, "can't parse specfile\n");
01327                      return NULL;
01328    }
01329 
01330     spec = rpmtsSpec(s->ts);
01331     return spec_Wrap(spec);
01332 }
01333 
01336 /*@null@*/
01337 static rpmmiObject *
01338 rpmts_Match(rpmtsObject * s, PyObject * args, PyObject * kwds)
01339         /*@globals rpmGlobalMacroContext @*/
01340         /*@modifies s, rpmGlobalMacroContext @*/
01341 {
01342     PyObject *TagN = NULL;
01343     PyObject *Key = NULL;
01344     char *key = NULL;
01345 /* XXX lkey *must* be a 32 bit integer, int "works" on all known platforms. */
01346     int lkey = 0;
01347     int len = 0;
01348     int tag = RPMDBI_PACKAGES;
01349     char * kwlist[] = {"tagNumber", "key", NULL};
01350 
01351 if (_rpmts_debug)
01352 fprintf(stderr, "*** rpmts_Match(%p) ts %p\n", s, s->ts);
01353 
01354     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:Match", kwlist,
01355             &TagN, &Key))
01356         return NULL;
01357 
01358     if (TagN && (tag = tagNumFromPyObject (TagN)) == -1) {
01359         PyErr_SetString(PyExc_TypeError, "unknown tag type");
01360         return NULL;
01361     }
01362 
01363     if (Key) {
01364 /*@-branchstate@*/
01365         if (PyString_Check(Key)) {
01366             key = PyString_AsString(Key);
01367             len = PyString_Size(Key);
01368         } else if (PyInt_Check(Key)) {
01369             lkey = PyInt_AsLong(Key);
01370             key = (char *)&lkey;
01371             len = sizeof(lkey);
01372         } else {
01373             PyErr_SetString(PyExc_TypeError, "unknown key type");
01374             return NULL;
01375         }
01376 /*@=branchstate@*/
01377     }
01378 
01379     /* XXX If not already opened, open the database O_RDONLY now. */
01380     /* XXX FIXME: lazy default rdonly open also done by rpmtsInitIterator(). */
01381     if (s->ts->rdb == NULL) {
01382         int rc = rpmtsOpenDB(s->ts, O_RDONLY);
01383         if (rc || s->ts->rdb == NULL) {
01384             PyErr_SetString(PyExc_TypeError, "rpmdb open failed");
01385             return NULL;
01386         }
01387     }
01388 
01389     return rpmmi_Wrap( rpmtsInitIterator(s->ts, tag, key, len) );
01390 }
01391 
01394 /*@-fullinitblock@*/
01395 /*@unchecked@*/ /*@observer@*/
01396 static struct PyMethodDef rpmts_methods[] = {
01397  {"Debug",      (PyCFunction)rpmts_Debug,       METH_VARARGS|METH_KEYWORDS,
01398         NULL},
01399 
01400  {"addInstall", (PyCFunction) rpmts_AddInstall, METH_VARARGS|METH_KEYWORDS,
01401         NULL },
01402  {"addErase",   (PyCFunction) rpmts_AddErase,   METH_VARARGS|METH_KEYWORDS,
01403         NULL },
01404  {"check",      (PyCFunction) rpmts_Check,      METH_VARARGS|METH_KEYWORDS,
01405         NULL },
01406  {"order",      (PyCFunction) rpmts_Order,      METH_NOARGS,
01407         NULL },
01408  {"setFlags",   (PyCFunction) rpmts_SetFlags,   METH_VARARGS|METH_KEYWORDS,
01409 "ts.setFlags(transFlags) -> previous transFlags\n\
01410 - Set control bit(s) for executing ts.run().\n\
01411   Note: This method replaces the 1st argument to the old ts.run()\n" },
01412  {"setProbFilter",      (PyCFunction) rpmts_SetProbFilter,      METH_VARARGS|METH_KEYWORDS,
01413 "ts.setProbFilter(ignoreSet) -> previous ignoreSet\n\
01414 - Set control bit(s) for ignoring problems found by ts.run().\n\
01415   Note: This method replaces the 2nd argument to the old ts.run()\n" },
01416  {"problems",   (PyCFunction) rpmts_Problems,   METH_NOARGS,
01417 "ts.problems() -> ps\n\
01418 - Return current problem set.\n" },
01419  {"run",        (PyCFunction) rpmts_Run,        METH_VARARGS|METH_KEYWORDS,
01420 "ts.run(callback, data) -> (problems)\n\
01421 - Run a transaction set, returning list of problems found.\n\
01422   Note: The callback may not be None.\n" },
01423  {"clean",      (PyCFunction) rpmts_Clean,      METH_NOARGS,
01424         NULL },
01425  {"IDTXload",   (PyCFunction) rpmts_IDTXload,   METH_NOARGS,
01426 "ts.IDTXload() -> ((tid,hdr,instance)+)\n\
01427 - Return list of installed packages reverse sorted by transaction id.\n" },
01428  {"IDTXglob",   (PyCFunction) rpmts_IDTXglob,   METH_NOARGS,
01429 "ts.IDTXglob() -> ((tid,hdr,instance)+)\n\
01430 - Return list of removed packages reverse sorted by transaction id.\n" },
01431  {"rollback",   (PyCFunction) rpmts_Rollback,   METH_VARARGS|METH_KEYWORDS,
01432         NULL },
01433  {"openDB",     (PyCFunction) rpmts_OpenDB,     METH_NOARGS,
01434 "ts.openDB() -> None\n\
01435 - Open the default transaction rpmdb.\n\
01436   Note: The transaction rpmdb is lazily opened, so ts.openDB() is seldom needed.\n" },
01437  {"closeDB",    (PyCFunction) rpmts_CloseDB,    METH_NOARGS,
01438 "ts.closeDB() -> None\n\
01439 - Close the default transaction rpmdb.\n\
01440   Note: ts.closeDB() disables lazy opens, and should hardly ever be used.\n" },
01441  {"initDB",     (PyCFunction) rpmts_InitDB,     METH_NOARGS,
01442 "ts.initDB() -> None\n\
01443 - Initialize the default transaction rpmdb.\n\
01444  Note: ts.initDB() is seldom needed anymore.\n" },
01445  {"rebuildDB",  (PyCFunction) rpmts_RebuildDB,  METH_NOARGS,
01446 "ts.rebuildDB() -> None\n\
01447 - Rebuild the default transaction rpmdb.\n" },
01448  {"verifyDB",   (PyCFunction) rpmts_VerifyDB,   METH_NOARGS,
01449 "ts.verifyDB() -> None\n\
01450 - Verify the default transaction rpmdb.\n" },
01451  {"hdrFromFdno",(PyCFunction) rpmts_HdrFromFdno,METH_VARARGS|METH_KEYWORDS,
01452 "ts.hdrFromFdno(fdno) -> hdr\n\
01453 - Read a package header from a file descriptor.\n" },
01454  {"hdrCheck",   (PyCFunction) rpmts_HdrCheck,   METH_VARARGS|METH_KEYWORDS,
01455         NULL },
01456  {"setVSFlags",(PyCFunction) rpmts_SetVSFlags,  METH_VARARGS|METH_KEYWORDS,
01457 "ts.setVSFlags(vsflags) -> ovsflags\n\
01458 - Set signature verification flags. Values for vsflags are:\n\
01459     rpm.RPMVSF_NOHDRCHK      if set, don't check rpmdb headers\n\
01460     rpm.RPMVSF_NEEDPAYLOAD   if not set, check header+payload (if possible)\n\
01461     rpm.RPMVSF_NOSHA1HEADER  if set, don't check header SHA1 digest\n\
01462     rpm.RPMVSF_NODSAHEADER   if set, don't check header DSA signature\n\
01463     rpm.RPMVSF_NOMD5         if set, don't check header+payload MD5 digest\n\
01464     rpm.RPMVSF_NODSA         if set, don't check header+payload DSA signature\n\
01465     rpm.RPMVSF_NORSA         if set, don't check header+payload RSA signature\n\
01466     rpm._RPMVSF_NODIGESTS    if set, don't check digest(s)\n\
01467     rpm._RPMVSF_NOSIGNATURES if set, don't check signature(s)\n" },
01468  {"setColor",(PyCFunction) rpmts_SetColor,      METH_VARARGS|METH_KEYWORDS,
01469         NULL },
01470  {"pgpPrtPkts", (PyCFunction) rpmts_PgpPrtPkts, METH_VARARGS|METH_KEYWORDS,
01471         NULL },
01472  {"pgpImportPubkey",    (PyCFunction) rpmts_PgpImportPubkey,    METH_VARARGS|METH_KEYWORDS,
01473         NULL },
01474  {"getKeys",    (PyCFunction) rpmts_GetKeys,    METH_NOARGS,
01475         NULL },
01476  {"parseSpec",  (PyCFunction) spec_Parse,       METH_VARARGS|METH_KEYWORDS,
01477 "ts.parseSpec(\"/path/to/foo.spec\") -> spec\n\
01478 - Parse a spec file.\n" },
01479  {"dbMatch",    (PyCFunction) rpmts_Match,      METH_VARARGS|METH_KEYWORDS,
01480 "ts.dbMatch([TagN, [key, [len]]]) -> mi\n\
01481 - Create a match iterator for the default transaction rpmdb.\n" },
01482  {"next",               (PyCFunction)rpmts_Next,        METH_NOARGS,
01483 "ts.next() -> te\n\
01484 - Retrieve next transaction set element.\n" },
01485     {NULL,              NULL}           /* sentinel */
01486 };
01487 /*@=fullinitblock@*/
01488 
01491 static void rpmts_dealloc(/*@only@*/ rpmtsObject * s)
01492         /*@modifies *s @*/
01493 {
01494 
01495 if (_rpmts_debug)
01496 fprintf(stderr, "%p -- ts %p db %p\n", s, s->ts, s->ts->rdb);
01497     s->ts = rpmtsFree(s->ts);
01498 
01499     if (s->scriptFd) Fclose(s->scriptFd);
01500     /* this will free the keyList, and decrement the ref count of all
01501        the items on the list as well :-) */
01502     Py_DECREF(s->keyList);
01503     PyObject_Del((PyObject *)s);
01504 }
01505 
01506 static PyObject * rpmts_getattro(PyObject * o, PyObject * n)
01507         /*@*/
01508 {
01509     return PyObject_GenericGetAttr(o, n);
01510 }
01511 
01514 static int rpmts_setattro(PyObject * o, PyObject * n, PyObject * v)
01515         /*@*/
01516 {
01517     rpmtsObject *s = (rpmtsObject *)o;
01518     char * name = PyString_AsString(n);
01519     int fdno;
01520 
01521     if (!strcmp(name, "scriptFd")) {
01522         if (!PyArg_Parse(v, "i", &fdno)) return 0;
01523         if (fdno < 0) {
01524             PyErr_SetString(PyExc_TypeError, "bad file descriptor");
01525             return -1;
01526         } else {
01527             s->scriptFd = fdDup(fdno);
01528             rpmtsSetScriptFd(s->ts, s->scriptFd);
01529         }
01530     } else {
01531         PyErr_SetString(PyExc_AttributeError, name);
01532         return -1;
01533     }
01534 
01535     return 0;
01536 }
01537 
01540 static int rpmts_init(rpmtsObject * s, PyObject *args, PyObject *kwds)
01541         /*@globals rpmGlobalMacroContext @*/
01542         /*@modifies s, rpmGlobalMacroContext @*/
01543 {
01544     char * rootDir = "/";
01545     int vsflags = rpmExpandNumeric("%{?_vsflags_up2date}");
01546     char * kwlist[] = {"rootdir", "vsflags", 0};
01547 
01548 if (_rpmts_debug < 0)
01549 fprintf(stderr, "*** rpmts_init(%p,%p,%p)\n", s, args, kwds);
01550 
01551     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|si:rpmts_init", kwlist,
01552             &rootDir, &vsflags))
01553         return -1;
01554 
01555     s->ts = rpmtsCreate();
01556     /* XXX: Why is there no rpmts_SetRootDir() ? */
01557     (void) rpmtsSetRootDir(s->ts, rootDir);
01558     /* XXX: make this use common code with rpmts_SetVSFlags() to check the
01559      *      python objects */
01560     (void) rpmtsSetVSFlags(s->ts, vsflags);
01561     s->keyList = PyList_New(0);
01562     s->scriptFd = NULL;
01563     s->tsi = NULL;
01564     s->tsiFilter = 0;
01565 
01566     return 0;
01567 }
01568 
01571 static void rpmts_free(/*@only@*/ rpmtsObject * s)
01572         /*@modifies s @*/
01573 {
01574 if (_rpmts_debug)
01575 fprintf(stderr, "%p -- ts %p db %p\n", s, s->ts, s->ts->rdb);
01576     s->ts = rpmtsFree(s->ts);
01577 
01578     if (s->scriptFd)
01579         Fclose(s->scriptFd);
01580 
01581     /* this will free the keyList, and decrement the ref count of all
01582        the items on the list as well :-) */
01583     Py_DECREF(s->keyList);
01584 
01585     PyObject_Del((PyObject *)s);
01586 }
01587 
01590 static PyObject * rpmts_alloc(PyTypeObject * subtype, int nitems)
01591         /*@*/
01592 {
01593     PyObject * s = PyType_GenericAlloc(subtype, nitems);
01594 
01595 if (_rpmts_debug < 0)
01596 fprintf(stderr, "*** rpmts_alloc(%p,%d) ret %p\n", subtype, nitems, s);
01597     return s;
01598 }
01599 
01602 static PyObject * rpmts_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
01603         /*@globals rpmGlobalMacroContext @*/
01604         /*@modifies rpmGlobalMacroContext @*/
01605 {
01606     rpmtsObject * s = (void *) PyObject_New(rpmtsObject, subtype);
01607 
01608     /* Perform additional initialization. */
01609     if (rpmts_init(s, args, kwds) < 0) {
01610         rpmts_free(s);
01611         return NULL;
01612     }
01613 
01614 if (_rpmts_debug)
01615 fprintf(stderr, "%p ++ ts %p db %p\n", s, s->ts, s->ts->rdb);
01616 
01617     return (PyObject *)s;
01618 }
01619 
01622 /*@unchecked@*/ /*@observer@*/
01623 static char rpmts_doc[] =
01624 "";
01625 
01628 /*@-fullinitblock@*/
01629 PyTypeObject rpmts_Type = {
01630         PyObject_HEAD_INIT(&PyType_Type)
01631         0,                              /* ob_size */
01632         "rpm.ts",                       /* tp_name */
01633         sizeof(rpmtsObject),            /* tp_size */
01634         0,                              /* tp_itemsize */
01635         (destructor) rpmts_dealloc,     /* tp_dealloc */
01636         0,                              /* tp_print */
01637         (getattrfunc)0,                 /* tp_getattr */
01638         (setattrfunc)0,                 /* tp_setattr */
01639         0,                              /* tp_compare */
01640         0,                              /* tp_repr */
01641         0,                              /* tp_as_number */
01642         0,                              /* tp_as_sequence */
01643         0,                              /* tp_as_mapping */
01644         0,                              /* tp_hash */
01645         0,                              /* tp_call */
01646         0,                              /* tp_str */
01647         (getattrofunc) rpmts_getattro,  /* tp_getattro */
01648         (setattrofunc) rpmts_setattro,  /* tp_setattro */
01649         0,                              /* tp_as_buffer */
01650         Py_TPFLAGS_DEFAULT,             /* tp_flags */
01651         rpmts_doc,                      /* tp_doc */
01652 #if Py_TPFLAGS_HAVE_ITER
01653         0,                              /* tp_traverse */
01654         0,                              /* tp_clear */
01655         0,                              /* tp_richcompare */
01656         0,                              /* tp_weaklistoffset */
01657         (getiterfunc) rpmts_iter,       /* tp_iter */
01658         (iternextfunc) rpmts_iternext,  /* tp_iternext */
01659         rpmts_methods,                  /* tp_methods */
01660         0,                              /* tp_members */
01661         0,                              /* tp_getset */
01662         0,                              /* tp_base */
01663         0,                              /* tp_dict */
01664         0,                              /* tp_descr_get */
01665         0,                              /* tp_descr_set */
01666         0,                              /* tp_dictoffset */
01667         (initproc) rpmts_init,          /* tp_init */
01668         (allocfunc) rpmts_alloc,        /* tp_alloc */
01669         (newfunc) rpmts_new,            /* tp_new */
01670         rpmts_free,                     /* tp_free */
01671         0,                              /* tp_is_gc */
01672 #endif
01673 };
01674 /*@=fullinitblock@*/
01675 
01678 /* XXX: This should use the same code as rpmts_init */
01679 rpmtsObject *
01680 rpmts_Create(/*@unused@*/ PyObject * self, PyObject * args, PyObject * kwds)
01681 {
01682     rpmtsObject * o;
01683     char * rootDir = "/";
01684     int vsflags = rpmExpandNumeric("%{?_vsflags_up2date}");
01685     char * kwlist[] = {"rootdir", "vsflags", NULL};
01686 
01687     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|si:Create", kwlist,
01688             &rootDir, &vsflags))
01689         return NULL;
01690 
01691     o = (void *) PyObject_New(rpmtsObject, &rpmts_Type);
01692 
01693     o->ts = rpmtsCreate();
01694     /* XXX: Why is there no rpmts_SetRootDir() ? */
01695     (void) rpmtsSetRootDir(o->ts, rootDir);
01696     /* XXX: make this use common code with rpmts_SetVSFlags() to check the
01697      *      python objects */
01698     (void) rpmtsSetVSFlags(o->ts, vsflags);
01699 
01700     o->keyList = PyList_New(0);
01701     o->scriptFd = NULL;
01702     o->tsi = NULL;
01703     o->tsiFilter = 0;
01704 
01705 if (_rpmts_debug)
01706 fprintf(stderr, "%p ++ ts %p db %p\n", o, o->ts, o->ts->rdb);
01707     return o;
01708 }

Generated on Wed Jan 28 12:45:25 2009 for rpm by  doxygen 1.4.7