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