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