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 = strdup(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             free(byName);
00479         }
00480 
00481         ps = rpmpsFree(ps);
00482 
00483         return list;
00484     }
00485 
00486     Py_INCREF(Py_None);
00487     return Py_None;
00488 }
00489 
00492 /*@null@*/
00493 static PyObject *
00494 rpmts_Order(rpmtsObject * s)
00495         /*@globals rpmGlobalMacroContext @*/
00496         /*@modifies s, rpmGlobalMacroContext @*/
00497 {
00498     int rc;
00499 
00500 if (_rpmts_debug)
00501 fprintf(stderr, "*** rpmts_Order(%p) ts %p\n", s, s->ts);
00502 
00503     Py_BEGIN_ALLOW_THREADS
00504     rc = rpmtsOrder(s->ts);
00505     Py_END_ALLOW_THREADS
00506 
00507     return Py_BuildValue("i", rc);
00508 }
00509 
00512 /*@null@*/
00513 static PyObject *
00514 rpmts_Clean(rpmtsObject * s)
00515         /*@globals _Py_NoneStruct @*/
00516         /*@modifies s, _Py_NoneStruct @*/
00517 {
00518 if (_rpmts_debug)
00519 fprintf(stderr, "*** rpmts_Clean(%p) ts %p\n", s, s->ts);
00520 
00521     rpmtsClean(s->ts);
00522 
00523     Py_INCREF(Py_None);
00524     return Py_None;
00525 }
00526 
00529 /*@null@*/
00530 static PyObject *
00531 rpmts_IDTXload(rpmtsObject * s)
00532         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00533         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00534 {
00535     PyObject * result = NULL;
00536     rpmTag tag = RPMTAG_INSTALLTID;
00537     IDTX idtx;
00538 
00539 if (_rpmts_debug)
00540 fprintf(stderr, "*** rpmts_IDTXload(%p) ts %p\n", s, s->ts);
00541 
00542     Py_BEGIN_ALLOW_THREADS
00543     idtx = IDTXload(s->ts, tag);
00544     Py_END_ALLOW_THREADS
00545 
00546 /*@-branchstate@*/
00547     if (idtx == NULL || idtx->nidt <= 0) {
00548         Py_INCREF(Py_None);
00549         result = Py_None;
00550     } else {
00551         PyObject * tuple;
00552         PyObject * ho;
00553         IDT idt;
00554         int i;
00555 
00556         result = PyTuple_New(idtx->nidt);
00557         for (i = 0; i < idtx->nidt; i++) {
00558             idt = idtx->idt + i;
00559             ho = (PyObject *) hdr_Wrap(idt->h);
00560             tuple = Py_BuildValue("(iOi)", idt->val.u32, ho, idt->instance);
00561             PyTuple_SET_ITEM(result,  i, tuple);
00562             Py_DECREF(ho);
00563         }
00564     }
00565 /*@=branchstate@*/
00566 
00567     idtx = IDTXfree(idtx);
00568 
00569     return result;
00570 }
00571 
00574 /*@null@*/
00575 static PyObject *
00576 rpmts_IDTXglob(rpmtsObject * s)
00577         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00578         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00579 {
00580     PyObject * result = NULL;
00581     rpmTag tag = RPMTAG_REMOVETID;
00582     const char * globstr;
00583     IDTX idtx;
00584 
00585 if (_rpmts_debug)
00586 fprintf(stderr, "*** rpmts_IDTXglob(%p) ts %p\n", s, s->ts);
00587 
00588     Py_BEGIN_ALLOW_THREADS
00589     globstr = rpmExpand("%{_repackage_dir}/*.rpm", NULL);
00590     idtx = IDTXglob(s->ts, globstr, tag);
00591     globstr = _free(globstr);
00592     Py_END_ALLOW_THREADS
00593 
00594 /*@-branchstate@*/
00595     if (idtx == NULL || idtx->nidt <= 0) {
00596         Py_INCREF(Py_None);
00597         result = Py_None;
00598     } else {
00599         PyObject * tuple;
00600         PyObject * ho;
00601         IDT idt;
00602         int i;
00603 
00604         result = PyTuple_New(idtx->nidt);
00605         for (i = 0; i < idtx->nidt; i++) {
00606             idt = idtx->idt + i;
00607             ho = (PyObject *) hdr_Wrap(idt->h);
00608             tuple = Py_BuildValue("(iOs)", idt->val.u32, ho, idt->key);
00609             PyTuple_SET_ITEM(result,  i, tuple);
00610             Py_DECREF(ho);
00611         }
00612     }
00613 /*@=branchstate@*/
00614 
00615     idtx = IDTXfree(idtx);
00616 
00617     return result;
00618 }
00619 
00622 /*@null@*/
00623 static PyObject *
00624 rpmts_Rollback(rpmtsObject * s, PyObject * args, PyObject * kwds)
00625         /*@globals rpmGlobalMacroContext @*/
00626         /*@modifies s, rpmGlobalMacroContext @*/
00627 {
00628     struct rpmInstallArguments_s * ia = alloca(sizeof(*ia));
00629     rpmtransFlags transFlags;
00630     const char ** av = NULL;
00631     uint_32 rbtid;
00632     int rc;
00633     char * kwlist[] = {"transactionId", NULL};
00634 
00635 if (_rpmts_debug)
00636 fprintf(stderr, "*** rpmts_Rollback(%p) ts %p\n", s, s->ts);
00637 
00638     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Rollback", kwlist, &rbtid))
00639         return NULL;
00640 
00641     Py_BEGIN_ALLOW_THREADS
00642     memset(ia, 0, sizeof(*ia));
00643     ia->qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE|VERIFY_HDRCHK);
00644     ia->transFlags |= (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL);
00645     ia->transFlags |= RPMTRANS_FLAG_NOMD5;
00646     ia->installInterfaceFlags = (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL);
00647     ia->rbtid = rbtid;
00648     ia->relocations = NULL;
00649     ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
00650 
00651     transFlags = rpmtsSetFlags(s->ts, ia->transFlags);
00652     rc = rpmRollback(s->ts, ia, av);
00653     transFlags = rpmtsSetFlags(s->ts, transFlags);
00654     Py_END_ALLOW_THREADS
00655 
00656     return Py_BuildValue("i", rc);
00657 }
00658 
00661 /*@null@*/
00662 static PyObject *
00663 rpmts_OpenDB(rpmtsObject * s)
00664         /*@globals rpmGlobalMacroContext @*/
00665         /*@modifies s, rpmGlobalMacroContext @*/
00666 {
00667 
00668 if (_rpmts_debug)
00669 fprintf(stderr, "*** rpmts_OpenDB(%p) ts %p\n", s, s->ts);
00670 
00671     if (s->ts->dbmode == -1)
00672         s->ts->dbmode = O_RDONLY;
00673 
00674     return Py_BuildValue("i", rpmtsOpenDB(s->ts, s->ts->dbmode));
00675 }
00676 
00679 /*@null@*/
00680 static PyObject *
00681 rpmts_CloseDB(rpmtsObject * s)
00682         /*@modifies s @*/
00683 {
00684     int rc;
00685 
00686 if (_rpmts_debug)
00687 fprintf(stderr, "*** rpmts_CloseDB(%p) ts %p\n", s, s->ts);
00688 
00689     rc = rpmtsCloseDB(s->ts);
00690     s->ts->dbmode = -1;         /* XXX disable lazy opens */
00691 
00692     return Py_BuildValue("i", rc);
00693 }
00694 
00697 /*@null@*/
00698 static PyObject *
00699 rpmts_InitDB(rpmtsObject * s)
00700         /*@globals rpmGlobalMacroContext @*/
00701         /*@modifies s, rpmGlobalMacroContext @*/
00702 {
00703     int rc;
00704 
00705 if (_rpmts_debug)
00706 fprintf(stderr, "*** rpmts_InitDB(%p) ts %p\n", s, s->ts);
00707 
00708     rc = rpmtsInitDB(s->ts, O_RDONLY);
00709     if (rc == 0)
00710         rc = rpmtsCloseDB(s->ts);
00711 
00712     return Py_BuildValue("i", rc);
00713 }
00714 
00717 /*@null@*/
00718 static PyObject *
00719 rpmts_RebuildDB(rpmtsObject * s)
00720         /*@globals rpmGlobalMacroContext @*/
00721         /*@modifies s, rpmGlobalMacroContext @*/
00722 {
00723     int rc;
00724 
00725 if (_rpmts_debug)
00726 fprintf(stderr, "*** rpmts_RebuildDB(%p) ts %p\n", s, s->ts);
00727 
00728     Py_BEGIN_ALLOW_THREADS
00729     rc = rpmtsRebuildDB(s->ts);
00730     Py_END_ALLOW_THREADS
00731 
00732     return Py_BuildValue("i", rc);
00733 }
00734 
00737 /*@null@*/
00738 static PyObject *
00739 rpmts_VerifyDB(rpmtsObject * s)
00740         /*@globals rpmGlobalMacroContext @*/
00741         /*@modifies s, rpmGlobalMacroContext @*/
00742 {
00743     int rc;
00744 
00745 if (_rpmts_debug)
00746 fprintf(stderr, "*** rpmts_VerifyDB(%p) ts %p\n", s, s->ts);
00747 
00748     Py_BEGIN_ALLOW_THREADS
00749     rc = rpmtsVerifyDB(s->ts);
00750     Py_END_ALLOW_THREADS
00751 
00752     return Py_BuildValue("i", rc);
00753 }
00754 
00757 /*@null@*/
00758 static PyObject *
00759 rpmts_HdrFromFdno(rpmtsObject * s, PyObject * args, PyObject * kwds)
00760         /*@globals rpmGlobalMacroContext, fileSystem @*/
00761         /*@modifies s, rpmGlobalMacroContext, fileSystem @*/
00762 {
00763     PyObject * result = NULL;
00764     Header h;
00765     FD_t fd;
00766     int fdno;
00767     rpmRC rpmrc;
00768     char * kwlist[] = {"fd", NULL};
00769 
00770     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:HdrFromFdno", kwlist,
00771             &fdno))
00772         return NULL;
00773 
00774     fd = fdDup(fdno);
00775     rpmrc = rpmReadPackageFile(s->ts, fd, "rpmts_HdrFromFdno", &h);
00776     Fclose(fd);
00777 
00778 if (_rpmts_debug)
00779 fprintf(stderr, "*** rpmts_HdrFromFdno(%p) ts %p rc %d\n", s, s->ts, rpmrc);
00780 
00781 /*@-branchstate@*/
00782     switch (rpmrc) {
00783     case RPMRC_OK:
00784         if (h)
00785             result = Py_BuildValue("N", hdr_Wrap(h));
00786         h = headerFree(h);      /* XXX ref held by result */
00787         break;
00788 
00789     case RPMRC_NOKEY:
00790         PyErr_SetString(pyrpmError, "public key not available");
00791         break;
00792 
00793     case RPMRC_NOTTRUSTED:
00794         PyErr_SetString(pyrpmError, "public key not trusted");
00795         break;
00796 
00797     case RPMRC_NOTFOUND:
00798     case RPMRC_FAIL:
00799     default:
00800         PyErr_SetString(pyrpmError, "error reading package header");
00801         break;
00802     }
00803 /*@=branchstate@*/
00804 
00805     return result;
00806 }
00807 
00810 /*@null@*/
00811 static PyObject *
00812 rpmts_HdrCheck(rpmtsObject * s, PyObject * args, PyObject * kwds)
00813         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00814         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00815 {
00816     PyObject * blob;
00817     PyObject * result = NULL;
00818     const char * msg = NULL;
00819     const void * uh;
00820     int uc;
00821     rpmRC rpmrc;
00822     char * kwlist[] = {"headers", NULL};
00823 
00824 if (_rpmts_debug)
00825 fprintf(stderr, "*** rpmts_HdrCheck(%p) ts %p\n", s, s->ts);
00826 
00827     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:HdrCheck", kwlist, &blob))
00828         return NULL;
00829 
00830     if (blob == Py_None) {
00831         Py_INCREF(Py_None);
00832         return Py_None;
00833     }
00834     if (!PyString_Check(blob)) {
00835         PyErr_SetString(pyrpmError, "hdrCheck takes a string of octets");
00836         return result;
00837     }
00838     uh = PyString_AsString(blob);
00839     uc = PyString_Size(blob);
00840 
00841     rpmrc = headerCheck(s->ts, uh, uc, &msg);
00842 
00843     switch (rpmrc) {
00844     case RPMRC_OK:
00845         Py_INCREF(Py_None);
00846         result = Py_None;
00847         break;
00848 
00849     case RPMRC_NOKEY:
00850         PyErr_SetString(pyrpmError, "public key not availaiable");
00851         break;
00852 
00853     case RPMRC_NOTTRUSTED:
00854         PyErr_SetString(pyrpmError, "public key not trusted");
00855         break;
00856 
00857     case RPMRC_FAIL:
00858     default:
00859         PyErr_SetString(pyrpmError, msg);
00860         break;
00861     }
00862     msg = _free(msg);
00863 
00864     return result;
00865 }
00866 
00869 /*@null@*/
00870 static PyObject *
00871 rpmts_SetVSFlags(rpmtsObject * s, PyObject * args, PyObject * kwds)
00872         /*@modifies s @*/
00873 {
00874     rpmVSFlags vsflags;
00875     char * kwlist[] = {"flags", NULL};
00876 
00877 if (_rpmts_debug)
00878 fprintf(stderr, "*** rpmts_SetVSFlags(%p) ts %p\n", s, s->ts);
00879 
00880     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetVSFlags", kwlist,
00881             &vsflags))
00882         return NULL;
00883 
00884     /* XXX FIXME: value check on vsflags, or build pure python object 
00885      * for it, and require an object of that type */
00886 
00887     return Py_BuildValue("i", rpmtsSetVSFlags(s->ts, vsflags));
00888 }
00889 
00892 /*@null@*/
00893 static PyObject *
00894 rpmts_GetVSFlags(rpmtsObject * s)
00895 {
00896     return Py_BuildValue("i", rpmtsVSFlags(s->ts));
00897 }
00898 
00901 static PyObject *
00902 rpmts_SetColor(rpmtsObject * s, PyObject * args, PyObject * kwds)
00903         /*@modifies s @*/
00904 {
00905     uint_32 tscolor;
00906     char * kwlist[] = {"color", NULL};
00907 
00908 if (_rpmts_debug)
00909 fprintf(stderr, "*** rpmts_SetColor(%p) ts %p\n", s, s->ts);
00910 
00911     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Color", kwlist, &tscolor))
00912         return NULL;
00913 
00914     /* XXX FIXME: value check on tscolor, or build pure python object
00915      * for it, and require an object of that type */
00916 
00917     return Py_BuildValue("i", rpmtsSetColor(s->ts, tscolor));
00918 }
00919 
00922 /*@null@*/
00923 static PyObject *
00924 rpmts_PgpPrtPkts(rpmtsObject * s, PyObject * args, PyObject * kwds)
00925         /*@globals _Py_NoneStruct @*/
00926         /*@modifies _Py_NoneStruct @*/
00927 {
00928     PyObject * blob;
00929     unsigned char * pkt;
00930     unsigned int pktlen;
00931     int rc;
00932     char * kwlist[] = {"octets", NULL};
00933 
00934 if (_rpmts_debug)
00935 fprintf(stderr, "*** rpmts_PgpPrtPkts(%p) ts %p\n", s, s->ts);
00936 
00937     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:PgpPrtPkts", kwlist, &blob))
00938         return NULL;
00939 
00940     if (blob == Py_None) {
00941         Py_INCREF(Py_None);
00942         return Py_None;
00943     }
00944     if (!PyString_Check(blob)) {
00945         PyErr_SetString(pyrpmError, "pgpPrtPkts takes a string of octets");
00946         return NULL;
00947     }
00948     pkt = PyString_AsString(blob);
00949     pktlen = PyString_Size(blob);
00950 
00951     rc = pgpPrtPkts(pkt, pktlen, NULL, 1);
00952 
00953     return Py_BuildValue("i", rc);
00954 }
00955 
00958 /*@null@*/
00959 static PyObject *
00960 rpmts_PgpImportPubkey(rpmtsObject * s, PyObject * args, PyObject * kwds)
00961         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00962         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00963 {
00964     PyObject * blob;
00965     unsigned char * pkt;
00966     unsigned int pktlen;
00967     int rc;
00968     char * kwlist[] = {"pubkey", NULL};
00969 
00970 if (_rpmts_debug)
00971 fprintf(stderr, "*** rpmts_PgpImportPubkey(%p) ts %p\n", s, s->ts);
00972 
00973     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:PgpImportPubkey",
00974             kwlist, &blob))
00975         return NULL;
00976 
00977     if (blob == Py_None) {
00978         Py_INCREF(Py_None);
00979         return Py_None;
00980     }
00981     if (!PyString_Check(blob)) {
00982         PyErr_SetString(pyrpmError, "PgpImportPubkey takes a string of octets");
00983         return NULL;
00984     }
00985     pkt = PyString_AsString(blob);
00986     pktlen = PyString_Size(blob);
00987 
00988     rc = rpmcliImportPubkey(s->ts, pkt, pktlen);
00989 
00990     return Py_BuildValue("i", rc);
00991 }
00992 
00995 /*@null@*/
00996 static PyObject *
00997 rpmts_GetKeys(rpmtsObject * s)
00998         /*@globals _Py_NoneStruct @*/
00999         /*@modifies s, _Py_NoneStruct @*/
01000 {
01001     const void **data = NULL;
01002     int num, i;
01003     PyObject *tuple;
01004 
01005 if (_rpmts_debug)
01006 fprintf(stderr, "*** rpmts_GetKeys(%p) ts %p\n", s, s->ts);
01007 
01008     rpmtsGetKeys(s->ts, &data, &num);
01009     if (data == NULL || num <= 0) {
01010         data = _free(data);
01011         Py_INCREF(Py_None);
01012         return Py_None;
01013     }
01014 
01015     tuple = PyTuple_New(num);
01016 
01017     for (i = 0; i < num; i++) {
01018         PyObject *obj;
01019         obj = (data[i] ? (PyObject *) data[i] : Py_None);
01020         Py_INCREF(obj);
01021         PyTuple_SetItem(tuple, i, obj);
01022     }
01023 
01024     data = _free(data);
01025 
01026     return tuple;
01027 }
01028 
01031 /*@null@*/
01032 static void *
01033 rpmtsCallback(/*@unused@*/ const void * hd, const rpmCallbackType what,
01034                          const unsigned long amount, const unsigned long total,
01035                          const void * pkgKey, rpmCallbackData data)
01036         /*@globals _Py_NoneStruct @*/
01037         /*@modifies _Py_NoneStruct @*/
01038 {
01039 /*@-castexpose@*/
01040     Header h = (Header) hd;
01041 /*@=castexpose@*/
01042     struct rpmtsCallbackType_s * cbInfo = data;
01043     PyObject * pkgObj = (PyObject *) pkgKey;
01044     PyObject * args, * result;
01045     static FD_t fd;
01046 
01047     if (cbInfo->pythonError) return NULL;
01048     if (cbInfo->cb == Py_None) return NULL;
01049 
01050     /* Synthesize a python object for callback (if necessary). */
01051     if (pkgObj == NULL) {
01052         if (h) {
01053             const char * n = NULL;
01054             (void) headerNVR(h, &n, NULL, NULL);
01055             pkgObj = Py_BuildValue("s", n);
01056         } else {
01057             pkgObj = Py_None;
01058             Py_INCREF(pkgObj);
01059         }
01060     } else
01061         Py_INCREF(pkgObj);
01062 
01063     PyEval_RestoreThread(cbInfo->_save);
01064 
01065     args = Py_BuildValue("(illOO)", what, amount, total, pkgObj, cbInfo->data);
01066     result = PyEval_CallObject(cbInfo->cb, args);
01067     Py_DECREF(args);
01068     Py_DECREF(pkgObj);
01069 
01070     if (!result) {
01071         cbInfo->pythonError = 1;
01072         cbInfo->_save = PyEval_SaveThread();
01073         return NULL;
01074     }
01075 
01076     if (what == RPMCALLBACK_INST_OPEN_FILE) {
01077         int fdno;
01078 
01079         if (!PyArg_Parse(result, "i", &fdno)) {
01080             cbInfo->pythonError = 1;
01081             cbInfo->_save = PyEval_SaveThread();
01082             return NULL;
01083         }
01084         Py_DECREF(result);
01085         cbInfo->_save = PyEval_SaveThread();
01086 
01087         fd = fdDup(fdno);
01088 if (_rpmts_debug)
01089 fprintf(stderr, "\t%p = fdDup(%d)\n", fd, fdno);
01090 
01091         fcntl(Fileno(fd), F_SETFD, FD_CLOEXEC);
01092 
01093         return fd;
01094     } else
01095     if (what == RPMCALLBACK_INST_CLOSE_FILE) {
01096 if (_rpmts_debug)
01097 fprintf(stderr, "\tFclose(%p)\n", fd);
01098         Fclose (fd);
01099     } else {
01100 if (_rpmts_debug)
01101 fprintf(stderr, "\t%ld:%ld key %p\n", amount, total, pkgKey);
01102     }
01103 
01104     Py_DECREF(result);
01105     cbInfo->_save = PyEval_SaveThread();
01106 
01107     return NULL;
01108 }
01109 
01112 static PyObject *
01113 rpmts_SetFlags(rpmtsObject * s, PyObject * args, PyObject * kwds)
01114         /*@modifies s @*/
01115 {
01116     rpmtransFlags transFlags = 0;
01117     char * kwlist[] = {"flags", NULL};
01118 
01119     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetFlags", kwlist,
01120             &transFlags))
01121         return NULL;
01122 
01123 if (_rpmts_debug)
01124 fprintf(stderr, "*** rpmts_SetFlags(%p) ts %p transFlags %x\n", s, s->ts, transFlags);
01125 
01126     /* XXX FIXME: value check on flags, or build pure python object 
01127      * for it, and require an object of that type */
01128 
01129     return Py_BuildValue("i", rpmtsSetFlags(s->ts, transFlags));
01130 }
01131 
01134 static PyObject *
01135 rpmts_SetProbFilter(rpmtsObject * s, PyObject * args, PyObject * kwds)
01136         /*@modifies s @*/
01137 {
01138     rpmprobFilterFlags ignoreSet = 0;
01139     rpmprobFilterFlags oignoreSet;
01140     char * kwlist[] = {"ignoreSet", NULL};
01141 
01142     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:ProbFilter", kwlist,
01143             &ignoreSet))
01144         return NULL;
01145 
01146 if (_rpmts_debug)
01147 fprintf(stderr, "*** rpmts_SetProbFilter(%p) ts %p ignoreSet %x\n", s, s->ts, ignoreSet);
01148 
01149     oignoreSet = s->ignoreSet;
01150     s->ignoreSet = ignoreSet;
01151 
01152     return Py_BuildValue("i", oignoreSet);
01153 }
01154 
01157 /*@null@*/
01158 static rpmpsObject *
01159 rpmts_Problems(rpmtsObject * s)
01160         /*@modifies s @*/
01161 {
01162 
01163 if (_rpmts_debug)
01164 fprintf(stderr, "*** rpmts_Problems(%p) ts %p\n", s, s->ts);
01165 
01166     return rpmps_Wrap( rpmtsProblems(s->ts) );
01167 }
01168 
01171 static PyObject *
01172 rpmts_Run(rpmtsObject * s, PyObject * args, PyObject * kwds)
01173         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
01174         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
01175 {
01176     int rc, i;
01177     PyObject * list;
01178     rpmps ps;
01179     struct rpmtsCallbackType_s cbInfo;
01180     char * kwlist[] = {"callback", "data", NULL};
01181 
01182     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO:Run", kwlist,
01183             &cbInfo.cb, &cbInfo.data))
01184         return NULL;
01185 
01186     cbInfo.tso = s;
01187     cbInfo.pythonError = 0;
01188     cbInfo._save = PyEval_SaveThread();
01189 
01190     if (cbInfo.cb != NULL) {
01191         if (!PyCallable_Check(cbInfo.cb)) {
01192             PyErr_SetString(PyExc_TypeError, "expected a callable");
01193             return NULL;
01194         }
01195         (void) rpmtsSetNotifyCallback(s->ts, rpmtsCallback, (void *) &cbInfo);
01196     }
01197 
01198     /* Initialize security context patterns (if not already done). */
01199     if (!(s->ts->transFlags & RPMTRANS_FLAG_NOCONTEXTS)) {
01200         rpmsx sx = rpmtsREContext(s->ts);
01201         if (sx == NULL) {
01202             const char *fn = rpmGetPath("%{?_install_file_context_path}", NULL);
01203             if (fn != NULL && *fn != '\0') {
01204                 sx = rpmsxNew(fn);
01205                 (void) rpmtsSetREContext(s->ts, sx);
01206             }
01207             fn = _free(fn);
01208         }
01209         sx = rpmsxFree(sx);
01210     } 
01211 
01212 if (_rpmts_debug)
01213 fprintf(stderr, "*** rpmts_Run(%p) ts %p ignore %x\n", s, s->ts, s->ignoreSet);
01214 
01215     rc = rpmtsRun(s->ts, NULL, s->ignoreSet);
01216     ps = rpmtsProblems(s->ts);
01217 
01218     if (cbInfo.cb)
01219         (void) rpmtsSetNotifyCallback(s->ts, NULL, NULL);
01220 
01221     PyEval_RestoreThread(cbInfo._save);
01222 
01223     if (cbInfo.pythonError) {
01224         ps = rpmpsFree(ps);
01225         return NULL;
01226     }
01227 
01228     if (rc < 0) {
01229         list = PyList_New(0);
01230         return list;
01231     } else if (!rc) {
01232         Py_INCREF(Py_None);
01233         return Py_None;
01234     }
01235 
01236     list = PyList_New(0);
01237     for (i = 0; i < ps->numProblems; i++) {
01238         rpmProblem p = ps->probs + i;
01239         PyObject * prob = Py_BuildValue("s(isN)", rpmProblemString(p),
01240                              p->type,
01241                              p->str1,
01242                              PyLong_FromLongLong(p->ulong1));
01243         PyList_Append(list, prob);
01244         Py_DECREF(prob);
01245     }
01246 
01247     ps = rpmpsFree(ps);
01248 
01249     return list;
01250 }
01251 
01252 #if Py_TPFLAGS_HAVE_ITER
01253 static PyObject *
01254 rpmts_iter(rpmtsObject * s)
01255         /*@*/
01256 {
01257 if (_rpmts_debug)
01258 fprintf(stderr, "*** rpmts_iter(%p) ts %p\n", s, s->ts);
01259 
01260     Py_INCREF(s);
01261     return (PyObject *)s;
01262 }
01263 #endif
01264 
01268 /*@null@*/
01269 static PyObject *
01270 rpmts_iternext(rpmtsObject * s)
01271         /*@modifies s @*/
01272 {
01273     PyObject * result = NULL;
01274     rpmte te;
01275 
01276 if (_rpmts_debug)
01277 fprintf(stderr, "*** rpmts_iternext(%p) ts %p tsi %p %d\n", s, s->ts, s->tsi, s->tsiFilter);
01278 
01279     /* Reset iterator on 1st entry. */
01280     if (s->tsi == NULL) {
01281         s->tsi = rpmtsiInit(s->ts);
01282         if (s->tsi == NULL)
01283             return NULL;
01284         s->tsiFilter = 0;
01285     }
01286 
01287     te = rpmtsiNext(s->tsi, s->tsiFilter);
01288 /*@-branchstate@*/
01289     if (te != NULL) {
01290         result = (PyObject *) rpmte_Wrap(te);
01291     } else {
01292         s->tsi = rpmtsiFree(s->tsi);
01293         s->tsiFilter = 0;
01294     }
01295 /*@=branchstate@*/
01296 
01297     return result;
01298 }
01299 
01303 static PyObject *
01304 rpmts_Next(rpmtsObject * s)
01305         /*@globals _Py_NoneStruct @*/
01306         /*@modifies s, _Py_NoneStruct @*/
01307 {
01308     PyObject * result;
01309 
01310 if (_rpmts_debug)
01311 fprintf(stderr, "*** rpmts_Next(%p) ts %p\n", s, s->ts);
01312 
01313     result = rpmts_iternext(s);
01314 
01315     if (result == NULL) {
01316         Py_INCREF(Py_None);
01317         return Py_None;
01318     }
01319 
01320     return result;
01321 }
01322 
01325 /*@null@*/
01326 static specObject *
01327 spec_Parse(rpmtsObject * s, PyObject * args, PyObject * kwds)
01328         /*@globals rpmGlobalMacroContext @*/
01329         /*@modifies s, rpmGlobalMacroContext @*/
01330 {
01331     const char * specfile;
01332     Spec spec;
01333     char * buildRoot = NULL;
01334     int recursing = 0;
01335     char * passPhrase = "";
01336     char *cookie = NULL;
01337     int anyarch = 1;
01338     int force = 1;
01339     char * kwlist[] = {"specfile", NULL};
01340 
01341     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:Parse", kwlist, &specfile))
01342         return NULL;
01343 
01344     if (parseSpec(s->ts, specfile,"/", buildRoot,recursing, passPhrase,
01345              cookie, anyarch, force)!=0) {
01346              PyErr_SetString(pyrpmError, "can't parse specfile\n");
01347                      return NULL;
01348    }
01349 
01350     spec = rpmtsSpec(s->ts);
01351     return spec_Wrap(spec);
01352 }
01353 
01356 /*@null@*/
01357 static rpmmiObject *
01358 rpmts_Match(rpmtsObject * s, PyObject * args, PyObject * kwds)
01359         /*@globals rpmGlobalMacroContext @*/
01360         /*@modifies s, rpmGlobalMacroContext @*/
01361 {
01362     PyObject *TagN = NULL;
01363     PyObject *Key = NULL;
01364     char *key = NULL;
01365 /* XXX lkey *must* be a 32 bit integer, int "works" on all known platforms. */
01366     int lkey = 0;
01367     int len = 0;
01368     int tag = RPMDBI_PACKAGES;
01369     char * kwlist[] = {"tagNumber", "key", NULL};
01370 
01371 if (_rpmts_debug)
01372 fprintf(stderr, "*** rpmts_Match(%p) ts %p\n", s, s->ts);
01373 
01374     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:Match", kwlist,
01375             &TagN, &Key))
01376         return NULL;
01377 
01378     if (TagN && (tag = tagNumFromPyObject (TagN)) == -1) {
01379         PyErr_SetString(PyExc_TypeError, "unknown tag type");
01380         return NULL;
01381     }
01382 
01383     if (Key) {
01384 /*@-branchstate@*/
01385         if (PyString_Check(Key) || PyUnicode_Check(Key)) {
01386             key = PyString_AsString(Key);
01387             len = PyString_Size(Key);
01388         } else if (PyInt_Check(Key)) {
01389             lkey = PyInt_AsLong(Key);
01390             key = (char *)&lkey;
01391             len = sizeof(lkey);
01392         } else {
01393             PyErr_SetString(PyExc_TypeError, "unknown key type");
01394             return NULL;
01395         }
01396 /*@=branchstate@*/
01397     }
01398 
01399     /* XXX If not already opened, open the database O_RDONLY now. */
01400     /* XXX FIXME: lazy default rdonly open also done by rpmtsInitIterator(). */
01401     if (s->ts->rdb == NULL) {
01402         int rc = rpmtsOpenDB(s->ts, O_RDONLY);
01403         if (rc || s->ts->rdb == NULL) {
01404             PyErr_SetString(PyExc_TypeError, "rpmdb open failed");
01405             return NULL;
01406         }
01407     }
01408 
01409     return rpmmi_Wrap( rpmtsInitIterator(s->ts, tag, key, len), (PyObject*)s);
01410 }
01411 
01414 /*@-fullinitblock@*/
01415 /*@unchecked@*/ /*@observer@*/
01416 static struct PyMethodDef rpmts_methods[] = {
01417  {"Debug",      (PyCFunction)rpmts_Debug,       METH_VARARGS|METH_KEYWORDS,
01418         NULL},
01419 
01420  {"addInstall", (PyCFunction) rpmts_AddInstall, METH_VARARGS|METH_KEYWORDS,
01421         NULL },
01422  {"addErase",   (PyCFunction) rpmts_AddErase,   METH_VARARGS|METH_KEYWORDS,
01423         NULL },
01424  {"check",      (PyCFunction) rpmts_Check,      METH_VARARGS|METH_KEYWORDS,
01425         NULL },
01426  {"order",      (PyCFunction) rpmts_Order,      METH_NOARGS,
01427         NULL },
01428  {"setFlags",   (PyCFunction) rpmts_SetFlags,   METH_VARARGS|METH_KEYWORDS,
01429 "ts.setFlags(transFlags) -> previous transFlags\n\
01430 - Set control bit(s) for executing ts.run().\n\
01431   Note: This method replaces the 1st argument to the old ts.run()\n" },
01432  {"setProbFilter",      (PyCFunction) rpmts_SetProbFilter,      METH_VARARGS|METH_KEYWORDS,
01433 "ts.setProbFilter(ignoreSet) -> previous ignoreSet\n\
01434 - Set control bit(s) for ignoring problems found by ts.run().\n\
01435   Note: This method replaces the 2nd argument to the old ts.run()\n" },
01436  {"problems",   (PyCFunction) rpmts_Problems,   METH_NOARGS,
01437 "ts.problems() -> ps\n\
01438 - Return current problem set.\n" },
01439  {"run",        (PyCFunction) rpmts_Run,        METH_VARARGS|METH_KEYWORDS,
01440 "ts.run(callback, data) -> (problems)\n\
01441 - Run a transaction set, returning list of problems found.\n\
01442   Note: The callback may not be None.\n" },
01443  {"clean",      (PyCFunction) rpmts_Clean,      METH_NOARGS,
01444         NULL },
01445  {"IDTXload",   (PyCFunction) rpmts_IDTXload,   METH_NOARGS,
01446 "ts.IDTXload() -> ((tid,hdr,instance)+)\n\
01447 - Return list of installed packages reverse sorted by transaction id.\n" },
01448  {"IDTXglob",   (PyCFunction) rpmts_IDTXglob,   METH_NOARGS,
01449 "ts.IDTXglob() -> ((tid,hdr,instance)+)\n\
01450 - Return list of removed packages reverse sorted by transaction id.\n" },
01451  {"rollback",   (PyCFunction) rpmts_Rollback,   METH_VARARGS|METH_KEYWORDS,
01452         NULL },
01453  {"openDB",     (PyCFunction) rpmts_OpenDB,     METH_NOARGS,
01454 "ts.openDB() -> None\n\
01455 - Open the default transaction rpmdb.\n\
01456   Note: The transaction rpmdb is lazily opened, so ts.openDB() is seldom needed.\n" },
01457  {"closeDB",    (PyCFunction) rpmts_CloseDB,    METH_NOARGS,
01458 "ts.closeDB() -> None\n\
01459 - Close the default transaction rpmdb.\n\
01460   Note: ts.closeDB() disables lazy opens, and should hardly ever be used.\n" },
01461  {"initDB",     (PyCFunction) rpmts_InitDB,     METH_NOARGS,
01462 "ts.initDB() -> None\n\
01463 - Initialize the default transaction rpmdb.\n\
01464  Note: ts.initDB() is seldom needed anymore.\n" },
01465  {"rebuildDB",  (PyCFunction) rpmts_RebuildDB,  METH_NOARGS,
01466 "ts.rebuildDB() -> None\n\
01467 - Rebuild the default transaction rpmdb.\n" },
01468  {"verifyDB",   (PyCFunction) rpmts_VerifyDB,   METH_NOARGS,
01469 "ts.verifyDB() -> None\n\
01470 - Verify the default transaction rpmdb.\n" },
01471  {"hdrFromFdno",(PyCFunction) rpmts_HdrFromFdno,METH_VARARGS|METH_KEYWORDS,
01472 "ts.hdrFromFdno(fdno) -> hdr\n\
01473 - Read a package header from a file descriptor.\n" },
01474  {"hdrCheck",   (PyCFunction) rpmts_HdrCheck,   METH_VARARGS|METH_KEYWORDS,
01475         NULL },
01476  {"setVSFlags",(PyCFunction) rpmts_SetVSFlags,  METH_VARARGS|METH_KEYWORDS,
01477 "ts.setVSFlags(vsflags) -> ovsflags\n\
01478 - Set signature verification flags. Values for vsflags are:\n\
01479     rpm.RPMVSF_NOHDRCHK      if set, don't check rpmdb headers\n\
01480     rpm.RPMVSF_NEEDPAYLOAD   if not set, check header+payload (if possible)\n\
01481     rpm.RPMVSF_NOSHA1HEADER  if set, don't check header SHA1 digest\n\
01482     rpm.RPMVSF_NODSAHEADER   if set, don't check header DSA signature\n\
01483     rpm.RPMVSF_NOMD5         if set, don't check header+payload MD5 digest\n\
01484     rpm.RPMVSF_NODSA         if set, don't check header+payload DSA signature\n\
01485     rpm.RPMVSF_NORSA         if set, don't check header+payload RSA signature\n\
01486     rpm._RPMVSF_NODIGESTS    if set, don't check digest(s)\n\
01487     rpm._RPMVSF_NOSIGNATURES if set, don't check signature(s)\n" },
01488  {"getVSFlags",(PyCFunction) rpmts_GetVSFlags,  METH_NOARGS,
01489 "ts.getVSFlags() -> vsflags\n\
01490 - Retrieve current signature verification flags from transaction\n" },
01491  {"setColor",(PyCFunction) rpmts_SetColor,      METH_VARARGS|METH_KEYWORDS,
01492         NULL },
01493  {"pgpPrtPkts", (PyCFunction) rpmts_PgpPrtPkts, METH_VARARGS|METH_KEYWORDS,
01494         NULL },
01495  {"pgpImportPubkey",    (PyCFunction) rpmts_PgpImportPubkey,    METH_VARARGS|METH_KEYWORDS,
01496         NULL },
01497  {"getKeys",    (PyCFunction) rpmts_GetKeys,    METH_NOARGS,
01498         NULL },
01499  {"parseSpec",  (PyCFunction) spec_Parse,       METH_VARARGS|METH_KEYWORDS,
01500 "ts.parseSpec(\"/path/to/foo.spec\") -> spec\n\
01501 - Parse a spec file.\n" },
01502  {"dbMatch",    (PyCFunction) rpmts_Match,      METH_VARARGS|METH_KEYWORDS,
01503 "ts.dbMatch([TagN, [key, [len]]]) -> mi\n\
01504 - Create a match iterator for the default transaction rpmdb.\n" },
01505  {"next",               (PyCFunction)rpmts_Next,        METH_NOARGS,
01506 "ts.next() -> te\n\
01507 - Retrieve next transaction set element.\n" },
01508     {NULL,              NULL}           /* sentinel */
01509 };
01510 /*@=fullinitblock@*/
01511 
01514 static void rpmts_dealloc(/*@only@*/ rpmtsObject * s)
01515         /*@modifies *s @*/
01516 {
01517 
01518 if (_rpmts_debug)
01519 fprintf(stderr, "%p -- ts %p db %p\n", s, s->ts, s->ts->rdb);
01520     s->ts = rpmtsFree(s->ts);
01521 
01522     if (s->scriptFd) Fclose(s->scriptFd);
01523     /* this will free the keyList, and decrement the ref count of all
01524        the items on the list as well :-) */
01525     Py_DECREF(s->keyList);
01526     PyObject_Del((PyObject *)s);
01527 }
01528 
01529 static PyObject * rpmts_getattro(PyObject * o, PyObject * n)
01530         /*@*/
01531 {
01532     return PyObject_GenericGetAttr(o, n);
01533 }
01534 
01537 static int rpmts_setattro(PyObject * o, PyObject * n, PyObject * v)
01538         /*@*/
01539 {
01540     rpmtsObject *s = (rpmtsObject *)o;
01541     char * name = PyString_AsString(n);
01542     int fdno;
01543 
01544     if (!strcmp(name, "scriptFd")) {
01545         if (!PyArg_Parse(v, "i", &fdno)) return 0;
01546         if (fdno < 0) {
01547             PyErr_SetString(PyExc_TypeError, "bad file descriptor");
01548             return -1;
01549         } else {
01550             s->scriptFd = fdDup(fdno);
01551             rpmtsSetScriptFd(s->ts, s->scriptFd);
01552         }
01553     } else {
01554         PyErr_SetString(PyExc_AttributeError, name);
01555         return -1;
01556     }
01557 
01558     return 0;
01559 }
01560 
01563 static int rpmts_init(rpmtsObject * s, PyObject *args, PyObject *kwds)
01564         /*@globals rpmGlobalMacroContext @*/
01565         /*@modifies s, rpmGlobalMacroContext @*/
01566 {
01567     char * rootDir = "/";
01568     int vsflags = rpmExpandNumeric("%{?_vsflags_up2date}");
01569     char * kwlist[] = {"rootdir", "vsflags", 0};
01570 
01571 if (_rpmts_debug < 0)
01572 fprintf(stderr, "*** rpmts_init(%p,%p,%p)\n", s, args, kwds);
01573 
01574     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|si:rpmts_init", kwlist,
01575             &rootDir, &vsflags))
01576         return -1;
01577 
01578     s->ts = rpmtsCreate();
01579     /* XXX: Why is there no rpmts_SetRootDir() ? */
01580     (void) rpmtsSetRootDir(s->ts, rootDir);
01581     /* XXX: make this use common code with rpmts_SetVSFlags() to check the
01582      *      python objects */
01583     (void) rpmtsSetVSFlags(s->ts, vsflags);
01584     s->keyList = PyList_New(0);
01585     s->scriptFd = NULL;
01586     s->tsi = NULL;
01587     s->tsiFilter = 0;
01588 
01589     return 0;
01590 }
01591 
01594 static void rpmts_free(/*@only@*/ rpmtsObject * s)
01595         /*@modifies s @*/
01596 {
01597 if (_rpmts_debug)
01598 fprintf(stderr, "%p -- ts %p db %p\n", s, s->ts, s->ts->rdb);
01599     s->ts = rpmtsFree(s->ts);
01600 
01601     if (s->scriptFd)
01602         Fclose(s->scriptFd);
01603 
01604     /* this will free the keyList, and decrement the ref count of all
01605        the items on the list as well :-) */
01606     Py_DECREF(s->keyList);
01607 
01608     PyObject_Del((PyObject *)s);
01609 }
01610 
01613 static PyObject * rpmts_alloc(PyTypeObject * subtype, int nitems)
01614         /*@*/
01615 {
01616     PyObject * s = PyType_GenericAlloc(subtype, nitems);
01617 
01618 if (_rpmts_debug < 0)
01619 fprintf(stderr, "*** rpmts_alloc(%p,%d) ret %p\n", subtype, nitems, s);
01620     return s;
01621 }
01622 
01625 static PyObject * rpmts_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
01626         /*@globals rpmGlobalMacroContext @*/
01627         /*@modifies rpmGlobalMacroContext @*/
01628 {
01629     rpmtsObject * s = (void *) PyObject_New(rpmtsObject, subtype);
01630 
01631     /* Perform additional initialization. */
01632     if (rpmts_init(s, args, kwds) < 0) {
01633         rpmts_free(s);
01634         return NULL;
01635     }
01636 
01637 if (_rpmts_debug)
01638 fprintf(stderr, "%p ++ ts %p db %p\n", s, s->ts, s->ts->rdb);
01639 
01640     return (PyObject *)s;
01641 }
01642 
01645 /*@unchecked@*/ /*@observer@*/
01646 static char rpmts_doc[] =
01647 "";
01648 
01651 /*@-fullinitblock@*/
01652 PyTypeObject rpmts_Type = {
01653         PyObject_HEAD_INIT(&PyType_Type)
01654         0,                              /* ob_size */
01655         "rpm.ts",                       /* tp_name */
01656         sizeof(rpmtsObject),            /* tp_size */
01657         0,                              /* tp_itemsize */
01658         (destructor) rpmts_dealloc,     /* tp_dealloc */
01659         0,                              /* tp_print */
01660         (getattrfunc)0,                 /* tp_getattr */
01661         (setattrfunc)0,                 /* tp_setattr */
01662         0,                              /* tp_compare */
01663         0,                              /* tp_repr */
01664         0,                              /* tp_as_number */
01665         0,                              /* tp_as_sequence */
01666         0,                              /* tp_as_mapping */
01667         0,                              /* tp_hash */
01668         0,                              /* tp_call */
01669         0,                              /* tp_str */
01670         (getattrofunc) rpmts_getattro,  /* tp_getattro */
01671         (setattrofunc) rpmts_setattro,  /* tp_setattro */
01672         0,                              /* tp_as_buffer */
01673         Py_TPFLAGS_DEFAULT,             /* tp_flags */
01674         rpmts_doc,                      /* tp_doc */
01675 #if Py_TPFLAGS_HAVE_ITER
01676         0,                              /* tp_traverse */
01677         0,                              /* tp_clear */
01678         0,                              /* tp_richcompare */
01679         0,                              /* tp_weaklistoffset */
01680         (getiterfunc) rpmts_iter,       /* tp_iter */
01681         (iternextfunc) rpmts_iternext,  /* tp_iternext */
01682         rpmts_methods,                  /* tp_methods */
01683         0,                              /* tp_members */
01684         0,                              /* tp_getset */
01685         0,                              /* tp_base */
01686         0,                              /* tp_dict */
01687         0,                              /* tp_descr_get */
01688         0,                              /* tp_descr_set */
01689         0,                              /* tp_dictoffset */
01690         (initproc) rpmts_init,          /* tp_init */
01691         (allocfunc) rpmts_alloc,        /* tp_alloc */
01692         (newfunc) rpmts_new,            /* tp_new */
01693         rpmts_free,                     /* tp_free */
01694         0,                              /* tp_is_gc */
01695 #endif
01696 };
01697 /*@=fullinitblock@*/
01698 
01701 /* XXX: This should use the same code as rpmts_init */
01702 rpmtsObject *
01703 rpmts_Create(/*@unused@*/ PyObject * self, PyObject * args, PyObject * kwds)
01704 {
01705     rpmtsObject * o;
01706     char * rootDir = "/";
01707     int vsflags = rpmExpandNumeric("%{?_vsflags_up2date}");
01708     char * kwlist[] = {"rootdir", "vsflags", NULL};
01709 
01710     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|si:Create", kwlist,
01711             &rootDir, &vsflags))
01712         return NULL;
01713 
01714     o = (void *) PyObject_New(rpmtsObject, &rpmts_Type);
01715 
01716     o->ts = rpmtsCreate();
01717     /* XXX: Why is there no rpmts_SetRootDir() ? */
01718     (void) rpmtsSetRootDir(o->ts, rootDir);
01719     /* XXX: make this use common code with rpmts_SetVSFlags() to check the
01720      *      python objects */
01721     (void) rpmtsSetVSFlags(o->ts, vsflags);
01722 
01723     o->keyList = PyList_New(0);
01724     o->scriptFd = NULL;
01725     o->tsi = NULL;
01726     o->tsiFilter = 0;
01727 
01728 if (_rpmts_debug)
01729 fprintf(stderr, "%p ++ ts %p db %p\n", o, o->ts, o->ts->rdb);
01730     return o;
01731 }

Generated on Sun Jun 1 21:56:22 2008 for rpm by  doxygen 1.5.4