[prev in list] [next in list] [prev in thread] [next in thread]
List: rpm-cvs
Subject: [CVS] RPM: rpm/ CHANGES rpm/tools/ rpmdigest.c
From: "Jeff Johnson" <jbj () rpm5 ! org>
Date: 2008-06-23 20:52:51
Message-ID: 20080623205251.64EDA348470 () rpm5 ! org
[Download RAW message or body]
RPM Package Manager, CVS Repository
http://rpm5.org/cvs/
____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson
Root: /v/rpm/cvs Email: jbj@rpm5.org
Module: rpm Date: 23-Jun-2008 22:52:51
Branch: HEAD Handle: 2008062320525001
Modified files:
rpm CHANGES
rpm/tools rpmdigest.c
Log:
- rpmdigest: achieve 0install manifest spewage for file args.
- rpmdigest: refactor to prepare for 0install manifest spewage.
Summary:
Revision Changes Path
1.2435 +1 -0 rpm/CHANGES
2.5 +322 -139 rpm/tools/rpmdigest.c
____________________________________________________________________________
patch -p0 <<'@@ .'
Index: rpm/CHANGES
============================================================================
$ cvs diff -u -r1.2434 -r1.2435 CHANGES
--- rpm/CHANGES 23 Jun 2008 19:16:29 -0000 1.2434
+++ rpm/CHANGES 23 Jun 2008 20:52:50 -0000 1.2435
@@ -1,5 +1,6 @@
5.1.0 -> 5.2a0:
+ - jbj: rpmdigest: achieve 0install manifest spewage for file args.
- jbj: rpmdigest: refactor to prepare for 0install manifest spewage.
- jbj: rpmrepo: put a --stats stopwatch on the mmap digest cost as well.
- jbj: rpmrepo: add repoFclose(), accumulate I/O stats into a ts.
@@ .
patch -p0 <<'@@ .'
Index: rpm/tools/rpmdigest.c
============================================================================
$ cvs diff -u -r2.4 -r2.5 rpmdigest.c
--- rpm/tools/rpmdigest.c 2 Jun 2008 19:23:03 -0000 2.4
+++ rpm/tools/rpmdigest.c 23 Jun 2008 20:52:51 -0000 2.5
@@ -14,16 +14,27 @@
enum dcFlags_e {
RPMDC_FLAGS_BINARY = _DFB( 0), /*!< -b,--binary ... */
RPMDC_FLAGS_WARN = _DFB( 1), /*!< -w,--warn ... */
- RPMDC_FLAGS_STATUS = _DFB( 2) /*!< --status ... */
+ RPMDC_FLAGS_STATUS = _DFB( 2), /*!< --status ... */
+ RPMDC_FLAGS_0INSTALL= _DFB( 3) /*!< -0 --0install ... */
};
struct rpmdc_s {
enum dcFlags_e flags;
uint32_t algo; /*!< default digest algorithm. */
+ uint32_t dalgo; /*!< digest algorithm. */
+/*@observer@*/ /*@null@*/
+ const char * dalgoName; /*!< digest algorithm name. */
const char * digest;
size_t digestlen;
const char * fn;
FD_t fd;
+ struct stat sb;
+ int (*parse) (rpmdc dc);
+ const char * (*print) (rpmdc dc, int rc);
+ const char * ofn; /*!< output file name */
+ FD_t ofd; /*!< output file handle */
+ uint32_t oalgo; /*!< output digest algorithm. */
+ const char * oalgoName; /*!< output digest algorithm name. */
ARGV_t manifests; /*!< array of file manifests to verify. */
ARGI_t algos; /*!< array of file digest algorithms. */
ARGV_t digests; /*!< array of file digests. */
@@ -31,131 +42,17 @@
unsigned char buf[BUFSIZ];
ssize_t nb;
int ix;
- int nfails;
+ size_t ncomputed; /*!< no. of digests computed. */
+ size_t nchecked; /*!< no. of digests checked. */
+ size_t nmatched; /*!< no. of digests matched. */
+ size_t nfailed; /*!< no. of digests failed. */
+ struct rpmop_s totalops;
+ struct rpmop_s readops;
+ struct rpmop_s digestops;
};
-static struct rpmdc_s _dc;
-static rpmdc dc = &_dc;
-
-static struct rpmop_s dc_totalops;
-static struct rpmop_s dc_readops;
-static struct rpmop_s dc_digestops;
-
-static int rpmdcPrintFile(rpmdc dc, int algo, const char * algoName)
-{
- static int asAscii = 1;
- int rc = 0;
-
- fdFiniDigest(dc->fd, algo, &dc->digest, &dc->digestlen, asAscii);
-assert(dc->digest != NULL);
- if (dc->manifests) {
- const char * msg = "OK";
- if ((rc = strcmp(dc->digest, dc->digests[dc->ix])) != 0) {
- msg = "FAILED";
- dc->nfails++;
- }
- if (rc || !F_ISSET(dc, STATUS))
- fprintf(stdout, "%s: %s\n", dc->fn, msg);
- } else {
- if (!F_ISSET(dc, STATUS)) {
- if (algoName) fprintf(stdout, "%s:", algoName);
- fprintf(stdout, "%s %c%s\n", dc->digest,
- (F_ISSET(dc, BINARY) ? '*' : ' '), dc->fn);
- fflush(stdout);
- }
- dc->digest = _free(dc->digest);
- }
- return rc;
-}
-
-static int rpmdcFiniFile(rpmdc dc)
-{
- uint32_t algo = (dc->manifests ? dc->algos->vals[dc->ix] : dc->algo);
- int rc = 0;
- int xx;
-
- switch (algo) {
- default:
- xx = rpmdcPrintFile(dc, algo, NULL);
- if (xx) rc = xx;
- break;
- case 256: /* --all digests requested. */
- { struct poptOption * opt = rpmioDigestPoptTable;
- for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
- if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)
- continue;
- if (opt->arg != (void *)&rpmioDigestHashAlgo)
- continue;
- dc->algo = opt->val;
- if (!(dc->algo > 0 && dc->algo < 256))
- continue;
- xx = rpmdcPrintFile(dc, dc->algo, opt->longName);
- if (xx) rc = xx;
- }
- } break;
- }
- (void) rpmswAdd(&dc_readops, fdstat_op(dc->fd, FDSTAT_READ));
- (void) rpmswAdd(&dc_digestops, fdstat_op(dc->fd, FDSTAT_DIGEST));
- Fclose(dc->fd);
- dc->fd = NULL;
- return rc;
-}
-
-static int rpmdcCalcFile(rpmdc dc)
-{
- int rc = 0;
-
- do {
- dc->nb = Fread(dc->buf, sizeof(dc->buf[0]), sizeof(dc->buf), dc->fd);
- if (Ferror(dc->fd)) {
- rc = 2;
- break;
- }
- } while (dc->nb > 0);
-
- return rc;
-}
-
-static int rpmdcInitFile(rpmdc dc)
-{
- uint32_t algo = (dc->manifests ? dc->algos->vals[dc->ix] : dc->algo);
- int rc = 0;
-
- /* XXX Stat(2) to insure files only? */
- dc->fd = Fopen(dc->fn, "r.ufdio");
- if (dc->fd == NULL || Ferror(dc->fd)) {
- fprintf(stderr, _("open of %s failed: %s\n"), dc->fn, Fstrerror(dc->fd));
- if (dc->fd != NULL) Fclose(dc->fd);
- dc->fd = NULL;
- rc = 2;
- goto exit;
- }
-
- switch (dc->algo) {
- default:
- /* XXX TODO: instantiate verify digests for all identical paths. */
- fdInitDigest(dc->fd, algo, 0);
- break;
- case 256: /* --all digests requested. */
- { struct poptOption * opt = rpmioDigestPoptTable;
- for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
- if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)
- continue;
- if (opt->longName == NULL)
- continue;
- if (!(opt->val > 0 && opt->val < 256))
- continue;
- algo = opt->val;
- fdInitDigest(dc->fd, algo, 0);
- }
- } break;
- }
-
-exit:
- return rc;
-}
-
-static int rpmdcLoadManifests(rpmdc dc)
+/* ================================================= */
+static int rpmdcParseCoreutils(rpmdc dc)
/*@globals h_errno, fileSystem, internalState @*/
/*@modifies h_errno, fileSystem, internalState @*/
{
@@ -185,7 +82,6 @@
while (fgets(buf, sizeof(buf), fp) != NULL) {
const char * dname, * digest, * path;
char *se = buf + (int)strlen(buf);
- int algo;
int c, xx;
while (se > buf && xisspace((int)se[-1]))
@@ -197,6 +93,7 @@
/* Skip comment lines */
if (buf[0] == '#') /*@innercontinue@*/ continue;
+ /* Parse "[algo:]digest [* ]path" line. */
dname = NULL; path = NULL;
for (digest = se = buf; (c = (int)*se) != 0; se++)
switch (c) {
@@ -218,7 +115,8 @@
/* Map name to algorithm number. */
if (dname) {
struct poptOption * opt = rpmioDigestPoptTable;
- algo = -1;
+ dc->dalgo = 0xffffffff;
+ dc->dalgoName = NULL;
for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)
continue;
@@ -228,20 +126,21 @@
continue;
if (strcmp(opt->longName, dname))
continue;
- algo = opt->val;
+ dc->dalgo = (uint32_t) opt->val;
+ dc->dalgoName = opt->longName;
break;
}
- if (algo == -1) {
+ if (dc->dalgo == 0xffffffff) {
fprintf(stderr, _("%s: Unknown digest name \"%s\"\n"),
__progname, dname);
rc = 2;
goto exit;
}
} else
- algo = dc->algo;
+ dc->dalgo = dc->algo;
/* Save {algo, digest, path} for processing. */
- xx = argiAdd(&dc->algos, -1, algo);
+ xx = argiAdd(&dc->algos, -1, dc->dalgo);
xx = argvAdd(&dc->digests, digest);
xx = argvAdd(&dc->paths, path);
}
@@ -257,6 +156,259 @@
return rc;
}
+/*@null@*/
+static const char * rpmdcPrintCoreutils(rpmdc dc, int rc)
+{
+ const char *msg = (rc ? "FAILED" : "OK");
+ char * t, * te;
+ size_t nb = 0;
+
+ /* Don't bother formatting if noone cares. */
+ if (rc == 0 && F_ISSET(dc, STATUS))
+ return NULL;
+
+ /* Calculate size of message. */
+ if (dc->dalgoName != NULL)
+ nb += strlen(dc->dalgoName) + sizeof(":") - 1;
+ if (dc->digest != NULL && dc->digestlen > 0)
+ nb += dc->digestlen;
+ nb += sizeof(" *") - 1;
+ if (dc->fn != NULL)
+ nb += strlen(dc->fn);
+ nb += strlen(msg);
+ nb += sizeof("\n"); /* XXX trailing NUL */
+
+ /* Compose the message. */
+ te = t = xmalloc(nb);
+ *te = '\0';
+
+ if (dc->manifests) {
+ if (rc || !F_ISSET(dc, STATUS)) {
+ if (dc->fn)
+ te = stpcpy( stpcpy(te, dc->fn), ": ");
+ te = stpcpy(te, msg);
+ *te++ = '\n';
+ }
+ } else {
+ if (dc->dalgoName)
+ te = stpcpy( stpcpy(te, dc->dalgoName), ":");
+ te = stpcpy(te, dc->digest);
+ *te++ = ' ';
+ *te++ = (F_ISSET(dc, BINARY) ? '*' : ' ');
+ te = stpcpy(te, dc->fn);
+ *te++ = '\n';
+ }
+ *te = '\0';
+
+ return t;
+}
+
+/* ================================================= */
+/*@null@*/
+static const char * rpmdcPrintZeroInstall(rpmdc dc, int rc)
+{
+ char * t, * te;
+ size_t nb = 0;
+ char _mtime[32];
+ char _size[32];
+ const char * _bn;
+
+ /* Don't bother formatting if noone cares. */
+ if (rc == 0 && F_ISSET(dc, STATUS))
+ return NULL;
+
+ snprintf(_mtime, sizeof(_mtime), "%llu",
+ (unsigned long long) dc->sb.st_mtime);
+ _mtime[sizeof(_mtime)-1] = '\0';
+ snprintf(_size, sizeof(_size), "%llu",
+ (unsigned long long)dc->sb.st_size);
+ _size[sizeof(_size)-1] = '\0';
+ if ((_bn = strrchr(dc->fn, '/')) != NULL)
+ _bn++;
+ else
+ _bn = dc->fn;
+
+ /* Calculate size of message. */
+ nb += sizeof("F");
+ if (dc->digest != NULL && dc->digestlen > 0)
+ nb += 1 + dc->digestlen;
+ nb += 1 + strlen(_mtime);
+ nb += 1 + strlen(_size);
+ nb += 1 + strlen(_bn);
+ nb += sizeof("\n"); /* XXX trailing NUL */
+
+ /* Compose the message. */
+ te = t = xmalloc(nb);
+ *te = '\0';
+
+ if (dc->manifests) {
+#ifdef NOTYET
+ const char *msg = (rc ? "FAILED" : "OK");
+ if (rc || !F_ISSET(dc, STATUS)) {
+ if (dc->fn)
+ te = stpcpy( stpcpy(te, dc->fn), ": ");
+ te = stpcpy(te, msg);
+ *te++ = '\n';
+ }
+#endif
+ } else {
+ *te++ = 'F';
+ *te++ = ' ';
+ te = stpcpy(te, dc->digest);
+ *te++ = ' ';
+ te = stpcpy(te, _mtime);
+ *te++ = ' ';
+ te = stpcpy(te, _size);
+ *te++ = ' ';
+ te = stpcpy(te, _bn);
+ *te++ = '\n';
+ }
+ *te = '\0';
+
+ return t;
+}
+
+/* ================================================= */
+static struct rpmdc_s _dc = {
+ .parse = rpmdcParseCoreutils,
+ .print = rpmdcPrintCoreutils
+};
+
+static rpmdc dc = &_dc;
+
+static int rpmdcPrintFile(rpmdc dc)
+{
+ static int asAscii = 1;
+ int rc = 0;
+
+ fdFiniDigest(dc->fd, dc->dalgo, &dc->digest, &dc->digestlen, asAscii);
+assert(dc->digest != NULL);
+ dc->ncomputed++;
+
+ if (dc->manifests) {
+ dc->nchecked++;
+ if ((rc = strcmp(dc->digest, dc->digests[dc->ix])) != 0)
+ dc->nfailed++;
+ else
+ dc->nmatched++;
+ }
+
+ { const char * t = (*dc->print) (dc, rc);
+ if (dc->ofd && t && *t) {
+ size_t nb = strlen(t);
+ nb = Fwrite(t, nb, sizeof(*t), dc->ofd);
+ (void) Fflush(dc->ofd);
+ }
+ t = _free(t);
+ }
+
+ dc->digest = _free(dc->digest);
+ return rc;
+}
+
+static int rpmdcFiniFile(rpmdc dc)
+{
+ uint32_t dalgo = (dc->manifests ? dc->algos->vals[dc->ix] : dc->algo);
+ int rc = 0;
+ int xx;
+
+ switch (dalgo) {
+ default:
+ dc->dalgo = dalgo;
+ dc->dalgoName = NULL;
+ xx = rpmdcPrintFile(dc);
+ if (xx) rc = xx;
+ break;
+ case 256: /* --all digests requested. */
+ { struct poptOption * opt = rpmioDigestPoptTable;
+ for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
+ if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)
+ continue;
+ if (opt->arg != (void *)&rpmioDigestHashAlgo)
+ continue;
+ dc->dalgo = opt->val;
+ if (!(dc->dalgo > 0 && dc->dalgo < 256))
+ continue;
+ dc->dalgoName = opt->longName;
+ xx = rpmdcPrintFile(dc);
+ if (xx) rc = xx;
+ }
+ } break;
+ }
+ (void) rpmswAdd(&dc->readops, fdstat_op(dc->fd, FDSTAT_READ));
+ (void) rpmswAdd(&dc->digestops, fdstat_op(dc->fd, FDSTAT_DIGEST));
+ Fclose(dc->fd);
+ dc->fd = NULL;
+ return rc;
+}
+
+static int rpmdcCalcFile(rpmdc dc)
+{
+ int rc = 0;
+
+ do {
+ dc->nb = Fread(dc->buf, sizeof(dc->buf[0]), sizeof(dc->buf), dc->fd);
+ if (Ferror(dc->fd)) {
+ rc = 2;
+ break;
+ }
+ } while (dc->nb > 0);
+
+ return rc;
+}
+
+static int rpmdcInitFile(rpmdc dc)
+{
+ int rc;
+
+ /* XXX Stat(2) to insure files only? */
+ if ((rc = Lstat(dc->fn, &dc->sb)) != 0) {
+ memset(&dc->sb, 0, sizeof(dc->sb));
+ goto exit;
+ }
+
+ dc->fd = Fopen(dc->fn, "r.ufdio");
+ if (dc->fd == NULL || Ferror(dc->fd)) {
+ fprintf(stderr, _("open of %s failed: %s\n"), dc->fn, Fstrerror(dc->fd));
+ if (dc->fd != NULL) Fclose(dc->fd);
+ dc->fd = NULL;
+ rc = 2;
+ goto exit;
+ }
+
+ switch (dc->algo) {
+ default:
+ /* XXX TODO: instantiate verify digests for all identical paths. */
+ dc->dalgo = dc->algo;
+ fdInitDigest(dc->fd, dc->dalgo, 0);
+ break;
+ case 256: /* --all digests requested. */
+ { struct poptOption * opt = rpmioDigestPoptTable;
+ for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
+ if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)
+ continue;
+ if (opt->longName == NULL)
+ continue;
+ if (!(opt->val > 0 && opt->val < 256))
+ continue;
+ dc->dalgo = opt->val;
+ dc->dalgoName = opt->longName;
+ fdInitDigest(dc->fd, dc->dalgo, 0);
+ }
+ } break;
+ }
+
+exit:
+ return rc;
+}
+
+static int rpmdcLoadManifests(rpmdc dc)
+ /*@globals h_errno, fileSystem, internalState @*/
+ /*@modifies dc, h_errno, fileSystem, internalState @*/
+{
+ return (dc->manifests != NULL ? (*dc->parse) (dc) : 0);
+}
+
#if !defined(POPT_ARG_ARGV)
static int _poptSaveString(const char ***argvp, unsigned int argInfo, const char * val)
/*@*/
@@ -305,7 +457,7 @@
}
#endif /* POPT_ARG_ARGV */
-static struct poptOption optionsTable[] = {
+static struct poptOption _optionsTable[] = {
#if !defined(POPT_ARG_ARGV)
/*@-type@*/ /* FIX: cast? */
{ NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
@@ -313,6 +465,9 @@
/*@=type@*/
#endif /* POPT_ARG_ARGV */
+ { "0install", '0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN, &_dc.flags, RPMDC_FLAGS_0INSTALL,
+ N_("print 0install manifest"), NULL },
+
{ "binary", 'b', POPT_BIT_SET, &_dc.flags, RPMDC_FLAGS_BINARY,
N_("read in binary mode"), NULL },
@@ -361,6 +516,8 @@
POPT_TABLEEND
};
+static struct poptOption *optionsTable = &_optionsTable[0];
+
int
main(int argc, char *argv[])
{
@@ -370,12 +527,23 @@
int rc = 0;
int xx;
- rpmswEnter(&dc_totalops, -1);
+ rpmswEnter(&dc->totalops, -1);
if ((int)rpmioDigestHashAlgo < 0)
rpmioDigestHashAlgo = PGPHASHALGO_MD5;
dc->algo = rpmioDigestHashAlgo;
+ if (dc->ofn == NULL)
+ dc->ofn = "-";
+ dc->ofd = Fopen(dc->ofn, "w.ufdio");
+
+ if (F_ISSET(dc, 0INSTALL)) {
+ dc->print = rpmdcPrintZeroInstall;
+ dc->algo = PGPHASHALGO_SHA1;
+ dc->oalgo = PGPHASHALGO_SHA1;
+ dc->oalgoName = "sha1";
+ fdInitDigest(dc->ofd, dc->oalgo, 0);
+ }
av = poptGetArgs(optCon);
ac = argvCount(av);
@@ -406,9 +574,24 @@
}
exit:
- if (dc->nfails)
- fprintf(stderr, "%s: WARNING: %d of %d computed checksums did NOT match\n",
- __progname, dc->nfails, dc->ix);
+ if (dc->nfailed)
+ fprintf(stderr, "%s: WARNING: %u of %d computed checksums did NOT match\n",
+ __progname, dc->nfailed, dc->ncomputed);
+
+ if (dc->ofd) {
+ if (F_ISSET(dc, 0INSTALL)) {
+ static int asAscii = 1;
+ char *t;
+ fdFiniDigest(dc->ofd, dc->oalgo, &dc->digest, &dc->digestlen, asAscii);
+assert(dc->digest != NULL);
+ t = rpmExpand(dc->oalgoName, "=", dc->digest, "\n", NULL);
+ (void) Fwrite(t, strlen(t), sizeof(*t), dc->ofd);
+ t = _free(t);
+ dc->digest = _free(dc->digest);
+ }
+ (void) Fclose(dc->ofd);
+ dc->ofd = NULL;
+ }
#ifdef NOTYET
dc->manifests = argvFree(dc->manifests);
@@ -417,11 +600,11 @@
dc->digests = argvFree(dc->digests);
dc->paths = argvFree(dc->paths);
- rpmswExit(&dc_totalops, 0);
+ rpmswExit(&dc->totalops, 0);
if (_rpmsw_stats) {
- rpmswPrint(" total:", &dc_totalops);
- rpmswPrint(" read:", &dc_readops);
- rpmswPrint("digest:", &dc_digestops);
+ rpmswPrint(" total:", &dc->totalops);
+ rpmswPrint(" read:", &dc->readops);
+ rpmswPrint("digest:", &dc->digestops);
}
optCon = rpmioFini(optCon);
@@ .
______________________________________________________________________
RPM Package Manager http://rpm5.org
CVS Sources Repository rpm-cvs@rpm5.org
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic