RPM Package Manager, CVS Repository
/cvs/
____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson
Root: /v/rpm/cvs Email: jbj@rpm5.org
Module: rpm Date: 28-Sep-2010 01:12:49
Branch: HEAD Handle: 2010092723124206
Added files:
rpm/rpmdb package.c
Modified files:
rpm CHANGES
rpm/lib Makefile.am librpm.vers
rpm/rpmdb Makefile.am librpmdb.vers rpmrepo.c rpmrepo.h
Removed files:
rpm/lib package.c
Log:
- rpmrepo: finish refactoring tools/rpmrepo.c.
- move package.c from lib -> rpmdb.
Summary:
Revision Changes Path
1.3454 +2 -0 rpm/CHANGES
2.199 +1 -1 rpm/lib/Makefile.am
1.77 +0 -1 rpm/lib/librpm.vers
2.211 +0 -395 rpm/lib/package.c
1.131 +3 -3 rpm/rpmdb/Makefile.am
1.91 +3 -13 rpm/rpmdb/librpmdb.vers
1.1 +395 -0 rpm/rpmdb/package.c
1.3 +417 -15 rpm/rpmdb/rpmrepo.c
1.3 +3 -136 rpm/rpmdb/rpmrepo.h
____________________________________________________________________________
patch -p0 <<'@@ .'
Index: rpm/CHANGES
============================================================================
$ cvs diff -u -r1.3453 -r1.3454 CHANGES
--- rpm/CHANGES 27 Sep 2010 21:18:09 -0000 1.3453
+++ rpm/CHANGES 27 Sep 2010 23:12:42 -0000 1.3454
@@ -1,6 +1,8 @@
5.3.4 -> 5.4a1:
5.3.3 -> 5.3.4:
+ - jbj: rpmrepo: finish refactoring tools/rpmrepo.c.
+ - jbj: move package.c from lib -> rpmdb.
- jbj: rpmrepo: move from rpmio -> rpmdb to finish tools/rpmrepo.c gutting.
- devzero2000 : added --withoutcheck popt alias (#lp:634104) (#mdvbz:35423)
- jbj: i18n: update po files (Translation Project).
@@ .
patch -p0 <<'@@ .'
Index: rpm/lib/Makefile.am
============================================================================
$ cvs diff -u -r2.198 -r2.199 Makefile.am
--- rpm/lib/Makefile.am 29 Apr 2010 23:35:14 -0000 2.198
+++ rpm/lib/Makefile.am 27 Sep 2010 23:12:47 -0000 2.199
@@ -62,7 +62,7 @@
usrlib_LTLIBRARIES = librpm.la
librpm_la_SOURCES = \
depends.c filetriggers.c formats.c fs.c fsm.c \
- manifest.c misc.c order.c package.c \
+ manifest.c misc.c order.c \
poptALL.c poptI.c poptQV.c psm.c query.c \
rpmal.c rpmchecksig.c rpmds.c rpmfc.c \
rpmfi.c rpmgi.c rpminstall.c rpmrollback.c rpmversion.c \
@@ .
patch -p0 <<'@@ .'
Index: rpm/lib/librpm.vers
============================================================================
$ cvs diff -u -r1.76 -r1.77 librpm.vers
--- rpm/lib/librpm.vers 21 Feb 2010 20:52:35 -0000 1.76
+++ rpm/lib/librpm.vers 27 Sep 2010 23:12:48 -0000 1.77
@@ -250,7 +250,6 @@
rpmQVKArgs;
rpmQVSourcePoptTable;
rpmReadConfigFiles;
- rpmReadPackageFile;
rpmReadPackageManifest;
rpmRollback;
rpmShowProgress;
@@ .
rm -f rpm/lib/package.c <<'@@ .'
Index: rpm/lib/package.c
============================================================================
[NO CHANGE SUMMARY BECAUSE FILE AS A WHOLE IS JUST REMOVED]
@@ .
patch -p0 <<'@@ .'
Index: rpm/rpmdb/Makefile.am
============================================================================
$ cvs diff -u -r1.130 -r1.131 Makefile.am
--- rpm/rpmdb/Makefile.am 27 Sep 2010 17:01:30 -0000 1.130
+++ rpm/rpmdb/Makefile.am 27 Sep 2010 23:12:43 -0000 1.131
@@ -68,9 +68,9 @@
$(AM_CPPFLAGS) -I$(top_srcdir)/scripts -I$(top_builddir)/scripts \
$(CPPFLAGS)
librpmdb_la_SOURCES = \
- dbconfig.c fprint.c \
- hdrfmt.c hdrNVR.c header.c header_internal.c legacy.c merge.c \
- pkgio.c poptDB.c rpmdb.c rpmdpkg.c rpmevr.c rpmlio.c rpmmdb.c rpmns.c \
+ dbconfig.c fprint.c hdrfmt.c hdrNVR.c header.c header_internal.c \
+ legacy.c merge.c package.c pkgio.c poptDB.c \
+ rpmdb.c rpmdpkg.c rpmevr.c rpmlio.c rpmmdb.c rpmns.c \
rpmrepo.c rpmtd.c rpmtxn.c rpmwf.c signature.c tagname.c tagtbl.c \
$(logio_LSOURCES)
librpmdb_la_LDFLAGS = -release $(LT_CURRENT).$(LT_REVISION)
@@ .
patch -p0 <<'@@ .'
Index: rpm/rpmdb/librpmdb.vers
============================================================================
$ cvs diff -u -r1.90 -r1.91 librpmdb.vers
--- rpm/rpmdb/librpmdb.vers 27 Sep 2010 17:01:30 -0000 1.90
+++ rpm/rpmdb/librpmdb.vers 27 Sep 2010 23:12:43 -0000 1.91
@@ -82,6 +82,7 @@
headerVerifyInfo;
hGetColor;
_init;
+ keyids;
logio_dispatch;
logio_Chmod_log;
logio_Chown_log;
@@ -183,6 +184,7 @@
rpmnsClassify;
rpmnsParse;
rpmnsProbeSignature;
+ rpmReadPackageFile;
rpmpkgCheck;
rpmpkgClean;
rpmpkgRead;
@@ -190,28 +192,16 @@
rpmpkgWrite;
rpm_mergesort;
_rpmrepo_debug;
- _rpmrepoOptions;
_rpmrepoPool;
rpmrepoCheckTimeStamps;
- rpmrepoCloseMDFile;
rpmrepoDoFinalMove;
+ rpmrepoDoPkgMetadata;
rpmrepoDoRepoMetadata;
rpmrepoError;
- rpmrepoFclose;
rpmrepoGetFileList;
- rpmrepoGetPath;
- rpmrepoMDExpand;
- rpmrepoMkdir;
rpmrepoNew;
- rpmrepoOpenMDFile;
- rpmrepoProgress;
rpmrepoRealpath;
- rpmrepoRfileDigest;
rpmrepoTestSetupDirs;
- rpmrfileSQL;
- rpmrfileSQLStep;
- rpmrfileSQLWrite;
- rpmrfileXMLWrite;
rpmTagTable;
rpmTagTableSize;
rpmTags;
@@ .
patch -p0 <<'@@ .'
Index: rpm/rpmdb/package.c
============================================================================
$ cvs diff -u -r0 -r1.1 package.c
--- /dev/null 2010-09-28 01:11:01.000000000 +0200
+++ package.c 2010-09-28 01:12:44.450399048 +0200
@@ -0,0 +1,395 @@
+/** \ingroup header
+ * \file lib/package.c
+ */
+
+#include "system.h"
+
+#include <netinet/in.h>
+
+#include <rpmio_internal.h>
+#include <rpmcb.h> /* XXX fnpyKey */
+
+#define _RPMHKP_INTERNAL /* XXX internal prototypes. */
+#include <rpmhkp.h>
+
+#include <rpmtag.h>
+#include <rpmtypes.h>
+#include <pkgio.h>
+#include "signature.h" /* XXX rpmVerifySignature */
+
+#include "rpmts.h"
+
+#include "debug.h"
+
+#define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
+
+/*@access pgpDig @*/
+/*@access pgpDigParams @*/
+/*@access Header @*/ /* XXX compared with NULL */
+/*@access FD_t @*/ /* XXX void * */
+
+/*@unchecked@*/
+static unsigned int nkeyids_max = 256;
+/*@unchecked@*/
+static unsigned int nkeyids = 0;
+/*@unchecked@*/
+static unsigned int nextkeyid = 0;
+/*@unchecked@*/ /*@only@*/ /*@null@*/
+unsigned int * keyids = NULL;
+
+/**
+ * Remember current key id.
+ * @param dig container
+ * @return 0 if new keyid, otherwise 1
+ */
+static int pgpStashKeyid(pgpDig dig)
+ /*@globals nextkeyid, nkeyids, keyids @*/
+ /*@modifies nextkeyid, nkeyids, keyids @*/
+{
+ pgpDigParams sigp = pgpGetSignature(dig);
+ const void * sig = pgpGetSig(dig);
+ unsigned int keyid;
+ unsigned int i;
+
+ if (sig == NULL || dig == NULL || sigp == NULL)
+ return 0;
+
+ keyid = pgpGrab(sigp->signid+4, 4);
+ if (keyid == 0)
+ return 0;
+
+ if (keyids != NULL)
+ for (i = 0; i < nkeyids; i++) {
+ if (keyid == keyids[i])
+ return 1;
+ }
+
+ if (nkeyids < nkeyids_max) {
+ nkeyids++;
+ keyids = xrealloc(keyids, nkeyids * sizeof(*keyids));
+ }
+ if (keyids) /* XXX can't happen */
+ keyids[nextkeyid] = keyid;
+ nextkeyid++;
+ nextkeyid %= nkeyids_max;
+
+ return 0;
+}
+
+/*@-mods@*/
+rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp)
+{
+ HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
+ HE_t she = memset(alloca(sizeof(*she)), 0, sizeof(*she));
+ pgpDig dig = rpmtsDig(ts);
+ char buf[8*BUFSIZ];
+ ssize_t count;
+ Header sigh = NULL;
+ rpmtsOpX opx;
+ rpmop op = NULL;
+ size_t nb;
+ unsigned ix;
+ Header h = NULL;
+ const char * msg = NULL;
+ rpmVSFlags vsflags;
+ rpmRC rc = RPMRC_FAIL; /* assume failure */
+ rpmop opsave = memset(alloca(sizeof(*opsave)), 0, sizeof(*opsave));
+ int xx;
+pgpPkt pp = alloca(sizeof(*pp));
+
+ if (hdrp) *hdrp = NULL;
+
+assert(dig != NULL);
+ (void) fdSetDig(fd, dig);
+
+ /* Snapshot current I/O counters (cached persistent I/O reuses counters) */
+ (void) rpmswAdd(opsave, fdstat_op(fd, FDSTAT_READ));
+
+ { const char item[] = "Lead";
+ msg = NULL;
+ rc = rpmpkgRead(item, fd, NULL, &msg);
+ switch (rc) {
+ default:
+ rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, msg);
+ /*@fallthrough@*/
+ case RPMRC_NOTFOUND:
+ msg = _free(msg);
+ goto exit;
+ /*@notreached@*/ break;
+ case RPMRC_OK:
+ break;
+ }
+ msg = _free(msg);
+ }
+
+ { const char item[] = "Signature";
+ msg = NULL;
+ rc = rpmpkgRead(item, fd, &sigh, &msg);
+ switch (rc) {
+ default:
+ rpmlog(RPMLOG_ERR, "%s: %s: %s", fn, item,
+ (msg && *msg ? msg : _("read failed\n")));
+ msg = _free(msg);
+ goto exit;
+ /*@notreached@*/ break;
+ case RPMRC_OK:
+ if (sigh == NULL) {
+ rpmlog(RPMLOG_ERR, _("%s: No signature available\n"), fn);
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+ break;
+ }
+ msg = _free(msg);
+ }
+
+#define _chk(_mask) (she->tag == 0 && !(vsflags & (_mask)))
+
+ /*
+ * Figger the most effective available signature.
+ * Prefer signatures over digests, then header-only over header+payload.
+ * DSA will be preferred over RSA if both exist because tested first.
+ * Note that NEEDPAYLOAD prevents header+payload signatures and digests.
+ */
+ she->tag = 0;
+ opx = 0;
+ vsflags = pgpDigVSFlags;
+ if (_chk(RPMVSF_NODSAHEADER) && headerIsEntry(sigh, (rpmTag)RPMSIGTAG_DSA)) {
+ she->tag = (rpmTag)RPMSIGTAG_DSA;
+ } else
+ if (_chk(RPMVSF_NORSAHEADER) && headerIsEntry(sigh, (rpmTag)RPMSIGTAG_RSA)) {
+ she->tag = (rpmTag)RPMSIGTAG_RSA;
+ } else
+ if (_chk(RPMVSF_NOSHA1HEADER) && headerIsEntry(sigh, (rpmTag)RPMSIGTAG_SHA1)) {
+ she->tag = (rpmTag)RPMSIGTAG_SHA1;
+ } else
+ if (_chk(RPMVSF_NOMD5|RPMVSF_NEEDPAYLOAD) &&
+ headerIsEntry(sigh, (rpmTag)RPMSIGTAG_MD5))
+ {
+ she->tag = (rpmTag)RPMSIGTAG_MD5;
+ fdInitDigest(fd, PGPHASHALGO_MD5, 0);
+ opx = RPMTS_OP_DIGEST;
+ }
+
+ /* Read the metadata, computing digest(s) on the fly. */
+ h = NULL;
+ msg = NULL;
+
+ /* XXX stats will include header i/o and setup overhead. */
+ /* XXX repackaged packages have appended tags, legacy dig/sig check fails */
+ if (opx > 0) {
+ op = pgpStatsAccumulator(dig, opx);
+ (void) rpmswEnter(op, 0);
+ }
+/*@-type@*/ /* XXX arrow access of non-pointer (FDSTAT_t) */
+ nb = fd->stats->ops[FDSTAT_READ].bytes;
+ { const char item[] = "Header";
+ msg = NULL;
+ rc = rpmpkgRead(item, fd, &h, &msg);
+ if (rc != RPMRC_OK) {
+ rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, msg);
+ msg = _free(msg);
+ goto exit;
+ }
+ msg = _free(msg);
+ }
+ nb = fd->stats->ops[FDSTAT_READ].bytes - nb;
+/*@=type@*/
+ if (opx > 0 && op != NULL) {
+ (void) rpmswExit(op, nb);
+ op = NULL;
+ }
+
+ /* Any digests or signatures to check? */
+ if (she->tag == 0) {
+ rc = RPMRC_OK;
+ goto exit;
+ }
+
+ dig->nbytes = 0;
+
+ /* Fish out the autosign pubkey (if present). */
+ he->tag = RPMTAG_PUBKEYS;
+ xx = headerGet(h, he, 0);
+ if (xx && he->p.argv != NULL && he->c > 0)
+ switch (he->t) {
+ default:
+ break;
+ case RPM_STRING_ARRAY_TYPE:
+ ix = he->c - 1; /* XXX FIXME: assumes last pubkey */
+ dig->pub = _free(dig->pub);
+ dig->publen = 0;
+ { rpmiob iob = rpmiobNew(0);
+ iob = rpmiobAppend(iob, he->p.argv[ix], 0);
+ xx = pgpArmorUnwrap(iob,(rpmuint8_t **)&dig->pub, &dig->publen);
+ iob = rpmiobFree(iob);
+ }
+ if (xx != PGPARMOR_PUBKEY) {
+ dig->pub = _free(dig->pub);
+ dig->publen = 0;
+ }
+ break;
+ }
+ he->p.ptr = _free(he->p.ptr);
+
+ /* Retrieve the tag parameters from the signature header. */
+ xx = headerGet(sigh, she, 0);
+ if (she->p.ptr == NULL) {
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+/*@-ownedtrans -noeffect@*/
+ xx = pgpSetSig(dig, she->tag, she->t, she->p.ptr, she->c);
+/*@=ownedtrans =noeffect@*/
+
+ switch ((rpmSigTag)she->tag) {
+ default: /* XXX keep gcc quiet. */
+assert(0);
+ /*@notreached@*/ break;
+ case RPMSIGTAG_RSA:
+ /* Parse the parameters from the OpenPGP packets that will be needed. */
+ xx = pgpPktLen(she->p.ptr, she->c, pp);
+ xx = rpmhkpLoadSignature(NULL, dig, pp);
+ if (dig->signature.version != 3 && dig->signature.version != 4) {
+ rpmlog(RPMLOG_ERR,
+ _("skipping package %s with unverifiable V%u signature\n"),
+ fn, dig->signature.version);
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+ { void * uh = NULL;
+ rpmTagType uht;
+ rpmTagCount uhc;
+ unsigned char * hmagic = NULL;
+ size_t nmagic = 0;
+
+ he->tag = RPMTAG_HEADERIMMUTABLE;
+ xx = headerGet(h, he, 0);
+ uht = he->t;
+ uh = he->p.ptr;
+ uhc = he->c;
+ if (!xx)
+ break;
+ (void) headerGetMagic(NULL, &hmagic, &nmagic);
+ op = pgpStatsAccumulator(dig, 10); /* RPMTS_OP_DIGEST */
+ (void) rpmswEnter(op, 0);
+ dig->hdrctx = rpmDigestInit(dig->signature.hash_algo, RPMDIGEST_NONE);
+ if (hmagic && nmagic > 0) {
+ (void) rpmDigestUpdate(dig->hdrctx, hmagic, nmagic);
+ dig->nbytes += nmagic;
+ }
+ (void) rpmDigestUpdate(dig->hdrctx, uh, uhc);
+ dig->nbytes += uhc;
+ (void) rpmswExit(op, dig->nbytes);
+ op->count--; /* XXX one too many */
+ uh = _free(uh);
+ } break;
+ case RPMSIGTAG_DSA:
+ /* Parse the parameters from the OpenPGP packets that will be needed. */
+ xx = pgpPktLen(she->p.ptr, she->c, pp);
+ xx = rpmhkpLoadSignature(NULL, dig, pp);
+ if (dig->signature.version != 3 && dig->signature.version != 4) {
+ rpmlog(RPMLOG_ERR,
+ _("skipping package %s with unverifiable V%u signature\n"),
+ fn, dig->signature.version);
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+ /*@fallthrough@*/
+ case RPMSIGTAG_SHA1:
+ { void * uh = NULL;
+ rpmTagType uht;
+ rpmTagCount uhc;
+ unsigned char * hmagic = NULL;
+ size_t nmagic = 0;
+
+ he->tag = RPMTAG_HEADERIMMUTABLE;
+ xx = headerGet(h, he, 0);
+ uht = he->t;
+ uh = he->p.ptr;
+ uhc = he->c;
+ if (!xx)
+ break;
+ (void) headerGetMagic(NULL, &hmagic, &nmagic);
+ op = pgpStatsAccumulator(dig, 10); /* RPMTS_OP_DIGEST */
+ (void) rpmswEnter(op, 0);
+ dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
+ if (hmagic && nmagic > 0) {
+ (void) rpmDigestUpdate(dig->hdrsha1ctx, hmagic, nmagic);
+ dig->nbytes += nmagic;
+ }
+ (void) rpmDigestUpdate(dig->hdrsha1ctx, uh, uhc);
+ dig->nbytes += uhc;
+ (void) rpmswExit(op, dig->nbytes);
+ if ((rpmSigTag)she->tag == RPMSIGTAG_SHA1)
+ op->count--; /* XXX one too many */
+ uh = _free(uh);
+ } break;
+ case RPMSIGTAG_MD5:
+ /* Legacy signatures need the compressed payload in the digest too. */
+ op = pgpStatsAccumulator(dig, 10); /* RPMTS_OP_DIGEST */
+ (void) rpmswEnter(op, 0);
+ while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0)
+ dig->nbytes += count;
+ (void) rpmswExit(op, dig->nbytes);
+ op->count--; /* XXX one too many */
+ dig->nbytes += nb; /* XXX include size of header blob. */
+ if (count < 0) {
+ rpmlog(RPMLOG_ERR, _("%s: Fread failed: %s\n"),
+ fn, Fstrerror(fd));
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+
+ /* XXX Steal the digest-in-progress from the file handle. */
+ fdStealDigest(fd, dig);
+ break;
+ }
+
+/** @todo Implement disable/enable/warn/error/anal policy. */
+
+ buf[0] = '\0';
+ rc = rpmVerifySignature(dig, buf);
+ switch (rc) {
+ case RPMRC_OK: /* Signature is OK. */
+ rpmlog(RPMLOG_DEBUG, "%s: %s\n", fn, buf);
+ break;
+ case RPMRC_NOTTRUSTED: /* Signature is OK, but key is not trusted. */
+ case RPMRC_NOKEY: /* Public key is unavailable. */
+ /* XXX Print NOKEY/NOTTRUSTED warning only once. */
+ { int lvl = (pgpStashKeyid(dig) ? RPMLOG_DEBUG : RPMLOG_WARNING);
+ rpmlog(lvl, "%s: %s\n", fn, buf);
+ } break;
+ case RPMRC_NOTFOUND: /* Signature is unknown type. */
+ rpmlog(RPMLOG_WARNING, "%s: %s\n", fn, buf);
+ break;
+ default:
+ case RPMRC_FAIL: /* Signature does not verify. */
+ rpmlog(RPMLOG_ERR, "%s: %s\n", fn, buf);
+ break;
+ }
+
+exit:
+ if (rc != RPMRC_FAIL && h != NULL && hdrp != NULL) {
+
+ /* Append (and remap) signature tags to the metadata. */
+ headerMergeLegacySigs(h, sigh);
+
+ /* Bump reference count for return. */
+ *hdrp = headerLink(h);
+ }
+ (void)headerFree(h);
+ h = NULL;
+
+ /* Accumulate time reading package header. */
+ (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_READHDR),
+ fdstat_op(fd, FDSTAT_READ));
+ (void) rpmswSub(rpmtsOp(ts, RPMTS_OP_READHDR),
+ opsave);
+
+ rpmtsCleanDig(ts);
+ (void)headerFree(sigh);
+ sigh = NULL;
+ return rc;
+}
+/*@=mods@*/
@@ .
patch -p0 <<'@@ .'
Index: rpm/rpmdb/rpmrepo.c
============================================================================
$ cvs diff -u -r1.2 -r1.3 rpmrepo.c
--- rpm/rpmdb/rpmrepo.c 27 Sep 2010 19:41:45 -0000 1.2
+++ rpm/rpmdb/rpmrepo.c 27 Sep 2010 23:12:43 -0000 1.3
@@ -53,6 +53,11 @@
#define _RPMREPO_INTERNAL
#include <rpmrepo.h>
+#include <rpmtypes.h>
+#include <rpmtag.h>
+#include <pkgio.h>
+#include <rpmts.h>
+
#include "debug.h"
/*@unchecked@*/
@@ -385,12 +390,26 @@
/*==============================================================*/
-int rpmioExists(const char * fn, /*@out@*/ struct stat * st)
+/**
+ * Return stat(2) for a file.
+ * @retval st stat(2) buffer
+ * @return 0 on success
+ */
+static int rpmioExists(const char * fn, /*@out@*/ struct stat * st)
+ /*@globals h_errno, fileSystem, internalState @*/
+ /*@modifies st, fileSystem, internalState @*/
{
return (Stat(fn, st) == 0);
}
-time_t rpmioCtime(const char * fn)
+/**
+ * Return stat(2) creation time of a file.
+ * @param fn file path
+ * @return st_ctime
+ */
+static time_t rpmioCtime(const char * fn)
+ /*@globals h_errno, fileSystem, internalState @*/
+ /*@modifies fileSystem, internalState @*/
{
struct stat sb;
time_t stctime = 0;
@@ -417,16 +436,34 @@
exit(EXIT_FAILURE);
}
-const char * rpmrepoGetPath(rpmrepo repo, const char * dir,
+/**
+ * Return /repository/directory/component.markup.compression path.
+ * @param repo repository
+ * @param dir directory
+ * @param type file
+ * @return repository file path
+ */
+static const char * rpmrepoGetPath(rpmrepo repo, const char * dir,
const char * type, int compress)
+ /*@globals h_errno, rpmGlobalMacroContext, internalState @*/
+ /*@modifies rpmGlobalMacroContext, internalState @*/
{
return rpmGetPath(repo->outputdir, "/", dir, "/", type,
(repo->markup != NULL ? repo->markup : ""),
(repo->suffix != NULL && compress ? repo->suffix : ""), NULL);
}
-void rpmrepoProgress(/*@unused@*/ rpmrepo repo,
+/**
+ * Display progress.
+ * @param repo repository
+ * @param item repository item (usually a file path)
+ * @param current current iteration index
+ * @param total maximum iteration index
+ */
+static void rpmrepoProgress(/*@unused@*/ rpmrepo repo,
/*@null@*/ const char * item, int current, int total)
+ /*@globals fileSystem, internalState @*/
+ /*@modifies fileSystem, internalState @*/
{
static size_t ncols = 80 - 1; /* XXX TIOCGWINSIZ */
const char * bn = (item != NULL ? strrchr(item, '/') : NULL);
@@ -446,7 +483,15 @@
(void) fflush(stdout);
}
-int rpmrepoMkdir(rpmrepo repo, const char * dn)
+/**
+ * Create directory path.
+ * @param repo repository
+ * @param dn directory path
+ * @return 0 on success
+ */
+static int rpmrepoMkdir(rpmrepo repo, const char * dn)
+ /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
+ /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
{
const char * dnurl = rpmGetPath(repo->outputdir, "/", dn, NULL);
/*@-mods@*/
@@ -653,7 +698,15 @@
return rc;
}
-int rpmrfileXMLWrite(rpmrfile rfile, const char * spew)
+/**
+ * Write to a repository metadata file.
+ * @param rfile repository metadata file
+ * @param spew contents
+ * @return 0 on success
+ */
+static int rpmrfileXMLWrite(rpmrfile rfile, const char * spew)
+ /*@globals fileSystem @*/
+ /*@modifies rfile, fileSystem @*/
{
size_t nspew = (spew != NULL ? strlen(spew) : 0);
/*@-nullpass@*/ /* XXX spew != NULL @*/
@@ -669,7 +722,14 @@
return rc;
}
-int rpmrepoFclose(rpmrepo repo, FD_t fd)
+/**
+ * Close an I/O stream, accumulating uncompress/digest statistics.
+ * @param repo repository
+ * @param fd I/O stream
+ * @return 0 on success
+ */
+static int rpmrepoFclose(rpmrepo repo, FD_t fd)
+ /*@modifies repo, fd @*/
{
int rc = 0;
@@ -688,7 +748,15 @@
return rc;
}
-int rpmrepoOpenMDFile(const rpmrepo repo, rpmrfile rfile)
+/**
+ * Open a repository metadata file.
+ * @param repo repository
+ * @param rfile repository metadata file
+ * @return 0 on success
+ */
+static int rpmrepoOpenMDFile(const rpmrepo repo, rpmrfile rfile)
+ /*@globals h_errno, rpmGlobalMacroContext, fileSystem, internalState @*/
+ /*@modifies rfile, rpmGlobalMacroContext, fileSystem, internalState @*/
{
const char * spew = rfile->xml_init;
size_t nspew = strlen(spew);
@@ -746,7 +814,14 @@
}
#if defined(WITH_SQLITE)
-int rpmrfileSQL(rpmrfile rfile, const char * msg, int rc)
+/**
+ * Check sqlite3 return, displaying error messages.
+ * @param rfile repository metadata file
+ * @return SQLITE_OK on success
+ */
+static int rpmrfileSQL(rpmrfile rfile, const char * msg, int rc)
+ /*@globals fileSystem @*/
+ /*@modifies fileSystem @*/
{
if (rc != SQLITE_OK || _rpmrepo_debug)
rpmrepoError(0, "sqlite3_%s(%s): %s", msg, rfile->type,
@@ -754,7 +829,14 @@
return rc;
}
-int rpmrfileSQLStep(rpmrfile rfile, sqlite3_stmt * stmt)
+/**
+ * Execute a compiled SQL command.
+ * @param rfile repository metadata file
+ * @return SQLITE_OK on success
+ */
+static int rpmrfileSQLStep(rpmrfile rfile, sqlite3_stmt * stmt)
+ /*@globals fileSystem @*/
+ /*@modifies fileSystem @*/
{
int loop = 1;
int rc = 0;
@@ -780,7 +862,15 @@
return rc;
}
-int rpmrfileSQLWrite(rpmrfile rfile, const char * cmd)
+/**
+ * Run a sqlite3 command.
+ * @param rfile repository metadata file
+ * @param cmd sqlite3 command to run
+ * @return 0 always
+ */
+static int rpmrfileSQLWrite(rpmrfile rfile, const char * cmd)
+ /*@globals fileSystem @*/
+ /*@modifies fileSystem @*/
{
sqlite3_stmt * stmt;
const char * tail;
@@ -803,8 +893,13 @@
}
#endif /* WITH_SQLITE */
-int rpmrepoRfileDigest(const rpmrepo repo, rpmrfile rfile,
+/**
+ * Compute digest of a file.
+ * @return 0 on success
+ */
+static int rpmrepoRfileDigest(const rpmrepo repo, rpmrfile rfile,
const char ** digestp)
+ /*@modifies *digestp @*/
{
static int asAscii = 1;
struct stat sb, *st = &sb;
@@ -870,7 +965,15 @@
return rc;
}
-int rpmrepoCloseMDFile(const rpmrepo repo, rpmrfile rfile)
+/**
+ * Close a repository metadata file.
+ * @param repo repository
+ * @param rfile repository metadata file
+ * @return 0 on success
+ */
+static int rpmrepoCloseMDFile(const rpmrepo repo, rpmrfile rfile)
+ /*@globals h_errno, rpmGlobalMacroContext, fileSystem, internalState @*/
+ /*@modifies rfile, rpmGlobalMacroContext, fileSystem, internalState @*/
{
static int asAscii = 1;
char * xmlfn = xstrdup(fdGetOPath(rfile->fd));
@@ -948,7 +1051,14 @@
return tagname;
}
-const char * rpmrepoMDExpand(rpmrepo repo, rpmrfile rfile)
+/**
+ * Return a repository metadata file item.
+ * @param repo repository
+ * @return repository metadata file item
+ */
+static const char * rpmrepoMDExpand(rpmrepo repo, rpmrfile rfile)
+ /*@globals h_errno, rpmGlobalMacroContext, internalState @*/
+ /*@modifies rpmGlobalMacroContext, internalState @*/
{
const char * spewalgo = algo2tagname(repo->algo);
char spewtime[64];
@@ -1239,6 +1349,298 @@
/*==============================================================*/
+/**
+ * Read a header from a repository package file, computing package file digest.
+ * @param repo repository
+ * @param path package file path
+ * @return header (NULL on error)
+ */
+static Header rpmrepoReadHeader(rpmrepo repo, const char * path)
+ /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
+ /*@modifies repo, rpmGlobalMacroContext, fileSystem, internalState @*/
+{
+ /* XXX todo: read the payload and collect the blessed file digest. */
+ FD_t fd = Fopen(path, "r.ufdio");
+ Header h = NULL;
+
+ if (fd != NULL) {
+ rpmts ts = repo->_ts;
+ uint32_t algo = repo->pkgalgo;
+ rpmRC rpmrc;
+
+ if (algo != PGPHASHALGO_NONE)
+ fdInitDigest(fd, algo, 0);
+
+ /* XXX what if path needs expansion? */
+ rpmrc = rpmReadPackageFile(ts, fd, path, &h);
+ if (algo != PGPHASHALGO_NONE) {
+ char buffer[32 * BUFSIZ];
+ size_t nb = sizeof(buffer);
+ size_t nr;
+ while ((nr = Fread(buffer, sizeof(buffer[0]), nb, fd)) == nb)
+ {};
+ if (Ferror(fd)) {
+ fprintf(stderr, _("%s: Fread(%s) failed: %s\n"),
+ __progname, path, Fstrerror(fd));
+ rpmrc = RPMRC_FAIL;
+ } else {
+ static int asAscii = 1;
+ const char *digest = NULL;
+ fdFiniDigest(fd, algo, &digest, NULL, asAscii);
+ (void) headerSetDigest(h, digest);
+ digest = _free(digest);
+ }
+ }
+
+ (void) Fclose(fd);
+
+ switch (rpmrc) {
+ case RPMRC_NOTFOUND:
+ case RPMRC_FAIL:
+ default:
+ (void) headerFree(h);
+ h = NULL;
+ break;
+ case RPMRC_NOTTRUSTED:
+ case RPMRC_NOKEY:
+ case RPMRC_OK:
+ if (repo->baseurl)
+ (void) headerSetBaseURL(h, repo->baseurl);
+ (void) headerSetInstance(h, (uint32_t)repo->current+1);
+ break;
+ }
+ }
+ return h;
+}
+
+/**
+ * Return header query.
+ * @param h header
+ * @param qfmt query format
+ * @return query format result
+ */
+static const char * rfileHeaderSprintf(Header h, const char * qfmt)
+ /*@globals fileSystem @*/
+ /*@modifies h, fileSystem @*/
+{
+ const char * msg = NULL;
+ const char * s = headerSprintf(h, qfmt, NULL, NULL, &msg);
+ if (s == NULL)
+ rpmrepoError(1, _("headerSprintf(%s): %s"), qfmt, msg);
+assert(s != NULL);
+ return s;
+}
+
+#if defined(WITH_SQLITE)
+/**
+ * Return header query, with "XXX" replaced by rpmdb header instance.
+ * @param h header
+ * @param qfmt query format
+ * @return query format result
+ */
+static const char * rfileHeaderSprintfHack(Header h, const char * qfmt)
+ /*@globals fileSystem @*/
+ /*@modifies h, fileSystem @*/
+{
+ static const char mark[] = "'XXX'";
+ static size_t nmark = sizeof("'XXX'") - 1;
+ const char * msg = NULL;
+ char * s = (char *) headerSprintf(h, qfmt, NULL, NULL, &msg);
+ char * f, * fe;
+ int nsubs = 0;
+
+ if (s == NULL)
+ rpmrepoError(1, _("headerSprintf(%s): %s"), qfmt, msg);
+assert(s != NULL);
+
+ /* XXX Find & replace 'XXX' with '%{DBINSTANCE}' the hard way. */
+/*@-nullptrarith@*/
+ for (f = s; *f != '\0' && (fe = strstr(f, "'XXX'")) != NULL; fe += nmark, f = fe)
+ nsubs++;
+/*@=nullptrarith@*/
+
+ if (nsubs > 0) {
+ char instance[64];
+ int xx = snprintf(instance, sizeof(instance), "'%u'",
+ (uint32_t) headerGetInstance(h));
+ size_t tlen = strlen(s) + nsubs * ((int)strlen(instance) - (int)nmark);
+ char * t = xmalloc(tlen + 1);
+ char * te = t;
+
+ xx = xx;
+/*@-nullptrarith@*/
+ for (f = s; *f != '\0' && (fe = strstr(f, mark)) != NULL; fe += nmark, f = fe) {
+ *fe = '\0';
+ te = stpcpy( stpcpy(te, f), instance);
+ }
+/*@=nullptrarith@*/
+ if (*f != '\0')
+ te = stpcpy(te, f);
+ s = _free(s);
+ s = t;
+ }
+
+ return s;
+}
+#endif
+
+/**
+ * Export a single package's metadata to repository metadata file(s).
+ * @param repo repository
+ * @param rfile repository metadata file
+ * @param h header
+ * @return 0 on success
+ */
+static int rpmrepoWriteMDFile(rpmrepo repo, rpmrfile rfile, Header h)
+ /*@globals fileSystem @*/
+ /*@modifies rfile, h, fileSystem @*/
+{
+ int rc = 0;
+
+ if (rfile->xml_qfmt != NULL) {
+ if (rpmrfileXMLWrite(rfile, rfileHeaderSprintf(h, rfile->xml_qfmt)))
+ rc = 1;
+ }
+
+#if defined(WITH_SQLITE)
+ if (REPO_ISSET(DATABASE)) {
+ if (rpmrfileSQLWrite(rfile, rfileHeaderSprintfHack(h, rfile->sql_qfmt)))
+ rc = 1;
+ }
+#endif
+
+ return rc;
+}
+
+/**
+ * Export all package metadata to repository metadata file(s).
+ * @param repo repository
+ * @return 0 on success
+ */
+static int repoWriteMetadataDocs(rpmrepo repo)
+ /*@globals h_errno, rpmGlobalMacroContext, fileSystem, internalState @*/
+ /*@modifies repo, rpmGlobalMacroContext, fileSystem, internalState @*/
+{
+ const char ** pkglist = repo->pkglist;
+ const char * pkg;
+ int rc = 0;
+
+ if (pkglist)
+ while ((pkg = *pkglist++) != NULL) {
+ Header h = rpmrepoReadHeader(repo, pkg);
+
+ repo->current++;
+
+ /* XXX repoReadHeader() displays error. Continuing is foolish */
+ if (h == NULL) {
+ rc = 1;
+ break;
+ }
+
+#ifdef REFERENCE
+ /* XXX todo: rpmGetPath(mydir, "/", filematrix[mydir], NULL); */
+ reldir = (pkgpath != NULL ? pkgpath : rpmGetPath(repo->basedir, "/", repo->directories[0], NULL));
+ self.primaryfile.write(po.do_primary_xml_dump(reldir, baseurl=repo->baseurl))
+ self.flfile.write(po.do_filelists_xml_dump())
+ self.otherfile.write(po.do_other_xml_dump())
+#endif
+
+ if (rpmrepoWriteMDFile(repo, &repo->primary, h)
+ || rpmrepoWriteMDFile(repo, &repo->filelists, h)
+ || rpmrepoWriteMDFile(repo, &repo->other, h))
+ rc = 1;
+
+ (void) headerFree(h);
+ h = NULL;
+ if (rc) break;
+
+ if (!repo->quiet) {
+ if (repo->verbose)
+ rpmrepoError(0, "%d/%d - %s", repo->current, repo->pkgcount, pkg);
+ else
+ rpmrepoProgress(repo, pkg, repo->current, repo->pkgcount);
+ }
+ }
+ return rc;
+}
+
+int rpmrepoDoPkgMetadata(rpmrepo repo)
+{
+ int rc = 0;
+
+ repo->current = 0;
+
+#ifdef REFERENCE
+ def _getFragmentUrl(self, url, fragment):
+ import urlparse
+ urlparse.uses_fragment.append('media')
+ if not url:
+ return url
+ (scheme, netloc, path, query, fragid) = urlparse.urlsplit(url)
+ return urlparse.urlunsplit((scheme, netloc, path, query, str(fragment)))
+
+ def doPkgMetadata(self):
+ """all the heavy lifting for the package metadata"""
+ if (argvCount(repo->directories) == 1) {
+ MetaDataGenerator.doPkgMetadata(self)
+ return
+ }
+
+ ARGV_t roots = NULL;
+ filematrix = {}
+ for mydir in repo->directories {
+ if (mydir[0] == '/')
+ thisdir = xstrdup(mydir);
+ else if (mydir[0] == '.' && mydir[1] == '.' && mydir[2] == '/')
+ thisdir = Realpath(mydir, NULL);
+ else
+ thisdir = rpmGetPath(repo->basedir, "/", mydir, NULL);
+
+ xx = argvAdd(&roots, thisdir);
+ thisdir = _free(thisdir);
+
+ filematrix[mydir] = rpmrepoGetFileList(repo, roots, '.rpm')
+ self.trimRpms(filematrix[mydir])
+ repo->pkgcount = argvCount(filematrix[mydir]);
+ roots = argvFree(roots);
+ }
+
+ mediano = 1;
+ repo->baseurl = self._getFragmentUrl(repo->baseurl, mediano)
+#endif
+
+ if (rpmrepoOpenMDFile(repo, &repo->primary)
+ || rpmrepoOpenMDFile(repo, &repo->filelists)
+ || rpmrepoOpenMDFile(repo, &repo->other))
+ rc = 1;
+ if (rc) return rc;
+
+#ifdef REFERENCE
+ for mydir in repo->directories {
+ repo->baseurl = self._getFragmentUrl(repo->baseurl, mediano)
+ /* XXX todo: rpmGetPath(mydir, "/", filematrix[mydir], NULL); */
+ if (repoWriteMetadataDocs(repo, filematrix[mydir]))
+ rc = 1;
+ mediano++;
+ }
+ repo->baseurl = self._getFragmentUrl(repo->baseurl, 1)
+#endif
+
+ if (repoWriteMetadataDocs(repo))
+ rc = 1;
+
+ if (!repo->quiet)
+ fprintf(stderr, "\n");
+ if (rpmrepoCloseMDFile(repo, &repo->primary)
+ || rpmrepoCloseMDFile(repo, &repo->filelists)
+ || rpmrepoCloseMDFile(repo, &repo->other))
+ rc = 1;
+
+ return rc;
+}
+
+/*==============================================================*/
+
/*@unchecked@*/
static int compression = -1;
@@ -1258,7 +1660,7 @@
};
/*@unchecked@*/ /*@observer@*/
-struct poptOption _rpmrepoOptions[] = {
+static struct poptOption _rpmrepoOptions[] = {
{ "quiet", 'q', POPT_ARG_VAL, &__repo.quiet, 0,
N_("output nothing except for serious errors"), NULL },
@@ .
patch -p0 <<'@@ .'
Index: rpm/rpmdb/rpmrepo.h
============================================================================
$ cvs diff -u -r1.2 -r1.3 rpmrepo.h
--- rpm/rpmdb/rpmrepo.h 27 Sep 2010 19:41:45 -0000 1.2
+++ rpm/rpmdb/rpmrepo.h 27 Sep 2010 23:12:43 -0000 1.3
@@ -220,28 +220,6 @@
/*@globals fileSystem, internalState @*/
/*@modifies fileSystem, internalState @*/;
-#if defined(_RPMREPO_INTERNAL)
-/**
- * Return stat(2) for a file.
- * @retval st stat(2) buffer
- * @return 0 on success
- */
-int rpmioExists(const char * fn, /*@out@*/ struct stat * st)
- /*@globals h_errno, fileSystem, internalState @*/
- /*@modifies st, fileSystem, internalState @*/;
-
-/**
- * Return stat(2) creation time of a file.
- * @param fn file path
- * @return st_ctime
- */
-time_t rpmioCtime(const char * fn)
- /*@globals h_errno, fileSystem, internalState @*/
- /*@modifies fileSystem, internalState @*/;
-
-/*@unchecked@*/
-extern struct poptOption _rpmrepoOptions[];
-
/**
* Print an error message and exit (if requested).
* @param lvl error level (non-zero exits)
@@ -253,40 +231,6 @@
/*@modifies fileSystem @*/;
/**
- * Return /repository/directory/component.markup.compression path.
- * @param repo repository
- * @param dir directory
- * @param type file
- * @return repository file path
- */
-const char * rpmrepoGetPath(rpmrepo repo, const char * dir,
- const char * type, int compress)
- /*@globals h_errno, rpmGlobalMacroContext, internalState @*/
- /*@modifies rpmGlobalMacroContext, internalState @*/;
-
-/**
- * Display progress.
- * @param repo repository
- * @param item repository item (usually a file path)
- * @param current current iteration index
- * @param total maximum iteration index
- */
-void rpmrepoProgress(/*@unused@*/ rpmrepo repo,
- /*@null@*/ const char * item, int current, int total)
- /*@globals fileSystem, internalState @*/
- /*@modifies fileSystem, internalState @*/;
-
-/**
- * Create directory path.
- * @param repo repository
- * @param dn directory path
- * @return 0 on success
- */
-int rpmrepoMkdir(rpmrepo repo, const char * dn)
- /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
- /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/;
-
-/**
* Return realpath(3) canonicalized absolute path.
* @param lpath file path
* @retrun canonicalized absolute path
@@ -328,88 +272,13 @@
/*@modifies fileSystem, internalState @*/;
/**
- * Write to a repository metadata file.
- * @param rfile repository metadata file
- * @param spew contents
- * @return 0 on success
- */
-int rpmrfileXMLWrite(rpmrfile rfile, /*@only@*/ /*@null@*/ const char * spew)
- /*@globals fileSystem @*/
- /*@modifies rfile, fileSystem @*/;
-
-/**
- * Close an I/O stream, accumulating uncompress/digest statistics.
- * @param repo repository
- * @param fd I/O stream
- * @return 0 on success
- */
-int rpmrepoFclose(rpmrepo repo, FD_t fd)
- /*@modifies repo, fd @*/;
-
-/**
- * Open a repository metadata file.
+ * Write repository metadata files.
* @param repo repository
- * @param rfile repository metadata file
* @return 0 on success
*/
-int rpmrepoOpenMDFile(const rpmrepo repo, rpmrfile rfile)
+int rpmrepoDoPkgMetadata(rpmrepo repo)
/*@globals h_errno, rpmGlobalMacroContext, fileSystem, internalState @*/
- /*@modifies rfile, rpmGlobalMacroContext, fileSystem, internalState @*/;
-
-/**
- * Check sqlite3 return, displaying error messages.
- * @param rfile repository metadata file
- * @return SQLITE_OK on success
- */
-int rpmrfileSQL(rpmrfile rfile, const char * msg, int rc)
- /*@globals fileSystem @*/
- /*@modifies fileSystem @*/;
-
-/**
- * Execute a compiled SQL command.
- * @param rfile repository metadata file
- * @return SQLITE_OK on success
- */
-int rpmrfileSQLStep(rpmrfile rfile, sqlite3_stmt * stmt)
- /*@globals fileSystem @*/
- /*@modifies fileSystem @*/;
-
-/**
- * Run a sqlite3 command.
- * @param rfile repository metadata file
- * @param cmd sqlite3 command to run
- * @return 0 always
- */
-int rpmrfileSQLWrite(rpmrfile rfile, /*@only@*/ const char * cmd)
- /*@globals fileSystem @*/
- /*@modifies fileSystem @*/;
-
-/**
- * Compute digest of a file.
- * @return 0 on success
- */
-int rpmrepoRfileDigest(const rpmrepo repo, rpmrfile rfile,
- const char ** digestp)
- /*@modifies *digestp @*/;
-
-/**
- * Close a repository metadata file.
- * @param repo repository
- * @param rfile repository metadata file
- * @return 0 on success
- */
-int rpmrepoCloseMDFile(const rpmrepo repo, rpmrfile rfile)
- /*@globals h_errno, rpmGlobalMacroContext, fileSystem, internalState @*/
- /*@modifies rfile, rpmGlobalMacroContext, fileSystem, internalState @*/;
-
-/**
- * Return a repository metadata file item.
- * @param repo repository
- * @return repository metadata file item
- */
-const char * rpmrepoMDExpand(rpmrepo repo, rpmrfile rfile)
- /*@globals h_errno, rpmGlobalMacroContext, internalState @*/
- /*@modifies rpmGlobalMacroContext, internalState @*/;
+ /*@modifies repo, rpmGlobalMacroContext, fileSystem, internalState @*/;
/**
* Write repository manifest.
@@ -429,8 +298,6 @@
/*@globals h_errno, rpmGlobalMacroContext, fileSystem, internalState @*/
/*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/;
-#endif /* _RPMREPO_INTERNAL */
-
#ifdef __cplusplus
}
#endif
@@ .
Received on Tue Sep 28 01:12:49 2010