commit:     c9e89dfa7cc3ae22bc3c731a3d617e4912bd831a
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Mon Dec 30 17:21:21 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Mon Dec 30 17:21:21 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=c9e89dfa

libq/tree: introduce a wrapper for retrieving ebuild metadata

To further hide the difference between trees, add a wrapper around
tree_get_meta, which deals with the underlying storage format.  This is
most notably useful when dealing with vdb-based and binpkgs because they
have a specific or more expensive way of retrieval.  This can now
properly be hidden from the q applets.

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 libq/tree.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++------------
 libq/tree.h |  55 +++++++++++---------
 qdepends.c  |  36 +++++--------
 qkeyword.c  |   6 +--
 qlist.c     |  71 +++-----------------------
 qsearch.c   |  16 ++----
 quse.c      |  71 +++++++++-----------------
 7 files changed, 213 insertions(+), 208 deletions(-)

diff --git a/libq/tree.c b/libq/tree.c
index d9eec76..bac9d00 100644
--- a/libq/tree.c
+++ b/libq/tree.c
@@ -326,6 +326,7 @@ tree_open_pkg(tree_cat_ctx *cat_ctx, const char *name)
        pkg_ctx->fd = -1;
        pkg_ctx->cat_ctx = cat_ctx;
        pkg_ctx->atom = NULL;
+       pkg_ctx->meta = NULL;
        return pkg_ctx;
 }
 
@@ -418,8 +419,7 @@ tree_next_pkg(tree_cat_ctx *cat_ctx)
                                tree_ctx *pkgdir = ctx->ebuilddir_ctx;
 
                                if (pkgdir == NULL)
-                                       pkgdir = ctx->ebuilddir_ctx = 
xmalloc(sizeof(tree_ctx));
-                               memset(ctx->ebuilddir_ctx, '\0', 
sizeof(*ctx->ebuilddir_ctx));
+                                       pkgdir = ctx->ebuilddir_ctx = 
xzalloc(sizeof(tree_ctx));
 
                                ctx->ebuilddir_pkg_ctx = 
tree_next_pkg_int(cat_ctx);
                                if (ctx->ebuilddir_pkg_ctx == NULL)
@@ -554,13 +554,13 @@ tree_read_file_pms(tree_pkg_ctx *pkg_ctx)
        if ((off_t)fread(ptr, 1, s.st_size, f) != s.st_size)
                goto err;
 
-       ret->DEPEND = ptr;
+       ret->Q_DEPEND = ptr;
 #define next_line(curr, next) \
