1 |
commit: 7cf702111a7350b17443f4d9d0d76138b503dac3 |
2 |
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu May 9 20:17:46 2019 +0000 |
4 |
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu May 9 20:17:46 2019 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=7cf70211 |
7 |
|
8 |
libq/tree: merge vdb and cache |
9 |
|
10 |
since cache was basically a shadow of vdb, and vdb grew too many |
11 |
non-vdb-like behaviour, renamed to tree such that further features only |
12 |
have to be implemented once |
13 |
|
14 |
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org> |
15 |
|
16 |
TODO.md | 7 +- |
17 |
libq/Makefile.am | 3 +- |
18 |
libq/Makefile.in | 31 +- |
19 |
libq/cache.c | 687 ----------------------------------- |
20 |
libq/cache.h | 74 ---- |
21 |
libq/tree.c | 1066 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
22 |
libq/tree.h | 141 ++++++++ |
23 |
libq/vdb.c | 515 -------------------------- |
24 |
libq/vdb.h | 96 ----- |
25 |
main.c | 20 - |
26 |
q.c | 2 - |
27 |
qcheck.c | 37 +- |
28 |
qdepends.c | 22 +- |
29 |
qfile.c | 19 +- |
30 |
qgrep.c | 29 +- |
31 |
qkeyword.c | 43 ++- |
32 |
qlist.c | 35 +- |
33 |
qmerge.c | 66 ++-- |
34 |
qpkg.c | 30 +- |
35 |
qsearch.c | 20 +- |
36 |
qsize.c | 13 +- |
37 |
quse.c | 17 +- |
38 |
22 files changed, 1419 insertions(+), 1554 deletions(-) |
39 |
|
40 |
diff --git a/TODO.md b/TODO.md |
41 |
index 3333fd6..ec5f843 100644 |
42 |
--- a/TODO.md |
43 |
+++ b/TODO.md |
44 |
@@ -23,10 +23,11 @@ |
45 |
we end up getting just:<br> |
46 |
`ACCEPT_LICENSE=" bar"` |
47 |
|
48 |
-- vdb\_foreach\_pkg should have variant that takes an atom (or just |
49 |
- cat?) to reduce search space, same for cache\_foreach\_pkg |
50 |
+- tree\_foreach\_pkg should have variant that takes an atom (or just |
51 |
+ cat?) to reduce search space |
52 |
|
53 |
-- vdb repo/slot think about when it is freed (see cache\_pkg\_close) |
54 |
+- tree\_get\_atoms should return atoms iso string set, needs a rewrite |
55 |
+ to use foreach\_pkg and get\_atom |
56 |
|
57 |
# Atoms |
58 |
|
59 |
|
60 |
diff --git a/libq/Makefile.am b/libq/Makefile.am |
61 |
index 765347f..62ffb83 100644 |
62 |
--- a/libq/Makefile.am |
63 |
+++ b/libq/Makefile.am |
64 |
@@ -3,7 +3,6 @@ QFILES = \ |
65 |
atom.c atom.h \ |
66 |
basename.c basename.h \ |
67 |
busybox.h \ |
68 |
- cache.c cache.h \ |
69 |
colors.c colors.h \ |
70 |
contents.c contents.h \ |
71 |
copy_file.c copy_file.h \ |
72 |
@@ -19,7 +18,7 @@ QFILES = \ |
73 |
safe_io.c safe_io.h \ |
74 |
scandirat.c scandirat.h \ |
75 |
set.c set.h \ |
76 |
- vdb.c vdb.h \ |
77 |
+ tree.c tree.h \ |
78 |
xarray.c xarray.h \ |
79 |
xasprintf.h \ |
80 |
xchdir.c xchdir.h \ |
81 |
|
82 |
diff --git a/libq/Makefile.in b/libq/Makefile.in |
83 |
index 5f118fc..c359f4b 100644 |
84 |
--- a/libq/Makefile.in |
85 |
+++ b/libq/Makefile.in |
86 |
@@ -241,13 +241,13 @@ CONFIG_CLEAN_FILES = |
87 |
CONFIG_CLEAN_VPATH_FILES = |
88 |
LTLIBRARIES = $(noinst_LTLIBRARIES) |
89 |
libq_la_LIBADD = |
90 |
-am__objects_1 = libq_la-atom.lo libq_la-basename.lo libq_la-cache.lo \ |
91 |
- libq_la-colors.lo libq_la-contents.lo libq_la-copy_file.lo \ |
92 |
- libq_la-dep.lo libq_la-eat_file.lo libq_la-hash_fd.lo \ |
93 |
+am__objects_1 = libq_la-atom.lo libq_la-basename.lo libq_la-colors.lo \ |
94 |
+ libq_la-contents.lo libq_la-copy_file.lo libq_la-dep.lo \ |
95 |
+ libq_la-eat_file.lo libq_la-hash_fd.lo \ |
96 |
libq_la-human_readable.lo libq_la-md5_sha1_sum.lo \ |
97 |
libq_la-prelink.lo libq_la-profile.lo libq_la-rmspace.lo \ |
98 |
libq_la-safe_io.lo libq_la-scandirat.lo libq_la-set.lo \ |
99 |
- libq_la-vdb.lo libq_la-xarray.lo libq_la-xchdir.lo \ |
100 |
+ libq_la-tree.lo libq_la-xarray.lo libq_la-xchdir.lo \ |
101 |
libq_la-xmkdir.lo libq_la-xpak.lo libq_la-xregex.lo \ |
102 |
libq_la-xsystem.lo |
103 |
am_libq_la_OBJECTS = $(am__objects_1) |
104 |
@@ -1447,7 +1447,6 @@ QFILES = \ |
105 |
atom.c atom.h \ |
106 |
basename.c basename.h \ |
107 |
busybox.h \ |
108 |
- cache.c cache.h \ |
109 |
colors.c colors.h \ |
110 |
contents.c contents.h \ |
111 |
copy_file.c copy_file.h \ |
112 |
@@ -1463,7 +1462,7 @@ QFILES = \ |
113 |
safe_io.c safe_io.h \ |
114 |
scandirat.c scandirat.h \ |
115 |
set.c set.h \ |
116 |
- vdb.c vdb.h \ |
117 |
+ tree.c tree.h \ |
118 |
xarray.c xarray.h \ |
119 |
xasprintf.h \ |
120 |
xchdir.c xchdir.h \ |
121 |
@@ -1535,7 +1534,6 @@ distclean-compile: |
122 |
|
123 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-atom.Plo@am__quote@ |
124 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-basename.Plo@am__quote@ |
125 |
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-cache.Plo@am__quote@ |
126 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-colors.Plo@am__quote@ |
127 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-contents.Plo@am__quote@ |
128 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-copy_file.Plo@am__quote@ |
129 |
@@ -1550,7 +1548,7 @@ distclean-compile: |
130 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-safe_io.Plo@am__quote@ |
131 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-scandirat.Plo@am__quote@ |
132 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-set.Plo@am__quote@ |
133 |
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-vdb.Plo@am__quote@ |
134 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-tree.Plo@am__quote@ |
135 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-xarray.Plo@am__quote@ |
136 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-xchdir.Plo@am__quote@ |
137 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-xmkdir.Plo@am__quote@ |
138 |
@@ -1593,13 +1591,6 @@ libq_la-basename.lo: basename.c |
139 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
140 |
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libq_la-basename.lo `test -f 'basename.c' || echo '$(srcdir)/'`basename.c |
141 |
|
142 |
-libq_la-cache.lo: cache.c |
143 |
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libq_la-cache.lo -MD -MP -MF $(DEPDIR)/libq_la-cache.Tpo -c -o libq_la-cache.lo `test -f 'cache.c' || echo '$(srcdir)/'`cache.c |
144 |
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libq_la-cache.Tpo $(DEPDIR)/libq_la-cache.Plo |
145 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cache.c' object='libq_la-cache.lo' libtool=yes @AMDEPBACKSLASH@ |
146 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
147 |
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libq_la-cache.lo `test -f 'cache.c' || echo '$(srcdir)/'`cache.c |
148 |
- |
149 |
libq_la-colors.lo: colors.c |
150 |
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libq_la-colors.lo -MD -MP -MF $(DEPDIR)/libq_la-colors.Tpo -c -o libq_la-colors.lo `test -f 'colors.c' || echo '$(srcdir)/'`colors.c |
151 |
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libq_la-colors.Tpo $(DEPDIR)/libq_la-colors.Plo |
152 |
@@ -1698,12 +1689,12 @@ libq_la-set.lo: set.c |
153 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
154 |
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libq_la-set.lo `test -f 'set.c' || echo '$(srcdir)/'`set.c |
155 |
|
156 |
-libq_la-vdb.lo: vdb.c |
157 |
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libq_la-vdb.lo -MD -MP -MF $(DEPDIR)/libq_la-vdb.Tpo -c -o libq_la-vdb.lo `test -f 'vdb.c' || echo '$(srcdir)/'`vdb.c |
158 |
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libq_la-vdb.Tpo $(DEPDIR)/libq_la-vdb.Plo |
159 |
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vdb.c' object='libq_la-vdb.lo' libtool=yes @AMDEPBACKSLASH@ |
160 |
+libq_la-tree.lo: tree.c |
161 |
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libq_la-tree.lo -MD -MP -MF $(DEPDIR)/libq_la-tree.Tpo -c -o libq_la-tree.lo `test -f 'tree.c' || echo '$(srcdir)/'`tree.c |
162 |
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libq_la-tree.Tpo $(DEPDIR)/libq_la-tree.Plo |
163 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tree.c' object='libq_la-tree.lo' libtool=yes @AMDEPBACKSLASH@ |
164 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
165 |
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libq_la-vdb.lo `test -f 'vdb.c' || echo '$(srcdir)/'`vdb.c |
166 |
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libq_la-tree.lo `test -f 'tree.c' || echo '$(srcdir)/'`tree.c |
167 |
|
168 |
libq_la-xarray.lo: xarray.c |
169 |
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libq_la-xarray.lo -MD -MP -MF $(DEPDIR)/libq_la-xarray.Tpo -c -o libq_la-xarray.lo `test -f 'xarray.c' || echo '$(srcdir)/'`xarray.c |
170 |
|
171 |
diff --git a/libq/cache.c b/libq/cache.c |
172 |
deleted file mode 100644 |
173 |
index 304cd34..0000000 |
174 |
--- a/libq/cache.c |
175 |
+++ /dev/null |
176 |
@@ -1,687 +0,0 @@ |
177 |
-/* |
178 |
- * Copyright 2005-2019 Gentoo Foundation |
179 |
- * Distributed under the terms of the GNU General Public License v2 |
180 |
- * |
181 |
- * Copyright 2005-2008 Ned Ludd - <solar@g.o> |
182 |
- * Copyright 2005-2014 Mike Frysinger - <vapier@g.o> |
183 |
- * Copyright 2018- Fabian Groffen - <grobian@g.o> |
184 |
- */ |
185 |
- |
186 |
-#include "main.h" |
187 |
- |
188 |
-#include <fcntl.h> |
189 |
-#include <sys/types.h> |
190 |
-#include <sys/stat.h> |
191 |
-#include <ctype.h> |
192 |
-#include <xalloc.h> |
193 |
- |
194 |
-#include "cache.h" |
195 |
-#include "eat_file.h" |
196 |
-#include "rmspace.h" |
197 |
-#include "scandirat.h" |
198 |
-#include "vdb.h" |
199 |
- |
200 |
-#ifdef EBUG |
201 |
-static void |
202 |
-cache_dump(cache_pkg_meta *cache) |
203 |
-{ |
204 |
- if (!cache) |
205 |
- errf("Cache is empty !"); |
206 |
- |
207 |
- printf("DEPEND : %s\n", cache->DEPEND); |
208 |
- printf("RDEPEND : %s\n", cache->RDEPEND); |
209 |
- printf("SLOT : %s\n", cache->SLOT); |
210 |
- printf("SRC_URI : %s\n", cache->SRC_URI); |
211 |
- printf("RESTRICT : %s\n", cache->RESTRICT); |
212 |
- printf("HOMEPAGE : %s\n", cache->HOMEPAGE); |
213 |
- printf("LICENSE : %s\n", cache->LICENSE); |
214 |
- printf("DESCRIPTION: %s\n", cache->DESCRIPTION); |
215 |
- printf("KEYWORDS : %s\n", cache->KEYWORDS); |
216 |
- printf("INHERITED : %s\n", cache->INHERITED); |
217 |
- printf("IUSE : %s\n", cache->IUSE); |
218 |
- printf("CDEPEND : %s\n", cache->CDEPEND); |
219 |
- printf("PDEPEND : %s\n", cache->PDEPEND); |
220 |
- printf("PROVIDE : %s\n", cache->PROVIDE); |
221 |
- printf("EAPI : %s\n", cache->EAPI); |
222 |
- printf("PROPERTIES : %s\n", cache->PROPERTIES); |
223 |
-} |
224 |
-#endif |
225 |
- |
226 |
-static const char portcachedir_pms[] = "metadata/cache"; |
227 |
-static const char portcachedir_md5[] = "metadata/md5-cache"; |
228 |
-static const char portrepo_name[] = "profiles/repo_name"; |
229 |
-cache_ctx * |
230 |
-cache_open(const char *sroot, const char *portdir) |
231 |
-{ |
232 |
- cache_ctx *ret; |
233 |
- char buf[_Q_PATH_MAX]; |
234 |
- char *repo = NULL; |
235 |
- size_t repolen = 0; |
236 |
- |
237 |
- snprintf(buf, sizeof(buf), "%s%s/%s", sroot, portdir, portrepo_name); |
238 |
- if (eat_file(buf, &repo, &repolen)) { |
239 |
- (void)rmspace(repo); |
240 |
- } else { |
241 |
- repo = NULL; /* ignore missing repo file */ |
242 |
- } |
243 |
- |
244 |
- snprintf(buf, sizeof(buf), "%s/%s", portdir, portcachedir_md5); |
245 |
- ret = vdb_open2(sroot, buf, true); |
246 |
- if (ret != NULL) { |
247 |
- ret->cachetype = CACHE_METADATA_MD5; |
248 |
- ret->repo = repo; |
249 |
- return ret; |
250 |
- } |
251 |
- |
252 |
- snprintf(buf, sizeof(buf), "%s/%s", portdir, portcachedir_pms); |
253 |
- ret = vdb_open2(sroot, buf, true); |
254 |
- if (ret != NULL) { |
255 |
- ret->cachetype = CACHE_METADATA_PMS; |
256 |
- ret->repo = repo; |
257 |
- return ret; |
258 |
- } |
259 |
- |
260 |
- ret = vdb_open2(sroot, portdir, true); |
261 |
- if (ret != NULL) { |
262 |
- ret->cachetype = CACHE_EBUILD; |
263 |
- ret->repo = repo; |
264 |
- return ret; |
265 |
- } |
266 |
- |
267 |
- cache_close(ret); |
268 |
- warnf("could not open repository at %s (under root %s)", portdir, sroot); |
269 |
- |
270 |
- return NULL; |
271 |
-} |
272 |
- |
273 |
-void |
274 |
-cache_close(cache_ctx *ctx) |
275 |
-{ |
276 |
- if (ctx->repo != NULL) |
277 |
- free(ctx->repo); |
278 |
- if (ctx->ebuilddir_ctx != NULL) |
279 |
- free(ctx->ebuilddir_ctx); |
280 |
- vdb_close(ctx); |
281 |
-} |
282 |
- |
283 |
-cache_cat_ctx * |
284 |
-cache_open_cat(cache_ctx *ctx, const char *name) |
285 |
-{ |
286 |
- return vdb_open_cat(ctx, name); |
287 |
-} |
288 |
- |
289 |
-cache_cat_ctx * |
290 |
-cache_next_cat(cache_ctx *ctx) |
291 |
-{ |
292 |
- return vdb_next_cat(ctx); |
293 |
-} |
294 |
- |
295 |
-void |
296 |
-cache_close_cat(cache_cat_ctx *cat_ctx) |
297 |
-{ |
298 |
- return vdb_close_cat(cat_ctx); |
299 |
-} |
300 |
- |
301 |
-cache_pkg_ctx * |
302 |
-cache_open_pkg(cache_cat_ctx *cat_ctx, const char *name) |
303 |
-{ |
304 |
- return vdb_open_pkg(cat_ctx, name); |
305 |
-} |
306 |
- |
307 |
-cache_pkg_ctx * |
308 |
-cache_next_pkg(cache_cat_ctx *cat_ctx) |
309 |
-{ |
310 |
- cache_ctx *ctx = (cache_ctx *)cat_ctx->ctx; |
311 |
- cache_pkg_ctx *ret = NULL; |
312 |
- |
313 |
- if (ctx->cachetype == CACHE_EBUILD) { |
314 |
- char *p; |
315 |
- |
316 |
- /* serve *.ebuild files each as separate pkg_ctx with name set |
317 |
- * to CAT/P like in VDB and metadata */ |
318 |
- do { |
319 |
- if (ctx->ebuilddir_pkg_ctx == NULL) { |
320 |
- vdb_ctx *pkgdir = ctx->ebuilddir_ctx; |
321 |
- |
322 |
- if (pkgdir == NULL) |
323 |
- pkgdir = ctx->ebuilddir_ctx = xmalloc(sizeof(vdb_ctx)); |
324 |
- memset(ctx->ebuilddir_ctx, '\0', sizeof(*ctx->ebuilddir_ctx)); |
325 |
- |
326 |
- if ((ctx->ebuilddir_pkg_ctx = vdb_next_pkg(cat_ctx)) == NULL) |
327 |
- return NULL; |
328 |
- |
329 |
- pkgdir->portroot_fd = -1; |
330 |
- pkgdir->vdb_fd = cat_ctx->fd; |
331 |
- pkgdir->do_sort = ctx->do_sort; |
332 |
- pkgdir->catsortfunc = ctx->catsortfunc; |
333 |
- pkgdir->pkgsortfunc = ctx->pkgsortfunc; |
334 |
- pkgdir->repo = ctx->repo; |
335 |
- pkgdir->cachetype = ctx->cachetype; |
336 |
- |
337 |
- ctx->ebuilddir_cat_ctx = |
338 |
- vdb_open_cat(pkgdir, ctx->ebuilddir_pkg_ctx->name); |
339 |
- |
340 |
- /* opening might fail if what we found wasn't a |
341 |
- * directory or something */ |
342 |
- if (ctx->ebuilddir_cat_ctx == NULL) { |
343 |
- ctx->ebuilddir_pkg_ctx = NULL; |
344 |
- return NULL; |
345 |
- } |
346 |
- |
347 |
- /* "zap" the pkg such that it looks like CAT/P */ |
348 |
- ctx->ebuilddir_cat_ctx->name = cat_ctx->name; |
349 |
- } |
350 |
- |
351 |
- ret = vdb_next_pkg(ctx->ebuilddir_cat_ctx); |
352 |
- if (ret == NULL) { |
353 |
- vdb_close_cat(ctx->ebuilddir_cat_ctx); |
354 |
- ctx->ebuilddir_pkg_ctx = NULL; |
355 |
- } else { |
356 |
- if ((p = strstr(ret->name, ".ebuild")) == NULL) { |
357 |
- cache_close_pkg(ret); |
358 |
- ret = NULL; |
359 |
- } else { |
360 |
- *p = '\0'; |
361 |
- } |
362 |
- } |
363 |
- } while (ret == NULL); |
364 |
- } else { |
365 |
- ret = vdb_next_pkg(cat_ctx); |
366 |
- } |
367 |
- |
368 |
- return ret; |
369 |
-} |
370 |
- |
371 |
-static cache_pkg_meta * |
372 |
-cache_read_file_pms(cache_pkg_ctx *pkg_ctx) |
373 |
-{ |
374 |
- struct stat s; |
375 |
- char *ptr; |
376 |
- FILE *f; |
377 |
- cache_pkg_meta *ret = NULL; |
378 |
- size_t len; |
379 |
- char buf[_Q_PATH_MAX]; |
380 |
- |
381 |
- if ((f = fdopen(pkg_ctx->fd, "r")) == NULL) |
382 |
- goto err; |
383 |
- |
384 |
- if (fstat(pkg_ctx->fd, &s) != 0) |
385 |
- goto err; |
386 |
- |
387 |
- len = sizeof(*ret) + s.st_size + 1; |
388 |
- ret = xzalloc(len); |
389 |
- ptr = (char*)ret; |
390 |
- ret->_data = ptr + sizeof(*ret); |
391 |
- if ((off_t)fread(ret->_data, 1, s.st_size, f) != s.st_size) |
392 |
- goto err; |
393 |
- |
394 |
- ret->DEPEND = ret->_data; |
395 |
-#define next_line(curr, next) \ |
396 |
- if ((ptr = strchr(ret->curr, '\n')) == NULL) { \ |
397 |
- warn("Invalid cache file for '%s'", buf); \ |
398 |
- goto err; \ |
399 |
- } \ |
400 |
- ret->next = ptr+1; \ |
401 |
- *ptr = '\0'; |
402 |
- next_line(DEPEND, RDEPEND) |
403 |
- next_line(RDEPEND, SLOT) |
404 |
- next_line(SLOT, SRC_URI) |
405 |
- next_line(SRC_URI, RESTRICT) |
406 |
- next_line(RESTRICT, HOMEPAGE) |
407 |
- next_line(HOMEPAGE, LICENSE) |
408 |
- next_line(LICENSE, DESCRIPTION) |
409 |
- next_line(DESCRIPTION, KEYWORDS) |
410 |
- next_line(KEYWORDS, INHERITED) |
411 |
- next_line(INHERITED, IUSE) |
412 |
- next_line(IUSE, CDEPEND) |
413 |
- next_line(CDEPEND, PDEPEND) |
414 |
- next_line(PDEPEND, PROVIDE) |
415 |
- next_line(PROVIDE, EAPI) |
416 |
- next_line(EAPI, PROPERTIES) |
417 |
-#undef next_line |
418 |
- ptr = strchr(ptr+1, '\n'); |
419 |
- if (ptr == NULL) { |
420 |
- warn("Invalid cache file for '%s' - could not find end of cache data", |
421 |
- buf); |
422 |
- goto err; |
423 |
- } |
424 |
- *ptr = '\0'; |
425 |
- |
426 |
- fclose(f); |
427 |
- pkg_ctx->fd = -1; |
428 |
- |
429 |
- return ret; |
430 |
- |
431 |
-err: |
432 |
- if (f) |
433 |
- fclose(f); |
434 |
- pkg_ctx->fd = -1; |
435 |
- if (ret) |
436 |
- cache_close_meta(ret); |
437 |
- return NULL; |
438 |
-} |
439 |
- |
440 |
-static cache_pkg_meta * |
441 |
-cache_read_file_md5(cache_pkg_ctx *pkg_ctx) |
442 |
-{ |
443 |
- struct stat s; |
444 |
- char *ptr, *endptr; |
445 |
- FILE *f; |
446 |
- cache_pkg_meta *ret = NULL; |
447 |
- size_t len; |
448 |
- |
449 |
- if ((f = fdopen(pkg_ctx->fd, "r")) == NULL) |
450 |
- goto err; |
451 |
- |
452 |
- if (fstat(pkg_ctx->fd, &s) != 0) |
453 |
- goto err; |
454 |
- |
455 |
- len = sizeof(*ret) + s.st_size + 1; |
456 |
- ret = xzalloc(len); |
457 |
- ptr = (char*)ret; |
458 |
- ret->_data = ptr + sizeof(*ret); |
459 |
- if ((off_t)fread(ret->_data, 1, s.st_size, f) != s.st_size) |
460 |
- goto err; |
461 |
- |
462 |
- /* We have a block of key=value\n data. |
463 |
- * KEY=VALUE\n |
464 |
- * Where KEY does NOT contain: |
465 |
- * \0 \n = |
466 |
- * And VALUE does NOT contain: |
467 |
- * \0 \n |
468 |
- * */ |
469 |
-#define assign_var_cmp(keyname, cmpkey) \ |
470 |
- if (strncmp(keyptr, cmpkey, strlen(cmpkey)) == 0) { \ |
471 |
- ret->keyname = valptr; \ |
472 |
- continue; \ |
473 |
- } |
474 |
-#define assign_var(keyname) \ |
475 |
- assign_var_cmp(keyname, #keyname); |
476 |
- |
477 |
- ptr = ret->_data; |
478 |
- endptr = strchr(ptr, '\0'); |
479 |
- if (endptr == NULL) { |
480 |
- warn("Invalid cache file for '%s/%s': " |
481 |
- "could not find end of cache data", |
482 |
- pkg_ctx->cat_ctx->name, pkg_ctx->name); |
483 |
- goto err; |
484 |
- } |
485 |
- |
486 |
- while (ptr != NULL && ptr != endptr) { |
487 |
- char *keyptr; |
488 |
- char *valptr; |
489 |
- keyptr = ptr; |
490 |
- valptr = strchr(ptr, '='); |
491 |
- if (valptr == NULL) { |
492 |
- warn("Invalid cache file for '%s/%s': missing val", |
493 |
- pkg_ctx->cat_ctx->name, pkg_ctx->name); |
494 |
- goto err; |
495 |
- } |
496 |
- *valptr = '\0'; |
497 |
- valptr++; |
498 |
- ptr = strchr(valptr, '\n'); |
499 |
- if (ptr == NULL) { |
500 |
- warn("Invalid cache file for '%s/%s': missing key", |
501 |
- pkg_ctx->cat_ctx->name, pkg_ctx->name); |
502 |
- goto err; |
503 |
- } |
504 |
- *ptr = '\0'; |
505 |
- ptr++; |
506 |
- |
507 |
- assign_var(CDEPEND); |
508 |
- assign_var(DEPEND); |
509 |
- assign_var(DESCRIPTION); |
510 |
- assign_var(EAPI); |
511 |
- assign_var(HOMEPAGE); |
512 |
- assign_var(INHERITED); |
513 |
- assign_var(IUSE); |
514 |
- assign_var(KEYWORDS); |
515 |
- assign_var(LICENSE); |
516 |
- assign_var(PDEPEND); |
517 |
- assign_var(PROPERTIES); |
518 |
- assign_var(PROVIDE); |
519 |
- assign_var(RDEPEND); |
520 |
- assign_var(RESTRICT); |
521 |
- assign_var(SLOT); |
522 |
- assign_var(SRC_URI); |
523 |
- assign_var(DEFINED_PHASES); |
524 |
- assign_var(REQUIRED_USE); |
525 |
- assign_var(BDEPEND); |
526 |
- assign_var(_eclasses_); |
527 |
- assign_var(_md5_); |
528 |
- warn("Cache file for '%s/%s' has unknown key %s", |
529 |
- pkg_ctx->cat_ctx->name, pkg_ctx->name, keyptr); |
530 |
- } |
531 |
-#undef assign_var |
532 |
-#undef assign_var_cmp |
533 |
- |
534 |
- fclose(f); |
535 |
- pkg_ctx->fd = -1; |
536 |
- |
537 |
- return ret; |
538 |
- |
539 |
-err: |
540 |
- if (f) |
541 |
- fclose(f); |
542 |
- pkg_ctx->fd = -1; |
543 |
- if (ret) |
544 |
- cache_close_meta(ret); |
545 |
- return NULL; |
546 |
-} |
547 |
- |
548 |
-static cache_pkg_meta * |
549 |
-cache_read_file_ebuild(cache_pkg_ctx *pkg_ctx) |
550 |
-{ |
551 |
- FILE *f; |
552 |
- struct stat s; |
553 |
- cache_pkg_meta *ret = NULL; |
554 |
- size_t len; |
555 |
- char *p; |
556 |
- char *q; |
557 |
- char *w; |
558 |
- char **key; |
559 |
- bool esc; |
560 |
- bool findnl; |
561 |
- |
562 |
- if ((f = fdopen(pkg_ctx->fd, "r")) == NULL) |
563 |
- goto err; |
564 |
- |
565 |
- if (fstat(pkg_ctx->fd, &s) != 0) |
566 |
- goto err; |
567 |
- |
568 |
- len = sizeof(*ret) + s.st_size + 1; |
569 |
- ret = xzalloc(len); |
570 |
- p = (char *)ret; |
571 |
- ret->_data = p + sizeof(*ret); |
572 |
- if ((off_t)fread(ret->_data, 1, s.st_size, f) != s.st_size) |
573 |
- goto err; |
574 |
- |
575 |
- p = ret->_data; |
576 |
- do { |
577 |
- q = p; |
578 |
- while (*p >= 'A' && *p <= 'Z') |
579 |
- p++; |
580 |
- |
581 |
- key = NULL; |
582 |
- if (q < p && *p == '=') { |
583 |
- *p++ = '\0'; |
584 |
- /* match variable against which ones we look for */ |
585 |
-#define match_key(X) else if (strcmp(q, #X) == 0) key = &ret->X |
586 |
- if (1 == 0); /* dummy for syntax */ |
587 |
- match_key(DEPEND); |
588 |
- match_key(RDEPEND); |
589 |
- match_key(SLOT); |
590 |
- match_key(SRC_URI); |
591 |
- match_key(RESTRICT); |
592 |
- match_key(HOMEPAGE); |
593 |
- match_key(LICENSE); |
594 |
- match_key(DESCRIPTION); |
595 |
- match_key(KEYWORDS); |
596 |
- match_key(IUSE); |
597 |
- match_key(CDEPEND); |
598 |
- match_key(PDEPEND); |
599 |
- match_key(EAPI); |
600 |
- match_key(REQUIRED_USE); |
601 |
-#undef match_key |
602 |
- } |
603 |
- |
604 |
- findnl = true; |
605 |
- if (key != NULL) { |
606 |
- q = p; |
607 |
- if (*q == '"' || *q == '\'') { |
608 |
- /* find matching quote */ |
609 |
- p++; |
610 |
- w = p; |
611 |
- esc = false; |
612 |
- do { |
613 |
- while (*p != '\0' && *p != *q) { |
614 |
- if (*p == '\\') { |
615 |
- esc = !esc; |
616 |
- if (esc) { |
617 |
- p++; |
618 |
- continue; |
619 |
- } |
620 |
- } else { |
621 |
- /* implement line continuation (\ before newline) */ |
622 |
- if (esc && (*p == '\n' || *p == '\r')) |
623 |
- *p = ' '; |
624 |
- esc = false; |
625 |
- } |
626 |
- |
627 |
- *w++ = *p++; |
628 |
- } |
629 |
- if (*p == *q && esc) { |
630 |
- /* escaped, move along */ |
631 |
- esc = false; |
632 |
- *w++ = *p++; |
633 |
- continue; |
634 |
- } |
635 |
- break; |
636 |
- } while (1); |
637 |
- q++; |
638 |
- *w = '\0'; |
639 |
- } else { |
640 |
- /* find first whitespace */ |
641 |
- while (!isspace((int)*p)) |
642 |
- p++; |
643 |
- if (*p == '\n') |
644 |
- findnl = false; |
645 |
- } |
646 |
- *p++ = '\0'; |
647 |
- *key = q; |
648 |
- } |
649 |
- |
650 |
- if (findnl && (p = strchr(p, '\n')) != NULL) |
651 |
- p++; |
652 |
- } while (p != NULL); |
653 |
- |
654 |
- fclose(f); |
655 |
- pkg_ctx->fd = -1; |
656 |
- |
657 |
- return ret; |
658 |
- |
659 |
-err: |
660 |
- if (f) |
661 |
- fclose(f); |
662 |
- pkg_ctx->fd = -1; |
663 |
- if (ret) |
664 |
- cache_close_meta(ret); |
665 |
- return NULL; |
666 |
-} |
667 |
- |
668 |
-cache_pkg_meta * |
669 |
-cache_pkg_read(cache_pkg_ctx *pkg_ctx) |
670 |
-{ |
671 |
- cache_ctx *ctx = (cache_ctx *)(pkg_ctx->cat_ctx->ctx); |
672 |
- |
673 |
- if (pkg_ctx->fd == -1) { |
674 |
- if (ctx->cachetype != CACHE_EBUILD) { |
675 |
- pkg_ctx->fd = openat(pkg_ctx->cat_ctx->fd, pkg_ctx->name, |
676 |
- O_RDONLY|O_CLOEXEC); |
677 |
- } else { |
678 |
- char *p = (char *)pkg_ctx->name; |
679 |
- p += strlen(p); |
680 |
- *p = '.'; |
681 |
- pkg_ctx->fd = openat(pkg_ctx->cat_ctx->fd, pkg_ctx->name, |
682 |
- O_RDONLY|O_CLOEXEC); |
683 |
- *p = '\0'; |
684 |
- } |
685 |
- if (pkg_ctx->fd == -1) |
686 |
- return NULL; |
687 |
- } |
688 |
- |
689 |
- if (ctx->cachetype == CACHE_METADATA_MD5) { |
690 |
- return cache_read_file_md5(pkg_ctx); |
691 |
- } else if (ctx->cachetype == CACHE_METADATA_PMS) { |
692 |
- return cache_read_file_pms(pkg_ctx); |
693 |
- } else if (ctx->cachetype == CACHE_EBUILD) { |
694 |
- return cache_read_file_ebuild(pkg_ctx); |
695 |
- } |
696 |
- |
697 |
- warn("Unknown metadata cache type!"); |
698 |
- return NULL; |
699 |
-} |
700 |
- |
701 |
-void |
702 |
-cache_close_meta(cache_pkg_meta *cache) |
703 |
-{ |
704 |
- if (!cache) |
705 |
- errf("Cache is empty !"); |
706 |
- free(cache); |
707 |
-} |
708 |
- |
709 |
-cache_metadata_xml * |
710 |
-cache_read_metadata(cache_pkg_ctx *pkg_ctx) |
711 |
-{ |
712 |
- cache_ctx *ctx = (cache_ctx *)(pkg_ctx->cat_ctx->ctx); |
713 |
- int fd; |
714 |
- FILE *f; |
715 |
- struct stat s; |
716 |
- char *xbuf; |
717 |
- char *p; |
718 |
- char *q; |
719 |
- size_t len; |
720 |
- cache_metadata_xml *ret = NULL; |
721 |
- struct elist *emailw = NULL; |
722 |
- char buf[_Q_PATH_MAX]; |
723 |
- |
724 |
- /* lame @$$ XML parsing, I don't want to pull in a real parser |
725 |
- * library because we only retrieve one element for now: email |
726 |
- * technically speaking, email may occur only once in a maintainer |
727 |
- * tag, but practically speaking we don't care at all, so we can |
728 |
- * just extract everything between <email> and </email> */ |
729 |
- |
730 |
- if (ctx->cachetype == CACHE_EBUILD) { |
731 |
- fd = openat(pkg_ctx->cat_ctx->fd, "metadata", O_RDONLY | O_CLOEXEC); |
732 |
- } else { |
733 |
- depend_atom *atom; |
734 |
- snprintf(buf, sizeof(buf), "%s/%s", |
735 |
- pkg_ctx->cat_ctx->name, pkg_ctx->name); |
736 |
- atom = atom_explode(buf); |
737 |
- snprintf(buf, sizeof(buf), "../../%s/%s/metadata.xml", |
738 |
- atom->CATEGORY, atom->PN); |
739 |
- atom_implode(atom); |
740 |
- fd = openat(ctx->vdb_fd, buf, O_RDONLY | O_CLOEXEC); |
741 |
- } |
742 |
- |
743 |
- if (fd == -1) |
744 |
- return NULL; |
745 |
- |
746 |
- if ((f = fdopen(fd, "r")) == NULL) { |
747 |
- close(fd); |
748 |
- return NULL; |
749 |
- } |
750 |
- |
751 |
- if (fstat(fd, &s) != 0) { |
752 |
- fclose(f); |
753 |
- return NULL; |
754 |
- } |
755 |
- |
756 |
- len = sizeof(*ret) + s.st_size + 1; |
757 |
- p = xbuf = xzalloc(len); |
758 |
- if ((off_t)fread(p, 1, s.st_size, f) != s.st_size) { |
759 |
- free(p); |
760 |
- fclose(f); |
761 |
- pkg_ctx->fd = -1; |
762 |
- return NULL; |
763 |
- } |
764 |
- |
765 |
- ret = xmalloc(sizeof(*ret)); |
766 |
- ret->email = NULL; |
767 |
- |
768 |
- while ((q = strstr(p, "<email>")) != NULL) { |
769 |
- p = q + sizeof("<email>") - 1; |
770 |
- if ((q = strstr(p, "</email>")) == NULL) |
771 |
- break; |
772 |
- *q = '\0'; |
773 |
- rmspace(p); |
774 |
- if (emailw == NULL) { |
775 |
- emailw = ret->email = xmalloc(sizeof(*emailw)); |
776 |
- } else { |
777 |
- emailw = emailw->next = xmalloc(sizeof(*emailw)); |
778 |
- } |
779 |
- emailw->next = NULL; |
780 |
- emailw->addr = xstrdup(p); |
781 |
- p = q + 1; |
782 |
- } |
783 |
- |
784 |
- free(xbuf); |
785 |
- fclose(f); |
786 |
- return ret; |
787 |
-} |
788 |
- |
789 |
-void |
790 |
-cache_close_metadata(cache_metadata_xml *meta_ctx) |
791 |
-{ |
792 |
- struct elist *e; |
793 |
- while (meta_ctx->email != NULL) { |
794 |
- e = meta_ctx->email; |
795 |
- free(e->addr); |
796 |
- e = e->next; |
797 |
- free(meta_ctx->email); |
798 |
- meta_ctx->email = e; |
799 |
- } |
800 |
- free(meta_ctx); |
801 |
-} |
802 |
- |
803 |
-void |
804 |
-cache_close_pkg(cache_pkg_ctx *pkg_ctx) |
805 |
-{ |
806 |
- /* avoid free of cache_ctx' repo by vdb_close_pkg */ |
807 |
- if (pkg_ctx->cat_ctx->ctx->repo == pkg_ctx->repo) |
808 |
- pkg_ctx->repo = NULL; |
809 |
- |
810 |
- vdb_close_pkg(pkg_ctx); |
811 |
-} |
812 |
- |
813 |
-static int |
814 |
-cache_foreach_pkg_int(const char *sroot, const char *portdir, |
815 |
- vdb_pkg_cb callback, void *priv, vdb_cat_filter filter, |
816 |
- bool sort, void *catsortfunc, void *pkgsortfunc) |
817 |
-{ |
818 |
- cache_ctx *ctx; |
819 |
- cache_cat_ctx *cat_ctx; |
820 |
- cache_pkg_ctx *pkg_ctx; |
821 |
- int ret; |
822 |
- |
823 |
- ctx = cache_open(sroot, portdir); |
824 |
- if (!ctx) |
825 |
- return EXIT_FAILURE; |
826 |
- |
827 |
- ctx->do_sort = sort; |
828 |
- if (catsortfunc != NULL) |
829 |
- ctx->catsortfunc = catsortfunc; |
830 |
- if (pkgsortfunc != NULL) |
831 |
- ctx->pkgsortfunc = pkgsortfunc; |
832 |
- |
833 |
- ret = 0; |
834 |
- while ((cat_ctx = cache_next_cat(ctx))) { |
835 |
- if (filter && !filter(cat_ctx, priv)) |
836 |
- continue; |
837 |
- while ((pkg_ctx = cache_next_pkg(cat_ctx))) { |
838 |
- ret |= callback(pkg_ctx, priv); |
839 |
- cache_close_pkg(pkg_ctx); |
840 |
- } |
841 |
- cache_close_cat(cat_ctx); |
842 |
- } |
843 |
- cache_close(ctx); |
844 |
- |
845 |
- return ret; |
846 |
-} |
847 |
- |
848 |
-int |
849 |
-cache_foreach_pkg(const char *sroot, const char *portdir, |
850 |
- vdb_pkg_cb callback, void *priv, vdb_cat_filter filter) |
851 |
-{ |
852 |
- return cache_foreach_pkg_int(sroot, portdir, callback, priv, |
853 |
- filter, false, NULL, NULL); |
854 |
-} |
855 |
- |
856 |
-int |
857 |
-cache_foreach_pkg_sorted(const char *sroot, const char *portdir, |
858 |
- vdb_pkg_cb callback, void *priv, |
859 |
- void *catsortfunc, void *pkgsortfunc) |
860 |
-{ |
861 |
- return cache_foreach_pkg_int(sroot, portdir, callback, priv, |
862 |
- NULL, true, catsortfunc, pkgsortfunc); |
863 |
-} |
864 |
|
865 |
diff --git a/libq/cache.h b/libq/cache.h |
866 |
deleted file mode 100644 |
867 |
index e863daf..0000000 |
868 |
--- a/libq/cache.h |
869 |
+++ /dev/null |
870 |
@@ -1,74 +0,0 @@ |
871 |
-/* |
872 |
- * Copyright 2005-2019 Gentoo Foundation |
873 |
- * Distributed under the terms of the GNU General Public License v2 |
874 |
- * |
875 |
- * Copyright 2005-2010 Ned Ludd - <solar@g.o> |
876 |
- * Copyright 2005-2014 Mike Frysinger - <vapier@g.o> |
877 |
- * Copyright 2019- Fabian Groffen - <grobian@g.o> |
878 |
- */ |
879 |
- |
880 |
-#ifndef _CACHE_H |
881 |
-#define _CACHE_H 1 |
882 |
- |
883 |
-#include "atom.h" |
884 |
-#include "vdb.h" |
885 |
- |
886 |
-#define cache_ctx vdb_ctx |
887 |
-#define cache_cat_ctx vdb_cat_ctx |
888 |
-#define cache_pkg_ctx vdb_pkg_ctx |
889 |
- |
890 |
-typedef struct { |
891 |
- char *_data; |
892 |
- char *DEPEND; /* line 1 */ |
893 |
- char *RDEPEND; |
894 |
- char *SLOT; |
895 |
- char *SRC_URI; |
896 |
- char *RESTRICT; /* line 5 */ |
897 |
- char *HOMEPAGE; |
898 |
- char *LICENSE; |
899 |
- char *DESCRIPTION; |
900 |
- char *KEYWORDS; |
901 |
- char *INHERITED; /* line 10 */ |
902 |
- char *IUSE; |
903 |
- char *CDEPEND; |
904 |
- char *PDEPEND; |
905 |
- char *PROVIDE; /* line 14 */ |
906 |
- char *EAPI; |
907 |
- char *PROPERTIES; |
908 |
- /* These are MD5-Cache only */ |
909 |
- char *DEFINED_PHASES; |
910 |
- char *REQUIRED_USE; |
911 |
- char *BDEPEND; |
912 |
- char *_eclasses_; |
913 |
- char *_md5_; |
914 |
-} cache_pkg_meta; |
915 |
- |
916 |
-typedef struct { |
917 |
- struct elist { |
918 |
- char *addr; |
919 |
- struct elist *next; |
920 |
- } *email; |
921 |
-} cache_metadata_xml; |
922 |
- |
923 |
-typedef int (cache_pkg_cb)(cache_pkg_ctx *, void *priv); |
924 |
-typedef int (cache_cat_filter)(cache_cat_ctx *, void *priv); |
925 |
- |
926 |
-cache_ctx *cache_open(const char *sroot, const char *portdir); |
927 |
-void cache_close(cache_ctx *ctx); |
928 |
-cache_cat_ctx *cache_open_cat(cache_ctx *ctx, const char *name); |
929 |
-cache_cat_ctx *cache_next_cat(cache_ctx *ctx); |
930 |
-void cache_close_cat(cache_cat_ctx *cat_ctx); |
931 |
-cache_pkg_ctx *cache_open_pkg(cache_cat_ctx *cat_ctx, const char *name); |
932 |
-cache_pkg_ctx *cache_next_pkg(cache_cat_ctx *cat_ctx); |
933 |
-cache_pkg_meta *cache_pkg_read(cache_pkg_ctx *pkg_ctx); |
934 |
-void cache_close_meta(cache_pkg_meta *cache); |
935 |
-cache_metadata_xml *cache_read_metadata(cache_pkg_ctx *pkg_ctx); |
936 |
-void cache_close_metadata(cache_metadata_xml *meta_ctx); |
937 |
-void cache_close_pkg(cache_pkg_ctx *pkg_ctx); |
938 |
-int cache_foreach_pkg(const char *sroot, const char *portdir, |
939 |
- cache_pkg_cb callback, void *priv, cache_cat_filter filter); |
940 |
-int cache_foreach_pkg_sorted(const char *sroot, const char *portdir, |
941 |
- cache_pkg_cb callback, void *priv, |
942 |
- void *catsortfunc, void *pkgsortfunc); |
943 |
- |
944 |
-#endif |
945 |
|
946 |
diff --git a/libq/tree.c b/libq/tree.c |
947 |
new file mode 100644 |
948 |
index 0000000..bb7eefa |
949 |
--- /dev/null |
950 |
+++ b/libq/tree.c |
951 |
@@ -0,0 +1,1066 @@ |
952 |
+/* |
953 |
+ * Copyright 2005-2019 Gentoo Foundation |
954 |
+ * Distributed under the terms of the GNU General Public License v2 |
955 |
+ * |
956 |
+ * Copyright 2005-2008 Ned Ludd - <solar@g.o> |
957 |
+ * Copyright 2005-2014 Mike Frysinger - <vapier@g.o> |
958 |
+ * Copyright 2018- Fabian Groffen - <grobian@g.o> |
959 |
+ */ |
960 |
+ |
961 |
+#include "main.h" |
962 |
+ |
963 |
+#include <fcntl.h> |
964 |
+#include <sys/types.h> |
965 |
+#include <sys/stat.h> |
966 |
+#include <ctype.h> |
967 |
+#include <xalloc.h> |
968 |
+ |
969 |
+#include "atom.h" |
970 |
+#include "eat_file.h" |
971 |
+#include "rmspace.h" |
972 |
+#include "scandirat.h" |
973 |
+#include "set.h" |
974 |
+#include "tree.h" |
975 |
+ |
976 |
+#include <ctype.h> |
977 |
+#include <xalloc.h> |
978 |
+ |
979 |
+static tree_ctx * |
980 |
+tree_open_int(const char *sroot, const char *tdir, bool quiet) |
981 |
+{ |
982 |
+ tree_ctx *ctx = xmalloc(sizeof(*ctx)); |
983 |
+ |
984 |
+ ctx->portroot_fd = open(sroot, O_RDONLY | O_CLOEXEC | O_PATH); |
985 |
+ if (ctx->portroot_fd == -1) { |
986 |
+ if (!quiet) |
987 |
+ warnp("could not open root: %s", sroot); |
988 |
+ goto f_error; |
989 |
+ } |
990 |
+ |
991 |
+ /* Skip the leading slash */ |
992 |
+ tdir++; |
993 |
+ if (*tdir == '\0') |
994 |
+ tdir = "."; |
995 |
+ /* Cannot use O_PATH as we want to use fdopendir() */ |
996 |
+ ctx->tree_fd = openat(ctx->portroot_fd, tdir, O_RDONLY | O_CLOEXEC); |
997 |
+ if (ctx->tree_fd == -1) { |
998 |
+ if (!quiet) |
999 |
+ warnp("could not open tree: %s (in root %s)", tdir, sroot); |
1000 |
+ goto cp_error; |
1001 |
+ } |
1002 |
+ |
1003 |
+ ctx->dir = fdopendir(ctx->tree_fd); |
1004 |
+ if (ctx->dir == NULL) |
1005 |
+ goto cv_error; |
1006 |
+ |
1007 |
+ ctx->do_sort = false; |
1008 |
+ ctx->cat_de = NULL; |
1009 |
+ ctx->catsortfunc = alphasort; |
1010 |
+ ctx->pkgsortfunc = alphasort; |
1011 |
+ ctx->repo = NULL; |
1012 |
+ ctx->ebuilddir_ctx = NULL; |
1013 |
+ ctx->ebuilddir_pkg_ctx = NULL; |
1014 |
+ return ctx; |
1015 |
+ |
1016 |
+ cv_error: |
1017 |
+ close(ctx->tree_fd); |
1018 |
+ cp_error: |
1019 |
+ close(ctx->portroot_fd); |
1020 |
+ f_error: |
1021 |
+ free(ctx); |
1022 |
+ return NULL; |
1023 |
+} |
1024 |
+ |
1025 |
+static const char portcachedir_pms[] = "metadata/cache"; |
1026 |
+static const char portcachedir_md5[] = "metadata/md5-cache"; |
1027 |
+static const char portrepo_name[] = "profiles/repo_name"; |
1028 |
+tree_ctx * |
1029 |
+tree_open(const char *sroot, const char *portdir) |
1030 |
+{ |
1031 |
+ tree_ctx *ret; |
1032 |
+ char buf[_Q_PATH_MAX]; |
1033 |
+ char *repo = NULL; |
1034 |
+ size_t repolen = 0; |
1035 |
+ |
1036 |
+ snprintf(buf, sizeof(buf), "%s%s/%s", sroot, portdir, portrepo_name); |
1037 |
+ if (eat_file(buf, &repo, &repolen)) { |
1038 |
+ (void)rmspace(repo); |
1039 |
+ } else { |
1040 |
+ repo = NULL; /* ignore missing repo file */ |
1041 |
+ } |
1042 |
+ |
1043 |
+ snprintf(buf, sizeof(buf), "%s/%s", portdir, portcachedir_md5); |
1044 |
+ ret = tree_open_int(sroot, buf, true); |
1045 |
+ if (ret != NULL) { |
1046 |
+ ret->cachetype = CACHE_METADATA_MD5; |
1047 |
+ ret->repo = repo; |
1048 |
+ return ret; |
1049 |
+ } |
1050 |
+ |
1051 |
+ snprintf(buf, sizeof(buf), "%s/%s", portdir, portcachedir_pms); |
1052 |
+ ret = tree_open_int(sroot, buf, true); |
1053 |
+ if (ret != NULL) { |
1054 |
+ ret->cachetype = CACHE_METADATA_PMS; |
1055 |
+ ret->repo = repo; |
1056 |
+ return ret; |
1057 |
+ } |
1058 |
+ |
1059 |
+ ret = tree_open_int(sroot, portdir, true); |
1060 |
+ if (ret != NULL) { |
1061 |
+ ret->cachetype = CACHE_EBUILD; |
1062 |
+ ret->repo = repo; |
1063 |
+ return ret; |
1064 |
+ } |
1065 |
+ |
1066 |
+ tree_close(ret); |
1067 |
+ warnf("could not open repository at %s (under root %s)", portdir, sroot); |
1068 |
+ |
1069 |
+ return NULL; |
1070 |
+} |
1071 |
+ |
1072 |
+tree_ctx * |
1073 |
+tree_open_vdb(const char *sroot, const char *svdb) |
1074 |
+{ |
1075 |
+ tree_ctx *ret = tree_open_int(sroot, svdb, false); |
1076 |
+ if (ret != NULL) |
1077 |
+ ret->cachetype = CACHE_VDB; |
1078 |
+ return ret; |
1079 |
+} |
1080 |
+ |
1081 |
+void |
1082 |
+tree_close(tree_ctx *ctx) |
1083 |
+{ |
1084 |
+ closedir(ctx->dir); |
1085 |
+ /* closedir() above does this for us: */ |
1086 |
+ /* close(ctx->tree_fd); */ |
1087 |
+ close(ctx->portroot_fd); |
1088 |
+ if (ctx->do_sort) |
1089 |
+ scandir_free(ctx->cat_de, ctx->cat_cnt); |
1090 |
+ if (ctx->repo != NULL) |
1091 |
+ free(ctx->repo); |
1092 |
+ if (ctx->ebuilddir_ctx != NULL) |
1093 |
+ free(ctx->ebuilddir_ctx); |
1094 |
+ free(ctx); |
1095 |
+} |
1096 |
+ |
1097 |
+int |
1098 |
+tree_filter_cat(const struct dirent *de) |
1099 |
+{ |
1100 |
+ int i; |
1101 |
+ bool founddash; |
1102 |
+ |
1103 |
+#ifdef DT_UNKNOWN |
1104 |
+ /* cat must be a dir */ |
1105 |
+ if (de->d_type != DT_UNKNOWN && |
1106 |
+ de->d_type != DT_DIR && |
1107 |
+ de->d_type != DT_LNK) |
1108 |
+ return 0; |
1109 |
+#endif |
1110 |
+ |
1111 |
+ /* PMS 3.1.1 */ |
1112 |
+ founddash = false; |
1113 |
+ for (i = 0; de->d_name[i] != '\0'; i++) { |
1114 |
+ switch (de->d_name[i]) { |
1115 |
+ case '_': |
1116 |
+ break; |
1117 |
+ case '-': |
1118 |
+ founddash = true; |
1119 |
+ /* fall through */ |
1120 |
+ case '+': |
1121 |
+ case '.': |
1122 |
+ if (i) |
1123 |
+ break; |
1124 |
+ return 0; |
1125 |
+ default: |
1126 |
+ if ((de->d_name[i] >= 'A' && de->d_name[i] <= 'Z') || |
1127 |
+ (de->d_name[i] >= 'a' && de->d_name[i] <= 'z') || |
1128 |
+ (de->d_name[i] >= '0' && de->d_name[i] <= '9')) |
1129 |
+ break; |
1130 |
+ return 0; |
1131 |
+ } |
1132 |
+ } |
1133 |
+ if (!founddash && strcmp(de->d_name, "virtual") != 0) |
1134 |
+ return 0; |
1135 |
+ |
1136 |
+ return i; |
1137 |
+} |
1138 |
+ |
1139 |
+tree_cat_ctx * |
1140 |
+tree_open_cat(tree_ctx *ctx, const char *name) |
1141 |
+{ |
1142 |
+ tree_cat_ctx *cat_ctx; |
1143 |
+ int fd; |
1144 |
+ DIR *dir; |
1145 |
+ |
1146 |
+ /* Cannot use O_PATH as we want to use fdopendir() */ |
1147 |
+ fd = openat(ctx->tree_fd, name, O_RDONLY | O_CLOEXEC); |
1148 |
+ if (fd == -1) |
1149 |
+ return NULL; |
1150 |
+ |
1151 |
+ dir = fdopendir(fd); |
1152 |
+ if (!dir) { |
1153 |
+ close(fd); |
1154 |
+ return NULL; |
1155 |
+ } |
1156 |
+ |
1157 |
+ cat_ctx = xmalloc(sizeof(*cat_ctx)); |
1158 |
+ cat_ctx->name = name; |
1159 |
+ cat_ctx->fd = fd; |
1160 |
+ cat_ctx->dir = dir; |
1161 |
+ cat_ctx->ctx = ctx; |
1162 |
+ cat_ctx->pkg_de = NULL; |
1163 |
+ return cat_ctx; |
1164 |
+} |
1165 |
+ |
1166 |
+tree_cat_ctx * |
1167 |
+tree_next_cat(tree_ctx *ctx) |
1168 |
+{ |
1169 |
+ /* search for a category directory */ |
1170 |
+ tree_cat_ctx *cat_ctx = NULL; |
1171 |
+ |
1172 |
+ if (ctx->do_sort) { |
1173 |
+ if (ctx->cat_de == NULL) { |
1174 |
+ ctx->cat_cnt = scandirat(ctx->tree_fd, |
1175 |
+ ".", &ctx->cat_de, tree_filter_cat, ctx->catsortfunc); |
1176 |
+ ctx->cat_cur = 0; |
1177 |
+ } |
1178 |
+ |
1179 |
+ while (ctx->cat_cur < ctx->cat_cnt) { |
1180 |
+ cat_ctx = tree_open_cat(ctx, ctx->cat_de[ctx->cat_cur++]->d_name); |
1181 |
+ if (!cat_ctx) |
1182 |
+ continue; |
1183 |
+ break; |
1184 |
+ } |
1185 |
+ } else { |
1186 |
+ /* cheaper "streaming" variant */ |
1187 |
+ const struct dirent *de; |
1188 |
+ do { |
1189 |
+ de = readdir(ctx->dir); |
1190 |
+ if (!de) |
1191 |
+ break; |
1192 |
+ |
1193 |
+ if (tree_filter_cat(de) == 0) |
1194 |
+ continue; |
1195 |
+ |
1196 |
+ cat_ctx = tree_open_cat(ctx, de->d_name); |
1197 |
+ if (!cat_ctx) |
1198 |
+ continue; |
1199 |
+ |
1200 |
+ break; |
1201 |
+ } while (1); |
1202 |
+ } |
1203 |
+ |
1204 |
+ return cat_ctx; |
1205 |
+} |
1206 |
+ |
1207 |
+void |
1208 |
+tree_close_cat(tree_cat_ctx *cat_ctx) |
1209 |
+{ |
1210 |
+ closedir(cat_ctx->dir); |
1211 |
+ /* closedir() above does this for us: */ |
1212 |
+ /* close(ctx->fd); */ |
1213 |
+ if (cat_ctx->ctx->do_sort) |
1214 |
+ scandir_free(cat_ctx->pkg_de, cat_ctx->pkg_cnt); |
1215 |
+ free(cat_ctx); |
1216 |
+} |
1217 |
+ |
1218 |
+int |
1219 |
+tree_filter_pkg(const struct dirent *de) |
1220 |
+{ |
1221 |
+ int i; |
1222 |
+ bool founddash = false; |
1223 |
+ |
1224 |
+ /* PMS 3.1.2 */ |
1225 |
+ for (i = 0; de->d_name[i] != '\0'; i++) { |
1226 |
+ switch (de->d_name[i]) { |
1227 |
+ case '_': |
1228 |
+ break; |
1229 |
+ case '-': |
1230 |
+ founddash = true; |
1231 |
+ /* fall through */ |
1232 |
+ case '+': |
1233 |
+ if (i) |
1234 |
+ break; |
1235 |
+ return 0; |
1236 |
+ default: |
1237 |
+ if ((de->d_name[i] >= 'A' && de->d_name[i] <= 'Z') || |
1238 |
+ (de->d_name[i] >= 'a' && de->d_name[i] <= 'z') || |
1239 |
+ (de->d_name[i] >= '0' && de->d_name[i] <= '9')) |
1240 |
+ break; |
1241 |
+ if (founddash) |
1242 |
+ return 1; |
1243 |
+ return 0; |
1244 |
+ } |
1245 |
+ } |
1246 |
+ |
1247 |
+ return i; |
1248 |
+} |
1249 |
+ |
1250 |
+tree_pkg_ctx * |
1251 |
+tree_open_pkg(tree_cat_ctx *cat_ctx, const char *name) |
1252 |
+{ |
1253 |
+ tree_pkg_ctx *pkg_ctx = xmalloc(sizeof(*pkg_ctx)); |
1254 |
+ pkg_ctx->name = name; |
1255 |
+ pkg_ctx->slot = NULL; |
1256 |
+ pkg_ctx->repo = cat_ctx->ctx->repo; |
1257 |
+ pkg_ctx->fd = -1; |
1258 |
+ pkg_ctx->cat_ctx = cat_ctx; |
1259 |
+ pkg_ctx->atom = NULL; |
1260 |
+ return pkg_ctx; |
1261 |
+} |
1262 |
+ |
1263 |
+static tree_pkg_ctx * |
1264 |
+tree_next_pkg_int(tree_cat_ctx *cat_ctx); |
1265 |
+static tree_pkg_ctx * |
1266 |
+tree_next_pkg_int(tree_cat_ctx *cat_ctx) |
1267 |
+{ |
1268 |
+ tree_pkg_ctx *pkg_ctx = NULL; |
1269 |
+ |
1270 |
+ if (cat_ctx->ctx->do_sort) { |
1271 |
+ if (cat_ctx->pkg_de == NULL) { |
1272 |
+ cat_ctx->pkg_cnt = scandirat(cat_ctx->fd, ".", &cat_ctx->pkg_de, |
1273 |
+ tree_filter_pkg, cat_ctx->ctx->pkgsortfunc); |
1274 |
+ cat_ctx->pkg_cur = 0; |
1275 |
+ } |
1276 |
+ |
1277 |
+ while (cat_ctx->pkg_cur < cat_ctx->pkg_cnt) { |
1278 |
+ pkg_ctx = |
1279 |
+ tree_open_pkg(cat_ctx, |
1280 |
+ cat_ctx->pkg_de[cat_ctx->pkg_cur++]->d_name); |
1281 |
+ if (!pkg_ctx) |
1282 |
+ continue; |
1283 |
+ break; |
1284 |
+ } |
1285 |
+ } else { |
1286 |
+ const struct dirent *de; |
1287 |
+ do { |
1288 |
+ de = readdir(cat_ctx->dir); |
1289 |
+ if (!de) |
1290 |
+ break; |
1291 |
+ |
1292 |
+ if (tree_filter_pkg(de) == 0) |
1293 |
+ continue; |
1294 |
+ |
1295 |
+ pkg_ctx = tree_open_pkg(cat_ctx, de->d_name); |
1296 |
+ if (!pkg_ctx) |
1297 |
+ continue; |
1298 |
+ |
1299 |
+ break; |
1300 |
+ } while (1); |
1301 |
+ } |
1302 |
+ |
1303 |
+ return pkg_ctx; |
1304 |
+} |
1305 |
+ |
1306 |
+tree_pkg_ctx * |
1307 |
+tree_next_pkg(tree_cat_ctx *cat_ctx) |
1308 |
+{ |
1309 |
+ tree_ctx *ctx = cat_ctx->ctx; |
1310 |
+ tree_pkg_ctx *ret = NULL; |
1311 |
+ |
1312 |
+ if (ctx->cachetype == CACHE_EBUILD) { |
1313 |
+ char *p; |
1314 |
+ |
1315 |
+ /* serve *.ebuild files each as separate pkg_ctx with name set |
1316 |
+ * to CAT/P like in VDB and metadata */ |
1317 |
+ do { |
1318 |
+ if (ctx->ebuilddir_pkg_ctx == NULL) { |
1319 |
+ tree_ctx *pkgdir = ctx->ebuilddir_ctx; |
1320 |
+ |
1321 |
+ if (pkgdir == NULL) |
1322 |
+ pkgdir = ctx->ebuilddir_ctx = xmalloc(sizeof(tree_ctx)); |
1323 |
+ memset(ctx->ebuilddir_ctx, '\0', sizeof(*ctx->ebuilddir_ctx)); |
1324 |
+ |
1325 |
+ ctx->ebuilddir_pkg_ctx = tree_next_pkg_int(cat_ctx); |
1326 |
+ if (ctx->ebuilddir_pkg_ctx == NULL) |
1327 |
+ return NULL; |
1328 |
+ |
1329 |
+ pkgdir->portroot_fd = -1; |
1330 |
+ pkgdir->tree_fd = cat_ctx->fd; |
1331 |
+ pkgdir->do_sort = ctx->do_sort; |
1332 |
+ pkgdir->catsortfunc = ctx->catsortfunc; |
1333 |
+ pkgdir->pkgsortfunc = ctx->pkgsortfunc; |
1334 |
+ pkgdir->repo = ctx->repo; |
1335 |
+ pkgdir->cachetype = ctx->cachetype; |
1336 |
+ |
1337 |
+ ctx->ebuilddir_cat_ctx = |
1338 |
+ tree_open_cat(pkgdir, ctx->ebuilddir_pkg_ctx->name); |
1339 |
+ |
1340 |
+ /* opening might fail if what we found wasn't a |
1341 |
+ * directory or something */ |
1342 |
+ if (ctx->ebuilddir_cat_ctx == NULL) { |
1343 |
+ ctx->ebuilddir_pkg_ctx = NULL; |
1344 |
+ return NULL; |
1345 |
+ } |
1346 |
+ |
1347 |
+ /* "zap" the pkg such that it looks like CAT/P */ |
1348 |
+ ctx->ebuilddir_cat_ctx->name = cat_ctx->name; |
1349 |
+ } |
1350 |
+ |
1351 |
+ ret = tree_next_pkg_int(ctx->ebuilddir_cat_ctx); |
1352 |
+ if (ret == NULL) { |
1353 |
+ tree_close_cat(ctx->ebuilddir_cat_ctx); |
1354 |
+ ctx->ebuilddir_pkg_ctx = NULL; |
1355 |
+ } else { |
1356 |
+ if ((p = strstr(ret->name, ".ebuild")) == NULL) { |
1357 |
+ tree_close_pkg(ret); |
1358 |
+ ret = NULL; |
1359 |
+ } else { |
1360 |
+ *p = '\0'; |
1361 |
+ } |
1362 |
+ } |
1363 |
+ } while (ret == NULL); |
1364 |
+ } else { |
1365 |
+ ret = tree_next_pkg_int(cat_ctx); |
1366 |
+ } |
1367 |
+ |
1368 |
+ return ret; |
1369 |
+} |
1370 |
+ |
1371 |
+int |
1372 |
+tree_pkg_vdb_openat( |
1373 |
+ tree_pkg_ctx *pkg_ctx, |
1374 |
+ const char *file, |
1375 |
+ int flags, mode_t mode) |
1376 |
+{ |
1377 |
+ if (pkg_ctx->fd == -1) { |
1378 |
+ pkg_ctx->fd = openat(pkg_ctx->cat_ctx->fd, pkg_ctx->name, |
1379 |
+ O_RDONLY | O_CLOEXEC | O_PATH); |
1380 |
+ if (pkg_ctx->fd == -1) |
1381 |
+ return -1; |
1382 |
+ } |
1383 |
+ |
1384 |
+ return openat(pkg_ctx->fd, file, flags | O_CLOEXEC, mode); |
1385 |
+} |
1386 |
+ |
1387 |
+FILE * |
1388 |
+tree_pkg_vdb_fopenat( |
1389 |
+ tree_pkg_ctx *pkg_ctx, |
1390 |
+ const char *file, |
1391 |
+ int flags, |
1392 |
+ mode_t mode, |
1393 |
+ const char *fmode) |
1394 |
+{ |
1395 |
+ FILE *fp; |
1396 |
+ int fd; |
1397 |
+ |
1398 |
+ fd = tree_pkg_vdb_openat(pkg_ctx, file, flags, mode); |
1399 |
+ if (fd == -1) |
1400 |
+ return NULL; |
1401 |
+ |
1402 |
+ fp = fdopen(fd, fmode); |
1403 |
+ if (!fp) |
1404 |
+ close(fd); |
1405 |
+ |
1406 |
+ return fp; |
1407 |
+} |
1408 |
+ |
1409 |
+bool |
1410 |
+tree_pkg_vdb_eat( |
1411 |
+ tree_pkg_ctx *pkg_ctx, |
1412 |
+ const char *file, |
1413 |
+ char **bufptr, |
1414 |
+ size_t *buflen) |
1415 |
+{ |
1416 |
+ int fd = tree_pkg_vdb_openat(pkg_ctx, file, O_RDONLY, 0); |
1417 |
+ bool ret = eat_file_fd(fd, bufptr, buflen); |
1418 |
+ rmspace(*bufptr); |
1419 |
+ if (fd != -1) |
1420 |
+ close(fd); |
1421 |
+ return ret; |
1422 |
+} |
1423 |
+ |
1424 |
+static tree_pkg_meta * |
1425 |
+tree_read_file_pms(tree_pkg_ctx *pkg_ctx) |
1426 |
+{ |
1427 |
+ struct stat s; |
1428 |
+ char *ptr; |
1429 |
+ FILE *f; |
1430 |
+ tree_pkg_meta *ret = NULL; |
1431 |
+ size_t len; |
1432 |
+ char buf[_Q_PATH_MAX]; |
1433 |
+ |
1434 |
+ if ((f = fdopen(pkg_ctx->fd, "r")) == NULL) |
1435 |
+ goto err; |
1436 |
+ |
1437 |
+ if (fstat(pkg_ctx->fd, &s) != 0) |
1438 |
+ goto err; |
1439 |
+ |
1440 |
+ len = sizeof(*ret) + s.st_size + 1; |
1441 |
+ ret = xzalloc(len); |
1442 |
+ ptr = (char*)ret; |
1443 |
+ ret->_data = ptr + sizeof(*ret); |
1444 |
+ if ((off_t)fread(ret->_data, 1, s.st_size, f) != s.st_size) |
1445 |
+ goto err; |
1446 |
+ |
1447 |
+ ret->DEPEND = ret->_data; |
1448 |
+#define next_line(curr, next) \ |
1449 |
+ if ((ptr = strchr(ret->curr, '\n')) == NULL) { \ |
1450 |
+ warn("Invalid cache file for '%s'", buf); \ |
1451 |
+ goto err; \ |
1452 |
+ } \ |
1453 |
+ ret->next = ptr+1; \ |
1454 |
+ *ptr = '\0'; |
1455 |
+ next_line(DEPEND, RDEPEND) |
1456 |
+ next_line(RDEPEND, SLOT) |
1457 |
+ next_line(SLOT, SRC_URI) |
1458 |
+ next_line(SRC_URI, RESTRICT) |
1459 |
+ next_line(RESTRICT, HOMEPAGE) |
1460 |
+ next_line(HOMEPAGE, LICENSE) |
1461 |
+ next_line(LICENSE, DESCRIPTION) |
1462 |
+ next_line(DESCRIPTION, KEYWORDS) |
1463 |
+ next_line(KEYWORDS, INHERITED) |
1464 |
+ next_line(INHERITED, IUSE) |
1465 |
+ next_line(IUSE, CDEPEND) |
1466 |
+ next_line(CDEPEND, PDEPEND) |
1467 |
+ next_line(PDEPEND, PROVIDE) |
1468 |
+ next_line(PROVIDE, EAPI) |
1469 |
+ next_line(EAPI, PROPERTIES) |
1470 |
+#undef next_line |
1471 |
+ ptr = strchr(ptr+1, '\n'); |
1472 |
+ if (ptr == NULL) { |
1473 |
+ warn("Invalid cache file for '%s' - could not find end of cache data", |
1474 |
+ buf); |
1475 |
+ goto err; |
1476 |
+ } |
1477 |
+ *ptr = '\0'; |
1478 |
+ |
1479 |
+ fclose(f); |
1480 |
+ pkg_ctx->fd = -1; |
1481 |
+ |
1482 |
+ return ret; |
1483 |
+ |
1484 |
+err: |
1485 |
+ if (f) |
1486 |
+ fclose(f); |
1487 |
+ pkg_ctx->fd = -1; |
1488 |
+ if (ret) |
1489 |
+ tree_close_meta(ret); |
1490 |
+ return NULL; |
1491 |
+} |
1492 |
+ |
1493 |
+static tree_pkg_meta * |
1494 |
+tree_read_file_md5(tree_pkg_ctx *pkg_ctx) |
1495 |
+{ |
1496 |
+ struct stat s; |
1497 |
+ char *ptr, *endptr; |
1498 |
+ FILE *f; |
1499 |
+ tree_pkg_meta *ret = NULL; |
1500 |
+ size_t len; |
1501 |
+ |
1502 |
+ if ((f = fdopen(pkg_ctx->fd, "r")) == NULL) |
1503 |
+ goto err; |
1504 |
+ |
1505 |
+ if (fstat(pkg_ctx->fd, &s) != 0) |
1506 |
+ goto err; |
1507 |
+ |
1508 |
+ len = sizeof(*ret) + s.st_size + 1; |
1509 |
+ ret = xzalloc(len); |
1510 |
+ ptr = (char*)ret; |
1511 |
+ ret->_data = ptr + sizeof(*ret); |
1512 |
+ if ((off_t)fread(ret->_data, 1, s.st_size, f) != s.st_size) |
1513 |
+ goto err; |
1514 |
+ |
1515 |
+ /* We have a block of key=value\n data. |
1516 |
+ * KEY=VALUE\n |
1517 |
+ * Where KEY does NOT contain: |
1518 |
+ * \0 \n = |
1519 |
+ * And VALUE does NOT contain: |
1520 |
+ * \0 \n |
1521 |
+ * */ |
1522 |
+#define assign_var_cmp(keyname, cmpkey) \ |
1523 |
+ if (strncmp(keyptr, cmpkey, strlen(cmpkey)) == 0) { \ |
1524 |
+ ret->keyname = valptr; \ |
1525 |
+ continue; \ |
1526 |
+ } |
1527 |
+#define assign_var(keyname) \ |
1528 |
+ assign_var_cmp(keyname, #keyname); |
1529 |
+ |
1530 |
+ ptr = ret->_data; |
1531 |
+ endptr = strchr(ptr, '\0'); |
1532 |
+ if (endptr == NULL) { |
1533 |
+ warn("Invalid cache file for '%s/%s': " |
1534 |
+ "could not find end of cache data", |
1535 |
+ pkg_ctx->cat_ctx->name, pkg_ctx->name); |
1536 |
+ goto err; |
1537 |
+ } |
1538 |
+ |
1539 |
+ while (ptr != NULL && ptr != endptr) { |
1540 |
+ char *keyptr; |
1541 |
+ char *valptr; |
1542 |
+ keyptr = ptr; |
1543 |
+ valptr = strchr(ptr, '='); |
1544 |
+ if (valptr == NULL) { |
1545 |
+ warn("Invalid cache file for '%s/%s': missing val", |
1546 |
+ pkg_ctx->cat_ctx->name, pkg_ctx->name); |
1547 |
+ goto err; |
1548 |
+ } |
1549 |
+ *valptr = '\0'; |
1550 |
+ valptr++; |
1551 |
+ ptr = strchr(valptr, '\n'); |
1552 |
+ if (ptr == NULL) { |
1553 |
+ warn("Invalid cache file for '%s/%s': missing key", |
1554 |
+ pkg_ctx->cat_ctx->name, pkg_ctx->name); |
1555 |
+ goto err; |
1556 |
+ } |
1557 |
+ *ptr = '\0'; |
1558 |
+ ptr++; |
1559 |
+ |
1560 |
+ assign_var(CDEPEND); |
1561 |
+ assign_var(DEPEND); |
1562 |
+ assign_var(DESCRIPTION); |
1563 |
+ assign_var(EAPI); |
1564 |
+ assign_var(HOMEPAGE); |
1565 |
+ assign_var(INHERITED); |
1566 |
+ assign_var(IUSE); |
1567 |
+ assign_var(KEYWORDS); |
1568 |
+ assign_var(LICENSE); |
1569 |
+ assign_var(PDEPEND); |
1570 |
+ assign_var(PROPERTIES); |
1571 |
+ assign_var(PROVIDE); |
1572 |
+ assign_var(RDEPEND); |
1573 |
+ assign_var(RESTRICT); |
1574 |
+ assign_var(SLOT); |
1575 |
+ assign_var(SRC_URI); |
1576 |
+ assign_var(DEFINED_PHASES); |
1577 |
+ assign_var(REQUIRED_USE); |
1578 |
+ assign_var(BDEPEND); |
1579 |
+ assign_var(_eclasses_); |
1580 |
+ assign_var(_md5_); |
1581 |
+ warn("Cache file for '%s/%s' has unknown key %s", |
1582 |
+ pkg_ctx->cat_ctx->name, pkg_ctx->name, keyptr); |
1583 |
+ } |
1584 |
+#undef assign_var |
1585 |
+#undef assign_var_cmp |
1586 |
+ |
1587 |
+ fclose(f); |
1588 |
+ pkg_ctx->fd = -1; |
1589 |
+ |
1590 |
+ return ret; |
1591 |
+ |
1592 |
+err: |
1593 |
+ if (f) |
1594 |
+ fclose(f); |
1595 |
+ pkg_ctx->fd = -1; |
1596 |
+ if (ret) |
1597 |
+ tree_close_meta(ret); |
1598 |
+ return NULL; |
1599 |
+} |
1600 |
+ |
1601 |
+static tree_pkg_meta * |
1602 |
+tree_read_file_ebuild(tree_pkg_ctx *pkg_ctx) |
1603 |
+{ |
1604 |
+ FILE *f; |
1605 |
+ struct stat s; |
1606 |
+ tree_pkg_meta *ret = NULL; |
1607 |
+ size_t len; |
1608 |
+ char *p; |
1609 |
+ char *q; |
1610 |
+ char *w; |
1611 |
+ char **key; |
1612 |
+ bool esc; |
1613 |
+ bool findnl; |
1614 |
+ |
1615 |
+ if ((f = fdopen(pkg_ctx->fd, "r")) == NULL) |
1616 |
+ goto err; |
1617 |
+ |
1618 |
+ if (fstat(pkg_ctx->fd, &s) != 0) |
1619 |
+ goto err; |
1620 |
+ |
1621 |
+ len = sizeof(*ret) + s.st_size + 1; |
1622 |
+ ret = xzalloc(len); |
1623 |
+ p = (char *)ret; |
1624 |
+ ret->_data = p + sizeof(*ret); |
1625 |
+ if ((off_t)fread(ret->_data, 1, s.st_size, f) != s.st_size) |
1626 |
+ goto err; |
1627 |
+ |
1628 |
+ p = ret->_data; |
1629 |
+ do { |
1630 |
+ q = p; |
1631 |
+ while (*p >= 'A' && *p <= 'Z') |
1632 |
+ p++; |
1633 |
+ |
1634 |
+ key = NULL; |
1635 |
+ if (q < p && *p == '=') { |
1636 |
+ *p++ = '\0'; |
1637 |
+ /* match variable against which ones we look for */ |
1638 |
+#define match_key(X) else if (strcmp(q, #X) == 0) key = &ret->X |
1639 |
+ if (1 == 0); /* dummy for syntax */ |
1640 |
+ match_key(DEPEND); |
1641 |
+ match_key(RDEPEND); |
1642 |
+ match_key(SLOT); |
1643 |
+ match_key(SRC_URI); |
1644 |
+ match_key(RESTRICT); |
1645 |
+ match_key(HOMEPAGE); |
1646 |
+ match_key(LICENSE); |
1647 |
+ match_key(DESCRIPTION); |
1648 |
+ match_key(KEYWORDS); |
1649 |
+ match_key(IUSE); |
1650 |
+ match_key(CDEPEND); |
1651 |
+ match_key(PDEPEND); |
1652 |
+ match_key(EAPI); |
1653 |
+ match_key(REQUIRED_USE); |
1654 |
+#undef match_key |
1655 |
+ } |
1656 |
+ |
1657 |
+ findnl = true; |
1658 |
+ if (key != NULL) { |
1659 |
+ q = p; |
1660 |
+ if (*q == '"' || *q == '\'') { |
1661 |
+ /* find matching quote */ |
1662 |
+ p++; |
1663 |
+ w = p; |
1664 |
+ esc = false; |
1665 |
+ do { |
1666 |
+ while (*p != '\0' && *p != *q) { |
1667 |
+ if (*p == '\\') { |
1668 |
+ esc = !esc; |
1669 |
+ if (esc) { |
1670 |
+ p++; |
1671 |
+ continue; |
1672 |
+ } |
1673 |
+ } else { |
1674 |
+ /* implement line continuation (\ before newline) */ |
1675 |
+ if (esc && (*p == '\n' || *p == '\r')) |
1676 |
+ *p = ' '; |
1677 |
+ esc = false; |
1678 |
+ } |
1679 |
+ |
1680 |
+ *w++ = *p++; |
1681 |
+ } |
1682 |
+ if (*p == *q && esc) { |
1683 |
+ /* escaped, move along */ |
1684 |
+ esc = false; |
1685 |
+ *w++ = *p++; |
1686 |
+ continue; |
1687 |
+ } |
1688 |
+ break; |
1689 |
+ } while (1); |
1690 |
+ q++; |
1691 |
+ *w = '\0'; |
1692 |
+ } else { |
1693 |
+ /* find first whitespace */ |
1694 |
+ while (!isspace((int)*p)) |
1695 |
+ p++; |
1696 |
+ if (*p == '\n') |
1697 |
+ findnl = false; |
1698 |
+ } |
1699 |
+ *p++ = '\0'; |
1700 |
+ *key = q; |
1701 |
+ } |
1702 |
+ |
1703 |
+ if (findnl && (p = strchr(p, '\n')) != NULL) |
1704 |
+ p++; |
1705 |
+ } while (p != NULL); |
1706 |
+ |
1707 |
+ fclose(f); |
1708 |
+ pkg_ctx->fd = -1; |
1709 |
+ |
1710 |
+ return ret; |
1711 |
+ |
1712 |
+err: |
1713 |
+ if (f) |
1714 |
+ fclose(f); |
1715 |
+ pkg_ctx->fd = -1; |
1716 |
+ if (ret) |
1717 |
+ tree_close_meta(ret); |
1718 |
+ return NULL; |
1719 |
+} |
1720 |
+ |
1721 |
+tree_pkg_meta * |
1722 |
+tree_pkg_read(tree_pkg_ctx *pkg_ctx) |
1723 |
+{ |
1724 |
+ tree_ctx *ctx = pkg_ctx->cat_ctx->ctx; |
1725 |
+ |
1726 |
+ if (pkg_ctx->fd == -1) { |
1727 |
+ if (ctx->cachetype != CACHE_EBUILD) { |
1728 |
+ pkg_ctx->fd = openat(pkg_ctx->cat_ctx->fd, pkg_ctx->name, |
1729 |
+ O_RDONLY | O_CLOEXEC); |
1730 |
+ } else { |
1731 |
+ char *p = (char *)pkg_ctx->name; |
1732 |
+ p += strlen(p); |
1733 |
+ *p = '.'; |
1734 |
+ pkg_ctx->fd = openat(pkg_ctx->cat_ctx->fd, pkg_ctx->name, |
1735 |
+ O_RDONLY | O_CLOEXEC); |
1736 |
+ *p = '\0'; |
1737 |
+ } |
1738 |
+ if (pkg_ctx->fd == -1) |
1739 |
+ return NULL; |
1740 |
+ } |
1741 |
+ |
1742 |
+ if (ctx->cachetype == CACHE_METADATA_MD5) { |
1743 |
+ return tree_read_file_md5(pkg_ctx); |
1744 |
+ } else if (ctx->cachetype == CACHE_METADATA_PMS) { |
1745 |
+ return tree_read_file_pms(pkg_ctx); |
1746 |
+ } else if (ctx->cachetype == CACHE_EBUILD) { |
1747 |
+ return tree_read_file_ebuild(pkg_ctx); |
1748 |
+ } |
1749 |
+ |
1750 |
+ warn("Unknown metadata cache type!"); |
1751 |
+ return NULL; |
1752 |
+} |
1753 |
+ |
1754 |
+void |
1755 |
+tree_close_meta(tree_pkg_meta *cache) |
1756 |
+{ |
1757 |
+ if (!cache) |
1758 |
+ errf("Cache is empty !"); |
1759 |
+ free(cache); |
1760 |
+} |
1761 |
+ |
1762 |
+tree_metadata_xml * |
1763 |
+tree_pkg_metadata(tree_pkg_ctx *pkg_ctx) |
1764 |
+{ |
1765 |
+ tree_ctx *ctx = pkg_ctx->cat_ctx->ctx; |
1766 |
+ int fd; |
1767 |
+ FILE *f; |
1768 |
+ struct stat s; |
1769 |
+ char *xbuf; |
1770 |
+ char *p; |
1771 |
+ char *q; |
1772 |
+ size_t len; |
1773 |
+ tree_metadata_xml *ret = NULL; |
1774 |
+ struct elist *emailw = NULL; |
1775 |
+ char buf[_Q_PATH_MAX]; |
1776 |
+ |
1777 |
+ /* lame @$$ XML parsing, I don't want to pull in a real parser |
1778 |
+ * library because we only retrieve one element for now: email |
1779 |
+ * technically speaking, email may occur only once in a maintainer |
1780 |
+ * tag, but practically speaking we don't care at all, so we can |
1781 |
+ * just extract everything between <email> and </email> */ |
1782 |
+ |
1783 |
+ if (ctx->cachetype == CACHE_EBUILD) { |
1784 |
+ fd = openat(pkg_ctx->cat_ctx->fd, "metadata", O_RDONLY | O_CLOEXEC); |
1785 |
+ } else { |
1786 |
+ depend_atom *atom; |
1787 |
+ snprintf(buf, sizeof(buf), "%s/%s", |
1788 |
+ pkg_ctx->cat_ctx->name, pkg_ctx->name); |
1789 |
+ atom = atom_explode(buf); |
1790 |
+ snprintf(buf, sizeof(buf), "../../%s/%s/metadata.xml", |
1791 |
+ atom->CATEGORY, atom->PN); |
1792 |
+ atom_implode(atom); |
1793 |
+ fd = openat(ctx->tree_fd, buf, O_RDONLY | O_CLOEXEC); |
1794 |
+ } |
1795 |
+ |
1796 |
+ if (fd == -1) |
1797 |
+ return NULL; |
1798 |
+ |
1799 |
+ if ((f = fdopen(fd, "r")) == NULL) { |
1800 |
+ close(fd); |
1801 |
+ return NULL; |
1802 |
+ } |
1803 |
+ |
1804 |
+ if (fstat(fd, &s) != 0) { |
1805 |
+ fclose(f); |
1806 |
+ return NULL; |
1807 |
+ } |
1808 |
+ |
1809 |
+ len = sizeof(*ret) + s.st_size + 1; |
1810 |
+ p = xbuf = xzalloc(len); |
1811 |
+ if ((off_t)fread(p, 1, s.st_size, f) != s.st_size) { |
1812 |
+ free(p); |
1813 |
+ fclose(f); |
1814 |
+ pkg_ctx->fd = -1; |
1815 |
+ return NULL; |
1816 |
+ } |
1817 |
+ |
1818 |
+ ret = xmalloc(sizeof(*ret)); |
1819 |
+ ret->email = NULL; |
1820 |
+ |
1821 |
+ while ((q = strstr(p, "<email>")) != NULL) { |
1822 |
+ p = q + sizeof("<email>") - 1; |
1823 |
+ if ((q = strstr(p, "</email>")) == NULL) |
1824 |
+ break; |
1825 |
+ *q = '\0'; |
1826 |
+ rmspace(p); |
1827 |
+ if (emailw == NULL) { |
1828 |
+ emailw = ret->email = xmalloc(sizeof(*emailw)); |
1829 |
+ } else { |
1830 |
+ emailw = emailw->next = xmalloc(sizeof(*emailw)); |
1831 |
+ } |
1832 |
+ emailw->next = NULL; |
1833 |
+ emailw->addr = xstrdup(p); |
1834 |
+ p = q + 1; |
1835 |
+ } |
1836 |
+ |
1837 |
+ free(xbuf); |
1838 |
+ fclose(f); |
1839 |
+ return ret; |
1840 |
+} |
1841 |
+ |
1842 |
+void |
1843 |
+tree_close_metadata(tree_metadata_xml *meta_ctx) |
1844 |
+{ |
1845 |
+ struct elist *e; |
1846 |
+ while (meta_ctx->email != NULL) { |
1847 |
+ e = meta_ctx->email; |
1848 |
+ free(e->addr); |
1849 |
+ e = e->next; |
1850 |
+ free(meta_ctx->email); |
1851 |
+ meta_ctx->email = e; |
1852 |
+ } |
1853 |
+ free(meta_ctx); |
1854 |
+} |
1855 |
+ |
1856 |
+void |
1857 |
+tree_close_pkg(tree_pkg_ctx *pkg_ctx) |
1858 |
+{ |
1859 |
+ if (pkg_ctx->fd != -1) |
1860 |
+ close(pkg_ctx->fd); |
1861 |
+ if (pkg_ctx->atom != NULL) |
1862 |
+ atom_implode(pkg_ctx->atom); |
1863 |
+ /* avoid freeing tree_ctx' repo */ |
1864 |
+ if (pkg_ctx->cat_ctx->ctx->repo != pkg_ctx->repo) |
1865 |
+ free(pkg_ctx->repo); |
1866 |
+ free(pkg_ctx->slot); |
1867 |
+ free(pkg_ctx); |
1868 |
+} |
1869 |
+ |
1870 |
+int |
1871 |
+tree_foreach_pkg(tree_ctx *ctx, |
1872 |
+ tree_pkg_cb callback, void *priv, tree_cat_filter filter, |
1873 |
+ bool sort, void *catsortfunc, void *pkgsortfunc) |
1874 |
+{ |
1875 |
+ tree_cat_ctx *cat_ctx; |
1876 |
+ tree_pkg_ctx *pkg_ctx; |
1877 |
+ int ret; |
1878 |
+ |
1879 |
+ if (ctx == NULL) |
1880 |
+ return EXIT_FAILURE; |
1881 |
+ |
1882 |
+ ctx->do_sort = sort; |
1883 |
+ if (catsortfunc != NULL) |
1884 |
+ ctx->catsortfunc = catsortfunc; |
1885 |
+ if (pkgsortfunc != NULL) |
1886 |
+ ctx->pkgsortfunc = pkgsortfunc; |
1887 |
+ |
1888 |
+ ret = 0; |
1889 |
+ while ((cat_ctx = tree_next_cat(ctx))) { |
1890 |
+ if (filter && !filter(cat_ctx, priv)) |
1891 |
+ continue; |
1892 |
+ while ((pkg_ctx = tree_next_pkg(cat_ctx))) { |
1893 |
+ ret |= callback(pkg_ctx, priv); |
1894 |
+ tree_close_pkg(pkg_ctx); |
1895 |
+ } |
1896 |
+ tree_close_cat(cat_ctx); |
1897 |
+ } |
1898 |
+ |
1899 |
+ return ret; |
1900 |
+} |
1901 |
+ |
1902 |
+depend_atom * |
1903 |
+tree_get_atom(tree_pkg_ctx *pkg_ctx, bool complete) |
1904 |
+{ |
1905 |
+ if (pkg_ctx->atom == NULL) { |
1906 |
+ pkg_ctx->atom = atom_explode(pkg_ctx->name); |
1907 |
+ if (pkg_ctx->atom == NULL) |
1908 |
+ return NULL; |
1909 |
+ pkg_ctx->atom->CATEGORY = (char *)pkg_ctx->cat_ctx->name; |
1910 |
+ } |
1911 |
+ |
1912 |
+ if (complete) { |
1913 |
+ tree_ctx *ctx = pkg_ctx->cat_ctx->ctx; |
1914 |
+ if (ctx->cachetype == CACHE_VDB) { |
1915 |
+ if (pkg_ctx->atom->SLOT == NULL) { |
1916 |
+ tree_pkg_vdb_eat(pkg_ctx, "SLOT", |
1917 |
+ &pkg_ctx->slot, &pkg_ctx->slot_len); |
1918 |
+ pkg_ctx->atom->SLOT = pkg_ctx->slot; |
1919 |
+ } |
1920 |
+ if (pkg_ctx->atom->REPO == NULL) { |
1921 |
+ tree_pkg_vdb_eat(pkg_ctx, "repository", |
1922 |
+ &pkg_ctx->repo, &pkg_ctx->repo_len); |
1923 |
+ pkg_ctx->atom->REPO = pkg_ctx->repo; |
1924 |
+ } |
1925 |
+ } else { /* metadata or ebuild */ |
1926 |
+ if (pkg_ctx->atom->SLOT == NULL) { |
1927 |
+ tree_pkg_meta *meta = tree_pkg_read(pkg_ctx); |
1928 |
+ if (meta != NULL) { |
1929 |
+ pkg_ctx->slot = xstrdup(meta->SLOT); |
1930 |
+ pkg_ctx->slot_len = strlen(pkg_ctx->slot); |
1931 |
+ pkg_ctx->atom->SLOT = pkg_ctx->slot; |
1932 |
+ tree_close_meta(meta); |
1933 |
+ } |
1934 |
+ } |
1935 |
+ /* repo is set from the tree, when found */ |
1936 |
+ if (pkg_ctx->atom->REPO == NULL) |
1937 |
+ pkg_ctx->atom->REPO = pkg_ctx->repo; |
1938 |
+ } |
1939 |
+ } |
1940 |
+ |
1941 |
+ return pkg_ctx->atom; |
1942 |
+} |
1943 |
+ |
1944 |
+set * |
1945 |
+tree_get_vdb_atoms(const char *sroot, const char *svdb, int fullcpv) |
1946 |
+{ |
1947 |
+ tree_ctx *ctx; |
1948 |
+ |
1949 |
+ int cfd, j; |
1950 |
+ int dfd, i; |
1951 |
+ |
1952 |
+ char buf[_Q_PATH_MAX]; |
1953 |
+ char slot[_Q_PATH_MAX]; |
1954 |
+ char *slotp = slot; |
1955 |
+ size_t slot_len; |
1956 |
+ |
1957 |
+ struct dirent **cat; |
1958 |
+ struct dirent **pf; |
1959 |
+ |
1960 |
+ depend_atom *atom = NULL; |
1961 |
+ set *cpf = NULL; |
1962 |
+ |
1963 |
+ ctx = tree_open_vdb(sroot, svdb); |
1964 |
+ if (!ctx) |
1965 |
+ return NULL; |
1966 |
+ |
1967 |
+ /* scan the cat first */ |
1968 |
+ cfd = scandirat(ctx->tree_fd, ".", &cat, tree_filter_cat, alphasort); |
1969 |
+ if (cfd < 0) |
1970 |
+ goto fuckit; |
1971 |
+ |
1972 |
+ for (j = 0; j < cfd; j++) { |
1973 |
+ dfd = scandirat(ctx->tree_fd, cat[j]->d_name, |
1974 |
+ &pf, tree_filter_pkg, alphasort); |
1975 |
+ if (dfd < 0) |
1976 |
+ continue; |
1977 |
+ for (i = 0; i < dfd; i++) { |
1978 |
+ int blen = snprintf(buf, sizeof(buf), "%s/%s/SLOT", |
1979 |
+ cat[j]->d_name, pf[i]->d_name); |
1980 |
+ if (blen < 0 || (size_t)blen >= sizeof(buf)) { |
1981 |
+ warnf("unable to parse long package: %s/%s", |
1982 |
+ cat[j]->d_name, pf[i]->d_name); |
1983 |
+ continue; |
1984 |
+ } |
1985 |
+ |
1986 |
+ /* Chop the SLOT for the atom parsing. */ |
1987 |
+ buf[blen - 5] = '\0'; |
1988 |
+ if ((atom = atom_explode(buf)) == NULL) |
1989 |
+ continue; |
1990 |
+ /* Restore the SLOT. */ |
1991 |
+ buf[blen - 5] = '/'; |
1992 |
+ |
1993 |
+ slot_len = sizeof(slot); |
1994 |
+ eat_file_at(ctx->tree_fd, buf, &slotp, &slot_len); |
1995 |
+ rmspace(slot); |
1996 |
+ |
1997 |
+ if (fullcpv) { |
1998 |
+ if (atom->PR_int) |
1999 |
+ snprintf(buf, sizeof(buf), "%s/%s-%s-r%i", |
2000 |
+ atom->CATEGORY, atom->PN, atom->PV, atom->PR_int); |
2001 |
+ else |
2002 |
+ snprintf(buf, sizeof(buf), "%s/%s-%s", |
2003 |
+ atom->CATEGORY, atom->PN, atom->PV); |
2004 |
+ } else { |
2005 |
+ snprintf(buf, sizeof(buf), "%s/%s", atom->CATEGORY, atom->PN); |
2006 |
+ } |
2007 |
+ atom_implode(atom); |
2008 |
+ cpf = add_set(buf, cpf); |
2009 |
+ } |
2010 |
+ scandir_free(pf, dfd); |
2011 |
+ } |
2012 |
+ scandir_free(cat, cfd); |
2013 |
+ |
2014 |
+ fuckit: |
2015 |
+ tree_close(ctx); |
2016 |
+ return cpf; |
2017 |
+} |
2018 |
|
2019 |
diff --git a/libq/tree.h b/libq/tree.h |
2020 |
new file mode 100644 |
2021 |
index 0000000..7f05819 |
2022 |
--- /dev/null |
2023 |
+++ b/libq/tree.h |
2024 |
@@ -0,0 +1,141 @@ |
2025 |
+/* |
2026 |
+ * Copyright 2005-2019 Gentoo Foundation |
2027 |
+ * Distributed under the terms of the GNU General Public License v2 |
2028 |
+ */ |
2029 |
+ |
2030 |
+#ifndef _TREE_H |
2031 |
+#define _TREE_H 1 |
2032 |
+ |
2033 |
+#include <dirent.h> |
2034 |
+#include <stdbool.h> |
2035 |
+ |
2036 |
+#include "atom.h" |
2037 |
+#include "set.h" |
2038 |
+ |
2039 |
+typedef struct tree_ctx tree_ctx; |
2040 |
+typedef struct tree_cat_ctx tree_cat_ctx; |
2041 |
+typedef struct tree_pkg_ctx tree_pkg_ctx; |
2042 |
+typedef struct tree_pkg_meta tree_pkg_meta; |
2043 |
+typedef struct tree_metadata_xml tree_metadata_xml; |
2044 |
+ |
2045 |
+/* VDB context */ |
2046 |
+struct tree_ctx { |
2047 |
+ int portroot_fd; |
2048 |
+ int tree_fd; |
2049 |
+ DIR *dir; |
2050 |
+ struct dirent **cat_de; |
2051 |
+ size_t cat_cnt; |
2052 |
+ size_t cat_cur; |
2053 |
+ void *catsortfunc; |
2054 |
+ void *pkgsortfunc; |
2055 |
+ bool do_sort:1; |
2056 |
+ enum { |
2057 |
+ CACHE_UNSET = 0, |
2058 |
+ CACHE_METADATA_MD5, |
2059 |
+ CACHE_METADATA_PMS, |
2060 |
+ CACHE_EBUILD, |
2061 |
+ CACHE_VDB, |
2062 |
+ } cachetype:3; |
2063 |
+ tree_pkg_ctx *ebuilddir_pkg_ctx; |
2064 |
+ tree_cat_ctx *ebuilddir_cat_ctx; |
2065 |
+ tree_ctx *ebuilddir_ctx; |
2066 |
+ char *repo; |
2067 |
+}; |
2068 |
+ |
2069 |
+/* Category context */ |
2070 |
+struct tree_cat_ctx { |
2071 |
+ const char *name; |
2072 |
+ int fd; |
2073 |
+ DIR *dir; |
2074 |
+ tree_ctx *ctx; |
2075 |
+ struct dirent **pkg_de; |
2076 |
+ size_t pkg_cnt; |
2077 |
+ size_t pkg_cur; |
2078 |
+}; |
2079 |
+ |
2080 |
+/* Package context */ |
2081 |
+struct tree_pkg_ctx { |
2082 |
+ const char *name; |
2083 |
+ char *slot; |
2084 |
+ char *repo; |
2085 |
+ size_t slot_len; |
2086 |
+ size_t repo_len; |
2087 |
+ int fd; |
2088 |
+ tree_cat_ctx *cat_ctx; |
2089 |
+ depend_atom *atom; |
2090 |
+}; |
2091 |
+ |
2092 |
+/* Ebuild data */ |
2093 |
+struct tree_pkg_meta { |
2094 |
+ char *_data; |
2095 |
+ char *DEPEND; /* line 1 */ |
2096 |
+ char *RDEPEND; |
2097 |
+ char *SLOT; |
2098 |
+ char *SRC_URI; |
2099 |
+ char *RESTRICT; /* line 5 */ |
2100 |
+ char *HOMEPAGE; |
2101 |
+ char *LICENSE; |
2102 |
+ char *DESCRIPTION; |
2103 |
+ char *KEYWORDS; |
2104 |
+ char *INHERITED; /* line 10 */ |
2105 |
+ char *IUSE; |
2106 |
+ char *CDEPEND; |
2107 |
+ char *PDEPEND; |
2108 |
+ char *PROVIDE; /* line 14 */ |
2109 |
+ char *EAPI; |
2110 |
+ char *PROPERTIES; |
2111 |
+ /* These are MD5-Cache only */ |
2112 |
+ char *DEFINED_PHASES; |
2113 |
+ char *REQUIRED_USE; |
2114 |
+ char *BDEPEND; |
2115 |
+ char *_eclasses_; |
2116 |
+ char *_md5_; |
2117 |
+}; |
2118 |
+ |
2119 |
+/* Metadata.xml */ |
2120 |
+struct tree_metadata_xml { |
2121 |
+ struct elist { |
2122 |
+ char *addr; |
2123 |
+ struct elist *next; |
2124 |
+ } *email; |
2125 |
+}; |
2126 |
+ |
2127 |
+/* Global helpers */ |
2128 |
+typedef int (tree_pkg_cb)(tree_pkg_ctx *, void *priv); |
2129 |
+typedef int (tree_cat_filter)(tree_cat_ctx *, void *priv); |
2130 |
+ |
2131 |
+tree_ctx *tree_open_vdb(const char *sroot, const char *svdb); |
2132 |
+tree_ctx *tree_open(const char *sroot, const char *portdir); |
2133 |
+void tree_close(tree_ctx *ctx); |
2134 |
+int tree_filter_cat(const struct dirent *de); |
2135 |
+tree_cat_ctx *tree_open_cat(tree_ctx *ctx, const char *name); |
2136 |
+tree_cat_ctx *tree_next_cat(tree_ctx *ctx); |
2137 |
+void tree_close_cat(tree_cat_ctx *cat_ctx); |
2138 |
+int tree_filter_pkg(const struct dirent *de); |
2139 |
+tree_pkg_ctx *tree_open_pkg(tree_cat_ctx *cat_ctx, const char *name); |
2140 |
+tree_pkg_ctx *tree_next_pkg(tree_cat_ctx *cat_ctx); |
2141 |
+int tree_pkg_vdb_openat(tree_pkg_ctx *pkg_ctx, const char *file, int flags, mode_t mode); |
2142 |
+FILE *tree_pkg_vdb_fopenat(tree_pkg_ctx *pkg_ctx, const char *file, |
2143 |
+ int flags, mode_t mode, const char *fmode); |
2144 |
+#define tree_pkg_vdb_fopenat_ro(pkg_ctx, file) \ |
2145 |
+ tree_pkg_vdb_fopenat(pkg_ctx, file, O_RDONLY, 0, "r") |
2146 |
+#define tree_pkg_vdb_fopenat_rw(pkg_ctx, file) \ |
2147 |
+ tree_pkg_vdb_fopenat(pkg_ctx, file, O_RDWR | O_CREAT | O_TRUNC, 0644, "w") |
2148 |
+bool tree_pkg_vdb_eat(tree_pkg_ctx *pkg_ctx, const char *file, char **bufptr, size_t *buflen); |
2149 |
+tree_pkg_meta *tree_pkg_read(tree_pkg_ctx *pkg_ctx); |
2150 |
+void tree_close_meta(tree_pkg_meta *cache); |
2151 |
+tree_metadata_xml *tree_pkg_metadata(tree_pkg_ctx *pkg_ctx); |
2152 |
+void tree_close_metadata(tree_metadata_xml *meta_ctx); |
2153 |
+void tree_close_pkg(tree_pkg_ctx *pkg_ctx); |
2154 |
+int tree_foreach_pkg(tree_ctx *ctx, |
2155 |
+ tree_pkg_cb callback, void *priv, tree_cat_filter filter, |
2156 |
+ bool sort, void *catsortfunc, void *pkgsortfunc); |
2157 |
+#define tree_foreach_pkg_fast(ctx, cb, priv, filter) \ |
2158 |
+ tree_foreach_pkg(ctx, cb, priv, filter, false, NULL, NULL); |
2159 |
+#define tree_foreach_pkg_sorted(ctx, cb, priv) \ |
2160 |
+ tree_foreach_pkg(ctx, cb, priv, NULL, true, NULL, NULL); |
2161 |
+struct dirent *tree_get_next_dir(DIR *dir); |
2162 |
+set *tree_get_vdb_atoms(const char *sroot, const char *svdb, int fullcpv); |
2163 |
+depend_atom *tree_get_atom(tree_pkg_ctx *pkg_ctx, bool complete); |
2164 |
+ |
2165 |
+#endif |
2166 |
|
2167 |
diff --git a/libq/vdb.c b/libq/vdb.c |
2168 |
deleted file mode 100644 |
2169 |
index 810a84c..0000000 |
2170 |
--- a/libq/vdb.c |
2171 |
+++ /dev/null |
2172 |
@@ -1,515 +0,0 @@ |
2173 |
-/* |
2174 |
- * Copyright 2005-2019 Gentoo Foundation |
2175 |
- * Distributed under the terms of the GNU General Public License v2 |
2176 |
- * |
2177 |
- * Copyright 2005-2010 Ned Ludd - <solar@g.o> |
2178 |
- * Copyright 2005-2014 Mike Frysinger - <vapier@g.o> |
2179 |
- * Copyright 2019- Fabian Groffen - <grobian@g.o> |
2180 |
- */ |
2181 |
- |
2182 |
-#include "main.h" |
2183 |
-#include "rmspace.h" |
2184 |
-#include "scandirat.h" |
2185 |
-#include "eat_file.h" |
2186 |
-#include "set.h" |
2187 |
-#include "atom.h" |
2188 |
-#include "vdb.h" |
2189 |
- |
2190 |
-#include <ctype.h> |
2191 |
-#include <xalloc.h> |
2192 |
- |
2193 |
-vdb_ctx * |
2194 |
-vdb_open2(const char *sroot, const char *svdb, bool quiet) |
2195 |
-{ |
2196 |
- vdb_ctx *ctx = xmalloc(sizeof(*ctx)); |
2197 |
- |
2198 |
- ctx->portroot_fd = open(sroot, O_RDONLY|O_CLOEXEC|O_PATH); |
2199 |
- if (ctx->portroot_fd == -1) { |
2200 |
- if (!quiet) |
2201 |
- warnp("could not open root: %s", sroot); |
2202 |
- goto f_error; |
2203 |
- } |
2204 |
- |
2205 |
- /* Skip the leading slash */ |
2206 |
- svdb++; |
2207 |
- if (*svdb == '\0') |
2208 |
- svdb = "."; |
2209 |
- /* Cannot use O_PATH as we want to use fdopendir() */ |
2210 |
- ctx->vdb_fd = openat(ctx->portroot_fd, svdb, O_RDONLY|O_CLOEXEC); |
2211 |
- if (ctx->vdb_fd == -1) { |
2212 |
- if (!quiet) |
2213 |
- warnp("could not open vdb: %s (in root %s)", svdb, sroot); |
2214 |
- goto cp_error; |
2215 |
- } |
2216 |
- |
2217 |
- ctx->dir = fdopendir(ctx->vdb_fd); |
2218 |
- if (ctx->dir == NULL) |
2219 |
- goto cv_error; |
2220 |
- |
2221 |
- ctx->do_sort = false; |
2222 |
- ctx->cat_de = NULL; |
2223 |
- ctx->catsortfunc = alphasort; |
2224 |
- ctx->pkgsortfunc = alphasort; |
2225 |
- ctx->repo = NULL; |
2226 |
- ctx->ebuilddir_ctx = NULL; |
2227 |
- ctx->ebuilddir_pkg_ctx = NULL; |
2228 |
- return ctx; |
2229 |
- |
2230 |
- cv_error: |
2231 |
- close(ctx->vdb_fd); |
2232 |
- cp_error: |
2233 |
- close(ctx->portroot_fd); |
2234 |
- f_error: |
2235 |
- free(ctx); |
2236 |
- return NULL; |
2237 |
-} |
2238 |
- |
2239 |
-vdb_ctx * |
2240 |
-vdb_open(const char *sroot, const char *svdb) |
2241 |
-{ |
2242 |
- return vdb_open2(sroot, svdb, false); |
2243 |
-} |
2244 |
- |
2245 |
-void |
2246 |
-vdb_close(vdb_ctx *ctx) |
2247 |
-{ |
2248 |
- closedir(ctx->dir); |
2249 |
- /* closedir() above does this for us: */ |
2250 |
- /* close(ctx->vdb_fd); */ |
2251 |
- close(ctx->portroot_fd); |
2252 |
- if (ctx->do_sort) |
2253 |
- scandir_free(ctx->cat_de, ctx->cat_cnt); |
2254 |
- free(ctx); |
2255 |
-} |
2256 |
- |
2257 |
-int |
2258 |
-vdb_filter_cat(const struct dirent *de) |
2259 |
-{ |
2260 |
- int i; |
2261 |
- bool founddash; |
2262 |
- |
2263 |
-#ifdef DT_UNKNOWN |
2264 |
- /* cat must be a dir */ |
2265 |
- if (de->d_type != DT_UNKNOWN && |
2266 |
- de->d_type != DT_DIR && |
2267 |
- de->d_type != DT_LNK) |
2268 |
- return 0; |
2269 |
-#endif |
2270 |
- |
2271 |
- /* PMS 3.1.1 */ |
2272 |
- founddash = false; |
2273 |
- for (i = 0; de->d_name[i] != '\0'; i++) { |
2274 |
- switch (de->d_name[i]) { |
2275 |
- case '_': |
2276 |
- break; |
2277 |
- case '-': |
2278 |
- founddash = true; |
2279 |
- /* fall through */ |
2280 |
- case '+': |
2281 |
- case '.': |
2282 |
- if (i) |
2283 |
- break; |
2284 |
- return 0; |
2285 |
- default: |
2286 |
- if ((de->d_name[i] >= 'A' && de->d_name[i] <= 'Z') || |
2287 |
- (de->d_name[i] >= 'a' && de->d_name[i] <= 'z') || |
2288 |
- (de->d_name[i] >= '0' && de->d_name[i] <= '9')) |
2289 |
- break; |
2290 |
- return 0; |
2291 |
- } |
2292 |
- } |
2293 |
- if (!founddash && strcmp(de->d_name, "virtual") != 0) |
2294 |
- return 0; |
2295 |
- |
2296 |
- return i; |
2297 |
-} |
2298 |
- |
2299 |
-vdb_cat_ctx * |
2300 |
-vdb_open_cat(vdb_ctx *ctx, const char *name) |
2301 |
-{ |
2302 |
- vdb_cat_ctx *cat_ctx; |
2303 |
- int fd; |
2304 |
- DIR *dir; |
2305 |
- |
2306 |
- /* Cannot use O_PATH as we want to use fdopendir() */ |
2307 |
- fd = openat(ctx->vdb_fd, name, O_RDONLY|O_CLOEXEC); |
2308 |
- if (fd == -1) |
2309 |
- return NULL; |
2310 |
- |
2311 |
- dir = fdopendir(fd); |
2312 |
- if (!dir) { |
2313 |
- close(fd); |
2314 |
- return NULL; |
2315 |
- } |
2316 |
- |
2317 |
- cat_ctx = xmalloc(sizeof(*cat_ctx)); |
2318 |
- cat_ctx->name = name; |
2319 |
- cat_ctx->fd = fd; |
2320 |
- cat_ctx->dir = dir; |
2321 |
- cat_ctx->ctx = ctx; |
2322 |
- cat_ctx->pkg_de = NULL; |
2323 |
- return cat_ctx; |
2324 |
-} |
2325 |
- |
2326 |
-vdb_cat_ctx * |
2327 |
-vdb_next_cat(vdb_ctx *ctx) |
2328 |
-{ |
2329 |
- /* search for a category directory */ |
2330 |
- vdb_cat_ctx *cat_ctx = NULL; |
2331 |
- |
2332 |
- if (ctx->do_sort) { |
2333 |
- if (ctx->cat_de == NULL) { |
2334 |
- ctx->cat_cnt = scandirat(ctx->vdb_fd, |
2335 |
- ".", &ctx->cat_de, vdb_filter_cat, ctx->catsortfunc); |
2336 |
- ctx->cat_cur = 0; |
2337 |
- } |
2338 |
- |
2339 |
- while (ctx->cat_cur < ctx->cat_cnt) { |
2340 |
- cat_ctx = vdb_open_cat(ctx, ctx->cat_de[ctx->cat_cur++]->d_name); |
2341 |
- if (!cat_ctx) |
2342 |
- continue; |
2343 |
- break; |
2344 |
- } |
2345 |
- } else { |
2346 |
- /* cheaper "streaming" variant */ |
2347 |
- const struct dirent *de; |
2348 |
- do { |
2349 |
- de = readdir(ctx->dir); |
2350 |
- if (!de) |
2351 |
- break; |
2352 |
- |
2353 |
- if (vdb_filter_cat(de) == 0) |
2354 |
- continue; |
2355 |
- |
2356 |
- cat_ctx = vdb_open_cat(ctx, de->d_name); |
2357 |
- if (!cat_ctx) |
2358 |
- continue; |
2359 |
- |
2360 |
- break; |
2361 |
- } while (1); |
2362 |
- } |
2363 |
- |
2364 |
- return cat_ctx; |
2365 |
-} |
2366 |
- |
2367 |
-void |
2368 |
-vdb_close_cat(vdb_cat_ctx *cat_ctx) |
2369 |
-{ |
2370 |
- closedir(cat_ctx->dir); |
2371 |
- /* closedir() above does this for us: */ |
2372 |
- /* close(ctx->fd); */ |
2373 |
- if (cat_ctx->ctx->do_sort) |
2374 |
- scandir_free(cat_ctx->pkg_de, cat_ctx->pkg_cnt); |
2375 |
- free(cat_ctx); |
2376 |
-} |
2377 |
- |
2378 |
-int |
2379 |
-vdb_filter_pkg(const struct dirent *de) |
2380 |
-{ |
2381 |
- int i; |
2382 |
- bool founddash = false; |
2383 |
- |
2384 |
- /* PMS 3.1.2 */ |
2385 |
- for (i = 0; de->d_name[i] != '\0'; i++) { |
2386 |
- switch (de->d_name[i]) { |
2387 |
- case '_': |
2388 |
- break; |
2389 |
- case '-': |
2390 |
- founddash = true; |
2391 |
- /* fall through */ |
2392 |
- case '+': |
2393 |
- if (i) |
2394 |
- break; |
2395 |
- return 0; |
2396 |
- default: |
2397 |
- if ((de->d_name[i] >= 'A' && de->d_name[i] <= 'Z') || |
2398 |
- (de->d_name[i] >= 'a' && de->d_name[i] <= 'z') || |
2399 |
- (de->d_name[i] >= '0' && de->d_name[i] <= '9')) |
2400 |
- break; |
2401 |
- if (founddash) |
2402 |
- return 1; |
2403 |
- return 0; |
2404 |
- } |
2405 |
- } |
2406 |
- |
2407 |
- return i; |
2408 |
-} |
2409 |
- |
2410 |
-vdb_pkg_ctx * |
2411 |
-vdb_open_pkg(vdb_cat_ctx *cat_ctx, const char *name) |
2412 |
-{ |
2413 |
- vdb_pkg_ctx *pkg_ctx = xmalloc(sizeof(*pkg_ctx)); |
2414 |
- pkg_ctx->name = name; |
2415 |
- pkg_ctx->slot = NULL; |
2416 |
- pkg_ctx->repo = cat_ctx->ctx->repo; |
2417 |
- pkg_ctx->fd = -1; |
2418 |
- pkg_ctx->cat_ctx = cat_ctx; |
2419 |
- pkg_ctx->atom = NULL; |
2420 |
- return pkg_ctx; |
2421 |
-} |
2422 |
- |
2423 |
-vdb_pkg_ctx * |
2424 |
-vdb_next_pkg(vdb_cat_ctx *cat_ctx) |
2425 |
-{ |
2426 |
- vdb_pkg_ctx *pkg_ctx = NULL; |
2427 |
- |
2428 |
- if (cat_ctx->ctx->do_sort) { |
2429 |
- if (cat_ctx->pkg_de == NULL) { |
2430 |
- cat_ctx->pkg_cnt = scandirat(cat_ctx->fd, ".", &cat_ctx->pkg_de, |
2431 |
- vdb_filter_pkg, cat_ctx->ctx->pkgsortfunc); |
2432 |
- cat_ctx->pkg_cur = 0; |
2433 |
- } |
2434 |
- |
2435 |
- while (cat_ctx->pkg_cur < cat_ctx->pkg_cnt) { |
2436 |
- pkg_ctx = |
2437 |
- vdb_open_pkg(cat_ctx, |
2438 |
- cat_ctx->pkg_de[cat_ctx->pkg_cur++]->d_name); |
2439 |
- if (!pkg_ctx) |
2440 |
- continue; |
2441 |
- break; |
2442 |
- } |
2443 |
- } else { |
2444 |
- const struct dirent *de; |
2445 |
- do { |
2446 |
- de = readdir(cat_ctx->dir); |
2447 |
- if (!de) |
2448 |
- break; |
2449 |
- |
2450 |
- if (vdb_filter_pkg(de) == 0) |
2451 |
- continue; |
2452 |
- |
2453 |
- pkg_ctx = vdb_open_pkg(cat_ctx, de->d_name); |
2454 |
- if (!pkg_ctx) |
2455 |
- continue; |
2456 |
- |
2457 |
- break; |
2458 |
- } while (1); |
2459 |
- } |
2460 |
- |
2461 |
- return pkg_ctx; |
2462 |
-} |
2463 |
- |
2464 |
-int |
2465 |
-vdb_pkg_openat(vdb_pkg_ctx *pkg_ctx, const char *file, int flags, mode_t mode) |
2466 |
-{ |
2467 |
- if (pkg_ctx->fd == -1) { |
2468 |
- pkg_ctx->fd = openat(pkg_ctx->cat_ctx->fd, pkg_ctx->name, |
2469 |
- O_RDONLY|O_CLOEXEC|O_PATH); |
2470 |
- if (pkg_ctx->fd == -1) |
2471 |
- return -1; |
2472 |
- } |
2473 |
- |
2474 |
- return openat(pkg_ctx->fd, file, flags|O_CLOEXEC, mode); |
2475 |
-} |
2476 |
- |
2477 |
-FILE * |
2478 |
-vdb_pkg_fopenat(vdb_pkg_ctx *pkg_ctx, const char *file, |
2479 |
- int flags, mode_t mode, const char *fmode) |
2480 |
-{ |
2481 |
- FILE *fp; |
2482 |
- int fd; |
2483 |
- |
2484 |
- fd = vdb_pkg_openat(pkg_ctx, file, flags, mode); |
2485 |
- if (fd == -1) |
2486 |
- return NULL; |
2487 |
- |
2488 |
- fp = fdopen(fd, fmode); |
2489 |
- if (!fp) |
2490 |
- close(fd); |
2491 |
- |
2492 |
- return fp; |
2493 |
-} |
2494 |
- |
2495 |
-bool |
2496 |
-vdb_pkg_eat(vdb_pkg_ctx *pkg_ctx, const char *file, char **bufptr, size_t *buflen) |
2497 |
-{ |
2498 |
- int fd = vdb_pkg_openat(pkg_ctx, file, O_RDONLY, 0); |
2499 |
- bool ret = eat_file_fd(fd, bufptr, buflen); |
2500 |
- rmspace(*bufptr); |
2501 |
- if (fd != -1) |
2502 |
- close(fd); |
2503 |
- return ret; |
2504 |
-} |
2505 |
- |
2506 |
-void |
2507 |
-vdb_close_pkg(vdb_pkg_ctx *pkg_ctx) |
2508 |
-{ |
2509 |
- if (pkg_ctx->fd != -1) |
2510 |
- close(pkg_ctx->fd); |
2511 |
- if (pkg_ctx->atom != NULL) |
2512 |
- atom_implode(pkg_ctx->atom); |
2513 |
- free(pkg_ctx->slot); |
2514 |
- free(pkg_ctx->repo); |
2515 |
- free(pkg_ctx); |
2516 |
-} |
2517 |
- |
2518 |
-static int |
2519 |
-vdb_foreach_pkg_int(const char *sroot, const char *svdb, |
2520 |
- vdb_pkg_cb callback, void *priv, vdb_cat_filter filter, |
2521 |
- bool sort, void *catsortfunc, void *pkgsortfunc) |
2522 |
-{ |
2523 |
- vdb_ctx *ctx; |
2524 |
- vdb_cat_ctx *cat_ctx; |
2525 |
- vdb_pkg_ctx *pkg_ctx; |
2526 |
- int ret; |
2527 |
- |
2528 |
- ctx = vdb_open(sroot, svdb); |
2529 |
- if (!ctx) |
2530 |
- return EXIT_FAILURE; |
2531 |
- |
2532 |
- ctx->do_sort = sort; |
2533 |
- if (catsortfunc != NULL) |
2534 |
- ctx->catsortfunc = catsortfunc; |
2535 |
- if (pkgsortfunc != NULL) |
2536 |
- ctx->pkgsortfunc = pkgsortfunc; |
2537 |
- |
2538 |
- ret = 0; |
2539 |
- while ((cat_ctx = vdb_next_cat(ctx))) { |
2540 |
- if (filter && !filter(cat_ctx, priv)) |
2541 |
- continue; |
2542 |
- while ((pkg_ctx = vdb_next_pkg(cat_ctx))) { |
2543 |
- ret |= callback(pkg_ctx, priv); |
2544 |
- vdb_close_pkg(pkg_ctx); |
2545 |
- } |
2546 |
- vdb_close_cat(cat_ctx); |
2547 |
- } |
2548 |
- vdb_close(ctx); |
2549 |
- |
2550 |
- return ret; |
2551 |
-} |
2552 |
- |
2553 |
-int |
2554 |
-vdb_foreach_pkg(const char *sroot, const char *svdb, |
2555 |
- vdb_pkg_cb callback, void *priv, vdb_cat_filter filter) |
2556 |
-{ |
2557 |
- return vdb_foreach_pkg_int(sroot, svdb, callback, priv, |
2558 |
- filter, false, NULL, NULL); |
2559 |
-} |
2560 |
- |
2561 |
-int |
2562 |
-vdb_foreach_pkg_sorted(const char *sroot, const char *svdb, |
2563 |
- vdb_pkg_cb callback, void *priv) |
2564 |
-{ |
2565 |
- return vdb_foreach_pkg_int(sroot, svdb, callback, priv, |
2566 |
- NULL, true, NULL, NULL); |
2567 |
-} |
2568 |
- |
2569 |
-struct dirent * |
2570 |
-vdb_get_next_dir(DIR *dir) |
2571 |
-{ |
2572 |
- /* search for a category directory */ |
2573 |
- struct dirent *ret; |
2574 |
- |
2575 |
-next_entry: |
2576 |
- ret = readdir(dir); |
2577 |
- if (ret == NULL) { |
2578 |
- closedir(dir); |
2579 |
- return NULL; |
2580 |
- } |
2581 |
- |
2582 |
- if (vdb_filter_cat(ret) == 0) |
2583 |
- goto next_entry; |
2584 |
- |
2585 |
- return ret; |
2586 |
-} |
2587 |
- |
2588 |
-depend_atom * |
2589 |
-vdb_get_atom(vdb_pkg_ctx *pkg_ctx, bool complete) |
2590 |
-{ |
2591 |
- if (pkg_ctx->atom == NULL) { |
2592 |
- pkg_ctx->atom = atom_explode(pkg_ctx->name); |
2593 |
- if (pkg_ctx->atom == NULL) |
2594 |
- return NULL; |
2595 |
- pkg_ctx->atom->CATEGORY = (char *)pkg_ctx->cat_ctx->name; |
2596 |
- } |
2597 |
- |
2598 |
- if (complete) { |
2599 |
- if (pkg_ctx->atom->SLOT == NULL) { |
2600 |
- vdb_pkg_eat(pkg_ctx, "SLOT", |
2601 |
- &pkg_ctx->slot, &pkg_ctx->slot_len); |
2602 |
- pkg_ctx->atom->SLOT = pkg_ctx->slot; |
2603 |
- } |
2604 |
- if (pkg_ctx->atom->REPO == NULL) { |
2605 |
- vdb_pkg_eat(pkg_ctx, "repository", |
2606 |
- &pkg_ctx->repo, &pkg_ctx->repo_len); |
2607 |
- pkg_ctx->atom->REPO = pkg_ctx->repo; |
2608 |
- } |
2609 |
- } |
2610 |
- |
2611 |
- return pkg_ctx->atom; |
2612 |
-} |
2613 |
- |
2614 |
-set * |
2615 |
-get_vdb_atoms(const char *sroot, const char *svdb, int fullcpv) |
2616 |
-{ |
2617 |
- vdb_ctx *ctx; |
2618 |
- |
2619 |
- int cfd, j; |
2620 |
- int dfd, i; |
2621 |
- |
2622 |
- char buf[_Q_PATH_MAX]; |
2623 |
- char slot[_Q_PATH_MAX]; |
2624 |
- char *slotp = slot; |
2625 |
- size_t slot_len; |
2626 |
- |
2627 |
- struct dirent **cat; |
2628 |
- struct dirent **pf; |
2629 |
- |
2630 |
- depend_atom *atom = NULL; |
2631 |
- set *cpf = NULL; |
2632 |
- |
2633 |
- ctx = vdb_open(sroot, svdb); |
2634 |
- if (!ctx) |
2635 |
- return NULL; |
2636 |
- |
2637 |
- /* scan the cat first */ |
2638 |
- cfd = scandirat(ctx->vdb_fd, ".", &cat, vdb_filter_cat, alphasort); |
2639 |
- if (cfd < 0) |
2640 |
- goto fuckit; |
2641 |
- |
2642 |
- for (j = 0; j < cfd; j++) { |
2643 |
- dfd = scandirat(ctx->vdb_fd, cat[j]->d_name, |
2644 |
- &pf, vdb_filter_pkg, alphasort); |
2645 |
- if (dfd < 0) |
2646 |
- continue; |
2647 |
- for (i = 0; i < dfd; i++) { |
2648 |
- int blen = snprintf(buf, sizeof(buf), "%s/%s/SLOT", |
2649 |
- cat[j]->d_name, pf[i]->d_name); |
2650 |
- if (blen < 0 || (size_t)blen >= sizeof(buf)) { |
2651 |
- warnf("unable to parse long package: %s/%s", |
2652 |
- cat[j]->d_name, pf[i]->d_name); |
2653 |
- continue; |
2654 |
- } |
2655 |
- |
2656 |
- /* Chop the SLOT for the atom parsing. */ |
2657 |
- buf[blen - 5] = '\0'; |
2658 |
- if ((atom = atom_explode(buf)) == NULL) |
2659 |
- continue; |
2660 |
- /* Restore the SLOT. */ |
2661 |
- buf[blen - 5] = '/'; |
2662 |
- |
2663 |
- slot_len = sizeof(slot); |
2664 |
- eat_file_at(ctx->vdb_fd, buf, &slotp, &slot_len); |
2665 |
- rmspace(slot); |
2666 |
- |
2667 |
- if (fullcpv) { |
2668 |
- if (atom->PR_int) |
2669 |
- snprintf(buf, sizeof(buf), "%s/%s-%s-r%i", |
2670 |
- atom->CATEGORY, atom->PN, atom->PV, atom->PR_int); |
2671 |
- else |
2672 |
- snprintf(buf, sizeof(buf), "%s/%s-%s", |
2673 |
- atom->CATEGORY, atom->PN, atom->PV); |
2674 |
- } else { |
2675 |
- snprintf(buf, sizeof(buf), "%s/%s", atom->CATEGORY, atom->PN); |
2676 |
- } |
2677 |
- atom_implode(atom); |
2678 |
- cpf = add_set(buf, cpf); |
2679 |
- } |
2680 |
- scandir_free(pf, dfd); |
2681 |
- } |
2682 |
- scandir_free(cat, cfd); |
2683 |
- |
2684 |
- fuckit: |
2685 |
- vdb_close(ctx); |
2686 |
- return cpf; |
2687 |
-} |
2688 |
|
2689 |
diff --git a/libq/vdb.h b/libq/vdb.h |
2690 |
deleted file mode 100644 |
2691 |
index 28ca040..0000000 |
2692 |
--- a/libq/vdb.h |
2693 |
+++ /dev/null |
2694 |
@@ -1,96 +0,0 @@ |
2695 |
-/* |
2696 |
- * Copyright 2005-2019 Gentoo Foundation |
2697 |
- * Distributed under the terms of the GNU General Public License v2 |
2698 |
- */ |
2699 |
- |
2700 |
-#ifndef _VDB_H |
2701 |
-#define _VDB_H 1 |
2702 |
- |
2703 |
-#include <dirent.h> |
2704 |
-#include <stdbool.h> |
2705 |
- |
2706 |
-#include "set.h" |
2707 |
- |
2708 |
-typedef struct vdb_ctx vdb_ctx; |
2709 |
-typedef struct vdb_cat_ctx vdb_cat_ctx; |
2710 |
-typedef struct vdb_pkg_ctx vdb_pkg_ctx; |
2711 |
- |
2712 |
-/* VDB context */ |
2713 |
-struct vdb_ctx { |
2714 |
- int portroot_fd; |
2715 |
- int vdb_fd; |
2716 |
- DIR *dir; |
2717 |
- struct dirent **cat_de; |
2718 |
- size_t cat_cnt; |
2719 |
- size_t cat_cur; |
2720 |
- void *catsortfunc; |
2721 |
- void *pkgsortfunc; |
2722 |
- bool do_sort:1; |
2723 |
- enum { |
2724 |
- CACHE_UNSET = 0, |
2725 |
- CACHE_METADATA_MD5, |
2726 |
- CACHE_METADATA_PMS, |
2727 |
- CACHE_EBUILD, |
2728 |
- CACHE_VDB, |
2729 |
- } cachetype:3; |
2730 |
- vdb_pkg_ctx *ebuilddir_pkg_ctx; |
2731 |
- vdb_cat_ctx *ebuilddir_cat_ctx; |
2732 |
- vdb_ctx *ebuilddir_ctx; |
2733 |
- char *repo; |
2734 |
-}; |
2735 |
- |
2736 |
-/* Category context */ |
2737 |
-struct vdb_cat_ctx { |
2738 |
- const char *name; |
2739 |
- int fd; |
2740 |
- DIR *dir; |
2741 |
- const vdb_ctx *ctx; |
2742 |
- struct dirent **pkg_de; |
2743 |
- size_t pkg_cnt; |
2744 |
- size_t pkg_cur; |
2745 |
-}; |
2746 |
- |
2747 |
-/* Package context */ |
2748 |
-struct vdb_pkg_ctx { |
2749 |
- const char *name; |
2750 |
- char *slot; |
2751 |
- char *repo; |
2752 |
- size_t slot_len; |
2753 |
- size_t repo_len; |
2754 |
- int fd; |
2755 |
- vdb_cat_ctx *cat_ctx; |
2756 |
- depend_atom *atom; |
2757 |
-}; |
2758 |
- |
2759 |
-/* Global helpers */ |
2760 |
-typedef int (vdb_pkg_cb)(vdb_pkg_ctx *, void *priv); |
2761 |
-typedef int (vdb_cat_filter)(vdb_cat_ctx *, void *priv); |
2762 |
- |
2763 |
-vdb_ctx *vdb_open(const char *sroot, const char *svdb); |
2764 |
-vdb_ctx *vdb_open2(const char *sroot, const char *svdb, bool quiet); |
2765 |
-void vdb_close(vdb_ctx *ctx); |
2766 |
-int vdb_filter_cat(const struct dirent *de); |
2767 |
-vdb_cat_ctx *vdb_open_cat(vdb_ctx *ctx, const char *name); |
2768 |
-vdb_cat_ctx *vdb_next_cat(vdb_ctx *ctx); |
2769 |
-void vdb_close_cat(vdb_cat_ctx *cat_ctx); |
2770 |
-int vdb_filter_pkg(const struct dirent *de); |
2771 |
-vdb_pkg_ctx *vdb_open_pkg(vdb_cat_ctx *cat_ctx, const char *name); |
2772 |
-vdb_pkg_ctx *vdb_next_pkg(vdb_cat_ctx *cat_ctx); |
2773 |
-int vdb_pkg_openat(vdb_pkg_ctx *pkg_ctx, const char *file, int flags, mode_t mode); |
2774 |
-FILE *vdb_pkg_fopenat(vdb_pkg_ctx *pkg_ctx, const char *file, |
2775 |
- int flags, mode_t mode, const char *fmode); |
2776 |
-#define vdb_pkg_fopenat_ro(pkg_ctx, file) \ |
2777 |
- vdb_pkg_fopenat(pkg_ctx, file, O_RDONLY, 0, "r") |
2778 |
-#define vdb_pkg_fopenat_rw(pkg_ctx, file) \ |
2779 |
- vdb_pkg_fopenat(pkg_ctx, file, O_RDWR|O_CREAT|O_TRUNC, 0644, "w") |
2780 |
-bool vdb_pkg_eat(vdb_pkg_ctx *pkg_ctx, const char *file, char **bufptr, size_t *buflen); |
2781 |
-void vdb_close_pkg(vdb_pkg_ctx *pkg_ctx); |
2782 |
-int vdb_foreach_pkg(const char *sroot, const char *svdb, |
2783 |
- vdb_pkg_cb callback, void *priv, vdb_cat_filter filter); |
2784 |
-int vdb_foreach_pkg_sorted(const char *sroot, const char *svdb, |
2785 |
- vdb_pkg_cb callback, void *priv); |
2786 |
-struct dirent *vdb_get_next_dir(DIR *dir); |
2787 |
-set *get_vdb_atoms(const char *sroot, const char *svdb, int fullcpv); |
2788 |
-depend_atom *vdb_get_atom(vdb_pkg_ctx *pkg_ctx, bool complete); |
2789 |
- |
2790 |
-#endif |
2791 |
|
2792 |
diff --git a/main.c b/main.c |
2793 |
index 159b262..944950e 100644 |
2794 |
--- a/main.c |
2795 |
+++ b/main.c |
2796 |
@@ -17,30 +17,10 @@ |
2797 |
#include <sys/time.h> |
2798 |
#include <limits.h> |
2799 |
|
2800 |
-#include "atom.h" |
2801 |
-#include "basename.h" |
2802 |
-#include "busybox.h" |
2803 |
-#include "cache.h" |
2804 |
-#include "colors.h" |
2805 |
-#include "copy_file.h" |
2806 |
#include "eat_file.h" |
2807 |
-#include "hash_fd.h" |
2808 |
-#include "human_readable.h" |
2809 |
-#include "i18n.h" |
2810 |
-#include "md5_sha1_sum.h" |
2811 |
-#include "prelink.h" |
2812 |
-#include "profile.h" |
2813 |
#include "rmspace.h" |
2814 |
-#include "safe_io.h" |
2815 |
#include "scandirat.h" |
2816 |
-#include "set.h" |
2817 |
-#include "vdb.h" |
2818 |
-#include "xarray.h" |
2819 |
#include "xasprintf.h" |
2820 |
-#include "xchdir.h" |
2821 |
-#include "xmkdir.h" |
2822 |
-#include "xregex.h" |
2823 |
-#include "xsystem.h" |
2824 |
|
2825 |
/* variables to control runtime behavior */ |
2826 |
char *module_name = NULL; |
2827 |
|
2828 |
diff --git a/q.c b/q.c |
2829 |
index a18c791..b6486ee 100644 |
2830 |
--- a/q.c |
2831 |
+++ b/q.c |
2832 |
@@ -19,9 +19,7 @@ |
2833 |
#include <libproc.h> |
2834 |
#endif |
2835 |
|
2836 |
-#include "atom.h" |
2837 |
#include "basename.h" |
2838 |
-#include "cache.h" |
2839 |
|
2840 |
#define Q_FLAGS "iM:" COMMON_FLAGS |
2841 |
static struct option const q_long_opts[] = { |
2842 |
|
2843 |
diff --git a/qcheck.c b/qcheck.c |
2844 |
index 68cdb30..a26b25d 100644 |
2845 |
--- a/qcheck.c |
2846 |
+++ b/qcheck.c |
2847 |
@@ -20,7 +20,7 @@ |
2848 |
#include "md5_sha1_sum.h" |
2849 |
#include "prelink.h" |
2850 |
#include "set.h" |
2851 |
-#include "vdb.h" |
2852 |
+#include "tree.h" |
2853 |
#include "xarray.h" |
2854 |
#include "xasprintf.h" |
2855 |
#include "xregex.h" |
2856 |
@@ -65,7 +65,7 @@ struct qcheck_opt_state { |
2857 |
}; |
2858 |
|
2859 |
static int |
2860 |
-qcheck_process_contents(vdb_pkg_ctx *pkg_ctx, struct qcheck_opt_state *state) |
2861 |
+qcheck_process_contents(tree_pkg_ctx *pkg_ctx, struct qcheck_opt_state *state) |
2862 |
{ |
2863 |
int fd_contents; |
2864 |
FILE *fp_contents, *fp_contents_update; |
2865 |
@@ -80,7 +80,8 @@ qcheck_process_contents(vdb_pkg_ctx *pkg_ctx, struct qcheck_opt_state *state) |
2866 |
fp_contents_update = NULL; |
2867 |
|
2868 |
/* Open contents */ |
2869 |
- fd_contents = vdb_pkg_openat(pkg_ctx, "CONTENTS", O_RDONLY|O_CLOEXEC, 0); |
2870 |
+ fd_contents = tree_pkg_vdb_openat(pkg_ctx, "CONTENTS", |
2871 |
+ O_RDONLY | O_CLOEXEC, 0); |
2872 |
if (fd_contents == -1) |
2873 |
return EXIT_SUCCESS; |
2874 |
if (fstat(fd_contents, &cst)) { |
2875 |
@@ -93,13 +94,13 @@ qcheck_process_contents(vdb_pkg_ctx *pkg_ctx, struct qcheck_opt_state *state) |
2876 |
} |
2877 |
|
2878 |
/* Open contents_update, if needed */ |
2879 |
- atom = vdb_get_atom(pkg_ctx, false); |
2880 |
+ atom = tree_get_atom(pkg_ctx, false); |
2881 |
num_files = num_files_ok = num_files_unknown = num_files_ignored = 0; |
2882 |
qcprintf("%sing %s ...\n", |
2883 |
(state->qc_update ? "Updat" : "Check"), |
2884 |
atom_format("%[CATEGORY]%[PF]", atom, 0)); |
2885 |
if (state->qc_update) { |
2886 |
- fp_contents_update = vdb_pkg_fopenat_rw(pkg_ctx, "CONTENTS~"); |
2887 |
+ fp_contents_update = tree_pkg_vdb_fopenat_rw(pkg_ctx, "CONTENTS~"); |
2888 |
if (fp_contents_update == NULL) { |
2889 |
fclose(fp_contents); |
2890 |
warnp("unable to fopen(%s/%s, w)", atom->P, "CONTENTS~"); |
2891 |
@@ -355,7 +356,7 @@ qcheck_process_contents(vdb_pkg_ctx *pkg_ctx, struct qcheck_opt_state *state) |
2892 |
} |
2893 |
|
2894 |
static int |
2895 |
-qcheck_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
2896 |
+qcheck_cb(tree_pkg_ctx *pkg_ctx, void *priv) |
2897 |
{ |
2898 |
struct qcheck_opt_state *state = priv; |
2899 |
bool showit = false; |
2900 |
@@ -366,7 +367,7 @@ qcheck_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
2901 |
depend_atom *qatom; |
2902 |
depend_atom *atom; |
2903 |
|
2904 |
- qatom = vdb_get_atom(pkg_ctx, false); |
2905 |
+ qatom = tree_get_atom(pkg_ctx, false); |
2906 |
array_for_each(state->atoms, i, atom) { |
2907 |
if (atom_compare(atom, qatom) == EQUAL) { |
2908 |
showit = true; |
2909 |
@@ -384,6 +385,7 @@ int qcheck_main(int argc, char **argv) |
2910 |
{ |
2911 |
size_t i; |
2912 |
int ret; |
2913 |
+ tree_ctx *vdb; |
2914 |
DECLARE_ARRAY(regex_arr); |
2915 |
depend_atom *atom; |
2916 |
DECLARE_ARRAY(atoms); |
2917 |
@@ -403,9 +405,9 @@ int qcheck_main(int argc, char **argv) |
2918 |
switch (ret) { |
2919 |
COMMON_GETOPTS_CASES(qcheck) |
2920 |
case 's': { |
2921 |
- regex_t regex; |
2922 |
- xregcomp(®ex, optarg, REG_EXTENDED|REG_NOSUB); |
2923 |
- xarraypush(regex_arr, ®ex, sizeof(regex)); |
2924 |
+ regex_t preg; |
2925 |
+ xregcomp(&preg, optarg, REG_EXTENDED | REG_NOSUB); |
2926 |
+ xarraypush(regex_arr, &preg, sizeof(preg)); |
2927 |
break; |
2928 |
} |
2929 |
case 'u': state.qc_update = true; break; |
2930 |
@@ -428,11 +430,16 @@ int qcheck_main(int argc, char **argv) |
2931 |
xarraypush_ptr(atoms, atom); |
2932 |
} |
2933 |
|
2934 |
- ret = vdb_foreach_pkg_sorted(portroot, portvdb, qcheck_cb, &state); |
2935 |
- { |
2936 |
- void *regex; |
2937 |
- array_for_each(regex_arr, i, regex) |
2938 |
- regfree(regex); |
2939 |
+ vdb = tree_open_vdb(portroot, portvdb); |
2940 |
+ ret = -1; |
2941 |
+ if (vdb != NULL) { |
2942 |
+ ret = tree_foreach_pkg_sorted(vdb, qcheck_cb, &state); |
2943 |
+ tree_close(vdb); |
2944 |
+ } |
2945 |
+ if (array_cnt(regex_arr) > 0) { |
2946 |
+ void *preg; |
2947 |
+ array_for_each(regex_arr, i, preg) |
2948 |
+ regfree(preg); |
2949 |
} |
2950 |
xarrayfree(regex_arr); |
2951 |
array_for_each(atoms, i, atom) |
2952 |
|
2953 |
diff --git a/qdepends.c b/qdepends.c |
2954 |
index 64bf991..15d5253 100644 |
2955 |
--- a/qdepends.c |
2956 |
+++ b/qdepends.c |
2957 |
@@ -17,7 +17,7 @@ |
2958 |
#include "atom.h" |
2959 |
#include "dep.h" |
2960 |
#include "set.h" |
2961 |
-#include "vdb.h" |
2962 |
+#include "tree.h" |
2963 |
#include "xarray.h" |
2964 |
#include "xasprintf.h" |
2965 |
#include "xregex.h" |
2966 |
@@ -92,7 +92,7 @@ qdepends_print_depend(FILE *fp, const char *depend) |
2967 |
} |
2968 |
|
2969 |
static int |
2970 |
-qdepends_results_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
2971 |
+qdepends_results_cb(tree_pkg_ctx *pkg_ctx, void *priv) |
2972 |
{ |
2973 |
struct qdepends_opt_state *state = priv; |
2974 |
depend_atom *atom; |
2975 |
@@ -116,7 +116,7 @@ qdepends_results_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
2976 |
* *DEPEND alters the search somewhat and affects results printing. |
2977 |
*/ |
2978 |
|
2979 |
- datom = vdb_get_atom(pkg_ctx, false); |
2980 |
+ datom = tree_get_atom(pkg_ctx, false); |
2981 |
if (datom == NULL) |
2982 |
return ret; |
2983 |
|
2984 |
@@ -135,7 +135,7 @@ qdepends_results_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
2985 |
|
2986 |
ret = 1; |
2987 |
|
2988 |
- datom = vdb_get_atom(pkg_ctx, true); |
2989 |
+ datom = tree_get_atom(pkg_ctx, true); |
2990 |
printf("%s:", atom_format(state->format, datom, 0)); |
2991 |
} |
2992 |
|
2993 |
@@ -146,7 +146,7 @@ qdepends_results_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
2994 |
for (i = QMODE_DEPEND; i <= QMODE_BDEPEND; i <<= 1, dfile++) { |
2995 |
if (!(state->qmode & i)) |
2996 |
continue; |
2997 |
- if (!vdb_pkg_eat(pkg_ctx, *dfile, |
2998 |
+ if (!tree_pkg_vdb_eat(pkg_ctx, *dfile, |
2999 |
&state->depend, &state->depend_len)) |
3000 |
continue; |
3001 |
|
3002 |
@@ -174,7 +174,7 @@ qdepends_results_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3003 |
ret = 1; |
3004 |
|
3005 |
if (!firstmatch) { |
3006 |
- datom = vdb_get_atom(pkg_ctx, true); |
3007 |
+ datom = tree_get_atom(pkg_ctx, true); |
3008 |
printf("%s:", atom_format(state->format, datom, 0)); |
3009 |
} |
3010 |
firstmatch = true; |
3011 |
@@ -203,7 +203,7 @@ qdepends_results_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3012 |
ret = 1; |
3013 |
|
3014 |
if (!firstmatch) { |
3015 |
- datom = vdb_get_atom(pkg_ctx, true); |
3016 |
+ datom = tree_get_atom(pkg_ctx, true); |
3017 |
printf("%s:", atom_format(state->format, datom, 0)); |
3018 |
} |
3019 |
firstmatch = true; |
3020 |
@@ -243,6 +243,7 @@ qdepends_results_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3021 |
int qdepends_main(int argc, char **argv) |
3022 |
{ |
3023 |
depend_atom *atom; |
3024 |
+ tree_ctx *vdb; |
3025 |
DECLARE_ARRAY(atoms); |
3026 |
DECLARE_ARRAY(deps); |
3027 |
struct qdepends_opt_state state = { |
3028 |
@@ -307,8 +308,11 @@ int qdepends_main(int argc, char **argv) |
3029 |
xarraypush_ptr(atoms, atom); |
3030 |
} |
3031 |
|
3032 |
- ret = vdb_foreach_pkg(portroot, portvdb, |
3033 |
- qdepends_results_cb, &state, NULL); |
3034 |
+ vdb = tree_open_vdb(portroot, portvdb); |
3035 |
+ if (vdb != NULL) { |
3036 |
+ ret = tree_foreach_pkg_fast(vdb, qdepends_results_cb, &state, NULL); |
3037 |
+ tree_close(vdb); |
3038 |
+ } |
3039 |
|
3040 |
if (state.depend != NULL) |
3041 |
free(state.depend); |
3042 |
|
3043 |
diff --git a/qfile.c b/qfile.c |
3044 |
index 3d1543e..c451ae4 100644 |
3045 |
--- a/qfile.c |
3046 |
+++ b/qfile.c |
3047 |
@@ -18,7 +18,7 @@ |
3048 |
#include "basename.h" |
3049 |
#include "contents.h" |
3050 |
#include "rmspace.h" |
3051 |
-#include "vdb.h" |
3052 |
+#include "tree.h" |
3053 |
|
3054 |
#define QFILE_FLAGS "boRx:S" COMMON_FLAGS |
3055 |
static struct option const qfile_long_opts[] = { |
3056 |
@@ -74,7 +74,7 @@ struct qfile_opt_state { |
3057 |
* We assume the people calling us have chdir(/var/db/pkg) and so |
3058 |
* we use relative paths throughout here. |
3059 |
*/ |
3060 |
-static int qfile_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3061 |
+static int qfile_cb(tree_pkg_ctx *pkg_ctx, void *priv) |
3062 |
{ |
3063 |
struct qfile_opt_state *state = priv; |
3064 |
const char *catname = pkg_ctx->cat_ctx->name; |
3065 |
@@ -115,14 +115,14 @@ static int qfile_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3066 |
} |
3067 |
if (state->exclude_slot == NULL) |
3068 |
goto qlist_done; /* "(CAT/)?(PN|PF)" matches, and no SLOT specified */ |
3069 |
- vdb_pkg_eat(pkg_ctx, "SLOT", &state->buf, &state->buflen); |
3070 |
+ tree_pkg_vdb_eat(pkg_ctx, "SLOT", &state->buf, &state->buflen); |
3071 |
rmspace(state->buf); |
3072 |
if (strcmp(state->exclude_slot, state->buf) == 0) |
3073 |
goto qlist_done; /* "(CAT/)?(PN|PF):SLOT" matches */ |
3074 |
} |
3075 |
dont_skip_pkg: /* End of the package exclusion tests. */ |
3076 |
|
3077 |
- fp = vdb_pkg_fopenat_ro(pkg_ctx, "CONTENTS"); |
3078 |
+ fp = tree_pkg_vdb_fopenat_ro(pkg_ctx, "CONTENTS"); |
3079 |
if (fp == NULL) |
3080 |
goto qlist_done; |
3081 |
|
3082 |
@@ -227,7 +227,7 @@ static int qfile_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3083 |
/* XXX: This assumes the buf is big enough. */ |
3084 |
char *slot_hack = slot + 1; |
3085 |
size_t slot_len = sizeof(slot) - 1; |
3086 |
- vdb_pkg_eat(pkg_ctx, "SLOT", &slot_hack, &slot_len); |
3087 |
+ tree_pkg_vdb_eat(pkg_ctx, "SLOT", &slot_hack, &slot_len); |
3088 |
rmspace(slot_hack); |
3089 |
slot[0] = ':'; |
3090 |
} else |
3091 |
@@ -478,8 +478,13 @@ int qfile_main(int argc, char **argv) |
3092 |
/* Prepare the qfile(...) arguments structure */ |
3093 |
nb_of_queries = prepare_qfile_args(argc, (const char **) argv, &state); |
3094 |
/* Now do the actual `qfile` checking */ |
3095 |
- if (nb_of_queries > 0) |
3096 |
- found += vdb_foreach_pkg_sorted(portroot, portvdb, qfile_cb, &state); |
3097 |
+ if (nb_of_queries > 0) { |
3098 |
+ tree_ctx *vdb = tree_open_vdb(portroot, portvdb); |
3099 |
+ if (vdb != NULL) { |
3100 |
+ found += tree_foreach_pkg_sorted(vdb, qfile_cb, &state); |
3101 |
+ tree_close(vdb); |
3102 |
+ } |
3103 |
+ } |
3104 |
|
3105 |
if (state.args.non_orphans) { |
3106 |
/* display orphan files */ |
3107 |
|
3108 |
diff --git a/qgrep.c b/qgrep.c |
3109 |
index f38f461..8e240f3 100644 |
3110 |
--- a/qgrep.c |
3111 |
+++ b/qgrep.c |
3112 |
@@ -19,8 +19,7 @@ |
3113 |
#include <fcntl.h> |
3114 |
|
3115 |
#include "atom.h" |
3116 |
-#include "cache.h" |
3117 |
-#include "vdb.h" |
3118 |
+#include "tree.h" |
3119 |
#include "xarray.h" |
3120 |
#include "xchdir.h" |
3121 |
#include "xregex.h" |
3122 |
@@ -381,14 +380,14 @@ print_after_context: |
3123 |
} |
3124 |
|
3125 |
static int |
3126 |
-qgrep_cache_cb(cache_pkg_ctx *pkg_ctx, void *priv) |
3127 |
+qgrep_cache_cb(tree_pkg_ctx *pkg_ctx, void *priv) |
3128 |
{ |
3129 |
struct qgrep_grepargs *data = (struct qgrep_grepargs *)priv; |
3130 |
char buf[_Q_PATH_MAX]; |
3131 |
char name[_Q_PATH_MAX]; |
3132 |
char *label; |
3133 |
depend_atom *patom = NULL; |
3134 |
- cache_ctx *cctx; |
3135 |
+ tree_ctx *cctx; |
3136 |
int ret; |
3137 |
int pfd; |
3138 |
|
3139 |
@@ -411,11 +410,11 @@ qgrep_cache_cb(cache_pkg_ctx *pkg_ctx, void *priv) |
3140 |
} |
3141 |
|
3142 |
/* need to construct path in portdir to ebuild, pass it to grep */ |
3143 |
- cctx = (cache_ctx *)(pkg_ctx->cat_ctx->ctx); |
3144 |
+ cctx = (tree_ctx *)(pkg_ctx->cat_ctx->ctx); |
3145 |
if (cctx->cachetype == CACHE_EBUILD) { |
3146 |
- pfd = cctx->vdb_fd; |
3147 |
+ pfd = cctx->tree_fd; |
3148 |
} else { |
3149 |
- pfd = openat(cctx->vdb_fd, "../..", O_RDONLY|O_CLOEXEC); |
3150 |
+ pfd = openat(cctx->tree_fd, "../..", O_RDONLY|O_CLOEXEC); |
3151 |
} |
3152 |
|
3153 |
/* cat/pkg/pkg-ver.ebuild */ |
3154 |
@@ -441,7 +440,7 @@ qgrep_cache_cb(cache_pkg_ctx *pkg_ctx, void *priv) |
3155 |
} |
3156 |
|
3157 |
static int |
3158 |
-qgrep_vdb_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3159 |
+qgrep_vdb_cb(tree_pkg_ctx *pkg_ctx, void *priv) |
3160 |
{ |
3161 |
struct qgrep_grepargs *data = (struct qgrep_grepargs *)priv; |
3162 |
char buf[_Q_PATH_MAX]; |
3163 |
@@ -687,11 +686,17 @@ int qgrep_main(int argc, char **argv) |
3164 |
} |
3165 |
closedir(eclass_dir); |
3166 |
} else if (do_installed) { |
3167 |
- status = vdb_foreach_pkg(portroot, portvdb, |
3168 |
- qgrep_vdb_cb, &args, NULL); |
3169 |
+ tree_ctx *t = tree_open_vdb(portroot, portvdb); |
3170 |
+ if (t != NULL) { |
3171 |
+ status = tree_foreach_pkg_fast(t, qgrep_vdb_cb, &args, NULL); |
3172 |
+ tree_close(t); |
3173 |
+ } |
3174 |
} else { /* do_ebuild */ |
3175 |
- status = cache_foreach_pkg(portroot, overlay, |
3176 |
- qgrep_cache_cb, &args, NULL); |
3177 |
+ tree_ctx *t = tree_open(portroot, overlay); |
3178 |
+ if (t != NULL) { |
3179 |
+ status = tree_foreach_pkg_fast(t, qgrep_cache_cb, &args, NULL); |
3180 |
+ tree_close(t); |
3181 |
+ } |
3182 |
} |
3183 |
} |
3184 |
|
3185 |
|
3186 |
diff --git a/qkeyword.c b/qkeyword.c |
3187 |
index ef61fba..b9792af 100644 |
3188 |
--- a/qkeyword.c |
3189 |
+++ b/qkeyword.c |
3190 |
@@ -18,10 +18,10 @@ |
3191 |
#include <sys/stat.h> |
3192 |
|
3193 |
#include "atom.h" |
3194 |
-#include "cache.h" |
3195 |
-#include "scandirat.h" |
3196 |
#include "rmspace.h" |
3197 |
+#include "scandirat.h" |
3198 |
#include "set.h" |
3199 |
+#include "tree.h" |
3200 |
#include "xasprintf.h" |
3201 |
|
3202 |
/********************************************************************/ |
3203 |
@@ -62,7 +62,7 @@ typedef struct { |
3204 |
int *keywordsbuf; |
3205 |
size_t keywordsbuflen; |
3206 |
const char *arch; |
3207 |
- cache_pkg_cb *runfunc; |
3208 |
+ tree_pkg_cb *runfunc; |
3209 |
} qkeyword_data; |
3210 |
|
3211 |
static set *archs = NULL; |
3212 |
@@ -214,7 +214,7 @@ qkeyword_vercmp(const struct dirent **x, const struct dirent **y) |
3213 |
} |
3214 |
|
3215 |
static int |
3216 |
-qkeyword_imlate(cache_pkg_ctx *pkg_ctx, void *priv) |
3217 |
+qkeyword_imlate(tree_pkg_ctx *pkg_ctx, void *priv) |
3218 |
{ |
3219 |
size_t a; |
3220 |
qkeyword_data *data = (qkeyword_data *)priv; |
3221 |
@@ -241,7 +241,7 @@ qkeyword_imlate(cache_pkg_ctx *pkg_ctx, void *priv) |
3222 |
} |
3223 |
|
3224 |
static int |
3225 |
-qkeyword_not(cache_pkg_ctx *pkg_ctx, void *priv) |
3226 |
+qkeyword_not(tree_pkg_ctx *pkg_ctx, void *priv) |
3227 |
{ |
3228 |
size_t a; |
3229 |
qkeyword_data *data = (qkeyword_data *)priv; |
3230 |
@@ -266,7 +266,7 @@ qkeyword_not(cache_pkg_ctx *pkg_ctx, void *priv) |
3231 |
} |
3232 |
|
3233 |
static int |
3234 |
-qkeyword_all(cache_pkg_ctx *pkg_ctx, void *priv) |
3235 |
+qkeyword_all(tree_pkg_ctx *pkg_ctx, void *priv) |
3236 |
{ |
3237 |
qkeyword_data *data = (qkeyword_data *)priv; |
3238 |
|
3239 |
@@ -282,7 +282,7 @@ qkeyword_all(cache_pkg_ctx *pkg_ctx, void *priv) |
3240 |
} |
3241 |
|
3242 |
static int |
3243 |
-qkeyword_dropped(cache_pkg_ctx *pkg_ctx, void *priv) |
3244 |
+qkeyword_dropped(tree_pkg_ctx *pkg_ctx, void *priv) |
3245 |
{ |
3246 |
static bool candidate = false; |
3247 |
static char pkg1[_Q_PATH_MAX]; |
3248 |
@@ -393,7 +393,7 @@ print_seconds_for_earthlings(const unsigned long t) |
3249 |
} |
3250 |
|
3251 |
static int |
3252 |
-qkeyword_stats(cache_pkg_ctx *pkg_ctx, void *priv) |
3253 |
+qkeyword_stats(tree_pkg_ctx *pkg_ctx, void *priv) |
3254 |
{ |
3255 |
static time_t runtime; |
3256 |
static int numpkg = 0; |
3257 |
@@ -536,7 +536,7 @@ qkeyword_stats(cache_pkg_ctx *pkg_ctx, void *priv) |
3258 |
} |
3259 |
|
3260 |
static int |
3261 |
-qkeyword_testing_only(cache_pkg_ctx *pkg_ctx, void *priv) |
3262 |
+qkeyword_testing_only(tree_pkg_ctx *pkg_ctx, void *priv) |
3263 |
{ |
3264 |
static bool candidate = false; |
3265 |
static char pkg1[_Q_PATH_MAX]; |
3266 |
@@ -606,14 +606,14 @@ qkeyword_testing_only(cache_pkg_ctx *pkg_ctx, void *priv) |
3267 |
} |
3268 |
|
3269 |
static int |
3270 |
-qkeyword_results_cb(cache_pkg_ctx *pkg_ctx, void *priv) |
3271 |
+qkeyword_results_cb(tree_pkg_ctx *pkg_ctx, void *priv) |
3272 |
{ |
3273 |
int *keywords; |
3274 |
qkeyword_data *data = (qkeyword_data *)priv; |
3275 |
char buf[_Q_PATH_MAX]; |
3276 |
depend_atom *patom = NULL; |
3277 |
- cache_pkg_meta *meta; |
3278 |
- cache_metadata_xml *metadata; |
3279 |
+ tree_pkg_meta *meta; |
3280 |
+ tree_metadata_xml *metadata; |
3281 |
struct elist *emailw; |
3282 |
int ret; |
3283 |
|
3284 |
@@ -638,7 +638,7 @@ qkeyword_results_cb(cache_pkg_ctx *pkg_ctx, void *priv) |
3285 |
} |
3286 |
|
3287 |
if (data->qmaint != NULL) { |
3288 |
- metadata = cache_read_metadata(pkg_ctx); |
3289 |
+ metadata = tree_pkg_metadata(pkg_ctx); |
3290 |
if (metadata == NULL) |
3291 |
return EXIT_SUCCESS; |
3292 |
|
3293 |
@@ -650,13 +650,13 @@ qkeyword_results_cb(cache_pkg_ctx *pkg_ctx, void *priv) |
3294 |
/* arbitrary pointer to trigger exit below */ |
3295 |
emailw = (struct elist *)buf; |
3296 |
|
3297 |
- cache_close_metadata(metadata); |
3298 |
+ tree_close_metadata(metadata); |
3299 |
if (emailw != NULL) |
3300 |
return EXIT_SUCCESS; |
3301 |
} |
3302 |
|
3303 |
keywords = data->keywordsbuf; |
3304 |
- meta = cache_pkg_read(pkg_ctx); |
3305 |
+ meta = tree_pkg_read(pkg_ctx); |
3306 |
if (meta == NULL) { |
3307 |
atom_implode(patom); |
3308 |
return EXIT_FAILURE; |
3309 |
@@ -731,7 +731,7 @@ qkeyword_load_arches(const char *overlay) |
3310 |
} |
3311 |
|
3312 |
static int |
3313 |
-qkeyword_traverse(cache_pkg_cb func, void *priv) |
3314 |
+qkeyword_traverse(tree_pkg_cb func, void *priv) |
3315 |
{ |
3316 |
int ret; |
3317 |
size_t n; |
3318 |
@@ -756,9 +756,14 @@ qkeyword_traverse(cache_pkg_cb func, void *priv) |
3319 |
|
3320 |
data->runfunc = func; |
3321 |
ret = 0; |
3322 |
- array_for_each(overlays, n, overlay) |
3323 |
- ret |= cache_foreach_pkg_sorted(portroot, overlay, |
3324 |
- qkeyword_results_cb, priv, NULL, qkeyword_vercmp); |
3325 |
+ array_for_each(overlays, n, overlay) { |
3326 |
+ tree_ctx *t = tree_open(portroot, overlay); |
3327 |
+ if (t != NULL) { |
3328 |
+ ret |= tree_foreach_pkg(t, qkeyword_results_cb, priv, |
3329 |
+ NULL, true, NULL, qkeyword_vercmp); |
3330 |
+ tree_close(t); |
3331 |
+ } |
3332 |
+ } |
3333 |
|
3334 |
return ret; |
3335 |
} |
3336 |
|
3337 |
diff --git a/qlist.c b/qlist.c |
3338 |
index 9314385..abefbcf 100644 |
3339 |
--- a/qlist.c |
3340 |
+++ b/qlist.c |
3341 |
@@ -18,7 +18,7 @@ |
3342 |
|
3343 |
#include "atom.h" |
3344 |
#include "contents.h" |
3345 |
-#include "vdb.h" |
3346 |
+#include "tree.h" |
3347 |
#include "xregex.h" |
3348 |
|
3349 |
#define QLIST_FLAGS "ISRUcDeados" COMMON_FLAGS |
3350 |
@@ -96,7 +96,7 @@ cmpstringp(const void *p1, const void *p2) |
3351 |
*/ |
3352 |
static char _umapstr_buf[BUFSIZ]; |
3353 |
static const char * |
3354 |
-umapstr(char display, vdb_pkg_ctx *pkg_ctx) |
3355 |
+umapstr(char display, tree_pkg_ctx *pkg_ctx) |
3356 |
{ |
3357 |
char *bufp = _umapstr_buf; |
3358 |
char *use = NULL; |
3359 |
@@ -115,10 +115,10 @@ umapstr(char display, vdb_pkg_ctx *pkg_ctx) |
3360 |
if (!display) |
3361 |
return bufp; |
3362 |
|
3363 |
- vdb_pkg_eat(pkg_ctx, "USE", &use, &use_len); |
3364 |
+ tree_pkg_vdb_eat(pkg_ctx, "USE", &use, &use_len); |
3365 |
if (!use[0]) |
3366 |
return bufp; |
3367 |
- vdb_pkg_eat(pkg_ctx, "IUSE", &iuse, &iuse_len); |
3368 |
+ tree_pkg_vdb_eat(pkg_ctx, "IUSE", &iuse, &iuse_len); |
3369 |
if (!iuse[0]) |
3370 |
return bufp; |
3371 |
|
3372 |
@@ -173,13 +173,13 @@ umapstr(char display, vdb_pkg_ctx *pkg_ctx) |
3373 |
/* forward declaration necessary for misuse from qmerge.c, see HACK there */ |
3374 |
bool |
3375 |
qlist_match( |
3376 |
- vdb_pkg_ctx *pkg_ctx, |
3377 |
+ tree_pkg_ctx *pkg_ctx, |
3378 |
const char *name, |
3379 |
depend_atom **name_atom, |
3380 |
bool exact); |
3381 |
bool |
3382 |
qlist_match( |
3383 |
- vdb_pkg_ctx *pkg_ctx, |
3384 |
+ tree_pkg_ctx *pkg_ctx, |
3385 |
const char *name, |
3386 |
depend_atom **name_atom, |
3387 |
bool exact) |
3388 |
@@ -200,7 +200,7 @@ qlist_match( |
3389 |
uslot = NULL; |
3390 |
else { |
3391 |
if (!pkg_ctx->slot) |
3392 |
- vdb_pkg_eat(pkg_ctx, "SLOT", &pkg_ctx->slot, |
3393 |
+ tree_pkg_vdb_eat(pkg_ctx, "SLOT", &pkg_ctx->slot, |
3394 |
&pkg_ctx->slot_len); |
3395 |
uslot_len = strlen(uslot); |
3396 |
} |
3397 |
@@ -209,7 +209,7 @@ qlist_match( |
3398 |
urepo = strstr(name, "::"); |
3399 |
if (urepo) { |
3400 |
if (!pkg_ctx->repo) |
3401 |
- vdb_pkg_eat(pkg_ctx, "repository", &pkg_ctx->repo, |
3402 |
+ tree_pkg_vdb_eat(pkg_ctx, "repository", &pkg_ctx->repo, |
3403 |
&pkg_ctx->repo_len); |
3404 |
urepo += 2; |
3405 |
urepo_len = strlen(urepo); |
3406 |
@@ -338,7 +338,7 @@ struct qlist_opt_state { |
3407 |
}; |
3408 |
|
3409 |
static int |
3410 |
-qlist_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3411 |
+qlist_cb(tree_pkg_ctx *pkg_ctx, void *priv) |
3412 |
{ |
3413 |
struct qlist_opt_state *state = priv; |
3414 |
int i; |
3415 |
@@ -359,7 +359,7 @@ qlist_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3416 |
atom = (verbose ? NULL : atom_explode(pkgname)); |
3417 |
if ((state->all + state->just_pkgname) < 2) { |
3418 |
if (state->show_slots && !pkg_ctx->slot) { |
3419 |
- vdb_pkg_eat(pkg_ctx, "SLOT", |
3420 |
+ tree_pkg_vdb_eat(pkg_ctx, "SLOT", |
3421 |
&pkg_ctx->slot, &pkg_ctx->slot_len); |
3422 |
/* chop off the subslot if desired */ |
3423 |
if (state->show_slots == 1) { |
3424 |
@@ -369,7 +369,7 @@ qlist_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3425 |
} |
3426 |
} |
3427 |
if (state->show_repo && !pkg_ctx->repo) |
3428 |
- vdb_pkg_eat(pkg_ctx, "repository", |
3429 |
+ tree_pkg_vdb_eat(pkg_ctx, "repository", |
3430 |
&pkg_ctx->repo, &pkg_ctx->repo_len); |
3431 |
/* display it */ |
3432 |
printf("%s%s/%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", |
3433 |
@@ -398,7 +398,7 @@ qlist_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3434 |
printf("%s%s/%s%s%s %sCONTENTS%s:\n", |
3435 |
BOLD, catname, BLUE, pkgname, NORM, DKBLUE, NORM); |
3436 |
|
3437 |
- fp = vdb_pkg_fopenat_ro(pkg_ctx, "CONTENTS"); |
3438 |
+ fp = tree_pkg_vdb_fopenat_ro(pkg_ctx, "CONTENTS"); |
3439 |
if (fp == NULL) |
3440 |
return 1; |
3441 |
|
3442 |
@@ -444,6 +444,9 @@ qlist_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3443 |
|
3444 |
int qlist_main(int argc, char **argv) |
3445 |
{ |
3446 |
+ int i; |
3447 |
+ int ret; |
3448 |
+ tree_ctx *vdb; |
3449 |
struct qlist_opt_state state = { |
3450 |
.argc = argc, |
3451 |
.argv = argv, |
3452 |
@@ -460,7 +463,6 @@ int qlist_main(int argc, char **argv) |
3453 |
.columns = false, |
3454 |
.buflen = _Q_PATH_MAX, |
3455 |
}; |
3456 |
- int i, ret; |
3457 |
|
3458 |
while ((i = GETOPT_LONG(QLIST, qlist, "")) != -1) { |
3459 |
switch (i) { |
3460 |
@@ -489,7 +491,12 @@ int qlist_main(int argc, char **argv) |
3461 |
|
3462 |
state.buf = xmalloc(state.buflen); |
3463 |
state.atoms = xcalloc(argc - optind, sizeof(*state.atoms)); |
3464 |
- ret = vdb_foreach_pkg_sorted(portroot, portvdb, qlist_cb, &state); |
3465 |
+ ret = 1; |
3466 |
+ vdb = tree_open_vdb(portroot, portvdb); |
3467 |
+ if (vdb != NULL) { |
3468 |
+ ret = tree_foreach_pkg_sorted(vdb, qlist_cb, &state); |
3469 |
+ tree_close(vdb); |
3470 |
+ } |
3471 |
free(state.buf); |
3472 |
for (i = optind; i < state.argc; ++i) |
3473 |
if (state.atoms[i - optind]) |
3474 |
|
3475 |
diff --git a/qmerge.c b/qmerge.c |
3476 |
index 41488fa..e6bbdb5 100644 |
3477 |
--- a/qmerge.c |
3478 |
+++ b/qmerge.c |
3479 |
@@ -30,7 +30,7 @@ |
3480 |
#include "rmspace.h" |
3481 |
#include "scandirat.h" |
3482 |
#include "set.h" |
3483 |
-#include "vdb.h" |
3484 |
+#include "tree.h" |
3485 |
#include "xasprintf.h" |
3486 |
#include "xchdir.h" |
3487 |
#include "xmkdir.h" |
3488 |
@@ -118,7 +118,7 @@ typedef struct llist_char_t llist_char; |
3489 |
|
3490 |
static void pkg_fetch(int, const depend_atom *, const struct pkg_t *); |
3491 |
static void pkg_merge(int, const depend_atom *, const struct pkg_t *); |
3492 |
-static int pkg_unmerge(vdb_pkg_ctx *, set *, int, char **, int, char **); |
3493 |
+static int pkg_unmerge(tree_pkg_ctx *, set *, int, char **, int, char **); |
3494 |
static struct pkg_t *grab_binpkg_info(const char *); |
3495 |
static char *find_binpkg(const char *); |
3496 |
|
3497 |
@@ -282,7 +282,7 @@ struct qmerge_bv_state { |
3498 |
}; |
3499 |
|
3500 |
static int |
3501 |
-qmerge_filter_cat(vdb_cat_ctx *cat_ctx, void *priv) |
3502 |
+qmerge_filter_cat(tree_cat_ctx *cat_ctx, void *priv) |
3503 |
{ |
3504 |
struct qmerge_bv_state *state = priv; |
3505 |
return !state->catname || strcmp(cat_ctx->name, state->catname) == 0; |
3506 |
@@ -292,13 +292,13 @@ qmerge_filter_cat(vdb_cat_ctx *cat_ctx, void *priv) |
3507 |
* should however figure out how to do what match does here from e.g. |
3508 |
* atom */ |
3509 |
extern bool qlist_match( |
3510 |
- vdb_pkg_ctx *pkg_ctx, |
3511 |
+ tree_pkg_ctx *pkg_ctx, |
3512 |
const char *name, |
3513 |
depend_atom **name_atom, |
3514 |
bool exact); |
3515 |
|
3516 |
static int |
3517 |
-qmerge_best_version_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3518 |
+qmerge_best_version_cb(tree_pkg_ctx *pkg_ctx, void *priv) |
3519 |
{ |
3520 |
struct qmerge_bv_state *state = priv; |
3521 |
if (qlist_match(pkg_ctx, state->buf, NULL, true)) |
3522 |
@@ -312,6 +312,8 @@ best_version(const char *catname, const char *pkgname, const char *slot) |
3523 |
{ |
3524 |
static int vdb_check = 1; |
3525 |
static char retbuf[4096]; |
3526 |
+ |
3527 |
+ tree_ctx *vdb; |
3528 |
struct qmerge_bv_state state = { |
3529 |
.catname = catname, |
3530 |
.pkgname = pkgname, |
3531 |
@@ -338,8 +340,12 @@ best_version(const char *catname, const char *pkgname, const char *slot) |
3532 |
retbuf[0] = '\0'; |
3533 |
snprintf(state.buf, sizeof(state.buf), "%s%s%s:%s", |
3534 |
catname ? : "", catname ? "/" : "", pkgname, slot); |
3535 |
- vdb_foreach_pkg(portroot, portvdb, |
3536 |
- qmerge_best_version_cb, &state, qmerge_filter_cat); |
3537 |
+ vdb = tree_open_vdb(portroot, portvdb); |
3538 |
+ if (vdb != NULL) { |
3539 |
+ tree_foreach_pkg_fast(vdb, |
3540 |
+ qmerge_best_version_cb, &state, qmerge_filter_cat); |
3541 |
+ tree_close(vdb); |
3542 |
+ } |
3543 |
|
3544 |
done: |
3545 |
return retbuf; |
3546 |
@@ -999,8 +1005,8 @@ static void |
3547 |
pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
3548 |
{ |
3549 |
set *objs; |
3550 |
- vdb_ctx *vdb; |
3551 |
- vdb_cat_ctx *cat_ctx; |
3552 |
+ tree_ctx *vdb; |
3553 |
+ tree_cat_ctx *cat_ctx; |
3554 |
FILE *fp, *contents; |
3555 |
static char *phases; |
3556 |
static size_t phases_len; |
3557 |
@@ -1122,19 +1128,19 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
3558 |
} |
3559 |
|
3560 |
/* Get a handle on the main vdb repo */ |
3561 |
- vdb = vdb_open(portroot, portvdb); |
3562 |
+ vdb = tree_open(portroot, portvdb); |
3563 |
if (!vdb) |
3564 |
return; |
3565 |
- cat_ctx = vdb_open_cat(vdb, pkg->CATEGORY); |
3566 |
+ cat_ctx = tree_open_cat(vdb, pkg->CATEGORY); |
3567 |
if (!cat_ctx) { |
3568 |
if (errno != ENOENT) { |
3569 |
- vdb_close(vdb); |
3570 |
+ tree_close(vdb); |
3571 |
return; |
3572 |
} |
3573 |
- mkdirat(vdb->vdb_fd, pkg->CATEGORY, 0755); |
3574 |
- cat_ctx = vdb_open_cat(vdb, pkg->CATEGORY); |
3575 |
+ mkdirat(vdb->tree_fd, pkg->CATEGORY, 0755); |
3576 |
+ cat_ctx = tree_open_cat(vdb, pkg->CATEGORY); |
3577 |
if (!cat_ctx) { |
3578 |
- vdb_close(vdb); |
3579 |
+ tree_close(vdb); |
3580 |
return; |
3581 |
} |
3582 |
} |
3583 |
@@ -1345,10 +1351,10 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
3584 |
/* TODO: Should see about merging with unmerge_packages() */ |
3585 |
while (1) { |
3586 |
int ret; |
3587 |
- vdb_pkg_ctx *pkg_ctx; |
3588 |
+ tree_pkg_ctx *pkg_ctx; |
3589 |
depend_atom *old_atom; |
3590 |
|
3591 |
- pkg_ctx = vdb_next_pkg(cat_ctx); |
3592 |
+ pkg_ctx = tree_next_pkg(cat_ctx); |
3593 |
if (!pkg_ctx) |
3594 |
break; |
3595 |
|
3596 |
@@ -1377,7 +1383,7 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
3597 |
|
3598 |
pkg_unmerge(pkg_ctx, objs, cp_argc, cp_argv, cpm_argc, cpm_argv); |
3599 |
next_pkg: |
3600 |
- vdb_close_pkg(pkg_ctx); |
3601 |
+ tree_close_pkg(pkg_ctx); |
3602 |
} |
3603 |
|
3604 |
freeargv(cp_argc, cp_argv); |
3605 |
@@ -1416,14 +1422,14 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
3606 |
printf("%s>>>%s %s%s%s/%s%s%s\n", |
3607 |
YELLOW, NORM, WHITE, atom->CATEGORY, NORM, CYAN, atom->PN, NORM); |
3608 |
|
3609 |
- vdb_close(vdb); |
3610 |
+ tree_close(vdb); |
3611 |
} |
3612 |
|
3613 |
static int |
3614 |
-pkg_unmerge(vdb_pkg_ctx *pkg_ctx, set *keep, |
3615 |
+pkg_unmerge(tree_pkg_ctx *pkg_ctx, set *keep, |
3616 |
int cp_argc, char **cp_argv, int cpm_argc, char **cpm_argv) |
3617 |
{ |
3618 |
- vdb_cat_ctx *cat_ctx = pkg_ctx->cat_ctx; |
3619 |
+ tree_cat_ctx *cat_ctx = pkg_ctx->cat_ctx; |
3620 |
const char *cat = cat_ctx->name; |
3621 |
const char *pkgname = pkg_ctx->name; |
3622 |
size_t buflen; |
3623 |
@@ -1447,7 +1453,7 @@ pkg_unmerge(vdb_pkg_ctx *pkg_ctx, set *keep, |
3624 |
return 0; |
3625 |
|
3626 |
/* First get a handle on the things to clean up */ |
3627 |
- fp = vdb_pkg_fopenat_ro(pkg_ctx, "CONTENTS"); |
3628 |
+ fp = tree_pkg_vdb_fopenat_ro(pkg_ctx, "CONTENTS"); |
3629 |
if (fp == NULL) |
3630 |
return ret; |
3631 |
|
3632 |
@@ -1455,7 +1461,7 @@ pkg_unmerge(vdb_pkg_ctx *pkg_ctx, set *keep, |
3633 |
|
3634 |
/* Then execute the pkg_prerm step */ |
3635 |
if (!pretend) { |
3636 |
- vdb_pkg_eat(pkg_ctx, "DEFINED_PHASES", &phases, &phases_len); |
3637 |
+ tree_pkg_vdb_eat(pkg_ctx, "DEFINED_PHASES", &phases, &phases_len); |
3638 |
mkdirat(pkg_ctx->fd, "temp", 0755); |
3639 |
pkg_run_func_at(pkg_ctx->fd, ".", phases, "pkg_prerm", T, T); |
3640 |
} |
3641 |
@@ -1587,7 +1593,7 @@ pkg_unmerge(vdb_pkg_ctx *pkg_ctx, set *keep, |
3642 |
unlinkat(cat_ctx->fd, pkg_ctx->name, AT_REMOVEDIR); |
3643 |
|
3644 |
/* And prune the category if it's empty */ |
3645 |
- unlinkat(cat_ctx->ctx->vdb_fd, cat_ctx->name, AT_REMOVEDIR); |
3646 |
+ unlinkat(cat_ctx->ctx->tree_fd, cat_ctx->name, AT_REMOVEDIR); |
3647 |
} |
3648 |
|
3649 |
ret = 0; |
3650 |
@@ -1776,7 +1782,7 @@ print_Pkg(int full, const depend_atom *atom, const struct pkg_t *pkg) |
3651 |
} |
3652 |
|
3653 |
static int |
3654 |
-qmerge_unmerge_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3655 |
+qmerge_unmerge_cb(tree_pkg_ctx *pkg_ctx, void *priv) |
3656 |
{ |
3657 |
int cp_argc; |
3658 |
int cpm_argc; |
3659 |
@@ -1804,7 +1810,13 @@ qmerge_unmerge_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3660 |
static int |
3661 |
unmerge_packages(set *todo) |
3662 |
{ |
3663 |
- return vdb_foreach_pkg(portroot, portvdb, qmerge_unmerge_cb, todo, NULL); |
3664 |
+ tree_ctx *vdb = tree_open_vdb(portroot, portvdb); |
3665 |
+ int ret = 1; |
3666 |
+ if (vdb != NULL) { |
3667 |
+ ret = tree_foreach_pkg_fast(vdb, qmerge_unmerge_cb, todo, NULL); |
3668 |
+ tree_close(vdb); |
3669 |
+ } |
3670 |
+ return ret; |
3671 |
} |
3672 |
|
3673 |
static FILE * |
3674 |
@@ -2315,7 +2327,7 @@ qmerge_add_set(char *buf, set *q) |
3675 |
if (strcmp(buf, "world") == 0) |
3676 |
return qmerge_add_set_file("/var/lib/portage", "world", q); |
3677 |
else if (strcmp(buf, "all") == 0) |
3678 |
- return get_vdb_atoms(portroot, portvdb, 0); |
3679 |
+ return tree_get_vdb_atoms(portroot, portvdb, 0); |
3680 |
else if (strcmp(buf, "system") == 0) |
3681 |
return q_profile_walk("packages", qmerge_add_set_system, q); |
3682 |
else if (buf[0] == '@') |
3683 |
|
3684 |
diff --git a/qpkg.c b/qpkg.c |
3685 |
index b93823b..26c14d1 100644 |
3686 |
--- a/qpkg.c |
3687 |
+++ b/qpkg.c |
3688 |
@@ -20,13 +20,12 @@ |
3689 |
|
3690 |
#include "atom.h" |
3691 |
#include "basename.h" |
3692 |
-#include "cache.h" |
3693 |
#include "contents.h" |
3694 |
#include "human_readable.h" |
3695 |
#include "md5_sha1_sum.h" |
3696 |
#include "scandirat.h" |
3697 |
#include "set.h" |
3698 |
-#include "vdb.h" |
3699 |
+#include "tree.h" |
3700 |
#include "xarray.h" |
3701 |
#include "xasprintf.h" |
3702 |
#include "xchdir.h" |
3703 |
@@ -125,7 +124,7 @@ qpkg_clean_dir(char *dirp, set *vdb) |
3704 |
} |
3705 |
|
3706 |
static int |
3707 |
-qpkg_cb(cache_pkg_ctx *pkg_ctx, void *priv) |
3708 |
+qpkg_cb(tree_pkg_ctx *pkg_ctx, void *priv) |
3709 |
{ |
3710 |
set *vdb = (set *)priv; |
3711 |
depend_atom *atom; |
3712 |
@@ -156,14 +155,19 @@ qpkg_clean(char *dirp) |
3713 |
if ((count = scandir(".", &dnames, filter_hidden, alphasort)) < 0) |
3714 |
return 1; |
3715 |
|
3716 |
- vdb = get_vdb_atoms(portroot, portvdb, 1); |
3717 |
+ vdb = tree_get_vdb_atoms(portroot, portvdb, 1); |
3718 |
|
3719 |
if (eclean) { |
3720 |
size_t n; |
3721 |
const char *overlay; |
3722 |
|
3723 |
- array_for_each(overlays, n, overlay) |
3724 |
- cache_foreach_pkg(portroot, overlay, qpkg_cb, vdb, NULL); |
3725 |
+ array_for_each(overlays, n, overlay) { |
3726 |
+ tree_ctx *t = tree_open(portroot, overlay); |
3727 |
+ if (t != NULL) { |
3728 |
+ tree_foreach_pkg_fast(t, qpkg_cb, vdb, NULL); |
3729 |
+ tree_close(t); |
3730 |
+ } |
3731 |
+ } |
3732 |
} |
3733 |
|
3734 |
num_all_bytes = qpkg_clean_dir(dirp, vdb); |
3735 |
@@ -334,9 +338,9 @@ qpkg_make(depend_atom *atom) |
3736 |
|
3737 |
int qpkg_main(int argc, char **argv) |
3738 |
{ |
3739 |
- vdb_ctx *ctx; |
3740 |
- vdb_cat_ctx *cat_ctx; |
3741 |
- vdb_pkg_ctx *pkg_ctx; |
3742 |
+ tree_ctx *ctx; |
3743 |
+ tree_cat_ctx *cat_ctx; |
3744 |
+ tree_pkg_ctx *pkg_ctx; |
3745 |
size_t s, pkgs_made; |
3746 |
int i; |
3747 |
struct stat st; |
3748 |
@@ -417,15 +421,15 @@ retry_mkdir: |
3749 |
} |
3750 |
|
3751 |
/* now try to run through vdb and locate matches for user inputs */ |
3752 |
- ctx = vdb_open(portroot, portvdb); |
3753 |
+ ctx = tree_open_vdb(portroot, portvdb); |
3754 |
if (!ctx) |
3755 |
return EXIT_FAILURE; |
3756 |
|
3757 |
/* scan all the categories */ |
3758 |
- while ((cat_ctx = vdb_next_cat(ctx))) { |
3759 |
+ while ((cat_ctx = tree_next_cat(ctx))) { |
3760 |
/* scan all the packages in this category */ |
3761 |
const char *catname = cat_ctx->name; |
3762 |
- while ((pkg_ctx = vdb_next_pkg(cat_ctx))) { |
3763 |
+ while ((pkg_ctx = tree_next_pkg(cat_ctx))) { |
3764 |
const char *pkgname = pkg_ctx->name; |
3765 |
|
3766 |
/* see if user wants any of these packages */ |
3767 |
@@ -449,7 +453,7 @@ retry_mkdir: |
3768 |
atom_implode(atom); |
3769 |
|
3770 |
next_pkg: |
3771 |
- vdb_close_pkg(pkg_ctx); |
3772 |
+ tree_close_pkg(pkg_ctx); |
3773 |
} |
3774 |
} |
3775 |
|
3776 |
|
3777 |
diff --git a/qsearch.c b/qsearch.c |
3778 |
index b6d7410..f52a5ff 100644 |
3779 |
--- a/qsearch.c |
3780 |
+++ b/qsearch.c |
3781 |
@@ -20,8 +20,8 @@ |
3782 |
|
3783 |
#include "atom.h" |
3784 |
#include "basename.h" |
3785 |
-#include "cache.h" |
3786 |
#include "rmspace.h" |
3787 |
+#include "tree.h" |
3788 |
#include "xarray.h" |
3789 |
#include "xregex.h" |
3790 |
|
3791 |
@@ -57,14 +57,14 @@ struct qsearch_state { |
3792 |
}; |
3793 |
|
3794 |
static int |
3795 |
-qsearch_cb(cache_pkg_ctx *pkg_ctx, void *priv) |
3796 |
+qsearch_cb(tree_pkg_ctx *pkg_ctx, void *priv) |
3797 |
{ |
3798 |
static depend_atom *last_atom; |
3799 |
|
3800 |
struct qsearch_state *state = (struct qsearch_state *)priv; |
3801 |
depend_atom *atom; |
3802 |
char buf[_Q_PATH_MAX]; |
3803 |
- cache_pkg_meta *meta; |
3804 |
+ tree_pkg_meta *meta; |
3805 |
char *desc; |
3806 |
char *repo; |
3807 |
bool match; |
3808 |
@@ -90,7 +90,7 @@ qsearch_cb(cache_pkg_ctx *pkg_ctx, void *priv) |
3809 |
if ((match && (state->show_homepage || state->show_desc)) || |
3810 |
(!match && state->search_desc)) |
3811 |
{ |
3812 |
- meta = cache_pkg_read(pkg_ctx); |
3813 |
+ meta = tree_pkg_read(pkg_ctx); |
3814 |
if (meta != NULL) { |
3815 |
if (state->show_homepage) |
3816 |
desc = meta->HOMEPAGE; |
3817 |
@@ -115,7 +115,7 @@ qsearch_cb(cache_pkg_ctx *pkg_ctx, void *priv) |
3818 |
} |
3819 |
|
3820 |
if (meta != NULL) |
3821 |
- cache_close_meta(meta); |
3822 |
+ tree_close_meta(meta); |
3823 |
|
3824 |
if (last_atom != NULL) |
3825 |
atom_implode(last_atom); |
3826 |
@@ -167,9 +167,13 @@ int qsearch_main(int argc, char **argv) |
3827 |
xregcomp(&state.search_expr, search_me, REG_EXTENDED | REG_ICASE); |
3828 |
|
3829 |
/* use sorted order here so the duplicate reduction works reliably */ |
3830 |
- array_for_each(overlays, n, overlay) |
3831 |
- ret |= cache_foreach_pkg_sorted(portroot, overlay, qsearch_cb, |
3832 |
- &state, NULL, NULL); |
3833 |
+ array_for_each(overlays, n, overlay) { |
3834 |
+ tree_ctx *t = tree_open(portroot, overlay); |
3835 |
+ if (t != NULL) { |
3836 |
+ ret |= tree_foreach_pkg_sorted(t, qsearch_cb, &state); |
3837 |
+ tree_close(t); |
3838 |
+ } |
3839 |
+ } |
3840 |
|
3841 |
return ret; |
3842 |
} |
3843 |
|
3844 |
diff --git a/qsize.c b/qsize.c |
3845 |
index 4fbbe47..1ae942d 100644 |
3846 |
--- a/qsize.c |
3847 |
+++ b/qsize.c |
3848 |
@@ -51,7 +51,7 @@ |
3849 |
#include "atom.h" |
3850 |
#include "contents.h" |
3851 |
#include "human_readable.h" |
3852 |
-#include "vdb.h" |
3853 |
+#include "tree.h" |
3854 |
#include "xarray.h" |
3855 |
#include "xregex.h" |
3856 |
|
3857 |
@@ -97,7 +97,7 @@ struct qsize_opt_state { |
3858 |
}; |
3859 |
|
3860 |
static int |
3861 |
-qsize_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3862 |
+qsize_cb(tree_pkg_ctx *pkg_ctx, void *priv) |
3863 |
{ |
3864 |
struct qsize_opt_state *state = priv; |
3865 |
const char *catname = pkg_ctx->cat_ctx->name; |
3866 |
@@ -126,7 +126,7 @@ qsize_cb(vdb_pkg_ctx *pkg_ctx, void *priv) |
3867 |
if (!showit) |
3868 |
return EXIT_SUCCESS; |
3869 |
|
3870 |
- if ((fp = vdb_pkg_fopenat_ro(pkg_ctx, "CONTENTS")) == NULL) |
3871 |
+ if ((fp = tree_pkg_vdb_fopenat_ro(pkg_ctx, "CONTENTS")) == NULL) |
3872 |
return EXIT_SUCCESS; |
3873 |
|
3874 |
num_ignored = num_files = num_nonfiles = num_bytes = 0; |
3875 |
@@ -181,6 +181,7 @@ int qsize_main(int argc, char **argv) |
3876 |
{ |
3877 |
size_t i; |
3878 |
int ret; |
3879 |
+ tree_ctx *vdb; |
3880 |
DECLARE_ARRAY(ignore_regexp); |
3881 |
depend_atom *atom; |
3882 |
DECLARE_ARRAY(atoms); |
3883 |
@@ -230,7 +231,11 @@ int qsize_main(int argc, char **argv) |
3884 |
state.buflen = _Q_PATH_MAX; |
3885 |
state.buf = xmalloc(state.buflen); |
3886 |
|
3887 |
- ret = vdb_foreach_pkg(portroot, portvdb, qsize_cb, &state, NULL); |
3888 |
+ vdb = tree_open_vdb(portroot, portvdb); |
3889 |
+ if (vdb != NULL) { |
3890 |
+ ret = tree_foreach_pkg_fast(vdb, qsize_cb, &state, NULL); |
3891 |
+ tree_close(vdb); |
3892 |
+ } |
3893 |
|
3894 |
if (state.summary) { |
3895 |
printf(" %sTotals%s: %'zu files, %'zu non-files, ", BOLD, NORM, |
3896 |
|
3897 |
diff --git a/quse.c b/quse.c |
3898 |
index 604efdf..6def799 100644 |
3899 |
--- a/quse.c |
3900 |
+++ b/quse.c |
3901 |
@@ -21,8 +21,8 @@ |
3902 |
#include <ctype.h> |
3903 |
#include <assert.h> |
3904 |
|
3905 |
-#include "cache.h" |
3906 |
#include "rmspace.h" |
3907 |
+#include "tree.h" |
3908 |
#include "xarray.h" |
3909 |
#include "xregex.h" |
3910 |
|
3911 |
@@ -401,12 +401,12 @@ quse_describe_flag(const char *root, const char *overlay, |
3912 |
} |
3913 |
|
3914 |
static int |
3915 |
-quse_results_cb(cache_pkg_ctx *pkg_ctx, void *priv) |
3916 |
+quse_results_cb(tree_pkg_ctx *pkg_ctx, void *priv) |
3917 |
{ |
3918 |
struct quse_state *state = (struct quse_state *)priv; |
3919 |
depend_atom *atom = NULL; /* pacify compiler */ |
3920 |
char buf[8192]; |
3921 |
- cache_pkg_meta *meta; |
3922 |
+ tree_pkg_meta *meta; |
3923 |
bool match; |
3924 |
char *p; |
3925 |
char *q; |
3926 |
@@ -436,7 +436,7 @@ quse_results_cb(cache_pkg_ctx *pkg_ctx, void *priv) |
3927 |
} |
3928 |
} |
3929 |
|
3930 |
- meta = cache_pkg_read(pkg_ctx); |
3931 |
+ meta = tree_pkg_read(pkg_ctx); |
3932 |
if (meta == NULL) |
3933 |
return 0; |
3934 |
|
3935 |
@@ -591,7 +591,7 @@ quse_results_cb(cache_pkg_ctx *pkg_ctx, void *priv) |
3936 |
} |
3937 |
} |
3938 |
|
3939 |
- cache_close_meta(meta); |
3940 |
+ tree_close_meta(meta); |
3941 |
if (state->match && verbose) |
3942 |
atom_implode(atom); |
3943 |
if (verbose) |
3944 |
@@ -656,9 +656,12 @@ int quse_main(int argc, char **argv) |
3945 |
quse_describe_flag(portroot, overlay, &state); |
3946 |
} else { |
3947 |
array_for_each(overlays, n, overlay) { |
3948 |
+ tree_ctx *t = tree_open(portroot, overlay); |
3949 |
state.overlay = overlay; |
3950 |
- cache_foreach_pkg_sorted(portroot, overlay, |
3951 |
- quse_results_cb, &state, NULL, NULL); |
3952 |
+ if (t != NULL) { |
3953 |
+ tree_foreach_pkg_sorted(t, quse_results_cb, &state); |
3954 |
+ tree_close(t); |
3955 |
+ } |
3956 |
} |
3957 |
} |