On Jun 21, 2008, at 11:41 AM, Denis Washington wrote:


The "upgrade issue" must certainly be dealt with. That needs to be
discussed. About package erasure: the package manager is good enough to
handle that on his own actually. We might need a feature to add a
post-remove script, but basic file removal we get pretty much for free
by registring in the package database.


LSB has chosen to leave "upgrade" UNSPECIFIED,
and has also chose in the "Berlin API" to ignore the
fact that both dpkg/rpm versions are a triple of
Epoch/Version/Release.

Pretending that a "version" string can be anything, opaquely handled,
including E:V-R, or something else, misses the
issue that "upgrade" based on "version" is undecidable
until "version" is well formed, and a collate sequence
is defined for "upgrade" comparison.

Leaving it to rpm to clean up _register_package()'s
mess is _EXACTLY_ what I mean by disaster avoidance.

E.g., files have a RPMTAG_FILESTATES array that is computed
and attached to package headers before rpmdbAdd() is called.

If you do not also add RPMTAG_FILESTATES, you _WILL_
cause rpm to segfault under certain conditions.

Note this comment in lib/transaction.c, been there for years and years, that
you _WILL_ end up traversing if you insist on registering
"LSB Format" headers:

    /* XXX there's an obscure segfault here w/o NULL check ... */
    if (otherStates != NULL)

Note also that there's nothing other than avoiding the segfault
that has ever been attempted in RPM because a header in a rpmdb
without RPMTAG_FILESTATES is a "should never ever happen"
condition.

Guess what Newer! Better! Besttest! rule your "Berlin API" _register_package()
method is about to impose on already released legacy versions of RPM?

Along these lines, you should attempt to add a SHA1 on you rregistered
header. Almost all headers (LSB and Sun java being the Luddites)
in an rpmdb carry a SHA1 to guarantee package metadata
integrity many years now. No such guarantee can be attempted unless you also
compute and supply the necessary Header SHA1.

The code that is needed to add a header SHA1 is in build/pack.c.

Essentially (this is rpm5 code, there are minor API differences)

    /* Reallocate the header into one contiguous region. */
    Header h = headerReload(h, RPMTAG_HEADERIMMUTABLE);
    ...
    size_t uhlen = 0;
    void * uh = headerUnload(h, &uhlen);
    DIGEST_CTX ctx = rpmDigestInit(PGPHASHALGO, 0);
    const char * SHA1 = NULL;

    (void) rpmDigestUpdate(ctx, uh, uhlen)
    (void) rpmDigestFinal(ctx, &SHA1, NULL, 1)

    headerAddEntry(h, RPMTAG_SHA1HEADER, RPM_STRING_TYPE, SHA1, 1);

Note that the ordering of tag additions is also significant. E.g. RPMTAG_FILESTATES
should be added _AFTER_ headerReload() and the SHA1 computation I've
just described, because that's what is done during installation with RPM.

Ditto adding RPMTAG_INSTALLTIME. FYI, the complete set of
additions is in lib/psm.c near the
     case PSM_RPMDB_ADD:
code.

But I've likely digressed, sigh ...

hth

73 de Jeff

______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
LSB Communication List                                rpm-lsb@rpm5.org

Reply via email to