-       if ((ptr = strchr(ret->curr, '\n')) == NULL) { \
+       if ((ptr = strchr(ret->Q_##curr, '\n')) == NULL) { \
                warn("Invalid cache file for '%s'", buf); \
                goto err; \
        } \
-       ret->next = ptr+1; \
+       ret->Q_##next = ptr+1; \
        *ptr = '\0';
        next_line(DEPEND, RDEPEND)
        next_line(RDEPEND, SLOT)
@@ -630,7 +630,7 @@ tree_read_file_md5(tree_pkg_ctx *pkg_ctx)
         * */
 #define assign_var_cmp(keyname, cmpkey) \
        if (strncmp(keyptr, cmpkey, strlen(cmpkey)) == 0) { \
-               ret->keyname = valptr; \
+               ret->Q_##keyname = valptr; \
                continue; \
        }
 #define assign_var(keyname) \
@@ -741,7 +741,7 @@ tree_read_file_ebuild(tree_pkg_ctx *pkg_ctx)
                if (q < p && *p == '=') {
                        *p++ = '\0';
                        /* match variable against which ones we look for */
-#define match_key(X) else if (strcmp(q, #X) == 0) key = &ret->X
+#define match_key(X) else if (strcmp(q, #X) == 0) key = &ret->Q_##X
                        if (1 == 0); /* dummy for syntax */
                        match_key(DEPEND);
                        match_key(RDEPEND);
@@ -840,7 +840,7 @@ tree_read_file_binpkg_xpak_cb(
 
 #define match_path(K) \
        else if (pathname_len == (sizeof(#K) - 1) && strcmp(pathname, #K) == 0) 
\
-               key = &m->K
+               key = &m->Q_##K
        if (1 == 0); /* dummy for syntax */
        match_path(DEPEND);
        match_path(RDEPEND);
@@ -868,33 +868,33 @@ tree_read_file_binpkg_xpak_cb(
 #undef match_path
 
        /* hijack unused members */
-       pos = (size_t)m->_eclasses_;
-       len = (size_t)m->_md5_;
+       pos = (size_t)m->Q__eclasses_;
+       len = (size_t)m->Q__md5_;
 
        /* trim whitespace (mostly trailing newline) */
        while (isspace((int)data[data_offset + data_len - 1]))
                data_len--;
 
        if (len - pos < (size_t)data_len) {
-               char *old_data = m->_data;
+               char *old_data = m->Q__data;
                len += (((data_len + 1) / BUFSIZ) + 1) * BUFSIZ;
-               m->_data = xrealloc(m->_data, len);
-               m->_md5_ = (char *)len;
+               m->Q__data = xrealloc(m->Q__data, len);
+               m->Q__md5_ = (char *)len;
 
                /* re-position existing keys */
-               if (old_data != NULL && m->_data != old_data) {
+               if (old_data != NULL && m->Q__data != old_data) {
                        char **newdata = (char **)m;
                        int elems = sizeof(tree_pkg_meta) / sizeof(char *);
                        while (elems-- > 0)
                                if (newdata[elems] != NULL)
-                                       newdata[elems] = m->_data + 
(newdata[elems] - old_data);
+                                       newdata[elems] = m->Q__data + 
(newdata[elems] - old_data);
                }
        }
 
-       *key = m->_data + pos;
+       *key = m->Q__data + pos;
        snprintf(*key, len - pos, "%.*s", data_len, data + data_offset);
        pos += data_len + 1;
-       m->_eclasses_ = (char *)pos;
+       m->Q__eclasses_ = (char *)pos;
 }
 
 static tree_pkg_meta *
@@ -941,7 +941,7 @@ tree_pkg_read(tree_pkg_ctx *pkg_ctx)
                return (tree_pkg_meta *)pkg_ctx->cat_ctx->ctx->pkgs;
        }
 
-       warn("Unknown metadata cache type!");
+       warn("Unknown/unsupported metadata cache type!");
        return NULL;
 }
 
@@ -950,11 +950,101 @@ tree_close_meta(tree_pkg_meta *cache)
 {
        if (cache == NULL)
                errf("Cache is empty !");
-       if (cache->_data != NULL)
-               free(cache->_data);
+       if (cache->Q__data != NULL)
+               free(cache->Q__data);
        free(cache);
 }
 
+char *
+tree_pkg_meta_get_int(tree_pkg_ctx *pkg_ctx, size_t offset, const char *keyn)
+{
+       tree_ctx *ctx = pkg_ctx->cat_ctx->ctx;
+       char **key;
+
+       /* offset is a byte offset in the tree_pkg_meta struct, pointing to
+        * key, the tree_pkg_meta_get macro takes care of this */
+
+       if (ctx->cachetype == CACHE_VDB) {
+               if (pkg_ctx->meta == NULL)
+                       pkg_ctx->meta = xzalloc(sizeof(tree_pkg_meta));
+
+               key = (char **)((char *)&pkg_ctx->meta->Q__data + offset);
+
+               /* just eat the file if we haven't yet */
+               if (*key == NULL) {
+                       int fd = tree_pkg_vdb_openat(pkg_ctx, keyn, O_RDONLY, 
0);
+                       struct stat s;
+                       size_t pos;
+                       size_t len;
+                       tree_pkg_meta *m = pkg_ctx->meta;
+
+                       if (fd < 0)
+                               return NULL;
+                       if (fstat(fd, &s) != 0 || s.st_size == 0) {
+                               close(fd);
+                               return NULL;
+                       }
+
+                       /* hijack unused members */
+                       pos = (size_t)m->Q__eclasses_;
+                       len = (size_t)m->Q__md5_;
+
+                       /* TODO: this is an exact copy from 
tree_read_file_binpkg_xpak_cb */
+                       if (len - pos < (size_t)s.st_size) {
+                               char *old_data = m->Q__data;
+                               len += (((s.st_size + 1) / BUFSIZ) + 1) * 
BUFSIZ;
+                               m->Q__data = xrealloc(m->Q__data, len);
+                               m->Q__md5_ = (char *)len;
+
+                               /* re-position existing keys */
+                               if (old_data != NULL && m->Q__data != old_data) 
{
+                                       char **newdata = (char **)m;
+                                       int elems = sizeof(tree_pkg_meta) / 
sizeof(char *);
+                                       while (elems-- > 0)
+                                               if (newdata[elems] != NULL)
+                                                       newdata[elems] =
+                                                               m->Q__data + 
(newdata[elems] - old_data);
+                               }
+                       }
+
+                       if (read(fd, &m->Q__data[pos], s.st_size) == 
(ssize_t)s.st_size) {
+                               char *p = *key = m->Q__data + pos;
+                               p[s.st_size] = '\0';
+                               while (s.st_size > 0 && 
isspace((int)p[s.st_size - 1]))
+                                       p[s.st_size--] = '\0';
+                               pos += s.st_size + 1;
+                               m->Q__eclasses_ = (char *)pos;
+                       }
+                       close(fd);
+               }
+       } else {
+               if (pkg_ctx->meta == NULL)
+                       pkg_ctx->meta = tree_pkg_read(pkg_ctx);
+               if (pkg_ctx->meta == NULL)
+                       return NULL;
+
+               key = (char **)((char *)&pkg_ctx->meta->Q__data + offset);
+
+               /* Packages are nice, but also a bit daft, because they don't
+                * contain everything available (for a semi-good reason though)
+                * We cannot downgrade the tree execution to BINPKGS, because
+                * we're running from tree_foreach_packages */
+               if (*key == NULL && ctx->cachetype == CACHE_PACKAGES) {
+                       ctx->cachetype = CACHE_BINPKGS;
+                       pkg_ctx->fd = -1;
+                       pkg_ctx->meta = tree_pkg_read(pkg_ctx);
+                       ctx->cachetype = CACHE_PACKAGES;
+                       if (pkg_ctx->meta == NULL) {
+                               /* hrmffff. */
+                               pkg_ctx->fd = 0;
+                               pkg_ctx->meta = tree_pkg_read(pkg_ctx);
+                       }
+                       key = (char **)((char *)&pkg_ctx->meta->Q__data + 
offset);
+               }
+       }
+       return *key;
+}
+
 tree_metadata_xml *
 tree_pkg_metadata(tree_pkg_ctx *pkg_ctx)
 {
@@ -1058,6 +1148,9 @@ tree_close_pkg(tree_pkg_ctx *pkg_ctx)
        if (pkg_ctx->cat_ctx->ctx->do_sort)
                free((char *)pkg_ctx->name);
        free(pkg_ctx->slot);
+       if (pkg_ctx->meta != NULL &&
+                       (void *)pkg_ctx->meta != (void 
*)pkg_ctx->cat_ctx->ctx->pkgs)
+               tree_close_meta(pkg_ctx->meta);
        free(pkg_ctx);
 }
 
@@ -1067,18 +1160,16 @@ tree_foreach_packages(tree_ctx *ctx, tree_pkg_cb 
callback, void *priv)
        char *p = ctx->pkgs;
        char *q;
        char *c;
+       char pkgname[_Q_PATH_MAX];
        size_t len = ctx->pkgslen;
        int ret = 0;
 
        /* reused for every entry */
-       tree_cat_ctx *cat = xzalloc(sizeof(tree_cat_ctx));
+       tree_cat_ctx *cat = NULL;
        tree_pkg_ctx *pkg = xzalloc(sizeof(tree_pkg_ctx));
        tree_pkg_meta *meta = xzalloc(sizeof(tree_pkg_meta));
        depend_atom *atom = NULL;
 
-       cat->ctx = ctx;
-       pkg->cat_ctx = cat;
-
        do {
                /* find next line */
                c = NULL;
@@ -1093,15 +1184,26 @@ tree_foreach_packages(tree_ctx *ctx, tree_pkg_cb 
callback, void *priv)
                if (p == q) {
                        /* make callback with populated atom */
                        if (atom != NULL) {
+                               size_t pkgnamelen;
+
                                /* store meta ptr in repo->pkgs, such that 
get_pkg_meta
                                 * can grab it from there (for free) */
                                ctx->pkgs = (char *)meta;
 
-                               cat->name = atom->CATEGORY;
-                               pkg->name = atom->PN;
-                               pkg->slot = meta->SLOT == NULL ? (char *)"0" : 
meta->SLOT;
+                               if (cat == NULL || strcmp(cat->name, 
atom->CATEGORY) != 0)
+                               {
+                                       if (cat != NULL)
+                                               tree_close_cat(cat);
+                                       pkg->cat_ctx = cat = tree_open_cat(ctx, 
atom->CATEGORY);
+                               }
+                               pkgnamelen = snprintf(pkgname, sizeof(pkgname), 
"%s-%s.tbz2",
+                                               atom->PN, atom->PR_int > 0 ? 
atom->PVR : atom->PV);
+                               pkgname[pkgnamelen - (sizeof(".tbz2") - 1)] = 
'\0';
+                               pkg->name = pkgname;
+                               pkg->slot = meta->Q_SLOT == NULL ? (char *)"0" 
: meta->Q_SLOT;
                                pkg->repo = ctx->repo;
                                pkg->atom = atom;
+                               pkg->fd = 0;  /* intentional, meta has already 
been read */
 
                                /* do call callback with pkg_atom (populate cat 
and pkg) */
                                ret |= callback(pkg, priv);
@@ -1140,7 +1242,7 @@ tree_foreach_packages(tree_ctx *ctx, tree_pkg_cb 
callback, void *priv)
 #define match_key(X) match_key2(X,X)
 #define match_key2(X,Y) \
                } else if (strcmp(p, #X) == 0) { \
-                       meta->Y = c
+                       meta->Q_##Y = c
                match_key(DEFINED_PHASES);
                match_key(DEPEND);
                match_key2(DESC, DESCRIPTION);
@@ -1234,8 +1336,8 @@ tree_get_atom(tree_pkg_ctx *pkg_ctx, bool complete)
                                if (pkg_ctx->slot == NULL) {
                                        meta = tree_pkg_read(pkg_ctx);
                                        if (meta != NULL) {
-                                               if (meta->SLOT != NULL) {
-                                                       pkg_ctx->slot = 
xstrdup(meta->SLOT);
+                                               if (meta->Q_SLOT != NULL) {
+                                                       pkg_ctx->slot = 
xstrdup(meta->Q_SLOT);
                                                        pkg_ctx->slot_len = 
strlen(pkg_ctx->slot);
                                                }
                                        }
@@ -1247,8 +1349,8 @@ tree_get_atom(tree_pkg_ctx *pkg_ctx, bool complete)
                                if (pkg_ctx->repo == NULL && ctx->cachetype == 
CACHE_BINPKGS) {
                                        if (meta == NULL)
                                                meta = tree_pkg_read(pkg_ctx);
-                                       if (meta != NULL && meta->repository != 
NULL) {
-                                               pkg_ctx->repo = 
xstrdup(meta->repository);
+                                       if (meta != NULL && meta->Q_repository 
!= NULL) {
+                                               pkg_ctx->repo = 
xstrdup(meta->Q_repository);
                                                pkg_ctx->repo_len = 
strlen(pkg_ctx->repo);
                                        }
                                }

diff --git a/libq/tree.h b/libq/tree.h
index aacfb14..8a37cbb 100644
--- a/libq/tree.h
+++ b/libq/tree.h
@@ -8,6 +8,7 @@
 
 #include <dirent.h>
 #include <stdbool.h>
+#include <stddef.h>
 
 #include "atom.h"
 #include "set.h"
@@ -67,37 +68,38 @@ struct tree_pkg_ctx {
        int fd;
        tree_cat_ctx *cat_ctx;
        depend_atom *atom;
+       tree_pkg_meta *meta;
 };
 
 /* Ebuild data */
 struct tree_pkg_meta {
-       char *_data;
-       char *DEPEND;        /* line 1 */
-       char *RDEPEND;
-       char *SLOT;
-       char *SRC_URI;
-       char *RESTRICT;      /* line 5 */
-       char *HOMEPAGE;
-       char *LICENSE;
-       char *DESCRIPTION;
-       char *KEYWORDS;
-       char *INHERITED;     /* line 10 */
-       char *IUSE;
-       char *CDEPEND;
-       char *PDEPEND;
-       char *PROVIDE;       /* line 14 */
-       char *EAPI;
-       char *PROPERTIES;
+       char *Q__data;
+       char *Q_DEPEND;        /* line 1 */
+       char *Q_RDEPEND;
+       char *Q_SLOT;
+       char *Q_SRC_URI;
+       char *Q_RESTRICT;      /* line 5 */
+       char *Q_HOMEPAGE;
+       char *Q_LICENSE;
+       char *Q_DESCRIPTION;
+       char *Q_KEYWORDS;
+       char *Q_INHERITED;     /* line 10 */
+       char *Q_IUSE;
+       char *Q_CDEPEND;
+       char *Q_PDEPEND;
+       char *Q_PROVIDE;       /* line 14 */
+       char *Q_EAPI;
+       char *Q_PROPERTIES;
        /* These are MD5-Cache only */
-       char *DEFINED_PHASES;
-       char *REQUIRED_USE;
-       char *BDEPEND;
-       char *_eclasses_;
-       char *_md5_;
+       char *Q_DEFINED_PHASES;
+       char *Q_REQUIRED_USE;
+       char *Q_BDEPEND;
+       char *Q__eclasses_;
+       char *Q__md5_;
        /* binpkgs/vdb */
-       char *CONTENTS;
-       char *USE;
-       char *repository;
+       char *Q_CONTENTS;
+       char *Q_USE;
+       char *Q_repository;
 };
 
 /* Metadata.xml */
@@ -132,6 +134,9 @@ FILE *tree_pkg_vdb_fopenat(tree_pkg_ctx *pkg_ctx, const 
char *file,
 bool tree_pkg_vdb_eat(tree_pkg_ctx *pkg_ctx, const char *file, char **bufptr, 
size_t *buflen);
 tree_pkg_meta *tree_pkg_read(tree_pkg_ctx *pkg_ctx);
 void tree_close_meta(tree_pkg_meta *cache);
+char *tree_pkg_meta_get_int(tree_pkg_ctx *pkg_ctx, size_t offset, const char 
*key);
+#define tree_pkg_meta_get(P,X) \
+       tree_pkg_meta_get_int(P, offsetof(tree_pkg_meta, Q_##X), #X)
 tree_metadata_xml *tree_pkg_metadata(tree_pkg_ctx *pkg_ctx);
 void tree_close_metadata(tree_metadata_xml *meta_ctx);
 void tree_close_pkg(tree_pkg_ctx *pkg_ctx);

diff --git a/qdepends.c b/qdepends.c
index 6f89835..9969d90 100644
--- a/qdepends.c
+++ b/qdepends.c
@@ -114,7 +114,6 @@ qdepends_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
        int ret = 0;
        dep_node *dep_tree;
        char **d;
-       tree_pkg_meta *meta = NULL;
        char *depstr;
 
        /* matrix consists of:
@@ -155,27 +154,17 @@ qdepends_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
        xarrayfree_int(state->deps);
        clear_set(state->udeps);
 
-       if (state->qmode & QMODE_TREE)
-               if ((meta = tree_pkg_read(pkg_ctx)) == NULL)
-                       return ret;
        dfile = depend_files;
        for (i = QMODE_DEPEND; i <= QMODE_BDEPEND; i <<= 1, dfile++) {
                if (!(state->qmode & i))
                        continue;
 
-               if (state->qmode & QMODE_INSTALLED) {
-                       if (!tree_pkg_vdb_eat(pkg_ctx, *dfile,
-                                               &state->depend, 
&state->depend_len))
-                               continue;
-                       depstr = state->depend;
-               } else {
-                       depstr = i == 1<<0 ? meta->DEPEND :
-                                        i == 1<<1 ? meta->RDEPEND :
-                                        i == 1<<2 ? meta->PDEPEND :
-                                        i == 1<<3 ? meta->BDEPEND : NULL;
-                       if (depstr == NULL)
-                               continue;
-               }
+               depstr = i == 1<<0 ? tree_pkg_meta_get(pkg_ctx, DEPEND) :
+                                i == 1<<1 ? tree_pkg_meta_get(pkg_ctx, 
RDEPEND) :
+                                i == 1<<2 ? tree_pkg_meta_get(pkg_ctx, 
PDEPEND) :
+                                i == 1<<3 ? tree_pkg_meta_get(pkg_ctx, 
BDEPEND) : NULL;
+               if (depstr == NULL)
+                       continue;
                dep_tree = dep_grow_tree(depstr);
                if (dep_tree == NULL)
                        continue;
@@ -188,10 +177,13 @@ qdepends_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
                                tree_pkg_ctx *vpkg =
                                        tree_open_pkg(vcat, pkg_ctx->name);
                                if (vpkg != NULL) {
-                                       if (tree_pkg_vdb_eat(vpkg, *dfile,
-                                                       &state->depend, 
&state->depend_len))
-                                       {
-                                               dep_node *dep_vdb = 
dep_grow_tree(state->depend);
+                                       depstr = i == 1<<0 ? 
tree_pkg_meta_get(vpkg, DEPEND) :
+                                                        i == 1<<1 ? 
tree_pkg_meta_get(vpkg, RDEPEND) :
+                                                        i == 1<<2 ? 
tree_pkg_meta_get(vpkg, PDEPEND) :
+                                                        i == 1<<3 ? 
tree_pkg_meta_get(vpkg, BDEPEND) :
+                                                        NULL;
+                                       if (depstr != NULL) {
+                                               dep_node *dep_vdb = 
dep_grow_tree(depstr);
                                                if (dep_vdb != NULL)
                                                        
dep_flatten_tree(dep_vdb, state->deps);
                                        }
@@ -299,8 +291,6 @@ int qdepends_main(int argc, char **argv)
                .deps = deps,
                .udeps = create_set(),
                .qmode = 0,
-               .depend = NULL,
-               .depend_len = 0,
                .format = "%[CATEGORY]%[PF]",
                .vdb = NULL,
        };

diff --git a/qkeyword.c b/qkeyword.c
index 4e84ebd..70f75de 100644
--- a/qkeyword.c
+++ b/qkeyword.c
@@ -643,7 +643,6 @@ qkeyword_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
        qkeyword_data *data = (qkeyword_data *)priv;
        char buf[_Q_PATH_MAX];
        depend_atom *patom = NULL;
-       tree_pkg_meta *meta;
        tree_metadata_xml *metadata;
        struct elist *emailw;
        int ret;
@@ -679,11 +678,8 @@ qkeyword_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
        }
 
        keywords = data->keywordsbuf;
-       meta = tree_pkg_read(pkg_ctx);
-       if (meta == NULL)
-               return EXIT_FAILURE;
 
-       if (read_keywords(meta->KEYWORDS, keywords) < 0) {
+       if (read_keywords(tree_pkg_meta_get(pkg_ctx, KEYWORDS), keywords) < 0) {
                if (verbose)
                        warn("Failed to read keywords for %s%s/%s%s%s",
                                BOLD, pkg_ctx->cat_ctx->name, BLUE, 
pkg_ctx->name, NORM);

diff --git a/qlist.c b/qlist.c
index 3f20ced..1d4862f 100644
--- a/qlist.c
+++ b/qlist.c
@@ -329,45 +329,14 @@ struct qlist_opt_state {
        const char *fmt;
 };
 
-struct qlist_xpakcbctx {
-       const char *key;
-       char *retdata;
-       size_t retlen;
-};
-
-static void
-_qlist_xpakcb(
-       void *ctx,
-       char *pathname,
-       int pathname_len,
-       int data_offset,
-       int data_len,
-       char *data)
-{
-       struct qlist_xpakcbctx *xctx = ctx;
-       (void)pathname_len;
-
-       /* see if this path matches what we're looking for */
-       if (strcmp(pathname, xctx->key) != 0)
-               return;
-
-       xctx->retdata = xrealloc(xctx->retdata, data_len + 1);
-       memcpy(xctx->retdata, data + data_offset, data_len + 1);
-       xctx->retlen = data_len;
-}
-
 static int
 qlist_cb(tree_pkg_ctx *pkg_ctx, void *priv)
 {
        struct qlist_opt_state *state = priv;
        int i;
-       FILE *fp;
+       char *contents;
+       char *line;
        depend_atom *atom;
-       struct qlist_xpakcbctx cbctx = {
-               .key = "CONTENTS",
-               .retdata = NULL,
-               .retlen = 0,
-       };
 
        /* see if this cat/pkg is requested */
        if (!state->all) {
@@ -392,38 +361,15 @@ qlist_cb(tree_pkg_ctx *pkg_ctx, void *priv)
                printf("%s %sCONTENTS%s:\n",
                                atom_format(state->fmt, atom), DKBLUE, NORM);
 
-       if (state->do_binpkgs) {
-               char xpak[_Q_PATH_MAX];
-               int ret;
-               snprintf(xpak, sizeof(xpak), "%s/%s/%s/%s-%s.tbz2",
-                               portroot, pkgdir, atom->CATEGORY, atom->PN,
-                               atom->PR_int > 0 ? atom->PVR : atom->PV);
-               ret = xpak_extract(xpak, &cbctx, &_qlist_xpakcb);
-               if (ret != 0 || cbctx.retdata == NULL)
-                       fp = NULL;
-               else
-#ifdef HAVE_FMEMOPEN
-                       fp = fmemopen(cbctx.retdata, cbctx.retlen, "r");
-#else
-               {
-                       /* resort to writing a file in tmpspace */
-                       fp = tmpfile();
-                       if (fp != NULL) {
-                               fwrite(cbctx.retdata, 1, cbctx.retlen, fp);
-                               fseek(fp, 0, SEEK_SET);
-                       }
-               }
-#endif
-       } else {
-               fp = tree_pkg_vdb_fopenat_ro(pkg_ctx, "CONTENTS");
-       }
-       if (fp == NULL)
+       if ((contents = tree_pkg_meta_get(pkg_ctx, CONTENTS)) == NULL)
                return 1;
 
-       while (getline(&state->buf, &state->buflen, fp) != -1) {
+       while ((line = strtok(contents, "\n")) != NULL) {
                contents_entry *e;
 
-               e = contents_parse_line(state->buf);
+               contents = NULL;  /* for strtok */
+
+               e = contents_parse_line(line);
                if (!e)
                        continue;
 
@@ -455,9 +401,6 @@ qlist_cb(tree_pkg_ctx *pkg_ctx, void *priv)
                                break;
                }
        }
-       fclose(fp);
-       if (state->do_binpkgs && cbctx.retdata != NULL)
-               free(cbctx.retdata);
 
        return 1;
 }

diff --git a/qsearch.c b/qsearch.c
index d6470f6..a26e2d6 100644
--- a/qsearch.c
+++ b/qsearch.c
@@ -66,7 +66,6 @@ qsearch_cb(tree_pkg_ctx *pkg_ctx, void *priv)
 
        struct qsearch_state *state = (struct qsearch_state *)priv;
        depend_atom *atom;
-       tree_pkg_meta *meta;
        char *desc;
        bool match;
 
@@ -84,17 +83,13 @@ qsearch_cb(tree_pkg_ctx *pkg_ctx, void *priv)
                match = true;
 
        desc = NULL;
-       meta = NULL;
        if ((match && (state->show_homepage || state->show_desc)) ||
                        (!match && state->search_desc))
        {
-               meta = tree_pkg_read(pkg_ctx);
-               if (meta != NULL) {
-                       if (state->show_homepage)
-                               desc = meta->HOMEPAGE;
-                       else if (state->show_desc)
-                               desc = meta->DESCRIPTION;
-               }
+               if (state->show_homepage)
+                       desc = tree_pkg_meta_get(pkg_ctx, HOMEPAGE);
+               else if (state->show_desc)
+                       desc = tree_pkg_meta_get(pkg_ctx, DESCRIPTION);
        }
 
        if (!match && state->search_desc && desc != NULL &&
@@ -109,9 +104,6 @@ qsearch_cb(tree_pkg_ctx *pkg_ctx, void *priv)
                                (state->show_name ? "" : desc ? desc : ""));
        }
 
-       if (meta != NULL)
-               tree_close_meta(meta);
-
        if (last_atom != NULL)
                atom_implode(last_atom);
        last_atom = atom;

diff --git a/quse.c b/quse.c
index df8626e..be34e48 100644
--- a/quse.c
+++ b/quse.c
@@ -412,7 +412,6 @@ quse_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
        struct quse_state *state = (struct quse_state *)priv;
        depend_atom *atom = NULL;  /* pacify compiler */
        char buf[8192];
-       tree_pkg_meta *meta;
        set *use = NULL;
        bool match;
        char *p;
@@ -439,52 +438,38 @@ quse_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
                }
        }
 
-       if (state->overlay != NULL) {
-               meta = tree_pkg_read(pkg_ctx);
-               if (meta == NULL)
+       if (!state->do_licence) {
+               if (tree_pkg_meta_get(pkg_ctx, IUSE) == NULL)
                        return 0;
-               if (meta->IUSE == NULL)
-                       return 0;
-       } else {
-               size_t dummy;
-
-               meta = xzalloc(sizeof(*meta));
 
-               dummy = 0;
-               if (!tree_pkg_vdb_eat(pkg_ctx, "IUSE", &meta->IUSE, &dummy)) {
-                       free(meta);
-                       return 0;
+               if (state->do_describe) {
+                       portdirfd = openat(pkg_ctx->cat_ctx->ctx->portroot_fd,
+                                       state->overlay == NULL ? main_overlay : 
state->overlay,
+                                       O_RDONLY | O_CLOEXEC | O_PATH);
+                       if (portdirfd == -1)
+                               return 0;
                }
 
-               dummy = 0;
-               tree_pkg_vdb_eat(pkg_ctx, "LICENSE", &meta->LICENSE, &dummy);
-
-               s = NULL;
-               dummy = 0;
-               tree_pkg_vdb_eat(pkg_ctx, "USE", &s, &dummy);
-               p = s;
-               while ((q = strchr(p, (int)' ')) != NULL) {
-                       *q++ = '\0';
-                       use = add_set(p, use);
-                       p = q;
+               /* available when dealing with VDB or binpkgs */
+               if ((p = tree_pkg_meta_get(pkg_ctx, USE)) != NULL) {
+                       while ((q = strchr(p, (int)' ')) != NULL) {
+                               *q++ = '\0';
+                               use = add_set(p, use);
+                               p = q;
+                       }
+                       if (*p != '\0')
+                               use = add_set(p, use);
                }
-               if (*p != '\0')
-                       use = add_set(p, use);
-               free(s);
-       }
-
-       if (state->do_describe) {
-               portdirfd = openat(pkg_ctx->cat_ctx->ctx->portroot_fd,
-                               state->overlay == NULL ? main_overlay : 
state->overlay,
-                               O_RDONLY | O_CLOEXEC | O_PATH);
-               if (portdirfd == -1)
+       } else {
+               if (tree_pkg_meta_get(pkg_ctx, LICENSE) == NULL)
                        return 0;
        }
 
        maxlen = 0;
        cnt = 0;
        match = false;
-       q = p = state->do_licence ? meta->LICENSE : meta->IUSE;
+       q = p = state->do_licence ?
+               tree_pkg_meta_get(pkg_ctx, LICENSE) : 
tree_pkg_meta_get(pkg_ctx, IUSE);
        buf[0] = '\0';
        v = buf;
        w = buf + sizeof(buf);
@@ -567,7 +552,7 @@ quse_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
 
                        printf("%s\n", atom_format(state->fmt, atom));
 
-                       q = p = meta->IUSE;
+                       q = p = tree_pkg_meta_get(pkg_ctx, IUSE);
                        buf[0] = '\0';
                        v = buf;
                        w = buf + sizeof(buf);
@@ -652,16 +637,8 @@ quse_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
                }
        }
 
-       if (state->overlay != NULL) {
-               tree_close_meta(meta);
-       } else {
-               free(meta->IUSE);
-               if (meta->LICENSE != NULL)
-                       free(meta->LICENSE);
-               free(meta);
-               if (use != NULL)
-                       free_set(use);
-       }
+       if (use != NULL)
+               free_set(use);
        if (state->do_describe)
                close(portdirfd);
 

Reply via email to