Oooh, very nice!
Yah, I've been fighting rpmlib -> rpmdb -> rpmio issues
for years. It _REALLY_ twists up rpmlib code.
FWIW, rpmnsProbeSignature() (and all of rpmns.c)
can likely be moved from rpmlib -> rpmdb w/o tremendous
pain. Only ts->pkpkts (the 1-level LRU cache for platforms
that don't have keyutils or equivalent pubkey cache) forces
the use of rpmts.
Moving rpmdb->rpmio is possible, but the twist is that
an rpmdb (and a Header) are currently what is used
as data store for pubkey keyring. There are of course many
other data stores that could/should be used.
There are other reasons, including bindings to rpmts methods,
that make perfect sense for leaving/using rpmluaext.c
exactly as implemented.
73 de Jeff
On Jan 1, 2008, at 3:52 PM, Ralf S. Engelschall wrote:
> RPM Package Manager, CVS Repository
> http://rpm5.org/cvs/
>
> ______________________________________________________________________
> ______
>
> Server: rpm5.org Name: Ralf S. Engelschall
> Root: /v/rpm/cvs Email: rse@rpm5.org
> Module: rpm Date: 01-Jan-2008
> 21:52:23
> Branch: HEAD Handle: 2008010120522200
>
> Added files:
> rpm/lib rpmluaext.c rpmluaext.h
> Modified files:
> rpm VENDOR
> rpm/lib Makefile.am librpm.vers rpmrc.c
>
> Log:
> Commit the OpenPKG-scoped functionality
> "rpm-lua-extensions-based-on-rpm-lib-functionality". This adds
> some
> essential RPM Lua extensions based on "lib" functionality.
>
> Background: the RPM Lua implementation is part of "rpmio".
> Hence it
> cannot use RPM "lib" functionality without breaking the RPM
> library
> dependency hierarchy. Nevertheless it is very important for
> OpenPKG to
> have some RPM "lib" functionality in RPM Lua. The lib/rpmluaext.
> [ch]
> provides this now.
>
> It attaches additional functionality into the RPM Lua scope
> from within
> RPM "lib". Currently it mainly provides the following essential
> methods:
>
> 1. rpm.digest() for calculating a message digest
>
> 2. rpm.signature() to check the public key signature on a
> clearsigned file or a file and its detached signature
>
> 3. rpm.query() to query the RPMDB similar to
> "rpm -q --qf '[...]' [-a] [...]"
>
> This RPM Lua functionality is essential for the forthcoming RPM
> Lua
> based integrity checking framework OpenPKG developed and which
> will be
> provided soon, too.
>
> Summary:
> Revision Changes Path
> 2.23 +18 -0 rpm/VENDOR
> 2.172 +2 -2 rpm/lib/Makefile.am
> 1.31 +1 -0 rpm/lib/librpm.vers
> 2.1 +254 -0 rpm/lib/rpmluaext.c
> 2.1 +25 -0 rpm/lib/rpmluaext.h
> 2.222 +2 -0 rpm/lib/rpmrc.c
>
> ______________________________________________________________________
> ______
>
> patch -p0 <<'@@ .'
> Index: rpm/VENDOR
>
> ======================================================================
> ======
> $ cvs diff -u -r2.22 -r2.23 VENDOR
> --- rpm/VENDOR 31 Dec 2007 12:10:50 -0000 2.22
> +++ rpm/VENDOR 1 Jan 2008 20:52:22 -0000 2.23
> @@ -340,6 +340,24 @@
> best would be to export also arbitrary tags
> as macros!
>
> ______________________________________________________________________
> __
>
> + Change: rpm-lua-extensions-based-on-rpm-lib-
> functionality
> + Purpose: Adds RPM Lua extensions based on "lib"
> functionality
> + Reason: The RPM Lua implementation is part of
> "rpmio". Hence
> + it cannot use RPM "lib" functionality without
> + breaking the RPM library dependency hierarchy.
> + Nevertheless it is very useful to have RPM
> "lib"
> + functionality in RPM Lua. The lib/rpmluaext.
> [ch]
> + provides this now. It attaches additional
> + functionality into the RPM Lua scope from
> within
> + RPM "lib". Currently it mainly provides the
> + following essential methods: rpm.digest() for
> + calculating a message digest, rpm.signature
> () to
> + check the public key signature on a
> clearsigned
> + file or a file and its detached signature, and
> + rpm.query() to query the RPMDB similar to
> "rpm -q
> + --qf '[...]' [-a] [...]" directly from
> within Lua.
> +
> ______________________________________________________________________
> __
> +
> o Name: RPM4DARWIN
> Vendor: RPM for Darwin (Mac OS X) <http://
> rpm4darwin.sourceforge.net/>
> Representative: Anders F. Bjorklund
> <afb@users.sourceforge.net> <afb@rpm5.org>
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/lib/Makefile.am
>
> ======================================================================
> ======
> $ cvs diff -u -r2.171 -r2.172 Makefile.am
> --- rpm/lib/Makefile.am 30 Dec 2007 10:06:39 -0000 2.171
> +++ rpm/lib/Makefile.am 1 Jan 2008 20:52:22 -0000 2.172
> @@ -36,7 +36,7 @@
> rpmal.h rpmdpkg.h rpmds.h rpmevr.h rpmfc.h rpmfi.h rpmgi.h \
> rpmns.h rpmps.h rpmsx.h rpmte.h rpmts.h
> noinst_HEADERS = \
> - cpio.h fsm.h manifest.h psm.h rpmlock.h tar.h
> + cpio.h fsm.h manifest.h psm.h rpmlock.h tar.h rpmluaext.h
>
> usrlibdir = $(libdir)
> usrlib_LTLIBRARIES = librpm.la
> @@ -47,7 +47,7 @@
> rpmal.c rpmchecksig.c rpmdpkg.c rpmds.c rpmevr.c rpmfc.c \
> rpmfi.c rpmgi.c rpminstall.c rpmrollback.c rpmversion.c \
> rpmlock.c rpmns.c rpmps.c rpmrc.c rpmsx.c rpmte.c rpmts.c \
> - transaction.c verify.c tar.c
> + transaction.c verify.c tar.c rpmluaext.c
> librpm_la_LDFLAGS = -release $(LT_CURRENT).$(LT_REVISION)
> if HAVE_LD_VERSION_SCRIPT
> librpm_la_LDFLAGS += -Wl,--version-script=$(srcdir)/librpm.vers
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/lib/librpm.vers
>
> ======================================================================
> ======
> $ cvs diff -u -r1.30 -r1.31 librpm.vers
> --- rpm/lib/librpm.vers 29 Dec 2007 20:18:47 -0000 1.30
> +++ rpm/lib/librpm.vers 1 Jan 2008 20:52:22 -0000 1.31
> @@ -216,6 +216,7 @@
> rpmlibVersion;
> rpmlibTimestamp;
> rpmlibVendor;
> + rpmluaextActivate;
> rpmMkdirPath;
> rpmNAME;
> _rpmns_debug;
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/lib/rpmluaext.c
>
> ======================================================================
> ======
> $ cvs diff -u -r0 -r2.1 rpmluaext.c
> --- /dev/null 2008-01-01 21:52:03 +0100
> +++ rpmluaext.c 2008-01-01 21:52:22 +0100
> @@ -0,0 +1,254 @@
> +/** \ingroup lib
> + * \file lib/rpmluaext.c
> + */
> +
> +#if defined(RPM_VENDOR_OPENPKG) /* rpm-lua-extensions-based-on-
> rpm-lib-functionality */
> +
> +#include "system.h"
> +
> +#ifdef WITH_LUA
> +
> +#define _MIRE_INTERNAL
> +#include <rpmio_internal.h>
> +#include <rpmmacro.h>
> +#include <rpmcli.h>
> +#include <rpmds.h>
> +#include <rpmcb.h>
> +#include <rpmlog.h>
> +#include <argv.h>
> +
> +#define _RPMLUA_INTERNAL
> +#include <rpmlua.h>
> +#include <rpmluaext.h>
> +
> +#include <lua.h>
> +#include <lualib.h>
> +#include <lauxlib.h>
> +
> +#include "debug.h"
> +
> +/* RPM Lua function:
> + * <digest> = rpm.digest(
> + * <type>, -- digest algorithm type ("md5", "sha1", etc)
> + * <data-file> -- file to calculate digest for
> + * )
> + */
> +static int rpmluaext_digest(lua_State *L)
> +{
> + const char *filename;
> + pgpHashAlgo algo;
> + FD_t fd;
> + const char *digest = NULL;
> + size_t digest_len = 0;
> + DIGEST_CTX ctx;
> + char buf[8 * BUFSIZ];
> + size_t nb;
> +
> + /* fetch arguments */
> + if (lua_isstring(L, 1)) {
> + if ((algo = pgpHashAlgoStringToNumber(lua_tostring(L,
> 1), 0)) == -1) {
> + (void)luaL_argerror(L, 1, "digest type");
> + return 0;
> + }
> + }
> + else {
> + (void)luaL_argerror(L, 1, "digest type");
> + return 0;
> + }
> + if (lua_isstring(L, 2))
> + filename = lua_tostring(L, 2);
> + else {
> + (void)luaL_argerror(L, 2, "data file");
> + return 0;
> + }
> +
> + /* open file */
> + fd = Fopen(filename, "r.fdio");
> + if (fd == NULL || Ferror(fd)) {
> + luaL_error(L, "failed to create transaction");
> + return 0;
> + }
> +
> + /* read file and calculate digest */
> + ctx = rpmDigestInit(algo, RPMDIGEST_NONE);
> + while ((nb = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0)
> + rpmDigestUpdate(ctx, buf, nb);
> + rpmDigestFinal(ctx, &digest, &digest_len, 1);
> + if (digest == NULL || digest[0] == '\0') {
> + luaL_error(L, "failed to calculate digest");
> + return 0;
> + }
> +
> + /* close file */
> + (void)Fclose(fd);
> +
> + /* provide results */
> + lua_pushstring(L, digest);
> + return 1;
> +}
> +
> +/* RPM Lua function:
> + * <ok> = rpm.signature(
> + * <data-file>, -- file to check signature on
> + * <detached-signature-file>, -- file to contain detached
> signature (or "nil" for clearsigning)
> + * <public-key-file>, -- file containing the
> signing public key (or "nil" to consult RPMDB)
> + * <public-key-fingerprint> -- fingerprint of signing
> public key (or "nil" to accept any signing key)
> + * )
> + */
> +static int rpmluaext_signature(lua_State *L)
> +{
> + rpmts ts;
> + rpmRC rc;
> + const char *fn_data;
> + const char *fn_sig;
> + const char *fn_pkey;
> + const char *fp;
> +
> + /* fetch arguments */
> + if (lua_isstring(L, 1))
> + fn_data = lua_tostring(L, 1);
> + else {
> + (void)luaL_argerror(L, 1, "filename of data file");
> + return 0;
> + }
> + if (lua_isstring(L, 2))
> + fn_sig = lua_tostring(L, 2);
> + else
> + fn_sig = NULL;
> + if (lua_isstring(L, 3))
> + fn_pkey = lua_tostring(L, 3);
> + else
> + fn_pkey = NULL;
> + if (lua_isstring(L, 4))
> + fp = lua_tostring(L, 4);
> + else
> + fp = NULL;
> +
> + /* create RPM transaction and open RPM database */
> + if ((ts = rpmtsCreate()) == NULL) {
> + luaL_error(L, "failed to create transaction");
> + return 0;
> + }
> + rpmtsOpenDB(ts, O_RDONLY);
> +
> + /* check signature on integrity specification file */
> + rc = rpmnsProbeSignature(ts, fn_data, fn_sig, fn_pkey, fp, 0);
> +
> + /* destroy transaction */
> + ts = rpmtsFree(ts);
> +
> + /* provide results */
> + lua_pushboolean(L, rc == RPMRC_OK);
> + return 1;
> +}
> +
> +/* callback for converting rpmlog() output into Lua result table */
> +static int rpmluaext_query_cb(rpmlogRec rec, rpmlogCallbackData
> data)
> +{
> + lua_State *L = (lua_State *)data;
> + size_t n;
> +
> + if (rpmlogRecPriority(rec) & RPMLOG_NOTICE) {
> + const char *msg = rpmlogRecMessage(rec);
> + if (msg != NULL) {
> + luaL_checktype(L, -1, LUA_TTABLE);
> + n = lua_objlen(L, -1);
> + if (n >= 0) {
> + lua_pushinteger(L, n + 1);
> + lua_pushstring(L, rpmlogRecMessage(rec));
> + lua_settable(L, -3);
> + }
> + }
> + }
> + return 0;
> +}
> +
> +/* RPM Lua function:
> + * <outputs> = rpm.query(
> + * <query-format>, -- query format (corresponds to CLI
> "rpm -q --qf <query-format>")
> + * <is-all-query> -- query all flag (corresponds to CLI
> "rpm -q -a")
> + * <query-filter> -- query filter (corresponds to CLI
> "rpm -q ... <query-filter>")
> + * )
> + */
> +static int rpmluaext_query(lua_State *L)
> +{
> + rpmts ts;
> + QVA_t qva;
> + const char *argv[2];
> + rpmlogCallback rpmlog_cb;
> + rpmlogCallbackData rpmlog_cb_data;
> + int ec;
> +
> + /* configure RPMDB query */
> + if ((qva = (QVA_t)malloc(sizeof(*qva))) == NULL) {
> + luaL_error(L, "failed to allocate query configuration");
> + return 0;
> + }
> + memset(qva, '\0', sizeof(*qva));
> + if (!lua_isstring(L, 1)) {
> + (void)luaL_argerror(L, 1, "query format");
> + return 0;
> + }
> + qva->qva_queryFormat = lua_tostring(L, 1);
> + qva->qva_mode = 'q';
> + qva->qva_char = ' ';
> + if (!lua_isboolean(L, 2)) {
> + (void)luaL_argerror(L, 1, "query all flag");
> + return 0;
> + }
> + if (lua_toboolean(L, 2)) {
> + qva->qva_source |= RPMQV_ALL;
> + qva->qva_sourceCount++;
> + }
> + argv[0] = NULL;
> + if (lua_isstring(L, 3)) {
> + argv[0] = lua_tostring(L, 3);
> + argv[1] = NULL;
> + }
> +
> + /* create RPM transaction and open RPM database */
> + if ((ts = rpmtsCreate()) == NULL) {
> + luaL_error(L, "failed to create transaction");
> + return 0;
> + }
> + rpmtsOpenDB(ts, O_RDONLY);
> +
> + /* intercept output channel */
> + rpmlogGetCallback(&rpmlog_cb, &rpmlog_cb_data);
> + rpmlogSetCallback(rpmluaext_query_cb, L);
> +
> + /* create result Lua table on Lua stack */
> + lua_newtable(L);
> +
> + /* perform query */
> + ec = rpmcliQuery(ts, qva, argv);
> +
> + /* restore output channel */
> + rpmlogSetCallback(rpmlog_cb, rpmlog_cb_data);
> +
> + /* destroy transaction */
> + ts = rpmtsFree(ts);
> +
> + return 1;
> +}
> +
> +/* RPM Lua "rpm.*" function registry */
> +static const luaL_reg rpmluaext_registry[] = {
> + { "digest", rpmluaext_digest },
> + { "signature", rpmluaext_signature },
> + { "query", rpmluaext_query },
> + { NULL, NULL }
> +};
> +
> +/* activate our RPM Lua extensions */
> +void rpmluaextActivate(rpmlua lua)
> +{
> + lua_pushvalue(lua->L, LUA_GLOBALSINDEX);
> + luaL_openlib(lua->L, "rpm", rpmluaext_registry, 0);
> + return;
> +}
> +
> +#endif /* WITH_LUA */
> +
> +#endif /* RPM_VENDOR_OPENPKG */
> +
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/lib/rpmluaext.h
>
> ======================================================================
> ======
> $ cvs diff -u -r0 -r2.1 rpmluaext.h
> --- /dev/null 2008-01-01 21:52:03 +0100
> +++ rpmluaext.h 2008-01-01 21:52:23 +0100
> @@ -0,0 +1,25 @@
> +#ifndef H_RPMLUAEXT
> +#define H_RPMLUAEXT
> +
> +/** \ingroup rpmluaext
> + * \file lib/rpmluaext.h
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/** \ingroup rpmluaext
> + * Add RPM _library_ based Lua extension
> + * @param lua Lua context
> + * @return none
> + */
> +void rpmluaextActivate(rpmlua lua)
> + /*@*/;
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif/* H_RPMLUA */
> +
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/lib/rpmrc.c
>
> ======================================================================
> ======
> $ cvs diff -u -r2.221 -r2.222 rpmrc.c
> --- rpm/lib/rpmrc.c 27 Dec 2007 23:21:15 -0000 2.221
> +++ rpm/lib/rpmrc.c 1 Jan 2008 20:52:22 -0000 2.222
> @@ -11,6 +11,7 @@
> #define _MIRE_INTERNAL
> #include <rpmio_internal.h> /* for rpmioSlurp() */
> #include <rpmlua.h>
> +#include <rpmluaext.h>
> #include <rpmmacro.h>
> #include <rpmcli.h>
> #include <rpmds.h>
> @@ -957,6 +958,7 @@
> /* Force Lua state initialization */
> #ifdef WITH_LUA
> (void)rpmluaGetPrintBuffer(NULL);
> + (void)rpmluaextActivate(rpmluaGetGlobalState());
> #endif
>
> return 0;
> @@ .
> ______________________________________________________________________
> RPM Package Manager http://rpm5.org
> CVS Sources Repository rpm-cvs@rpm5.org
Received on Tue Jan 1 22:05:05 2008