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

Generated on Fri Oct 12 08:44:54 2007 for rpm by  doxygen 1.5.2