• 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 #include <rpmcb.h>
00009 
00010 #define _RPMPS_INTERNAL /* XXX almost (but not quite) opaque. */
00011 #include <rpmpgp.h>
00012 
00013 #include <rpmtypes.h>
00014 #include <rpmtag.h>
00015 #include <pkgio.h>              /* XXX headerCheck() */
00016 #include <rpmdb.h>
00017 
00018 #define _RPMTS_INTERNAL         /* XXX expose rpmtsSetScriptFd */
00019 #include <rpmbuild.h>
00020 
00021 #include <rpmcli.h>
00022 #define _RPMROLLBACK_INTERNAL   /* XXX IDTX et al */
00023 #include <rpmrollback.h>
00024 
00025 #include "header-py.h"
00026 #include "rpmds-py.h"   /* XXX for rpmdsNew */
00027 #include "rpmfi-py.h"   /* XXX for rpmfiNew */
00028 #include "rpmmi-py.h"
00029 #include "rpmps-py.h"
00030 #include "rpmte-py.h"
00031 #include "spec-py.h"
00032 
00033 #include "rpmts-py.h"
00034 
00035 #include "debug.h"
00036 
00037 #define rpmtsfree() rpmioFreePoolItem()
00038 
00039 /*@unchecked@*/
00040 /*@-shadow@*/
00041 extern int _rpmts_debug;
00042 /*@=shadow@*/
00043 
00044 /*@access alKey @*/
00045 /*@access FD_t @*/
00046 /*@access Header @*/
00047 /*@access rpmal @*/
00048 /*@access rpmdb @*/
00049 /*@access rpmds @*/
00050 /*@access rpmts @*/
00051 /*@access rpmtsi @*/
00052 
00173 struct rpmtsCallbackType_s {
00174     PyObject * cb;
00175     PyObject * data;
00176     rpmtsObject * tso;
00177     rpmdsObject * dso;
00178     PyThreadState *_save;
00179 };
00180 
00183 /*@exits@*/
00184 static void rpmts_Die(PyObject *cb)
00185         /*@*/
00186 {
00187     PyObject * r = PyObject_Repr(cb);
00188     char *pyfn = (r != NULL ? PyString_AsString(r) : "???");
00189 
00190     if (PyErr_Occurred())
00191         PyErr_Print();
00192     rpmlog(RPMLOG_ERR, _("python callback %s failed, aborting!\n"), pyfn);
00193     rpmdbCheckTerminate(1);
00194     exit(EXIT_FAILURE);
00195 }
00196 
00199 static int
00200 rpmts_SolveCallback(rpmts ts, rpmds ds, const void * data)
00201         /*@*/
00202 {
00203     struct rpmtsCallbackType_s * cbInfo = (struct rpmtsCallbackType_s *) data;
00204     PyObject * args, * result;
00205     int res = 1;
00206 
00207 if (_rpmts_debug)
00208 fprintf(stderr, "*** rpmts_SolveCallback(%p,%p,%p) \"%s\"\n", ts, ds, data, rpmdsDNEVR(ds));
00209 
00210     if (cbInfo->tso == NULL) return res;
00211     if (cbInfo->cb == Py_None) return res;
00212 
00213     PyEval_RestoreThread(cbInfo->_save);
00214 
00215     cbInfo->dso = rpmds_Wrap(ds);       /* XXX perhaps persistent? */
00216     args = Py_BuildValue("(OO)", cbInfo->tso, cbInfo->dso);
00217     result = PyEval_CallObject(cbInfo->cb, args);
00218     Py_DECREF(cbInfo->dso);
00219     cbInfo->dso = NULL;
00220     Py_DECREF(args);
00221 
00222     if (!result) {
00223         rpmts_Die(cbInfo->cb);
00224         /*@notreached@*/
00225     } else {
00226         if (PyInt_Check(result))
00227             res = PyInt_AsLong(result);
00228         Py_DECREF(result);
00229     }
00230 
00231     cbInfo->_save = PyEval_SaveThread();
00232 
00233     return res;
00234 }
00235 
00238 /*@null@*/
00239 static void *
00240 rpmtsCallback(/*@unused@*/ const void * hd, const rpmCallbackType what,
00241                          const rpmuint64_t amount, const rpmuint64_t total,
00242                          fnpyKey pkgKey, rpmCallbackData data)
00243         /*@globals _Py_NoneStruct @*/
00244         /*@modifies _Py_NoneStruct @*/
00245 {
00246 /*@-castexpose@*/
00247     Header h = (Header) hd;
00248 /*@=castexpose@*/
00249     struct rpmtsCallbackType_s * cbInfo = data;
00250     PyObject * pkgObj = (PyObject *) pkgKey;
00251     PyObject * oh = NULL;
00252     const char * origin = NULL;
00253     PyObject * args, * result;
00254     static FD_t fd;
00255 
00256     if (cbInfo->cb == Py_None) return NULL;
00257 
00258     /* Synthesize a python object for callback (if necessary). */
00259     if (pkgObj == NULL) {
00260         if (h) {
00261             HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00262             he->tag = RPMTAG_NAME;
00263             if (headerGet(h, he, 0)) {
00264                 pkgObj = Py_BuildValue("s", he->p.str);
00265                 he->p.ptr = _free(he->p.ptr);
00266             } else {
00267                 pkgObj = Py_None;
00268                 Py_INCREF(pkgObj);
00269             }
00270         } else {
00271             pkgObj = Py_None;
00272             Py_INCREF(pkgObj);
00273         }
00274     } else {
00275         Py_INCREF(pkgObj);
00276         /* XXX yum has (h, rpmloc) tuple as pkgKey. Extract the path. */
00277         if (!(PyTuple_Check(pkgObj) && PyArg_ParseTuple(pkgObj, "|Os", &oh, &origin)))
00278             origin = NULL;
00279         /* XXX clean up the path, yum paths start "//..." */
00280         if (origin && origin[0] == '/' && origin[1] == '/')
00281             origin++;
00282     }
00283 
00284     PyEval_RestoreThread(cbInfo->_save);
00285 
00286     args = Py_BuildValue("(iLLOO)", what, amount, total, pkgObj, cbInfo->data);
00287     result = PyEval_CallObject(cbInfo->cb, args);
00288     Py_DECREF(args);
00289     Py_DECREF(pkgObj);
00290 
00291     if (!result) {
00292         rpmts_Die(cbInfo->cb);
00293         /*@notreached@*/
00294     }
00295 
00296     if (what == RPMCALLBACK_INST_OPEN_FILE) {
00297         int fdno;
00298 
00299         if (!PyArg_Parse(result, "i", &fdno)) {
00300             rpmts_Die(cbInfo->cb);
00301             /*@notreached@*/
00302         }
00303         Py_DECREF(result);
00304         cbInfo->_save = PyEval_SaveThread();
00305 
00306         fd = fdDup(fdno);
00307 if (_rpmts_debug)
00308 fprintf(stderr, "\t%p = fdDup(%d)\n", fd, fdno);
00309 
00310         fcntl(Fileno(fd), F_SETFD, FD_CLOEXEC);
00311 
00312         if (origin != NULL)
00313             (void) fdSetOpen(fd, origin, 0, 0);
00314 
00315         return fd;
00316     } else
00317     if (what == RPMCALLBACK_INST_CLOSE_FILE) {
00318 if (_rpmts_debug)
00319 fprintf(stderr, "\tFclose(%p)\n", fd);
00320         Fclose (fd);
00321     } else {
00322 if (_rpmts_debug)
00323 fprintf(stderr, "\t%llu:%llu key %p\n", (unsigned long long)amount, (unsigned long long)total, pkgKey);
00324     }
00325 
00326     Py_DECREF(result);
00327     cbInfo->_save = PyEval_SaveThread();
00328 
00329     return NULL;
00330 }
00331 
00332 #if Py_TPFLAGS_HAVE_ITER
00333 
00335 static PyObject *
00336 rpmts_iter(rpmtsObject * s)
00337         /*@*/
00338 {
00339 if (_rpmts_debug)
00340 fprintf(stderr, "*** rpmts_iter(%p) ts %p\n", s, s->ts);
00341 
00342     Py_INCREF(s);
00343     return (PyObject *)s;
00344 }
00345 #endif
00346 
00350 /*@null@*/
00351 static PyObject *
00352 rpmts_iternext(rpmtsObject * s)
00353         /*@modifies s @*/
00354 {
00355     PyObject * result = NULL;
00356     rpmte te;
00357 
00358 if (_rpmts_debug)
00359 fprintf(stderr, "*** rpmts_iternext(%p) ts %p tsi %p %d\n", s, s->ts, s->tsi, s->tsiFilter);
00360 
00361     /* Reset iterator on 1st entry. */
00362     if (s->tsi == NULL) {
00363         s->tsi = rpmtsiInit(s->ts);
00364         if (s->tsi == NULL)
00365             return NULL;
00366         s->tsiFilter = 0;
00367     }
00368 
00369     te = rpmtsiNext(s->tsi, s->tsiFilter);
00370 /*@-branchstate@*/
00371     if (te != NULL) {
00372         result = (PyObject *) rpmte_Wrap(te);
00373     } else {
00374         s->tsi = rpmtsiFree(s->tsi);
00375         s->tsiFilter = 0;
00376     }
00377 /*@=branchstate@*/
00378 
00379     return result;
00380 }
00381 
00386 
00389 /*@null@*/
00390 static PyObject *
00391 rpmts_Debug(/*@unused@*/ rpmtsObject * s, PyObject * args, PyObject * kwds)
00392         /*@globals _Py_NoneStruct @*/
00393         /*@modifies _Py_NoneStruct @*/
00394 {
00395     char * kwlist[] = {"debugLevel", NULL};
00396 
00397     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Debug", kwlist,
00398             &_rpmts_debug))
00399         return NULL;
00400 
00401 if (_rpmts_debug < 0)
00402 fprintf(stderr, "*** rpmts_Debug(%p) ts %p\n", s, s->ts);
00403 
00404     Py_INCREF(Py_None);
00405     return Py_None;
00406 }
00407 
00410 /*@null@*/
00411 static PyObject *
00412 rpmts_AddInstall(rpmtsObject * s, PyObject * args, PyObject * kwds)
00413         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00414         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00415 {
00416     hdrObject * h;
00417     PyObject * key;
00418     char * how = "u";   /* XXX default to upgrade element if missing */
00419     int isUpgrade = 0;
00420     char * kwlist[] = {"header", "key", "how", NULL};
00421 
00422     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O|s:AddInstall", kwlist,
00423             &hdr_Type, &h, &key, &how))
00424         return NULL;
00425 
00426     {   PyObject * hObj = (PyObject *) h;
00427         if (hObj->ob_type != &hdr_Type) {
00428             PyErr_SetString(PyExc_TypeError, "bad type for header argument");
00429             return NULL;
00430         }
00431     }
00432 
00433 if (_rpmts_debug < 0 || (_rpmts_debug > 0 && *how != 'a'))
00434 fprintf(stderr, "*** rpmts_AddInstall(%p,%p,%p,%s) ts %p\n", s, h, key, how, s->ts);
00435 
00436     if (how && strcmp(how, "a") && strcmp(how, "u") && strcmp(how, "i")) {
00437         PyErr_SetString(PyExc_TypeError, "how argument must be \"u\", \"a\", or \"i\"");
00438         return NULL;
00439     } else if (how && !strcmp(how, "u"))
00440         isUpgrade = 1;
00441 
00442         rpmtsAddInstallElement(s->ts, hdrGetHeader(h), key, isUpgrade, NULL);
00443 
00444     /* This should increment the usage count for me */
00445     if (key)
00446         PyList_Append(s->keyList, key);
00447 
00448     Py_INCREF(Py_None);
00449     return Py_None;
00450 }
00451 
00455 /*@null@*/
00456 static PyObject *
00457 rpmts_AddErase(rpmtsObject * s, PyObject * args, PyObject * kwds)
00458         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00459         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00460 {
00461     PyObject * o;
00462     int count;
00463     rpmmi mi;
00464     char * kwlist[] = {"name", NULL};
00465 
00466 if (_rpmts_debug)
00467 fprintf(stderr, "*** rpmts_AddErase(%p) ts %p\n", s, s->ts);
00468 
00469     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:AddErase", kwlist, &o))
00470         return NULL;
00471 
00472     if (PyString_Check(o) || PyUnicode_Check(o)) {
00473         char * name = PyString_AsString(o);
00474 
00475         mi = rpmtsInitIterator(s->ts, RPMDBI_LABEL, name, 0);
00476         count = rpmmiCount(mi);
00477         if (count <= 0) {
00478             mi = rpmmiFree(mi);
00479             PyErr_SetString(pyrpmError, "package not installed");
00480             return NULL;
00481         } else { /* XXX: Note that we automatically choose to remove all matches */
00482             Header h;
00483             while ((h = rpmmiNext(mi)) != NULL) {
00484                 unsigned int recOffset = rpmmiInstance(mi);
00485                 if (recOffset)
00486                     rpmtsAddEraseElement(s->ts, h, recOffset);
00487             }
00488         }
00489         mi = rpmmiFree(mi);
00490     } else
00491     if (PyInt_Check(o)) {
00492         uint32_t instance = PyInt_AsLong(o);
00493 
00494         mi = rpmtsInitIterator(s->ts, RPMDBI_PACKAGES, &instance, sizeof(instance));
00495         if (instance == 0 || mi == NULL) {
00496             mi = rpmmiFree(mi);
00497             PyErr_SetString(pyrpmError, "package not installed");
00498             return NULL;
00499         } else {
00500             Header h;
00501             while ((h = rpmmiNext(mi)) != NULL) {
00502                 uint32_t recOffset = rpmmiInstance(mi);
00503                 if (recOffset)
00504                     rpmtsAddEraseElement(s->ts, h, recOffset);
00505                 break;
00506             }
00507         }
00508         mi = rpmmiFree(mi);
00509     }
00510 
00511     Py_INCREF(Py_None);
00512     return Py_None;
00513 }
00514 
00517 /*@null@*/
00518 static PyObject *
00519 rpmts_Check(rpmtsObject * s, PyObject * args, PyObject * kwds)
00520         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00521         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00522 {
00523     rpmps ps;
00524     rpmProblem p;
00525     PyObject * list, * cf;
00526     struct rpmtsCallbackType_s cbInfo;
00527     int i;
00528     int xx;
00529     char * kwlist[] = {"callback", NULL};
00530 
00531     memset(&cbInfo, 0, sizeof(cbInfo));
00532     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:Check", kwlist,
00533             &cbInfo.cb))
00534         return NULL;
00535 
00536     if (cbInfo.cb != NULL) {
00537         if (!PyCallable_Check(cbInfo.cb)) {
00538             PyErr_SetString(PyExc_TypeError, "expected a callable");
00539             return NULL;
00540         }
00541         xx = rpmtsSetSolveCallback(s->ts, rpmts_SolveCallback, (void *)&cbInfo);
00542     }
00543 
00544 if (_rpmts_debug)
00545 fprintf(stderr, "*** rpmts_Check(%p) ts %p cb %p\n", s, s->ts, cbInfo.cb);
00546 
00547     cbInfo.tso = s;
00548     cbInfo.dso = NULL;          /* XXX perhaps persistent? */
00549     cbInfo._save = PyEval_SaveThread();
00550 
00551     xx = rpmtsCheck(s->ts);
00552     ps = rpmtsProblems(s->ts);
00553 
00554     if (cbInfo.cb)
00555         xx = rpmtsSetSolveCallback(s->ts, rpmtsSolve, NULL);
00556 
00557     PyEval_RestoreThread(cbInfo._save);
00558 
00559     if (ps != NULL) {
00560         list = PyList_New(0);
00561         rpmpsi psi = rpmpsInitIterator(ps);
00562 
00563         while ((i = rpmpsNextIterator(psi)) >= 0) {
00564 #ifdef  DYING
00565             cf = Py_BuildValue("((sss)(ss)iOi)", conflicts[i].byName,
00566                                conflicts[i].byVersion, conflicts[i].byRelease,
00567 
00568                                conflicts[i].needsName,
00569                                conflicts[i].needsVersion,
00570 
00571                                conflicts[i].needsFlags,
00572                                conflicts[i].suggestedPkgs ?
00573                                    conflicts[i].suggestedPkgs[0] : Py_None,
00574                                conflicts[i].sense);
00575 #else
00576             char * byName, * byVersion, * byRelease, *byArch;
00577             char * needsName, * needsOP, * needsVersion;
00578             char * a, * b;
00579             int needsFlags, sense;
00580             fnpyKey key;
00581 
00582             p = rpmpsProblem(psi);
00583 
00584             /* XXX autorelocated i386 on ia64, fix system-config-packages! */
00585             if (rpmProblemGetType(p) == RPMPROB_BADRELOCATE)
00586                 continue;
00587 
00588             a = byName = xstrdup(rpmProblemGetPkgNEVR(p));
00589             if ((byArch= strrchr(byName, '.')) != NULL)
00590                 *byArch++ = '\0';
00591             if ((byRelease = strrchr(byName, '-')) != NULL)
00592                 *byRelease++ = '\0';
00593             if ((byVersion = strrchr(byName, '-')) != NULL)
00594                 *byVersion++ = '\0';
00595 
00596             key = rpmProblemKey(p);
00597 
00598             b = needsName = xstrdup(rpmProblemGetAltNEVR(p));
00599             if (needsName[1] == ' ') {
00600                 sense = (needsName[0] == 'C')
00601                         ? RPMDEP_SENSE_CONFLICTS : RPMDEP_SENSE_REQUIRES;
00602                 needsName += 2;
00603             } else
00604                 sense = RPMDEP_SENSE_REQUIRES;
00605             if ((needsVersion = strrchr(needsName, ' ')) != NULL)
00606                 *needsVersion++ = '\0';
00607 
00608             needsFlags = 0;
00609             if ((needsOP = strrchr(needsName, ' ')) != NULL) {
00610                 for (*needsOP++ = '\0'; *needsOP != '\0'; needsOP++) {
00611                     if (*needsOP == '<')        needsFlags |= RPMSENSE_LESS;
00612                     else if (*needsOP == '>')   needsFlags |= RPMSENSE_GREATER;
00613                     else if (*needsOP == '=')   needsFlags |= RPMSENSE_EQUAL;
00614                 }
00615             }
00616 
00617             cf = Py_BuildValue("((sss)(ss)iOi)", byName, byVersion, byRelease,
00618                                needsName, needsVersion, needsFlags,
00619                                (key != NULL ? key : Py_None),
00620                                sense);
00621             a = _free(a);
00622             b = _free(b);
00623 #endif
00624             PyList_Append(list, (PyObject *) cf);
00625             Py_DECREF(cf);
00626         }
00627 
00628         psi = rpmpsFreeIterator(psi);
00629         ps = rpmpsFree(ps);
00630 
00631         return list;
00632     }
00633 
00634     Py_INCREF(Py_None);
00635     return Py_None;
00636 }
00637 
00640 /*@null@*/
00641 static PyObject *
00642 rpmts_Order(rpmtsObject * s)
00643         /*@globals rpmGlobalMacroContext @*/
00644         /*@modifies s, rpmGlobalMacroContext @*/
00645 {
00646     int rc;
00647 
00648 if (_rpmts_debug)
00649 fprintf(stderr, "*** rpmts_Order(%p) ts %p\n", s, s->ts);
00650 
00651     Py_BEGIN_ALLOW_THREADS
00652     rc = rpmtsOrder(s->ts);
00653     Py_END_ALLOW_THREADS
00654 
00655     return Py_BuildValue("i", rc);
00656 }
00657 
00660 /*@null@*/
00661 static PyObject *
00662 rpmts_Clean(rpmtsObject * s)
00663         /*@globals _Py_NoneStruct @*/
00664         /*@modifies s, _Py_NoneStruct @*/
00665 {
00666 if (_rpmts_debug)
00667 fprintf(stderr, "*** rpmts_Clean(%p) ts %p\n", s, s->ts);
00668 
00669     rpmtsClean(s->ts);
00670 
00671     Py_INCREF(Py_None);
00672     return Py_None;
00673 }
00674 
00677 /*@null@*/
00678 static PyObject *
00679 rpmts_IDTXload(rpmtsObject * s, PyObject * args, PyObject * kwds)
00680         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00681         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00682 {
00683     PyObject * result = NULL;
00684     rpmTag tag = RPMTAG_INSTALLTID;
00685     char * kwlist[] = {"rbtid", NULL};
00686     uint32_t rbtid = 0;
00687     IDTX idtx;
00688 
00689 if (_rpmts_debug)
00690 fprintf(stderr, "*** rpmts_IDTXload(%p) ts %p\n", s, s->ts);
00691 
00692     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:IDTXload", kwlist, &rbtid))
00693         return NULL;
00694 
00695     Py_BEGIN_ALLOW_THREADS
00696     idtx = IDTXload(s->ts, tag, rbtid);
00697     Py_END_ALLOW_THREADS
00698 
00699 /*@-branchstate@*/
00700     if (idtx == NULL || idtx->nidt <= 0) {
00701         Py_INCREF(Py_None);
00702         result = Py_None;
00703     } else {
00704         PyObject * tuple;
00705         PyObject * ho;
00706         IDT idt;
00707         int i;
00708 
00709         result = PyTuple_New(idtx->nidt);
00710         for (i = 0; i < idtx->nidt; i++) {
00711             idt = idtx->idt + i;
00712             ho = (PyObject *) hdr_Wrap(idt->h);
00713             tuple = Py_BuildValue("(iOi)", idt->val.u32, ho, idt->instance);
00714             PyTuple_SET_ITEM(result,  i, tuple);
00715             Py_DECREF(ho);
00716         }
00717     }
00718 /*@=branchstate@*/
00719 
00720     idtx = IDTXfree(idtx);
00721 
00722     return result;
00723 }
00724 
00727 /*@null@*/
00728 static PyObject *
00729 rpmts_IDTXglob(rpmtsObject * s, PyObject * args, PyObject * kwds)
00730         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00731         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00732 {
00733     PyObject * result = NULL;
00734     const char * globstr;
00735     rpmTag tag = RPMTAG_REMOVETID;
00736     char * kwlist[] = {"rbtid", NULL};
00737     uint32_t rbtid = 0;
00738     IDTX idtx;
00739 
00740 if (_rpmts_debug)
00741 fprintf(stderr, "*** rpmts_IDTXglob(%p) ts %p\n", s, s->ts);
00742 
00743     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:IDTXglob", kwlist, &rbtid))
00744         return NULL;
00745 
00746     Py_BEGIN_ALLOW_THREADS
00747     globstr = rpmExpand("%{_repackage_dir}/*.rpm", NULL);
00748     idtx = IDTXglob(s->ts, globstr, tag, rbtid);
00749     globstr = _free(globstr);
00750     Py_END_ALLOW_THREADS
00751 
00752 /*@-branchstate@*/
00753     if (idtx == NULL || idtx->nidt <= 0) {
00754         Py_INCREF(Py_None);
00755         result = Py_None;
00756     } else {
00757         PyObject * tuple;
00758         PyObject * ho;
00759         IDT idt;
00760         int i;
00761 
00762         result = PyTuple_New(idtx->nidt);
00763         for (i = 0; i < idtx->nidt; i++) {
00764             idt = idtx->idt + i;
00765             ho = (PyObject *) hdr_Wrap(idt->h);
00766             tuple = Py_BuildValue("(iOs)", idt->val.u32, ho, idt->key);
00767             PyTuple_SET_ITEM(result,  i, tuple);
00768             Py_DECREF(ho);
00769         }
00770     }
00771 /*@=branchstate@*/
00772 
00773     idtx = IDTXfree(idtx);
00774 
00775     return result;
00776 }
00777 
00780 /*@null@*/
00781 static PyObject *
00782 rpmts_Rollback(rpmtsObject * s, PyObject * args, PyObject * kwds)
00783         /*@globals rpmGlobalMacroContext @*/
00784         /*@modifies s, rpmGlobalMacroContext @*/
00785 {
00786     QVA_t ia = memset(alloca(sizeof(*ia)), 0, sizeof(*ia));
00787     rpmtransFlags transFlags;
00788     const char ** av = NULL;
00789     uint32_t rbtid;
00790     int rc;
00791     char * kwlist[] = {"transactionId", NULL};
00792 
00793 if (_rpmts_debug)
00794 fprintf(stderr, "*** rpmts_Rollback(%p) ts %p\n", s, s->ts);
00795 
00796     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Rollback", kwlist, &rbtid))
00797         return NULL;
00798 
00799     Py_BEGIN_ALLOW_THREADS
00800     ia->qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE|VERIFY_HDRCHK);
00801     ia->transFlags |= (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL);
00802     ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS;
00803     ia->installInterfaceFlags = (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL);
00804     ia->rbtid = rbtid;
00805     ia->relocations = NULL;
00806     ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
00807 
00808     transFlags = rpmtsSetFlags(s->ts, ia->transFlags);
00809     rc = rpmRollback(s->ts, ia, av);
00810     transFlags = rpmtsSetFlags(s->ts, transFlags);
00811     Py_END_ALLOW_THREADS
00812 
00813     return Py_BuildValue("i", rc);
00814 }
00815 
00818 /*@null@*/
00819 static PyObject *
00820 rpmts_OpenDB(rpmtsObject * s)
00821         /*@globals rpmGlobalMacroContext @*/
00822         /*@modifies s, rpmGlobalMacroContext @*/
00823 {
00824 
00825 if (_rpmts_debug)
00826 fprintf(stderr, "*** rpmts_OpenDB(%p) ts %p\n", s, s->ts);
00827 
00828     if (rpmtsDBMode(s->ts) == -1)
00829         (void) rpmtsSetDBMode(s->ts, O_RDONLY);
00830 
00831     return Py_BuildValue("i", rpmtsOpenDB(s->ts, rpmtsDBMode(s->ts)));
00832 }
00833 
00836 /*@null@*/
00837 static PyObject *
00838 rpmts_CloseDB(rpmtsObject * s)
00839         /*@modifies s @*/
00840 {
00841     int rc;
00842 
00843 if (_rpmts_debug)
00844 fprintf(stderr, "*** rpmts_CloseDB(%p) ts %p\n", s, s->ts);
00845 
00846     rc = rpmtsCloseDB(s->ts);
00847     (void) rpmtsSetDBMode(s->ts, -1);           /* XXX disable lazy opens */
00848 
00849     return Py_BuildValue("i", rc);
00850 }
00851 
00854 /*@null@*/
00855 static PyObject *
00856 rpmts_InitDB(rpmtsObject * s)
00857         /*@globals rpmGlobalMacroContext @*/
00858         /*@modifies s, rpmGlobalMacroContext @*/
00859 {
00860     int rc;
00861 
00862 if (_rpmts_debug)
00863 fprintf(stderr, "*** rpmts_InitDB(%p) ts %p\n", s, s->ts);
00864 
00865     rc = rpmtsInitDB(s->ts, O_RDONLY);
00866     if (rc == 0)
00867         rc = rpmtsCloseDB(s->ts);
00868 
00869     return Py_BuildValue("i", rc);
00870 }
00871 
00874 /*@null@*/
00875 static PyObject *
00876 rpmts_RebuildDB(rpmtsObject * s)
00877         /*@globals rpmGlobalMacroContext @*/
00878         /*@modifies s, rpmGlobalMacroContext @*/
00879 {
00880     int rc;
00881 
00882 if (_rpmts_debug)
00883 fprintf(stderr, "*** rpmts_RebuildDB(%p) ts %p\n", s, s->ts);
00884 
00885     Py_BEGIN_ALLOW_THREADS
00886     rc = rpmtsRebuildDB(s->ts);
00887     Py_END_ALLOW_THREADS
00888 
00889     return Py_BuildValue("i", rc);
00890 }
00891 
00894 /*@null@*/
00895 static PyObject *
00896 rpmts_VerifyDB(rpmtsObject * s)
00897         /*@globals rpmGlobalMacroContext @*/
00898         /*@modifies s, rpmGlobalMacroContext @*/
00899 {
00900     int rc;
00901 
00902 if (_rpmts_debug)
00903 fprintf(stderr, "*** rpmts_VerifyDB(%p) ts %p\n", s, s->ts);
00904 
00905     Py_BEGIN_ALLOW_THREADS
00906     rc = rpmtsVerifyDB(s->ts);
00907     Py_END_ALLOW_THREADS
00908 
00909     return Py_BuildValue("i", rc);
00910 }
00911 
00914 /*@null@*/
00915 static PyObject *
00916 rpmts_HdrFromFdno(rpmtsObject * s, PyObject * args, PyObject * kwds)
00917         /*@globals rpmGlobalMacroContext, fileSystem @*/
00918         /*@modifies s, rpmGlobalMacroContext, fileSystem @*/
00919 {
00920     PyObject * result = NULL;
00921     Header h;
00922     FD_t fd;
00923     int fdno;
00924     rpmRC rpmrc;
00925     char * kwlist[] = {"fd", NULL};
00926 
00927     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:HdrFromFdno", kwlist,
00928             &fdno))
00929         return NULL;
00930 
00931     fd = fdDup(fdno);
00932     rpmrc = rpmReadPackageFile(s->ts, fd, "rpmts_HdrFromFdno", &h);
00933     Fclose(fd);
00934 
00935 if (_rpmts_debug)
00936 fprintf(stderr, "*** rpmts_HdrFromFdno(%p) ts %p rc %d\n", s, s->ts, rpmrc);
00937 
00938 /*@-branchstate@*/
00939     switch (rpmrc) {
00940     case RPMRC_OK:
00941         if (h)
00942             result = Py_BuildValue("N", hdr_Wrap(h));
00943         (void)headerFree(h);    /* XXX ref held by result */
00944         h = NULL;
00945         break;
00946 
00947     case RPMRC_NOKEY:
00948         PyErr_SetString(pyrpmError, "public key not available");
00949         break;
00950 
00951     case RPMRC_NOTTRUSTED:
00952         PyErr_SetString(pyrpmError, "public key not trusted");
00953         break;
00954 
00955     case RPMRC_NOTFOUND:
00956     case RPMRC_FAIL:
00957     default:
00958         PyErr_SetString(pyrpmError, "error reading package header");
00959         break;
00960     }
00961 /*@=branchstate@*/
00962 
00963     return result;
00964 }
00965 
00968 /*@null@*/
00969 static PyObject *
00970 rpmts_HdrCheck(rpmtsObject * s, PyObject * args, PyObject * kwds)
00971         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00972         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00973 {
00974     PyObject * blob;
00975     PyObject * result = NULL;
00976     const char * msg = NULL;
00977     const void * uh;
00978     int uc;
00979     pgpDig dig;
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     dig = pgpDigNew(rpmtsVSFlags(s->ts));
01001     rpmrc = headerCheck(dig, uh, uc, &msg);
01002     dig = pgpDigFree(dig, "rpmts_HdrCheck");
01003 
01004     switch (rpmrc) {
01005     case RPMRC_OK:
01006         Py_INCREF(Py_None);
01007         result = Py_None;
01008         break;
01009 
01010     case RPMRC_NOKEY:
01011         /* XXX note "availaiable", the script kiddies need the misspelling. */
01012         PyErr_SetString(pyrpmError, "public key not availaiable");
01013         break;
01014 
01015     case RPMRC_NOTTRUSTED:
01016         PyErr_SetString(pyrpmError, "public key not trusted");
01017         break;
01018 
01019     case RPMRC_FAIL:
01020     default:
01021         PyErr_SetString(pyrpmError, msg);
01022         break;
01023     }
01024     msg = _free(msg);
01025 
01026     return result;
01027 }
01028 
01031 static PyObject *
01032 rpmts_GetVSFlags(rpmtsObject * s)
01033 {
01034     return Py_BuildValue("i", rpmtsVSFlags(s->ts));
01035 }
01036 
01039 /*@null@*/
01040 static PyObject *
01041 rpmts_SetVSFlags(rpmtsObject * s, PyObject * args, PyObject * kwds)
01042         /*@modifies s @*/
01043 {
01044     rpmVSFlags vsflags;
01045     char * kwlist[] = {"flags", NULL};
01046 
01047 if (_rpmts_debug)
01048 fprintf(stderr, "*** rpmts_SetVSFlags(%p) ts %p\n", s, s->ts);
01049 
01050     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetVSFlags", kwlist,
01051             &vsflags))
01052         return NULL;
01053 
01054     /* XXX FIXME: value check on vsflags, or build pure python object 
01055      * for it, and require an object of that type */
01056 
01057     return Py_BuildValue("i", rpmtsSetVSFlags(s->ts, vsflags));
01058 }
01059 
01062 /*@null@*/
01063 static PyObject *
01064 rpmts_SetColor(rpmtsObject * s, PyObject * args, PyObject * kwds)
01065         /*@modifies s @*/
01066 {
01067     uint32_t tscolor;
01068     char * kwlist[] = {"color", NULL};
01069 
01070 if (_rpmts_debug)
01071 fprintf(stderr, "*** rpmts_SetColor(%p) ts %p\n", s, s->ts);
01072 
01073     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Color", kwlist, &tscolor))
01074         return NULL;
01075 
01076     /* XXX FIXME: value check on tscolor, or build pure python object
01077      * for it, and require an object of that type */
01078 
01079     return Py_BuildValue("i", rpmtsSetColor(s->ts, tscolor));
01080 }
01081 
01084 /*@null@*/
01085 static PyObject *
01086 rpmts_PgpPrtPkts(rpmtsObject * s, PyObject * args, PyObject * kwds)
01087         /*@globals _Py_NoneStruct @*/
01088         /*@modifies _Py_NoneStruct @*/
01089 {
01090     PyObject * blob;
01091     unsigned char * pkt;
01092     unsigned int pktlen;
01093     int rc;
01094     char * kwlist[] = {"octets", NULL};
01095 
01096 if (_rpmts_debug)
01097 fprintf(stderr, "*** rpmts_PgpPrtPkts(%p) ts %p\n", s, s->ts);
01098 
01099     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:PgpPrtPkts", kwlist, &blob))
01100         return NULL;
01101 
01102     if (blob == Py_None) {
01103         Py_INCREF(Py_None);
01104         return Py_None;
01105     }
01106     if (!(PyString_Check(blob) || PyUnicode_Check(blob))) {
01107         PyErr_SetString(pyrpmError, "pgpPrtPkts takes a string of octets");
01108         return NULL;
01109     }
01110     pkt = (unsigned char *) PyString_AsString(blob);
01111     pktlen = PyString_Size(blob);
01112 
01113     rc = pgpPrtPkts(pkt, pktlen, NULL, 1);
01114 
01115     return Py_BuildValue("i", rc);
01116 }
01117 
01120 /*@null@*/
01121 static PyObject *
01122 rpmts_PgpImportPubkey(rpmtsObject * s, PyObject * args, PyObject * kwds)
01123         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
01124         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
01125 {
01126     PyObject * blob;
01127     unsigned char * pkt;
01128     unsigned int pktlen;
01129     int rc;
01130     char * kwlist[] = {"pubkey", NULL};
01131 
01132 if (_rpmts_debug)
01133 fprintf(stderr, "*** rpmts_PgpImportPubkey(%p) ts %p\n", s, s->ts);
01134 
01135     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:PgpImportPubkey",
01136             kwlist, &blob))
01137         return NULL;
01138 
01139     if (blob == Py_None) {
01140         Py_INCREF(Py_None);
01141         return Py_None;
01142     }
01143     if (!(PyString_Check(blob) || PyUnicode_Check(blob))) {
01144         PyErr_SetString(pyrpmError, "PgpImportPubkey takes a string of octets");
01145         return NULL;
01146     }
01147     pkt = (unsigned char *) PyString_AsString(blob);
01148     pktlen = PyString_Size(blob);
01149 
01150     rc = rpmcliImportPubkey(s->ts, pkt, pktlen);
01151 
01152     return Py_BuildValue("i", rc);
01153 }
01154 
01157 static PyObject *
01158 rpmts_SetFlags(rpmtsObject * s, PyObject * args, PyObject * kwds)
01159         /*@modifies s @*/
01160 {
01161     rpmtransFlags transFlags = 0;
01162     char * kwlist[] = {"flags", NULL};
01163 
01164     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetFlags", kwlist,
01165             &transFlags))
01166         return NULL;
01167 
01168 if (_rpmts_debug)
01169 fprintf(stderr, "*** rpmts_SetFlags(%p) ts %p transFlags 0x%x\n", s, s->ts, transFlags);
01170 
01171     /* XXX FIXME: value check on flags, or build pure python object 
01172      * for it, and require an object of that type */
01173 
01174     return Py_BuildValue("i", rpmtsSetFlags(s->ts, transFlags));
01175 }
01176 
01179 static PyObject *
01180 rpmts_SetDFlags(rpmtsObject * s, PyObject * args, PyObject * kwds)
01181         /*@modifies s @*/
01182 {
01183     rpmdepFlags depFlags = 0;
01184     char * kwlist[] = {"flags", NULL};
01185 
01186     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetDFlags", kwlist,
01187             &depFlags))
01188         return NULL;
01189 
01190 if (_rpmts_debug)
01191 fprintf(stderr, "*** rpmts_SetDFlags(%p) ts %p depFlags 0x%x\n", s, s->ts, depFlags);
01192 
01193     /* XXX FIXME: value check on flags, or build pure python object 
01194      * for it, and require an object of that type */
01195 
01196     return Py_BuildValue("i", rpmtsSetDFlags(s->ts, depFlags));
01197 }
01198 
01201 static PyObject *
01202 rpmts_SetProbFilter(rpmtsObject * s, PyObject * args, PyObject * kwds)
01203         /*@modifies s @*/
01204 {
01205     rpmprobFilterFlags ignoreSet = 0;
01206     rpmprobFilterFlags oignoreSet = 0;
01207     char * kwlist[] = {"ignoreSet", NULL};
01208 
01209     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:ProbFilter", kwlist,
01210             &ignoreSet))
01211         return NULL;
01212 
01213 if (_rpmts_debug)
01214 fprintf(stderr, "*** rpmts_SetProbFilter(%p) ts %p ignoreSet %x\n", s, s->ts, ignoreSet);
01215 
01216     oignoreSet = s->ignoreSet;
01217     s->ignoreSet = ignoreSet;
01218 
01219     return Py_BuildValue("i", oignoreSet);
01220 }
01221 
01224 /*@null@*/
01225 static rpmpsObject *
01226 rpmts_Problems(rpmtsObject * s)
01227         /*@modifies s @*/
01228 {
01229 
01230 if (_rpmts_debug)
01231 fprintf(stderr, "*** rpmts_Problems(%p) ts %p\n", s, s->ts);
01232 
01233     return rpmps_Wrap( rpmtsProblems(s->ts) );
01234 }
01235 
01238 static PyObject *
01239 rpmts_Run(rpmtsObject * s, PyObject * args, PyObject * kwds)
01240         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
01241         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
01242 {
01243     int rc;
01244     PyObject * list;
01245     rpmps ps;
01246     rpmpsi psi;
01247     struct rpmtsCallbackType_s cbInfo;
01248     char * kwlist[] = {"callback", "data", NULL};
01249 
01250     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO:Run", kwlist,
01251             &cbInfo.cb, &cbInfo.data))
01252         return NULL;
01253 
01254     cbInfo.tso = s;
01255     cbInfo.dso = NULL;
01256     cbInfo._save = PyEval_SaveThread();
01257 
01258     if (cbInfo.cb != NULL) {
01259         if (!PyCallable_Check(cbInfo.cb)) {
01260             PyErr_SetString(PyExc_TypeError, "expected a callable");
01261             return NULL;
01262         }
01263         (void) rpmtsSetNotifyCallback(s->ts, rpmtsCallback, (void *) &cbInfo);
01264     }
01265 
01266 if (_rpmts_debug)
01267 fprintf(stderr, "*** rpmts_Run(%p) ts %p ignore %x\n", s, s->ts, s->ignoreSet);
01268 
01269     rc = rpmtsRun(s->ts, NULL, s->ignoreSet);
01270     ps = rpmtsProblems(s->ts);
01271 
01272     if (cbInfo.cb)
01273         (void) rpmtsSetNotifyCallback(s->ts, NULL, NULL);
01274 
01275     PyEval_RestoreThread(cbInfo._save);
01276 
01277     if (rc < 0) {
01278         list = PyList_New(0);
01279         return list;
01280     } else if (!rc) {
01281         Py_INCREF(Py_None);
01282         return Py_None;
01283     }
01284 
01285     list = PyList_New(0);
01286     psi = rpmpsInitIterator(ps);
01287     while (rpmpsNextIterator(psi) >= 0) {
01288         rpmProblem p = rpmpsProblem(psi);
01289         PyObject * prob = Py_BuildValue("s(isN)", rpmProblemString(p),
01290                              rpmProblemGetType(p),
01291                              rpmProblemGetStr(p),
01292                              PyLong_FromLongLong(rpmProblemGetDiskNeed(p)));
01293         PyList_Append(list, prob);
01294         Py_DECREF(prob);
01295     }
01296     psi = rpmpsFreeIterator(psi);
01297 
01298     ps = rpmpsFree(ps);
01299 
01300     return list;
01301 }
01302 
01306 static PyObject *
01307 rpmts_Next(rpmtsObject * s)
01308         /*@globals _Py_NoneStruct @*/
01309         /*@modifies s, _Py_NoneStruct @*/
01310 {
01311     PyObject * result;
01312 
01313 if (_rpmts_debug)
01314 fprintf(stderr, "*** rpmts_Next(%p) ts %p\n", s, s->ts);
01315 
01316     result = rpmts_iternext(s);
01317 
01318     if (result == NULL) {
01319         Py_INCREF(Py_None);
01320         return Py_None;
01321     }
01322 
01323     return result;
01324 }
01325 
01328 /*@null@*/
01329 static specObject *
01330 spec_Parse(rpmtsObject * s, PyObject * args, PyObject * kwds)
01331         /*@globals rpmGlobalMacroContext @*/
01332         /*@modifies s, rpmGlobalMacroContext @*/
01333 {
01334     const char * specfile;
01335     Spec spec;
01336     int recursing = 0;
01337     char * passPhrase = "";
01338     char *cookie = NULL;
01339     int anyarch = 1;
01340     int verify = 1;
01341     int force = 1;
01342     char * kwlist[] = {"specfile", NULL};
01343 
01344     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:Parse", kwlist, &specfile))
01345         return NULL;
01346 
01347     if (parseSpec(s->ts, specfile,"/", recursing, passPhrase,
01348              cookie, anyarch, force, verify)!=0) {
01349              PyErr_SetString(pyrpmError, "can't parse specfile\n");
01350                      return NULL;
01351    }
01352 
01353     spec = rpmtsSpec(s->ts);
01354     return spec_Wrap(spec);
01355 }
01356 
01359 /*@null@*/
01360 static rpmmiObject *
01361 rpmts_Match(rpmtsObject * s, PyObject * args, PyObject * kwds)
01362         /*@globals rpmGlobalMacroContext @*/
01363         /*@modifies s, rpmGlobalMacroContext @*/
01364 {
01365     PyObject *TagN = NULL;
01366     PyObject *Key = NULL;
01367     char *key = NULL;
01368 /* XXX lkey *must* be a 32 bit integer, int "works" on all known platforms. */
01369     int lkey = 0;
01370     int len = 0;
01371     int tag = RPMDBI_PACKAGES;
01372     char * kwlist[] = {"tagNumber", "key", NULL};
01373 
01374 if (_rpmts_debug)
01375 fprintf(stderr, "*** rpmts_Match(%p) ts %p\n", s, s->ts);
01376 
01377     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:Match", kwlist,
01378             &TagN, &Key))
01379         return NULL;
01380 
01381     if (TagN && (tag = tagNumFromPyObject (TagN)) == -1) {
01382         PyErr_SetString(PyExc_TypeError, "unknown tag type");
01383         return NULL;
01384     }
01385 
01386     if (Key) {
01387 /*@-branchstate@*/
01388         if (PyString_Check(Key) || PyUnicode_Check(Key)) {
01389             key = PyString_AsString(Key);
01390             len = PyString_Size(Key);
01391         } else if (PyInt_Check(Key)) {
01392             lkey = PyInt_AsLong(Key);
01393             key = (char *)&lkey;
01394             len = sizeof(lkey);
01395         } else {
01396             PyErr_SetString(PyExc_TypeError, "unknown key type");
01397             return NULL;
01398         }
01399 /*@=branchstate@*/
01400     }
01401 
01402     /* XXX If not already opened, open the database O_RDONLY now. */
01403     /* XXX FIXME: lazy default rdonly open also done by rpmtsInitIterator(). */
01404     if (rpmtsGetRdb(s->ts) == NULL) {
01405         int rc = rpmtsOpenDB(s->ts, O_RDONLY);
01406         if (rc || rpmtsGetRdb(s->ts) == NULL) {
01407             PyErr_SetString(PyExc_TypeError, "rpmdb open failed");
01408             return NULL;
01409         }
01410     }
01411 
01412     return rpmmi_Wrap( rpmtsInitIterator(s->ts, tag, key, len) );
01413 }
01414 
01419 /*@-fullinitblock@*/
01420 /*@unchecked@*/ /*@observer@*/
01421 static struct PyMethodDef rpmts_methods[] = {
01422  {"Debug",      (PyCFunction)rpmts_Debug,       METH_VARARGS|METH_KEYWORDS,
01423         NULL},
01424 
01425  {"addInstall", (PyCFunction) rpmts_AddInstall, METH_VARARGS|METH_KEYWORDS,
01426         NULL },
01427  {"addErase",   (PyCFunction) rpmts_AddErase,   METH_VARARGS|METH_KEYWORDS,
01428         NULL },
01429  {"setDFlags",  (PyCFunction) rpmts_SetDFlags,  METH_VARARGS|METH_KEYWORDS,
01430 "ts.setDFlags(depFlags) -> previous depFlags\n\
01431 - Set control bit(s) for executing ts.check() and ts.order().\n" },
01432  {"check",      (PyCFunction) rpmts_Check,      METH_VARARGS|METH_KEYWORDS,
01433         NULL },
01434  {"order",      (PyCFunction) rpmts_Order,      METH_NOARGS,
01435         NULL },
01436  {"setFlags",   (PyCFunction) rpmts_SetFlags,   METH_VARARGS|METH_KEYWORDS,
01437 "ts.setFlags(transFlags) -> previous transFlags\n\
01438 - Set control bit(s) for executing ts.run().\n\
01439   Note: This method replaces the 1st argument to the old ts.run()\n" },
01440  {"setProbFilter",      (PyCFunction) rpmts_SetProbFilter,      METH_VARARGS|METH_KEYWORDS,
01441 "ts.setProbFilter(ignoreSet) -> previous ignoreSet\n\
01442 - Set control bit(s) for ignoring problems found by ts.run().\n\
01443   Note: This method replaces the 2nd argument to the old ts.run()\n" },
01444  {"problems",   (PyCFunction) rpmts_Problems,   METH_NOARGS,
01445 "ts.problems() -> ps\n\
01446 - Return current problem set.\n" },
01447  {"run",        (PyCFunction) rpmts_Run,        METH_VARARGS|METH_KEYWORDS,
01448 "ts.run(callback, data) -> (problems)\n\
01449 - Run a transaction set, returning list of problems found.\n\
01450   Note: The callback may not be None.\n" },
01451  {"clean",      (PyCFunction) rpmts_Clean,      METH_NOARGS,
01452         NULL },
01453  {"IDTXload",   (PyCFunction) rpmts_IDTXload,   METH_VARARGS|METH_KEYWORDS,
01454 "ts.IDTXload(rbtid=iid) -> ((tid,hdr,instance)+)\n\
01455 - Return list of installed packages reverse sorted by transaction id.\n" },
01456  {"IDTXglob",   (PyCFunction) rpmts_IDTXglob,   METH_VARARGS|METH_KEYWORDS,
01457 "ts.IDTXglob(rbtid=rid) -> ((tid,hdr,instance)+)\n\
01458 - Return list of removed packages reverse sorted by transaction id.\n" },
01459  {"rollback",   (PyCFunction) rpmts_Rollback,   METH_VARARGS|METH_KEYWORDS,
01460         NULL },
01461  {"openDB",     (PyCFunction) rpmts_OpenDB,     METH_NOARGS,
01462 "ts.openDB() -> None\n\
01463 - Open the default transaction rpmdb.\n\
01464   Note: The transaction rpmdb is lazily opened, so ts.openDB() is seldom needed.\n" },
01465  {"closeDB",    (PyCFunction) rpmts_CloseDB,    METH_NOARGS,
01466 "ts.closeDB() -> None\n\
01467 - Close the default transaction rpmdb.\n\
01468   Note: ts.closeDB() disables lazy opens, and should hardly ever be used.\n" },
01469  {"initDB",     (PyCFunction) rpmts_InitDB,     METH_NOARGS,
01470 "ts.initDB() -> None\n\
01471 - Initialize the default transaction rpmdb.\n\
01472  Note: ts.initDB() is seldom needed anymore.\n" },
01473  {"rebuildDB",  (PyCFunction) rpmts_RebuildDB,  METH_NOARGS,
01474 "ts.rebuildDB() -> None\n\
01475 - Rebuild the default transaction rpmdb.\n" },
01476  {"verifyDB",   (PyCFunction) rpmts_VerifyDB,   METH_NOARGS,
01477 "ts.verifyDB() -> None\n\
01478 - Verify the default transaction rpmdb.\n" },
01479  {"hdrFromFdno",(PyCFunction) rpmts_HdrFromFdno,METH_VARARGS|METH_KEYWORDS,
01480 "ts.hdrFromFdno(fdno) -> hdr\n\
01481 - Read a package header from a file descriptor.\n" },
01482  {"hdrCheck",   (PyCFunction) rpmts_HdrCheck,   METH_VARARGS|METH_KEYWORDS,
01483         NULL },
01484 {"getVSFlags",(PyCFunction) rpmts_GetVSFlags,   METH_NOARGS,
01485 "ts.getVSFlags() -> vsflags\n\
01486 - Retrieve current signature verification flags from transaction\n" },
01487  {"setVSFlags",(PyCFunction) rpmts_SetVSFlags,  METH_VARARGS|METH_KEYWORDS,
01488 "ts.setVSFlags(vsflags) -> ovsflags\n\
01489 - Set signature verification flags. Values for vsflags are:\n\
01490     rpm.RPMVSF_NOHDRCHK      if set, don't check rpmdb headers\n\
01491     rpm.RPMVSF_NEEDPAYLOAD   if not set, check header+payload (if possible)\n\
01492     rpm.RPMVSF_NOSHA1HEADER  if set, don't check header SHA1 digest\n\
01493     rpm.RPMVSF_NODSAHEADER   if set, don't check header DSA signature\n\
01494     rpm.RPMVSF_NORSAHEADER   if set, don't check header RSA signature\n\
01495     rpm.RPMVSF_NOMD5         if set, don't check header+payload MD5 digest\n\
01496     rpm.RPMVSF_NODSA         if set, don't check header+payload DSA signature\n\
01497     rpm.RPMVSF_NORSA         if set, don't check header+payload RSA signature\n\
01498     rpm._RPMVSF_NODIGESTS    if set, don't check digest(s)\n\
01499     rpm._RPMVSF_NOSIGNATURES if set, don't check signature(s)\n" },
01500  {"setColor",(PyCFunction) rpmts_SetColor,      METH_VARARGS|METH_KEYWORDS,
01501         NULL },
01502  {"pgpPrtPkts", (PyCFunction) rpmts_PgpPrtPkts, METH_VARARGS|METH_KEYWORDS,
01503         NULL },
01504  {"pgpImportPubkey",    (PyCFunction) rpmts_PgpImportPubkey,    METH_VARARGS|METH_KEYWORDS,
01505         NULL },
01506  {"parseSpec",  (PyCFunction) spec_Parse,       METH_VARARGS|METH_KEYWORDS,
01507 "ts.parseSpec(\"/path/to/foo.spec\") -> spec\n\
01508 - Parse a spec file.\n" },
01509  {"dbMatch",    (PyCFunction) rpmts_Match,      METH_VARARGS|METH_KEYWORDS,
01510 "ts.dbMatch([TagN, [key, [len]]]) -> mi\n\
01511 - Create a match iterator for the default transaction rpmdb.\n" },
01512  {"next",               (PyCFunction)rpmts_Next,        METH_NOARGS,
01513 "ts.next() -> te\n\
01514 - Retrieve next transaction set element.\n" },
01515     {NULL,              NULL}           /* sentinel */
01516 };
01517 /*@=fullinitblock@*/
01518 
01521 static void rpmts_dealloc(/*@only@*/ rpmtsObject * s)
01522         /*@modifies *s @*/
01523 {
01524 
01525 if (_rpmts_debug)
01526 fprintf(stderr, "%p -- ts %p db %p\n", s, s->ts, rpmtsGetRdb(s->ts));
01527     (void)rpmtsFree(s->ts);
01528     s->ts = NULL;
01529 
01530     if (s->scriptFd) Fclose(s->scriptFd);
01531     /* this will free the keyList, and decrement the ref count of all
01532        the items on the list as well :-) */
01533     Py_DECREF(s->keyList);
01534     PyObject_Del((PyObject *)s);
01535 }
01536 
01537 static PyObject * rpmts_getattro(PyObject * o, PyObject * n)
01538         /*@*/
01539 {
01540     return PyObject_GenericGetAttr(o, n);
01541 }
01542 
01545 static int rpmts_setattro(PyObject * o, PyObject * n, PyObject * v)
01546         /*@*/
01547 {
01548     rpmtsObject *s = (rpmtsObject *)o;
01549     char * name = PyString_AsString(n);
01550     int fdno;
01551 
01552     if (!strcmp(name, "scriptFd")) {
01553         if (!PyArg_Parse(v, "i", &fdno)) return 0;
01554         if (fdno < 0) {
01555             PyErr_SetString(PyExc_TypeError, "bad file descriptor");
01556             return -1;
01557         } else {
01558             s->scriptFd = fdDup(fdno);
01559             rpmtsSetScriptFd(s->ts, s->scriptFd);
01560         }
01561     } else {
01562         PyErr_SetString(PyExc_AttributeError, name);
01563         return -1;
01564     }
01565 
01566     return 0;
01567 }
01568 
01571 static int rpmts_init(rpmtsObject * s, PyObject *args, PyObject *kwds)
01572         /*@globals rpmGlobalMacroContext @*/
01573         /*@modifies s, rpmGlobalMacroContext @*/
01574 {
01575     /* nothing to do atm... */
01576     return 0;
01577 }
01578 
01581 static void rpmts_free(/*@only@*/ rpmtsObject * s)
01582         /*@modifies s @*/
01583 {
01584 if (_rpmts_debug)
01585 fprintf(stderr, "%p -- ts %p db %p\n", s, s->ts, rpmtsGetRdb(s->ts));
01586     (void)rpmtsFree(s->ts);
01587     s->ts = NULL;
01588 
01589     if (s->scriptFd)
01590         Fclose(s->scriptFd);
01591 
01592     /* this will free the keyList, and decrement the ref count of all
01593        the items on the list as well :-) */
01594     Py_DECREF(s->keyList);
01595 
01596     PyObject_Del((PyObject *)s);
01597 }
01598 
01601 static PyObject * rpmts_alloc(PyTypeObject * subtype, int nitems)
01602         /*@*/
01603 {
01604     PyObject * s = PyType_GenericAlloc(subtype, nitems);
01605 
01606 if (_rpmts_debug < 0)
01607 fprintf(stderr, "*** rpmts_alloc(%p,%d) ret %p\n", subtype, nitems, s);
01608     return s;
01609 }
01610 
01613 static PyObject * rpmts_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
01614         /*@globals rpmGlobalMacroContext @*/
01615         /*@modifies rpmGlobalMacroContext @*/
01616 {
01617     rpmtsObject * s = (void *) PyObject_New(rpmtsObject, subtype);
01618 
01619     char * rootDir = "/";
01620     int vsflags = rpmExpandNumeric("%{?_vsflags}");
01621     char * kwlist[] = {"rootdir", "vsflags", 0};
01622 
01623 if (_rpmts_debug < 0)
01624 fprintf(stderr, "*** rpmts_init(%p,%p,%p)\n", s, args, kwds);
01625 
01626     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|si:rpmts_init", kwlist,
01627             &rootDir, &vsflags))
01628         return NULL;
01629 
01630     s->ts = rpmtsCreate();
01631     /* XXX: Why is there no rpmts_SetRootDir() ? */
01632     (void) rpmtsSetRootDir(s->ts, rootDir);
01633     /* XXX: make this use common code with rpmts_SetVSFlags() to check the
01634      *      python objects */
01635     (void) rpmtsSetVSFlags(s->ts, vsflags);
01636     s->keyList = PyList_New(0);
01637     s->ignoreSet = 0;
01638     s->scriptFd = NULL;
01639     s->tsi = NULL;
01640     s->tsiFilter = 0;
01641 
01642 if (_rpmts_debug)
01643 fprintf(stderr, "%p ++ ts %p db %p\n", s, s->ts, rpmtsGetRdb(s->ts));
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         (freefunc) rpmts_free,          /* tp_free */
01699         0,                              /* tp_is_gc */
01700 #endif
01701 };
01702 /*@=fullinitblock@*/
01703 
01706 PyObject *
01707 rpmts_Create(/*@unused@*/ PyObject * s, PyObject * args,
01708                 PyObject * kwds)
01709 {
01710     return PyObject_Call((PyObject *) &rpmts_Type, args, kwds);
01711 }

Generated on Fri Dec 3 2010 20:53:53 for rpm by  doxygen 1.7.2