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

Generated on Tue Dec 28 15:17:15 2004 for rpm by doxygen 1.3.6