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 = NULL, * needsOP = NULL, * needsVersion = NULL;
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 ((p->altNEVR != NULL) && 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 ((p->altNEVR != NULL) && 
00437                 (needsVersion = strrchr(needsName, ' ')) != NULL)
00438                 *needsVersion++ = '\0';
00439 
00440             needsFlags = 0;
00441             if ((p->altNEVR != NULL) && 
00442                 (needsOP = strrchr(needsName, ' ')) != NULL) {
00443                 for (*needsOP++ = '\0'; *needsOP != '\0'; needsOP++) {
00444                     if (*needsOP == '<')        needsFlags |= RPMSENSE_LESS;
00445                     else if (*needsOP == '>')   needsFlags |= RPMSENSE_GREATER;
00446                     else if (*needsOP == '=')   needsFlags |= RPMSENSE_EQUAL;
00447                 }
00448             }
00449             
00450             cf = Py_BuildValue("((sss)(ss)iOi)", byName, byVersion, byRelease,
00451                                needsName, needsVersion, needsFlags,
00452                                (key != NULL ? key : Py_None),
00453                                sense);
00454 #endif
00455             PyList_Append(list, (PyObject *) cf);
00456             Py_DECREF(cf);
00457         }
00458 
00459         ps = rpmpsFree(ps);
00460 
00461         return list;
00462     }
00463 
00464     Py_INCREF(Py_None);
00465     return Py_None;
00466 }
00467 
00470 static PyObject *
00471 rpmts_Order(rpmtsObject * s, PyObject * args)
00472         /*@modifies s @*/
00473 {
00474     int rc;
00475 
00476 if (_rpmts_debug)
00477 fprintf(stderr, "*** rpmts_Order(%p) ts %p\n", s, s->ts);
00478 
00479     if (!PyArg_ParseTuple(args, ":Order")) return NULL;
00480 
00481     Py_BEGIN_ALLOW_THREADS
00482     rc = rpmtsOrder(s->ts);
00483     Py_END_ALLOW_THREADS
00484 
00485     return Py_BuildValue("i", rc);
00486 }
00487 
00490 static PyObject *
00491 rpmts_Clean(rpmtsObject * s, PyObject * args)
00492         /*@globals _Py_NoneStruct @*/
00493         /*@modifies s, _Py_NoneStruct @*/
00494 {
00495 if (_rpmts_debug)
00496 fprintf(stderr, "*** rpmts_Clean(%p) ts %p\n", s, s->ts);
00497 
00498     if (!PyArg_ParseTuple(args, ":Clean")) return NULL;
00499 
00500     rpmtsClean(s->ts);
00501 
00502     Py_INCREF(Py_None);
00503     return Py_None;
00504 }
00505 
00508 static PyObject *
00509 rpmts_IDTXload(rpmtsObject * s, PyObject * args)
00510         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00511         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00512 {
00513     PyObject * result = NULL;
00514     rpmTag tag = RPMTAG_INSTALLTID;
00515     IDTX idtx;
00516 
00517 if (_rpmts_debug)
00518 fprintf(stderr, "*** rpmts_IDTXload(%p) ts %p\n", s, s->ts);
00519 
00520     if (!PyArg_ParseTuple(args, ":IDTXload")) return NULL;
00521 
00522     Py_BEGIN_ALLOW_THREADS
00523     idtx = IDTXload(s->ts, tag);
00524     Py_END_ALLOW_THREADS
00525 
00526     if (idtx == NULL || idtx->nidt <= 0) {
00527         Py_INCREF(Py_None);
00528         result = Py_None;
00529     } else {
00530         PyObject * tuple;
00531         PyObject * ho;
00532         IDT idt;
00533         int i;
00534 
00535         result = PyTuple_New(idtx->nidt);
00536         for (i = 0; i < idtx->nidt; i++) {
00537             idt = idtx->idt + i;
00538             ho = (PyObject *) hdr_Wrap(idt->h);
00539             tuple = Py_BuildValue("(iOi)", idt->val.u32, ho, idt->instance);
00540             PyTuple_SET_ITEM(result,  i, tuple);
00541             Py_DECREF(ho);
00542         }
00543     }
00544 
00545     idtx = IDTXfree(idtx);
00546 
00547     return result;
00548 }
00549 
00552 static PyObject *
00553 rpmts_IDTXglob(rpmtsObject * s, PyObject * args)
00554         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00555         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00556 {
00557     PyObject * result = NULL;
00558     rpmTag tag = RPMTAG_REMOVETID;
00559     const char * globstr;
00560     IDTX idtx;
00561 
00562 if (_rpmts_debug)
00563 fprintf(stderr, "*** rpmts_IDTXglob(%p) ts %p\n", s, s->ts);
00564 
00565     if (!PyArg_ParseTuple(args, ":IDTXglob")) return NULL;
00566 
00567     Py_BEGIN_ALLOW_THREADS
00568     globstr = rpmExpand("%{_repackage_dir}/*.rpm", NULL);
00569     idtx = IDTXglob(s->ts, globstr, tag);
00570     globstr = _free(globstr);
00571     Py_END_ALLOW_THREADS
00572 
00573     if (idtx == NULL || idtx->nidt <= 0) {
00574         Py_INCREF(Py_None);
00575         result = Py_None;
00576     } else {
00577         PyObject * tuple;
00578         PyObject * ho;
00579         IDT idt;
00580         int i;
00581 
00582         result = PyTuple_New(idtx->nidt);
00583         for (i = 0; i < idtx->nidt; i++) {
00584             idt = idtx->idt + i;
00585             ho = (PyObject *) hdr_Wrap(idt->h);
00586             tuple = Py_BuildValue("(iOs)", idt->val.u32, ho, idt->key);
00587             PyTuple_SET_ITEM(result,  i, tuple);
00588             Py_DECREF(ho);
00589         }
00590     }
00591 
00592     idtx = IDTXfree(idtx);
00593 
00594     return result;
00595 }
00596 
00599 static PyObject *
00600 rpmts_Rollback(rpmtsObject * s, PyObject * args)
00601         /*@globals rpmGlobalMacroContext @*/
00602         /*@modifies s, rpmGlobalMacroContext @*/
00603 {
00604     struct rpmInstallArguments_s * ia = alloca(sizeof(*ia));
00605     rpmtransFlags transFlags;
00606     const char ** av = NULL;
00607     uint_32 rbtid;
00608     int rc;
00609 
00610 if (_rpmts_debug)
00611 fprintf(stderr, "*** rpmts_Rollback(%p) ts %p\n", s, s->ts);
00612 
00613     if (!PyArg_ParseTuple(args, "i:Rollback", &rbtid)) return NULL;
00614 
00615     Py_BEGIN_ALLOW_THREADS
00616     memset(ia, 0, sizeof(*ia));
00617     ia->qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE|VERIFY_HDRCHK);
00618     ia->transFlags |= (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL);
00619     ia->transFlags |= RPMTRANS_FLAG_NOMD5;
00620     ia->installInterfaceFlags = (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL);
00621     ia->rbtid = rbtid;
00622     ia->relocations = NULL;
00623     ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
00624 
00625     transFlags = rpmtsSetFlags(s->ts, ia->transFlags);
00626     rc = rpmRollback(s->ts, ia, av);
00627     transFlags = rpmtsSetFlags(s->ts, transFlags);
00628     Py_END_ALLOW_THREADS
00629 
00630     return Py_BuildValue("i", rc);
00631 }
00632 
00635 static PyObject *
00636 rpmts_OpenDB(rpmtsObject * s, PyObject * args)
00637         /*@globals rpmGlobalMacroContext @*/
00638         /*@modifies s, rpmGlobalMacroContext @*/
00639 {
00640 
00641 if (_rpmts_debug)
00642 fprintf(stderr, "*** rpmts_OpenDB(%p) ts %p\n", s, s->ts);
00643 
00644     if (!PyArg_ParseTuple(args, ":OpenDB")) return NULL;
00645 
00646     if (s->ts->dbmode == -1)
00647         s->ts->dbmode = O_RDONLY;
00648 
00649     return Py_BuildValue("i", rpmtsOpenDB(s->ts, s->ts->dbmode));
00650 }
00651 
00654 static PyObject *
00655 rpmts_CloseDB(rpmtsObject * s, PyObject * args)
00656         /*@modifies s @*/
00657 {
00658     int rc;
00659 
00660 if (_rpmts_debug)
00661 fprintf(stderr, "*** rpmts_CloseDB(%p) ts %p\n", s, s->ts);
00662 
00663     if (!PyArg_ParseTuple(args, ":CloseDB")) return NULL;
00664 
00665     rc = rpmtsCloseDB(s->ts);
00666     s->ts->dbmode = -1;         /* XXX disable lazy opens */
00667 
00668     return Py_BuildValue("i", rc);
00669 }
00670 
00673 static PyObject *
00674 rpmts_InitDB(rpmtsObject * s, PyObject * args)
00675         /*@globals rpmGlobalMacroContext @*/
00676         /*@modifies s, rpmGlobalMacroContext @*/
00677 {
00678     int rc;
00679 
00680 if (_rpmts_debug)
00681 fprintf(stderr, "*** rpmts_InitDB(%p) ts %p\n", s, s->ts);
00682 
00683     if (!PyArg_ParseTuple(args, ":InitDB")) return NULL;
00684 
00685     rc = rpmtsInitDB(s->ts, O_RDONLY);
00686     if (rc == 0)
00687         rc = rpmtsCloseDB(s->ts);
00688 
00689     return Py_BuildValue("i", rc);
00690 }
00691 
00694 static PyObject *
00695 rpmts_RebuildDB(rpmtsObject * s, PyObject * args)
00696         /*@globals rpmGlobalMacroContext @*/
00697         /*@modifies s, rpmGlobalMacroContext @*/
00698 {
00699     int rc;
00700 
00701 if (_rpmts_debug)
00702 fprintf(stderr, "*** rpmts_RebuildDB(%p) ts %p\n", s, s->ts);
00703 
00704     if (!PyArg_ParseTuple(args, ":RebuildDB")) return NULL;
00705 
00706     Py_BEGIN_ALLOW_THREADS
00707     rc = rpmtsRebuildDB(s->ts);
00708     Py_END_ALLOW_THREADS
00709 
00710     return Py_BuildValue("i", rc);
00711 }
00712 
00715 static PyObject *
00716 rpmts_VerifyDB(rpmtsObject * s, PyObject * args)
00717         /*@globals rpmGlobalMacroContext @*/
00718         /*@modifies s, rpmGlobalMacroContext @*/
00719 {
00720     int rc;
00721 
00722 if (_rpmts_debug)
00723 fprintf(stderr, "*** rpmts_VerifyDB(%p) ts %p\n", s, s->ts);
00724 
00725     if (!PyArg_ParseTuple(args, ":VerifyDB")) return NULL;
00726 
00727     Py_BEGIN_ALLOW_THREADS
00728     rc = rpmtsVerifyDB(s->ts);
00729     Py_END_ALLOW_THREADS
00730 
00731     return Py_BuildValue("i", rc);
00732 }
00733 
00736 static PyObject *
00737 rpmts_HdrFromFdno(rpmtsObject * s, PyObject * args)
00738         /*@globals rpmGlobalMacroContext, _Py_NoneStruct, fileSystem @*/
00739         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct, fileSystem @*/
00740 {
00741     PyObject * result = NULL;
00742     Header h;
00743     FD_t fd;
00744     int fdno;
00745     rpmRC rpmrc;
00746 
00747     if (!PyArg_ParseTuple(args, "i:HdrFromFdno", &fdno)) return NULL;
00748 
00749     fd = fdDup(fdno);
00750     rpmrc = rpmReadPackageFile(s->ts, fd, "rpmts_HdrFromFdno", &h);
00751     Fclose(fd);
00752 
00753 if (_rpmts_debug)
00754 fprintf(stderr, "*** rpmts_HdrFromFdno(%p) ts %p rc %d\n", s, s->ts, rpmrc);
00755 
00756     switch (rpmrc) {
00757     case RPMRC_OK:
00758         if (h)
00759             result = Py_BuildValue("N", hdr_Wrap(h));
00760         h = headerFree(h);      /* XXX ref held by result */
00761         break;
00762 
00763     case RPMRC_NOKEY:
00764         PyErr_SetString(pyrpmError, "public key not available");
00765         break;
00766 
00767     case RPMRC_NOTFOUND:
00768     case RPMRC_NOTTRUSTED:
00769         PyErr_SetString(pyrpmError, "public key not trusted");
00770         break;
00771 
00772     case RPMRC_FAIL:
00773     default:
00774         PyErr_SetString(pyrpmError, "error reading package header");
00775         break;
00776     }
00777 
00778     return result;
00779 }
00780 
00783 static PyObject *
00784 rpmts_HdrCheck(rpmtsObject * s, PyObject * args)
00785         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00786         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00787 {
00788     PyObject * blob;
00789     PyObject * result = NULL;
00790     const char * msg = NULL;
00791     const void * uh;
00792     int uc;
00793     rpmRC rpmrc;
00794 
00795 if (_rpmts_debug)
00796 fprintf(stderr, "*** rpmts_HdrCheck(%p) ts %p\n", s, s->ts);
00797 
00798     if (!PyArg_ParseTuple(args, "O:HdrCheck", &blob)) return NULL;
00799     if (blob == Py_None) {
00800         Py_INCREF(Py_None);
00801         return Py_None;
00802     }
00803     if (!PyString_Check(blob)) {
00804         PyErr_SetString(pyrpmError, "hdrCheck takes a string of octets");
00805         return result;
00806     }
00807     uh = PyString_AsString(blob);
00808     uc = PyString_Size(blob);
00809 
00810     rpmrc = headerCheck(s->ts, uh, uc, &msg);
00811 
00812     switch (rpmrc) {
00813     case RPMRC_OK:
00814         Py_INCREF(Py_None);
00815         result = Py_None;
00816         break;
00817 
00818     case RPMRC_NOKEY:
00819         PyErr_SetString(pyrpmError, "public key not availaiable");
00820         break;
00821 
00822     case RPMRC_NOTTRUSTED:
00823         PyErr_SetString(pyrpmError, "public key not trusted");
00824         break;
00825 
00826     case RPMRC_FAIL:
00827     default:
00828         PyErr_SetString(pyrpmError, msg);
00829         break;
00830     }
00831     msg = _free(msg);
00832 
00833     return result;
00834 }
00835 
00838 static PyObject *
00839 rpmts_SetVSFlags(rpmtsObject * s, PyObject * args)
00840         /*@modifies s @*/
00841 {
00842     rpmVSFlags vsflags;
00843 
00844 if (_rpmts_debug)
00845 fprintf(stderr, "*** rpmts_SetVSFlags(%p) ts %p\n", s, s->ts);
00846 
00847     if (!PyArg_ParseTuple(args, "i:SetVSFlags", &vsflags)) return NULL;
00848 
00849     /* XXX FIXME: value check on vsflags. */
00850 
00851     return Py_BuildValue("i", rpmtsSetVSFlags(s->ts, vsflags));
00852 }
00853 
00856 static PyObject *
00857 rpmts_SetColor(rpmtsObject * s, PyObject * args)
00858         /*@modifies s @*/
00859 {
00860     uint_32 tscolor;
00861 
00862 if (_rpmts_debug)
00863 fprintf(stderr, "*** rpmts_SetColor(%p) ts %p\n", s, s->ts);
00864 
00865     if (!PyArg_ParseTuple(args, "i:Color", &tscolor)) return NULL;
00866 
00867     /* XXX FIXME: value check on tscolor. */
00868 
00869     return Py_BuildValue("i", rpmtsSetColor(s->ts, tscolor));
00870 }
00871 
00874 static PyObject *
00875 rpmts_PgpPrtPkts(rpmtsObject * s, PyObject * args)
00876         /*@globals _Py_NoneStruct @*/
00877         /*@modifies _Py_NoneStruct @*/
00878 {
00879     PyObject * blob;
00880     unsigned char * pkt;
00881     unsigned int pktlen;
00882     int rc;
00883 
00884 if (_rpmts_debug)
00885 fprintf(stderr, "*** rpmts_PgpPrtPkts(%p) ts %p\n", s, s->ts);
00886 
00887     if (!PyArg_ParseTuple(args, "O:PgpPrtPkts", &blob)) return NULL;
00888     if (blob == Py_None) {
00889         Py_INCREF(Py_None);
00890         return Py_None;
00891     }
00892     if (!PyString_Check(blob)) {
00893         PyErr_SetString(pyrpmError, "pgpPrtPkts takes a string of octets");
00894         return NULL;
00895     }
00896     pkt = PyString_AsString(blob);
00897     pktlen = PyString_Size(blob);
00898 
00899     rc = pgpPrtPkts(pkt, pktlen, NULL, 1);
00900 
00901     return Py_BuildValue("i", rc);
00902 }
00903 
00906 static PyObject *
00907 rpmts_PgpImportPubkey(rpmtsObject * s, PyObject * args)
00908         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
00909         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
00910 {
00911     PyObject * blob;
00912     unsigned char * pkt;
00913     unsigned int pktlen;
00914     int rc;
00915 
00916 if (_rpmts_debug)
00917 fprintf(stderr, "*** rpmts_PgpImportPubkey(%p) ts %p\n", s, s->ts);
00918 
00919     if (!PyArg_ParseTuple(args, "O:PgpImportPubkey", &blob)) return NULL;
00920     if (blob == Py_None) {
00921         Py_INCREF(Py_None);
00922         return Py_None;
00923     }
00924     if (!PyString_Check(blob)) {
00925         PyErr_SetString(pyrpmError, "PgpImportPubkey takes a string of octets");
00926         return NULL;
00927     }
00928     pkt = PyString_AsString(blob);
00929     pktlen = PyString_Size(blob);
00930 
00931     rc = rpmcliImportPubkey(s->ts, pkt, pktlen);
00932 
00933     return Py_BuildValue("i", rc);
00934 }
00935 
00938 static PyObject *
00939 rpmts_GetKeys(rpmtsObject * s, PyObject * args)
00940         /*@globals _Py_NoneStruct @*/
00941         /*@modifies s, _Py_NoneStruct @*/
00942 {
00943     const void **data = NULL;
00944     int num, i;
00945     PyObject *tuple;
00946 
00947 if (_rpmts_debug)
00948 fprintf(stderr, "*** rpmts_GetKeys(%p) ts %p\n", s, s->ts);
00949 
00950     if (!PyArg_ParseTuple(args, ":GetKeys")) return NULL;
00951 
00952     rpmtsGetKeys(s->ts, &data, &num);
00953     if (data == NULL || num <= 0) {
00954         data = _free(data);
00955         Py_INCREF(Py_None);
00956         return Py_None;
00957     }
00958 
00959     tuple = PyTuple_New(num);
00960 
00961     for (i = 0; i < num; i++) {
00962         PyObject *obj;
00963         obj = (data[i] ? (PyObject *) data[i] : Py_None);
00964         Py_INCREF(obj);
00965         PyTuple_SetItem(tuple, i, obj);
00966     }
00967 
00968     data = _free(data);
00969 
00970     return tuple;
00971 }
00972 
00975 static void *
00976 rpmtsCallback(/*@unused@*/ const void * hd, const rpmCallbackType what,
00977                          const unsigned long amount, const unsigned long total,
00978                          const void * pkgKey, rpmCallbackData data)
00979         /*@globals _Py_NoneStruct @*/
00980         /*@modifies _Py_NoneStruct @*/
00981 {
00982 /*@-castexpose@*/
00983     Header h = (Header) hd;
00984 /*@=castexpose@*/
00985     struct rpmtsCallbackType_s * cbInfo = data;
00986     PyObject * pkgObj = (PyObject *) pkgKey;
00987     PyObject * args, * result;
00988     static FD_t fd;
00989 
00990     if (cbInfo->pythonError) return NULL;
00991     if (cbInfo->cb == Py_None) return NULL;
00992 
00993     /* Synthesize a python object for callback (if necessary). */
00994     if (pkgObj == NULL) {
00995         if (h) {
00996             const char * n = NULL;
00997             (void) headerNVR(h, &n, NULL, NULL);
00998             pkgObj = Py_BuildValue("s", n);
00999         } else {
01000             pkgObj = Py_None;
01001             Py_INCREF(pkgObj);
01002         }
01003     } else
01004         Py_INCREF(pkgObj);
01005 
01006     PyEval_RestoreThread(cbInfo->_save);
01007 
01008     args = Py_BuildValue("(illOO)", what, amount, total, pkgObj, cbInfo->data);
01009     result = PyEval_CallObject(cbInfo->cb, args);
01010     Py_DECREF(args);
01011     Py_DECREF(pkgObj);
01012 
01013     if (!result) {
01014         cbInfo->pythonError = 1;
01015         cbInfo->_save = PyEval_SaveThread();
01016         return NULL;
01017     }
01018 
01019     if (what == RPMCALLBACK_INST_OPEN_FILE) {
01020         int fdno;
01021 
01022         if (!PyArg_Parse(result, "i", &fdno)) {
01023             cbInfo->pythonError = 1;
01024             cbInfo->_save = PyEval_SaveThread();
01025             return NULL;
01026         }
01027         Py_DECREF(result);
01028         cbInfo->_save = PyEval_SaveThread();
01029 
01030         fd = fdDup(fdno);
01031 if (_rpmts_debug)
01032 fprintf(stderr, "\t%p = fdDup(%d)\n", fd, fdno);
01033         
01034         return fd;
01035     } else
01036     if (what == RPMCALLBACK_INST_CLOSE_FILE) {
01037 if (_rpmts_debug)
01038 fprintf(stderr, "\tFclose(%p)\n", fd);
01039         Fclose (fd);
01040     } else {
01041 if (_rpmts_debug)
01042 fprintf(stderr, "\t%ld:%ld key %p\n", amount, total, pkgKey);
01043     }
01044 
01045     Py_DECREF(result);
01046     cbInfo->_save = PyEval_SaveThread();
01047 
01048     return NULL;
01049 }
01050 
01053 static PyObject * rpmts_SetFlags(rpmtsObject * s, PyObject * args)
01054         /*@modifies s @*/
01055 {
01056     rpmtransFlags transFlags = 0;
01057 
01058     if (!PyArg_ParseTuple(args, "i:SetFlags", &transFlags))
01059         return NULL;
01060 
01061 if (_rpmts_debug)
01062 fprintf(stderr, "*** rpmts_SetFlags(%p) ts %p transFlags %x\n", s, s->ts, transFlags);
01063 
01064     return Py_BuildValue("i", rpmtsSetFlags(s->ts, transFlags));
01065 }
01066 
01069 static PyObject * rpmts_SetProbFilter(rpmtsObject * s, PyObject * args)
01070         /*@modifies s @*/
01071 {
01072     rpmprobFilterFlags ignoreSet = 0;
01073     rpmprobFilterFlags oignoreSet;
01074 
01075     if (!PyArg_ParseTuple(args, "i:ProbFilter", &ignoreSet))
01076         return NULL;
01077 
01078 if (_rpmts_debug)
01079 fprintf(stderr, "*** rpmts_SetProbFilter(%p) ts %p ignoreSet %x\n", s, s->ts, ignoreSet);
01080 
01081     oignoreSet = s->ignoreSet;
01082     s->ignoreSet = ignoreSet;
01083 
01084     return Py_BuildValue("i", oignoreSet);
01085 }
01086 
01089 static PyObject * rpmts_Run(rpmtsObject * s, PyObject * args)
01090         /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
01091         /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
01092 {
01093     int rc, i;
01094     PyObject * list;
01095     rpmps ps;
01096     struct rpmtsCallbackType_s cbInfo;
01097 
01098     if (!PyArg_ParseTuple(args, "OO:Run", &cbInfo.cb, &cbInfo.data))
01099         return NULL;
01100 
01101     cbInfo.tso = s;
01102     cbInfo.pythonError = 0;
01103     cbInfo._save = PyEval_SaveThread();
01104 
01105     if (cbInfo.cb != NULL) {
01106         if (!PyCallable_Check(cbInfo.cb)) {
01107             PyErr_SetString(PyExc_TypeError, "expected a callable");
01108             return NULL;
01109         }
01110         (void) rpmtsSetNotifyCallback(s->ts, rpmtsCallback, (void *) &cbInfo);
01111     }
01112 
01113 
01114 if (_rpmts_debug)
01115 fprintf(stderr, "*** rpmts_Run(%p) ts %p ignore %x\n", s, s->ts, s->ignoreSet);
01116 
01117     rc = rpmtsRun(s->ts, NULL, s->ignoreSet);
01118     ps = rpmtsProblems(s->ts);
01119 
01120     if (cbInfo.cb)
01121         (void) rpmtsSetNotifyCallback(s->ts, NULL, NULL);
01122 
01123     PyEval_RestoreThread(cbInfo._save);
01124 
01125     if (cbInfo.pythonError) {
01126         ps = rpmpsFree(ps);
01127         return NULL;
01128     }
01129 
01130     if (rc < 0) {
01131         list = PyList_New(0);
01132         return list;
01133     } else if (!rc) {
01134         Py_INCREF(Py_None);
01135         return Py_None;
01136     }
01137 
01138     list = PyList_New(0);
01139     for (i = 0; i < ps->numProblems; i++) {
01140         rpmProblem p = ps->probs + i;
01141         PyObject * prob = Py_BuildValue("s(isN)", rpmProblemString(p),
01142                              p->type,
01143                              p->str1,
01144                              PyLong_FromLongLong(p->ulong1));
01145         PyList_Append(list, prob);
01146         Py_DECREF(prob);
01147     }
01148 
01149     ps = rpmpsFree(ps);
01150 
01151     return list;
01152 }
01153 
01154 #if Py_TPFLAGS_HAVE_ITER
01155 static PyObject *
01156 rpmts_iter(rpmtsObject * s)
01157         /*@*/
01158 {
01159 if (_rpmts_debug)
01160 fprintf(stderr, "*** rpmts_iter(%p) ts %p\n", s, s->ts);
01161 
01162     Py_INCREF(s);
01163     return (PyObject *)s;
01164 }
01165 #endif
01166 
01170 static PyObject *
01171 rpmts_iternext(rpmtsObject * s)
01172         /*@modifies s @*/
01173 {
01174     PyObject * result = NULL;
01175     rpmte te;
01176 
01177 if (_rpmts_debug)
01178 fprintf(stderr, "*** rpmts_iternext(%p) ts %p tsi %p %d\n", s, s->ts, s->tsi, s->tsiFilter);
01179 
01180     /* Reset iterator on 1st entry. */
01181     if (s->tsi == NULL) {
01182         s->tsi = rpmtsiInit(s->ts);
01183         if (s->tsi == NULL)
01184             return NULL;
01185         s->tsiFilter = 0;
01186     }
01187 
01188     te = rpmtsiNext(s->tsi, s->tsiFilter);
01189     if (te != NULL) {
01190         result = (PyObject *) rpmte_Wrap(te);
01191     } else {
01192         s->tsi = rpmtsiFree(s->tsi);
01193         s->tsiFilter = 0;
01194     }
01195 
01196     return result;
01197 }
01198 
01202 static PyObject *
01203 rpmts_Next(rpmtsObject * s)
01204         /*@globals _Py_NoneStruct @*/
01205         /*@modifies s, _Py_NoneStruct @*/
01206 {
01207     PyObject * result;
01208 
01209 if (_rpmts_debug)
01210 fprintf(stderr, "*** rpmts_Next(%p) ts %p\n", s, s->ts);
01211 
01212     result = rpmts_iternext(s);
01213 
01214     if (result == NULL) {
01215         Py_INCREF(Py_None);
01216         return Py_None;
01217     }
01218 
01219     return result;
01220 }
01221 
01224 static rpmmiObject *
01225 rpmts_Match(rpmtsObject * s, PyObject * args)
01226         /*@globals rpmGlobalMacroContext @*/
01227         /*@modifies s, rpmGlobalMacroContext @*/
01228 {
01229     PyObject *TagN = NULL;
01230     char *key = NULL;
01231     int len = 0;
01232     int tag = RPMDBI_PACKAGES;
01233     
01234 if (_rpmts_debug)
01235 fprintf(stderr, "*** rpmts_Match(%p) ts %p\n", s, s->ts);
01236 
01237     if (!PyArg_ParseTuple(args, "|Ozi", &TagN, &key, &len))
01238         return NULL;
01239 
01240     if (TagN && (tag = tagNumFromPyObject (TagN)) == -1) {
01241         PyErr_SetString(PyExc_TypeError, "unknown tag type");
01242         return NULL;
01243     }
01244 
01245     /* XXX If not already opened, open the database O_RDONLY now. */
01246     if (s->ts->rdb == NULL) {
01247         int rc = rpmtsOpenDB(s->ts, O_RDONLY);
01248         if (rc || s->ts->rdb == NULL) {
01249             PyErr_SetString(PyExc_TypeError, "rpmdb open failed");
01250             return NULL;
01251         }
01252     }
01253 
01254     return rpmmi_Wrap( rpmtsInitIterator(s->ts, tag, key, len) );
01255 }
01256 
01259 /*@-fullinitblock@*/
01260 /*@unchecked@*/ /*@observer@*/
01261 static struct PyMethodDef rpmts_methods[] = {
01262  {"Debug",      (PyCFunction)rpmts_Debug,       METH_VARARGS,
01263         NULL},
01264 
01265  {"addInstall", (PyCFunction) rpmts_AddInstall, METH_VARARGS,
01266         NULL },
01267  {"addErase",   (PyCFunction) rpmts_AddErase,   METH_VARARGS,
01268         NULL },
01269  {"check",      (PyCFunction) rpmts_Check,      METH_VARARGS,
01270         NULL },
01271  {"order",      (PyCFunction) rpmts_Order,      METH_VARARGS,
01272         NULL },
01273  {"setFlags",   (PyCFunction) rpmts_SetFlags,   METH_VARARGS,
01274 "ts.setFlags(transFlags) -> previous transFlags\n\
01275 - Set control bit(s) for executing ts.run().\n\
01276   Note: This method replaces the 1st argument to the old ts.run()\n" },
01277  {"setProbFilter",      (PyCFunction) rpmts_SetProbFilter,      METH_VARARGS,
01278 "ts.setProbFilter(ignoreSet) -> previous ignoreSet\n\
01279 - Set control bit(s) for ignoring problems found by ts.run().\n\
01280   Note: This method replaces the 2nd argument to the old ts.run()\n" },
01281  {"run",        (PyCFunction) rpmts_Run,        METH_VARARGS,
01282 "ts.run(callback, data) -> (problems)\n\
01283 - Run a transaction set, returning list of problems found.\n\
01284   Note: The callback may not be None.\n" },
01285  {"clean",      (PyCFunction) rpmts_Clean,      METH_VARARGS,
01286         NULL },
01287  {"IDTXload",   (PyCFunction) rpmts_IDTXload,   METH_VARARGS,
01288 "ts.IDTXload() -> ((tid,hdr,instance)+)\n\
01289 - Return list of installed packages reverse sorted by transaction id.\n" },
01290  {"IDTXglob",   (PyCFunction) rpmts_IDTXglob,   METH_VARARGS,
01291 "ts.IDTXglob() -> ((tid,hdr,instance)+)\n\
01292 - Return list of removed packages reverse sorted by transaction id.\n" },
01293  {"rollback",   (PyCFunction) rpmts_Rollback,   METH_VARARGS,
01294         NULL },
01295  {"openDB",     (PyCFunction) rpmts_OpenDB,     METH_VARARGS,
01296 "ts.openDB() -> None\n\
01297 - Open the default transaction rpmdb.\n\
01298   Note: The transaction rpmdb is lazily opened, so ts.openDB() is seldom needed.\n" },
01299  {"closeDB",    (PyCFunction) rpmts_CloseDB,    METH_VARARGS,
01300 "ts.closeDB() -> None\n\
01301 - Close the default transaction rpmdb.\n\
01302   Note: ts.closeDB() disables lazy opens, and should hardly ever be used.\n" },
01303  {"initDB",     (PyCFunction) rpmts_InitDB,     METH_VARARGS,
01304 "ts.initDB() -> None\n\
01305 - Initialize the default transaction rpmdb.\n\
01306  Note: ts.initDB() is seldom needed anymore.\n" },
01307  {"rebuildDB",  (PyCFunction) rpmts_RebuildDB,  METH_VARARGS,
01308 "ts.rebuildDB() -> None\n\
01309 - Rebuild the default transaction rpmdb.\n" },
01310  {"verifyDB",   (PyCFunction) rpmts_VerifyDB,   METH_VARARGS,
01311 "ts.verifyDB() -> None\n\
01312 - Verify the default transaction rpmdb.\n" },
01313  {"hdrFromFdno",(PyCFunction) rpmts_HdrFromFdno,METH_VARARGS,
01314 "ts.hdrFromFdno(fdno) -> hdr\n\
01315 - Read a package header from a file descriptor.\n" },
01316  {"hdrCheck",   (PyCFunction) rpmts_HdrCheck,   METH_VARARGS,
01317         NULL },
01318  {"setVSFlags",(PyCFunction) rpmts_SetVSFlags,  METH_VARARGS,
01319 "ts.setVSFlags(vsflags) -> ovsflags\n\
01320 - Set signature verification flags. Values for vsflags are:\n\
01321     rpm.RPMVSF_NOHDRCHK      if set, don't check rpmdb headers\n\
01322     rpm.RPMVSF_NEEDPAYLOAD   if not set, check header+payload (if possible)\n\
01323     rpm.RPMVSF_NOSHA1HEADER  if set, don't check header SHA1 digest\n\
01324     rpm.RPMVSF_NODSAHEADER   if set, don't check header DSA signature\n\
01325     rpm.RPMVSF_NOMD5         if set, don't check header+payload MD5 digest\n\
01326     rpm.RPMVSF_NODSA         if set, don't check header+payload DSA signature\n\
01327     rpm.RPMVSF_NORSA         if set, don't check header+payload RSA signature\n\
01328     rpm._RPMVSF_NODIGESTS    if set, don't check digest(s)\n\
01329     rpm._RPMVSF_NOSIGNATURES if set, don't check signature(s)\n" },
01330  {"setColor",(PyCFunction) rpmts_SetColor,      METH_VARARGS,
01331         NULL },
01332  {"pgpPrtPkts", (PyCFunction) rpmts_PgpPrtPkts, METH_VARARGS,
01333         NULL },
01334  {"pgpImportPubkey",    (PyCFunction) rpmts_PgpImportPubkey,    METH_VARARGS,
01335         NULL },
01336  {"getKeys",    (PyCFunction) rpmts_GetKeys,    METH_VARARGS,
01337         NULL },
01338  {"dbMatch",    (PyCFunction) rpmts_Match,      METH_VARARGS,
01339 "ts.dbMatch([TagN, [key, [len]]]) -> mi\n\
01340 - Create a match iterator for the default transaction rpmdb.\n" },
01341  {"next",               (PyCFunction)rpmts_Next,        METH_VARARGS,
01342 "ts.next() -> te\n\
01343 - Retrieve next transaction set element.\n" },
01344     {NULL,              NULL}           /* sentinel */
01345 };
01346 /*@=fullinitblock@*/
01347 
01350 static void rpmts_dealloc(/*@only@*/ rpmtsObject * s)
01351         /*@modifies *s @*/
01352 {
01353 
01354 if (_rpmts_debug)
01355 fprintf(stderr, "%p -- ts %p db %p\n", s, s->ts, s->ts->rdb);
01356     s->ts = rpmtsFree(s->ts);
01357 
01358     if (s->scriptFd) Fclose(s->scriptFd);
01359     /* this will free the keyList, and decrement the ref count of all
01360        the items on the list as well :-) */
01361     Py_DECREF(s->keyList);
01362     PyObject_Del((PyObject *)s);
01363 }
01364 
01367 static PyObject * rpmts_getattr(rpmtsObject * o, char * name)
01368         /*@*/
01369 {
01370     return Py_FindMethod(rpmts_methods, (PyObject *) o, name);
01371 }
01372 
01375 static int rpmts_setattr(rpmtsObject * o, char * name, PyObject * val)
01376         /*@modifies o @*/
01377 {
01378     int i;
01379 
01380     if (!strcmp(name, "scriptFd")) {
01381         if (!PyArg_Parse(val, "i", &i)) return 0;
01382         if (i < 0) {
01383             PyErr_SetString(PyExc_TypeError, "bad file descriptor");
01384             return -1;
01385         } else {
01386             o->scriptFd = fdDup(i);
01387             rpmtsSetScriptFd(o->ts, o->scriptFd);
01388         }
01389     } else {
01390         PyErr_SetString(PyExc_AttributeError, name);
01391         return -1;
01392     }
01393 
01394     return 0;
01395 }
01396 
01399 static int rpmts_init(rpmtsObject * s, PyObject *args, PyObject *kwds)
01400         /*@globals rpmGlobalMacroContext @*/
01401         /*@modifies s, rpmGlobalMacroContext @*/
01402 {
01403     char * rootDir = "/";
01404     int vsflags = rpmExpandNumeric("%{?_vsflags_up2date}");
01405 
01406 if (_rpmts_debug < 0)
01407 fprintf(stderr, "*** rpmts_init(%p,%p,%p)\n", s, args, kwds);
01408 
01409     if (!PyArg_ParseTuple(args, "|si:rpmts_init", &rootDir, &vsflags))
01410         return -1;
01411 
01412     s->ts = rpmtsCreate();
01413     (void) rpmtsSetRootDir(s->ts, rootDir);
01414     (void) rpmtsSetVSFlags(s->ts, vsflags);
01415     s->keyList = PyList_New(0);         
01416     s->scriptFd = NULL;                 
01417     s->tsi = NULL;
01418     s->tsiFilter = 0;
01419 
01420     return 0;
01421 }
01422 
01425 static void rpmts_free(/*@only@*/ rpmtsObject * s)
01426         /*@modifies s @*/
01427 {
01428 if (_rpmts_debug)
01429 fprintf(stderr, "%p -- ts %p db %p\n", s, s->ts, s->ts->rdb);
01430     rpmtsFree(s->ts);
01431 
01432     if (s->scriptFd)
01433         Fclose(s->scriptFd);
01434 
01435     /* this will free the keyList, and decrement the ref count of all
01436        the items on the list as well :-) */
01437     Py_DECREF(s->keyList);
01438 
01439     PyObject_Del((PyObject *)s);
01440 }
01441 
01444 static PyObject * rpmts_alloc(PyTypeObject * subtype, int nitems)
01445         /*@*/
01446 {
01447     PyObject * s = PyType_GenericAlloc(subtype, nitems);
01448 
01449 if (_rpmts_debug < 0)
01450 fprintf(stderr, "*** rpmts_alloc(%p,%d) ret %p\n", subtype, nitems, s);
01451     return s;
01452 }
01453 
01456 static PyObject * rpmts_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
01457         /*@globals rpmGlobalMacroContext @*/
01458         /*@modifies rpmGlobalMacroContext @*/
01459 {
01460     rpmtsObject * s = (void *) PyObject_New(rpmtsObject, subtype);
01461 
01462     /* Perform additional initialization. */
01463     if (rpmts_init(s, args, kwds) < 0) {
01464         rpmts_free(s);
01465         return NULL;
01466     }
01467 
01468 if (_rpmts_debug)
01469 fprintf(stderr, "%p ++ ts %p db %p\n", s, s->ts, s->ts->rdb);
01470 
01471     return (PyObject *)s;
01472 }
01473 
01476 /*@unchecked@*/ /*@observer@*/
01477 static char rpmts_doc[] =
01478 "";
01479 
01482 /*@-fullinitblock@*/
01483 PyTypeObject rpmts_Type = {
01484         PyObject_HEAD_INIT(&PyType_Type)
01485         0,                              /* ob_size */
01486         "rpm.ts",                       /* tp_name */
01487         sizeof(rpmtsObject),            /* tp_size */
01488         0,                              /* tp_itemsize */
01489         (destructor) rpmts_dealloc,     /* tp_dealloc */
01490         0,                              /* tp_print */
01491         (getattrfunc) rpmts_getattr,    /* tp_getattr */
01492         (setattrfunc) rpmts_setattr,    /* tp_setattr */
01493         0,                              /* tp_compare */
01494         0,                              /* tp_repr */
01495         0,                              /* tp_as_number */
01496         0,                              /* tp_as_sequence */
01497         0,                              /* tp_as_mapping */
01498         0,                              /* tp_hash */
01499         0,                              /* tp_call */
01500         0,                              /* tp_str */
01501         0,                              /* tp_getattro */
01502         0,                              /* tp_setattro */
01503         0,                              /* tp_as_buffer */
01504         Py_TPFLAGS_DEFAULT,             /* tp_flags */
01505         rpmts_doc,                      /* tp_doc */
01506 #if Py_TPFLAGS_HAVE_ITER
01507         0,                              /* tp_traverse */
01508         0,                              /* tp_clear */
01509         0,                              /* tp_richcompare */
01510         0,                              /* tp_weaklistoffset */
01511         (getiterfunc) rpmts_iter,       /* tp_iter */
01512         (iternextfunc) rpmts_iternext,  /* tp_iternext */
01513         rpmts_methods,                  /* tp_methods */
01514         0,                              /* tp_members */
01515         0,                              /* tp_getset */
01516         0,                              /* tp_base */
01517         0,                              /* tp_dict */
01518         0,                              /* tp_descr_get */
01519         0,                              /* tp_descr_set */
01520         0,                              /* tp_dictoffset */
01521         (initproc) rpmts_init,          /* tp_init */
01522         (allocfunc) rpmts_alloc,        /* tp_alloc */
01523         (newfunc) rpmts_new,            /* tp_new */
01524         (destructor) rpmts_free,        /* tp_free */
01525         0,                              /* tp_is_gc */
01526 #endif
01527 };
01528 /*@=fullinitblock@*/
01529 
01532 rpmtsObject *
01533 rpmts_Create(/*@unused@*/ PyObject * self, PyObject * args)
01534 {
01535     rpmtsObject * o;
01536     char * rootDir = "/";
01537     int vsflags = rpmExpandNumeric("%{?_vsflags_up2date}");
01538 
01539     if (!PyArg_ParseTuple(args, "|si:Create", &rootDir, &vsflags))
01540         return NULL;
01541 
01542     o = (void *) PyObject_New(rpmtsObject, &rpmts_Type);
01543 
01544     o->ts = rpmtsCreate();
01545     (void) rpmtsSetRootDir(o->ts, rootDir);
01546     (void) rpmtsSetVSFlags(o->ts, vsflags);
01547 
01548     o->keyList = PyList_New(0);
01549     o->scriptFd = NULL;
01550     o->tsi = NULL;
01551     o->tsiFilter = 0;
01552 
01553 if (_rpmts_debug)
01554 fprintf(stderr, "%p ++ ts %p db %p\n", o, o->ts, o->ts->rdb);
01555     return o;
01556 }

Generated on Sun Oct 26 13:02:02 2003 for rpm by doxygen1.2.18