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