• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

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

Generated on Mon Nov 29 2010 05:18:46 for rpm by  doxygen 1.7.2