Main Page Modules Data Structures File List Data Fields Globals Related Pages

# python/rpmts-py.c

Go to the documentation of this file.

    00001
    00005 #include "system.h"
    00006
    00007 #include "Python.h"
    00008 #ifdef __LCLINT__
    00009 #undef  PyObject_HEAD
    00010 #define PyObject_HEAD   int _PyObjectHead;
    00011 #endif
    00012
    00013 #include <rpmcli.h>
    00014 #include <rpmpgp.h>
    00015 #include <rpmdb.h>
    00016
    00017 #include "header-py.h"
    00018 #include "rpmds-py.h"   /* XXX for rpmdsNew */
    00019 #include "rpmfi-py.h"   /* XXX for rpmfiNew */
    00020 #include "rpmmi-py.h"
    00021 #include "rpmte-py.h"
    00022
    00023 #define _RPMTS_INTERNAL /* XXX for ts->rdb, ts->availablePackage */
    00024 #include "rpmts-py.h"
    00025
    00026 #include "debug.h"
    00027
    00028 static int _rpmts_debug = 0;
    00029
    00030 /*@access alKey @*/
    00031
    00152 struct rpmtsCallbackType_s {
    00153     PyObject * cb;
    00154     PyObject * data;
    00155     rpmtsObject * tso;
    00156     int pythonError;
    00157     PyThreadState *_save;
    00158 };
    00159
    00162 static PyObject *
    00163 rpmts_Debug(/*@unused@*/ rpmtsObject * s, PyObject * args)
    00164         /*@globals _Py_NoneStruct @*/
    00165         /*@modifies _Py_NoneStruct @*/
    00166 {
    00167     if (!PyArg_ParseTuple(args, "i:Debug", &_rpmts_debug)) return NULL;
    00168
    00169 if (_rpmts_debug < 0)
    00170 fprintf(stderr, "*** rpmts_Debug(%p) ts %p\n", s, s->ts);
    00171
    00172     Py_INCREF(Py_None);
    00173     return Py_None;
    00174 }
    00175
    00182 static void rpmtsAddAvailableElement(rpmts ts, Header h,
    00183                 /*@exposed@*/ /*@null@*/ fnpyKey key)
    00184         /*@modifies h, ts @*/
    00185 {
    00186     int scareMem = 0;
    00187     rpmds provides = rpmdsNew(h, RPMTAG_PROVIDENAME, scareMem);
    00188     rpmfi fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
    00189
    00190     /* XXX FIXME: return code RPMAL_NOMATCH is error */
    00191     (void) rpmalAdd(&ts->availablePackages, RPMAL_NOMATCH, key,
    00192                 provides, fi);
    00193     fi = rpmfiFree(fi);
    00194     provides = rpmdsFree(provides);
    00195
    00196 if (_rpmts_debug < 0)
    00197 fprintf(stderr, "\tAddAvailable(%p) list %p\n", ts, ts->availablePackages);
    00198
    00199 }
    00200
    00203 static PyObject *
    00204 rpmts_AddInstall(rpmtsObject * s, PyObject * args)
    00205         /*@globals _Py_NoneStruct @*/
    00206         /*@modifies s, _Py_NoneStruct @*/
    00207 {
    00208     hdrObject * h;
    00209     PyObject * key;
    00210     char * how = NULL;
    00211     int isUpgrade = 0;
    00212
    00213     if (!PyArg_ParseTuple(args, "O!O|s:AddInstall", &hdr_Type, &h, &key, &how))
    00214         return NULL;
    00215
    00216     {   PyObject * hObj = (PyObject *) h;
    00217         if (hObj->ob_type != &hdr_Type) {
    00218             PyErr_SetString(PyExc_TypeError, "bad type for header argument");
    00219             return NULL;
    00220         }
    00221     }
    00222
    00223 if (_rpmts_debug < 0 || (_rpmts_debug > 0 && *how != 'a'))
    00224 fprintf(stderr, "*** rpmts_AddInstall(%p) ts %p\n", s, s->ts);
    00225
    00226     if (how && strcmp(how, "a") && strcmp(how, "u") && strcmp(how, "i")) {
    00227         PyErr_SetString(PyExc_TypeError, "how argument must be \"u\", \"a\", or \"i\"");
    00228         return NULL;
    00229     } else if (how && !strcmp(how, "u"))
    00230         isUpgrade = 1;
    00231
    00232     if (how && !strcmp(how, "a"))
    00233         rpmtsAddAvailableElement(s->ts, hdrGetHeader(h), key);
    00234     else
    00235         rpmtsAddInstallElement(s->ts, hdrGetHeader(h), key, isUpgrade, NULL);
    00236
    00237     /* This should increment the usage count for me */
    00238     if (key) {
    00239         PyList_Append(s->keyList, key);
    00240     }
    00241
    00242     Py_INCREF(Py_None);
    00243     return Py_None;
    00244 }
    00245
    00249 static PyObject *
    00250 rpmts_AddErase(rpmtsObject * s, PyObject * args)
    00251         /*@globals _Py_NoneStruct @*/
    00252         /*@modifies s, _Py_NoneStruct @*/
    00253 {
    00254     PyObject * o;
    00255     int count;
    00256     rpmdbMatchIterator mi;
    00257
    00258 if (_rpmts_debug)
    00259 fprintf(stderr, "*** rpmts_AddErase(%p) ts %p\n", s, s->ts);
    00260
    00261     if (!PyArg_ParseTuple(args, "O:AddErase", &o))
    00262         return NULL;
    00263
    00264     if (PyString_Check(o)) {
    00265         char * name = PyString_AsString(o);
    00266
    00267         mi = rpmtsInitIterator(s->ts, RPMDBI_LABEL, name, 0);
    00268         count = rpmdbGetIteratorCount(mi);
    00269         if (count <= 0) {
    00270             mi = rpmdbFreeIterator(mi);
    00271             PyErr_SetString(pyrpmError, "package not installed");
    00272             return NULL;
    00273         } else { /* XXX: Note that we automatically choose to remove all matches */
    00274             Header h;
    00275             while ((h = rpmdbNextIterator(mi)) != NULL) {
    00276                 unsigned int recOffset = rpmdbGetIteratorOffset(mi);
    00277                 if (recOffset)
    00278                     rpmtsAddEraseElement(s->ts, h, recOffset);
    00279             }
    00280         }
    00281         mi = rpmdbFreeIterator(mi);
    00282     } else
    00283     if (PyInt_Check(o)) {
    00284         uint_32 instance = PyInt_AsLong(o);
    00285
    00286         mi = rpmtsInitIterator(s->ts, RPMDBI_PACKAGES, &instance, sizeof(instance));
    00287         if (instance <= 0 || mi == NULL) {
    00288             mi = rpmdbFreeIterator(mi);
    00289             PyErr_SetString(pyrpmError, "package not installed");
    00290             return NULL;
    00291         } else {
    00292             Header h;
    00293             while ((h = rpmdbNextIterator(mi)) != NULL) {
    00294                 uint_32 recOffset = rpmdbGetIteratorOffset(mi);
    00295                 if (recOffset)
    00296                     rpmtsAddEraseElement(s->ts, h, recOffset);
    00297                 break;
    00298             }
    00299         }
    00300         mi = rpmdbFreeIterator(mi);
    00301     }
    00302
    00303     Py_INCREF(Py_None);
    00304     return Py_None;
    00305 }
    00306
    00309 static int
    00310 rpmts_SolveCallback(rpmts ts, rpmds ds, void * data)
    00311         /*@*/
    00312 {
    00313     struct rpmtsCallbackType_s * cbInfo = data;
    00314     PyObject * args, * result;
    00315     int res = 1;
    00316
    00317 if (_rpmts_debug)
    00318 fprintf(stderr, "*** rpmts_SolveCallback(%p,%p,%p) \"%s\"\n", ts, ds, data, rpmdsDNEVR(ds));
    00319
    00320     if (cbInfo->tso == NULL) return res;
    00321     if (cbInfo->pythonError) return res;
    00322     if (cbInfo->cb == Py_None) return res;
    00323
    00324     PyEval_RestoreThread(cbInfo->_save);
    00325
    00326     args = Py_BuildValue("(Oissi)", cbInfo->tso,
    00327                 rpmdsTagN(ds), rpmdsN(ds), rpmdsEVR(ds), rpmdsFlags(ds));
    00328     result = PyEval_CallObject(cbInfo->cb, args);
    00329     Py_DECREF(args);
    00330
    00331     if (!result) {
    00332         cbInfo->pythonError = 1;
    00333     } else {
    00334         if (PyInt_Check(result))
    00335             res = PyInt_AsLong(result);
    00336         Py_DECREF(result);
    00337     }
    00338
    00339     cbInfo->_save = PyEval_SaveThread();
    00340
    00341     return res;
    00342 }
    00343
    00346 static PyObject *
    00347 rpmts_Check(rpmtsObject * s, PyObject * args)
    00348         /*@globals _Py_NoneStruct @*/
    00349         /*@modifies s, _Py_NoneStruct @*/
    00350 {
    00351     rpmps ps;
    00352     rpmProblem p;
    00353     PyObject * list, * cf;
    00354     struct rpmtsCallbackType_s cbInfo;
    00355     int i;
    00356     int xx;
    00357
    00358     memset(&cbInfo, 0, sizeof(cbInfo));
    00359     if (!PyArg_ParseTuple(args, "|O:Check", &cbInfo.cb))
    00360         return NULL;
    00361
    00362     if (cbInfo.cb != NULL) {
    00363         if (!PyCallable_Check(cbInfo.cb)) {
    00364             PyErr_SetString(PyExc_TypeError, "expected a callable");
    00365             return NULL;
    00366         }
    00367         xx = rpmtsSetSolveCallback(s->ts, rpmts_SolveCallback, (void *)&cbInfo);
    00368     }
    00369
    00370 if (_rpmts_debug)
    00371 fprintf(stderr, "*** rpmts_Check(%p) ts %p cb %p\n", s, s->ts, cbInfo.cb);
    00372
    00373     cbInfo.tso = s;
    00374     cbInfo.pythonError = 0;
    00375     cbInfo._save = PyEval_SaveThread();
    00376
    00377     xx = rpmtsCheck(s->ts);
    00378     ps = rpmtsProblems(s->ts);
    00379
    00380     if (cbInfo.cb) {
    00381         xx = rpmtsSetSolveCallback(s->ts, rpmtsSolve, NULL);
    00382     }
    00383
    00384     PyEval_RestoreThread(cbInfo._save);
    00385
    00386     if (ps) {
    00387         list = PyList_New(0);
    00388
    00389         /* XXX TODO: rpmlib >= 4.0.3 can return multiple suggested keys. */
    00390         for (i = 0; i < ps->numProblems; i++) {
    00391 #ifdef  DYING
    00392             cf = Py_BuildValue("((sss)(ss)iOi)", conflicts[i].byName,
    00393                                conflicts[i].byVersion, conflicts[i].byRelease,
    00394
    00395                                conflicts[i].needsName,
    00396                                conflicts[i].needsVersion,
    00397
    00398                                conflicts[i].needsFlags,
    00399                                conflicts[i].suggestedPkgs ?
    00400                                    conflicts[i].suggestedPkgs[0] : Py_None,
    00401                                conflicts[i].sense);
    00402 #else
    00403             char * byName, * byVersion, * byRelease;
    00404             char * needsName, * needsOP, * needsVersion;
    00405             int needsFlags, sense;
    00406             fnpyKey key;
    00407
    00408             p = ps->probs + i;
    00409
    00410             byName = p->pkgNEVR;
    00411             if ((byRelease = strrchr(byName, '-')) != NULL)
    00412                 *byRelease++ = '\0';
    00413             if ((byVersion = strrchr(byName, '-')) != NULL)
    00414                 *byVersion++ = '\0';
    00415
    00416             key = p->key;
    00417
    00418             needsName = p->altNEVR;
    00419             if (needsName[1] == ' ') {
    00420                 sense = (needsName[0] == 'C')
    00421                         ? RPMDEP_SENSE_CONFLICTS : RPMDEP_SENSE_REQUIRES;
    00422                 needsName += 2;
    00423             } else
    00424                 sense = RPMDEP_SENSE_REQUIRES;
    00425             if ((needsVersion = strrchr(needsName, ' ')) != NULL)
    00426                 *needsVersion++ = '\0';
    00427
    00428             needsFlags = 0;
    00429             if ((needsOP = strrchr(needsName, ' ')) != NULL) {
    00430                 for (*needsOP++ = '\0'; *needsOP != '\0'; needsOP++) {
    00431                     if (*needsOP == '<')        needsFlags |= RPMSENSE_LESS;
    00432                     else if (*needsOP == '>')   needsFlags |= RPMSENSE_GREATER;
    00433                     else if (*needsOP == '=')   needsFlags |= RPMSENSE_EQUAL;
    00434                 }
    00435             }
    00436
    00437             cf = Py_BuildValue("((sss)(ss)iOi)", byName, byVersion, byRelease,
    00438                                needsName, needsVersion, needsFlags,
    00439                                (key != NULL ? key : Py_None),
    00440                                sense);
    00441 #endif
    00442             PyList_Append(list, (PyObject *) cf);
    00443             Py_DECREF(cf);
    00444         }
    00445
    00446         ps = rpmpsFree(ps);
    00447
    00448         return list;
    00449     }
    00450
    00451     Py_INCREF(Py_None);
    00452     return Py_None;
    00453 }
    00454
    00457 static PyObject *
    00458 rpmts_Order(rpmtsObject * s, PyObject * args)
    00459         /*@globals _Py_NoneStruct @*/
    00460         /*@modifies s, _Py_NoneStruct @*/
    00461 {
    00462     int rc;
    00463
    00464 if (_rpmts_debug)
    00465 fprintf(stderr, "*** rpmts_Order(%p) ts %p\n", s, s->ts);
    00466
    00467     if (!PyArg_ParseTuple(args, ":Order")) return NULL;
    00468
    00469     Py_BEGIN_ALLOW_THREADS
    00470     rc = rpmtsOrder(s->ts);
    00471     Py_END_ALLOW_THREADS
    00472
    00473     return Py_BuildValue("i", rc);
    00474 }
    00475
    00478 static PyObject *
    00479 rpmts_Clean(rpmtsObject * s, PyObject * args)
    00480         /*@globals _Py_NoneStruct @*/
    00481         /*@modifies s, _Py_NoneStruct @*/
    00482 {
    00483 if (_rpmts_debug)
    00484 fprintf(stderr, "*** rpmts_Clean(%p) ts %p\n", s, s->ts);
    00485
    00486     if (!PyArg_ParseTuple(args, ":Clean")) return NULL;
    00487
    00488     rpmtsClean(s->ts);
    00489
    00490     Py_INCREF(Py_None);
    00491     return Py_None;
    00492 }
    00493
    00496 static PyObject *
    00497 rpmts_IDTXload(rpmtsObject * s, PyObject * args)
    00498         /*@globals _Py_NoneStruct @*/
    00499         /*@modifies s, _Py_NoneStruct @*/
    00500 {
    00501     PyObject * result = NULL;
    00502     rpmTag tag = RPMTAG_INSTALLTID;
    00503     IDTX idtx;
    00504
    00505 if (_rpmts_debug)
    00506 fprintf(stderr, "*** rpmts_IDTXload(%p) ts %p\n", s, s->ts);
    00507
    00508     if (!PyArg_ParseTuple(args, ":IDTXload")) return NULL;
    00509
    00510     Py_BEGIN_ALLOW_THREADS
    00511     idtx = IDTXload(s->ts, tag);
    00512     Py_END_ALLOW_THREADS
    00513
    00514     if (idtx == NULL || idtx->nidt <= 0) {
    00515         Py_INCREF(Py_None);
    00516         result = Py_None;
    00517     } else {
    00518         PyObject * tuple;
    00519         IDT idt;
    00520         int i;
    00521
    00522         result = PyTuple_New(idtx->nidt);
    00523         for (i = 0; i < idtx->nidt; i++) {
    00524             idt = idtx->idt + i;
    00525             tuple = Py_BuildValue("(iOi)", idt->val.u32, hdr_Wrap(idt->h), idt->instance);
    00526             PyTuple_SET_ITEM(result,  i, tuple);
    00527         }
    00528     }
    00529
    00530     idtx = IDTXfree(idtx);
    00531
    00532     return result;
    00533 }
    00534
    00537 static PyObject *
    00538 rpmts_IDTXglob(rpmtsObject * s, PyObject * args)
    00539         /*@globals _Py_NoneStruct @*/
    00540         /*@modifies s, _Py_NoneStruct @*/
    00541 {
    00542     PyObject * result = NULL;
    00543     rpmTag tag = RPMTAG_REMOVETID;
    00544     const char * globstr;
    00545     IDTX idtx;
    00546
    00547 if (_rpmts_debug)
    00548 fprintf(stderr, "*** rpmts_IDTXglob(%p) ts %p\n", s, s->ts);
    00549
    00550     if (!PyArg_ParseTuple(args, ":IDTXglob")) return NULL;
    00551
    00552     Py_BEGIN_ALLOW_THREADS
    00553     globstr = rpmExpand("%{_repackage_dir}/*.rpm", NULL);
    00554     idtx = IDTXglob(s->ts, globstr, tag);
    00555     globstr = _free(globstr);
    00556     Py_END_ALLOW_THREADS
    00557
    00558     if (idtx == NULL || idtx->nidt <= 0) {
    00559         Py_INCREF(Py_None);
    00560         result = Py_None;
    00561     } else {
    00562         PyObject * tuple;
    00563         IDT idt;
    00564         int i;
    00565
    00566         result = PyTuple_New(idtx->nidt);
    00567         for (i = 0; i < idtx->nidt; i++) {
    00568             idt = idtx->idt + i;
    00569             tuple = Py_BuildValue("(iOs)", idt->val.u32, hdr_Wrap(idt->h), idt->key);
    00570             PyTuple_SET_ITEM(result,  i, tuple);
    00571         }
    00572     }
    00573
    00574     idtx = IDTXfree(idtx);
    00575
    00576     return result;
    00577 }
    00578
    00581 static PyObject *
    00582 rpmts_Rollback(rpmtsObject * s, PyObject * args)
    00583         /*@globals _Py_NoneStruct @*/
    00584         /*@modifies s, _Py_NoneStruct @*/
    00585 {
    00586     struct rpmInstallArguments_s * ia = alloca(sizeof(*ia));
    00587     rpmtransFlags transFlags;
    00588     const char ** av = NULL;
    00589     uint_32 rbtid;
    00590     int rc;
    00591
    00592 if (_rpmts_debug)
    00593 fprintf(stderr, "*** rpmts_Rollback(%p) ts %p\n", s, s->ts);
    00594
    00595     if (!PyArg_ParseTuple(args, "i:Rollback", &rbtid)) return NULL;
    00596
    00597     Py_BEGIN_ALLOW_THREADS
    00598     memset(ia, 0, sizeof(*ia));
    00599     ia->qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE|VERIFY_HDRCHK);
    00600     ia->transFlags |= (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL);
    00601     ia->transFlags |= RPMTRANS_FLAG_NOMD5;
    00602     ia->installInterfaceFlags = (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL);
    00603     ia->rbtid = rbtid;
    00604     ia->relocations = NULL;
    00605     ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
    00606
    00607     transFlags = rpmtsSetFlags(s->ts, ia->transFlags);
    00608     rc = rpmRollback(s->ts, ia, av);
    00609     transFlags = rpmtsSetFlags(s->ts, transFlags);
    00610     Py_END_ALLOW_THREADS
    00611
    00612     return Py_BuildValue("i", rc);
    00613 }
    00614
    00617 static PyObject *
    00618 rpmts_OpenDB(rpmtsObject * s, PyObject * args)
    00619         /*@globals _Py_NoneStruct @*/
    00620         /*@modifies s, _Py_NoneStruct @*/
    00621 {
    00622
    00623 if (_rpmts_debug)
    00624 fprintf(stderr, "*** rpmts_OpenDB(%p) ts %p\n", s, s->ts);
    00625
    00626     if (!PyArg_ParseTuple(args, ":OpenDB")) return NULL;
    00627
    00628     if (s->ts->dbmode == -1)
    00629         s->ts->dbmode = O_RDONLY;
    00630
    00631     return Py_BuildValue("i", rpmtsOpenDB(s->ts, s->ts->dbmode));
    00632 }
    00633
    00636 static PyObject *
    00637 rpmts_CloseDB(rpmtsObject * s, PyObject * args)
    00638         /*@globals _Py_NoneStruct @*/
    00639         /*@modifies s, _Py_NoneStruct @*/
    00640 {
    00641     int rc;
    00642
    00643 if (_rpmts_debug)
    00644 fprintf(stderr, "*** rpmts_CloseDB(%p) ts %p\n", s, s->ts);
    00645
    00646     if (!PyArg_ParseTuple(args, ":CloseDB")) return NULL;
    00647
    00648     rc = rpmtsCloseDB(s->ts);
    00649     s->ts->dbmode = -1;         /* XXX disable lazy opens */
    00650
    00651     return Py_BuildValue("i", rc);
    00652 }
    00653
    00656 static PyObject *
    00657 rpmts_InitDB(rpmtsObject * s, PyObject * args)
    00658         /*@globals _Py_NoneStruct @*/
    00659         /*@modifies s, _Py_NoneStruct @*/
    00660 {
    00661     int rc;
    00662
    00663 if (_rpmts_debug)
    00664 fprintf(stderr, "*** rpmts_InitDB(%p) ts %p\n", s, s->ts);
    00665
    00666     if (!PyArg_ParseTuple(args, ":InitDB")) return NULL;
    00667
    00668     rc = rpmtsInitDB(s->ts, O_RDONLY);
    00669     if (rc == 0)
    00670         rc = rpmtsCloseDB(s->ts);
    00671
    00672     return Py_BuildValue("i", rc);
    00673 }
    00674
    00677 static PyObject *
    00678 rpmts_RebuildDB(rpmtsObject * s, PyObject * args)
    00679         /*@globals _Py_NoneStruct @*/
    00680         /*@modifies s, _Py_NoneStruct @*/
    00681 {
    00682     int rc;
    00683
    00684 if (_rpmts_debug)
    00685 fprintf(stderr, "*** rpmts_RebuildDB(%p) ts %p\n", s, s->ts);
    00686
    00687     if (!PyArg_ParseTuple(args, ":RebuildDB")) return NULL;
    00688
    00689     Py_BEGIN_ALLOW_THREADS
    00690     rc = rpmtsRebuildDB(s->ts);
    00691     Py_END_ALLOW_THREADS
    00692
    00693     return Py_BuildValue("i", rc);
    00694 }
    00695
    00698 static PyObject *
    00699 rpmts_VerifyDB(rpmtsObject * s, PyObject * args)
    00700         /*@globals _Py_NoneStruct @*/
    00701         /*@modifies s, _Py_NoneStruct @*/
    00702 {
    00703     int rc;
    00704
    00705 if (_rpmts_debug)
    00706 fprintf(stderr, "*** rpmts_VerifyDB(%p) ts %p\n", s, s->ts);
    00707
    00708     if (!PyArg_ParseTuple(args, ":VerifyDB")) return NULL;
    00709
    00710     Py_BEGIN_ALLOW_THREADS
    00711     rc = rpmtsVerifyDB(s->ts);
    00712     Py_END_ALLOW_THREADS
    00713
    00714     return Py_BuildValue("i", rc);
    00715 }
    00716
    00719 static PyObject *
    00720 rpmts_HdrFromFdno(rpmtsObject * s, PyObject * args)
    00721         /*@globals _Py_NoneStruct, fileSystem @*/
    00722         /*@modifies s, _Py_NoneStruct, fileSystem @*/
    00723 {
    00724     PyObject * result = NULL;
    00725     Header h;
    00726     FD_t fd;
    00727     int fdno;
    00728     rpmRC rpmrc;
    00729
    00730     if (!PyArg_ParseTuple(args, "i:HdrFromFdno", &fdno)) return NULL;
    00731
    00732     fd = fdDup(fdno);
    00733     rpmrc = rpmReadPackageFile(s->ts, fd, "rpmts_HdrFromFdno", &h);
    00734     Fclose(fd);
    00735
    00736 if (_rpmts_debug)
    00737 fprintf(stderr, "*** rpmts_HdrFromFdno(%p) ts %p rc %d\n", s, s->ts, rpmrc);
    00738
    00739     switch (rpmrc) {
    00740     case RPMRC_OK:
    00741         if (h)
    00742             result = Py_BuildValue("N", hdr_Wrap(h));
    00743         h = headerFree(h);      /* XXX ref held by result */
    00744         break;
    00745
    00746     case RPMRC_NOTFOUND:
    00747         Py_INCREF(Py_None);
    00748         result = Py_None;
    00749         break;
    00750
    00751     case RPMRC_NOKEY:
    00752         PyErr_SetString(pyrpmError, "public key not available");
    00753         break;
    00754
    00755     case RPMRC_NOTTRUSTED:
    00756         PyErr_SetString(pyrpmError, "public key not trusted");
    00757         break;
    00758
    00759     case RPMRC_FAIL:
    00760     default:
    00761         PyErr_SetString(pyrpmError, "error reading package header");
    00762         break;
    00763     }
    00764
    00765     return result;
    00766 }
    00767
    00770 static PyObject *
    00771 rpmts_HdrCheck(rpmtsObject * s, PyObject * args)
    00772         /*@globals _Py_NoneStruct @*/
    00773         /*@modifies s, _Py_NoneStruct @*/
    00774 {
    00775     PyObject * blob;
    00776     PyObject * result = NULL;
    00777     const char * msg = NULL;
    00778     const void * uh;
    00779     int uc;
    00780     rpmRC rpmrc;
    00781
    00782 if (_rpmts_debug)
    00783 fprintf(stderr, "*** rpmts_HdrCheck(%p) ts %p\n", s, s->ts);
    00784
    00785     if (!PyArg_ParseTuple(args, "O:HdrCheck", &blob)) return NULL;
    00786     if (blob == Py_None) {
    00787         Py_INCREF(Py_None);
    00788         return Py_None;
    00789     }
    00790     if (!PyString_Check(blob)) {
    00791         PyErr_SetString(pyrpmError, "hdrCheck takes a string of octets");
    00792         return result;
    00793     }
    00794     uh = PyString_AsString(blob);
    00795     uc = PyString_Size(blob);
    00796
    00797     rpmrc = headerCheck(s->ts, uh, uc, &msg);
    00798
    00799     switch (rpmrc) {
    00800     case RPMRC_OK:
    00801         Py_INCREF(Py_None);
    00802         result = Py_None;
    00803         break;
    00804
    00805     case RPMRC_NOKEY:
    00806         PyErr_SetString(pyrpmError, "public key not availaiable");
    00807         break;
    00808
    00809     case RPMRC_NOTTRUSTED:
    00810         PyErr_SetString(pyrpmError, "public key not trusted");
    00811         break;
    00812
    00813     case RPMRC_FAIL:
    00814     default:
    00815         PyErr_SetString(pyrpmError, msg);
    00816         break;
    00817     }
    00818     msg = _free(msg);
    00819
    00820     return result;
    00821 }
    00822
    00825 static PyObject *
    00826 rpmts_SetVSFlags(rpmtsObject * s, PyObject * args)
    00827         /*@globals _Py_NoneStruct @*/
    00828         /*@modifies s, _Py_NoneStruct @*/
    00829 {
    00830     rpmVSFlags vsflags;
    00831
    00832 if (_rpmts_debug)
    00833 fprintf(stderr, "*** rpmts_SetVSFlags(%p) ts %p\n", s, s->ts);
    00834
    00835     if (!PyArg_ParseTuple(args, "i:SetVSFlags", &vsflags)) return NULL;
    00836
    00837     /* XXX FIXME: value check on vsflags. */
    00838
    00839     return Py_BuildValue("i", rpmtsSetVSFlags(s->ts, vsflags));
    00840 }
    00841
    00844 static PyObject *
    00845 rpmts_PgpPrtPkts(rpmtsObject * s, PyObject * args)
    00846         /*@globals _Py_NoneStruct @*/
    00847         /*@modifies _Py_NoneStruct @*/
    00848 {
    00849     PyObject * blob;
    00850     unsigned char * pkt;
    00851     unsigned int pktlen;
    00852     int rc;
    00853
    00854 if (_rpmts_debug)
    00855 fprintf(stderr, "*** rpmts_PgpPrtPkts(%p) ts %p\n", s, s->ts);
    00856
    00857     if (!PyArg_ParseTuple(args, "O:PgpPrtPkts", &blob)) return NULL;
    00858     if (blob == Py_None) {
    00859         Py_INCREF(Py_None);
    00860         return Py_None;
    00861     }
    00862     if (!PyString_Check(blob)) {
    00863         PyErr_SetString(pyrpmError, "pgpPrtPkts takes a string of octets");
    00864         return NULL;
    00865     }
    00866     pkt = PyString_AsString(blob);
    00867     pktlen = PyString_Size(blob);
    00868
    00869     rc = pgpPrtPkts(pkt, pktlen, NULL, 1);
    00870
    00871     return Py_BuildValue("i", rc);
    00872 }
    00873
    00876 static PyObject *
    00877 rpmts_PgpImportPubkey(rpmtsObject * s, PyObject * args)
    00878         /*@globals _Py_NoneStruct @*/
    00879         /*@modifies _Py_NoneStruct @*/
    00880 {
    00881     PyObject * blob;
    00882     unsigned char * pkt;
    00883     unsigned int pktlen;
    00884     int rc;
    00885
    00886 if (_rpmts_debug)
    00887 fprintf(stderr, "*** rpmts_PgpImportPubkey(%p) ts %p\n", s, s->ts);
    00888
    00889     if (!PyArg_ParseTuple(args, "O:PgpImportPubkey", &blob)) return NULL;
    00890     if (blob == Py_None) {
    00891         Py_INCREF(Py_None);
    00892         return Py_None;
    00893     }
    00894     if (!PyString_Check(blob)) {
    00895         PyErr_SetString(pyrpmError, "PgpImportPubkey takes a string of octets");
    00896         return NULL;
    00897     }
    00898     pkt = PyString_AsString(blob);
    00899     pktlen = PyString_Size(blob);
    00900
    00901     rc = rpmcliImportPubkey(s->ts, pkt, pktlen);
    00902
    00903     return Py_BuildValue("i", rc);
    00904 }
    00905
    00908 static PyObject *
    00909 rpmts_GetKeys(rpmtsObject * s, PyObject * args)
    00910         /*@globals _Py_NoneStruct @*/
    00911         /*@modifies s, _Py_NoneStruct @*/
    00912 {
    00913     const void **data = NULL;
    00914     int num, i;
    00915     PyObject *tuple;
    00916
    00917 if (_rpmts_debug)
    00918 fprintf(stderr, "*** rpmts_GetKeys(%p) ts %p\n", s, s->ts);
    00919
    00920     if (!PyArg_ParseTuple(args, ":GetKeys")) return NULL;
    00921
    00922     rpmtsGetKeys(s->ts, &data, &num);
    00923     if (data == NULL || num <= 0) {
    00924         data = _free(data);
    00925         Py_INCREF(Py_None);
    00926         return Py_None;
    00927     }
    00928
    00929     tuple = PyTuple_New(num);
    00930
    00931     for (i = 0; i < num; i++) {
    00932         PyObject *obj;
    00933         obj = (data[i] ? (PyObject *) data[i] : Py_None);
    00934         Py_INCREF(obj);
    00935         PyTuple_SetItem(tuple, i, obj);
    00936     }
    00937
    00938     data = _free(data);
    00939
    00940     return tuple;
    00941 }
    00942
    00945 static void *
    00946 rpmtsCallback(/*@unused@*/ const void * hd, const rpmCallbackType what,
    00947                          const unsigned long amount, const unsigned long total,
    00948                          const void * pkgKey, rpmCallbackData data)
    00949         /*@*/
    00950 {
    00951     Header h = (Header) hd;
    00952     struct rpmtsCallbackType_s * cbInfo = data;
    00953     PyObject * pkgObj = (PyObject *) pkgKey;
    00954     PyObject * args, * result;
    00955     static FD_t fd;
    00956
    00957     if (cbInfo->pythonError) return NULL;
    00958     if (cbInfo->cb == Py_None) return NULL;
    00959
    00960     /* Synthesize a python object for callback (if necessary). */
    00961     if (pkgObj == NULL) {
    00962         if (h) {
    00963             const char * n = NULL;
    00964             (void) headerNVR(h, &n, NULL, NULL);
    00965             pkgObj = Py_BuildValue("s", n);
    00966         } else {
    00967             pkgObj = Py_None;
    00968             Py_INCREF(pkgObj);
    00969         }
    00970     } else
    00971         Py_INCREF(pkgObj);
    00972
    00973     PyEval_RestoreThread(cbInfo->_save);
    00974
    00975     args = Py_BuildValue("(illOO)", what, amount, total, pkgObj, cbInfo->data);
    00976     result = PyEval_CallObject(cbInfo->cb, args);
    00977     Py_DECREF(args);
    00978     Py_DECREF(pkgObj);
    00979
    00980     if (!result) {
    00981         cbInfo->pythonError = 1;
    00982         cbInfo->_save = PyEval_SaveThread();
    00983         return NULL;
    00984     }
    00985
    00986     if (what == RPMCALLBACK_INST_OPEN_FILE) {
    00987         int fdno;
    00988
    00989         if (!PyArg_Parse(result, "i", &fdno)) {
    00990             cbInfo->pythonError = 1;
    00991             cbInfo->_save = PyEval_SaveThread();
    00992             return NULL;
    00993         }
    00994         Py_DECREF(result);
    00995         cbInfo->_save = PyEval_SaveThread();
    00996
    00997         fd = fdDup(fdno);
    00998 if (_rpmts_debug)
    00999 fprintf(stderr, "\t%p = fdDup(%d)\n", fd, fdno);
    01000
    01001         return fd;
    01002     } else
    01003     if (what == RPMCALLBACK_INST_CLOSE_FILE) {
    01004 if (_rpmts_debug)
    01005 fprintf(stderr, "\tFclose(%p)\n", fd);
    01006         Fclose (fd);
    01007     } else {
    01008 if (_rpmts_debug)
    01009 fprintf(stderr, "\t%ld:%ld key %p\n", amount, total, pkgKey);
    01010     }
    01011
    01012     Py_DECREF(result);
    01013     cbInfo->_save = PyEval_SaveThread();
    01014
    01015     return NULL;
    01016 }
    01017
    01020 static PyObject * rpmts_SetFlags(rpmtsObject * s, PyObject * args)
    01021         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
    01022         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
    01023 {
    01024     rpmtransFlags transFlags = 0;
    01025
    01026     if (!PyArg_ParseTuple(args, "i:SetFlags", &transFlags))
    01027         return NULL;
    01028
    01029 if (_rpmts_debug)
    01030 fprintf(stderr, "*** rpmts_SetFlags(%p) ts %p transFlags %x\n", s, s->ts, transFlags);
    01031
    01032     return Py_BuildValue("i", rpmtsSetFlags(s->ts, transFlags));
    01033 }
    01034
    01037 static PyObject * rpmts_SetProbFilter(rpmtsObject * s, PyObject * args)
    01038         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
    01039         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
    01040 {
    01041     rpmprobFilterFlags ignoreSet = 0;
    01042     rpmprobFilterFlags oignoreSet;
    01043
    01044     if (!PyArg_ParseTuple(args, "i:ProbFilter", &ignoreSet))
    01045         return NULL;
    01046
    01047 if (_rpmts_debug)
    01048 fprintf(stderr, "*** rpmts_SetProbFilter(%p) ts %p ignoreSet %x\n", s, s->ts, ignoreSet);
    01049
    01050     oignoreSet = s->ignoreSet;
    01051     s->ignoreSet = ignoreSet;
    01052
    01053     return Py_BuildValue("i", oignoreSet);
    01054 }
    01055
    01058 static PyObject * rpmts_Run(rpmtsObject * s, PyObject * args)
    01059         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
    01060         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
    01061 {
    01062     int rc, i;
    01063     PyObject * list;
    01064     rpmps ps;
    01065     struct rpmtsCallbackType_s cbInfo;
    01066
    01067     if (!PyArg_ParseTuple(args, "OO:Run", &cbInfo.cb, &cbInfo.data))
    01068         return NULL;
    01069
    01070     cbInfo.tso = s;
    01071     cbInfo.pythonError = 0;
    01072     cbInfo._save = PyEval_SaveThread();
    01073
    01074     if (cbInfo.cb != NULL) {
    01075         if (!PyCallable_Check(cbInfo.cb)) {
    01076             PyErr_SetString(PyExc_TypeError, "expected a callable");
    01077             return NULL;
    01078         }
    01079         (void) rpmtsSetNotifyCallback(s->ts, rpmtsCallback, (void *) &cbInfo);
    01080     }
    01081
    01082
    01083 if (_rpmts_debug)
    01084 fprintf(stderr, "*** rpmts_Run(%p) ts %p ignore %x\n", s, s->ts, s->ignoreSet);
    01085
    01086     rc = rpmtsRun(s->ts, NULL, s->ignoreSet);
    01087     ps = rpmtsProblems(s->ts);
    01088
    01089     if (cbInfo.cb) {
    01090         (void) rpmtsSetNotifyCallback(s->ts, NULL, NULL);
    01091     }
    01092
    01093     PyEval_RestoreThread(cbInfo._save);
    01094
    01095     if (cbInfo.pythonError) {
    01096         ps = rpmpsFree(ps);
    01097         return NULL;
    01098     }
    01099
    01100     if (rc < 0) {
    01101         list = PyList_New(0);
    01102         return list;
    01103     } else if (!rc) {
    01104         Py_INCREF(Py_None);
    01105         return Py_None;
    01106     }
    01107
    01108     list = PyList_New(0);
    01109     for (i = 0; i < ps->numProblems; i++) {
    01110         rpmProblem p = ps->probs + i;
    01111         PyObject * prob = Py_BuildValue("s(isN)", rpmProblemString(p),
    01112                              p->type,
    01113                              p->str1,
    01114                              PyLong_FromLongLong(p->ulong1));
    01115         PyList_Append(list, prob);
    01116         Py_DECREF(prob);
    01117     }
    01118
    01119     ps = rpmpsFree(ps);
    01120
    01121     return list;
    01122 }
    01123
    01124 #if Py_TPFLAGS_HAVE_ITER
    01125 static PyObject *
    01126 rpmts_iter(rpmtsObject * s)
    01127         /*@modifies s @*/
    01128 {
    01129 if (_rpmts_debug)
    01130 fprintf(stderr, "*** rpmts_iter(%p) ts %p\n", s, s->ts);
    01131
    01132     Py_INCREF(s);
    01133     return (PyObject *)s;
    01134 }
    01135 #endif
    01136
    01140 static PyObject *
    01141 rpmts_iternext(rpmtsObject * s)
    01142         /*@globals _Py_NoneStruct @*/
    01143         /*@modifies s, _Py_NoneStruct @*/
    01144 {
    01145     PyObject * result = NULL;
    01146     rpmte te;
    01147
    01148 if (_rpmts_debug)
    01149 fprintf(stderr, "*** rpmts_iternext(%p) ts %p tsi %p %d\n", s, s->ts, s->tsi, s->tsiFilter);
    01150
    01151     /* Reset iterator on 1st entry. */
    01152     if (s->tsi == NULL) {
    01153         s->tsi = rpmtsiInit(s->ts);
    01154         if (s->tsi == NULL)
    01155             return NULL;
    01156         s->tsiFilter = 0;
    01157     }
    01158
    01159     te = rpmtsiNext(s->tsi, s->tsiFilter);
    01160     if (te != NULL) {
    01161         result = (PyObject *) rpmte_Wrap(te);
    01162     } else {
    01163         s->tsi = rpmtsiFree(s->tsi);
    01164         s->tsiFilter = 0;
    01165     }
    01166
    01167     return result;
    01168 }
    01169
    01173 static PyObject *
    01174 rpmts_Next(rpmtsObject * s)
    01175         /*@globals _Py_NoneStruct @*/
    01176         /*@modifies s, _Py_NoneStruct @*/
    01177 {
    01178     PyObject * result;
    01179
    01180 if (_rpmts_debug)
    01181 fprintf(stderr, "*** rpmts_Next(%p) ts %p\n", s, s->ts);
    01182
    01183     result = rpmts_iternext(s);
    01184
    01185     if (result == NULL) {
    01186         Py_INCREF(Py_None);
    01187         return Py_None;
    01188     }
    01189
    01190     return result;
    01191 }
    01192
    01195 static rpmmiObject *
    01196 rpmts_Match(rpmtsObject * s, PyObject * args)
    01197         /*@globals _Py_NoneStruct @*/
    01198         /*@modifies s, _Py_NoneStruct @*/
    01199 {
    01200     PyObject *TagN = NULL;
    01201     char *key = NULL;
    01202     int len = 0;
    01203     int tag = RPMDBI_PACKAGES;
    01204
    01205 if (_rpmts_debug)
    01206 fprintf(stderr, "*** rpmts_Match(%p) ts %p\n", s, s->ts);
    01207
    01208     if (!PyArg_ParseTuple(args, "|Ozi", &TagN, &key, &len))
    01209         return NULL;
    01210
    01211     if (TagN && (tag = tagNumFromPyObject (TagN)) == -1) {
    01212         PyErr_SetString(PyExc_TypeError, "unknown tag type");
    01213         return NULL;
    01214     }
    01215
    01216     /* XXX If not already opened, open the database O_RDONLY now. */
    01217     if (s->ts->rdb == NULL) {
    01218         int rc = rpmtsOpenDB(s->ts, O_RDONLY);
    01219         if (rc || s->ts->rdb == NULL) {
    01220             PyErr_SetString(PyExc_TypeError, "rpmdb open failed");
    01221             return NULL;
    01222         }
    01223     }
    01224
    01225     return rpmmi_Wrap( rpmtsInitIterator(s->ts, tag, key, len) );
    01226 }
    01227
    01230 /*@-fullinitblock@*/
    01231 /*@unchecked@*/ /*@observer@*/
    01232 static struct PyMethodDef rpmts_methods[] = {
    01233  {"Debug",      (PyCFunction)rpmts_Debug,       METH_VARARGS,
    01234         NULL},
    01235
    01236  {"addInstall", (PyCFunction) rpmts_AddInstall, METH_VARARGS,
    01237         NULL },
    01238  {"addErase",   (PyCFunction) rpmts_AddErase,   METH_VARARGS,
    01239         NULL },
    01240  {"check",      (PyCFunction) rpmts_Check,      METH_VARARGS,
    01241         NULL },
    01242  {"order",      (PyCFunction) rpmts_Order,      METH_VARARGS,
    01243         NULL },
    01244  {"setFlags",   (PyCFunction) rpmts_SetFlags,   METH_VARARGS,
    01245 "ts.setFlags(transFlags) -> previous transFlags\n\
    01246 - Set control bit(s) for executing ts.run().\n\
    01247   Note: This method replaces the 1st argument to the old ts.run()\n" },
    01248  {"setProbFilter",      (PyCFunction) rpmts_SetProbFilter,      METH_VARARGS,
    01249 "ts.setProbFilter(ignoreSet) -> previous ignoreSet\n\
    01250 - Set control bit(s) for ignoring problems found by ts.run().\n\
    01251   Note: This method replaces the 2nd argument to the old ts.run()\n" },
    01252  {"run",        (PyCFunction) rpmts_Run,        METH_VARARGS,
    01253         NULL },
    01254  {"clean",      (PyCFunction) rpmts_Clean,      METH_VARARGS,
    01255         NULL },
    01256  {"IDTXload",   (PyCFunction) rpmts_IDTXload,   METH_VARARGS,
    01257         NULL },
    01258  {"IDTXglob",   (PyCFunction) rpmts_IDTXglob,   METH_VARARGS,
    01259         NULL },
    01260  {"rollback",   (PyCFunction) rpmts_Rollback,   METH_VARARGS,
    01261         NULL },
    01262  {"openDB",     (PyCFunction) rpmts_OpenDB,     METH_VARARGS,
    01263 "ts.openDB() -> None\n\
    01264 - Open the default transaction rpmdb.\n\
    01265   Note: The transaction rpmdb is lazily opened, so ts.openDB() is seldom needed.\n" },
    01266  {"closeDB",    (PyCFunction) rpmts_CloseDB,    METH_VARARGS,
    01267 "ts.closeDB() -> None\n\
    01268 - Close the default transaction rpmdb.\n\
    01269   Note: ts.closeDB() disables lazy opens, and should hardly ever be used.\n" },
    01270  {"initDB",     (PyCFunction) rpmts_InitDB,     METH_VARARGS,
    01271 "ts.initDB() -> None\n\
    01272 - Initialize the default transaction rpmdb.\n\
    01273  Note: ts.initDB() is seldom needed anymore.\n" },
    01274  {"rebuildDB",  (PyCFunction) rpmts_RebuildDB,  METH_VARARGS,
    01275 "ts.rebuildDB() -> None\n\
    01276 - Rebuild the default transaction rpmdb.\n" },
    01277  {"verifyDB",   (PyCFunction) rpmts_VerifyDB,   METH_VARARGS,
    01278 "ts.verifyDB() -> None\n\
    01279 - Verify the default transaction rpmdb.\n" },
    01280  {"hdrFromFdno",(PyCFunction) rpmts_HdrFromFdno,METH_VARARGS,
    01281 "ts.hdrFromFdno(fdno) -> hdr\n\
    01282 - Read a package header from a file descriptor.\n" },
    01283  {"hdrCheck",   (PyCFunction) rpmts_HdrCheck,   METH_VARARGS,
    01284         NULL },
    01285  {"setVSFlags",(PyCFunction) rpmts_SetVSFlags,  METH_VARARGS,
    01286 "ts.setVSFlags(vsflags) -> ovsflags\n\
    01287 - Set signature verification flags. Values for vsflags are:\n\
    01288     rpm.RPMVSF_NOHDRCHK      if set, don't check rpmdb headers\n\
    01289     rpm.RPMVSF_NEEDPAYLOAD   if not set, check header+payload (if possible)\n\
    01290     rpm.RPMVSF_NOSHA1HEADER  if set, don't check header SHA1 digest\n\
    01291     rpm.RPMVSF_NODSAHEADER   if set, don't check header DSA signature\n\
    01292     rpm.RPMVSF_NOMD5         if set, don't check header+payload MD5 digest\n\
    01293     rpm.RPMVSF_NODSA         if set, don't check header+payload DSA signature\n\
    01294     rpm.RPMVSF_NORSA         if set, don't check header+payload RSA signature\n\
    01295     rpm._RPMVSF_NODIGESTS    if set, don't check digest(s)\n\
    01296     rpm._RPMVSF_NOSIGNATURES if set, don't check signature(s)\n" },
    01297  {"pgpPrtPkts", (PyCFunction) rpmts_PgpPrtPkts, METH_VARARGS,
    01298         NULL },
    01299  {"pgpImportPubkey",    (PyCFunction) rpmts_PgpImportPubkey,    METH_VARARGS,
    01300         NULL },
    01301  {"getKeys",    (PyCFunction) rpmts_GetKeys,    METH_VARARGS,
    01302         NULL },
    01303  {"dbMatch",    (PyCFunction) rpmts_Match,      METH_VARARGS,
    01304 "ts.dbMatch([TagN, [key, [len]]]) -> mi\n\
    01305 - Create a match iterator for the default transaction rpmdb.\n" },
    01306  {"next",               (PyCFunction)rpmts_Next,        METH_VARARGS,
    01307 "ts.next() -> te\n\
    01308 - Retrieve next transaction set element.\n" },
    01309     {NULL,              NULL}           /* sentinel */
    01310 };
    01311 /*@=fullinitblock@*/
    01312
    01315 static void rpmts_dealloc(/*@only@*/ PyObject * o)
    01316         /*@modifies o @*/
    01317 {
    01318     rpmtsObject * trans = (void *) o;
    01319
    01320 if (_rpmts_debug)
    01321 fprintf(stderr, "%p -- ts %p db %p\n", trans, trans->ts, trans->ts->rdb);
    01322     rpmtsFree(trans->ts);
    01323
    01324     if (trans->scriptFd) Fclose(trans->scriptFd);
    01325     /* this will free the keyList, and decrement the ref count of all
    01326        the items on the list as well :-) */
    01327     Py_DECREF(trans->keyList);
    01328     PyMem_DEL(o);
    01329 }
    01330
    01333 static PyObject * rpmts_getattr(rpmtsObject * o, char * name)
    01334         /*@*/
    01335 {
    01336     return Py_FindMethod(rpmts_methods, (PyObject *) o, name);
    01337 }
    01338
    01341 static int rpmts_setattr(rpmtsObject * o, char * name, PyObject * val)
    01342         /*@modifies o @*/
    01343 {
    01344     int i;
    01345
    01346     if (!strcmp(name, "scriptFd")) {
    01347         if (!PyArg_Parse(val, "i", &i)) return 0;
    01348         if (i < 0) {
    01349             PyErr_SetString(PyExc_TypeError, "bad file descriptor");
    01350             return -1;
    01351         } else {
    01352             o->scriptFd = fdDup(i);
    01353             rpmtsSetScriptFd(o->ts, o->scriptFd);
    01354         }
    01355     } else {
    01356         PyErr_SetString(PyExc_AttributeError, name);
    01357         return -1;
    01358     }
    01359
    01360     return 0;
    01361 }
    01362
    01365 /*@unchecked@*/ /*@observer@*/
    01366 static char rpmts_doc[] =
    01367 "";
    01368
    01371 /*@-fullinitblock@*/
    01372 PyTypeObject rpmts_Type = {
    01373         PyObject_HEAD_INIT(NULL)
    01374         0,                              /* ob_size */
    01375         "rpm.ts",                       /* tp_name */
    01376         sizeof(rpmtsObject),            /* tp_size */
    01377         0,                              /* tp_itemsize */
    01378         (destructor) rpmts_dealloc,     /* tp_dealloc */
    01379         0,                              /* tp_print */
    01380         (getattrfunc) rpmts_getattr,    /* tp_getattr */
    01381         (setattrfunc) rpmts_setattr,    /* tp_setattr */
    01382         0,                              /* tp_compare */
    01383         0,                              /* tp_repr */
    01384         0,                              /* tp_as_number */
    01385         0,                              /* tp_as_sequence */
    01386         0,                              /* tp_as_mapping */
    01387         0,                              /* tp_hash */
    01388         0,                              /* tp_call */
    01389         0,                              /* tp_str */
    01390         0,                              /* tp_getattro */
    01391         0,                              /* tp_setattro */
    01392         0,                              /* tp_as_buffer */
    01393         Py_TPFLAGS_DEFAULT,             /* tp_flags */
    01394         rpmts_doc,                      /* tp_doc */
    01395 #if Py_TPFLAGS_HAVE_ITER
    01396         0,                              /* tp_traverse */
    01397         0,                              /* tp_clear */
    01398         0,                              /* tp_richcompare */
    01399         0,                              /* tp_weaklistoffset */
    01400         (getiterfunc)rpmts_iter,        /* tp_iter */
    01401         (iternextfunc)rpmts_iternext,   /* tp_iternext */
    01402         rpmts_methods,                  /* tp_methods */
    01403         0,                              /* tp_members */
    01404         0,                              /* tp_getset */
    01405         0,                              /* tp_base */
    01406         0,                              /* tp_dict */
    01407         0,                              /* tp_descr_get */
    01408         0,                              /* tp_descr_set */
    01409         0,                              /* tp_dictoffset */
    01410         0,                              /* tp_init */
    01411         0,                              /* tp_alloc */
    01412         0,                              /* tp_new */
    01413         0,                              /* tp_free */
    01414         0,                              /* tp_is_gc */
    01415 #endif
    01416 };
    01417 /*@=fullinitblock@*/
    01418
    01421 rpmtsObject *
    01422 rpmts_Create(/*@unused@*/ PyObject * self, PyObject * args)
    01423 {
    01424     rpmtsObject * o;
    01425     char * rootDir = "/";
    01426     int vsflags = rpmExpandNumeric("%{?_vsflags_up2date}");
    01427
    01428     if (!PyArg_ParseTuple(args, "|si:Create", &rootDir, &vsflags))
    01429         return NULL;
    01430
    01431     o = (void *) PyObject_NEW(rpmtsObject, &rpmts_Type);
    01432
    01433     o->ts = rpmtsCreate();
    01434     (void) rpmtsSetRootDir(o->ts, rootDir);
    01435     (void) rpmtsSetVSFlags(o->ts, vsflags);
    01436
    01437     o->keyList = PyList_New(0);
    01438     o->scriptFd = NULL;
    01439     o->tsi = NULL;
    01440     o->tsiFilter = 0;
    01441
    01442 if (_rpmts_debug)
    01443 fprintf(stderr, "%p ++ ts %p db %p\n", o, o->ts, o->ts->rdb);
    01444     return o;
    01445 }