-I$(top_srcdir)/popt \
@INCPATH@
-EXTRA_DIST = getdate.y
+EXTRA_DIST = getdate.y tgi.c rpmgi.c rpmgi.h
+
+EXTRA_PROGRAMS = tgi
pkgincdir = $(pkgincludedir)
pkginc_HEADERS = \
misc.h rpmcli.h rpmlib.h \
- rpmal.h rpmds.h rpmfi.h rpmps.h rpmsx.h rpmte.h rpmts.h stringbuf.h
+ rpmal.h rpmds.h rpmfi.h rpmps.h rpmsx.h rpmte.h rpmts.h \
+ stringbuf.h
noinst_HEADERS = \
cpio.h fsm.h manifest.h psm.h rpmlead.h signature.h rpmlock.h
trhn: trhn.o librpm.la
$(LINK) @LDFLAGS_STATIC@ $(CFLAGS) $(DEFS) $(INCLUDES) -o $@ $< $(mylibs)
+
+tgi_SOURCES = tgi.c rpmgi.c
+tgi_LDADD = librpm.la
--- /dev/null
+/*@-modfilesys@*/
+/** \ingroup rpmio
+ * \file rpmio/rpmio.c
+ */
+#include "system.h"
+
+#define _RPMGI_INTERNAL
+#include <rpmgi.h>
+
+#include <rpmdb.h>
+
+#include "debug.h"
+
+/*@unchecked@*/
+int _rpmgi_debug = 0;
+
+rpmgi XrpmgiUnlink(rpmgi gi, const char * msg, const char * fn, unsigned ln)
+{
+ if (gi == NULL) return NULL;
+
+if (_rpmgi_debug && msg != NULL)
+fprintf(stderr, "--> gi %p -- %d %s at %s:%u\n", gi, gi->nrefs, msg, fn, ln);
+
+ gi->nrefs--;
+ return NULL;
+}
+
+rpmgi XrpmgiLink(rpmgi gi, const char * msg, const char * fn, unsigned ln)
+{
+ if (gi == NULL) return NULL;
+ gi->nrefs++;
+
+if (_rpmgi_debug && msg != NULL)
+fprintf(stderr, "--> gi %p ++ %d %s at %s:%u\n", gi, gi->nrefs, msg, fn, ln);
+
+ /*@-refcounttrans@*/ return gi; /*@=refcounttrans@*/
+}
+
+rpmgi rpmgiFree(rpmgi gi)
+{
+ if (gi == NULL)
+ return NULL;
+
+ if (gi->nrefs > 1)
+ return rpmgiUnlink(gi, NULL);
+
+if (_rpmgi_debug < 0)
+fprintf(stderr, "*** gi %p\t%p[%d]\n", gi, gi->argv, gi->argc);
+
+ (void) rpmgiUnlink(gi, NULL);
+
+ switch (gi->tag) {
+ default:
+ case RPMGI_RPMDB:
+ break;
+ case RPMGI_HDLIST:
+ break;
+ case RPMGI_ARGLIST:
+ break;
+ case RPMGI_FTSWALK:
+ break;
+ }
+
+ if (gi->ftsp != NULL) {
+ int xx;
+ xx = Fts_close(gi->ftsp);
+ gi->ftsp = NULL;
+ gi->fts = NULL;
+ }
+ gi->mi = rpmdbFreeIterator(gi->mi);
+ gi->ts = rpmtsFree(gi->ts);
+
+ memset(gi, 0, sizeof(*gi)); /* XXX trash and burn */
+ gi = _free(gi);
+ return NULL;
+}
+
+rpmgi rpmgiNew(rpmts ts, int tag, const void * keyp, size_t keylen)
+{
+ rpmgi gi = xcalloc(1, sizeof(*gi));
+
+ if (gi == NULL)
+ return NULL;
+
+ gi->ts = rpmtsLink(ts, NULL);
+ gi->tag = tag;
+ gi->i = -1;
+
+ 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:
+ break;
+ case RPMGI_ARGLIST:
+ case RPMGI_FTSWALK:
+ { char *const * argv = keyp;
+ unsigned flags = keylen;
+
+ gi->argv = argv;
+ gi->argc = 0;
+ if (argv != NULL)
+ while (*argv++ != NULL)
+ gi->argc++;
+ gi->ftsOpts = flags;
+
+if (_rpmgi_debug < 0)
+fprintf(stderr, "*** gi %p\t%p[%d]\n", gi, gi->argv, gi->argc);
+
+ } break;
+ }
+
+ gi = rpmgiLink(gi, NULL);
+
+ return gi;
+}
+
+static int indent = 2;
+
+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 ];
+}
+
+const char * rpmgiNext(/*@null@*/ rpmgi gi)
+ /*@modifies gi @*/
+{
+ const char * val = NULL;
+ Header h = NULL;
+
+ if (gi != NULL && ++gi->i >= 0)
+ switch (gi->tag) {
+ default:
+ case RPMGI_RPMDB:
+ h = rpmdbNextIterator(gi->mi);
+ if (h != NULL) {
+ const char * fmt = "%{NAME}-%{VERSION}-%{RELEASE}";
+ val = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, NULL);
+ } else {
+ gi->mi = rpmdbFreeIterator(gi->mi);
+ gi->i = -1;
+ }
+ break;
+ case RPMGI_HDLIST:
+ break;
+ case RPMGI_ARGLIST:
+ 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]);
+ val = xstrdup(gi->argv[gi->i]);
+ } else
+ gi->i = -1;
+ break;
+ case RPMGI_FTSWALK:
+ if (gi->ftsp == NULL && gi->i == 0)
+ gi->ftsp = Fts_open(gi->argv, gi->ftsOpts, 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);
+
+ 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);
+ val = xstrdup(fts->fts_path);
+ break;
+ default:
+ break;
+ }
+ }
+ if (gi->fts == NULL && gi->ftsp != NULL) {
+ int xx;
+ xx = Fts_close(gi->ftsp);
+ gi->ftsp = NULL;
+ gi->i = -1;
+ }
+ break;
+ }
+
+ return val;
+}
+/*@=modfilesys@*/
--- /dev/null
+#ifndef H_RPMGI
+#define H_RPMGI
+
+/** \ingroup rpmio
+ * \file rpmio/rpmgi.h
+ */
+
+#include <rpmlib.h>
+#include <rpmts.h>
+#include <fts.h>
+#include <argv.h>
+
+/**
+ */
+/*@-exportlocal@*/
+/*@unchecked@*/
+extern int _rpmgi_debug;
+/*@=exportlocal@*/
+
+/**
+ */
+typedef /*@abstract@*/ struct rpmgi_s * rpmgi;
+
+/**
+ */
+typedef enum rpmgiTag_e {
+ RPMGI_RPMDB = RPMDBI_PACKAGES,
+ RPMGI_HDLIST = 6, /* XXX next after RPMDBI_AVAILABLE */
+ RPMGI_ARGLIST = 7,
+ RPMGI_FTSWALK = 8
+} rpmgiTag;
+
+#if defined(_RPMGI_INTERNAL)
+/** \ingroup rpmio
+ */
+struct rpmgi_s {
+ rpmts ts;
+ int tag;
+ int i;
+
+ rpmdbMatchIterator mi;
+
+ char *const * argv;
+ int argc;
+ int ftsOpts;
+ FTS * ftsp;
+ FTSENT * fts;
+
+/*@refs@*/
+ int nrefs;
+};
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Unreference a generalized iterator instance.
+ * @param gi generalized iterator
+ * @param msg
+ * @return NULL always
+ */
+/*@unused@*/ /*@null@*/
+rpmgi rpmgiUnlink (/*@killref@*/ /*@only@*/ /*@null@*/ rpmgi gi,
+ /*@null@*/ const char * msg)
+ /*@modifies gi @*/;
+
+/** @todo Remove debugging entry from the ABI. */
+/*@-exportlocal@*/
+/*@null@*/
+rpmgi XrpmgiUnlink (/*@killref@*/ /*@only@*/ /*@null@*/ rpmgi gi,
+ /*@null@*/ const char * msg, const char * fn, unsigned ln)
+ /*@modifies gi @*/;
+/*@=exportlocal@*/
+#define rpmgiUnlink(_gi, _msg) XrpmgiUnlink(_gi, _msg, __FILE__, __LINE__)
+
+/**
+ * Reference a generalized iterator instance.
+ * @param gi generalized iterator
+ * @param msg
+ * @return new generalized iterator reference
+ */
+/*@unused@*/ /*@newref@*/ /*@null@*/
+rpmgi rpmgiLink (/*@null@*/ rpmgi gi, /*@null@*/ const char * msg)
+ /*@modifies gi @*/;
+
+/** @todo Remove debugging entry from the ABI. */
+/*@newref@*/ /*@null@*/
+rpmgi XrpmgiLink (/*@null@*/ rpmgi gi, /*@null@*/ const char * msg,
+ const char * fn, unsigned ln)
+ /*@modifies gi @*/;
+#define rpmgiLink(_gi, _msg) XrpmgiLink(_gi, _msg, __FILE__, __LINE__)
+
+/** Destroy a generalized iterator.
+ * @param gi generalized iterator
+ * @return NULL always
+ */
+/*@only@*/
+rpmgi rpmgiFree(/*@killref@*/ /*@only@*/ /*@null@*/ rpmgi gi)
+ /*@modifies gi @*/;
+
+/** Create a generalized iterator.
+ * @param argv iterator argv array
+ * @param flags iterator flags
+ * @return new general iterator
+ */
+/*@only@*/
+rpmgi rpmgiNew(rpmts ts, int tag, const void * keyp, size_t keylen)
+ /*@*/;
+
+const char * rpmgiNext(/*@null@*/ rpmgi gi)
+ /*@modifies gi @*/;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_RPMGI */
--- /dev/null
+#include "system.h"
+
+#include <rpmio_internal.h>
+#define _RPMGI_INTERNAL
+#include <rpmgi.h>
+#include <rpmcli.h>
+
+#include <rpmmacro.h>
+#include <rpmmessages.h>
+#include <popt.h>
+
+#include "debug.h"
+
+static int gitag = RPMGI_FTSWALK;
+static int ftsOpts = 0;
+
+static struct poptOption optionsTable[] = {
+ { "rpmgidebug", 'd', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmgi_debug, -1,
+ N_("debug generalized iterator"), NULL},
+
+ { "rpmdb", '\0', POPT_ARG_VAL, &gitag, RPMGI_RPMDB,
+ N_("iterate rpmdb"), NULL },
+ { "hdlist", '\0', POPT_ARG_VAL, &gitag, RPMGI_HDLIST,
+ N_("iterate hdlist"), NULL },
+ { "arglist", '\0', POPT_ARG_VAL, &gitag, RPMGI_ARGLIST,
+ N_("iterate arglist"), NULL },
+ { "ftswalk", '\0', POPT_ARG_VAL, &gitag, RPMGI_FTSWALK,
+ N_("iterate fts(3) walk"), NULL },
+
+ { "comfollow", '\0', POPT_BIT_SET, &ftsOpts, FTS_COMFOLLOW,
+ N_("follow command line symlinks"), NULL },
+ { "logical", '\0', POPT_BIT_SET, &ftsOpts, FTS_LOGICAL,
+ N_("logical walk"), NULL },
+ { "nochdir", '\0', POPT_BIT_SET, &ftsOpts, FTS_NOCHDIR,
+ N_("don't change directories"), NULL },
+ { "nostat", '\0', POPT_BIT_SET, &ftsOpts, FTS_NOSTAT,
+ N_("don't get stat info"), NULL },
+ { "physical", '\0', POPT_BIT_SET, &ftsOpts, FTS_PHYSICAL,
+ N_("physical walk"), NULL },
+ { "seedot", '\0', POPT_BIT_SET, &ftsOpts, FTS_SEEDOT,
+ N_("return dot and dot-dot"), NULL },
+ { "xdev", '\0', POPT_BIT_SET, &ftsOpts, FTS_XDEV,
+ N_("don't cross devices"), NULL },
+ { "whiteout", '\0', POPT_BIT_SET, &ftsOpts, FTS_WHITEOUT,
+ N_("return whiteout information"), NULL },
+
+#ifdef DYING
+ { "ftpdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_ftp_debug, -1,
+ N_("debug protocol data stream"), NULL},
+ { "rpmiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmio_debug, -1,
+ N_("debug rpmio I/O"), NULL},
+ { "urldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_url_debug, -1,
+ N_("debug URL cache handling"), NULL},
+ { "verbose", 'v', 0, 0, 'v', NULL, NULL },
+#endif
+
+ { 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[])
+{
+ poptContext optCon;
+ rpmts ts = NULL;
+ rpmgi gi = NULL;
+ const char ** av;
+ const char * arg;
+ int ac;
+ int rc = 0;
+
+ optCon = rpmcliInit(argc, argv, optionsTable);
+ if (optCon == NULL)
+ exit(EXIT_FAILURE);
+
+ if (ftsOpts == 0)
+ ftsOpts = (FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOSTAT);
+
+ ts = rpmtsCreate();
+ av = poptGetArgs(optCon);
+ gi = rpmgiNew(ts, gitag, av, ftsOpts);
+
+ ac = 0;
+ while ((arg = rpmgiNext(gi)) != NULL) {
+ fprintf(stderr, "%5d %s\n", ac, arg);
+ arg = _free(arg);
+ ac++;
+ }
+
+ gi = rpmgiFree(gi);
+ ts = rpmtsFree(ts);
+ optCon = rpmcliFini(optCon);
+
+ return rc;
+}