rpm 5.2.1

- 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 }