-/** \ingroup py_c
- * \file python/rpmts-py.c
- */
+#include "rpmsystem-py.h"
-#include "system.h"
+#include <fcntl.h>
#include <rpm/rpmlib.h> /* rpmReadPackageFile, headerCheck */
#include <rpm/rpmtag.h>
#include "header-py.h"
#include "rpmds-py.h" /* XXX for rpmdsNew */
+#include "rpmfd-py.h"
+#include "rpmkeyring-py.h"
#include "rpmfi-py.h" /* XXX for rpmfiNew */
#include "rpmmi-py.h"
+#include "rpmii-py.h"
#include "rpmps-py.h"
#include "rpmte-py.h"
-#include "spec-py.h"
-
#include "rpmts-py.h"
-#include "debug.h"
-
-extern int _rpmts_debug;
-
-
/** \ingroup python
* \name Class: Rpmts
* \class Rpmts
* @param data user data that will be passed to the transaction callback
* during transaction execution
* @param mode optional argument that specifies if this package should
- * be installed ('i'), upgraded ('u'), or if it is just
- * available to the transaction when computing
- * dependencies but no action should be performed with it
- * ('a').
+ * be installed ('i'), upgraded ('u').
*
* - addErase(name) Add an erase element to a transaction set.
* @param name the package name to be erased
* @return None
*
* - ts.setFlags(transFlags) Set transaction set flags.
- * @param transFlags - bit(s) to controll transaction operations. The
+ * @param transFlags - bit(s) to control transaction operations. The
* following values can be logically OR'ed together:
* - rpm.RPMTRANS_FLAG_TEST - test mode, do not modify the RPM
* database, change any files, or run any package scripts
* - rpm.RPMTRANS_FLAG_BUILD_PROBS - only build a list of
* problems encountered when attempting to run this transaction
* set
- * - rpm.RPMTRANS_FLAG_NOSCRIPTS - do not execute package scripts
* - rpm.RPMTRANS_FLAG_JUSTDB - only make changes to the rpm
* database, do not modify files.
+ * - rpm.RPMTRANS_FLAG_NOSCRIPTS - do not execute package scripts
* - rpm.RPMTRANS_FLAG_NOTRIGGERS - do not run trigger scripts
+ * - rpm.RPMTRANS_FLAG_NO* - disable specific scripts and triggers
* - rpm.RPMTRANS_FLAG_NODOCS - do not install files marked as %doc
+ * - rpm.RPMTRANS_FLAG_NOPLUGINS - do not run plugins
+ * - rpm.RPMTRANS_FLAG_NOFILEDIGEST - disable checking checksums
* - rpm.RPMTRANS_FLAG_ALLFILES - create all files, even if a
* file is marked %config(missingok) and an upgrade is
* being performed.
- * - rpm.RPMTRANS_FLAG_KEEPOBSOLETE - do not remove obsoleted
- * packages.
+ * - rpm.RPMTRANS_FLAG_NOCONFIGS - skip config files
+ * - rpm.RPMTRANS_FLAG_DEPLOOPS - enable debugging for dependency loops
* @return previous transFlags
*
* - ts.setProbFilter(ignoreSet) Set transaction set problem filter.
* the ts.run() method.
*/
-/** \ingroup py_c
- */
+struct rpmtsObject_s {
+ PyObject_HEAD
+ PyObject *md_dict; /*!< to look like PyModuleObject */
+ rpmfdObject *scriptFd;
+ PyObject *keyList;
+ rpmts ts;
+ rpmtsi tsi;
+};
+
struct rpmtsCallbackType_s {
PyObject * cb;
PyObject * data;
rpmtsObject * tso;
- int pythonError;
PyThreadState *_save;
};
-/** \ingroup py_c
- */
-static PyObject *
-rpmts_Debug(rpmtsObject * s, PyObject * args, PyObject * kwds)
-{
- char * kwlist[] = {"debugLevel", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Debug", kwlist,
- &_rpmts_debug))
- return NULL;
-
-if (_rpmts_debug < 0)
-fprintf(stderr, "*** rpmts_Debug(%p) ts %p\n", s, s->ts);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-#if 0
-/** \ingroup py_c
- * Add package to universe of possible packages to install in transaction set.
- * @param ts transaction set
- * @param h header
- * @param key package private data
- */
-static void rpmtsAddAvailableElement(rpmts ts, Header h,
- fnpyKey key)
+RPM_GNUC_NORETURN
+static void die(PyObject *cb)
{
- int scareMem = 0;
- rpmds provides = rpmdsNew(h, RPMTAG_PROVIDENAME, scareMem);
- rpmfi fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
-
- /* XXX FIXME: return code RPMAL_NOMATCH is error */
- (void) rpmalAdd(&ts->availablePackages, RPMAL_NOMATCH, key,
- provides, fi, rpmtsColor(ts));
- fi = rpmfiFree(fi);
- provides = rpmdsFree(provides);
-
-if (_rpmts_debug < 0)
-fprintf(stderr, "\tAddAvailable(%p) list %p\n", ts, ts->availablePackages);
+ char *pyfn = NULL;
+ PyObject *r;
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ }
+ if ((r = PyObject_Repr(cb)) != NULL) {
+ pyfn = PyBytes_AsString(r);
+ }
+ fprintf(stderr, "FATAL ERROR: python callback %s failed, aborting!\n",
+ pyfn ? pyfn : "???");
+ exit(EXIT_FAILURE);
}
-#endif
-/** \ingroup py_c
- */
static PyObject *
-rpmts_AddInstall(rpmtsObject * s, PyObject * args, PyObject * kwds)
+rpmts_AddInstall(rpmtsObject * s, PyObject * args)
{
- hdrObject * h;
+ Header h = NULL;
PyObject * key;
- char * how = "u"; /* XXX default to upgrade element if missing */
- int isUpgrade = 0;
- char * kwlist[] = {"header", "key", "how", NULL};
- int rc = 0;
+ int how = 0;
+ int rc;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O|s:AddInstall", kwlist,
- &hdr_Type, &h, &key, &how))
+ if (!PyArg_ParseTuple(args, "O&Oi:AddInstall",
+ hdrFromPyObject, &h, &key, &how))
return NULL;
- { PyObject * hObj = (PyObject *) h;
- if (hObj->ob_type != &hdr_Type) {
- PyErr_SetString(PyExc_TypeError, "bad type for header argument");
- return NULL;
- }
+ rc = rpmtsAddInstallElement(s->ts, h, key, how, NULL);
+ if (key && rc == 0) {
+ PyList_Append(s->keyList, key);
}
+ return PyBool_FromLong((rc == 0));
+}
-if (_rpmts_debug < 0 || (_rpmts_debug > 0 && *how != 'a'))
-fprintf(stderr, "*** rpmts_AddInstall(%p,%p,%p,%s) ts %p\n", s, h, key, how, s->ts);
+static PyObject *
+rpmts_AddReinstall(rpmtsObject * s, PyObject * args)
+{
+ Header h = NULL;
+ PyObject * key;
+ int rc;
- if (how && strcmp(how, "a") && strcmp(how, "u") && strcmp(how, "i")) {
- PyErr_SetString(PyExc_TypeError, "how argument must be \"u\", \"a\", or \"i\"");
- return NULL;
- } else if (how && !strcmp(how, "u"))
- isUpgrade = 1;
-
- /*
- * XXX resurrect when better available mechanism is, well, available.
- * OTOH nothing appears to use it these days...
- * Raise exception to catch out any callers while broken.
- */
- if (how && !strcmp(how, "a")) {
-#ifdef DYING
- rpmtsAddAvailableElement(s->ts, hdrGetHeader(h), key);
-#else
- PyErr_SetString(pyrpmError, "available package mechanism currently broken");
+ if (!PyArg_ParseTuple(args, "O&O:AddReinstall",
+ hdrFromPyObject, &h, &key))
return NULL;
-#endif
- } else
- rc = rpmtsAddInstallElement(s->ts, hdrGetHeader(h), key, isUpgrade, NULL);
- if (rc) {
- PyErr_SetString(pyrpmError, "adding package to transaction failed");
- return NULL;
- }
-
- /* This should increment the usage count for me */
- if (key)
+ rc = rpmtsAddReinstallElement(s->ts, h, key);
+ if (key && rc == 0) {
PyList_Append(s->keyList, key);
-
- Py_INCREF(Py_None);
- return Py_None;
+ }
+ return PyBool_FromLong((rc == 0));
}
-/** \ingroup py_c
- * @todo Permit finer control (i.e. not just --allmatches) of deleted elments.
- */
static PyObject *
-rpmts_AddErase(rpmtsObject * s, PyObject * args, PyObject * kwds)
+rpmts_AddErase(rpmtsObject * s, PyObject * args)
{
- PyObject * o;
- int count;
- rpmdbMatchIterator mi;
- char * kwlist[] = {"name", NULL};
-
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_AddErase(%p) ts %p\n", s, s->ts);
+ Header h;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:AddErase", kwlist, &o))
+ if (!PyArg_ParseTuple(args, "O&:AddErase", hdrFromPyObject, &h))
return NULL;
- if (PyString_Check(o)) {
- char * name = PyString_AsString(o);
-
- mi = rpmtsInitIterator(s->ts, RPMDBI_LABEL, name, 0);
- count = rpmdbGetIteratorCount(mi);
- if (count <= 0) {
- mi = rpmdbFreeIterator(mi);
- PyErr_SetString(pyrpmError, "package not installed");
- return NULL;
- } else { /* XXX: Note that we automatically choose to remove all matches */
- Header h;
- while ((h = rpmdbNextIterator(mi)) != NULL) {
- unsigned int recOffset = rpmdbGetIteratorOffset(mi);
- if (recOffset)
- rpmtsAddEraseElement(s->ts, h, recOffset);
- }
- }
- mi = rpmdbFreeIterator(mi);
- } else
- if (PyInt_Check(o)) {
- uint32_t instance = PyInt_AsLong(o);
-
- mi = rpmtsInitIterator(s->ts, RPMDBI_PACKAGES, &instance, sizeof(instance));
- if (instance == 0 || mi == NULL) {
- mi = rpmdbFreeIterator(mi);
- PyErr_SetString(pyrpmError, "package not installed");
- return NULL;
- } else {
- Header h;
- while ((h = rpmdbNextIterator(mi)) != NULL) {
- uint32_t recOffset = rpmdbGetIteratorOffset(mi);
- if (recOffset)
- rpmtsAddEraseElement(s->ts, h, recOffset);
- break;
- }
- }
- mi = rpmdbFreeIterator(mi);
- }
-
- Py_INCREF(Py_None);
- return Py_None;
+ return PyBool_FromLong(rpmtsAddEraseElement(s->ts, h, -1) == 0);
}
-/** \ingroup py_c
- */
static int
rpmts_SolveCallback(rpmts ts, rpmds ds, const void * data)
{
PyObject * args, * result;
int res = 1;
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_SolveCallback(%p,%p,%p) \"%s\"\n", ts, ds, data, rpmdsDNEVR(ds));
-
if (cbInfo->tso == NULL) return res;
- if (cbInfo->pythonError) return res;
if (cbInfo->cb == Py_None) return res;
PyEval_RestoreThread(cbInfo->_save);
- args = Py_BuildValue("(Oissi)", cbInfo->tso,
- rpmdsTagN(ds), rpmdsN(ds), rpmdsEVR(ds), rpmdsFlags(ds));
+ args = Py_BuildValue("(OiNNi)", cbInfo->tso,
+ rpmdsTagN(ds), utf8FromString(rpmdsN(ds)),
+ utf8FromString(rpmdsEVR(ds)), rpmdsFlags(ds));
result = PyEval_CallObject(cbInfo->cb, args);
Py_DECREF(args);
if (!result) {
- cbInfo->pythonError = 1;
+ die(cbInfo->cb);
} else {
if (PyInt_Check(result))
res = PyInt_AsLong(result);
return res;
}
-/** \ingroup py_c
- */
static PyObject *
rpmts_Check(rpmtsObject * s, PyObject * args, PyObject * kwds)
{
- rpmps ps;
- rpmProblem p;
- PyObject * list, * cf;
struct rpmtsCallbackType_s cbInfo;
- int i;
- int xx;
+ int rc;
char * kwlist[] = {"callback", NULL};
memset(&cbInfo, 0, sizeof(cbInfo));
PyErr_SetString(PyExc_TypeError, "expected a callable");
return NULL;
}
- xx = rpmtsSetSolveCallback(s->ts, rpmts_SolveCallback, (void *)&cbInfo);
+ rc = rpmtsSetSolveCallback(s->ts, rpmts_SolveCallback, (void *)&cbInfo);
}
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_Check(%p) ts %p cb %p\n", s, s->ts, cbInfo.cb);
-
cbInfo.tso = s;
- cbInfo.pythonError = 0;
cbInfo._save = PyEval_SaveThread();
-#ifdef DYING
- /* XXX resurrect availablePackages one more time ... */
- rpmalMakeIndex(s->ts->availablePackages);
-#endif
-
- xx = rpmtsCheck(s->ts);
- ps = rpmtsProblems(s->ts);
-
- if (cbInfo.cb)
- xx = rpmtsSetSolveCallback(s->ts, rpmtsSolve, NULL);
+ rc = rpmtsCheck(s->ts);
PyEval_RestoreThread(cbInfo._save);
- if (ps != NULL) {
- list = PyList_New(0);
- rpmpsi psi = rpmpsInitIterator(ps);
-
- /* XXX TODO: rpmlib >= 4.0.3 can return multiple suggested keys. */
- while ((i = rpmpsNextIterator(psi)) >= 0) {
- const char * needsName;
- char * byName, * byVersion, * byRelease, *byArch;
- char * needsOP, * needsVersion;
- rpmsenseFlags needsFlags, sense;
- fnpyKey key;
-
- p = rpmpsGetProblem(psi);
-
- byName = strdup(rpmProblemGetPkgNEVR(p));
- if ((byArch= strrchr(byName, '.')) != NULL)
- *byArch++ = '\0';
- if ((byRelease = strrchr(byName, '-')) != NULL)
- *byRelease++ = '\0';
- if ((byVersion = strrchr(byName, '-')) != NULL)
- *byVersion++ = '\0';
-
- key = rpmProblemGetKey(p);
-
- needsName = rpmProblemGetAltNEVR(p);
- if (needsName[1] == ' ') {
- sense = (needsName[0] == 'C')
- ? RPMDEP_SENSE_CONFLICTS : RPMDEP_SENSE_REQUIRES;
- needsName += 2;
- } else
- sense = RPMDEP_SENSE_REQUIRES;
- if ((needsVersion = strrchr(needsName, ' ')) != NULL)
- *needsVersion++ = '\0';
-
- needsFlags = 0;
- if ((needsOP = strrchr(needsName, ' ')) != NULL) {
- for (*needsOP++ = '\0'; *needsOP != '\0'; needsOP++) {
- if (*needsOP == '<') needsFlags |= RPMSENSE_LESS;
- else if (*needsOP == '>') needsFlags |= RPMSENSE_GREATER;
- else if (*needsOP == '=') needsFlags |= RPMSENSE_EQUAL;
- }
- }
-
- cf = Py_BuildValue("((sss)(ss)iOi)", byName, byVersion, byRelease,
- needsName, needsVersion, needsFlags,
- (key != NULL ? key : Py_None),
- sense);
- PyList_Append(list, (PyObject *) cf);
- Py_DECREF(cf);
- free(byName);
- }
-
- psi = rpmpsFreeIterator(psi);
- ps = rpmpsFree(ps);
-
- return list;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
+ return PyBool_FromLong((rc == 0));
}
-/** \ingroup py_c
- */
static PyObject *
rpmts_Order(rpmtsObject * s)
{
int rc;
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_Order(%p) ts %p\n", s, s->ts);
-
Py_BEGIN_ALLOW_THREADS
rc = rpmtsOrder(s->ts);
Py_END_ALLOW_THREADS
return Py_BuildValue("i", rc);
}
-/** \ingroup py_c
- */
static PyObject *
rpmts_Clean(rpmtsObject * s)
{
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_Clean(%p) ts %p\n", s, s->ts);
-
rpmtsClean(s->ts);
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+rpmts_Clear(rpmtsObject * s)
+{
+ rpmtsEmpty(s->ts);
+
+ Py_RETURN_NONE;
}
-/** \ingroup py_c
- */
static PyObject *
rpmts_OpenDB(rpmtsObject * s)
{
int dbmode;
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_OpenDB(%p) ts %p\n", s, s->ts);
-
dbmode = rpmtsGetDBMode(s->ts);
if (dbmode == -1)
dbmode = O_RDONLY;
return Py_BuildValue("i", rpmtsOpenDB(s->ts, dbmode));
}
-/** \ingroup py_c
- */
static PyObject *
rpmts_CloseDB(rpmtsObject * s)
{
int rc;
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_CloseDB(%p) ts %p\n", s, s->ts);
-
rc = rpmtsCloseDB(s->ts);
rpmtsSetDBMode(s->ts, -1); /* XXX disable lazy opens */
return Py_BuildValue("i", rc);
}
-/** \ingroup py_c
- */
static PyObject *
rpmts_InitDB(rpmtsObject * s)
{
int rc;
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_InitDB(%p) ts %p\n", s, s->ts);
-
rc = rpmtsInitDB(s->ts, O_RDONLY);
if (rc == 0)
rc = rpmtsCloseDB(s->ts);
return Py_BuildValue("i", rc);
}
-/** \ingroup py_c
- */
static PyObject *
rpmts_RebuildDB(rpmtsObject * s)
{
int rc;
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_RebuildDB(%p) ts %p\n", s, s->ts);
-
Py_BEGIN_ALLOW_THREADS
rc = rpmtsRebuildDB(s->ts);
Py_END_ALLOW_THREADS
return Py_BuildValue("i", rc);
}
-/** \ingroup py_c
- */
static PyObject *
rpmts_VerifyDB(rpmtsObject * s)
{
int rc;
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_VerifyDB(%p) ts %p\n", s, s->ts);
-
Py_BEGIN_ALLOW_THREADS
rc = rpmtsVerifyDB(s->ts);
Py_END_ALLOW_THREADS
return Py_BuildValue("i", rc);
}
-/** \ingroup py_c
- */
static PyObject *
-rpmts_HdrFromFdno(rpmtsObject * s, PyObject * args, PyObject * kwds)
+rpmts_HdrFromFdno(rpmtsObject * s, PyObject *arg)
{
- PyObject * result = NULL;
+ PyObject *ho = NULL;
+ rpmfdObject *fdo = NULL;
Header h;
- FD_t fd;
- int fdno;
rpmRC rpmrc;
- char * kwlist[] = {"fd", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:HdrFromFdno", kwlist,
- &fdno))
+ if (!PyArg_Parse(arg, "O&:HdrFromFdno", rpmfdFromPyObject, &fdo))
return NULL;
- fd = fdDup(fdno);
- rpmrc = rpmReadPackageFile(s->ts, fd, "rpmts_HdrFromFdno", &h);
- Fclose(fd);
-
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_HdrFromFdno(%p) ts %p rc %d\n", s, s->ts, rpmrc);
-
- switch (rpmrc) {
- case RPMRC_OK:
- if (h)
- result = Py_BuildValue("N", hdr_Wrap(h));
- h = headerFree(h); /* XXX ref held by result */
- break;
-
- case RPMRC_NOKEY:
- PyErr_SetString(pyrpmError, "public key not available");
- break;
-
- case RPMRC_NOTTRUSTED:
- PyErr_SetString(pyrpmError, "public key not trusted");
- break;
-
- case RPMRC_NOTFOUND:
- case RPMRC_FAIL:
- default:
- PyErr_SetString(pyrpmError, "error reading package header");
- break;
- }
+ Py_BEGIN_ALLOW_THREADS;
+ rpmrc = rpmReadPackageFile(s->ts, rpmfdGetFd(fdo), NULL, &h);
+ Py_END_ALLOW_THREADS;
+ Py_XDECREF(fdo);
- return result;
+ if (rpmrc == RPMRC_OK) {
+ ho = hdr_Wrap(&hdr_Type, h);
+ } else {
+ Py_INCREF(Py_None);
+ ho = Py_None;
+ }
+ return Py_BuildValue("(iN)", rpmrc, ho);
}
-/** \ingroup py_c
- */
static PyObject *
-rpmts_HdrCheck(rpmtsObject * s, PyObject * args, PyObject * kwds)
+rpmts_HdrCheck(rpmtsObject * s, PyObject *obj)
{
PyObject * blob;
- PyObject * result = NULL;
char * msg = NULL;
const void * uh;
int uc;
rpmRC rpmrc;
- char * kwlist[] = {"headers", NULL};
-
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_HdrCheck(%p) ts %p\n", s, s->ts);
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:HdrCheck", kwlist, &blob))
+ if (!PyArg_Parse(obj, "S:HdrCheck", &blob))
return NULL;
- if (blob == Py_None) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- if (!PyString_Check(blob)) {
- PyErr_SetString(pyrpmError, "hdrCheck takes a string of octets");
- return result;
- }
- uh = PyString_AsString(blob);
- uc = PyString_Size(blob);
+ uh = PyBytes_AsString(blob);
+ uc = PyBytes_Size(blob);
+ Py_BEGIN_ALLOW_THREADS;
rpmrc = headerCheck(s->ts, uh, uc, &msg);
+ Py_END_ALLOW_THREADS;
- switch (rpmrc) {
- case RPMRC_OK:
- Py_INCREF(Py_None);
- result = Py_None;
- break;
-
- case RPMRC_NOKEY:
- PyErr_SetString(pyrpmError, "public key not availaiable");
- break;
-
- case RPMRC_NOTTRUSTED:
- PyErr_SetString(pyrpmError, "public key not trusted");
- break;
-
- case RPMRC_FAIL:
- default:
- PyErr_SetString(pyrpmError, msg);
- break;
- }
- msg = _free(msg);
-
- return result;
-}
-
-/** \ingroup py_c
- */
-static PyObject *
-rpmts_SetVSFlags(rpmtsObject * s, PyObject * args, PyObject * kwds)
-{
- rpmVSFlags vsflags;
- char * kwlist[] = {"flags", NULL};
-
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_SetVSFlags(%p) ts %p\n", s, s->ts);
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetVSFlags", kwlist,
- &vsflags))
- return NULL;
-
- /* XXX FIXME: value check on vsflags, or build pure python object
- * for it, and require an object of that type */
-
- return Py_BuildValue("i", rpmtsSetVSFlags(s->ts, vsflags));
-}
-
-/** \ingroup py_c
- */
-static PyObject *
-rpmts_GetVSFlags(rpmtsObject * s)
-{
- return Py_BuildValue("i", rpmtsVSFlags(s->ts));
-}
-
-/** \ingroup py_c
- */
-static PyObject *
-rpmts_SetColor(rpmtsObject * s, PyObject * args, PyObject * kwds)
-{
- rpm_color_t tscolor;
- char * kwlist[] = {"color", NULL};
-
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_SetColor(%p) ts %p\n", s, s->ts);
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:Color", kwlist, &tscolor))
- return NULL;
-
- /* XXX FIXME: value check on tscolor, or build pure python object
- * for it, and require an object of that type */
-
- return Py_BuildValue("i", rpmtsSetColor(s->ts, tscolor));
+ return Py_BuildValue("(iN)", rpmrc, utf8FromString(msg));
}
-/** \ingroup py_c
- */
static PyObject *
rpmts_PgpPrtPkts(rpmtsObject * s, PyObject * args, PyObject * kwds)
{
int rc;
char * kwlist[] = {"octets", NULL};
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_PgpPrtPkts(%p) ts %p\n", s, s->ts);
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:PgpPrtPkts", kwlist, &blob))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:PgpPrtPkts", kwlist, &blob))
return NULL;
- if (blob == Py_None) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- if (!PyString_Check(blob)) {
- PyErr_SetString(pyrpmError, "pgpPrtPkts takes a string of octets");
- return NULL;
- }
- pkt = (unsigned char *)PyString_AsString(blob);
- pktlen = PyString_Size(blob);
+ pkt = (unsigned char *)PyBytes_AsString(blob);
+ pktlen = PyBytes_Size(blob);
rc = pgpPrtPkts(pkt, pktlen, NULL, 1);
return Py_BuildValue("i", rc);
}
-/** \ingroup py_c
- */
static PyObject *
rpmts_PgpImportPubkey(rpmtsObject * s, PyObject * args, PyObject * kwds)
{
int rc;
char * kwlist[] = {"pubkey", NULL};
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_PgpImportPubkey(%p) ts %p\n", s, s->ts);
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:PgpImportPubkey",
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:PgpImportPubkey",
kwlist, &blob))
return NULL;
- if (blob == Py_None) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- if (!PyString_Check(blob)) {
- PyErr_SetString(pyrpmError, "PgpImportPubkey takes a string of octets");
- return NULL;
- }
- pkt = (unsigned char *)PyString_AsString(blob);
- pktlen = PyString_Size(blob);
+ pkt = (unsigned char *)PyBytes_AsString(blob);
+ pktlen = PyBytes_Size(blob);
rc = rpmtsImportPubkey(s->ts, pkt, pktlen);
return Py_BuildValue("i", rc);
}
-/** \ingroup py_c
- */
-static PyObject *
-rpmts_GetKeys(rpmtsObject * s)
+static PyObject *rpmts_setKeyring(rpmtsObject *s, PyObject *arg)
{
- const void **data = NULL;
- int num, i;
- PyObject *tuple;
-
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_GetKeys(%p) ts %p\n", s, s->ts);
-
- rpmtsGetKeys(s->ts, &data, &num);
- if (data == NULL || num <= 0) {
- data = _free(data);
- Py_INCREF(Py_None);
- return Py_None;
+ rpmKeyring keyring = NULL;
+ if (arg == Py_None || rpmKeyringFromPyObject(arg, &keyring)) {
+ return PyBool_FromLong(rpmtsSetKeyring(s->ts, keyring) == 0);
+ } else {
+ PyErr_SetString(PyExc_TypeError, "rpm.keyring or None expected");
+ return NULL;
}
+}
- tuple = PyTuple_New(num);
-
- for (i = 0; i < num; i++) {
- PyObject *obj;
- obj = (data[i] ? (PyObject *) data[i] : Py_None);
- Py_INCREF(obj);
- PyTuple_SetItem(tuple, i, obj);
- }
+static PyObject *rpmts_getKeyring(rpmtsObject *s, PyObject *args, PyObject *kwds)
+{
+ rpmKeyring keyring = NULL;
+ int autoload = 1;
+ char * kwlist[] = { "autoload", NULL };
- data = _free(data);
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:getKeyring",
+ kwlist, &autoload))
+ return NULL;
- return tuple;
+ keyring = rpmtsGetKeyring(s->ts, autoload);
+ if (keyring) {
+ return rpmKeyring_Wrap(&rpmKeyring_Type, keyring);
+ } else {
+ Py_RETURN_NONE;
+ }
}
-/** \ingroup py_c
- */
static void *
rpmtsCallback(const void * hd, const rpmCallbackType what,
- const rpm_off_t amount, const rpm_off_t total,
+ const rpm_loff_t amount, const rpm_loff_t total,
const void * pkgKey, rpmCallbackData data)
{
Header h = (Header) hd;
PyObject * args, * result;
static FD_t fd;
- if (cbInfo->pythonError) return NULL;
if (cbInfo->cb == Py_None) return NULL;
/* Synthesize a python object for callback (if necessary). */
if (pkgObj == NULL) {
if (h) {
- const char * n = NULL;
- (void) headerNVR(h, &n, NULL, NULL);
- pkgObj = Py_BuildValue("s", n);
+ pkgObj = utf8FromString(headerGetString(h, RPMTAG_NAME));
} else {
pkgObj = Py_None;
Py_INCREF(pkgObj);
PyEval_RestoreThread(cbInfo->_save);
- args = Py_BuildValue("(illOO)", what, amount, total, pkgObj, cbInfo->data);
+ args = Py_BuildValue("(iLLOO)", what, amount, total, pkgObj, cbInfo->data);
result = PyEval_CallObject(cbInfo->cb, args);
Py_DECREF(args);
Py_DECREF(pkgObj);
if (!result) {
- cbInfo->pythonError = 1;
- cbInfo->_save = PyEval_SaveThread();
- return NULL;
+ die(cbInfo->cb);
}
if (what == RPMCALLBACK_INST_OPEN_FILE) {
int fdno;
if (!PyArg_Parse(result, "i", &fdno)) {
- cbInfo->pythonError = 1;
- cbInfo->_save = PyEval_SaveThread();
- return NULL;
+ die(cbInfo->cb);
}
Py_DECREF(result);
cbInfo->_save = PyEval_SaveThread();
fd = fdDup(fdno);
-if (_rpmts_debug)
-fprintf(stderr, "\t%p = fdDup(%d)\n", fd, fdno);
-
fcntl(Fileno(fd), F_SETFD, FD_CLOEXEC);
return fd;
} else
if (what == RPMCALLBACK_INST_CLOSE_FILE) {
-if (_rpmts_debug)
-fprintf(stderr, "\tFclose(%p)\n", fd);
Fclose (fd);
- } else {
-if (_rpmts_debug)
-fprintf(stderr, "\t%d:%d key %p\n", amount, total, pkgKey);
}
Py_DECREF(result);
return NULL;
}
-/** \ingroup py_c
- */
-static PyObject *
-rpmts_SetFlags(rpmtsObject * s, PyObject * args, PyObject * kwds)
-{
- rpmtransFlags transFlags = 0;
- char * kwlist[] = {"flags", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:SetFlags", kwlist,
- &transFlags))
- return NULL;
-
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_SetFlags(%p) ts %p transFlags %x\n", s, s->ts, transFlags);
-
- /* XXX FIXME: value check on flags, or build pure python object
- * for it, and require an object of that type */
-
- return Py_BuildValue("i", rpmtsSetFlags(s->ts, transFlags));
-}
-
-/** \ingroup py_c
- */
static PyObject *
-rpmts_SetProbFilter(rpmtsObject * s, PyObject * args, PyObject * kwds)
-{
- rpmprobFilterFlags ignoreSet = 0;
- rpmprobFilterFlags oignoreSet;
- char * kwlist[] = {"ignoreSet", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "i:ProbFilter", kwlist,
- &ignoreSet))
- return NULL;
-
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_SetProbFilter(%p) ts %p ignoreSet %x\n", s, s->ts, ignoreSet);
-
- oignoreSet = s->ignoreSet;
- s->ignoreSet = ignoreSet;
-
- return Py_BuildValue("i", oignoreSet);
-}
-
-/** \ingroup py_c
- */
-static rpmpsObject *
rpmts_Problems(rpmtsObject * s)
{
-
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_Problems(%p) ts %p\n", s, s->ts);
-
- return rpmps_Wrap( rpmtsProblems(s->ts) );
+ rpmps ps = rpmtsProblems(s->ts);
+ PyObject *problems = rpmps_AsList(ps);
+ rpmpsFree(ps);
+ return problems;
}
-/** \ingroup py_c
- */
static PyObject *
rpmts_Run(rpmtsObject * s, PyObject * args, PyObject * kwds)
{
int rc;
- PyObject * list;
- rpmps ps;
- rpmpsi psi;
struct rpmtsCallbackType_s cbInfo;
- char * kwlist[] = {"callback", "data", NULL};
+ rpmprobFilterFlags ignoreSet;
+ char * kwlist[] = {"callback", "data", "ignoreSet", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO:Run", kwlist,
- &cbInfo.cb, &cbInfo.data))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOi:Run", kwlist,
+ &cbInfo.cb, &cbInfo.data, &ignoreSet))
return NULL;
cbInfo.tso = s;
- cbInfo.pythonError = 0;
cbInfo._save = PyEval_SaveThread();
if (cbInfo.cb != NULL) {
(void) rpmtsSetNotifyCallback(s->ts, rpmtsCallback, (void *) &cbInfo);
}
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_Run(%p) ts %p ignore %x\n", s, s->ts, s->ignoreSet);
-
- rc = rpmtsRun(s->ts, NULL, s->ignoreSet);
- ps = rpmtsProblems(s->ts);
+ rc = rpmtsRun(s->ts, NULL, ignoreSet);
if (cbInfo.cb)
(void) rpmtsSetNotifyCallback(s->ts, NULL, NULL);
PyEval_RestoreThread(cbInfo._save);
- if (cbInfo.pythonError) {
- ps = rpmpsFree(ps);
- return NULL;
- }
-
- if (rc < 0) {
- list = PyList_New(0);
- return list;
- } else if (!rc) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- list = PyList_New(0);
- psi = rpmpsInitIterator(ps);
- while (rpmpsNextIterator(psi) >= 0) {
- rpmProblem p = rpmpsGetProblem(psi);
- char * ps = rpmProblemString(p);
- PyObject * prob = Py_BuildValue("s(isN)", ps,
- rpmProblemGetType(p),
- rpmProblemGetStr(p),
- PyLong_FromLongLong(rpmProblemGetLong(p)));
- PyList_Append(list, prob);
- free(ps);
- Py_DECREF(prob);
- }
-
- psi = rpmpsFreeIterator(psi);
- ps = rpmpsFree(ps);
-
- return list;
-}
-
-#if Py_TPFLAGS_HAVE_ITER
-static PyObject *
-rpmts_iter(rpmtsObject * s)
-{
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_iter(%p) ts %p\n", s, s->ts);
-
- Py_INCREF(s);
- return (PyObject *)s;
+ return Py_BuildValue("i", rc);
}
-#endif
-/**
- * @todo Add TR_ADDED filter to iterator.
- */
static PyObject *
rpmts_iternext(rpmtsObject * s)
{
PyObject * result = NULL;
rpmte te;
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_iternext(%p) ts %p tsi %p %d\n", s, s->ts, s->tsi, s->tsiFilter);
-
/* Reset iterator on 1st entry. */
if (s->tsi == NULL) {
s->tsi = rpmtsiInit(s->ts);
if (s->tsi == NULL)
return NULL;
- s->tsiFilter = 0;
}
- te = rpmtsiNext(s->tsi, s->tsiFilter);
+ te = rpmtsiNext(s->tsi, 0);
if (te != NULL) {
- result = (PyObject *) rpmte_Wrap(te);
+ result = rpmte_Wrap(&rpmte_Type, te);
} else {
s->tsi = rpmtsiFree(s->tsi);
- s->tsiFilter = 0;
}
return result;
}
-/**
- * @todo Add TR_ADDED filter to iterator.
- */
static PyObject *
-rpmts_Next(rpmtsObject * s)
-{
- PyObject * result;
-
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_Next(%p) ts %p\n", s, s->ts);
-
- result = rpmts_iternext(s);
-
- if (result == NULL) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- return result;
-}
-
-/**
- */
-static specObject *
-spec_Parse(rpmtsObject * s, PyObject * args, PyObject * kwds)
-{
- const char * specfile;
- rpmSpec spec;
- char * buildRoot = NULL;
- int recursing = 0;
- char * passPhrase = "";
- char *cookie = NULL;
- int anyarch = 1;
- int force = 1;
- char * kwlist[] = {"specfile", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:Parse", kwlist, &specfile))
- return NULL;
-
- if (parseSpec(s->ts, specfile,"/", buildRoot,recursing, passPhrase,
- cookie, anyarch, force)!=0) {
- PyErr_SetString(pyrpmError, "can't parse specfile\n");
- return NULL;
- }
-
- spec = rpmtsSpec(s->ts);
- return spec_Wrap(spec);
-}
-
-/**
- */
-static rpmmiObject *
rpmts_Match(rpmtsObject * s, PyObject * args, PyObject * kwds)
{
- PyObject *TagN = NULL;
PyObject *Key = NULL;
+ PyObject *str = NULL;
+ PyObject *mio = NULL;
char *key = NULL;
/* XXX lkey *must* be a 32 bit integer, int "works" on all known platforms. */
int lkey = 0;
int len = 0;
- rpmTag tag = RPMDBI_PACKAGES;
+ rpmDbiTagVal tag = RPMDBI_PACKAGES;
char * kwlist[] = {"tagNumber", "key", NULL};
-if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_Match(%p) ts %p\n", s, s->ts);
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:Match", kwlist,
- &TagN, &Key))
- return NULL;
-
- if (TagN && (tag = tagNumFromPyObject (TagN)) == -1) {
- PyErr_SetString(PyExc_TypeError, "unknown tag type");
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&O:Match", kwlist,
+ tagNumFromPyObject, &tag, &Key))
return NULL;
- }
if (Key) {
- if (PyString_Check(Key) || PyUnicode_Check(Key)) {
- key = PyString_AsString(Key);
- len = PyString_Size(Key);
- } else if (PyInt_Check(Key)) {
+ if (PyInt_Check(Key)) {
lkey = PyInt_AsLong(Key);
key = (char *)&lkey;
len = sizeof(lkey);
+ } else if (PyLong_Check(Key)) {
+ lkey = PyLong_AsLong(Key);
+ key = (char *)&lkey;
+ len = sizeof(lkey);
+ } else if (utf8FromPyObject(Key, &str)) {
+ key = PyBytes_AsString(str);
+ len = PyBytes_Size(str);
} else {
PyErr_SetString(PyExc_TypeError, "unknown key type");
return NULL;
}
+ /* One of the conversions above failed, exception is set already */
+ if (PyErr_Occurred()) goto exit;
}
/* XXX If not already opened, open the database O_RDONLY now. */
if (rpmtsGetRdb(s->ts) == NULL) {
int rc = rpmtsOpenDB(s->ts, O_RDONLY);
if (rc || rpmtsGetRdb(s->ts) == NULL) {
- PyErr_SetString(PyExc_TypeError, "rpmdb open failed");
- return NULL;
+ PyErr_SetString(pyrpmError, "rpmdb open failed");
+ goto exit;
}
}
- return rpmmi_Wrap( rpmtsInitIterator(s->ts, tag, key, len), (PyObject*)s);
+ mio = rpmmi_Wrap(&rpmmi_Type, rpmtsInitIterator(s->ts, tag, key, len), (PyObject*)s);
+
+exit:
+ Py_XDECREF(str);
+ return mio;
}
+static PyObject *
+rpmts_index(rpmtsObject * s, PyObject * args, PyObject * kwds)
+{
+ rpmDbiTagVal tag;
+ PyObject *mio = NULL;
+ char * kwlist[] = {"tag", NULL};
-/** \ingroup py_c
- */
-static struct PyMethodDef rpmts_methods[] = {
- {"Debug", (PyCFunction)rpmts_Debug, METH_VARARGS|METH_KEYWORDS,
- NULL},
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:Keys", kwlist,
+ tagNumFromPyObject, &tag))
+ return NULL;
+
+ /* XXX If not already opened, open the database O_RDONLY now. */
+ if (rpmtsGetRdb(s->ts) == NULL) {
+ int rc = rpmtsOpenDB(s->ts, O_RDONLY);
+ if (rc || rpmtsGetRdb(s->ts) == NULL) {
+ PyErr_SetString(pyrpmError, "rpmdb open failed");
+ goto exit;
+ }
+ }
+
+ rpmdbIndexIterator ii = rpmdbIndexIteratorInit(rpmtsGetRdb(s->ts), tag);
+ if (ii == NULL) {
+ PyErr_SetString(PyExc_KeyError, "No index for this tag");
+ return NULL;
+ }
+ mio = rpmii_Wrap(&rpmii_Type, ii, (PyObject*)s);
+
+exit:
+ return mio;
+}
- {"addInstall", (PyCFunction) rpmts_AddInstall, METH_VARARGS|METH_KEYWORDS,
- NULL },
+static struct PyMethodDef rpmts_methods[] = {
+ {"addInstall", (PyCFunction) rpmts_AddInstall, METH_VARARGS,
+ "ts.addInstall(hdr, data, mode) -- Add transaction element(s)\n"
+ "representing an installation or update of a package.\n\n"
+ "Args:\n"
+ " hdr : the header to be added\n"
+ " data : user data that will be passed to the transaction callback\n\t\tduring transaction execution\n"
+ " mode : optional argument that specifies if this package should be\n\t\tinstalled ('i'), upgraded ('u')"},
+ {"addReinstall", (PyCFunction) rpmts_AddReinstall, METH_VARARGS,
+ "ts.addReinstall(hdr, data) -- Adds transaction elements\nrepresenting a reinstall of an already installed package.\n\nSee addInstall for details."},
{"addErase", (PyCFunction) rpmts_AddErase, METH_VARARGS|METH_KEYWORDS,
- NULL },
+ "addErase(name) -- Add a transaction element representing an erase\nof an installed package.\n\n"
+ " name: the package name to be erased"},
{"check", (PyCFunction) rpmts_Check, METH_VARARGS|METH_KEYWORDS,
- NULL },
+ "ts.check( )-- Perform a dependency check on the transaction set.\n"
+ " After headers have been added to a transaction set,\n"
+ " a dependencycheck can be performed to make sure that\n"
+ " all package dependencies are satisfied.\n"
+ "Return None If there are no unresolved dependencies\n"
+ " Otherwise a list of complex tuples is returned,\n"
+ " one tuple per unresolved dependency, with\n"
+ "The format of the dependency tuple is:\n"
+ " ((packageName, packageVersion, packageRelease),\n"
+ " (reqName, reqVersion),\n"
+ " needsFlags,\n"
+ " suggestedPackage,\n"
+ " sense)\n"
+ " packageName, packageVersion, packageRelease are the name,\n"
+ " version, and release of the package that has the unresolved\n"
+ " dependency or conflict.\n"
+ " The reqName and reqVersion are the name and version of the\n"
+ " requirement or conflict.\n"
+ " The needsFlags is a bitfield that describes the versioned\n"
+ " nature of a requirement or conflict. The constants\n"
+ " rpm.RPMSENSE_LESS, rpm.RPMSENSE_GREATER, and\n"
+ " rpm.RPMSENSE_EQUAL can be logical ANDed with the needsFlags\n"
+ " to get versioned dependency information.\n"
+ " suggestedPackage is a tuple if the dependency check was aware\n"
+ " of a package that solves this dependency problem when the\n"
+ " dependency check was run. Packages that are added to the\n"
+ " transaction set as \"available\" are examined during the\n"
+ " dependency check as possible dependency solvers. The tuple\n"
+ " contains two values, (header, suggestedName). These are set to\n"
+ " the header of the suggested package and its name, respectively.\n"
+ " If there is no known package to solve the dependency problem,\n"
+ " suggestedPackage is None.\n"
+ " The constants rpm.RPMDEP_SENSE_CONFLICTS and\n"
+ " rpm.RPMDEP_SENSE_REQUIRES are set to show a dependency as a\n"
+ " requirement or a conflict.\n"},
{"order", (PyCFunction) rpmts_Order, METH_NOARGS,
- NULL },
- {"setFlags", (PyCFunction) rpmts_SetFlags, METH_VARARGS|METH_KEYWORDS,
-"ts.setFlags(transFlags) -> previous transFlags\n\
-- Set control bit(s) for executing ts.run().\n\
- Note: This method replaces the 1st argument to the old ts.run()\n" },
- {"setProbFilter", (PyCFunction) rpmts_SetProbFilter, METH_VARARGS|METH_KEYWORDS,
-"ts.setProbFilter(ignoreSet) -> previous ignoreSet\n\
-- Set control bit(s) for ignoring problems found by ts.run().\n\
- Note: This method replaces the 2nd argument to the old ts.run()\n" },
+ "ts.order() Do a topological sort of added element relations." },
{"problems", (PyCFunction) rpmts_Problems, METH_NOARGS,
"ts.problems() -> ps\n\
- Return current problem set.\n" },
- Run a transaction set, returning list of problems found.\n\
Note: The callback may not be None.\n" },
{"clean", (PyCFunction) rpmts_Clean, METH_NOARGS,
- NULL },
+ "ts.clean()-- Free memory needed only for dependency checks\nand ordering. Should not be needed in normal operation." },
+ {"clear", (PyCFunction) rpmts_Clear, METH_NOARGS,
+"ts.clear() -> None\n\
+Remove all elements from the transaction set\n" },
{"openDB", (PyCFunction) rpmts_OpenDB, METH_NOARGS,
-"ts.openDB() -> None\n\
-- Open the default transaction rpmdb.\n\
- Note: The transaction rpmdb is lazily opened, so ts.openDB() is seldom needed.\n" },
+"ts.openDB() -> None -- Open the default transaction rpmdb.\n\n\
+ Note: The transaction rpmdb is lazily opened,\n so ts.openDB() is seldom needed.\n" },
{"closeDB", (PyCFunction) rpmts_CloseDB, METH_NOARGS,
"ts.closeDB() -> None\n\
- Close the default transaction rpmdb.\n\
- Note: ts.closeDB() disables lazy opens, and should hardly ever be used.\n" },
+ Note: ts.closeDB() disables lazy opens,\n\
+ and should hardly ever be used.\n" },
{"initDB", (PyCFunction) rpmts_InitDB, METH_NOARGS,
"ts.initDB() -> None\n\
- Initialize the default transaction rpmdb.\n\
{"verifyDB", (PyCFunction) rpmts_VerifyDB, METH_NOARGS,
"ts.verifyDB() -> None\n\
- Verify the default transaction rpmdb.\n" },
- {"hdrFromFdno",(PyCFunction) rpmts_HdrFromFdno,METH_VARARGS|METH_KEYWORDS,
+ {"hdrFromFdno",(PyCFunction) rpmts_HdrFromFdno,METH_O,
"ts.hdrFromFdno(fdno) -> hdr\n\
- Read a package header from a file descriptor.\n" },
- {"hdrCheck", (PyCFunction) rpmts_HdrCheck, METH_VARARGS|METH_KEYWORDS,
- NULL },
- {"setVSFlags",(PyCFunction) rpmts_SetVSFlags, METH_VARARGS|METH_KEYWORDS,
-"ts.setVSFlags(vsflags) -> ovsflags\n\
-- Set signature verification flags. Values for vsflags are:\n\
- rpm.RPMVSF_NOHDRCHK if set, don't check rpmdb headers\n\
- rpm.RPMVSF_NEEDPAYLOAD if not set, check header+payload (if possible)\n\
- rpm.RPMVSF_NOSHA1HEADER if set, don't check header SHA1 digest\n\
- rpm.RPMVSF_NODSAHEADER if set, don't check header DSA signature\n\
- rpm.RPMVSF_NOMD5 if set, don't check header+payload MD5 digest\n\
- rpm.RPMVSF_NODSA if set, don't check header+payload DSA signature\n\
- rpm.RPMVSF_NORSA if set, don't check header+payload RSA signature\n\
- rpm._RPMVSF_NODIGESTS if set, don't check digest(s)\n\
- rpm._RPMVSF_NOSIGNATURES if set, don't check signature(s)\n" },
- {"getVSFlags",(PyCFunction) rpmts_GetVSFlags, METH_NOARGS,
-"ts.getVSFlags() -> vsflags\n\
-- Retrieve current signature verification flags from transaction\n" },
- {"setColor",(PyCFunction) rpmts_SetColor, METH_VARARGS|METH_KEYWORDS,
- NULL },
+ {"hdrCheck", (PyCFunction) rpmts_HdrCheck, METH_O,
+ "ts.hdrCheck(hdrblob) -- Check header consistency,\nperforming headerGetEntry() the hard way.\n\n"
+ "Sanity checks on the header are performed while looking for a\n"
+ "header-only digest or signature to verify the blob. If found,\n"
+ "the digest or signature is verified.\n\n"
+ "\thdrblob : unloaded header blob\n"
+ "Return tuple (int status, message string)"},
{"pgpPrtPkts", (PyCFunction) rpmts_PgpPrtPkts, METH_VARARGS|METH_KEYWORDS,
- NULL },
+ "pgpPrtPkts(octets) -- Print/parse a OpenPGP packet(s).\n\nReturn 0 on success." },
{"pgpImportPubkey", (PyCFunction) rpmts_PgpImportPubkey, METH_VARARGS|METH_KEYWORDS,
- NULL },
- {"getKeys", (PyCFunction) rpmts_GetKeys, METH_NOARGS,
- NULL },
- {"parseSpec", (PyCFunction) spec_Parse, METH_VARARGS|METH_KEYWORDS,
-"ts.parseSpec(\"/path/to/foo.spec\") -> spec\n\
-- Parse a spec file.\n" },
+ "pgpImportPubkey(pubkey) -- Import public key packet." },
+ {"getKeyring", (PyCFunction) rpmts_getKeyring, METH_VARARGS|METH_KEYWORDS,
+ "ts.getKeyring(autoload=False) -- Return key ring object." },
+ {"setKeyring", (PyCFunction) rpmts_setKeyring, METH_O,
+ "ts.setKeyring(keyring) -- Set key ring used for checking signatures\n\n"
+ "Pass None for an empty key ring." },
{"dbMatch", (PyCFunction) rpmts_Match, METH_VARARGS|METH_KEYWORDS,
-"ts.dbMatch([TagN, [key, [len]]]) -> mi\n\
+"ts.dbMatch([TagN, [key]]) -> mi\n\
- Create a match iterator for the default transaction rpmdb.\n" },
- {"next", (PyCFunction)rpmts_Next, METH_NOARGS,
-"ts.next() -> te\n\
-- Retrieve next transaction set element.\n" },
+ {"dbIndex", (PyCFunction) rpmts_index, METH_VARARGS|METH_KEYWORDS,
+"ts.dbIndex(TagN) -> ii\n\
+- Create a key iterator for the default transaction rpmdb.\n" },
{NULL, NULL} /* sentinel */
};
-/** \ingroup py_c
- */
static void rpmts_dealloc(rpmtsObject * s)
{
-if (_rpmts_debug)
-fprintf(stderr, "%p -- ts %p db %p\n", s, s->ts, rpmtsGetRdb(s->ts));
s->ts = rpmtsFree(s->ts);
-
- if (s->scriptFd) Fclose(s->scriptFd);
- /* this will free the keyList, and decrement the ref count of all
- the items on the list as well :-) */
- Py_DECREF(s->keyList);
- PyObject_Del((PyObject *)s);
+ Py_XDECREF(s->scriptFd);
+ Py_XDECREF(s->keyList);
+ Py_TYPE(s)->tp_free((PyObject *)s);
}
-static PyObject * rpmts_getattro(PyObject * o, PyObject * n)
+static PyObject * rpmts_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
{
- return PyObject_GenericGetAttr(o, n);
+ rpmtsObject * s = (rpmtsObject *)subtype->tp_alloc(subtype, 0);
+ if (s == NULL) return NULL;
+
+ s->ts = rpmtsCreate();
+ s->scriptFd = NULL;
+ s->tsi = NULL;
+ s->keyList = PyList_New(0);
+ return (PyObject *) s;
}
-/** \ingroup py_c
- */
-static int rpmts_setattro(PyObject * o, PyObject * n, PyObject * v)
+static int rpmts_init(rpmtsObject *s, PyObject *args, PyObject *kwds)
{
- rpmtsObject *s = (rpmtsObject *)o;
- char * name = PyString_AsString(n);
- int fdno;
-
- if (!strcmp(name, "scriptFd")) {
- if (!PyArg_Parse(v, "i", &fdno)) return 0;
- if (fdno < 0) {
- PyErr_SetString(PyExc_TypeError, "bad file descriptor");
- return -1;
- } else {
- s->scriptFd = fdDup(fdno);
- rpmtsSetScriptFd(s->ts, s->scriptFd);
- }
- } else {
- PyErr_SetString(PyExc_AttributeError, name);
+ const char * rootDir = "/";
+ rpmVSFlags vsflags = rpmExpandNumeric("%{?__vsflags}");
+ char * kwlist[] = {"rootdir", "vsflags", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|si:rpmts_new", kwlist,
+ &rootDir, &vsflags))
return -1;
- }
+
+ (void) rpmtsSetRootDir(s->ts, rootDir);
+ /* XXX: make this use common code with rpmts_SetVSFlags() to check the
+ * python objects */
+ (void) rpmtsSetVSFlags(s->ts, vsflags);
return 0;
}
-/** \ingroup py_c
- */
-static int rpmts_init(rpmtsObject * s, PyObject *args, PyObject *kwds)
+static PyObject *rpmts_get_tid(rpmtsObject *s, void *closure)
{
- /* nothing to do atm... */
- return 0;
+ return Py_BuildValue("i", rpmtsGetTid(s->ts));
}
-/** \ingroup py_c
- */
-static void rpmts_free(rpmtsObject * s)
+static PyObject *rpmts_get_rootDir(rpmtsObject *s, void *closure)
{
-if (_rpmts_debug)
-fprintf(stderr, "%p -- ts %p db %p\n", s, s->ts, rpmtsGetRdb(s->ts));
- s->ts = rpmtsFree(s->ts);
+ return utf8FromString(rpmtsRootDir(s->ts));
+}
- if (s->scriptFd)
- Fclose(s->scriptFd);
+static int rpmts_set_scriptFd(rpmtsObject *s, PyObject *value, void *closure)
+{
+ rpmfdObject *fdo = NULL;
+ int rc = 0;
+ if (PyArg_Parse(value, "O&", rpmfdFromPyObject, &fdo)) {
+ Py_XDECREF(s->scriptFd);
+ s->scriptFd = fdo;
+ rpmtsSetScriptFd(s->ts, rpmfdGetFd(s->scriptFd));
+ } else if (value == Py_None) {
+ Py_XDECREF(s->scriptFd);
+ s->scriptFd = NULL;
+ rpmtsSetScriptFd(s->ts, NULL);
+ } else {
+ rc = -1;
+ }
+ return rc;
+}
- /* this will free the keyList, and decrement the ref count of all
- the items on the list as well :-) */
- Py_DECREF(s->keyList);
+static PyObject *rpmts_get_color(rpmtsObject *s, void *closure)
+{
+ return Py_BuildValue("i", rpmtsColor(s->ts));
+}
- PyObject_Del((PyObject *)s);
+static PyObject *rpmts_get_prefcolor(rpmtsObject *s, void *closure)
+{
+ return Py_BuildValue("i", rpmtsPrefColor(s->ts));
}
-/** \ingroup py_c
- */
-static PyObject * rpmts_alloc(PyTypeObject * subtype, int nitems)
+static int rpmts_set_color(rpmtsObject *s, PyObject *value, void *closure)
{
- PyObject * s = PyType_GenericAlloc(subtype, nitems);
+ rpm_color_t color;
+ if (!PyArg_Parse(value, "i", &color)) return -1;
-if (_rpmts_debug < 0)
-fprintf(stderr, "*** rpmts_alloc(%p,%d) ret %p\n", subtype, nitems, s);
- return s;
+ /* TODO: validate the bits */
+ rpmtsSetColor(s->ts, color);
+ return 0;
}
-/** \ingroup py_c
- */
-static PyObject * rpmts_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
+static int rpmts_set_prefcolor(rpmtsObject *s, PyObject *value, void *closure)
{
- rpmtsObject * s = (void *) PyObject_New(rpmtsObject, subtype);
+ rpm_color_t color;
+ if (!PyArg_Parse(value, "i", &color)) return -1;
- char * rootDir = "/";
- rpmVSFlags vsflags = rpmExpandNumeric("%{?__vsflags}");
- char * kwlist[] = {"rootdir", "vsflags", 0};
+ /* TODO: validate the bits */
+ rpmtsSetPrefColor(s->ts, color);
+ return 0;
+}
- if (_rpmts_debug < 0)
- fprintf(stderr, "*** rpmts_new(%p,%p,%p)\n", s, args, kwds);
+static int rpmts_set_flags(rpmtsObject *s, PyObject *value, void *closure)
+{
+ rpmtransFlags flags;
+ if (!PyArg_Parse(value, "i", &flags)) return -1;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|si:rpmts_init", kwlist,
- &rootDir, &vsflags))
- return NULL;
+ /* TODO: validate the bits */
+ rpmtsSetFlags(s->ts, flags);
+ return 0;
+}
- s->ts = rpmtsCreate();
- /* XXX: Why is there no rpmts_SetRootDir() ? */
- (void) rpmtsSetRootDir(s->ts, rootDir);
- /* XXX: make this use common code with rpmts_SetVSFlags() to check the
- * python objects */
- (void) rpmtsSetVSFlags(s->ts, vsflags);
- s->keyList = PyList_New(0);
- s->scriptFd = NULL;
- s->tsi = NULL;
- s->tsiFilter = 0;
+static int rpmts_set_vsflags(rpmtsObject *s, PyObject *value, void *closure)
+{
+ rpmVSFlags flags;
+ if (!PyArg_Parse(value, "i", &flags)) return -1;
- if (_rpmts_debug)
- fprintf(stderr, "%p ++ ts %p db %p\n", s, s->ts, rpmtsGetRdb(s->ts));
+ /* TODO: validate the bits */
+ rpmtsSetVSFlags(s->ts, flags);
+ return 0;
+}
- return (PyObject *)s;
+static PyObject *rpmts_get_flags(rpmtsObject *s, void *closure)
+{
+ return Py_BuildValue("i", rpmtsFlags(s->ts));
+}
+
+static PyObject *rpmts_get_vsflags(rpmtsObject *s, void *closure)
+{
+ return Py_BuildValue("i", rpmtsVSFlags(s->ts));
}
-/**
- */
static char rpmts_doc[] =
-"";
+ "A python rpm.ts object represents an RPM transaction set.\n"
+ "\n"
+ "The transaction set is the workhorse of RPM. It performs the\n"
+ "installation and upgrade of packages. The rpm.ts object is\n"
+ "instantiated by the TransactionSet function in the rpm module.\n"
+ "\n"
+ "The TransactionSet function takes two optional arguments. The first\n"
+ "argument is the root path. The second is the verify signature disable\n"
+ "flags, a set of the following bits:\n"
+ "\n"
+ "- rpm.RPMVSF_NOHDRCHK if set, don't check rpmdb headers\n"
+ "- rpm.RPMVSF_NEEDPAYLOAD if not set, check header+payload\n"
+ " (if possible)\n"
+ "- rpm.RPMVSF_NOSHA1HEADER if set, don't check header SHA1 digest\n"
+ "- rpm.RPMVSF_NODSAHEADER if set, don't check header DSA signature\n"
+ "- rpm.RPMVSF_NOMD5 if set, don't check header+payload MD5 digest\n"
+ "- rpm.RPMVSF_NODSA if set, don't check header+payload DSA signature\n"
+ "- rpm.RPMVSF_NORSA if set, don't check header+payload RSA signature\n"
+ "\n"
+ "For convenience, there are the following masks:\n"
+ "- rpm._RPMVSF_NODIGESTS if set, don't check digest(s).\n"
+ "- rpm._RPMVSF_NOSIGNATURES if set, don't check signature(s).\n\n"
+ "The transaction set offers an read only iterable interface for the\ntransaction elements added by the .addInstall(), .addErase() and\n.addReinstall() methods.";
+
+static PyGetSetDef rpmts_getseters[] = {
+ /* only provide a setter until we have rpmfd wrappings */
+ {"scriptFd", NULL, (setter)rpmts_set_scriptFd,
+ "write only, file descriptor the output of script gets written to." },
+ {"tid", (getter)rpmts_get_tid, NULL,
+ "read only, current transaction id, i.e. transaction time stamp."},
+ {"rootDir", (getter)rpmts_get_rootDir, NULL,
+ "read only, directory rpm treats as root of the file system." },
+ {"_color", (getter)rpmts_get_color, (setter)rpmts_set_color, NULL},
+ {"_prefcolor", (getter)rpmts_get_prefcolor, (setter)rpmts_set_prefcolor, NULL},
+ {"_flags", (getter)rpmts_get_flags, (setter)rpmts_set_flags, NULL},
+ {"_vsflags", (getter)rpmts_get_vsflags, (setter)rpmts_set_vsflags, NULL},
+ { NULL }
+};
-/** \ingroup py_c
- */
PyTypeObject rpmts_Type = {
- PyObject_HEAD_INIT(&PyType_Type)
- 0, /* ob_size */
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
"rpm.ts", /* tp_name */
sizeof(rpmtsObject), /* tp_size */
0, /* tp_itemsize */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
- (getattrofunc) rpmts_getattro, /* tp_getattro */
- (setattrofunc) rpmts_setattro, /* tp_setattro */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
rpmts_doc, /* tp_doc */
-#if Py_TPFLAGS_HAVE_ITER
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
- (getiterfunc) rpmts_iter, /* tp_iter */
+ PyObject_SelfIter, /* tp_iter */
(iternextfunc) rpmts_iternext, /* tp_iternext */
rpmts_methods, /* tp_methods */
0, /* tp_members */
- 0, /* tp_getset */
+ rpmts_getseters, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc) rpmts_init, /* tp_init */
- (allocfunc) rpmts_alloc, /* tp_alloc */
+ 0, /* tp_alloc */
(newfunc) rpmts_new, /* tp_new */
- (freefunc) rpmts_free, /* tp_free */
+ 0, /* tp_free */
0, /* tp_is_gc */
-#endif
};
-
-/**
- */
-PyObject *
-rpmts_Create(PyObject * self, PyObject * args, PyObject * kwds)
-{
- return PyObject_Call((PyObject *) &rpmts_Type, args, kwds);
-}