10 #define _RPMPS_INTERNAL
18 #define _RPMTS_INTERNAL
22 #define _RPMROLLBACK_INTERNAL
23 #include <rpmrollback.h>
37 #define rpmtsfree() rpmioFreePoolItem()
187 PyObject * r = PyObject_Repr(cb);
188 char *pyfn = (r != NULL ? PyString_AsString(r) :
"???");
190 if (PyErr_Occurred())
204 PyObject * args, * result;
208 fprintf(stderr,
"*** rpmts_SolveCallback(%p,%p,%p) \"%s\"\n", ts, ds, data,
rpmdsDNEVR(ds));
210 if (cbInfo->
tso == NULL)
return res;
211 if (cbInfo->
cb == Py_None)
return res;
213 PyEval_RestoreThread(cbInfo->
_save);
216 args = Py_BuildValue(
"(OO)", cbInfo->
tso, cbInfo->
dso);
217 result = PyEval_CallObject(cbInfo->
cb, args);
218 Py_DECREF(cbInfo->
dso);
226 if (PyInt_Check(result))
227 res = PyInt_AsLong(result);
231 cbInfo->
_save = PyEval_SaveThread();
250 PyObject * pkgObj = (PyObject *) pkgKey;
251 PyObject * oh = NULL;
252 const char * origin = NULL;
253 PyObject * args, * result;
256 if (cbInfo->
cb == Py_None)
return NULL;
259 if (pkgObj == NULL) {
261 HE_t he = memset(
alloca(
sizeof(*he)), 0,
sizeof(*he));
264 pkgObj = Py_BuildValue(
"s", he->
p.
str);
277 if (!(PyTuple_Check(pkgObj) && PyArg_ParseTuple(pkgObj,
"|Os", &oh, &origin)))
280 if (origin && origin[0] ==
'/' && origin[1] ==
'/')
284 PyEval_RestoreThread(cbInfo->
_save);
286 args = Py_BuildValue(
"(iLLOO)", what, amount, total, pkgObj, cbInfo->
data);
287 result = PyEval_CallObject(cbInfo->
cb, args);
299 if (!PyArg_Parse(result,
"i", &fdno)) {
304 cbInfo->
_save = PyEval_SaveThread();
308 fprintf(stderr,
"\t%p = fdDup(%d)\n", fd, fdno);
310 fcntl(
Fileno(fd), F_SETFD, FD_CLOEXEC);
319 fprintf(stderr,
"\tFclose(%p)\n", fd);
323 fprintf(stderr,
"\t%llu:%llu key %p\n", (
unsigned long long)amount, (
unsigned long long)total, pkgKey);
327 cbInfo->
_save = PyEval_SaveThread();
332 #if Py_TPFLAGS_HAVE_ITER
340 fprintf(stderr,
"*** rpmts_iter(%p) ts %p\n", s, s->
ts);
343 return (PyObject *)s;
355 PyObject * result = NULL;
359 fprintf(stderr,
"*** rpmts_iternext(%p) ts %p tsi %p %d\n", s, s->
ts, s->
tsi, s->
tsiFilter);
362 if (s->
tsi == NULL) {
395 char * kwlist[] = {
"debugLevel", NULL};
397 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"i:Debug", kwlist,
402 fprintf(stderr,
"*** rpmts_Debug(%p) ts %p\n", s, s->
ts);
420 char * kwlist[] = {
"header",
"key",
"how", NULL};
422 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"O!O|s:AddInstall", kwlist,
426 { PyObject * hObj = (PyObject *) h;
428 PyErr_SetString(PyExc_TypeError,
"bad type for header argument");
434 fprintf(stderr,
"*** rpmts_AddInstall(%p,%p,%p,%s) ts %p\n", s, h, key, how, s->
ts);
436 if (how && strcmp(how,
"a") && strcmp(how,
"u") && strcmp(how,
"i")) {
437 PyErr_SetString(PyExc_TypeError,
"how argument must be \"u\", \"a\", or \"i\"");
439 }
else if (how && !strcmp(how,
"u"))
446 PyList_Append(s->
keyList, key);
464 char * kwlist[] = {
"name", NULL};
467 fprintf(stderr,
"*** rpmts_AddErase(%p) ts %p\n", s, s->
ts);
469 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"O:AddErase", kwlist, &o))
472 if (PyString_Check(o) || PyUnicode_Check(o)) {
473 char *
name = PyString_AsString(o);
479 PyErr_SetString(
pyrpmError,
"package not installed");
491 if (PyInt_Check(o)) {
492 uint32_t instance = PyInt_AsLong(o);
495 if (instance == 0 || mi == NULL) {
497 PyErr_SetString(
pyrpmError,
"package not installed");
525 PyObject * list, * cf;
529 char * kwlist[] = {
"callback", NULL};
531 memset(&cbInfo, 0,
sizeof(cbInfo));
532 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"|O:Check", kwlist,
536 if (cbInfo.
cb != NULL) {
537 if (!PyCallable_Check(cbInfo.
cb)) {
538 PyErr_SetString(PyExc_TypeError,
"expected a callable");
545 fprintf(stderr,
"*** rpmts_Check(%p) ts %p cb %p\n", s, s->
ts, cbInfo.
cb);
549 cbInfo.
_save = PyEval_SaveThread();
557 PyEval_RestoreThread(cbInfo.
_save);
560 list = PyList_New(0);
565 cf = Py_BuildValue(
"((sss)(ss)iOi)", conflicts[i].byName,
566 conflicts[i].byVersion, conflicts[i].byRelease,
568 conflicts[i].needsName,
569 conflicts[i].needsVersion,
571 conflicts[i].needsFlags,
572 conflicts[i].suggestedPkgs ?
573 conflicts[i].suggestedPkgs[0] : Py_None,
576 char * byName, * byVersion, * byRelease, *byArch;
577 char * needsName, * needsOP, * needsVersion;
579 int needsFlags, sense;
589 if ((byArch= strrchr(byName,
'.')) != NULL)
591 if ((byRelease = strrchr(byName,
'-')) != NULL)
593 if ((byVersion = strrchr(byName,
'-')) != NULL)
599 if (needsName[1] ==
' ') {
600 sense = (needsName[0] ==
'C')
605 if ((needsVersion = strrchr(needsName,
' ')) != NULL)
606 *needsVersion++ =
'\0';
609 if ((needsOP = strrchr(needsName,
' ')) != NULL) {
610 for (*needsOP++ =
'\0'; *needsOP !=
'\0'; needsOP++) {
617 cf = Py_BuildValue(
"((sss)(ss)iOi)", byName, byVersion, byRelease,
618 needsName, needsVersion, needsFlags,
619 (key != NULL ? key : Py_None),
624 PyList_Append(list, (PyObject *) cf);
649 fprintf(stderr,
"*** rpmts_Order(%p) ts %p\n", s, s->
ts);
651 Py_BEGIN_ALLOW_THREADS
655 return Py_BuildValue(
"i", rc);
667 fprintf(stderr,
"*** rpmts_Clean(%p) ts %p\n", s, s->
ts);
683 PyObject * result = NULL;
685 char * kwlist[] = {
"rbtid", NULL};
690 fprintf(stderr,
"*** rpmts_IDTXload(%p) ts %p\n", s, s->
ts);
692 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"|i:IDTXload", kwlist, &rbtid))
695 Py_BEGIN_ALLOW_THREADS
700 if (idtx == NULL || idtx->nidt <= 0) {
709 result = PyTuple_New(idtx->nidt);
710 for (i = 0; i < idtx->nidt; i++) {
713 tuple = Py_BuildValue(
"(iOi)", idt->val.u32, ho, idt->instance);
714 PyTuple_SET_ITEM(result, i, tuple);
733 PyObject * result = NULL;
734 const char * globstr;
736 char * kwlist[] = {
"rbtid", NULL};
741 fprintf(stderr,
"*** rpmts_IDTXglob(%p) ts %p\n", s, s->
ts);
743 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"|i:IDTXglob", kwlist, &rbtid))
746 Py_BEGIN_ALLOW_THREADS
747 globstr =
rpmExpand(
"%{_repackage_dir}/*.rpm", NULL);
749 globstr =
_free(globstr);
753 if (idtx == NULL || idtx->nidt <= 0) {
762 result = PyTuple_New(idtx->nidt);
763 for (i = 0; i < idtx->nidt; i++) {
766 tuple = Py_BuildValue(
"(iOs)", idt->val.u32, ho, idt->key);
767 PyTuple_SET_ITEM(result, i, tuple);
786 QVA_t ia = memset(
alloca(
sizeof(*ia)), 0,
sizeof(*ia));
788 const char ** av = NULL;
791 char * kwlist[] = {
"transactionId", NULL};
794 fprintf(stderr,
"*** rpmts_Rollback(%p) ts %p\n", s, s->
ts);
796 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"i:Rollback", kwlist, &rbtid))
799 Py_BEGIN_ALLOW_THREADS
813 return Py_BuildValue(
"i", rc);
826 fprintf(stderr,
"*** rpmts_OpenDB(%p) ts %p\n", s, s->
ts);
844 fprintf(stderr,
"*** rpmts_CloseDB(%p) ts %p\n", s, s->
ts);
849 return Py_BuildValue(
"i", rc);
863 fprintf(stderr,
"*** rpmts_InitDB(%p) ts %p\n", s, s->
ts);
869 return Py_BuildValue(
"i", rc);
883 fprintf(stderr,
"*** rpmts_RebuildDB(%p) ts %p\n", s, s->
ts);
885 Py_BEGIN_ALLOW_THREADS
889 return Py_BuildValue(
"i", rc);
903 fprintf(stderr,
"*** rpmts_VerifyDB(%p) ts %p\n", s, s->
ts);
905 Py_BEGIN_ALLOW_THREADS
909 return Py_BuildValue(
"i", rc);
920 PyObject * result = NULL;
925 char * kwlist[] = {
"fd", NULL};
927 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"i:HdrFromFdno", kwlist,
936 fprintf(stderr,
"*** rpmts_HdrFromFdno(%p) ts %p rc %d\n", s, s->
ts, rpmrc);
942 result = Py_BuildValue(
"N",
hdr_Wrap(h));
948 PyErr_SetString(
pyrpmError,
"public key not available");
952 PyErr_SetString(
pyrpmError,
"public key not trusted");
958 PyErr_SetString(
pyrpmError,
"error reading package header");
975 PyObject * result = NULL;
976 const char * msg = NULL;
981 char * kwlist[] = {
"headers", NULL};
984 fprintf(stderr,
"*** rpmts_HdrCheck(%p) ts %p\n", s, s->
ts);
986 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"O:HdrCheck", kwlist, &blob))
989 if (blob == Py_None) {
993 if (!(PyString_Check(blob) || PyUnicode_Check(blob))) {
994 PyErr_SetString(
pyrpmError,
"hdrCheck takes a string of octets");
997 uh = PyString_AsString(blob);
998 uc = PyString_Size(blob);
1012 PyErr_SetString(
pyrpmError,
"public key not availaiable");
1016 PyErr_SetString(
pyrpmError,
"public key not trusted");
1045 char * kwlist[] = {
"flags", NULL};
1048 fprintf(stderr,
"*** rpmts_SetVSFlags(%p) ts %p\n", s, s->
ts);
1050 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"i:SetVSFlags", kwlist,
1068 char * kwlist[] = {
"color", NULL};
1071 fprintf(stderr,
"*** rpmts_SetColor(%p) ts %p\n", s, s->
ts);
1073 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"i:Color", kwlist, &tscolor))
1091 unsigned char * pkt;
1092 unsigned int pktlen;
1094 char * kwlist[] = {
"octets", NULL};
1097 fprintf(stderr,
"*** rpmts_PgpPrtPkts(%p) ts %p\n", s, s->
ts);
1099 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"O:PgpPrtPkts", kwlist, &blob))
1102 if (blob == Py_None) {
1106 if (!(PyString_Check(blob) || PyUnicode_Check(blob))) {
1107 PyErr_SetString(
pyrpmError,
"pgpPrtPkts takes a string of octets");
1110 pkt = (
unsigned char *) PyString_AsString(blob);
1111 pktlen = PyString_Size(blob);
1115 return Py_BuildValue(
"i", rc);
1127 unsigned char * pkt;
1128 unsigned int pktlen;
1130 char * kwlist[] = {
"pubkey", NULL};
1133 fprintf(stderr,
"*** rpmts_PgpImportPubkey(%p) ts %p\n", s, s->
ts);
1135 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"O:PgpImportPubkey",
1139 if (blob == Py_None) {
1143 if (!(PyString_Check(blob) || PyUnicode_Check(blob))) {
1144 PyErr_SetString(
pyrpmError,
"PgpImportPubkey takes a string of octets");
1147 pkt = (
unsigned char *) PyString_AsString(blob);
1148 pktlen = PyString_Size(blob);
1152 return Py_BuildValue(
"i", rc);
1162 char * kwlist[] = {
"flags", NULL};
1164 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"i:SetFlags", kwlist,
1169 fprintf(stderr,
"*** rpmts_SetFlags(%p) ts %p transFlags 0x%x\n", s, s->
ts, transFlags);
1184 char * kwlist[] = {
"flags", NULL};
1186 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"i:SetDFlags", kwlist,
1191 fprintf(stderr,
"*** rpmts_SetDFlags(%p) ts %p depFlags 0x%x\n", s, s->
ts, depFlags);
1207 char * kwlist[] = {
"ignoreSet", NULL};
1209 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"i:ProbFilter", kwlist,
1214 fprintf(stderr,
"*** rpmts_SetProbFilter(%p) ts %p ignoreSet %x\n", s, s->
ts, ignoreSet);
1219 return Py_BuildValue(
"i", oignoreSet);
1231 fprintf(stderr,
"*** rpmts_Problems(%p) ts %p\n", s, s->
ts);
1248 char * kwlist[] = {
"callback",
"data", NULL};
1250 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"OO:Run", kwlist,
1251 &cbInfo.
cb, &cbInfo.
data))
1256 cbInfo.
_save = PyEval_SaveThread();
1258 if (cbInfo.
cb != NULL) {
1259 if (!PyCallable_Check(cbInfo.
cb)) {
1260 PyErr_SetString(PyExc_TypeError,
"expected a callable");
1267 fprintf(stderr,
"*** rpmts_Run(%p) ts %p ignore %x\n", s, s->
ts, s->
ignoreSet);
1275 PyEval_RestoreThread(cbInfo.
_save);
1278 list = PyList_New(0);
1285 list = PyList_New(0);
1293 PyList_Append(list, prob);
1314 fprintf(stderr,
"*** rpmts_Next(%p) ts %p\n", s, s->
ts);
1318 if (result == NULL) {
1334 const char * specfile;
1337 char * passPhrase =
"";
1338 char *cookie = NULL;
1342 char * kwlist[] = {
"specfile", NULL};
1344 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"s:Parse", kwlist, &specfile))
1347 if (
parseSpec(s->
ts, specfile,
"/", recursing, passPhrase,
1348 cookie, anyarch, force, verify)!=0) {
1349 PyErr_SetString(
pyrpmError,
"can't parse specfile\n");
1365 PyObject *TagN = NULL;
1366 PyObject *Key = NULL;
1372 char * kwlist[] = {
"tagNumber",
"key", NULL};
1375 fprintf(stderr,
"*** rpmts_Match(%p) ts %p\n", s, s->
ts);
1377 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"|OO:Match", kwlist,
1382 PyErr_SetString(PyExc_TypeError,
"unknown tag type");
1388 if (PyString_Check(Key) || PyUnicode_Check(Key)) {
1389 key = PyString_AsString(Key);
1390 len = PyString_Size(Key);
1391 }
else if (PyInt_Check(Key)) {
1392 lkey = PyInt_AsLong(Key);
1393 key = (
char *)&lkey;
1396 PyErr_SetString(PyExc_TypeError,
"unknown key type");
1407 PyErr_SetString(PyExc_TypeError,
"rpmdb open failed");
1422 {
"Debug", (PyCFunction)
rpmts_Debug, METH_VARARGS|METH_KEYWORDS,
1427 {
"addErase", (PyCFunction)
rpmts_AddErase, METH_VARARGS|METH_KEYWORDS,
1429 {
"setDFlags", (PyCFunction)
rpmts_SetDFlags, METH_VARARGS|METH_KEYWORDS,
1430 "ts.setDFlags(depFlags) -> previous depFlags\n\
1431 - Set control bit(s) for executing ts.check() and ts.order().\n" },
1432 {
"check", (PyCFunction)
rpmts_Check, METH_VARARGS|METH_KEYWORDS,
1436 {
"setFlags", (PyCFunction)
rpmts_SetFlags, METH_VARARGS|METH_KEYWORDS,
1437 "ts.setFlags(transFlags) -> previous transFlags\n\
1438 - Set control bit(s) for executing ts.run().\n\
1439 Note: This method replaces the 1st argument to the old ts.run()\n" },
1441 "ts.setProbFilter(ignoreSet) -> previous ignoreSet\n\
1442 - Set control bit(s) for ignoring problems found by ts.run().\n\
1443 Note: This method replaces the 2nd argument to the old ts.run()\n" },
1445 "ts.problems() -> ps\n\
1446 - Return current problem set.\n" },
1447 {
"run", (PyCFunction)
rpmts_Run, METH_VARARGS|METH_KEYWORDS,
1448 "ts.run(callback, data) -> (problems)\n\
1449 - Run a transaction set, returning list of problems found.\n\
1450 Note: The callback may not be None.\n" },
1453 {
"IDTXload", (PyCFunction)
rpmts_IDTXload, METH_VARARGS|METH_KEYWORDS,
1454 "ts.IDTXload(rbtid=iid) -> ((tid,hdr,instance)+)\n\
1455 - Return list of installed packages reverse sorted by transaction id.\n" },
1456 {
"IDTXglob", (PyCFunction)
rpmts_IDTXglob, METH_VARARGS|METH_KEYWORDS,
1457 "ts.IDTXglob(rbtid=rid) -> ((tid,hdr,instance)+)\n\
1458 - Return list of removed packages reverse sorted by transaction id.\n" },
1459 {
"rollback", (PyCFunction)
rpmts_Rollback, METH_VARARGS|METH_KEYWORDS,
1462 "ts.openDB() -> None\n\
1463 - Open the default transaction rpmdb.\n\
1464 Note: The transaction rpmdb is lazily opened, so ts.openDB() is seldom needed.\n" },
1466 "ts.closeDB() -> None\n\
1467 - Close the default transaction rpmdb.\n\
1468 Note: ts.closeDB() disables lazy opens, and should hardly ever be used.\n" },
1470 "ts.initDB() -> None\n\
1471 - Initialize the default transaction rpmdb.\n\
1472 Note: ts.initDB() is seldom needed anymore.\n" },
1474 "ts.rebuildDB() -> None\n\
1475 - Rebuild the default transaction rpmdb.\n" },
1477 "ts.verifyDB() -> None\n\
1478 - Verify the default transaction rpmdb.\n" },
1480 "ts.hdrFromFdno(fdno) -> hdr\n\
1481 - Read a package header from a file descriptor.\n" },
1482 {
"hdrCheck", (PyCFunction)
rpmts_HdrCheck, METH_VARARGS|METH_KEYWORDS,
1485 "ts.getVSFlags() -> vsflags\n\
1486 - Retrieve current signature verification flags from transaction\n" },
1488 "ts.setVSFlags(vsflags) -> ovsflags\n\
1489 - Set signature verification flags. Values for vsflags are:\n\
1490 rpm.RPMVSF_NOHDRCHK if set, don't check rpmdb headers\n\
1491 rpm.RPMVSF_NEEDPAYLOAD if not set, check header+payload (if possible)\n\
1492 rpm.RPMVSF_NOSHA1HEADER if set, don't check header SHA1 digest\n\
1493 rpm.RPMVSF_NODSAHEADER if set, don't check header DSA signature\n\
1494 rpm.RPMVSF_NORSAHEADER if set, don't check header RSA signature\n\
1495 rpm.RPMVSF_NOMD5 if set, don't check header+payload MD5 digest\n\
1496 rpm.RPMVSF_NODSA if set, don't check header+payload DSA signature\n\
1497 rpm.RPMVSF_NORSA if set, don't check header+payload RSA signature\n\
1498 rpm._RPMVSF_NODIGESTS if set, don't check digest(s)\n\
1499 rpm._RPMVSF_NOSIGNATURES if set, don't check signature(s)\n" },
1500 {
"setColor",(PyCFunction)
rpmts_SetColor, METH_VARARGS|METH_KEYWORDS,
1506 {
"parseSpec", (PyCFunction)
spec_Parse, METH_VARARGS|METH_KEYWORDS,
1507 "ts.parseSpec(\"/path/to/foo.spec\") -> spec\n\
1508 - Parse a spec file.\n" },
1509 {
"dbMatch", (PyCFunction)
rpmts_Match, METH_VARARGS|METH_KEYWORDS,
1510 "ts.dbMatch([TagN, [key, [len]]]) -> mi\n\
1511 - Create a match iterator for the default transaction rpmdb.\n" },
1512 {
"next", (PyCFunction)
rpmts_Next, METH_NOARGS,
1514 - Retrieve next transaction set element.\n" },
1534 PyObject_Del((PyObject *)s);
1540 return PyObject_GenericGetAttr(o, n);
1549 char *
name = PyString_AsString(n);
1552 if (!strcmp(name,
"scriptFd")) {
1553 if (!PyArg_Parse(v,
"i", &fdno))
return 0;
1555 PyErr_SetString(PyExc_TypeError,
"bad file descriptor");
1562 PyErr_SetString(PyExc_AttributeError, name);
1596 PyObject_Del((PyObject *)s);
1604 PyObject * s = PyType_GenericAlloc(subtype, nitems);
1607 fprintf(stderr,
"*** rpmts_alloc(%p,%d) ret %p\n", subtype, nitems, s);
1613 static PyObject *
rpmts_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
1619 char * rootDir =
"/";
1621 char * kwlist[] = {
"rootdir",
"vsflags", 0};
1624 fprintf(stderr,
"*** rpmts_init(%p,%p,%p)\n", s, args, kwds);
1626 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"|si:rpmts_init", kwlist,
1627 &rootDir, &vsflags))
1645 return (PyObject *)s;
1658 PyObject_HEAD_INIT(&PyType_Type)
1680 #if Py_TPFLAGS_HAVE_ITER
1710 return PyObject_Call((PyObject *) &rpmts_Type, args, kwds);