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