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: 18-Aug-2007 18:45:03
Branch: HEAD Handle: 2007081817450200
Added files:
rpm/tools rpmcache.c rpmcmp.c rpmdigest.c
Modified files:
rpm CHANGES
rpm/tools Makefile.am
Log:
- re-add rpmcache/rpmcmp/rpmdigest tools.
Summary:
Revision Changes Path
1.1585 +1 -0 rpm/CHANGES
2.98 +10 -1 rpm/tools/Makefile.am
2.13 +586 -0 rpm/tools/rpmcache.c
2.1 +89 -0 rpm/tools/rpmcmp.c
2.1 +61 -0 rpm/tools/rpmdigest.c
____________________________________________________________________________
patch -p0 <<'@@ .'
Index: rpm/CHANGES
============================================================================
$ cvs diff -u -r1.1584 -r1.1585 CHANGES
--- rpm/CHANGES 18 Aug 2007 16:29:20 -0000 1.1584
+++ rpm/CHANGES 18 Aug 2007 16:45:02 -0000 1.1585
@@ -1,4 +1,5 @@
4.5 -> 5.0:
+ - jbj: re-add rpmcache/rpmcmp/rpmdigest tools.
- jbj: more rpmInstall refactoring.
- jbj: use rpmgi for --addsign/--checksig arg iteration.
- jbj: repair a minor rpmInstall and major matchpathcon_init() memleaks.
@@ .
patch -p0 <<'@@ .'
Index: rpm/tools/Makefile.am
============================================================================
$ cvs diff -u -r2.97 -r2.98 Makefile.am
--- rpm/tools/Makefile.am 15 Aug 2007 13:23:05 -0000 2.97
+++ rpm/tools/Makefile.am 18 Aug 2007 16:45:02 -0000 2.98
@@ -22,14 +22,23 @@
@LTLIBINTL@
pkglibdir = @USRLIBRPM@
-pkglib_PROGRAMS = rpmdeps @WITH_LIBELF_DEBUGEDIT@
+pkglib_PROGRAMS = rpmcache rpmcmp rpmdeps rpmdigest @WITH_LIBELF_DEBUGEDIT@
debugedit_SOURCES = debugedit.c hashtab.c
debugedit_LDADD = $(myLDADD)
+rpmcache_SOURCES = rpmcache.c
+rpmcache_LDADD = $(myLDADD)
+
+rpmcmp_SOURCES = rpmcmp.c
+rpmcmp_LDADD = $(myLDADD)
+
rpmdeps_SOURCES = rpmdeps.c
rpmdeps_LDADD = $(myLDADD)
+rpmdigest_SOURCES = rpmdigest.c
+rpmdigest_LDADD = $(myLDADD)
+
##
## keyctl(1) clone
##
@@ .
patch -p0 <<'@@ .'
Index: rpm/tools/rpmcache.c
============================================================================
$ cvs diff -u -r0 -r2.13 rpmcache.c
--- /dev/null 2007-08-18 18:44:00 +0200
+++ rpmcache.c 2007-08-18 18:45:03 +0200
@@ -0,0 +1,586 @@
+/**
+ * \file tools/rpmcache.c
+ */
+
+#include "system.h"
+const char *__progname;
+
+#include <fnmatch.h>
+#include <fts.h>
+
+#include <rpmio.h>
+#include <rpmcli.h>
+
+#define _RPMGI_INTERNAL
+#include <rpmgi.h>
+
+#include "rpmps.h"
+#include "rpmdb.h"
+
+#include "misc.h" /* XXX rpmMkdirPath */
+
+#include "debug.h"
+
+static int _debug = 0;
+
+/* XXX should be flag in ts */
+static int noCache = 0;
+
+static ARGV_t ftsSet;
+
+const char * bhpath;
+int bhpathlen = 0;
+int bhlvl = -1;
+
+struct ftsglob_s {
+ const char ** patterns;
+ int fnflags;
+};
+
+static struct ftsglob_s * bhglobs;
+static int nbhglobs = 5;
+
+static int indent = 2;
+
+typedef struct Item_s {
+ const char * path;
+ int_32 size;
+ int_32 mtime;
+ rpmds this;
+ Header h;
+} * Item;
+
+static Item * items = NULL;
+static int nitems = 0;
+
+static inline Item freeItem(Item item) {
+ if (item != NULL) {
+ item->path = _free(item->path);
+ item->this = rpmdsFree(item->this);
+ item->h = headerFree(item->h);
+ item = _free(item);
+ }
+ return NULL;
+}
+
+static inline Item newItem(void) {
+ Item item = xcalloc(1, sizeof(*item));
+ return item;
+}
+
+static int cmpItem(const void * a, const void * b) {
+ Item aitem = *(Item *)a;
+ Item bitem = *(Item *)b;
+ int rc = strcmp(rpmdsN(aitem->this), rpmdsN(bitem->this));
+ return rc;
+}
+
+static void freeItems(void) {
+ int i;
+ for (i = 0; i < nitems; i++)
+ items[i] = freeItem(items[i]);
+ items = _free(items);
+ nitems = 0;
+}
+
+static int ftsCachePrint(/*@unused@*/ rpmts ts, FILE * fp)
+{
+ int rc = 0;
+ int i;
+
+ if (fp == NULL) fp = stdout;
+ for (i = 0; i < nitems; i++) {
+ Item ip;
+
+ ip = items[i];
+ if (ip == NULL) {
+ rc = 1;
+ break;
+ }
+
+ fprintf(fp, "%s\n", ip->path);
+ }
+ return rc;
+}
+
+static int ftsCacheUpdate(rpmts ts)
+{
+ HGE_t hge = (HGE_t)headerGetEntryMinMemory;
+ int_32 tid = rpmtsGetTid(ts);
+ rpmdbMatchIterator mi;
+ unsigned char * md5;
+ int rc = 0;
+ int xx;
+ int i;
+
+ rc = rpmtsCloseDB(ts);
+ rc = rpmDefineMacro(NULL, "_dbpath %{_cache_dbpath}", RMIL_CMDLINE);
+ rc = rpmtsOpenDB(ts, O_RDWR);
+ if (rc != 0)
+ return rc;
+
+ for (i = 0; i < nitems; i++) {
+ Item ip;
+
+ ip = items[i];
+ if (ip == NULL) {
+ rc = 1;
+ break;
+ }
+
+ /* --- Check that identical package is not already cached. */
+ if (!hge(ip->h, RPMTAG_SIGMD5, NULL, (void **) &md5, NULL)
+ || md5 == NULL)
+ {
+ rc = 1;
+ break;
+ }
+ mi = rpmtsInitIterator(ts, RPMTAG_SIGMD5, md5, 16);
+ rc = rpmdbGetIteratorCount(mi);
+ mi = rpmdbFreeIterator(mi);
+ if (rc) {
+ rc = 0;
+ continue;
+ }
+
+ /* --- Add cache tags to new cache header. */
+ rc = headerAddOrAppendEntry(ip->h, RPMTAG_CACHECTIME,
+ RPM_INT32_TYPE, &tid, 1);
+ if (rc != 1) break;
+ rc = headerAddOrAppendEntry(ip->h, RPMTAG_CACHEPKGPATH,
+ RPM_STRING_ARRAY_TYPE, &ip->path, 1);
+ if (rc != 1) break;
+ rc = headerAddOrAppendEntry(ip->h, RPMTAG_CACHEPKGSIZE,
+ RPM_INT32_TYPE, &ip->size, 1);
+ if (rc != 1) break;
+ rc = headerAddOrAppendEntry(ip->h, RPMTAG_CACHEPKGMTIME,
+ RPM_INT32_TYPE, &ip->mtime, 1);
+ if (rc != 1) break;
+
+ /* --- Add new cache header to database. */
+ rc = rpmdbAdd(rpmtsGetRdb(ts), tid, ip->h, NULL, NULL);
+ if (rc) break;
+
+ }
+ xx = rpmtsCloseDB(ts);
+ return rc;
+}
+
+static rpmRC cacheStashLatest(rpmgi gi, Header h)
+{
+ FTSENT * fts = gi->fts;
+ rpmds add = NULL;
+ struct stat sb, * st;
+ int ec = -1; /* assume not found */
+ int i = 0;
+
+ rpmMessage(RPMMESS_DEBUG, "============== %s\n", fts->fts_accpath);
+
+ /* XXX DIEDIEDIE: check platform compatibility. */
+
+ add = rpmdsThis(h, RPMTAG_REQUIRENAME, (RPMSENSE_EQUAL|RPMSENSE_LESS));
+
+ if (items != NULL && nitems > 0) {
+ Item needle = memset(alloca(sizeof(*needle)), 0, sizeof(*needle));
+ Item * found, * fneedle = &needle;
+
+ needle->this = add;
+
+ found = bsearch(fneedle, items, nitems, sizeof(*found), cmpItem);
+
+ /* Rewind to the first item with same name. */
+ while (found > items && cmpItem(found-1, fneedle) == 0)
+ found--;
+
+ /* Check that all saved items are newer than this item. */
+ if (found != NULL)
+ while (found < (items + nitems) && cmpItem(found, fneedle) == 0) {
+ ec = rpmdsCompare(needle->this, (*found)->this);
+ if (ec == 0) {
+ found++;
+ continue;
+ }
+ i = found - items;
+ break;
+ }
+ }
+
+ /*
+ * At this point, ec is
+ * -1 no item with the same name has been seen.
+ * 0 item exists, but already saved item EVR is newer.
+ * 1 item exists, but already saved item EVR is same/older.
+ */
+ if (ec == 0) {
+ goto exit;
+ } else if (ec == 1) {
+ items[i] = freeItem(items[i]);
+ } else {
+ i = nitems++;
+ items = xrealloc(items, nitems * sizeof(*items));
+ }
+
+ items[i] = newItem();
+ items[i]->path = xstrdup(fts->fts_path);
+ st = fts->fts_statp;
+ if (st == NULL && Stat(fts->fts_accpath, &sb) == 0)
+ st = &sb;
+
+ if (st != NULL) {
+ items[i]->size = st->st_size;
+ items[i]->mtime = st->st_mtime;
+ }
+ st = NULL;
+ items[i]->this = rpmdsThis(h, RPMTAG_PROVIDENAME, RPMSENSE_EQUAL);
+ items[i]->h = headerLink(h);
+
+ if (nitems > 1)
+ qsort(items, nitems, sizeof(*items), cmpItem);
+
+#if 0
+ fprintf(stderr, "\t%*s [%d] %s\n",
+ indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
+ i, fts->fts_name);
+#endif
+
+exit:
+ add = rpmdsFree(add);
+ return (ec ? RPMRC_NOTFOUND : RPMRC_OK);
+}
+
+static const char * ftsInfoStrings[] = {
+ "UNKNOWN",
+ "D",
+ "DC",
+ "DEFAULT",
+ "DNR",
+ "DOT",
+ "DP",
+ "ERR",
+ "F",
+ "INIT",
+ "NS",
+ "NSOK",
+ "SL",
+ "SLNONE",
+ "W",
+};
+
+static const char * ftsInfoStr(int fts_info) {
+ if (!(fts_info >= 1 && fts_info <= 14))
+ fts_info = 0;
+ return ftsInfoStrings[ fts_info ];
+}
+
+static rpmRC cacheWalkPathFilter(rpmgi gi)
+{
+ FTS * ftsp = gi->ftsp;
+ FTSENT * fts = gi->fts;
+ struct ftsglob_s * bhg;
+ const char ** patterns;
+ const char * pattern;
+ const char * s;
+ int lvl;
+ int xx;
+
+ switch (fts->fts_info) {
+ case FTS_D: /* preorder directory */
+ if (fts->fts_pathlen < bhpathlen)
+ break;
+
+ /* Grab the level of the beehive top directory. */
+ if (bhlvl < 0) {
+ if (fts->fts_pathlen == bhpathlen && !strcmp(fts->fts_path, bhpath))
+ bhlvl = fts->fts_level;
+ else
+ break;
+ }
+ lvl = fts->fts_level - bhlvl;
+
+ if (lvl < 0)
+ break;
+
+#if 0
+ if (_debug)
+ fprintf(stderr, "FTS_%s\t%*s %s\n", ftsInfoStr(fts->fts_info),
+ indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
+ fts->fts_name);
+#endif
+
+ /* Full path glob expression check. */
+ bhg = bhglobs;
+
+ if ((patterns = bhg->patterns) != NULL)
+ while ((pattern = *patterns++) != NULL) {
+ if (*pattern == '/')
+ xx = fnmatch(pattern, fts->fts_path, bhg->fnflags);
+ else
+ xx = fnmatch(pattern, fts->fts_name, bhg->fnflags);
+ if (xx == 0)
+ break;
+ }
+
+ /* Level specific glob expression check(s). */
+ if (lvl == 0 || lvl >= nbhglobs)
+ break;
+ bhg += lvl;
+
+ if ((patterns = bhg->patterns) != NULL)
+ while ((pattern = *patterns++) != NULL) {
+ if (*pattern == '/')
+ xx = fnmatch(pattern, fts->fts_path, bhg->fnflags);
+ else
+ xx = fnmatch(pattern, fts->fts_name, bhg->fnflags);
+ if (xx == 0)
+ break;
+ else
+ xx = Fts_set(ftsp, fts, FTS_SKIP);
+ }
+
+ break;
+ case FTS_DP: /* postorder directory */
+#if 0
+ if (_debug)
+ fprintf(stderr, "FTS_%s\t%*s %s\n", ftsInfoStr(fts->fts_info),
+ indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
+ fts->fts_name);
+#endif
+ break;
+ case FTS_F: /* regular file */
+#if 0
+ if (_debug)
+ fprintf(stderr, "FTS_%s\t%*s %s\n", ftsInfoStr(fts->fts_info),
+ indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
+ fts->fts_name);
+#endif
+ if (fts->fts_level >= 0) {
+ /* Ignore source packages. */
+ if (!strcmp(fts->fts_parent->fts_name, "SRPMS")) {
+ xx = Fts_set(ftsp, fts->fts_parent, FTS_SKIP);
+ break;
+ }
+ }
+
+ /* Ignore all but *.rpm files. */
+ s = fts->fts_name + fts->fts_namelen + 1 - sizeof(".rpm");
+ if (strcmp(s, ".rpm"))
+ break;
+
+ break;
+ case FTS_NS: /* stat(2) failed */
+ case FTS_DNR: /* unreadable directory */
+ case FTS_ERR: /* error; errno is set */
+ if (_debug)
+ fprintf(stderr, "FTS_%s\t%*s %s\n", ftsInfoStr(fts->fts_info),
+ indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
+ fts->fts_name);
+ break;
+ case FTS_DC: /* directory that causes cycles */
+ case FTS_DEFAULT: /* none of the above */
+ case FTS_DOT: /* dot or dot-dot */
+ case FTS_INIT: /* initialized only */
+ case FTS_NSOK: /* no stat(2) requested */
+ case FTS_SL: /* symbolic link */
+ case FTS_SLNONE: /* symbolic link without target */
+ case FTS_W: /* whiteout object */
+ default:
+ if (_debug)
+ fprintf(stderr, "FTS_%s\t%*s %s\n", ftsInfoStr(fts->fts_info),
+ indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
+ fts->fts_name);
+ break;
+ }
+
+ return RPMRC_OK;
+}
+
+/**
+ * Initialize fts and glob structures.
+ * @param ts transaction set
+ * @param argv package names to match
+ */
+static void initGlobs(/*@unused@*/ rpmts ts, const char ** argv)
+{
+ char buf[BUFSIZ];
+ int i;
+
+ buf[0] = '\0';
+ if (argv != NULL && * argv != NULL) {
+ const char * arg;
+ int single = (Glob_pattern_p(argv[0], 0) && argv[1] == NULL);
+ char * t;
+
+ t = buf;
+ if (!single)
+ t = stpcpy(t, "@(");
+ while ((arg = *argv++) != NULL) {
+ t = stpcpy(t, arg);
+ *t++ = '|';
+ }
+ t[-1] = (single ? '\0' : ')');
+ *t = '\0';
+ }
+
+ bhpath = rpmExpand("%{_bhpath}", NULL);
+ bhpathlen = strlen(bhpath);
+
+ ftsSet = xcalloc(2, sizeof(*ftsSet));
+ ftsSet[0] = rpmExpand("%{_bhpath}", NULL);
+
+ nbhglobs = 5;
+ bhglobs = xcalloc(nbhglobs, sizeof(*bhglobs));
+ for (i = 0; i < nbhglobs; i++) {
+ const char * pattern;
+ const char * macro;
+
+ switch (i) {
+ case 0:
+ macro = "%{_bhpath}";
+ break;
+ case 1:
+ macro = "%{_bhcoll}";
+ break;
+ case 2:
+ macro = (buf[0] == '\0' ? "%{_bhN}" : buf);
+ break;
+ case 3:
+ macro = "%{_bhVR}";
+ break;
+ case 4:
+ macro = "%{_bhA}";
+ break;
+ default:
+ macro = NULL;
+ break;
+ }
+ bhglobs[i].patterns = xcalloc(2, sizeof(*bhglobs[i].patterns));
+ if (macro == NULL)
+ continue;
+ pattern = rpmExpand(macro, NULL);
+ if (pattern == NULL || *pattern == '\0') {
+ pattern = _free(pattern);
+ continue;
+ }
+ bhglobs[i].patterns[0] = pattern;
+ bhglobs[i].fnflags = (FNM_PATHNAME | FNM_PERIOD | FNM_EXTMATCH);
+ if (bhglobs[i].patterns[0] != NULL)
+ rpmMessage(RPMMESS_DEBUG, "\t%d \"%s\"\n",
+ i, bhglobs[i].patterns[0]);
+ }
+}
+
+static void freeGlobs(void)
+{
+ int i;
+ for (i = 0; i < nbhglobs; i++) {
+ bhglobs[i].patterns[0] = _free(bhglobs[i].patterns[0]);
+ bhglobs[i].patterns = _free(bhglobs[i].patterns);
+ }
+ bhglobs = _free(bhglobs);
+ ftsSet[0] = _free(ftsSet[0]);
+ ftsSet = _free(ftsSet);
+}
+
+static rpmVSFlags vsflags = 0;
+
+static struct poptOption optionsTable[] = {
+ { "nolegacy", '\0', POPT_BIT_SET, &vsflags, RPMVSF_NEEDPAYLOAD,
+ N_("don't verify header+payload signature"), NULL },
+
+ { "nocache", '\0', POPT_ARG_VAL, &noCache, -1,
+ N_("don't update cache database, only print package paths"), NULL },
+
+ { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliFtsPoptTable, 0,
+ N_("File tree walk options:"),
+ NULL },
+
+ { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
+ N_("Common options for all rpm modes and executables:"),
+ NULL },
+
+ POPT_AUTOALIAS
+ POPT_AUTOHELP
+ POPT_TABLEEND
+};
+
+int
+main(int argc, char *const argv[])
+{
+ rpmts ts = NULL;
+ rpmgi gi = NULL;
+ poptContext optCon;
+ const char * s;
+ int ec = 1;
+ rpmRC rpmrc;
+ int xx;
+
+ optCon = rpmcliInit(argc, argv, optionsTable);
+ if (optCon == NULL)
+ exit(EXIT_FAILURE);
+
+ /* Configure the path to cache database, creating if necessary. */
+ s = rpmExpand("%{?_cache_dbpath}", NULL);
+ if (!(s && *s))
+ rpmrc = RPMRC_FAIL;
+ else
+ rpmrc = rpmMkdirPath(s, "cache_dbpath");
+ if (rpmrc == RPMRC_OK && Access(s, W_OK))
+ rpmrc = RPMRC_FAIL;
+ s = _free(s);
+ if (rpmrc != RPMRC_OK) {
+ fprintf(stderr, _("%s: %%{_cache_dbpath} macro is mis-configured.\n"),
+ __progname);
+ exit(EXIT_FAILURE);
+ }
+
+ ts = rpmtsCreate();
+
+ if (rpmcliQueryFlags & VERIFY_DIGEST)
+ vsflags |= _RPMVSF_NODIGESTS;
+ if (rpmcliQueryFlags & VERIFY_SIGNATURE)
+ vsflags |= _RPMVSF_NOSIGNATURES;
+ if (rpmcliQueryFlags & VERIFY_HDRCHK)
+ vsflags |= RPMVSF_NOHDRCHK;
+ (void) rpmtsSetVSFlags(ts, vsflags);
+
+ { int_32 tid = (int_32) time(NULL);
+ (void) rpmtsSetTid(ts, tid);
+ }
+
+ initGlobs(ts, poptGetArgs(optCon));
+
+ gi = rpmgiNew(ts, RPMDBI_FTSWALK, NULL, 0);
+
+ if (ftsOpts == 0)
+ ftsOpts = (FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOSTAT);
+
+ if (noCache)
+ ftsOpts |= FTS_NOSTAT;
+ else
+ ftsOpts &= ~FTS_NOSTAT;
+
+ xx = rpmgiSetArgs(gi, ftsSet, ftsOpts, giFlags);
+
+ gi->walkPathFilter = cacheWalkPathFilter;
+ gi->stash = cacheStashLatest;
+ while ((rpmrc = rpmgiNext(gi)) == RPMRC_OK)
+ {};
+
+ if (noCache)
+ ec = ftsCachePrint(ts, stdout);
+ else
+ ec = ftsCacheUpdate(ts);
+ if (ec) {
+ fprintf(stderr, _("%s: cache operation failed: ec %d.\n"),
+ __progname, ec);
+ }
+
+ freeItems();
+ freeGlobs();
+
+ gi = rpmgiFree(gi);
+ ts = rpmtsFree(ts);
+ optCon = rpmcliFini(optCon);
+
+ return ec;
+}
@@ .
patch -p0 <<'@@ .'
Index: rpm/tools/rpmcmp.c
============================================================================
$ cvs diff -u -r0 -r2.1 rpmcmp.c
--- /dev/null 2007-08-18 18:44:00 +0200
+++ rpmcmp.c 2007-08-18 18:45:03 +0200
@@ -0,0 +1,89 @@
+#include "system.h"
+#include <rpmio_internal.h>
+#include <rpmlib.h>
+#define _RPMDS_INTERNAL
+#define _RPMEVR_INTERNAL
+#include <rpmds.h>
+#include <argv.h>
+#include <popt.h>
+#include "debug.h"
+
+const char *__progname;
+#define progname __progname
+
+static int pointRpmEVR(ARGV_t av)
+{
+ EVR_t a = memset(alloca(sizeof(*a)), 0, sizeof(*a));
+ EVR_t b = memset(alloca(sizeof(*b)), 0, sizeof(*a));
+ int rc;
+
+ (void) rpmEVRparse(av[0], a);
+ (void) rpmEVRparse(av[2], b);
+
+ rc = rpmEVRcompare(a, b);
+ if (rc < 0)
+ rc = !(av[1][0] == 'l');
+ else if (rc > 0)
+ rc = !(av[1][0] == 'g');
+ else
+ rc = !(av[1][0] == 'e' || av[1][1] == 'e');
+
+ a->str = _free(a->str);
+ b->str = _free(b->str);
+ return rc;
+}
+
+static struct poptOption optionsTable[] = {
+ { "debug", 'd', POPT_ARG_VAL, &_rpmevr_debug, -1, NULL, NULL },
+ POPT_AUTOALIAS
+ POPT_AUTOHELP
+ POPT_TABLEEND
+};
+
+int
+main(int argc, const char *argv[])
+{
+ poptContext optCon;
+ ARGV_t av;
+ int ac;
+ const char * arg;
+ int ec = 0;
+ int rc;
+ int xx;
+
+ if ((progname = strrchr(argv[0], '/')) != NULL)
+ progname++;
+ else
+ progname = argv[0];
+
+ optCon = poptGetContext(argv[0], argc, argv, optionsTable, 0);
+ while ((rc = poptGetNextOpt(optCon)) > 0)
+ ;
+
+ av = poptGetArgs(optCon);
+ ac = argvCount(av);
+
+ if (ac == 0 || !strcmp(*av, "-")) {
+ av = NULL;
+ xx = argvFgets(&av, NULL);
+ ac = argvCount(av);
+ }
+
+ if (av != NULL)
+ while ((arg = *av++) != NULL) {
+ ARGV_t rav = NULL;
+ int rac = 0;
+ if (poptParseArgvString(arg, &rac, &rav) || rac != 3) {
+ fprintf(stderr, _("skipping malformed comparison: \"%s\"\n"), arg);
+ continue;
+ }
+ rc = pointRpmEVR(rav);
+ free(rav);
+ rav = NULL;
+ rac = 0;
+ }
+
+ optCon = poptFreeContext(optCon);
+
+ return ec;
+}
@@ .
patch -p0 <<'@@ .'
Index: rpm/tools/rpmdigest.c
============================================================================
$ cvs diff -u -r0 -r2.1 rpmdigest.c
--- /dev/null 2007-08-18 18:44:00 +0200
+++ rpmdigest.c 2007-08-18 18:45:03 +0200
@@ -0,0 +1,61 @@
+#include "system.h"
+#include <rpmio.h>
+#include <rpmpgp.h>
+#include "debug.h"
+
+static struct poptOption optionsTable[] = {
+ { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmDigestPoptTable, 0,
+ N_("Digest options:"),
+ NULL },
+ POPT_AUTOHELP
+ POPT_TABLEEND
+};
+
+int
+main(int argc, const char *argv[])
+{
+ poptContext optCon;
+ const char ** args;
+ const char * fn;
+ FD_t fd;
+ unsigned char buf[BUFSIZ];
+ ssize_t nb;
+ DIGEST_CTX ctx = NULL;
+ const char * digest = NULL;
+ size_t digestlen = 0;
+ int asAscii = 1;
+ int rc = 0;
+
+ optCon = poptGetContext(argv[0], argc, argv, optionsTable, 0);
+ while ((rc = poptGetNextOpt(optCon)) > 0)
+ ;
+
+ if ((args = poptGetArgs(optCon)) != NULL)
+ while ((fn = *args++) != NULL) {
+
+ fd = Fopen(fn, "r");
+ if (fd == NULL || Ferror(fd)) {
+ fprintf(stderr, _("cannot open %s: %s\n"), fn, Fstrerror(fd));
+ if (fd) Fclose(fd);
+ rc++;
+ continue;
+ }
+
+ ctx = rpmDigestInit(rpmDigestHashAlgo, RPMDIGEST_NONE);
+ while ((nb = Fread(buf, 1, sizeof(buf), fd)) > 0)
+ rpmDigestUpdate(ctx, buf, nb);
+ Fclose(fd);
+ rpmDigestFinal(ctx, (void **)&digest, &digestlen, asAscii);
+
+ if (digest) {
+ fprintf(stdout, "%s %s\n", digest, fn);
+ fflush(stdout);
+ free((void *)digest);
+ digest = NULL;
+ }
+ }
+
+ optCon = poptFreeContext(optCon);
+
+ return rc;
+}
@@ .
Received on Sat Aug 18 18:45:03 2007