7 #define _RPMGI_INTERNAL
18 static const char * hdlistpath = "/usr/share/comps/i386/hdlist";
20 rpmgi XrpmgiUnlink(rpmgi gi, const char * msg, const char * fn, unsigned ln)
22 if (gi == NULL) return NULL;
24 if (_rpmgi_debug && msg != NULL)
25 fprintf(stderr, "--> gi %p -- %d %s at %s:%u\n", gi, gi->nrefs, msg, fn, ln);
31 rpmgi XrpmgiLink(rpmgi gi, const char * msg, const char * fn, unsigned ln)
33 if (gi == NULL) return NULL;
36 if (_rpmgi_debug && msg != NULL)
37 fprintf(stderr, "--> gi %p ++ %d %s at %s:%u\n", gi, gi->nrefs, msg, fn, ln);
39 /*@-refcounttrans@*/ return gi; /*@=refcounttrans@*/
42 rpmgi rpmgiFree(rpmgi gi)
48 return rpmgiUnlink(gi, NULL);
51 fprintf(stderr, "*** gi %p\t%p[%d]\n", gi, gi->argv, gi->argc);
53 (void) rpmgiUnlink(gi, NULL);
67 gi->queryFormat = _free(gi->queryFormat);
68 gi->argv = argvFree(gi->argv);
69 if (gi->ftsp != NULL) {
71 xx = Fts_close(gi->ftsp);
76 (void) Fclose(gi->fd);
79 gi->mi = rpmdbFreeIterator(gi->mi);
80 gi->ts = rpmtsFree(gi->ts);
82 memset(gi, 0, sizeof(*gi)); /* XXX trash and burn */
87 rpmgi rpmgiNew(rpmts ts, int tag, void *const keyp, size_t keylen)
89 rpmgi gi = xcalloc(1, sizeof(*gi));
94 gi->ts = rpmtsLink(ts, NULL);
101 gi->mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
103 if (_rpmgi_debug < 0)
104 fprintf(stderr, "*** gi %p\t%p\n", gi, gi->mi);
108 gi->fd = Fopen(hdlistpath, "r.ufdio");
114 unsigned flags = keylen;
117 gi->argv = xcalloc(1, sizeof(*gi->argv));
120 while ((arg = *pav++) != NULL) {
124 xx = rpmGlob(arg, &ac, &av);
125 xx = argvAppend(&gi->argv, av);
131 if (_rpmgi_debug < 0)
132 fprintf(stderr, "*** gi %p\t%p[%d]\n", gi, gi->argv, gi->argc);
137 gi = rpmgiLink(gi, NULL);
142 static int indent = 2;
144 static const char * ftsInfoStrings[] = {
162 static const char * ftsInfoStr(int fts_info) {
163 if (!(fts_info >= 1 && fts_info <= 14))
165 return ftsInfoStrings[ fts_info ];
169 static const char * rpmgiPathOrQF(rpmgi gi, const char * fn,
170 /*@null@*/ Header * hdrp)
171 /*@modifies gi, *hdrp @*/
173 const char * fmt = ((gi->queryFormat != NULL)
174 ? gi->queryFormat : "%{name}-%{version}-%{release}");
175 const char * val = NULL;
178 if (hdrp != NULL && *hdrp != NULL)
179 h = headerLink(*hdrp);
182 val = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, NULL);
192 static rpmRC rpmgiReadManifest(rpmgi gi, const char * fileURL)
198 fd = Fopen(fileURL, "r.ufdio");
199 if (fd == NULL || Ferror(fd)) {
200 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), fileURL,
202 if (fd != NULL) (void) Fclose(fd);
206 rpmrc = rpmReadPackageManifest(fd, &gi->argc, &gi->argv);
214 static Header rpmgiReadHeader(rpmgi gi, const char * fileURL)
221 fd = Fopen(fileURL, "r.ufdio");
222 if (fd == NULL || Ferror(fd)) {
223 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), fileURL,
225 if (fd != NULL) (void) Fclose(fd);
229 rpmrc = rpmReadPackageFile(gi->ts, fd, fileURL, &h);
235 /* XXX Try to read a package manifest. Restart ftswalk on success. */
240 case RPMRC_NOTTRUSTED:
249 const char * rpmgiNext(/*@null@*/ rpmgi gi)
252 const char * val = NULL;
253 const char * fn = NULL;
257 if (gi != NULL && ++gi->i >= 0)
261 h = rpmdbNextIterator(gi->mi);
263 val = rpmgiPathOrQF(gi, "rpmdb", &h);
265 gi->mi = rpmdbFreeIterator(gi->mi);
270 h = headerRead(gi->fd, HEADER_MAGIC_YES);
272 val = rpmgiPathOrQF(gi, "hdlist", &h);
274 (void) Fclose(gi->fd);
280 if (gi->argv != NULL && gi->argv[gi->i] != NULL) {
281 if (_rpmgi_debug < 0)
282 fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->argv, gi->i, gi->argv[gi->i]);
283 /* Read next header, lazily expanding manifests as found. */
285 fn = gi->argv[gi->i];
286 h = rpmgiReadHeader(gi, fn);
289 /* Not a header, so try for a manifest. */
290 gi->argv[gi->i] = NULL;
291 rpmrc = rpmgiReadManifest(gi, fn);
292 if (rpmrc != RPMRC_OK) {
293 gi->argv[gi->i] = fn;
298 /* XXX check rpmrc */
299 val = rpmgiPathOrQF(gi, fn, &h);
305 if (gi->argv == NULL)
307 if (gi->ftsp == NULL && gi->i == 0) {
308 gi->ftsp = Fts_open((char *const *)gi->argv, gi->ftsOpts, NULL);
309 /* XXX NULL with open(2)/malloc(3) errno set */
312 if (gi->ftsp != NULL)
313 while (val == NULL && (gi->fts = Fts_read(gi->ftsp)) != NULL) {
314 FTSENT * fts = gi->fts;
316 if (_rpmgi_debug < 0)
317 fprintf(stderr, "FTS_%s\t%*s %s\n", ftsInfoStr(fts->fts_info),
318 indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
321 switch (fts->fts_info) {
324 if (_rpmgi_debug < 0)
325 fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->ftsp, gi->i, fts->fts_path);
327 h = rpmgiReadHeader(gi, fn);
328 val = rpmgiPathOrQF(gi, fn, &h);
335 if (gi->fts == NULL && gi->ftsp != NULL) {
337 xx = Fts_close(gi->ftsp);
347 int rpmgiSetQueryFormat(rpmgi gi, const char * queryFormat)
352 gi->queryFormat = _free(gi->queryFormat);
353 gi->queryFormat = (queryFormat != NULL ? xstrdup(queryFormat) : NULL);