Gentoo Archives: gentoo-commits

From: Fabian Groffen <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage-utils:master commit in: libq/, /
Date: Mon, 30 Dec 2019 17:24:54
Message-Id: 1577726481.c9e89dfa7cc3ae22bc3c731a3d617e4912bd831a.grobian@gentoo
1 commit: c9e89dfa7cc3ae22bc3c731a3d617e4912bd831a
2 Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
3 AuthorDate: Mon Dec 30 17:21:21 2019 +0000
4 Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
5 CommitDate: Mon Dec 30 17:21:21 2019 +0000
6 URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=c9e89dfa
7
8 libq/tree: introduce a wrapper for retrieving ebuild metadata
9
10 To further hide the difference between trees, add a wrapper around
11 tree_get_meta, which deals with the underlying storage format. This is
12 most notably useful when dealing with vdb-based and binpkgs because they
13 have a specific or more expensive way of retrieval. This can now
14 properly be hidden from the q applets.
15
16 Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
17
18 libq/tree.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++------------
19 libq/tree.h | 55 +++++++++++---------
20 qdepends.c | 36 +++++--------
21 qkeyword.c | 6 +--
22 qlist.c | 71 +++-----------------------
23 qsearch.c | 16 ++----
24 quse.c | 71 +++++++++-----------------
25 7 files changed, 213 insertions(+), 208 deletions(-)
26
27 diff --git a/libq/tree.c b/libq/tree.c
28 index d9eec76..bac9d00 100644
29 --- a/libq/tree.c
30 +++ b/libq/tree.c
31 @@ -326,6 +326,7 @@ tree_open_pkg(tree_cat_ctx *cat_ctx, const char *name)
32 pkg_ctx->fd = -1;
33 pkg_ctx->cat_ctx = cat_ctx;
34 pkg_ctx->atom = NULL;
35 + pkg_ctx->meta = NULL;
36 return pkg_ctx;
37 }
38
39 @@ -418,8 +419,7 @@ tree_next_pkg(tree_cat_ctx *cat_ctx)
40 tree_ctx *pkgdir = ctx->ebuilddir_ctx;
41
42 if (pkgdir == NULL)
43 - pkgdir = ctx->ebuilddir_ctx = xmalloc(sizeof(tree_ctx));
44 - memset(ctx->ebuilddir_ctx, '\0', sizeof(*ctx->ebuilddir_ctx));
45 + pkgdir = ctx->ebuilddir_ctx = xzalloc(sizeof(tree_ctx));
46
47 ctx->ebuilddir_pkg_ctx = tree_next_pkg_int(cat_ctx);
48 if (ctx->ebuilddir_pkg_ctx == NULL)
49 @@ -554,13 +554,13 @@ tree_read_file_pms(tree_pkg_ctx *pkg_ctx)
50 if ((off_t)fread(ptr, 1, s.st_size, f) != s.st_size)
51 goto err;
52
53 - ret->DEPEND = ptr;
54 + ret->Q_DEPEND = ptr;
55 #define next_line(curr, next) \
56 - if ((ptr = strchr(ret->curr, '\n')) == NULL) { \
57 + if ((ptr = strchr(ret->Q_##curr, '\n')) == NULL) { \
58 warn("Invalid cache file for '%s'", buf); \
59 goto err; \
60 } \
61 - ret->next = ptr+1; \
62 + ret->Q_##next = ptr+1; \
63 *ptr = '\0';
64 next_line(DEPEND, RDEPEND)
65 next_line(RDEPEND, SLOT)
66 @@ -630,7 +630,7 @@ tree_read_file_md5(tree_pkg_ctx *pkg_ctx)
67 * */
68 #define assign_var_cmp(keyname, cmpkey) \
69 if (strncmp(keyptr, cmpkey, strlen(cmpkey)) == 0) { \
70 - ret->keyname = valptr; \
71 + ret->Q_##keyname = valptr; \
72 continue; \
73 }
74 #define assign_var(keyname) \
75 @@ -741,7 +741,7 @@ tree_read_file_ebuild(tree_pkg_ctx *pkg_ctx)
76 if (q < p && *p == '=') {
77 *p++ = '\0';
78 /* match variable against which ones we look for */
79 -#define match_key(X) else if (strcmp(q, #X) == 0) key = &ret->X
80 +#define match_key(X) else if (strcmp(q, #X) == 0) key = &ret->Q_##X
81 if (1 == 0); /* dummy for syntax */
82 match_key(DEPEND);
83 match_key(RDEPEND);
84 @@ -840,7 +840,7 @@ tree_read_file_binpkg_xpak_cb(
85
86 #define match_path(K) \
87 else if (pathname_len == (sizeof(#K) - 1) && strcmp(pathname, #K) == 0) \
88 - key = &m->K
89 + key = &m->Q_##K
90 if (1 == 0); /* dummy for syntax */
91 match_path(DEPEND);
92 match_path(RDEPEND);
93 @@ -868,33 +868,33 @@ tree_read_file_binpkg_xpak_cb(
94 #undef match_path
95
96 /* hijack unused members */
97 - pos = (size_t)m->_eclasses_;
98 - len = (size_t)m->_md5_;
99 + pos = (size_t)m->Q__eclasses_;
100 + len = (size_t)m->Q__md5_;
101
102 /* trim whitespace (mostly trailing newline) */
103 while (isspace((int)data[data_offset + data_len - 1]))
104 data_len--;
105
106 if (len - pos < (size_t)data_len) {
107 - char *old_data = m->_data;
108 + char *old_data = m->Q__data;
109 len += (((data_len + 1) / BUFSIZ) + 1) * BUFSIZ;
110 - m->_data = xrealloc(m->_data, len);
111 - m->_md5_ = (char *)len;
112 + m->Q__data = xrealloc(m->Q__data, len);
113 + m->Q__md5_ = (char *)len;
114
115 /* re-position existing keys */
116 - if (old_data != NULL && m->_data != old_data) {
117 + if (old_data != NULL && m->Q__data != old_data) {
118 char **newdata = (char **)m;
119 int elems = sizeof(tree_pkg_meta) / sizeof(char *);
120 while (elems-- > 0)
121 if (newdata[elems] != NULL)
122 - newdata[elems] = m->_data + (newdata[elems] - old_data);
123 + newdata[elems] = m->Q__data + (newdata[elems] - old_data);
124 }
125 }
126
127 - *key = m->_data + pos;
128 + *key = m->Q__data + pos;
129 snprintf(*key, len - pos, "%.*s", data_len, data + data_offset);
130 pos += data_len + 1;
131 - m->_eclasses_ = (char *)pos;
132 + m->Q__eclasses_ = (char *)pos;
133 }
134
135 static tree_pkg_meta *
136 @@ -941,7 +941,7 @@ tree_pkg_read(tree_pkg_ctx *pkg_ctx)
137 return (tree_pkg_meta *)pkg_ctx->cat_ctx->ctx->pkgs;
138 }
139
140 - warn("Unknown metadata cache type!");
141 + warn("Unknown/unsupported metadata cache type!");
142 return NULL;
143 }
144
145 @@ -950,11 +950,101 @@ tree_close_meta(tree_pkg_meta *cache)
146 {
147 if (cache == NULL)
148 errf("Cache is empty !");
149 - if (cache->_data != NULL)
150 - free(cache->_data);
151 + if (cache->Q__data != NULL)
152 + free(cache->Q__data);
153 free(cache);
154 }
155
156 +char *
157 +tree_pkg_meta_get_int(tree_pkg_ctx *pkg_ctx, size_t offset, const char *keyn)
158 +{
159 + tree_ctx *ctx = pkg_ctx->cat_ctx->ctx;
160 + char **key;
161 +
162 + /* offset is a byte offset in the tree_pkg_meta struct, pointing to
163 + * key, the tree_pkg_meta_get macro takes care of this */
164 +
165 + if (ctx->cachetype == CACHE_VDB) {
166 + if (pkg_ctx->meta == NULL)
167 + pkg_ctx->meta = xzalloc(sizeof(tree_pkg_meta));
168 +
169 + key = (char **)((char *)&pkg_ctx->meta->Q__data + offset);
170 +
171 + /* just eat the file if we haven't yet */
172 + if (*key == NULL) {
173 + int fd = tree_pkg_vdb_openat(pkg_ctx, keyn, O_RDONLY, 0);
174 + struct stat s;
175 + size_t pos;
176 + size_t len;
177 + tree_pkg_meta *m = pkg_ctx->meta;
178 +
179 + if (fd < 0)
180 + return NULL;
181 + if (fstat(fd, &s) != 0 || s.st_size == 0) {
182 + close(fd);
183 + return NULL;
184 + }
185 +
186 + /* hijack unused members */
187 + pos = (size_t)m->Q__eclasses_;
188 + len = (size_t)m->Q__md5_;
189 +
190 + /* TODO: this is an exact copy from tree_read_file_binpkg_xpak_cb */
191 + if (len - pos < (size_t)s.st_size) {
192 + char *old_data = m->Q__data;
193 + len += (((s.st_size + 1) / BUFSIZ) + 1) * BUFSIZ;
194 + m->Q__data = xrealloc(m->Q__data, len);
195 + m->Q__md5_ = (char *)len;
196 +
197 + /* re-position existing keys */
198 + if (old_data != NULL && m->Q__data != old_data) {
199 + char **newdata = (char **)m;
200 + int elems = sizeof(tree_pkg_meta) / sizeof(char *);
201 + while (elems-- > 0)
202 + if (newdata[elems] != NULL)
203 + newdata[elems] =
204 + m->Q__data + (newdata[elems] - old_data);
205 + }
206 + }
207 +
208 + if (read(fd, &m->Q__data[pos], s.st_size) == (ssize_t)s.st_size) {
209 + char *p = *key = m->Q__data + pos;
210 + p[s.st_size] = '\0';
211 + while (s.st_size > 0 && isspace((int)p[s.st_size - 1]))
212 + p[s.st_size--] = '\0';
213 + pos += s.st_size + 1;
214 + m->Q__eclasses_ = (char *)pos;
215 + }
216 + close(fd);
217 + }
218 + } else {
219 + if (pkg_ctx->meta == NULL)
220 + pkg_ctx->meta = tree_pkg_read(pkg_ctx);
221 + if (pkg_ctx->meta == NULL)
222 + return NULL;
223 +
224 + key = (char **)((char *)&pkg_ctx->meta->Q__data + offset);
225 +
226 + /* Packages are nice, but also a bit daft, because they don't
227 + * contain everything available (for a semi-good reason though)
228 + * We cannot downgrade the tree execution to BINPKGS, because
229 + * we're running from tree_foreach_packages */
230 + if (*key == NULL && ctx->cachetype == CACHE_PACKAGES) {
231 + ctx->cachetype = CACHE_BINPKGS;
232 + pkg_ctx->fd = -1;
233 + pkg_ctx->meta = tree_pkg_read(pkg_ctx);
234 + ctx->cachetype = CACHE_PACKAGES;
235 + if (pkg_ctx->meta == NULL) {
236 + /* hrmffff. */
237 + pkg_ctx->fd = 0;
238 + pkg_ctx->meta = tree_pkg_read(pkg_ctx);
239 + }
240 + key = (char **)((char *)&pkg_ctx->meta->Q__data + offset);
241 + }
242 + }
243 + return *key;
244 +}
245 +
246 tree_metadata_xml *
247 tree_pkg_metadata(tree_pkg_ctx *pkg_ctx)
248 {
249 @@ -1058,6 +1148,9 @@ tree_close_pkg(tree_pkg_ctx *pkg_ctx)
250 if (pkg_ctx->cat_ctx->ctx->do_sort)
251 free((char *)pkg_ctx->name);
252 free(pkg_ctx->slot);
253 + if (pkg_ctx->meta != NULL &&
254 + (void *)pkg_ctx->meta != (void *)pkg_ctx->cat_ctx->ctx->pkgs)
255 + tree_close_meta(pkg_ctx->meta);
256 free(pkg_ctx);
257 }
258
259 @@ -1067,18 +1160,16 @@ tree_foreach_packages(tree_ctx *ctx, tree_pkg_cb callback, void *priv)
260 char *p = ctx->pkgs;
261 char *q;
262 char *c;
263 + char pkgname[_Q_PATH_MAX];
264 size_t len = ctx->pkgslen;
265 int ret = 0;
266
267 /* reused for every entry */
268 - tree_cat_ctx *cat = xzalloc(sizeof(tree_cat_ctx));
269 + tree_cat_ctx *cat = NULL;
270 tree_pkg_ctx *pkg = xzalloc(sizeof(tree_pkg_ctx));
271 tree_pkg_meta *meta = xzalloc(sizeof(tree_pkg_meta));
272 depend_atom *atom = NULL;
273
274 - cat->ctx = ctx;
275 - pkg->cat_ctx = cat;
276 -
277 do {
278 /* find next line */
279 c = NULL;
280 @@ -1093,15 +1184,26 @@ tree_foreach_packages(tree_ctx *ctx, tree_pkg_cb callback, void *priv)
281 if (p == q) {
282 /* make callback with populated atom */
283 if (atom != NULL) {
284 + size_t pkgnamelen;
285 +
286 /* store meta ptr in repo->pkgs, such that get_pkg_meta
287 * can grab it from there (for free) */
288 ctx->pkgs = (char *)meta;
289
290 - cat->name = atom->CATEGORY;
291 - pkg->name = atom->PN;
292 - pkg->slot = meta->SLOT == NULL ? (char *)"0" : meta->SLOT;
293 + if (cat == NULL || strcmp(cat->name, atom->CATEGORY) != 0)
294 + {
295 + if (cat != NULL)
296 + tree_close_cat(cat);
297 + pkg->cat_ctx = cat = tree_open_cat(ctx, atom->CATEGORY);
298 + }
299 + pkgnamelen = snprintf(pkgname, sizeof(pkgname), "%s-%s.tbz2",
300 + atom->PN, atom->PR_int > 0 ? atom->PVR : atom->PV);
301 + pkgname[pkgnamelen - (sizeof(".tbz2") - 1)] = '\0';
302 + pkg->name = pkgname;
303 + pkg->slot = meta->Q_SLOT == NULL ? (char *)"0" : meta->Q_SLOT;
304 pkg->repo = ctx->repo;
305 pkg->atom = atom;
306 + pkg->fd = 0; /* intentional, meta has already been read */
307
308 /* do call callback with pkg_atom (populate cat and pkg) */
309 ret |= callback(pkg, priv);
310 @@ -1140,7 +1242,7 @@ tree_foreach_packages(tree_ctx *ctx, tree_pkg_cb callback, void *priv)
311 #define match_key(X) match_key2(X,X)
312 #define match_key2(X,Y) \
313 } else if (strcmp(p, #X) == 0) { \
314 - meta->Y = c
315 + meta->Q_##Y = c
316 match_key(DEFINED_PHASES);
317 match_key(DEPEND);
318 match_key2(DESC, DESCRIPTION);
319 @@ -1234,8 +1336,8 @@ tree_get_atom(tree_pkg_ctx *pkg_ctx, bool complete)
320 if (pkg_ctx->slot == NULL) {
321 meta = tree_pkg_read(pkg_ctx);
322 if (meta != NULL) {
323 - if (meta->SLOT != NULL) {
324 - pkg_ctx->slot = xstrdup(meta->SLOT);
325 + if (meta->Q_SLOT != NULL) {
326 + pkg_ctx->slot = xstrdup(meta->Q_SLOT);
327 pkg_ctx->slot_len = strlen(pkg_ctx->slot);
328 }
329 }
330 @@ -1247,8 +1349,8 @@ tree_get_atom(tree_pkg_ctx *pkg_ctx, bool complete)
331 if (pkg_ctx->repo == NULL && ctx->cachetype == CACHE_BINPKGS) {
332 if (meta == NULL)
333 meta = tree_pkg_read(pkg_ctx);
334 - if (meta != NULL && meta->repository != NULL) {
335 - pkg_ctx->repo = xstrdup(meta->repository);
336 + if (meta != NULL && meta->Q_repository != NULL) {
337 + pkg_ctx->repo = xstrdup(meta->Q_repository);
338 pkg_ctx->repo_len = strlen(pkg_ctx->repo);
339 }
340 }
341
342 diff --git a/libq/tree.h b/libq/tree.h
343 index aacfb14..8a37cbb 100644
344 --- a/libq/tree.h
345 +++ b/libq/tree.h
346 @@ -8,6 +8,7 @@
347
348 #include <dirent.h>
349 #include <stdbool.h>
350 +#include <stddef.h>
351
352 #include "atom.h"
353 #include "set.h"
354 @@ -67,37 +68,38 @@ struct tree_pkg_ctx {
355 int fd;
356 tree_cat_ctx *cat_ctx;
357 depend_atom *atom;
358 + tree_pkg_meta *meta;
359 };
360
361 /* Ebuild data */
362 struct tree_pkg_meta {
363 - char *_data;
364 - char *DEPEND; /* line 1 */
365 - char *RDEPEND;
366 - char *SLOT;
367 - char *SRC_URI;
368 - char *RESTRICT; /* line 5 */
369 - char *HOMEPAGE;
370 - char *LICENSE;
371 - char *DESCRIPTION;
372 - char *KEYWORDS;
373 - char *INHERITED; /* line 10 */
374 - char *IUSE;
375 - char *CDEPEND;
376 - char *PDEPEND;
377 - char *PROVIDE; /* line 14 */
378 - char *EAPI;
379 - char *PROPERTIES;
380 + char *Q__data;
381 + char *Q_DEPEND; /* line 1 */
382 + char *Q_RDEPEND;
383 + char *Q_SLOT;
384 + char *Q_SRC_URI;
385 + char *Q_RESTRICT; /* line 5 */
386 + char *Q_HOMEPAGE;
387 + char *Q_LICENSE;
388 + char *Q_DESCRIPTION;
389 + char *Q_KEYWORDS;
390 + char *Q_INHERITED; /* line 10 */
391 + char *Q_IUSE;
392 + char *Q_CDEPEND;
393 + char *Q_PDEPEND;
394 + char *Q_PROVIDE; /* line 14 */
395 + char *Q_EAPI;
396 + char *Q_PROPERTIES;
397 /* These are MD5-Cache only */
398 - char *DEFINED_PHASES;
399 - char *REQUIRED_USE;
400 - char *BDEPEND;
401 - char *_eclasses_;
402 - char *_md5_;
403 + char *Q_DEFINED_PHASES;
404 + char *Q_REQUIRED_USE;
405 + char *Q_BDEPEND;
406 + char *Q__eclasses_;
407 + char *Q__md5_;
408 /* binpkgs/vdb */
409 - char *CONTENTS;
410 - char *USE;
411 - char *repository;
412 + char *Q_CONTENTS;
413 + char *Q_USE;
414 + char *Q_repository;
415 };
416
417 /* Metadata.xml */
418 @@ -132,6 +134,9 @@ FILE *tree_pkg_vdb_fopenat(tree_pkg_ctx *pkg_ctx, const char *file,
419 bool tree_pkg_vdb_eat(tree_pkg_ctx *pkg_ctx, const char *file, char **bufptr, size_t *buflen);
420 tree_pkg_meta *tree_pkg_read(tree_pkg_ctx *pkg_ctx);
421 void tree_close_meta(tree_pkg_meta *cache);
422 +char *tree_pkg_meta_get_int(tree_pkg_ctx *pkg_ctx, size_t offset, const char *key);
423 +#define tree_pkg_meta_get(P,X) \
424 + tree_pkg_meta_get_int(P, offsetof(tree_pkg_meta, Q_##X), #X)
425 tree_metadata_xml *tree_pkg_metadata(tree_pkg_ctx *pkg_ctx);
426 void tree_close_metadata(tree_metadata_xml *meta_ctx);
427 void tree_close_pkg(tree_pkg_ctx *pkg_ctx);
428
429 diff --git a/qdepends.c b/qdepends.c
430 index 6f89835..9969d90 100644
431 --- a/qdepends.c
432 +++ b/qdepends.c
433 @@ -114,7 +114,6 @@ qdepends_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
434 int ret = 0;
435 dep_node *dep_tree;
436 char **d;
437 - tree_pkg_meta *meta = NULL;
438 char *depstr;
439
440 /* matrix consists of:
441 @@ -155,27 +154,17 @@ qdepends_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
442 xarrayfree_int(state->deps);
443 clear_set(state->udeps);
444
445 - if (state->qmode & QMODE_TREE)
446 - if ((meta = tree_pkg_read(pkg_ctx)) == NULL)
447 - return ret;
448 dfile = depend_files;
449 for (i = QMODE_DEPEND; i <= QMODE_BDEPEND; i <<= 1, dfile++) {
450 if (!(state->qmode & i))
451 continue;
452
453 - if (state->qmode & QMODE_INSTALLED) {
454 - if (!tree_pkg_vdb_eat(pkg_ctx, *dfile,
455 - &state->depend, &state->depend_len))
456 - continue;
457 - depstr = state->depend;
458 - } else {
459 - depstr = i == 1<<0 ? meta->DEPEND :
460 - i == 1<<1 ? meta->RDEPEND :
461 - i == 1<<2 ? meta->PDEPEND :
462 - i == 1<<3 ? meta->BDEPEND : NULL;
463 - if (depstr == NULL)
464 - continue;
465 - }
466 + depstr = i == 1<<0 ? tree_pkg_meta_get(pkg_ctx, DEPEND) :
467 + i == 1<<1 ? tree_pkg_meta_get(pkg_ctx, RDEPEND) :
468 + i == 1<<2 ? tree_pkg_meta_get(pkg_ctx, PDEPEND) :
469 + i == 1<<3 ? tree_pkg_meta_get(pkg_ctx, BDEPEND) : NULL;
470 + if (depstr == NULL)
471 + continue;
472 dep_tree = dep_grow_tree(depstr);
473 if (dep_tree == NULL)
474 continue;
475 @@ -188,10 +177,13 @@ qdepends_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
476 tree_pkg_ctx *vpkg =
477 tree_open_pkg(vcat, pkg_ctx->name);
478 if (vpkg != NULL) {
479 - if (tree_pkg_vdb_eat(vpkg, *dfile,
480 - &state->depend, &state->depend_len))
481 - {
482 - dep_node *dep_vdb = dep_grow_tree(state->depend);
483 + depstr = i == 1<<0 ? tree_pkg_meta_get(vpkg, DEPEND) :
484 + i == 1<<1 ? tree_pkg_meta_get(vpkg, RDEPEND) :
485 + i == 1<<2 ? tree_pkg_meta_get(vpkg, PDEPEND) :
486 + i == 1<<3 ? tree_pkg_meta_get(vpkg, BDEPEND) :
487 + NULL;
488 + if (depstr != NULL) {
489 + dep_node *dep_vdb = dep_grow_tree(depstr);
490 if (dep_vdb != NULL)
491 dep_flatten_tree(dep_vdb, state->deps);
492 }
493 @@ -299,8 +291,6 @@ int qdepends_main(int argc, char **argv)
494 .deps = deps,
495 .udeps = create_set(),
496 .qmode = 0,
497 - .depend = NULL,
498 - .depend_len = 0,
499 .format = "%[CATEGORY]%[PF]",
500 .vdb = NULL,
501 };
502
503 diff --git a/qkeyword.c b/qkeyword.c
504 index 4e84ebd..70f75de 100644
505 --- a/qkeyword.c
506 +++ b/qkeyword.c
507 @@ -643,7 +643,6 @@ qkeyword_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
508 qkeyword_data *data = (qkeyword_data *)priv;
509 char buf[_Q_PATH_MAX];
510 depend_atom *patom = NULL;
511 - tree_pkg_meta *meta;
512 tree_metadata_xml *metadata;
513 struct elist *emailw;
514 int ret;
515 @@ -679,11 +678,8 @@ qkeyword_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
516 }
517
518 keywords = data->keywordsbuf;
519 - meta = tree_pkg_read(pkg_ctx);
520 - if (meta == NULL)
521 - return EXIT_FAILURE;
522
523 - if (read_keywords(meta->KEYWORDS, keywords) < 0) {
524 + if (read_keywords(tree_pkg_meta_get(pkg_ctx, KEYWORDS), keywords) < 0) {
525 if (verbose)
526 warn("Failed to read keywords for %s%s/%s%s%s",
527 BOLD, pkg_ctx->cat_ctx->name, BLUE, pkg_ctx->name, NORM);
528
529 diff --git a/qlist.c b/qlist.c
530 index 3f20ced..1d4862f 100644
531 --- a/qlist.c
532 +++ b/qlist.c
533 @@ -329,45 +329,14 @@ struct qlist_opt_state {
534 const char *fmt;
535 };
536
537 -struct qlist_xpakcbctx {
538 - const char *key;
539 - char *retdata;
540 - size_t retlen;
541 -};
542 -
543 -static void
544 -_qlist_xpakcb(
545 - void *ctx,
546 - char *pathname,
547 - int pathname_len,
548 - int data_offset,
549 - int data_len,
550 - char *data)
551 -{
552 - struct qlist_xpakcbctx *xctx = ctx;
553 - (void)pathname_len;
554 -
555 - /* see if this path matches what we're looking for */
556 - if (strcmp(pathname, xctx->key) != 0)
557 - return;
558 -
559 - xctx->retdata = xrealloc(xctx->retdata, data_len + 1);
560 - memcpy(xctx->retdata, data + data_offset, data_len + 1);
561 - xctx->retlen = data_len;
562 -}
563 -
564 static int
565 qlist_cb(tree_pkg_ctx *pkg_ctx, void *priv)
566 {
567 struct qlist_opt_state *state = priv;
568 int i;
569 - FILE *fp;
570 + char *contents;
571 + char *line;
572 depend_atom *atom;
573 - struct qlist_xpakcbctx cbctx = {
574 - .key = "CONTENTS",
575 - .retdata = NULL,
576 - .retlen = 0,
577 - };
578
579 /* see if this cat/pkg is requested */
580 if (!state->all) {
581 @@ -392,38 +361,15 @@ qlist_cb(tree_pkg_ctx *pkg_ctx, void *priv)
582 printf("%s %sCONTENTS%s:\n",
583 atom_format(state->fmt, atom), DKBLUE, NORM);
584
585 - if (state->do_binpkgs) {
586 - char xpak[_Q_PATH_MAX];
587 - int ret;
588 - snprintf(xpak, sizeof(xpak), "%s/%s/%s/%s-%s.tbz2",
589 - portroot, pkgdir, atom->CATEGORY, atom->PN,
590 - atom->PR_int > 0 ? atom->PVR : atom->PV);
591 - ret = xpak_extract(xpak, &cbctx, &_qlist_xpakcb);
592 - if (ret != 0 || cbctx.retdata == NULL)
593 - fp = NULL;
594 - else
595 -#ifdef HAVE_FMEMOPEN
596 - fp = fmemopen(cbctx.retdata, cbctx.retlen, "r");
597 -#else
598 - {
599 - /* resort to writing a file in tmpspace */
600 - fp = tmpfile();
601 - if (fp != NULL) {
602 - fwrite(cbctx.retdata, 1, cbctx.retlen, fp);
603 - fseek(fp, 0, SEEK_SET);
604 - }
605 - }
606 -#endif
607 - } else {
608 - fp = tree_pkg_vdb_fopenat_ro(pkg_ctx, "CONTENTS");
609 - }
610 - if (fp == NULL)
611 + if ((contents = tree_pkg_meta_get(pkg_ctx, CONTENTS)) == NULL)
612 return 1;
613
614 - while (getline(&state->buf, &state->buflen, fp) != -1) {
615 + while ((line = strtok(contents, "\n")) != NULL) {
616 contents_entry *e;
617
618 - e = contents_parse_line(state->buf);
619 + contents = NULL; /* for strtok */
620 +
621 + e = contents_parse_line(line);
622 if (!e)
623 continue;
624
625 @@ -455,9 +401,6 @@ qlist_cb(tree_pkg_ctx *pkg_ctx, void *priv)
626 break;
627 }
628 }
629 - fclose(fp);
630 - if (state->do_binpkgs && cbctx.retdata != NULL)
631 - free(cbctx.retdata);
632
633 return 1;
634 }
635
636 diff --git a/qsearch.c b/qsearch.c
637 index d6470f6..a26e2d6 100644
638 --- a/qsearch.c
639 +++ b/qsearch.c
640 @@ -66,7 +66,6 @@ qsearch_cb(tree_pkg_ctx *pkg_ctx, void *priv)
641
642 struct qsearch_state *state = (struct qsearch_state *)priv;
643 depend_atom *atom;
644 - tree_pkg_meta *meta;
645 char *desc;
646 bool match;
647
648 @@ -84,17 +83,13 @@ qsearch_cb(tree_pkg_ctx *pkg_ctx, void *priv)
649 match = true;
650
651 desc = NULL;
652 - meta = NULL;
653 if ((match && (state->show_homepage || state->show_desc)) ||
654 (!match && state->search_desc))
655 {
656 - meta = tree_pkg_read(pkg_ctx);
657 - if (meta != NULL) {
658 - if (state->show_homepage)
659 - desc = meta->HOMEPAGE;
660 - else if (state->show_desc)
661 - desc = meta->DESCRIPTION;
662 - }
663 + if (state->show_homepage)
664 + desc = tree_pkg_meta_get(pkg_ctx, HOMEPAGE);
665 + else if (state->show_desc)
666 + desc = tree_pkg_meta_get(pkg_ctx, DESCRIPTION);
667 }
668
669 if (!match && state->search_desc && desc != NULL &&
670 @@ -109,9 +104,6 @@ qsearch_cb(tree_pkg_ctx *pkg_ctx, void *priv)
671 (state->show_name ? "" : desc ? desc : ""));
672 }
673
674 - if (meta != NULL)
675 - tree_close_meta(meta);
676 -
677 if (last_atom != NULL)
678 atom_implode(last_atom);
679 last_atom = atom;
680
681 diff --git a/quse.c b/quse.c
682 index df8626e..be34e48 100644
683 --- a/quse.c
684 +++ b/quse.c
685 @@ -412,7 +412,6 @@ quse_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
686 struct quse_state *state = (struct quse_state *)priv;
687 depend_atom *atom = NULL; /* pacify compiler */
688 char buf[8192];
689 - tree_pkg_meta *meta;
690 set *use = NULL;
691 bool match;
692 char *p;
693 @@ -439,52 +438,38 @@ quse_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
694 }
695 }
696
697 - if (state->overlay != NULL) {
698 - meta = tree_pkg_read(pkg_ctx);
699 - if (meta == NULL)
700 + if (!state->do_licence) {
701 + if (tree_pkg_meta_get(pkg_ctx, IUSE) == NULL)
702 return 0;
703 - if (meta->IUSE == NULL)
704 - return 0;
705 - } else {
706 - size_t dummy;
707 -
708 - meta = xzalloc(sizeof(*meta));
709
710 - dummy = 0;
711 - if (!tree_pkg_vdb_eat(pkg_ctx, "IUSE", &meta->IUSE, &dummy)) {
712 - free(meta);
713 - return 0;
714 + if (state->do_describe) {
715 + portdirfd = openat(pkg_ctx->cat_ctx->ctx->portroot_fd,
716 + state->overlay == NULL ? main_overlay : state->overlay,
717 + O_RDONLY | O_CLOEXEC | O_PATH);
718 + if (portdirfd == -1)
719 + return 0;
720 }
721
722 - dummy = 0;
723 - tree_pkg_vdb_eat(pkg_ctx, "LICENSE", &meta->LICENSE, &dummy);
724 -
725 - s = NULL;
726 - dummy = 0;
727 - tree_pkg_vdb_eat(pkg_ctx, "USE", &s, &dummy);
728 - p = s;
729 - while ((q = strchr(p, (int)' ')) != NULL) {
730 - *q++ = '\0';
731 - use = add_set(p, use);
732 - p = q;
733 + /* available when dealing with VDB or binpkgs */
734 + if ((p = tree_pkg_meta_get(pkg_ctx, USE)) != NULL) {
735 + while ((q = strchr(p, (int)' ')) != NULL) {
736 + *q++ = '\0';
737 + use = add_set(p, use);
738 + p = q;
739 + }
740 + if (*p != '\0')
741 + use = add_set(p, use);
742 }
743 - if (*p != '\0')
744 - use = add_set(p, use);
745 - free(s);
746 - }
747 -
748 - if (state->do_describe) {
749 - portdirfd = openat(pkg_ctx->cat_ctx->ctx->portroot_fd,
750 - state->overlay == NULL ? main_overlay : state->overlay,
751 - O_RDONLY | O_CLOEXEC | O_PATH);
752 - if (portdirfd == -1)
753 + } else {
754 + if (tree_pkg_meta_get(pkg_ctx, LICENSE) == NULL)
755 return 0;
756 }
757
758 maxlen = 0;
759 cnt = 0;
760 match = false;
761 - q = p = state->do_licence ? meta->LICENSE : meta->IUSE;
762 + q = p = state->do_licence ?
763 + tree_pkg_meta_get(pkg_ctx, LICENSE) : tree_pkg_meta_get(pkg_ctx, IUSE);
764 buf[0] = '\0';
765 v = buf;
766 w = buf + sizeof(buf);
767 @@ -567,7 +552,7 @@ quse_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
768
769 printf("%s\n", atom_format(state->fmt, atom));
770
771 - q = p = meta->IUSE;
772 + q = p = tree_pkg_meta_get(pkg_ctx, IUSE);
773 buf[0] = '\0';
774 v = buf;
775 w = buf + sizeof(buf);
776 @@ -652,16 +637,8 @@ quse_results_cb(tree_pkg_ctx *pkg_ctx, void *priv)
777 }
778 }
779
780 - if (state->overlay != NULL) {
781 - tree_close_meta(meta);
782 - } else {
783 - free(meta->IUSE);
784 - if (meta->LICENSE != NULL)
785 - free(meta->LICENSE);
786 - free(meta);
787 - if (use != NULL)
788 - free_set(use);
789 - }
790 + if (use != NULL)
791 + free_set(use);
792 if (state->do_describe)
793 close(portdirfd);