1 |
commit: f2e63b4a1280d0a2c18cb1a66ceffd9699d1b9ac |
2 |
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon May 25 10:39:05 2020 +0000 |
4 |
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon May 25 10:39:05 2020 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=f2e63b4a |
7 |
|
8 |
qmerge: use libq/tree for binpkg/Packages needs |
9 |
|
10 |
Instead of manual parsing of Packages file and traversing binpkgs, use |
11 |
the functionality provided by libq/tree, most notably tree_match_atom(). |
12 |
|
13 |
This is just phase one, where we replace the custom code with libq/tree |
14 |
code and then fill in the Pkg structure. In a next phase we should skip |
15 |
this and directly use tree_match_ctx, with atom and meta in there. |
16 |
|
17 |
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org> |
18 |
|
19 |
qmerge.c | 596 +++++++++++++-------------------------------------------------- |
20 |
1 file changed, 116 insertions(+), 480 deletions(-) |
21 |
|
22 |
diff --git a/qmerge.c b/qmerge.c |
23 |
index 087c5f2..554e3dc 100644 |
24 |
--- a/qmerge.c |
25 |
+++ b/qmerge.c |
26 |
@@ -120,8 +120,7 @@ typedef struct llist_char_t llist_char; |
27 |
static void pkg_fetch(int, const depend_atom *, const struct pkg_t *); |
28 |
static void pkg_merge(int, const depend_atom *, const struct pkg_t *); |
29 |
static int pkg_unmerge(tree_pkg_ctx *, set *, int, char **, int, char **); |
30 |
-static struct pkg_t *grab_binpkg_info(const char *); |
31 |
-static char *find_binpkg(const char *); |
32 |
+static struct pkg_t *grab_binpkg_info(depend_atom *); |
33 |
|
34 |
static bool |
35 |
prompt(const char *p) |
36 |
@@ -129,12 +128,12 @@ prompt(const char *p) |
37 |
printf("%s? [Y/n] ", p); |
38 |
fflush(stdout); |
39 |
switch (getc(stdin)) { |
40 |
- case '\n': |
41 |
- case 'y': |
42 |
- case 'Y': |
43 |
- return true; |
44 |
- default: |
45 |
- return false; |
46 |
+ case '\n': |
47 |
+ case 'y': |
48 |
+ case 'Y': |
49 |
+ return true; |
50 |
+ default: |
51 |
+ return false; |
52 |
} |
53 |
} |
54 |
|
55 |
@@ -579,7 +578,7 @@ qprint_tree_node(int level, const depend_atom *atom, const struct pkg_t *pkg) |
56 |
} else { |
57 |
depend_atom *subatom = atom_explode(p); |
58 |
if (subatom != NULL) { |
59 |
- ret = atom_compare(atom, subatom); |
60 |
+ ret = atom_compare(subatom, atom); |
61 |
switch (ret) { |
62 |
case EQUAL: c = 'R'; break; |
63 |
case NEWER: c = 'U'; break; |
64 |
@@ -1009,7 +1008,7 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
65 |
if (((c == 'R') || (c == 'D')) && update_only) |
66 |
return; |
67 |
|
68 |
- if (pkg->RDEPEND[0] && follow_rdepends) { |
69 |
+ if (pkg->RDEPEND[0] != '\0' && follow_rdepends) { |
70 |
const char *rdepend; |
71 |
|
72 |
IF_DEBUG(fprintf(stderr, "\n+Parent: %s/%s\n", pkg->CATEGORY, pkg->PF)); |
73 |
@@ -1040,30 +1039,17 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
74 |
case '\0': |
75 |
break; |
76 |
default: |
77 |
- if (*name == '~') { |
78 |
- name = ARGV[i] + 1; |
79 |
- /* warn("newname = %s", name); */ |
80 |
- } |
81 |
if ((subatom = atom_explode(name)) != NULL) { |
82 |
struct pkg_t *subpkg; |
83 |
- char *resolved = NULL; |
84 |
- |
85 |
- resolved = find_binpkg(name); |
86 |
|
87 |
- IF_DEBUG(fprintf(stderr, |
88 |
- "+Atom: argv0(%s) resolved(%s)\n", |
89 |
- name, resolved)); |
90 |
- |
91 |
- if (strlen(resolved) < 1) { |
92 |
- warn("Cant find a binpkg for %s from rdepend(%s)", |
93 |
+ subpkg = grab_binpkg_info(subatom); /* free me later */ |
94 |
+ if (subpkg == NULL) { |
95 |
+ warn("Cannot find a binpkg for %s from rdepend(%s)", |
96 |
name, pkg->RDEPEND); |
97 |
atom_implode(subatom); |
98 |
continue; |
99 |
} |
100 |
|
101 |
- /* ratom = atom_explode(resolved); */ |
102 |
- subpkg = grab_binpkg_info(resolved); /* free me later */ |
103 |
- |
104 |
assert(subpkg != NULL); |
105 |
IF_DEBUG(fprintf(stderr, "+Subpkg: %s/%s\n", |
106 |
subpkg->CATEGORY, subpkg->PF)); |
107 |
@@ -1182,7 +1168,8 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
108 |
} else if (mlen == 257+6 && |
109 |
magic[257] == 'u' && magic[258] == 's' && |
110 |
magic[259] == 't' && magic[260] == 'a' && |
111 |
- magic[261] == 'r' && magic[262] == '\0') |
112 |
+ magic[261] == 'r' && |
113 |
+ (magic[262] == '\0' || magic[262] == ' ')) |
114 |
{ |
115 |
compr = ""; |
116 |
} else if (mlen >= 4 && |
117 |
@@ -1399,7 +1386,7 @@ pkg_merge(int level, const depend_atom *atom, const struct pkg_t *pkg) |
118 |
rmdir("../qmerge"); |
119 |
|
120 |
printf("%s>>>%s %s%s%s/%s%s%s\n", |
121 |
- YELLOW, NORM, WHITE, atom->CATEGORY, NORM, CYAN, pkg->PF, NORM); |
122 |
+ YELLOW, NORM, WHITE, pkg->CATEGORY, NORM, CYAN, pkg->PF, NORM); |
123 |
|
124 |
tree_close_cat(cat_ctx); |
125 |
tree_close(vdb); |
126 |
@@ -1622,7 +1609,7 @@ pkg_verify_checksums( |
127 |
} |
128 |
|
129 |
if (pkg->MD5[0]) { |
130 |
- if (md5 != NULL && strcmp(md5, pkg->MD5) == 0) { |
131 |
+ if (strcmp(md5, pkg->MD5) == 0) { |
132 |
if (display) |
133 |
printf("MD5: [%sOK%s] %s %s/%s\n", |
134 |
GREEN, NORM, md5, atom->CATEGORY, pkg->PF); |
135 |
@@ -1634,7 +1621,7 @@ pkg_verify_checksums( |
136 |
} |
137 |
} |
138 |
|
139 |
- if (sha1 != NULL && pkg->SHA1[0]) { |
140 |
+ if (pkg->SHA1[0]) { |
141 |
if (strcmp(sha1, pkg->SHA1) == 0) { |
142 |
if (display) |
143 |
qprintf("SHA1: [%sOK%s] %s %s/%s\n", |
144 |
@@ -1663,7 +1650,8 @@ pkg_fetch(int level, const depend_atom *atom, const struct pkg_t *pkg) |
145 |
|
146 |
/* qmerge -pv patch */ |
147 |
if (pretend) { |
148 |
- if (!install) install++; |
149 |
+ if (!install) |
150 |
+ install++; |
151 |
/* qprint_tree_node(level, atom, pkg); */ |
152 |
pkg_merge(level, atom, pkg); |
153 |
return; |
154 |
@@ -1679,13 +1667,12 @@ pkg_fetch(int level, const depend_atom *atom, const struct pkg_t *pkg) |
155 |
return; |
156 |
} |
157 |
|
158 |
- /* XXX: should do a size check here for partial downloads */ |
159 |
- |
160 |
if (force_download && (access(buf, R_OK) == 0) && |
161 |
(pkg->SHA1[0] || pkg->MD5[0])) |
162 |
{ |
163 |
if (pkg_verify_checksums(buf, pkg, atom, 0, 0) != 0) |
164 |
- unlink(buf); |
165 |
+ if (getenv("QMERGE") == NULL) |
166 |
+ unlink(buf); |
167 |
} |
168 |
if (access(buf, R_OK) == 0) { |
169 |
if (!pkg->SHA1[0] && !pkg->MD5[0]) { |
170 |
@@ -1742,7 +1729,7 @@ print_Pkg(int full, const depend_atom *atom, const struct pkg_t *pkg) |
171 |
char *p = NULL; |
172 |
char buf[512]; |
173 |
|
174 |
- printf("%s%s/%s%s:%s%s%s%s%s\n", BOLD, atom->CATEGORY, BLUE, pkg->PF, pkg->SLOT, NORM, |
175 |
+ printf("%s%s%s%s\n", atom_format("%[CAT]%[PF]%[SLOT]", atom), |
176 |
!quiet ? " [" : "", |
177 |
!quiet ? make_human_readable_str(pkg->SIZE, 1, KILOBYTE) : "", |
178 |
!quiet ? " KiB]" : ""); |
179 |
@@ -1757,7 +1744,8 @@ print_Pkg(int full, const depend_atom *atom, const struct pkg_t *pkg) |
180 |
if (pkg->MD5[0]) |
181 |
printf(" %sMd5%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->MD5); |
182 |
if (!pkg->MD5[0] && !pkg->SHA1[0]) |
183 |
- printf(" %sSums%s:%s %s(MISSING!)%s\n", DKGREEN, YELLOW, NORM, RED, NORM); |
184 |
+ printf(" %sSums%s:%s %s(MISSING!)%s\n", |
185 |
+ DKGREEN, YELLOW, NORM, RED, NORM); |
186 |
if (pkg->SLOT[0]) |
187 |
printf(" %sSlot%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->SLOT); |
188 |
if (pkg->LICENSE[0]) |
189 |
@@ -1781,7 +1769,8 @@ print_Pkg(int full, const depend_atom *atom, const struct pkg_t *pkg) |
190 |
case OLDER: icolor = BLUE; break; |
191 |
default: icolor = NORM; break; |
192 |
} |
193 |
- printf(" %sInstalled%s:%s %s%s%s\n", DKGREEN, YELLOW, NORM, icolor, p, NORM); |
194 |
+ printf(" %sInstalled%s:%s %s%s%s\n", |
195 |
+ DKGREEN, YELLOW, NORM, icolor, p, NORM); |
196 |
} |
197 |
} |
198 |
} |
199 |
@@ -1833,453 +1822,70 @@ unmerge_packages(set *todo) |
200 |
return ret; |
201 |
} |
202 |
|
203 |
-static FILE * |
204 |
-open_binpkg_index(void) |
205 |
-{ |
206 |
- FILE *fp; |
207 |
- char *path; |
208 |
- |
209 |
- xasprintf(&path, "%s/portage/%s", port_tmpdir, Packages); |
210 |
- fp = fopen(path, "r"); |
211 |
- if (fp) |
212 |
- goto done; |
213 |
- free(path); |
214 |
- |
215 |
- xasprintf(&path, "%s/%s", pkgdir, Packages); |
216 |
- fp = fopen(path, "r"); |
217 |
- if (fp) |
218 |
- goto done; |
219 |
- |
220 |
- /* This is normal when installing from local repo only. */ |
221 |
- warnp("Unable to open package file %s in %s/portage or %s", |
222 |
- Packages, port_tmpdir, pkgdir); |
223 |
- warn("Attempting to manually regen via `emaint binhost`"); |
224 |
- |
225 |
- pid_t p; |
226 |
- int status; |
227 |
- |
228 |
- char argv_emaint[] = "emaint"; |
229 |
- char argv_binhost[] = "binhost"; |
230 |
- char argv_fix[] = "--fix"; |
231 |
- char *argv[] = { |
232 |
- argv_emaint, |
233 |
- argv_binhost, |
234 |
- argv_fix, |
235 |
- NULL, |
236 |
- }; |
237 |
- |
238 |
- p = vfork(); |
239 |
- switch (p) { |
240 |
- case 0: |
241 |
- _exit(execvp(argv[0], argv)); |
242 |
- case -1: |
243 |
- errp("vfork failed"); |
244 |
- } |
245 |
- waitpid(p, &status, 0); |
246 |
- |
247 |
- fp = fopen(path, "r"); |
248 |
- |
249 |
- done: |
250 |
- free(path); |
251 |
- return fp; |
252 |
-} |
253 |
- |
254 |
+static tree_ctx *_grab_binpkg_info_tree = NULL; |
255 |
static struct pkg_t * |
256 |
-grab_binpkg_info(const char *name) |
257 |
-{ |
258 |
- FILE *fp; |
259 |
- char buf[BUFSIZ]; |
260 |
- char *p; |
261 |
- depend_atom *atom; |
262 |
- |
263 |
- struct pkg_t Pkg; |
264 |
- struct pkg_t *pkg = xzalloc(sizeof(struct pkg_t)); |
265 |
- struct pkg_t *rpkg = xzalloc(sizeof(struct pkg_t)); |
266 |
- |
267 |
- static char best_match[sizeof(Pkg.PF)+2+sizeof(Pkg.CATEGORY)]; |
268 |
- |
269 |
- best_match[0] = 0; |
270 |
- strcpy(pkg->SLOT,"0"); |
271 |
- |
272 |
- fp = open_binpkg_index(); |
273 |
- |
274 |
- while (fgets(buf, sizeof(buf), fp) != NULL) { |
275 |
- if (*buf == '\n') { |
276 |
- if (pkg->PF[0] && pkg->CATEGORY[0]) { |
277 |
- int ret; |
278 |
- |
279 |
- snprintf(buf, sizeof(buf), "%s/%s", pkg->CATEGORY, pkg->PF); |
280 |
- if (strstr(buf, name) != NULL) { |
281 |
- if (!best_match[0]) |
282 |
- snprintf(best_match, sizeof(best_match), "%.*s", |
283 |
- (int)sizeof(best_match) - 1, buf); |
284 |
- |
285 |
- atom = atom_explode(buf); |
286 |
- if (atom->PR_int) { |
287 |
- snprintf(buf, sizeof(buf), "%s/%s-%s-r%i", |
288 |
- atom->CATEGORY, atom->PN, |
289 |
- atom->PV, atom->PR_int); |
290 |
- } else { |
291 |
- snprintf(buf, sizeof(buf), "%s/%s-%s", |
292 |
- atom->CATEGORY, atom->PN, atom->PV); |
293 |
- } |
294 |
- ret = atom_compare_str(name, buf); |
295 |
- IF_DEBUG(fprintf(stderr, |
296 |
- "=== atom_compare(%s, %s) = %d %s\n", |
297 |
- name, buf, ret, booga[ret])); |
298 |
- /* buf(%s) depend(%s)\n", ret, pkg->CATEGORY, |
299 |
- * pkg->PF, name, pkg->RDEPEND); */ |
300 |
- switch (ret) { |
301 |
- case EQUAL: |
302 |
- case NEWER: |
303 |
- snprintf(buf, sizeof(buf), "%s/%s", |
304 |
- pkg->CATEGORY, pkg->PF); |
305 |
- ret = atom_compare_str(buf, best_match); |
306 |
- if (ret == NEWER || ret == EQUAL) { |
307 |
- snprintf(best_match, sizeof(best_match), "%.*s", |
308 |
- (int)sizeof(best_match) - 1, buf); |
309 |
- memcpy(rpkg, pkg, sizeof(struct pkg_t)); |
310 |
- IF_DEBUG(fprintf(stderr, |
311 |
- "--- %s/%s depend(%s)\n", |
312 |
- rpkg->CATEGORY, rpkg->PF, |
313 |
- rpkg->RDEPEND)); |
314 |
- } |
315 |
- case OLDER: break; |
316 |
- default: |
317 |
- break; |
318 |
- } |
319 |
- atom_implode(atom); |
320 |
- } |
321 |
- memset(pkg, 0, sizeof(struct pkg_t)); |
322 |
- strcpy(pkg->SLOT,"0"); |
323 |
- } |
324 |
- continue; |
325 |
- } |
326 |
- |
327 |
- if ((p = strchr(buf, '\n')) != NULL) |
328 |
- *p = 0; |
329 |
- if ((p = strchr(buf, ':')) == NULL) |
330 |
- continue; |
331 |
- if (p[1] != ' ') |
332 |
- continue; |
333 |
- *p = 0; |
334 |
- p += 2; |
335 |
- |
336 |
- if (*buf) { |
337 |
- /* we dont need all the info */ |
338 |
- if (strcmp(buf, "RDEPEND") == 0) |
339 |
- snprintf(pkg->RDEPEND, sizeof(Pkg.RDEPEND), "%.*s", |
340 |
- (int)sizeof(Pkg.RDEPEND) - 1, p); |
341 |
- if (strcmp(buf, "PF") == 0) |
342 |
- snprintf(pkg->PF, sizeof(Pkg.PF), "%.*s", |
343 |
- (int)sizeof(Pkg.PF) - 1, p); |
344 |
- if (strcmp(buf, "CATEGORY") == 0) |
345 |
- snprintf(pkg->CATEGORY, sizeof(Pkg.CATEGORY), "%.*s", |
346 |
- (int)sizeof(Pkg.CATEGORY) - 1, p); |
347 |
- if (strcmp(buf, "REPO") == 0) |
348 |
- snprintf(pkg->REPO, sizeof(Pkg.REPO), "%.*s", |
349 |
- (int)sizeof(Pkg.REPO) - 1, p); |
350 |
- |
351 |
- if (strcmp(buf, "CPV") == 0) { |
352 |
- if ((atom = atom_explode(p)) != NULL) { |
353 |
- if (atom->PR_int) { |
354 |
- snprintf(buf, sizeof(buf), "%s-%s-r%i", |
355 |
- atom->PN, atom->PV, atom->PR_int); |
356 |
- } else { |
357 |
- snprintf(buf, sizeof(buf), "%s-%s", atom->PN, atom->PV); |
358 |
- } |
359 |
- snprintf(pkg->PF, sizeof(Pkg.PF), "%.*s", |
360 |
- (int)sizeof(Pkg.PF) - 1, buf); |
361 |
- snprintf(pkg->CATEGORY, sizeof(Pkg.CATEGORY), "%.*s", |
362 |
- (int)sizeof(Pkg.CATEGORY) - 1, atom->CATEGORY); |
363 |
- atom_implode(atom); |
364 |
- } |
365 |
- } |
366 |
- if (strcmp(buf, "SLOT") == 0) |
367 |
- snprintf(pkg->SLOT, sizeof(Pkg.SLOT), "%.*s", |
368 |
- (int)sizeof(Pkg.SLOT) - 1, p); |
369 |
- if (strcmp(buf, "USE") == 0) |
370 |
- snprintf(pkg->USE, sizeof(Pkg.USE), "%.*s", |
371 |
- (int)sizeof(Pkg.USE) - 1, p); |
372 |
- /* checksums. We must have 1 or the other unless --*/ |
373 |
- if (strcmp(buf, "MD5") == 0) |
374 |
- snprintf(pkg->MD5, sizeof(Pkg.MD5), "%.*s", |
375 |
- (int)sizeof(Pkg.MD5) - 1, p); |
376 |
- if (strcmp(buf, "SHA1") == 0) |
377 |
- snprintf(pkg->SHA1, sizeof(Pkg.SHA1), "%.*s", |
378 |
- (int)sizeof(Pkg.SHA1) - 1, p); |
379 |
- } |
380 |
- } |
381 |
- fclose(fp); |
382 |
- free(pkg); |
383 |
- return rpkg; |
384 |
-} |
385 |
- |
386 |
-static char * |
387 |
-find_binpkg(const char *name) |
388 |
+grab_binpkg_info(depend_atom *atom) |
389 |
{ |
390 |
- FILE *fp; |
391 |
- char buf[BUFSIZ]; |
392 |
- char *p; |
393 |
- struct pkg_t Pkg; |
394 |
- char PF[sizeof(Pkg.PF)]; |
395 |
- char CATEGORY[sizeof(Pkg.CATEGORY)]; |
396 |
- |
397 |
- static char best_match[sizeof(Pkg.PF)+2+sizeof(Pkg.CATEGORY)]; |
398 |
- |
399 |
- best_match[0] = 0; |
400 |
- if (NULL == name) |
401 |
- return best_match; |
402 |
- |
403 |
- fp = open_binpkg_index(); |
404 |
- PF[0] = CATEGORY[0] = '\0'; |
405 |
- |
406 |
- while (fgets(buf, sizeof(buf), fp) != NULL) { |
407 |
- if (*buf == '\n') { |
408 |
- if (PF[0] && CATEGORY[0]) { |
409 |
- int ret; |
410 |
- snprintf(buf, sizeof(buf), "%s/%s", CATEGORY, PF); |
411 |
- if (strstr(buf, name) != NULL) { |
412 |
- depend_atom *atom; |
413 |
- |
414 |
- if (!best_match[0]) |
415 |
- snprintf(best_match, sizeof(best_match), "%.*s", |
416 |
- (int)sizeof(best_match) - 1, buf); |
417 |
- |
418 |
- atom = atom_explode(buf); |
419 |
- snprintf(buf, sizeof(buf), "%s/%s", |
420 |
- atom->CATEGORY, atom->PN); |
421 |
- ret = atom_compare_str(name, buf); |
422 |
- switch (ret) { |
423 |
- case OLDER: break; |
424 |
- case NEWER: |
425 |
- case EQUAL: |
426 |
- snprintf(buf, sizeof(buf), "%s/%s", CATEGORY, PF); |
427 |
- ret = atom_compare_str(buf, best_match); |
428 |
- if (ret == NEWER || ret == EQUAL) |
429 |
- snprintf(best_match, sizeof(best_match), "%.*s", |
430 |
- (int)sizeof(best_match) - 1, buf); |
431 |
- /* printf("[%s == %s] = %d; %s/%s\n", |
432 |
- * name, buf, ret, CATEGORY, PF); */ |
433 |
- default: |
434 |
- break; |
435 |
- } |
436 |
- atom_implode(atom); |
437 |
- } |
438 |
- } |
439 |
- continue; |
440 |
- } |
441 |
- |
442 |
- if ((p = strchr(buf, '\n')) != NULL) |
443 |
- *p = 0; |
444 |
- if ((p = strchr(buf, ':')) == NULL) |
445 |
- continue; |
446 |
- if (p[1] != ' ') |
447 |
- continue; |
448 |
- *p = 0; |
449 |
- p += 2; |
450 |
- |
451 |
- if (*buf) { |
452 |
- if (strcmp(buf, "CPV") == 0) { |
453 |
- depend_atom *atom; |
454 |
- if ((atom = atom_explode(p)) != NULL) { |
455 |
- if (atom->PR_int) { |
456 |
- snprintf(buf, sizeof(buf), "%s-%s-r%i", |
457 |
- atom->PN, atom->PV, atom->PR_int); |
458 |
- } else { |
459 |
- snprintf(buf, sizeof(buf), "%s-%s", atom->PN, atom->PV); |
460 |
- } |
461 |
- snprintf(PF, sizeof(PF), "%.*s", (int)sizeof(PF) - 1, buf); |
462 |
- snprintf(CATEGORY, sizeof(CATEGORY), "%.*s", |
463 |
- (int)sizeof(CATEGORY) - 1, atom->CATEGORY); |
464 |
- atom_implode(atom); |
465 |
- } |
466 |
- } |
467 |
- if (strcmp(buf, "PF") == 0) |
468 |
- snprintf(PF, sizeof(PF), "%.*s", (int)sizeof(PF) - 1, p); |
469 |
- if (strcmp(buf, "CATEGORY") == 0) |
470 |
- snprintf(CATEGORY, sizeof(CATEGORY), "%.*s", |
471 |
- (int)sizeof(CATEGORY) - 1, p); |
472 |
- } |
473 |
- } |
474 |
- fclose(fp); |
475 |
- return best_match; |
476 |
-} |
477 |
- |
478 |
-static int |
479 |
-parse_packages(set *todo) |
480 |
-{ |
481 |
- FILE *fp; |
482 |
- int linelen; |
483 |
- size_t buflen; |
484 |
- char *buf, *p; |
485 |
- struct pkg_t Pkg; |
486 |
- depend_atom *pkg_atom; |
487 |
- char repo[sizeof(Pkg.REPO)]; |
488 |
- depend_atom **todo_atoms = NULL; |
489 |
- size_t todo_cnt = 0; |
490 |
- size_t i; |
491 |
- |
492 |
- fp = open_binpkg_index(); |
493 |
- if (fp == NULL) |
494 |
- return EXIT_FAILURE; |
495 |
- |
496 |
- buf = NULL; |
497 |
- buflen = 0; /* make getline allocate */ |
498 |
- repo[0] = '\0'; |
499 |
- |
500 |
- /* First consume the header with the common data. */ |
501 |
- while ((linelen = getline(&buf, &buflen, fp)) >= 0) { |
502 |
- rmspace_len(buf, (size_t)linelen); |
503 |
- if (buf[0] == '\0') |
504 |
- break; |
505 |
- |
506 |
- if ((p = strchr(buf, ':')) == NULL) |
507 |
- continue; |
508 |
- if (p[1] != ' ') |
509 |
- continue; |
510 |
- *p = 0; |
511 |
- p += 2; |
512 |
- |
513 |
- switch (*buf) { |
514 |
- case 'R': |
515 |
- if (!strcmp(buf, "REPO")) |
516 |
- snprintf(repo, sizeof(repo), "%.*s", (int)sizeof(repo) - 1, p); |
517 |
- break; |
518 |
+ tree_ctx *tree = _grab_binpkg_info_tree; |
519 |
+ tree_match_ctx *tpkg; |
520 |
+ struct pkg_t *pkg = NULL; |
521 |
+ char path[BUFSIZ]; |
522 |
+ FILE *d; |
523 |
+ |
524 |
+ /* reuse previously opened tree, so we really employ the cache |
525 |
+ * from libq/tree */ |
526 |
+ if (tree == NULL) { |
527 |
+ snprintf(path, sizeof(path), "%s/portage/Packages", port_tmpdir); |
528 |
+ /* we don't use ROOT on package tree here, operating on ROOT |
529 |
+ * should be for package merges/unmerges, but be able to pull |
530 |
+ * binpkgs from current system */ |
531 |
+ if ((d = fopen(path, "r")) != NULL) { |
532 |
+ fclose(d); |
533 |
+ snprintf(path, sizeof(path), "%s/portage", port_tmpdir); |
534 |
+ tree = tree_open_binpkg("/", path); |
535 |
+ } else { |
536 |
+ tree = tree_open_binpkg("/", pkgdir); |
537 |
} |
538 |
- } |
539 |
+ _grab_binpkg_info_tree = tree; |
540 |
|
541 |
- pkg_atom = NULL; |
542 |
- memset(&Pkg, 0, sizeof(Pkg)); |
543 |
- strcpy(Pkg.SLOT, "0"); |
544 |
- |
545 |
- /* build list with exploded atoms for each access below */ |
546 |
- if (todo != NULL) { |
547 |
- char **todo_strs; |
548 |
- todo_cnt = list_set(todo, &todo_strs); |
549 |
- todo_atoms = xmalloc(sizeof(*todo_atoms) * todo_cnt); |
550 |
- for (i = 0; i < todo_cnt; i++) |
551 |
- todo_atoms[i] = atom_explode(todo_strs[i]); |
552 |
- free(todo_strs); |
553 |
+ /* if opening the tree failed somehow, we can't return anything */ |
554 |
+ if (tree == NULL) |
555 |
+ return NULL; |
556 |
} |
557 |
|
558 |
- /* Then walk all the package entries. */ |
559 |
- while (getline(&buf, &buflen, fp) != -1) { |
560 |
- if (*buf == '\n') { |
561 |
- if (pkg_atom) { |
562 |
- if (search_pkgs && !todo) { |
563 |
- print_Pkg(verbose, pkg_atom, &Pkg); |
564 |
- } else { |
565 |
- for (i = 0; i < todo_cnt; i++) { |
566 |
- pkg_atom->REPO = todo_atoms[i]->REPO ? Pkg.REPO : NULL; |
567 |
- pkg_atom->SLOT = todo_atoms[i]->SLOT ? Pkg.SLOT : NULL; |
568 |
- if (atom_compare(pkg_atom, todo_atoms[i]) == EQUAL) { |
569 |
- if (search_pkgs) |
570 |
- print_Pkg(verbose, pkg_atom, &Pkg); |
571 |
- else |
572 |
- pkg_fetch(0, pkg_atom, &Pkg); |
573 |
- } |
574 |
- } |
575 |
- } |
576 |
|
577 |
- atom_implode(pkg_atom); |
578 |
- pkg_atom = NULL; |
579 |
- } |
580 |
- memset(&Pkg, 0, sizeof(Pkg)); |
581 |
- strcpy(Pkg.SLOT, "0"); |
582 |
- strcpy(Pkg.REPO, repo); |
583 |
- continue; |
584 |
- } |
585 |
- |
586 |
- if ((p = strchr(buf, '\n')) != NULL) |
587 |
- *p = 0; |
588 |
- if ((p = strchr(buf, ':')) == NULL) |
589 |
- continue; |
590 |
- if (p[1] != ' ') |
591 |
- continue; |
592 |
- *p = 0; |
593 |
- p += 2; |
594 |
- |
595 |
- switch (*buf) { |
596 |
- case 'U': |
597 |
- if (strcmp(buf, "USE") == 0) |
598 |
- snprintf(Pkg.USE, sizeof(Pkg.USE), "%.*s", |
599 |
- (int)sizeof(Pkg.USE) - 1, p); |
600 |
- break; |
601 |
- case 'P': |
602 |
- if (strcmp(buf, "PF") == 0) |
603 |
- snprintf(Pkg.PF, sizeof(Pkg.PF), "%.*s", |
604 |
- (int)sizeof(Pkg.PF) - 1, p); |
605 |
- break; |
606 |
- case 'S': |
607 |
- if (strcmp(buf, "SIZE") == 0) |
608 |
- Pkg.SIZE = atol(p); |
609 |
- if (strcmp(buf, "SLOT") == 0) |
610 |
- snprintf(Pkg.SLOT, sizeof(Pkg.SLOT), "%.*s", |
611 |
- (int)sizeof(Pkg.SLOT) - 1, p); |
612 |
- if (strcmp(buf, "SHA1") == 0) |
613 |
- snprintf(Pkg.SHA1, sizeof(Pkg.SHA1), "%.*s", |
614 |
- (int)sizeof(Pkg.SHA1) - 1, p); |
615 |
- break; |
616 |
- case 'M': |
617 |
- if (strcmp(buf, "MD5") == 0) |
618 |
- snprintf(Pkg.MD5, sizeof(Pkg.MD5), "%.*s", |
619 |
- (int)sizeof(Pkg.MD5) - 1, p); |
620 |
- break; |
621 |
- case 'R': |
622 |
- if (strcmp(buf, "REPO") == 0) |
623 |
- snprintf(Pkg.REPO, sizeof(Pkg.REPO), "%.*s", |
624 |
- (int)sizeof(Pkg.REPO) - 1, p); |
625 |
- if (strcmp(buf, "RDEPEND") == 0) |
626 |
- snprintf(Pkg.RDEPEND, sizeof(Pkg.RDEPEND), "%.*s", |
627 |
- (int)sizeof(Pkg.RDEPEND) - 1, p); |
628 |
- break; |
629 |
- case 'L': |
630 |
- if (strcmp(buf, "LICENSE") == 0) |
631 |
- snprintf(Pkg.LICENSE, sizeof(Pkg.LICENSE), "%.*s", |
632 |
- (int)sizeof(Pkg.LICENSE) - 1, p); |
633 |
- break; |
634 |
- case 'C': |
635 |
- if (strcmp(buf, "CATEGORY") == 0) |
636 |
- snprintf(Pkg.CATEGORY, sizeof(Pkg.CATEGORY), "%.*s", |
637 |
- (int)sizeof(Pkg.CATEGORY) - 1, p); |
638 |
- if (strcmp(buf, "CPV") == 0) { |
639 |
- if (pkg_atom != NULL) /* hypothetical Coverity case */ |
640 |
- atom_implode(pkg_atom); |
641 |
- if ((pkg_atom = atom_explode(p)) != NULL) { |
642 |
- if (pkg_atom->PR_int) |
643 |
- snprintf(Pkg.PF, sizeof(Pkg.PF), "%s-%s-r%i", |
644 |
- pkg_atom->PN, pkg_atom->PV, |
645 |
- pkg_atom->PR_int); |
646 |
- else |
647 |
- snprintf(Pkg.PF, sizeof(Pkg.PF), "%s-%s", |
648 |
- pkg_atom->PN, pkg_atom->PV); |
649 |
- snprintf(Pkg.CATEGORY, sizeof(Pkg.CATEGORY), |
650 |
- "%.*s", (int)sizeof(Pkg.CATEGORY) - 1, |
651 |
- pkg_atom->CATEGORY); |
652 |
- } |
653 |
- } |
654 |
- break; |
655 |
- case 'D': |
656 |
- if (strcmp(buf, "DESC") == 0) |
657 |
- snprintf(Pkg.DESC, sizeof(Pkg.DESC), "%.*s", |
658 |
- (int)sizeof(Pkg.DESC) - 1, p); |
659 |
- break; |
660 |
- default: |
661 |
- break; |
662 |
- } |
663 |
+ tpkg = tree_match_atom(tree, atom, |
664 |
+ TREE_MATCH_FIRST | TREE_MATCH_VIRTUAL | TREE_MATCH_METADATA); |
665 |
+ if (tpkg != NULL) { |
666 |
+ depend_atom *tatom = tpkg->atom; |
667 |
+ tree_pkg_meta *meta = tpkg->meta; |
668 |
+ pkg = xzalloc(sizeof(struct pkg_t)); |
669 |
+ |
670 |
+ snprintf(pkg->PF, sizeof(pkg->PF), "%s", tatom->PF); |
671 |
+ snprintf(pkg->CATEGORY, sizeof(pkg->CATEGORY), "%s", tatom->CATEGORY); |
672 |
+ if (meta->Q_DESCRIPTION != NULL) |
673 |
+ snprintf(pkg->DESC, sizeof(pkg->DESC), "%s", meta->Q_DESCRIPTION); |
674 |
+ if (meta->Q_LICENSE != NULL) |
675 |
+ snprintf(pkg->LICENSE, sizeof(pkg->LICENSE), "%s", meta->Q_LICENSE); |
676 |
+ if (meta->Q_RDEPEND != NULL) |
677 |
+ snprintf(pkg->RDEPEND, sizeof(pkg->RDEPEND), "%s", meta->Q_RDEPEND); |
678 |
+ if (meta->Q_MD5 != NULL) |
679 |
+ snprintf(pkg->MD5, sizeof(pkg->MD5), "%s", meta->Q_MD5); |
680 |
+ if (meta->Q_SHA1 != NULL) |
681 |
+ snprintf(pkg->SHA1, sizeof(pkg->SHA1), "%s", meta->Q_SHA1); |
682 |
+ if (meta->Q_USE != NULL) |
683 |
+ snprintf(pkg->USE, sizeof(pkg->USE), "%s", meta->Q_USE); |
684 |
+ if (meta->Q_repository != NULL) |
685 |
+ snprintf(pkg->REPO, sizeof(pkg->REPO), "%s", meta->Q_repository); |
686 |
+ if (meta->Q_SLOT != NULL) |
687 |
+ snprintf(pkg->REPO, sizeof(pkg->REPO), "%s", meta->Q_SLOT); |
688 |
+ if (meta->Q_SIZE != NULL) |
689 |
+ pkg->SIZE = atoi(meta->Q_SIZE); |
690 |
+ |
691 |
+ tree_match_close(tpkg); |
692 |
} |
693 |
|
694 |
- free(buf); |
695 |
- fclose(fp); |
696 |
- if (pkg_atom) |
697 |
- atom_implode(pkg_atom); |
698 |
- |
699 |
- for (i = 0; i < todo_cnt; i++) |
700 |
- atom_implode(todo_atoms[i]); |
701 |
- free(todo_atoms); |
702 |
- |
703 |
- return EXIT_SUCCESS; |
704 |
+ return pkg; |
705 |
} |
706 |
|
707 |
static set * |
708 |
@@ -2366,10 +1972,40 @@ qmerge_add_set(char *buf, set *q) |
709 |
static int |
710 |
qmerge_run(set *todo) |
711 |
{ |
712 |
- if (uninstall) |
713 |
+ if (uninstall) { |
714 |
return unmerge_packages(todo); |
715 |
- else |
716 |
- return parse_packages(todo); |
717 |
+ } else { |
718 |
+ if (todo == NULL && search_pkgs) { |
719 |
+ /* disputable, this should be qlist -kIv or something */ |
720 |
+ warn("please use qlist -kI"); |
721 |
+ |
722 |
+ return EXIT_SUCCESS; |
723 |
+ } else { |
724 |
+ char **todo_strs; |
725 |
+ size_t todo_cnt = list_set(todo, &todo_strs); |
726 |
+ size_t i; |
727 |
+ depend_atom *atom; |
728 |
+ struct pkg_t *pkg; |
729 |
+ int ret = EXIT_FAILURE; |
730 |
+ |
731 |
+ for (i = 0; i < todo_cnt; i++) { |
732 |
+ atom = atom_explode(todo_strs[i]); |
733 |
+ pkg = grab_binpkg_info(atom); |
734 |
+ if (pkg != NULL) { |
735 |
+ if (search_pkgs) |
736 |
+ print_Pkg(verbose, atom, pkg); |
737 |
+ else |
738 |
+ pkg_fetch(0, atom, pkg); |
739 |
+ free(pkg); |
740 |
+ ret = EXIT_SUCCESS; |
741 |
+ } |
742 |
+ atom_implode(atom); |
743 |
+ } |
744 |
+ free(todo_strs); |
745 |
+ |
746 |
+ return ret; |
747 |
+ } |
748 |
+ } |
749 |
} |
750 |
|
751 |
int qmerge_main(int argc, char **argv) |
752 |
@@ -2437,10 +2073,10 @@ int qmerge_main(int argc, char **argv) |
753 |
|
754 |
if (uninstall) { |
755 |
if (!prompt("OK to unmerge these packages")) |
756 |
- return 0; |
757 |
+ return EXIT_FAILURE; |
758 |
} else { |
759 |
if (!prompt("OK to merge these packages")) |
760 |
- return 0; |
761 |
+ return EXIT_FAILURE; |
762 |
} |
763 |
|
764 |
pretend = save_pretend; |