summaryrefslogtreecommitdiff
path: root/lib/rpmgi.c
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2004-10-18 22:47:20 +0000
committerjbj <devnull@localhost>2004-10-18 22:47:20 +0000
commitddfad5f8782002bc2679aa82b9e58b58efb1430b (patch)
treeb4832b16bd3dd2c6e85e63f262c26ea0523e0164 /lib/rpmgi.c
parente93a77c9b792b68c63ce7d3d360ab7f43d37feb6 (diff)
downloadlibrpm-tizen-ddfad5f8782002bc2679aa82b9e58b58efb1430b.tar.gz
librpm-tizen-ddfad5f8782002bc2679aa82b9e58b58efb1430b.tar.bz2
librpm-tizen-ddfad5f8782002bc2679aa82b9e58b58efb1430b.zip
Isolate most state changes in rpmgiNext, with lazy open/close.
Refactor some of the mess into subroutines. CVS patchset: 7483 CVS date: 2004/10/18 22:47:20
Diffstat (limited to 'lib/rpmgi.c')
-rw-r--r--lib/rpmgi.c470
1 files changed, 309 insertions, 161 deletions
diff --git a/lib/rpmgi.c b/lib/rpmgi.c
index 1c151d115..5383d0a10 100644
--- a/lib/rpmgi.c
+++ b/lib/rpmgi.c
@@ -8,6 +8,7 @@
#include <rpmgi.h>
#include <rpmdb.h>
+#include <rpmmacro.h> /* XXX rpmExpand */
#include "manifest.h"
#include "debug.h"
@@ -17,8 +18,226 @@
/*@unchecked@*/
int _rpmgi_debug = 0;
+/*@unchecked@*/
+static int indent = 2;
+
/*@unchecked@*/ /*@observer@*/
-static const char * hdlistpath = "/usr/share/comps/i386/hdlist";
+static const char * ftsInfoStrings[] = {
+ "UNKNOWN",
+ "D",
+ "DC",
+ "DEFAULT",
+ "DNR",
+ "DOT",
+ "DP",
+ "ERR",
+ "F",
+ "INIT",
+ "NS",
+ "NSOK",
+ "SL",
+ "SLNONE",
+ "W",
+};
+
+/*@observer@*/
+static const char * ftsInfoStr(int fts_info)
+ /*@*/
+{
+
+ if (!(fts_info >= 1 && fts_info <= 14))
+ fts_info = 0;
+/*@-compmempass@*/
+ return ftsInfoStrings[ fts_info ];
+/*@=compmempass@*/
+}
+
+/**
+ * Open a file after macro expanding path.
+ * @param path file path
+ * @param fmode open mode
+ * @return file handle
+ */
+/*@null@*/
+static FD_t rpmgiOpen(const char * path, const char * fmode)
+ /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
+ /*@modifies rpmGlobalMacroContext, h_errno, internalState @*/
+{
+ const char * fn = rpmExpand(path, NULL);
+ FD_t fd = Fopen(fn, fmode);
+
+ if (fd == NULL || Ferror(fd)) {
+ rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), fn, Fstrerror(fd));
+ if (fd != NULL) (void) Fclose(fd);
+ fd = NULL;
+ }
+ fn = _free(fn);
+
+ return fd;
+}
+
+/**
+ * Load manifest into iterator arg list.
+ * @param gi generalized iterator
+ * @param path file path
+ * @return RPMRC_OK on success
+ */
+static rpmRC rpmgiLoadManifest(rpmgi gi, const char * path)
+ /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
+ /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
+{
+ FD_t fd = rpmgiOpen(path, "r.ufdio");
+ rpmRC rpmrc = RPMRC_FAIL;
+
+ if (fd != NULL) {
+ rpmrc = rpmReadPackageManifest(fd, &gi->argc, &gi->argv);
+ (void) Fclose(fd);
+ }
+ return rpmrc;
+}
+
+/**
+ * Return header from package.
+ * @param gi generalized iterator
+ * @param path file path
+ * @return header (NULL on failure)
+ */
+/*@null@*/
+static Header rpmgiReadHeader(rpmgi gi, const char * path)
+ /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
+ /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
+{
+ FD_t fd = rpmgiOpen(path, "r.ufdio");
+ Header h = NULL;
+
+ if (fd != NULL) {
+ /* XXX what if path needs expansion? */
+ rpmRC rpmrc = rpmReadPackageFile(gi->ts, fd, path, &h);
+
+ (void) Fclose(fd);
+
+ switch (rpmrc) {
+ case RPMRC_NOTFOUND:
+ /* XXX 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;
+ }
+ }
+
+ return h;
+}
+
+/**
+ * Return next header, lazily expanding manifests as found.
+ * @param gi generalized iterator
+ * @return header (NULL on failure)
+ */
+/*@null@*/
+static Header rpmgiLoadReadHeader(rpmgi gi)
+ /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
+ /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
+{
+ Header h;
+ rpmRC rpmrc = RPMRC_OK;
+
+ do {
+ const char * fn;
+
+ 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; /* HACK */
+ rpmrc = rpmgiLoadManifest(gi, fn);
+ if (rpmrc != RPMRC_OK) {
+ gi->argv[gi->i] = fn; /* HACK */
+ break;
+ }
+ fn = _free(fn);
+ } while (1);
+
+ /* XXX check rpmrc */
+
+ return h;
+}
+
+/**
+ * Return next header, lazily walking file tree.
+ * @param gi generalized iterator
+ * @return header (NULL on failure)
+ */
+/*@null@*/
+static Header rpmgiWalkReadHeader(rpmgi gi)
+ /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
+ /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
+{
+ Header h = NULL;
+
+ if (gi->ftsp != NULL)
+ while (h == NULL && (gi->fts = Fts_read(gi->ftsp)) != NULL) {
+ FTSENT * fts = gi->fts;
+
+if (_rpmgi_debug < 0)
+fprintf(stderr, "FTS_%s\t%*s %s\n", ftsInfoStr(fts->fts_info),
+ indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
+ fts->fts_name);
+
+/*@-branchstate@*/
+ switch (fts->fts_info) {
+ case FTS_F:
+ case FTS_SL:
+if (_rpmgi_debug < 0)
+fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->ftsp, gi->i, fts->fts_path);
+ h = rpmgiReadHeader(gi, fts->fts_path);
+ /*@switchbreak@*/ break;
+ default:
+ /*@switchbreak@*/ break;
+ }
+/*@=branchstate@*/
+ }
+
+ return h;
+}
+
+/**
+ * Load globbed arg list into iterator.
+ * @param gi generalized iterator
+ * @param argv arg list to be globbed
+ * @returns RPMRC_OK on success
+ */
+static rpmRC rpmgiGlobArgv(rpmgi gi, ARGV_t argv)
+ /*@globals internalState @*/
+ /*@modifies gi, internalState @*/
+{
+ const char * arg;
+ rpmRC rpmrc = RPMRC_OK;
+
+ if (gi->argv != NULL)
+ gi->argv = argvFree(gi->argv);
+
+ gi->argv = xcalloc(1, sizeof(*gi->argv));
+ gi->argc = 0;
+ if (argv != NULL)
+ while ((arg = *argv++) != NULL) {
+ ARGV_t av = NULL;
+ int ac = 0;
+ int xx;
+
+ xx = rpmGlob(arg, &ac, &av);
+ xx = argvAppend(&gi->argv, av);
+ gi->argc += ac;
+ av = argvFree(av);
+ ac = 0;
+ }
+ return rpmrc;
+}
rpmgi XrpmgiUnlink(rpmgi gi, const char * msg, const char * fn, unsigned ln)
{
@@ -56,6 +275,7 @@ fprintf(stderr, "*** gi %p\t%p[%d]\n", gi, gi->argv, gi->argc);
(void) rpmgiUnlink(gi, NULL);
/*@-usereleased@*/
+#ifdef NOTYET
switch (gi->tag) {
default:
case RPMGI_RPMDB:
@@ -67,9 +287,14 @@ fprintf(stderr, "*** gi %p\t%p[%d]\n", gi, gi->argv, gi->argc);
case RPMGI_FTSWALK:
break;
}
+#endif
gi->queryFormat = _free(gi->queryFormat);
+ gi->hdrPath = _free(gi->hdrPath);
+ gi->h = headerFree(gi->h);
+
gi->argv = argvFree(gi->argv);
+
if (gi->ftsp != NULL) {
int xx;
xx = Fts_close(gi->ftsp);
@@ -100,42 +325,33 @@ rpmgi rpmgiNew(rpmts ts, int tag, void *const keyp, size_t keylen)
gi->ts = rpmtsLink(ts, NULL);
gi->tag = tag;
+ gi->active = 0;
gi->i = -1;
+
+ gi->queryFormat = NULL;
+ gi->hdrPath = NULL;
+ gi->h = NULL;
+ gi->mi = NULL;
gi->fd = NULL;
gi->argv = NULL;
gi->argc = 0;
+ gi->ftsOpts = 0;
+ gi->ftsp = NULL;
+ gi->fts = NULL;
switch (gi->tag) {
default:
case RPMGI_RPMDB:
- gi->mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
-
-if (_rpmgi_debug < 0)
-fprintf(stderr, "*** gi %p\t%p\n", gi, gi->mi);
-
break;
case RPMGI_HDLIST:
- gi->fd = Fopen(hdlistpath, "r.ufdio");
break;
case RPMGI_ARGLIST:
case RPMGI_FTSWALK:
- { ARGV_t pav = keyp;
- const char * arg;
- unsigned flags = keylen;
- int xx;
+ { ARGV_t argv = keyp; /* HACK */
+ unsigned flags = keylen; /* HACK */
+ rpmRC rpmrc;
- gi->argv = xcalloc(1, sizeof(*gi->argv));
- gi->argc = 0;
- if (pav != NULL)
- while ((arg = *pav++) != NULL) {
- ARGV_t av = NULL;
- int ac;
-
- xx = rpmGlob(arg, &ac, &av);
- xx = argvAppend(&gi->argv, av);
- gi->argc += ac;
- av = argvFree(av);
- }
+ rpmrc = rpmgiGlobArgv(gi, argv);
gi->ftsOpts = flags;
if (_rpmgi_debug < 0)
@@ -149,40 +365,6 @@ fprintf(stderr, "*** gi %p\t%p[%d]\n", gi, gi->argv, gi->argc);
return gi;
}
-/*@unchecked@*/
-static int indent = 2;
-
-/*@unchecked@*/ /*@observer@*/
-static const char * ftsInfoStrings[] = {
- "UNKNOWN",
- "D",
- "DC",
- "DEFAULT",
- "DNR",
- "DOT",
- "DP",
- "ERR",
- "F",
- "INIT",
- "NS",
- "NSOK",
- "SL",
- "SLNONE",
- "W",
-};
-
-/*@observer@*/
-static const char * ftsInfoStr(int fts_info)
- /*@*/
-{
-
- if (!(fts_info >= 1 && fts_info <= 14))
- fts_info = 0;
-/*@-compmempass@*/
- return ftsInfoStrings[ fts_info ];
-/*@=compmempass@*/
-}
-
/*@only@*/
static const char * rpmgiPathOrQF(const rpmgi gi, const char * fn,
/*@null@*/ Header * hdrp)
@@ -206,96 +388,56 @@ static const char * rpmgiPathOrQF(const rpmgi gi, const char * fn,
return val;
}
-/*@null@*/
-static rpmRC rpmgiLoadManifest(rpmgi gi, const char * fileURL)
- /*@globals h_errno, internalState @*/
- /*@modifies gi, h_errno, internalState @*/
-{
- 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)
- /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
- /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
-{
- Header h = NULL;
- 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 h;
- }
-
- rpmrc = rpmReadPackageFile(gi->ts, fd, fileURL, &h);
-
- (void) Fclose(fd);
-
- switch (rpmrc) {
- 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;
- }
-
- return h;
-}
-
const char * rpmgiNext(/*@null@*/ rpmgi gi)
{
const char * val = NULL;
const char * fn = NULL;
Header h = NULL;
- rpmRC rpmrc;
if (gi != NULL && ++gi->i >= 0)
switch (gi->tag) {
default:
case RPMGI_RPMDB:
- h = rpmdbNextIterator(gi->mi);
+ if (!gi->active) {
+ gi->mi = rpmtsInitIterator(gi->ts, RPMDBI_PACKAGES, NULL, 0);
+if (_rpmgi_debug < 0)
+fprintf(stderr, "*** gi %p\t%p\n", gi, gi->mi);
+ gi->active = 1;
+ }
+ if (gi->mi != NULL) /* XXX unnecessary */
+ h = rpmdbNextIterator(gi->mi);
/*@-branchstate@*/
if (h != NULL) {
val = rpmgiPathOrQF(gi, "rpmdb", &h);
} else {
gi->mi = rpmdbFreeIterator(gi->mi);
gi->i = -1;
+ gi->active = 0;
}
/*@=branchstate@*/
break;
case RPMGI_HDLIST:
- h = headerRead(gi->fd, HEADER_MAGIC_YES);
+ if (!gi->active) {
+ const char * hdrPath = gi->hdrPath;
+
/*@-branchstate@*/
+ if (hdrPath == NULL)
+ hdrPath = "/usr/share/comps/%{_arch}/hdlist";
+/*@=branchstate@*/
+ gi->fd = rpmgiOpen(hdrPath, "r.ufdio");
+ gi->active = 1;
+ }
+ if (gi->fd != NULL)
+ h = headerRead(gi->fd, HEADER_MAGIC_YES);
+/*@-branchstate@*/
+
if (h != NULL) {
val = rpmgiPathOrQF(gi, "hdlist", &h);
} else {
- (void) Fclose(gi->fd);
+ if (gi->fd != NULL) (void) Fclose(gi->fd);
gi->fd = NULL;
gi->i = -1;
+ gi->active = 0;
}
/*@=branchstate@*/
break;
@@ -305,67 +447,45 @@ const char * rpmgiNext(/*@null@*/ rpmgi gi)
if (_rpmgi_debug < 0)
fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->argv, gi->i, gi->argv[gi->i]);
/* Read next header, lazily expanding manifests as found. */
- do {
- fn = gi->argv[gi->i];
- h = rpmgiReadHeader(gi, fn);
- if (h != NULL)
- /*@loopbreak@*/ break;
- /* Not a header, so try for a manifest. */
- gi->argv[gi->i] = NULL;
- rpmrc = rpmgiLoadManifest(gi, fn);
- if (rpmrc != RPMRC_OK) {
- gi->argv[gi->i] = fn;
- /*@loopbreak@*/ break;
- }
- fn = _free(fn);
- } while (1);
- /* XXX check rpmrc */
+ h = rpmgiLoadReadHeader(gi);
+
/*@-compdef@*/ /* XXX WTF? gi->argv undefined */
val = rpmgiPathOrQF(gi, fn, &h);
/*@=compdef@*/
h = headerFree(h);
- } else
+ } else {
gi->i = -1;
+ gi->active = 0;
+ }
/*@=branchstate@*/
break;
case RPMGI_FTSWALK:
- if (gi->argv == NULL)
+ if (gi->argv == NULL) /* HACK */
break;
- if (gi->ftsp == NULL && gi->i == 0) {
+ if (!gi->active) {
gi->ftsp = Fts_open((char *const *)gi->argv, gi->ftsOpts, NULL);
/* XXX NULL with open(2)/malloc(3) errno set */
+ gi->active = 1;
}
if (gi->ftsp != NULL)
- while (val == NULL && (gi->fts = Fts_read(gi->ftsp)) != NULL) {
- FTSENT * fts = gi->fts;
-
-if (_rpmgi_debug < 0)
-fprintf(stderr, "FTS_%s\t%*s %s\n", ftsInfoStr(fts->fts_info),
- indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
- fts->fts_name);
+ h = rpmgiWalkReadHeader(gi);
/*@-branchstate@*/
- switch (fts->fts_info) {
- case FTS_F:
- case FTS_SL:
-if (_rpmgi_debug < 0)
-fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->ftsp, gi->i, fts->fts_path);
- fn = fts->fts_path;
- h = rpmgiReadHeader(gi, fn);
- val = rpmgiPathOrQF(gi, fn, &h);
- h = headerFree(h);
- /*@switchbreak@*/ break;
- default:
- /*@switchbreak@*/ break;
- }
-/*@=branchstate@*/
+ if (h != NULL) {
+ if (gi->fts != NULL)
+ fn = gi->fts->fts_path;
+ val = rpmgiPathOrQF(gi, fn, &h);
+ h = headerFree(h);
}
+/*@=branchstate@*/
+
if (gi->fts == NULL && gi->ftsp != NULL) {
int xx;
xx = Fts_close(gi->ftsp);
gi->ftsp = NULL;
gi->i = -1;
+ gi->active = 0;
}
break;
}
@@ -373,16 +493,44 @@ fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->ftsp, gi->i, fts->fts_path);
return val;
}
+const char * rpmgiQueryFormat(rpmgi gi)
+{
+ const char * queryFormat = NULL;
+
+ if (gi != NULL)
+ queryFormat = gi->queryFormat;
+ return queryFormat;
+}
+
int rpmgiSetQueryFormat(rpmgi gi, const char * queryFormat)
{
int rc = 0;
-
+
if (gi != NULL) {
gi->queryFormat = _free(gi->queryFormat);
gi->queryFormat = (queryFormat != NULL ? xstrdup(queryFormat) : NULL);
}
return rc;
+}
+
+const char * rpmgiHdrPath(rpmgi gi)
+{
+ const char * hdrPath = NULL;
+
+ if (gi != NULL)
+ hdrPath = gi->hdrPath;
+ return hdrPath;
+}
+
+int rpmgiSetHdrPath(rpmgi gi, const char * hdrPath)
+{
+ int rc = 0;
+ if (gi != NULL) {
+ gi->hdrPath = _free(gi->hdrPath);
+ gi->hdrPath = (hdrPath != NULL ? xstrdup(hdrPath) : NULL);
+ }
+ return rc;
}
/*@=modfilesys@*/