rpm 5.2.1
|
00001 00005 #include "system.h" 00006 00007 #include <rpmio_internal.h> /* XXX for fdSetOpen */ 00008 #include <rpmcb.h> 00009 00010 #define _RPMPS_INTERNAL /* XXX almost (but not quite) opaque. */ 00011 #include <rpmpgp.h> 00012 00013 #include <rpmtypes.h> 00014 #include <rpmtag.h> 00015 #include <pkgio.h> /* XXX headerCheck() */ 00016 #include <rpmdb.h> 00017 00018 #define _RPMTS_INTERNAL /* XXX expose rpmtsSetScriptFd */ 00019 #include <rpmbuild.h> 00020 00021 #include <rpmcli.h> 00022 #define _RPMROLLBACK_INTERNAL /* XXX IDTX et al */ 00023 #include <rpmrollback.h> 00024 00025 #include "header-py.h" 00026 #include "rpmds-py.h" /* XXX for rpmdsNew */ 00027 #include "rpmfi-py.h" /* XXX for rpmfiNew */ 00028 #include "rpmmi-py.h" 00029 #include "rpmps-py.h" 00030 #include "rpmte-py.h" 00031 #include "spec-py.h" 00032 00033 #include "rpmts-py.h" 00034 00035 #include "debug.h" 00036 00037 #define rpmtsfree() rpmioFreePoolItem() 00038 00039 /*@unchecked@*/ 00040 /*@-shadow@*/ 00041 extern int _rpmts_debug; 00042 /*@=shadow@*/ 00043 00044 /*@access alKey @*/ 00045 /*@access FD_t @*/ 00046 /*@access Header @*/ 00047 /*@access rpmal @*/ 00048 /*@access rpmdb @*/ 00049 /*@access rpmds @*/ 00050 /*@access rpmts @*/ 00051 /*@access rpmtsi @*/ 00052 00173 struct rpmtsCallbackType_s { 00174 PyObject * cb; 00175 PyObject * data; 00176 rpmtsObject * tso; 00177 rpmdsObject * dso; 00178 PyThreadState *_save; 00179 }; 00180 00183 /*@exits@*/ 00184 static void rpmts_Die(PyObject *cb) 00185 /*@*/ 00186 { 00187 PyObject * r = PyObject_Repr(cb); 00188 char *pyfn = (r != NULL ? PyString_AsString(r) : "???"); 00189 00190 if (PyErr_Occurred()) 00191 PyErr_Print(); 00192 rpmlog(RPMLOG_ERR, _("python callback %s failed, aborting!\n"), pyfn); 00193 rpmdbCheckTerminate(1); 00194 exit(EXIT_FAILURE); 00195 } 00196 00199 static int 00200 rpmts_SolveCallback(rpmts ts, rpmds ds, const void * data) 00201 /*@*/ 00202 { 00203 struct rpmtsCallbackType_s * cbInfo = (struct rpmtsCallbackType_s *) data; 00204 PyObject * args, * result; 00205 int res = 1; 00206 00207 if (_rpmts_debug) 00208 fprintf(stderr, "*** rpmts_SolveCallback(%p,%p,%p) \"%s\"\n", ts, ds, data, rpmdsDNEVR(ds)); 00209 00210 if (cbInfo->tso == NULL) return res; 00211 if (cbInfo->cb == Py_None) return res; 00212 00213 PyEval_RestoreThread(cbInfo->_save); 00214 00215 cbInfo->dso = rpmds_Wrap(ds); /* XXX perhaps persistent? */ 00216 args = Py_BuildValue("(OO)", cbInfo->tso, cbInfo->dso); 00217 result = PyEval_CallObject(cbInfo->cb, args); 00218 Py_DECREF(cbInfo->dso); 00219 cbInfo->dso = NULL; 00220 Py_DECREF(args); 00221 00222 if (!result) { 00223 rpmts_Die(cbInfo->cb); 00224 /*@notreached@*/ 00225 } else { 00226 if (PyInt_Check(result)) 00227 res = PyInt_AsLong(result); 00228 Py_DECREF(result); 00229 } 00230 00231 cbInfo->_save = PyEval_SaveThread(); 00232 00233 return res; 00234 } 00235 00238 /*@null@*/ 00239 static void * 00240 rpmtsCallback(/*@unused@*/ const void * hd, const rpmCallbackType what, 00241 const rpmuint64_t amount, const rpmuint64_t total, 00242 fnpyKey pkgKey, rpmCallbackData data) 00243 /*@globals _Py_NoneStruct @*/ 00244 /*@modifies _Py_NoneStruct @*/ 00245 { 00246 /*@-castexpose@*/ 00247 Header h = (Header) hd; 00248 /*@=castexpose@*/ 00249 struct rpmtsCallbackType_s * cbInfo = data; 00250 PyObject * pkgObj = (PyObject *) pkgKey; 00251 PyObject * oh = NULL; 00252 const char * origin = NULL; 00253 PyObject * args, * result; 00254 static FD_t fd; 00255 00256 if (cbInfo->cb == Py_None) return NULL; 00257 00258 /* Synthesize a python object for callback (if necessary). */ 00259 if (pkgObj == NULL) { 00260 if (h) { 00261 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00262 he->tag = RPMTAG_NAME; 00263 if (headerGet(h, he, 0)) { 00264 pkgObj = Py_BuildValue("s", he->p.str); 00265 he->p.ptr = _free(he->p.ptr); 00266 } else { 00267 pkgObj = Py_None; 00268 Py_INCREF(pkgObj); 00269 } 00270 } else { 00271 pkgObj = Py_None; 00272 Py_INCREF(pkgObj); 00273 } 00274 } else { 00275 Py_INCREF(pkgObj); 00276 /* XXX yum has (h, rpmloc) tuple as pkgKey. Extract the path. */ 00277 if (!(PyTuple_Check(pkgObj) && PyArg_ParseTuple(pkgObj, "|Os", &oh, &origin))) 00278 origin = NULL; 00279 /* XXX clean up the path, yum paths start "//..." */ 00280 if (origin && origin[0] == '/' && origin[1] == '/') 00281 origin++; 00282 } 00283 00284 PyEval_RestoreThread(cbInfo->_save); 00285 00286 args = Py_BuildValue("(iLLOO)", what, amount, total, pkgObj, cbInfo->data); 00287 result = PyEval_CallObject(cbInfo->cb, args); 00288 Py_DECREF(args); 00289 Py_DECREF(pkgObj); 00290 00291 if (!result) { 00292 rpmts_Die(cbInfo->cb); 00293 /*@notreached@*/ 00294 } 00295 00296 if (what == RPMCALLBACK_INST_OPEN_FILE) { 00297 int fdno; 00298 00299 if (!PyArg_Parse(result, "i", &fdno)) { 00300 rpmts_Die(cbInfo->cb); 00301 /*@notreached@*/ 00302 } 00303 Py_DECREF(result); 00304 cbInfo->_save = PyEval_SaveThread(); 00305 00306 fd = fdDup(fdno); 00307 if (_rpmts_debug) 00308 fprintf(stderr, "\t%p = fdDup(%d)\n", fd, fdno); 00309 00310 fcntl(Fileno(fd), F_SETFD, FD_CLOEXEC); 00311 00312 if (origin != NULL) 00313 (void) fdSetOpen(fd, origin, 0, 0); 00314 00315 return fd; 00316 } else 00317 if (what == RPMCALLBACK_INST_CLOSE_FILE) { 00318 if (_rpmts_debug) 00319 fprintf(stderr, "\tFclose(%p)\n", fd); 00320 Fclose (fd); 00321 } else { 00322 if (_rpmts_debug) 00323 fprintf(stderr, "\t%llu:%llu key %p\n", (unsigned long long)amount, (unsigned long long)total, pkgKey); 00324 } 00325 00326 Py_DECREF(result); 00327 cbInfo->_save = PyEval_SaveThread(); 00328 00329 return NULL; 00330 } 00331 00332 #if Py_TPFLAGS_HAVE_ITER 00333 00335 static PyObject * 00336 rpmts_iter(rpmtsObject * s) 00337 /*@*/ 00338 { 00339 if (_rpmts_debug) 00340 fprintf(stderr, "*** rpmts_iter(%p) ts %p\n", s, s->ts); 00341 00342 Py_INCREF(s); 00343 return (PyObject *)s; 00344 } 00345 #endif 00346 00350 /*@null@*/ 00351 static PyObject * 00352 rpmts_iternext(rpmtsObject * s) 00353 /*@modifies s @*/ 00354 { 00355 PyObject * result = NULL; 00356 rpmte te; 00357 00358 if (_rpmts_debug) 00359 fprintf(stderr, "*** rpmts_iternext(%p) ts %p tsi %p %d\n", s, s->ts, s->tsi, s->tsiFilter); 00360 00361 /* Reset iterator on 1st entry. */ 00362 if (s->tsi == NULL) { 00363 s->tsi = rpmtsiInit(s->ts); 00364 if (s->tsi == NULL) 00365 return NULL; 00366 s->tsiFilter = 0; 00367 } 00368 00369 te = rpmtsiNext(s->tsi, s->tsiFilter); 00370 /*@-branchstate@*/ 00371 if (te != NULL) { 00372 result = (PyObject *) rpmte_Wrap(te); 00373 } else { 00374 s->tsi = rpmtsiFree(s->tsi); 00375 s->tsiFilter = 0; 00376 } 00377 /*@=branchstate@*/ 00378 00379 return result; 00380 } 00381 00386 00389 /*@null@*/ 00390 static PyObject * 00391 rpmts_Debug(/*@unused@*/ rpmtsObject * s, PyObject * args, PyObject * kwds) 00392 /*@globals _Py_NoneStruct @*/ 00393 /*@modifies _Py_NoneStruct @*/ 00394 { 00395 char * kwlist[] = {"debugLevel", NULL}; 00396 00397 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Debug", kwlist, 00398 &_rpmts_debug)) 00399 return NULL; 00400 00401 if (_rpmts_debug < 0) 00402 fprintf(stderr, "*** rpmts_Debug(%p) ts %p\n", s, s->ts); 00403 00404 Py_INCREF(Py_None); 00405 return Py_None; 00406 } 00407 00410 /*@null@*/ 00411 static PyObject * 00412 rpmts_AddInstall(rpmtsObject * s, PyObject * args, PyObject * kwds) 00413 /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/ 00414 /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/ 00415 { 00416 hdrObject * h; 00417 PyObject * key; 00418 char * how = "u"; /* XXX default to upgrade element if missing */ 00419 int isUpgrade = 0; 00420 char * kwlist[] = {"header", "key", "how", NULL}; 00421 00422 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O|s:AddInstall", kwlist, 00423 &hdr_Type, &h, &key, &how)) 00424 return NULL; 00425 00426 { PyObject * hObj = (PyObject *) h; 00427 if (hObj->ob_type != &hdr_Type) { 00428 PyErr_SetString(PyExc_TypeError, "bad type for header argument"); 00429 return NULL; 00430 } 00431 } 00432 00433 if (_rpmts_debug < 0 || (_rpmts_debug > 0 && *how != 'a')) 00434 fprintf(stderr, "*** rpmts_AddInstall(%p,%p,%p,%s) ts %p\n", s, h, key, how, s->ts); 00435 00436 if (how && strcmp(how, "a") && strcmp(how, "u") && strcmp(how, "i")) { 00437 PyErr_SetString(PyExc_TypeError, "how argument must be \"u\", \"a\", or \"i\""); 00438 return NULL; 00439 } else if (how && !strcmp(how, "u")) 00440 isUpgrade = 1; 00441 00442 rpmtsAddInstallElement(s->ts, hdrGetHeader(h), key, isUpgrade, NULL); 00443 00444 /* This should increment the usage count for me */ 00445 if (key) 00446 PyList_Append(s->keyList, key); 00447 00448 Py_INCREF(Py_None); 00449 return Py_None; 00450 } 00451 00455 /*@null@*/ 00456 static PyObject * 00457 rpmts_AddErase(rpmtsObject * s, PyObject * args, PyObject * kwds) 00458 /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/ 00459 /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/ 00460 { 00461 PyObject * o; 00462 int count; 00463 rpmmi mi; 00464 char * kwlist[] = {"name", NULL}; 00465 00466 if (_rpmts_debug) 00467 fprintf(stderr, "*** rpmts_AddErase(%p) ts %p\n", s, s->ts); 00468 00469 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:AddErase", kwlist, &o)) 00470 return NULL; 00471 00472 if (PyString_Check(o) || PyUnicode_Check(o)) { 00473 char * name = PyString_AsString(o); 00474 00475 mi = rpmtsInitIterator(s->ts, RPMDBI_LABEL, name, 0); 00476 count = rpmmiCount(mi); 00477 if (count <= 0) { 00478 mi = rpmmiFree(mi); 00479 PyErr_SetString(pyrpmError, "package not installed"); 00480 return NULL; 00481 } else { /* XXX: Note that we automatically choose to remove all matches */ 00482 Header h; 00483 while ((h = rpmmiNext(mi)) != NULL) { 00484 unsigned int recOffset = rpmmiInstance(mi); 00485 if (recOffset) 00486 rpmtsAddEraseElement(s->ts, h, recOffset); 00487 } 00488 } 00489 mi = rpmmiFree(mi); 00490 } else 00491 if (PyInt_Check(o)) { 00492 uint32_t instance = PyInt_AsLong(o); 00493 00494 mi = rpmtsInitIterator(s->ts, RPMDBI_PACKAGES, &instance, sizeof(instance)); 00495 if (instance == 0 || mi == NULL) { 00496 mi = rpmmiFree(mi); 00497 PyErr_SetString(pyrpmError, "package not installed"); 00498 return NULL; 00499 } else { 00500 Header h; 00501 while ((h = rpmmiNext(mi)) != NULL) { 00502 uint32_t recOffset = rpmmiInstance(mi); 00503 if (recOffset) 00504 rpmtsAddEraseElement(s->ts, h, recOffset); 00505 break; 00506 } 00507 } 00508 mi = rpmmiFree(mi); 00509 } 00510 00511 Py_INCREF(Py_None); 00512 return Py_None; 00513 } 00514 00517 /*@null@*/ 00518 static PyObject * 00519 rpmts_Check(rpmtsObject * s, PyObject * args, PyObject * kwds) 00520 /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/ 00521 /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/ 00522 { 00523 rpmps ps; 00524 rpmProblem p; 00525 PyObject * list, * cf; 00526 struct rpmtsCallbackType_s cbInfo; 00527 int i; 00528 int xx; 00529 char * kwlist[] = {"callback", NULL}; 00530 00531 memset(&cbInfo, 0, sizeof(cbInfo)); 00532 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:Check", kwlist, 00533 &cbInfo.cb)) 00534 return NULL; 00535 00536 if (cbInfo.cb != NULL) { 00537 if (!PyCallable_Check(cbInfo.cb)) { 00538 PyErr_SetString(PyExc_TypeError, "expected a callable"); 00539 return NULL; 00540 } 00541 xx = rpmtsSetSolveCallback(s->ts, rpmts_SolveCallback, (void *)&cbInfo); 00542 } 00543 00544 if (_rpmts_debug) 00545 fprintf(stderr, "*** rpmts_Check(%p) ts %p cb %p\n", s, s->ts, cbInfo.cb); 00546 00547 cbInfo.tso = s; 00548 cbInfo.dso = NULL; /* XXX perhaps persistent? */ 00549 cbInfo._save = PyEval_SaveThread(); 00550 00551 xx = rpmtsCheck(s->ts); 00552 ps = rpmtsProblems(s->ts); 00553 00554 if (cbInfo.cb) 00555 xx = rpmtsSetSolveCallback(s->ts, rpmtsSolve, NULL); 00556 00557 PyEval_RestoreThread(cbInfo._save); 00558 00559 if (ps != NULL) { 00560 list = PyList_New(0); 00561 rpmpsi psi = rpmpsInitIterator(ps); 00562 00563 while ((i = rpmpsNextIterator(psi)) >= 0) { 00564 #ifdef DYING 00565 cf = Py_BuildValue("((sss)(ss)iOi)", conflicts[i].byName, 00566 conflicts[i].byVersion, conflicts[i].byRelease, 00567 00568 conflicts[i].needsName, 00569 conflicts[i].needsVersion, 00570 00571 conflicts[i].needsFlags, 00572 conflicts[i].suggestedPkgs ? 00573 conflicts[i].suggestedPkgs[0] : Py_None, 00574 conflicts[i].sense); 00575 #else 00576 char * byName, * byVersion, * byRelease, *byArch; 00577 char * needsName, * needsOP, * needsVersion; 00578 char * a, * b; 00579 int needsFlags, sense; 00580 fnpyKey key; 00581 00582 p = rpmpsProblem(psi); 00583 00584 /* XXX autorelocated i386 on ia64, fix system-config-packages! */ 00585 if (rpmProblemGetType(p) == RPMPROB_BADRELOCATE) 00586 continue; 00587 00588 a = byName = xstrdup(rpmProblemGetPkgNEVR(p)); 00589 if ((byArch= strrchr(byName, '.')) != NULL) 00590 *byArch++ = '\0'; 00591 if ((byRelease = strrchr(byName, '-')) != NULL) 00592 *byRelease++ = '\0'; 00593 if ((byVersion = strrchr(byName, '-')) != NULL) 00594 *byVersion++ = '\0'; 00595 00596 key = rpmProblemKey(p); 00597 00598 b = needsName = xstrdup(rpmProblemGetAltNEVR(p)); 00599 if (needsName[1] == ' ') { 00600 sense = (needsName[0] == 'C') 00601 ? RPMDEP_SENSE_CONFLICTS : RPMDEP_SENSE_REQUIRES; 00602 needsName += 2; 00603 } else 00604 sense = RPMDEP_SENSE_REQUIRES; 00605 if ((needsVersion = strrchr(needsName, ' ')) != NULL) 00606 *needsVersion++ = '\0'; 00607 00608 needsFlags = 0; 00609 if ((needsOP = strrchr(needsName, ' ')) != NULL) { 00610 for (*needsOP++ = '\0'; *needsOP != '\0'; needsOP++) { 00611 if (*needsOP == '<') needsFlags |= RPMSENSE_LESS; 00612 else if (*needsOP == '>') needsFlags |= RPMSENSE_GREATER; 00613 else if (*needsOP == '=') needsFlags |= RPMSENSE_EQUAL; 00614 } 00615 } 00616 00617 cf = Py_BuildValue("((sss)(ss)iOi)", byName, byVersion, byRelease, 00618 needsName, needsVersion, needsFlags, 00619 (key != NULL ? key : Py_None), 00620 sense); 00621 a = _free(a); 00622 b = _free(b); 00623 #endif 00624 PyList_Append(list, (PyObject *) cf); 00625 Py_DECREF(cf); 00626 } 00627 00628 psi = rpmpsFreeIterator(psi); 00629 ps = rpmpsFree(ps); 00630 00631 return list; 00632 } 00633 00634 Py_INCREF(Py_None); 00635 return Py_None; 00636 } 00637 00640 /*@null@*/ 00641 static PyObject * 00642 rpmts_Order(rpmtsObject * s) 00643 /*@globals rpmGlobalMacroContext @*/ 00644 /*@modifies s, rpmGlobalMacroContext @*/ 00645 { 00646 int rc; 00647 00648 if (_rpmts_debug) 00649 fprintf(stderr, "*** rpmts_Order(%p) ts %p\n", s, s->ts); 00650 00651 Py_BEGIN_ALLOW_THREADS 00652 rc = rpmtsOrder(s->ts); 00653 Py_END_ALLOW_THREADS 00654 00655 return Py_BuildValue("i", rc); 00656 } 00657 00660 /*@null@*/ 00661 static PyObject * 00662 rpmts_Clean(rpmtsObject * s) 00663 /*@globals _Py_NoneStruct @*/ 00664 /*@modifies s, _Py_NoneStruct @*/ 00665 { 00666 if (_rpmts_debug) 00667 fprintf(stderr, "*** rpmts_Clean(%p) ts %p\n", s, s->ts); 00668 00669 rpmtsClean(s->ts); 00670 00671 Py_INCREF(Py_None); 00672 return Py_None; 00673 } 00674 00677 /*@null@*/ 00678 static PyObject * 00679 rpmts_IDTXload(rpmtsObject * s, PyObject * args, PyObject * kwds) 00680 /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/ 00681 /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/ 00682 { 00683 PyObject * result = NULL; 00684 rpmTag tag = RPMTAG_INSTALLTID; 00685 char * kwlist[] = {"rbtid", NULL}; 00686 uint32_t rbtid = 0; 00687 IDTX idtx; 00688 00689 if (_rpmts_debug) 00690 fprintf(stderr, "*** rpmts_IDTXload(%p) ts %p\n", s, s->ts); 00691 00692 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:IDTXload", kwlist, &rbtid)) 00693 return NULL; 00694 00695 Py_BEGIN_ALLOW_THREADS 00696 idtx = IDTXload(s->ts, tag, rbtid); 00697 Py_END_ALLOW_THREADS 00698 00699 /*@-branchstate@*/ 00700 if (idtx == NULL || idtx->nidt <= 0) { 00701 Py_INCREF(Py_None); 00702 result = Py_None; 00703 } else { 00704 PyObject * tuple; 00705 PyObject * ho; 00706 IDT idt; 00707 int i; 00708 00709 result = PyTuple_New(idtx->nidt); 00710 for (i = 0; i < idtx->nidt; i++) { 00711 idt = idtx->idt + i; 00712 ho = (PyObject *) hdr_Wrap(idt->h); 00713 tuple = Py_BuildValue("(iOi)", idt->val.u32, ho, idt->instance); 00714 PyTuple_SET_ITEM(result, i, tuple); 00715 Py_DECREF(ho); 00716 } 00717 } 00718 /*@=branchstate@*/ 00719 00720 idtx = IDTXfree(idtx); 00721 00722 return result; 00723 } 00724 00727 /*@null@*/ 00728 static PyObject * 00729 rpmts_IDTXglob(rpmtsObject * s, PyObject * args, PyObject * kwds) 00730 /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/ 00731 /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/ 00732 { 00733 PyObject * result = NULL; 00734 const char * globstr; 00735 rpmTag tag = RPMTAG_REMOVETID; 00736 char * kwlist[] = {"rbtid", NULL}; 00737 uint32_t rbtid = 0; 00738 IDTX idtx; 00739 00740 if (_rpmts_debug) 00741 fprintf(stderr, "*** rpmts_IDTXglob(%p) ts %p\n", s, s->ts); 00742 00743 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:IDTXglob", kwlist, &rbtid)) 00744 return NULL; 00745 00746 Py_BEGIN_ALLOW_THREADS 00747 globstr = rpmExpand("%{_repackage_dir}/*.rpm", NULL); 00748 idtx = IDTXglob(s->ts, globstr, tag, rbtid); 00749 globstr = _free(globstr); 00750 Py_END_ALLOW_THREADS 00751 00752 /*@-branchstate@*/ 00753 if (idtx == NULL || idtx->nidt <= 0) { 00754 Py_INCREF(Py_None); 00755 result = Py_None; 00756 } else { 00757 PyObject * tuple; 00758 PyObject * ho; 00759 IDT idt; 00760 int i; 00761 00762 result = PyTuple_New(idtx->nidt); 00763 for (i = 0; i < idtx->nidt; i++) { 00764 idt = idtx->idt + i; 00765 ho = (PyObject *) hdr_Wrap(idt->h); 00766 tuple = Py_BuildValue("(iOs)", idt->val.u32, ho, idt->key); 00767 PyTuple_SET_ITEM(result, i, tuple); 00768 Py_DECREF(ho); 00769 } 00770 } 00771 /*@=branchstate@*/ 00772 00773 idtx = IDTXfree(idtx); 00774 00775 return result; 00776 } 00777 00780 /*@null@*/ 00781 static PyObject * 00782 rpmts_Rollback(rpmtsObject * s, PyObject * args, PyObject * kwds) 00783 /*@globals rpmGlobalMacroContext @*/ 00784 /*@modifies s, rpmGlobalMacroContext @*/ 00785 { 00786 QVA_t ia = memset(alloca(sizeof(*ia)), 0, sizeof(*ia)); 00787 rpmtransFlags transFlags; 00788 const char ** av = NULL; 00789 uint32_t rbtid; 00790 int rc; 00791 char * kwlist[] = {"transactionId", NULL}; 00792 00793 if (_rpmts_debug) 00794 fprintf(stderr, "*** rpmts_Rollback(%p) ts %p\n", s, s->ts); 00795 00796 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Rollback", kwlist, &rbtid)) 00797 return NULL; 00798 00799 Py_BEGIN_ALLOW_THREADS 00800 ia->qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE|VERIFY_HDRCHK); 00801 ia->transFlags |= (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL); 00802 ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS; 00803 ia->installInterfaceFlags = (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL); 00804 ia->rbtid = rbtid; 00805 ia->relocations = NULL; 00806 ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE; 00807 00808 transFlags = rpmtsSetFlags(s->ts, ia->transFlags); 00809 rc = rpmRollback(s->ts, ia, av); 00810 transFlags = rpmtsSetFlags(s->ts, transFlags); 00811 Py_END_ALLOW_THREADS 00812 00813 return Py_BuildValue("i", rc); 00814 } 00815 00818 /*@null@*/ 00819 static PyObject * 00820 rpmts_OpenDB(rpmtsObject * s) 00821 /*@globals rpmGlobalMacroContext @*/ 00822 /*@modifies s, rpmGlobalMacroContext @*/ 00823 { 00824 00825 if (_rpmts_debug) 00826 fprintf(stderr, "*** rpmts_OpenDB(%p) ts %p\n", s, s->ts); 00827 00828 if (rpmtsDBMode(s->ts) == -1) 00829 (void) rpmtsSetDBMode(s->ts, O_RDONLY); 00830 00831 return Py_BuildValue("i", rpmtsOpenDB(s->ts, rpmtsDBMode(s->ts))); 00832 } 00833 00836 /*@null@*/ 00837 static PyObject * 00838 rpmts_CloseDB(rpmtsObject * s) 00839 /*@modifies s @*/ 00840 { 00841 int rc; 00842 00843 if (_rpmts_debug) 00844 fprintf(stderr, "*** rpmts_CloseDB(%p) ts %p\n", s, s->ts); 00845 00846 rc = rpmtsCloseDB(s->ts); 00847 (void) rpmtsSetDBMode(s->ts, -1); /* XXX disable lazy opens */ 00848 00849 return Py_BuildValue("i", rc); 00850 } 00851 00854 /*@null@*/ 00855 static PyObject * 00856 rpmts_InitDB(rpmtsObject * s) 00857 /*@globals rpmGlobalMacroContext @*/ 00858 /*@modifies s, rpmGlobalMacroContext @*/ 00859 { 00860 int rc; 00861 00862 if (_rpmts_debug) 00863 fprintf(stderr, "*** rpmts_InitDB(%p) ts %p\n", s, s->ts); 00864 00865 rc = rpmtsInitDB(s->ts, O_RDONLY); 00866 if (rc == 0) 00867 rc = rpmtsCloseDB(s->ts); 00868 00869 return Py_BuildValue("i", rc); 00870 } 00871 00874 /*@null@*/ 00875 static PyObject * 00876 rpmts_RebuildDB(rpmtsObject * s) 00877 /*@globals rpmGlobalMacroContext @*/ 00878 /*@modifies s, rpmGlobalMacroContext @*/ 00879 { 00880 int rc; 00881 00882 if (_rpmts_debug) 00883 fprintf(stderr, "*** rpmts_RebuildDB(%p) ts %p\n", s, s->ts); 00884 00885 Py_BEGIN_ALLOW_THREADS 00886 rc = rpmtsRebuildDB(s->ts); 00887 Py_END_ALLOW_THREADS 00888 00889 return Py_BuildValue("i", rc); 00890 } 00891 00894 /*@null@*/ 00895 static PyObject * 00896 rpmts_VerifyDB(rpmtsObject * s) 00897 /*@globals rpmGlobalMacroContext @*/ 00898 /*@modifies s, rpmGlobalMacroContext @*/ 00899 { 00900 int rc; 00901 00902 if (_rpmts_debug) 00903 fprintf(stderr, "*** rpmts_VerifyDB(%p) ts %p\n", s, s->ts); 00904 00905 Py_BEGIN_ALLOW_THREADS 00906 rc = rpmtsVerifyDB(s->ts); 00907 Py_END_ALLOW_THREADS 00908 00909 return Py_BuildValue("i", rc); 00910 } 00911 00914 /*@null@*/ 00915 static PyObject * 00916 rpmts_HdrFromFdno(rpmtsObject * s, PyObject * args, PyObject * kwds) 00917 /*@globals rpmGlobalMacroContext, fileSystem @*/ 00918 /*@modifies s, rpmGlobalMacroContext, fileSystem @*/ 00919 { 00920 PyObject * result = NULL; 00921 Header h; 00922 FD_t fd; 00923 int fdno; 00924 rpmRC rpmrc; 00925 char * kwlist[] = {"fd", NULL}; 00926 00927 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:HdrFromFdno", kwlist, 00928 &fdno)) 00929 return NULL; 00930 00931 fd = fdDup(fdno); 00932 rpmrc = rpmReadPackageFile(s->ts, fd, "rpmts_HdrFromFdno", &h); 00933 Fclose(fd); 00934 00935 if (_rpmts_debug) 00936 fprintf(stderr, "*** rpmts_HdrFromFdno(%p) ts %p rc %d\n", s, s->ts, rpmrc); 00937 00938 /*@-branchstate@*/ 00939 switch (rpmrc) { 00940 case RPMRC_OK: 00941 if (h) 00942 result = Py_BuildValue("N", hdr_Wrap(h)); 00943 (void)headerFree(h); /* XXX ref held by result */ 00944 h = NULL; 00945 break; 00946 00947 case RPMRC_NOKEY: 00948 PyErr_SetString(pyrpmError, "public key not available"); 00949 break; 00950 00951 case RPMRC_NOTTRUSTED: 00952 PyErr_SetString(pyrpmError, "public key not trusted"); 00953 break; 00954 00955 case RPMRC_NOTFOUND: 00956 case RPMRC_FAIL: 00957 default: 00958 PyErr_SetString(pyrpmError, "error reading package header"); 00959 break; 00960 } 00961 /*@=branchstate@*/ 00962 00963 return result; 00964 } 00965 00968 /*@null@*/ 00969 static PyObject * 00970 rpmts_HdrCheck(rpmtsObject * s, PyObject * args, PyObject * kwds) 00971 /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/ 00972 /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/ 00973 { 00974 PyObject * blob; 00975 PyObject * result = NULL; 00976 const char * msg = NULL; 00977 const void * uh; 00978 int uc; 00979 pgpDig dig; 00980 rpmRC rpmrc; 00981 char * kwlist[] = {"headers", NULL}; 00982 00983 if (_rpmts_debug) 00984 fprintf(stderr, "*** rpmts_HdrCheck(%p) ts %p\n", s, s->ts); 00985 00986 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:HdrCheck", kwlist, &blob)) 00987 return NULL; 00988 00989 if (blob == Py_None) { 00990 Py_INCREF(Py_None); 00991 return Py_None; 00992 } 00993 if (!(PyString_Check(blob) || PyUnicode_Check(blob))) { 00994 PyErr_SetString(pyrpmError, "hdrCheck takes a string of octets"); 00995 return result; 00996 } 00997 uh = PyString_AsString(blob); 00998 uc = PyString_Size(blob); 00999 01000 dig = pgpDigNew(rpmtsVSFlags(s->ts)); 01001 rpmrc = headerCheck(dig, uh, uc, &msg); 01002 dig = pgpDigFree(dig, "rpmts_HdrCheck"); 01003 01004 switch (rpmrc) { 01005 case RPMRC_OK: 01006 Py_INCREF(Py_None); 01007 result = Py_None; 01008 break; 01009 01010 case RPMRC_NOKEY: 01011 /* XXX note "availaiable", the script kiddies need the misspelling. */ 01012 PyErr_SetString(pyrpmError, "public key not availaiable"); 01013 break; 01014 01015 case RPMRC_NOTTRUSTED: 01016 PyErr_SetString(pyrpmError, "public key not trusted"); 01017 break; 01018 01019 case RPMRC_FAIL: 01020 default: 01021 PyErr_SetString(pyrpmError, msg); 01022 break; 01023 } 01024 msg = _free(msg); 01025 01026 return result; 01027 } 01028 01031 static PyObject * 01032 rpmts_GetVSFlags(rpmtsObject * s) 01033 { 01034 return Py_BuildValue("i", rpmtsVSFlags(s->ts)); 01035 } 01036 01039 /*@null@*/ 01040 static PyObject * 01041 rpmts_SetVSFlags(rpmtsObject * s, PyObject * args, PyObject * kwds) 01042 /*@modifies s @*/ 01043 { 01044 rpmVSFlags vsflags; 01045 char * kwlist[] = {"flags", NULL}; 01046 01047 if (_rpmts_debug) 01048 fprintf(stderr, "*** rpmts_SetVSFlags(%p) ts %p\n", s, s->ts); 01049 01050 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetVSFlags", kwlist, 01051 &vsflags)) 01052 return NULL; 01053 01054 /* XXX FIXME: value check on vsflags, or build pure python object 01055 * for it, and require an object of that type */ 01056 01057 return Py_BuildValue("i", rpmtsSetVSFlags(s->ts, vsflags)); 01058 } 01059 01062 /*@null@*/ 01063 static PyObject * 01064 rpmts_SetColor(rpmtsObject * s, PyObject * args, PyObject * kwds) 01065 /*@modifies s @*/ 01066 { 01067 uint32_t tscolor; 01068 char * kwlist[] = {"color", NULL}; 01069 01070 if (_rpmts_debug) 01071 fprintf(stderr, "*** rpmts_SetColor(%p) ts %p\n", s, s->ts); 01072 01073 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Color", kwlist, &tscolor)) 01074 return NULL; 01075 01076 /* XXX FIXME: value check on tscolor, or build pure python object 01077 * for it, and require an object of that type */ 01078 01079 return Py_BuildValue("i", rpmtsSetColor(s->ts, tscolor)); 01080 } 01081 01084 /*@null@*/ 01085 static PyObject * 01086 rpmts_PgpPrtPkts(rpmtsObject * s, PyObject * args, PyObject * kwds) 01087 /*@globals _Py_NoneStruct @*/ 01088 /*@modifies _Py_NoneStruct @*/ 01089 { 01090 PyObject * blob; 01091 unsigned char * pkt; 01092 unsigned int pktlen; 01093 int rc; 01094 char * kwlist[] = {"octets", NULL}; 01095 01096 if (_rpmts_debug) 01097 fprintf(stderr, "*** rpmts_PgpPrtPkts(%p) ts %p\n", s, s->ts); 01098 01099 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:PgpPrtPkts", kwlist, &blob)) 01100 return NULL; 01101 01102 if (blob == Py_None) { 01103 Py_INCREF(Py_None); 01104 return Py_None; 01105 } 01106 if (!(PyString_Check(blob) || PyUnicode_Check(blob))) { 01107 PyErr_SetString(pyrpmError, "pgpPrtPkts takes a string of octets"); 01108 return NULL; 01109 } 01110 pkt = (unsigned char *) PyString_AsString(blob); 01111 pktlen = PyString_Size(blob); 01112 01113 rc = pgpPrtPkts(pkt, pktlen, NULL, 1); 01114 01115 return Py_BuildValue("i", rc); 01116 } 01117 01120 /*@null@*/ 01121 static PyObject * 01122 rpmts_PgpImportPubkey(rpmtsObject * s, PyObject * args, PyObject * kwds) 01123 /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/ 01124 /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/ 01125 { 01126 PyObject * blob; 01127 unsigned char * pkt; 01128 unsigned int pktlen; 01129 int rc; 01130 char * kwlist[] = {"pubkey", NULL}; 01131 01132 if (_rpmts_debug) 01133 fprintf(stderr, "*** rpmts_PgpImportPubkey(%p) ts %p\n", s, s->ts); 01134 01135 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:PgpImportPubkey", 01136 kwlist, &blob)) 01137 return NULL; 01138 01139 if (blob == Py_None) { 01140 Py_INCREF(Py_None); 01141 return Py_None; 01142 } 01143 if (!(PyString_Check(blob) || PyUnicode_Check(blob))) { 01144 PyErr_SetString(pyrpmError, "PgpImportPubkey takes a string of octets"); 01145 return NULL; 01146 } 01147 pkt = (unsigned char *) PyString_AsString(blob); 01148 pktlen = PyString_Size(blob); 01149 01150 rc = rpmcliImportPubkey(s->ts, pkt, pktlen); 01151 01152 return Py_BuildValue("i", rc); 01153 } 01154 01157 static PyObject * 01158 rpmts_SetFlags(rpmtsObject * s, PyObject * args, PyObject * kwds) 01159 /*@modifies s @*/ 01160 { 01161 rpmtransFlags transFlags = 0; 01162 char * kwlist[] = {"flags", NULL}; 01163 01164 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetFlags", kwlist, 01165 &transFlags)) 01166 return NULL; 01167 01168 if (_rpmts_debug) 01169 fprintf(stderr, "*** rpmts_SetFlags(%p) ts %p transFlags 0x%x\n", s, s->ts, transFlags); 01170 01171 /* XXX FIXME: value check on flags, or build pure python object 01172 * for it, and require an object of that type */ 01173 01174 return Py_BuildValue("i", rpmtsSetFlags(s->ts, transFlags)); 01175 } 01176 01179 static PyObject * 01180 rpmts_SetDFlags(rpmtsObject * s, PyObject * args, PyObject * kwds) 01181 /*@modifies s @*/ 01182 { 01183 rpmdepFlags depFlags = 0; 01184 char * kwlist[] = {"flags", NULL}; 01185 01186 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetDFlags", kwlist, 01187 &depFlags)) 01188 return NULL; 01189 01190 if (_rpmts_debug) 01191 fprintf(stderr, "*** rpmts_SetDFlags(%p) ts %p depFlags 0x%x\n", s, s->ts, depFlags); 01192 01193 /* XXX FIXME: value check on flags, or build pure python object 01194 * for it, and require an object of that type */ 01195 01196 return Py_BuildValue("i", rpmtsSetDFlags(s->ts, depFlags)); 01197 } 01198 01201 static PyObject * 01202 rpmts_SetProbFilter(rpmtsObject * s, PyObject * args, PyObject * kwds) 01203 /*@modifies s @*/ 01204 { 01205 rpmprobFilterFlags ignoreSet = 0; 01206 rpmprobFilterFlags oignoreSet = 0; 01207 char * kwlist[] = {"ignoreSet", NULL}; 01208 01209 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:ProbFilter", kwlist, 01210 &ignoreSet)) 01211 return NULL; 01212 01213 if (_rpmts_debug) 01214 fprintf(stderr, "*** rpmts_SetProbFilter(%p) ts %p ignoreSet %x\n", s, s->ts, ignoreSet); 01215 01216 oignoreSet = s->ignoreSet; 01217 s->ignoreSet = ignoreSet; 01218 01219 return Py_BuildValue("i", oignoreSet); 01220 } 01221 01224 /*@null@*/ 01225 static rpmpsObject * 01226 rpmts_Problems(rpmtsObject * s) 01227 /*@modifies s @*/ 01228 { 01229 01230 if (_rpmts_debug) 01231 fprintf(stderr, "*** rpmts_Problems(%p) ts %p\n", s, s->ts); 01232 01233 return rpmps_Wrap( rpmtsProblems(s->ts) ); 01234 } 01235 01238 static PyObject * 01239 rpmts_Run(rpmtsObject * s, PyObject * args, PyObject * kwds) 01240 /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/ 01241 /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/ 01242 { 01243 int rc; 01244 PyObject * list; 01245 rpmps ps; 01246 rpmpsi psi; 01247 struct rpmtsCallbackType_s cbInfo; 01248 char * kwlist[] = {"callback", "data", NULL}; 01249 01250 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO:Run", kwlist, 01251 &cbInfo.cb, &cbInfo.data)) 01252 return NULL; 01253 01254 cbInfo.tso = s; 01255 cbInfo.dso = NULL; 01256 cbInfo._save = PyEval_SaveThread(); 01257 01258 if (cbInfo.cb != NULL) { 01259 if (!PyCallable_Check(cbInfo.cb)) { 01260 PyErr_SetString(PyExc_TypeError, "expected a callable"); 01261 return NULL; 01262 } 01263 (void) rpmtsSetNotifyCallback(s->ts, rpmtsCallback, (void *) &cbInfo); 01264 } 01265 01266 if (_rpmts_debug) 01267 fprintf(stderr, "*** rpmts_Run(%p) ts %p ignore %x\n", s, s->ts, s->ignoreSet); 01268 01269 rc = rpmtsRun(s->ts, NULL, s->ignoreSet); 01270 ps = rpmtsProblems(s->ts); 01271 01272 if (cbInfo.cb) 01273 (void) rpmtsSetNotifyCallback(s->ts, NULL, NULL); 01274 01275 PyEval_RestoreThread(cbInfo._save); 01276 01277 if (rc < 0) { 01278 list = PyList_New(0); 01279 return list; 01280 } else if (!rc) { 01281 Py_INCREF(Py_None); 01282 return Py_None; 01283 } 01284 01285 list = PyList_New(0); 01286 psi = rpmpsInitIterator(ps); 01287 while (rpmpsNextIterator(psi) >= 0) { 01288 rpmProblem p = rpmpsProblem(psi); 01289 PyObject * prob = Py_BuildValue("s(isN)", rpmProblemString(p), 01290 rpmProblemGetType(p), 01291 rpmProblemGetStr(p), 01292 PyLong_FromLongLong(rpmProblemGetDiskNeed(p))); 01293 PyList_Append(list, prob); 01294 Py_DECREF(prob); 01295 } 01296 psi = rpmpsFreeIterator(psi); 01297 01298 ps = rpmpsFree(ps); 01299 01300 return list; 01301 } 01302 01306 static PyObject * 01307 rpmts_Next(rpmtsObject * s) 01308 /*@globals _Py_NoneStruct @*/ 01309 /*@modifies s, _Py_NoneStruct @*/ 01310 { 01311 PyObject * result; 01312 01313 if (_rpmts_debug) 01314 fprintf(stderr, "*** rpmts_Next(%p) ts %p\n", s, s->ts); 01315 01316 result = rpmts_iternext(s); 01317 01318 if (result == NULL) { 01319 Py_INCREF(Py_None); 01320 return Py_None; 01321 } 01322 01323 return result; 01324 } 01325 01328 /*@null@*/ 01329 static specObject * 01330 spec_Parse(rpmtsObject * s, PyObject * args, PyObject * kwds) 01331 /*@globals rpmGlobalMacroContext @*/ 01332 /*@modifies s, rpmGlobalMacroContext @*/ 01333 { 01334 const char * specfile; 01335 Spec spec; 01336 int recursing = 0; 01337 char * passPhrase = ""; 01338 char *cookie = NULL; 01339 int anyarch = 1; 01340 int verify = 1; 01341 int force = 1; 01342 char * kwlist[] = {"specfile", NULL}; 01343 01344 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:Parse", kwlist, &specfile)) 01345 return NULL; 01346 01347 if (parseSpec(s->ts, specfile,"/", recursing, passPhrase, 01348 cookie, anyarch, force, verify)!=0) { 01349 PyErr_SetString(pyrpmError, "can't parse specfile\n"); 01350 return NULL; 01351 } 01352 01353 spec = rpmtsSpec(s->ts); 01354 return spec_Wrap(spec); 01355 } 01356 01359 /*@null@*/ 01360 static rpmmiObject * 01361 rpmts_Match(rpmtsObject * s, PyObject * args, PyObject * kwds) 01362 /*@globals rpmGlobalMacroContext @*/ 01363 /*@modifies s, rpmGlobalMacroContext @*/ 01364 { 01365 PyObject *TagN = NULL; 01366 PyObject *Key = NULL; 01367 char *key = NULL; 01368 /* XXX lkey *must* be a 32 bit integer, int "works" on all known platforms. */ 01369 int lkey = 0; 01370 int len = 0; 01371 int tag = RPMDBI_PACKAGES; 01372 char * kwlist[] = {"tagNumber", "key", NULL}; 01373 01374 if (_rpmts_debug) 01375 fprintf(stderr, "*** rpmts_Match(%p) ts %p\n", s, s->ts); 01376 01377 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:Match", kwlist, 01378 &TagN, &Key)) 01379 return NULL; 01380 01381 if (TagN && (tag = tagNumFromPyObject (TagN)) == -1) { 01382 PyErr_SetString(PyExc_TypeError, "unknown tag type"); 01383 return NULL; 01384 } 01385 01386 if (Key) { 01387 /*@-branchstate@*/ 01388 if (PyString_Check(Key) || PyUnicode_Check(Key)) { 01389 key = PyString_AsString(Key); 01390 len = PyString_Size(Key); 01391 } else if (PyInt_Check(Key)) { 01392 lkey = PyInt_AsLong(Key); 01393 key = (char *)&lkey; 01394 len = sizeof(lkey); 01395 } else { 01396 PyErr_SetString(PyExc_TypeError, "unknown key type"); 01397 return NULL; 01398 } 01399 /*@=branchstate@*/ 01400 } 01401 01402 /* XXX If not already opened, open the database O_RDONLY now. */ 01403 /* XXX FIXME: lazy default rdonly open also done by rpmtsInitIterator(). */ 01404 if (rpmtsGetRdb(s->ts) == NULL) { 01405 int rc = rpmtsOpenDB(s->ts, O_RDONLY); 01406 if (rc || rpmtsGetRdb(s->ts) == NULL) { 01407 PyErr_SetString(PyExc_TypeError, "rpmdb open failed"); 01408 return NULL; 01409 } 01410 } 01411 01412 return rpmmi_Wrap( rpmtsInitIterator(s->ts, tag, key, len) ); 01413 } 01414 01419 /*@-fullinitblock@*/ 01420 /*@unchecked@*/ /*@observer@*/ 01421 static struct PyMethodDef rpmts_methods[] = { 01422 {"Debug", (PyCFunction)rpmts_Debug, METH_VARARGS|METH_KEYWORDS, 01423 NULL}, 01424 01425 {"addInstall", (PyCFunction) rpmts_AddInstall, METH_VARARGS|METH_KEYWORDS, 01426 NULL }, 01427 {"addErase", (PyCFunction) rpmts_AddErase, METH_VARARGS|METH_KEYWORDS, 01428 NULL }, 01429 {"setDFlags", (PyCFunction) rpmts_SetDFlags, METH_VARARGS|METH_KEYWORDS, 01430 "ts.setDFlags(depFlags) -> previous depFlags\n\ 01431 - Set control bit(s) for executing ts.check() and ts.order().\n" }, 01432 {"check", (PyCFunction) rpmts_Check, METH_VARARGS|METH_KEYWORDS, 01433 NULL }, 01434 {"order", (PyCFunction) rpmts_Order, METH_NOARGS, 01435 NULL }, 01436 {"setFlags", (PyCFunction) rpmts_SetFlags, METH_VARARGS|METH_KEYWORDS, 01437 "ts.setFlags(transFlags) -> previous transFlags\n\ 01438 - Set control bit(s) for executing ts.run().\n\ 01439 Note: This method replaces the 1st argument to the old ts.run()\n" }, 01440 {"setProbFilter", (PyCFunction) rpmts_SetProbFilter, METH_VARARGS|METH_KEYWORDS, 01441 "ts.setProbFilter(ignoreSet) -> previous ignoreSet\n\ 01442 - Set control bit(s) for ignoring problems found by ts.run().\n\ 01443 Note: This method replaces the 2nd argument to the old ts.run()\n" }, 01444 {"problems", (PyCFunction) rpmts_Problems, METH_NOARGS, 01445 "ts.problems() -> ps\n\ 01446 - Return current problem set.\n" }, 01447 {"run", (PyCFunction) rpmts_Run, METH_VARARGS|METH_KEYWORDS, 01448 "ts.run(callback, data) -> (problems)\n\ 01449 - Run a transaction set, returning list of problems found.\n\ 01450 Note: The callback may not be None.\n" }, 01451 {"clean", (PyCFunction) rpmts_Clean, METH_NOARGS, 01452 NULL }, 01453 {"IDTXload", (PyCFunction) rpmts_IDTXload, METH_VARARGS|METH_KEYWORDS, 01454 "ts.IDTXload(rbtid=iid) -> ((tid,hdr,instance)+)\n\ 01455 - Return list of installed packages reverse sorted by transaction id.\n" }, 01456 {"IDTXglob", (PyCFunction) rpmts_IDTXglob, METH_VARARGS|METH_KEYWORDS, 01457 "ts.IDTXglob(rbtid=rid) -> ((tid,hdr,instance)+)\n\ 01458 - Return list of removed packages reverse sorted by transaction id.\n" }, 01459 {"rollback", (PyCFunction) rpmts_Rollback, METH_VARARGS|METH_KEYWORDS, 01460 NULL }, 01461 {"openDB", (PyCFunction) rpmts_OpenDB, METH_NOARGS, 01462 "ts.openDB() -> None\n\ 01463 - Open the default transaction rpmdb.\n\ 01464 Note: The transaction rpmdb is lazily opened, so ts.openDB() is seldom needed.\n" }, 01465 {"closeDB", (PyCFunction) rpmts_CloseDB, METH_NOARGS, 01466 "ts.closeDB() -> None\n\ 01467 - Close the default transaction rpmdb.\n\ 01468 Note: ts.closeDB() disables lazy opens, and should hardly ever be used.\n" }, 01469 {"initDB", (PyCFunction) rpmts_InitDB, METH_NOARGS, 01470 "ts.initDB() -> None\n\ 01471 - Initialize the default transaction rpmdb.\n\ 01472 Note: ts.initDB() is seldom needed anymore.\n" }, 01473 {"rebuildDB", (PyCFunction) rpmts_RebuildDB, METH_NOARGS, 01474 "ts.rebuildDB() -> None\n\ 01475 - Rebuild the default transaction rpmdb.\n" }, 01476 {"verifyDB", (PyCFunction) rpmts_VerifyDB, METH_NOARGS, 01477 "ts.verifyDB() -> None\n\ 01478 - Verify the default transaction rpmdb.\n" }, 01479 {"hdrFromFdno",(PyCFunction) rpmts_HdrFromFdno,METH_VARARGS|METH_KEYWORDS, 01480 "ts.hdrFromFdno(fdno) -> hdr\n\ 01481 - Read a package header from a file descriptor.\n" }, 01482 {"hdrCheck", (PyCFunction) rpmts_HdrCheck, METH_VARARGS|METH_KEYWORDS, 01483 NULL }, 01484 {"getVSFlags",(PyCFunction) rpmts_GetVSFlags, METH_NOARGS, 01485 "ts.getVSFlags() -> vsflags\n\ 01486 - Retrieve current signature verification flags from transaction\n" }, 01487 {"setVSFlags",(PyCFunction) rpmts_SetVSFlags, METH_VARARGS|METH_KEYWORDS, 01488 "ts.setVSFlags(vsflags) -> ovsflags\n\ 01489 - Set signature verification flags. Values for vsflags are:\n\ 01490 rpm.RPMVSF_NOHDRCHK if set, don't check rpmdb headers\n\ 01491 rpm.RPMVSF_NEEDPAYLOAD if not set, check header+payload (if possible)\n\ 01492 rpm.RPMVSF_NOSHA1HEADER if set, don't check header SHA1 digest\n\ 01493 rpm.RPMVSF_NODSAHEADER if set, don't check header DSA signature\n\ 01494 rpm.RPMVSF_NORSAHEADER if set, don't check header RSA signature\n\ 01495 rpm.RPMVSF_NOMD5 if set, don't check header+payload MD5 digest\n\ 01496 rpm.RPMVSF_NODSA if set, don't check header+payload DSA signature\n\ 01497 rpm.RPMVSF_NORSA if set, don't check header+payload RSA signature\n\ 01498 rpm._RPMVSF_NODIGESTS if set, don't check digest(s)\n\ 01499 rpm._RPMVSF_NOSIGNATURES if set, don't check signature(s)\n" }, 01500 {"setColor",(PyCFunction) rpmts_SetColor, METH_VARARGS|METH_KEYWORDS, 01501 NULL }, 01502 {"pgpPrtPkts", (PyCFunction) rpmts_PgpPrtPkts, METH_VARARGS|METH_KEYWORDS, 01503 NULL }, 01504 {"pgpImportPubkey", (PyCFunction) rpmts_PgpImportPubkey, METH_VARARGS|METH_KEYWORDS, 01505 NULL }, 01506 {"parseSpec", (PyCFunction) spec_Parse, METH_VARARGS|METH_KEYWORDS, 01507 "ts.parseSpec(\"/path/to/foo.spec\") -> spec\n\ 01508 - Parse a spec file.\n" }, 01509 {"dbMatch", (PyCFunction) rpmts_Match, METH_VARARGS|METH_KEYWORDS, 01510 "ts.dbMatch([TagN, [key, [len]]]) -> mi\n\ 01511 - Create a match iterator for the default transaction rpmdb.\n" }, 01512 {"next", (PyCFunction)rpmts_Next, METH_NOARGS, 01513 "ts.next() -> te\n\ 01514 - Retrieve next transaction set element.\n" }, 01515 {NULL, NULL} /* sentinel */ 01516 }; 01517 /*@=fullinitblock@*/ 01518 01521 static void rpmts_dealloc(/*@only@*/ rpmtsObject * s) 01522 /*@modifies *s @*/ 01523 { 01524 01525 if (_rpmts_debug) 01526 fprintf(stderr, "%p -- ts %p db %p\n", s, s->ts, rpmtsGetRdb(s->ts)); 01527 (void)rpmtsFree(s->ts); 01528 s->ts = NULL; 01529 01530 if (s->scriptFd) Fclose(s->scriptFd); 01531 /* this will free the keyList, and decrement the ref count of all 01532 the items on the list as well :-) */ 01533 Py_DECREF(s->keyList); 01534 PyObject_Del((PyObject *)s); 01535 } 01536 01537 static PyObject * rpmts_getattro(PyObject * o, PyObject * n) 01538 /*@*/ 01539 { 01540 return PyObject_GenericGetAttr(o, n); 01541 } 01542 01545 static int rpmts_setattro(PyObject * o, PyObject * n, PyObject * v) 01546 /*@*/ 01547 { 01548 rpmtsObject *s = (rpmtsObject *)o; 01549 char * name = PyString_AsString(n); 01550 int fdno; 01551 01552 if (!strcmp(name, "scriptFd")) { 01553 if (!PyArg_Parse(v, "i", &fdno)) return 0; 01554 if (fdno < 0) { 01555 PyErr_SetString(PyExc_TypeError, "bad file descriptor"); 01556 return -1; 01557 } else { 01558 s->scriptFd = fdDup(fdno); 01559 rpmtsSetScriptFd(s->ts, s->scriptFd); 01560 } 01561 } else { 01562 PyErr_SetString(PyExc_AttributeError, name); 01563 return -1; 01564 } 01565 01566 return 0; 01567 } 01568 01571 static int rpmts_init(rpmtsObject * s, PyObject *args, PyObject *kwds) 01572 /*@globals rpmGlobalMacroContext @*/ 01573 /*@modifies s, rpmGlobalMacroContext @*/ 01574 { 01575 /* nothing to do atm... */ 01576 return 0; 01577 } 01578 01581 static void rpmts_free(/*@only@*/ rpmtsObject * s) 01582 /*@modifies s @*/ 01583 { 01584 if (_rpmts_debug) 01585 fprintf(stderr, "%p -- ts %p db %p\n", s, s->ts, rpmtsGetRdb(s->ts)); 01586 (void)rpmtsFree(s->ts); 01587 s->ts = NULL; 01588 01589 if (s->scriptFd) 01590 Fclose(s->scriptFd); 01591 01592 /* this will free the keyList, and decrement the ref count of all 01593 the items on the list as well :-) */ 01594 Py_DECREF(s->keyList); 01595 01596 PyObject_Del((PyObject *)s); 01597 } 01598 01601 static PyObject * rpmts_alloc(PyTypeObject * subtype, int nitems) 01602 /*@*/ 01603 { 01604 PyObject * s = PyType_GenericAlloc(subtype, nitems); 01605 01606 if (_rpmts_debug < 0) 01607 fprintf(stderr, "*** rpmts_alloc(%p,%d) ret %p\n", subtype, nitems, s); 01608 return s; 01609 } 01610 01613 static PyObject * rpmts_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds) 01614 /*@globals rpmGlobalMacroContext @*/ 01615 /*@modifies rpmGlobalMacroContext @*/ 01616 { 01617 rpmtsObject * s = (void *) PyObject_New(rpmtsObject, subtype); 01618 01619 char * rootDir = "/"; 01620 int vsflags = rpmExpandNumeric("%{?_vsflags}"); 01621 char * kwlist[] = {"rootdir", "vsflags", 0}; 01622 01623 if (_rpmts_debug < 0) 01624 fprintf(stderr, "*** rpmts_init(%p,%p,%p)\n", s, args, kwds); 01625 01626 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|si:rpmts_init", kwlist, 01627 &rootDir, &vsflags)) 01628 return NULL; 01629 01630 s->ts = rpmtsCreate(); 01631 /* XXX: Why is there no rpmts_SetRootDir() ? */ 01632 (void) rpmtsSetRootDir(s->ts, rootDir); 01633 /* XXX: make this use common code with rpmts_SetVSFlags() to check the 01634 * python objects */ 01635 (void) rpmtsSetVSFlags(s->ts, vsflags); 01636 s->keyList = PyList_New(0); 01637 s->ignoreSet = 0; 01638 s->scriptFd = NULL; 01639 s->tsi = NULL; 01640 s->tsiFilter = 0; 01641 01642 if (_rpmts_debug) 01643 fprintf(stderr, "%p ++ ts %p db %p\n", s, s->ts, rpmtsGetRdb(s->ts)); 01644 01645 return (PyObject *)s; 01646 } 01647 01650 /*@unchecked@*/ /*@observer@*/ 01651 static char rpmts_doc[] = 01652 ""; 01653 01656 /*@-fullinitblock@*/ 01657 PyTypeObject rpmts_Type = { 01658 PyObject_HEAD_INIT(&PyType_Type) 01659 0, /* ob_size */ 01660 "rpm.ts", /* tp_name */ 01661 sizeof(rpmtsObject), /* tp_size */ 01662 0, /* tp_itemsize */ 01663 (destructor) rpmts_dealloc, /* tp_dealloc */ 01664 0, /* tp_print */ 01665 (getattrfunc)0, /* tp_getattr */ 01666 (setattrfunc)0, /* tp_setattr */ 01667 0, /* tp_compare */ 01668 0, /* tp_repr */ 01669 0, /* tp_as_number */ 01670 0, /* tp_as_sequence */ 01671 0, /* tp_as_mapping */ 01672 0, /* tp_hash */ 01673 0, /* tp_call */ 01674 0, /* tp_str */ 01675 (getattrofunc) rpmts_getattro, /* tp_getattro */ 01676 (setattrofunc) rpmts_setattro, /* tp_setattro */ 01677 0, /* tp_as_buffer */ 01678 Py_TPFLAGS_DEFAULT, /* tp_flags */ 01679 rpmts_doc, /* tp_doc */ 01680 #if Py_TPFLAGS_HAVE_ITER 01681 0, /* tp_traverse */ 01682 0, /* tp_clear */ 01683 0, /* tp_richcompare */ 01684 0, /* tp_weaklistoffset */ 01685 (getiterfunc) rpmts_iter, /* tp_iter */ 01686 (iternextfunc) rpmts_iternext, /* tp_iternext */ 01687 rpmts_methods, /* tp_methods */ 01688 0, /* tp_members */ 01689 0, /* tp_getset */ 01690 0, /* tp_base */ 01691 0, /* tp_dict */ 01692 0, /* tp_descr_get */ 01693 0, /* tp_descr_set */ 01694 0, /* tp_dictoffset */ 01695 (initproc) rpmts_init, /* tp_init */ 01696 (allocfunc) rpmts_alloc, /* tp_alloc */ 01697 (newfunc) rpmts_new, /* tp_new */ 01698 (freefunc) rpmts_free, /* tp_free */ 01699 0, /* tp_is_gc */ 01700 #endif 01701 }; 01702 /*@=fullinitblock@*/ 01703 01706 PyObject * 01707 rpmts_Create(/*@unused@*/ PyObject * s, PyObject * args, 01708 PyObject * kwds) 01709 { 01710 return PyObject_Call((PyObject *) &rpmts_Type, args, kwds); 01711 }