RPM Community Forums

Mailing List Message of <rpm-devel>

Re: [CVS] RPM: rpm/ VENDOR rpm/lib/ Makefile.am librpm.vers rpmluaext.c rp...

From: Jeff Johnson <n3npq@mac.com>
Date: Tue 01 Jan 2008 - 22:04:30 CET
Message-Id: <FA08C271-19B6-4A71-9E10-EB8747013317@mac.com>
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
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.