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

python/rpmts-py.c

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

Generated on Thu Jul 17 22:37:11 2003 for rpm by doxygen1.3