python/rpmts-py.c

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

Generated on Mon Aug 23 22:20:33 2010 for rpm by  doxygen 1.5.1