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

Generated on 30 Sep 2013 for rpm by  doxygen 1.4.7