diff options
-rw-r--r-- | lib/rpmgi.c | 58 | ||||
-rw-r--r-- | lib/rpmgi.h | 4 | ||||
-rw-r--r-- | lib/tgi.c | 19 |
3 files changed, 67 insertions, 14 deletions
diff --git a/lib/rpmgi.c b/lib/rpmgi.c index f546b7105..341dc804c 100644 --- a/lib/rpmgi.c +++ b/lib/rpmgi.c @@ -8,6 +8,7 @@ #include <rpmgi.h> #include <rpmdb.h> +#include "manifest.h" #include "debug.h" @@ -64,6 +65,7 @@ fprintf(stderr, "*** gi %p\t%p[%d]\n", gi, gi->argv, gi->argc); } gi->queryFormat = _free(gi->queryFormat); + gi->argv = argvFree(gi->argv); if (gi->ftsp != NULL) { int xx; xx = Fts_close(gi->ftsp); @@ -82,7 +84,7 @@ fprintf(stderr, "*** gi %p\t%p[%d]\n", gi, gi->argv, gi->argc); return NULL; } -rpmgi rpmgiNew(rpmts ts, int tag, const void * keyp, size_t keylen) +rpmgi rpmgiNew(rpmts ts, int tag, void *const keyp, size_t keylen) { rpmgi gi = xcalloc(1, sizeof(*gi)); @@ -107,7 +109,7 @@ fprintf(stderr, "*** gi %p\t%p\n", gi, gi->mi); break; case RPMGI_ARGLIST: case RPMGI_FTSWALK: - { char *const * argv = keyp; + { ARGV_t argv = keyp; unsigned flags = keylen; gi->argv = argv; @@ -178,6 +180,28 @@ static const char * rpmgiPathOrQF(rpmgi gi, const char * fn, } /*@null@*/ +static rpmRC rpmgiReadManifest(rpmgi gi, const char * fileURL) + /*@*/ +{ + rpmRC rpmrc; + FD_t fd; + + fd = Fopen(fileURL, "r.ufdio"); + if (fd == NULL || Ferror(fd)) { + rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), fileURL, + Fstrerror(fd)); + if (fd != NULL) (void) Fclose(fd); + return RPMRC_FAIL; + } + + rpmrc = rpmReadPackageManifest(fd, &gi->argc, &gi->argv); + + (void) Fclose(fd); + + return rpmrc; +} + +/*@null@*/ static Header rpmgiReadHeader(rpmgi gi, const char * fileURL) /*@*/ { @@ -198,17 +222,16 @@ static Header rpmgiReadHeader(rpmgi gi, const char * fileURL) (void) Fclose(fd); switch (rpmrc) { - default: + case RPMRC_NOTFOUND: + /* XXX Try to read a package manifest. Restart ftswalk on success. */ case RPMRC_FAIL: + default: h = headerFree(h); break; case RPMRC_NOTTRUSTED: case RPMRC_NOKEY: case RPMRC_OK: break; - case RPMRC_NOTFOUND: - /* Try to read a package manifest. Restart ftswalk on success. */ - break; } return h; @@ -218,8 +241,9 @@ const char * rpmgiNext(/*@null@*/ rpmgi gi) /*@modifies gi @*/ { const char * val = NULL; - const char * fn; + const char * fn = NULL; Header h = NULL; + rpmRC rpmrc; if (gi != NULL && ++gi->i >= 0) switch (gi->tag) { @@ -247,8 +271,22 @@ const char * rpmgiNext(/*@null@*/ rpmgi gi) if (gi->argv != NULL && gi->argv[gi->i] != NULL) { if (_rpmgi_debug < 0) fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->argv, gi->i, gi->argv[gi->i]); - fn = gi->argv[gi->i]; - h = rpmgiReadHeader(gi, fn); + /* Read next header, lazily expanding manifests as found. */ + do { + fn = gi->argv[gi->i]; + h = rpmgiReadHeader(gi, fn); + if (h != NULL) + break; + /* Not a header, so try for a manifest. */ + gi->argv[gi->i] = NULL; + rpmrc = rpmgiReadManifest(gi, fn); + if (rpmrc != RPMRC_OK) { + gi->argv[gi->i] = fn; + break; + } + fn = _free(fn); + } while (1); + /* XXX check rpmrc */ val = rpmgiPathOrQF(gi, fn, &h); h = headerFree(h); } else @@ -258,7 +296,7 @@ fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->argv, gi->i, gi->argv[gi->i]) if (gi->argv == NULL) break; if (gi->ftsp == NULL && gi->i == 0) { - gi->ftsp = Fts_open(gi->argv, gi->ftsOpts, NULL); + gi->ftsp = Fts_open((char *const *)gi->argv, gi->ftsOpts, NULL); /* XXX NULL with open(2)/malloc(3) errno set */ } diff --git a/lib/rpmgi.h b/lib/rpmgi.h index 269c29f74..53a9f3f7b 100644 --- a/lib/rpmgi.h +++ b/lib/rpmgi.h @@ -49,7 +49,7 @@ struct rpmgi_s { const char * queryFormat; /*@dependent@*/ - char *const * argv; + ARGV_t argv; int argc; int ftsOpts; /*@dependent@*/ @@ -117,7 +117,7 @@ rpmgi rpmgiFree(/*@killref@*/ /*@only@*/ /*@null@*/ rpmgi gi) * @return new general iterator */ /*@only@*/ -rpmgi rpmgiNew(rpmts ts, int tag, const void * keyp, size_t keylen) +rpmgi rpmgiNew(rpmts ts, int tag, /*@only@*/ void *const keyp, size_t keylen) /*@*/; const char * rpmgiNext(/*@null@*/ rpmgi gi) @@ -67,10 +67,12 @@ main(int argc, char *const argv[]) rpmts ts = NULL; rpmVSFlags vsflags; rpmgi gi = NULL; - const char ** av; + const char ** pav; const char * arg; + ARGV_t av; int ac; int rc = 0; + int xx; optCon = rpmcliInit(argc, argv, optionsTable); if (optCon == NULL) @@ -93,7 +95,20 @@ main(int argc, char *const argv[]) (void) rpmtsSetTid(ts, tid); } - av = poptGetArgs(optCon); + pav = poptGetArgs(optCon); + + /* Glob all args and concatenate. */ + av = xcalloc(1, sizeof(*av)); + if (pav != NULL) + while ((arg = *pav++) != NULL) { + ARGV_t aav; + int aac; + aav = NULL; + xx = rpmGlob(arg, &aac, &aav); + xx = argvAppend(&av, aav); + aav = argvFree(aav); + } + gi = rpmgiNew(ts, gitag, av, ftsOpts); (void) rpmgiSetQueryFormat(gi, queryFormat); |