commit: f2e63b4a1280d0a2c18cb1a66ceffd9699d1b9ac
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Mon May 25 10:39:05 2020 +0000
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Mon May 25 10:39:05 2020 +0000
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=f2e63b4a
qmerge: use libq/tree for binpkg/Packages needs
Instead of manual parsing of Packages file and traversing binpkgs, use
the functionality provided by libq/tree, most notably tree_match_atom().
This is just phase one, where we replace the custom code with libq/tree
code and then fill in the Pkg structure. In a next phase we should skip
this and directly use tree_match_ctx, with atom and meta in there.
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
qmerge.c | 596 +++++++++++++--------------------------------------------------
1 file changed, 116 insertions(+), 480 deletions(-)
diff --git a/qmerge.c b/qmerge.c
index 087c5f2..554e3dc 100644
--- a/qmerge.c
+++ b/qmerge.c
@@ -120,8 +120,7 @@ typedef struct llist_char_t llist_char;
static void pkg_fetch(int, const depend_atom *, const struct pkg_t *);
static void pkg_merge(int, const depend_atom *, const struct pkg_t *);
static int pkg_unmerge(tree_pkg_ctx *, set *, int, char **, int, char **);
-static struct pkg_t *grab_binpkg_info(const char *);
-static char *find_binpkg(const char *);
+static struct pkg_t *grab_binpkg_info(depend_atom *);
static bool
prompt(const char *p)
@@ -129,12 +128,12 @@ prompt(const char *p)
printf("%s? [Y/n] ", p);
fflush(stdout);
switch (getc(stdin)) {
- case '\n':
- case 'y':
- case 'Y':
- return true;
- default:
- return false;
+ case '\n':
+ case 'y':
+ case 'Y':
+ return true;
+ default:
+ return false;
}
}
@@ -579,7 +578,7 @@ qprint_tree_node(int level, const depend_atom *atom, const
struct pkg_t *pkg)
} else {
depend_atom *subatom = atom_explode(p);
if (subatom != NULL) {
- ret = atom_compare(atom, subatom);
+ ret = atom_compare(subatom, atom);
switch (ret) {
case EQUAL: c = 'R'; break;
case NEWER: c = 'U'; break;
@@ -1009,7 +1008,7 @@ pkg_merge(int level, const depend_atom *atom, const
struct pkg_t *pkg)
if (((c == 'R') || (c == 'D')) && update_only)
return;
- if (pkg->RDEPEND[0] && follow_rdepends) {
+ if (pkg->RDEPEND[0] != '\0' && follow_rdepends) {
const char *rdepend;
IF_DEBUG(fprintf(stderr, "\n+Parent: %s/%s\n", pkg->CATEGORY,
pkg->PF));
@@ -1040,30 +1039,17 @@ pkg_merge(int level, const depend_atom *atom, const
struct pkg_t *pkg)
case '\0':
break;
default:
- if (*name == '~') {
- name = ARGV[i] + 1;
- /* warn("newname = %s", name);
*/
- }
if ((subatom = atom_explode(name)) !=
NULL) {
struct pkg_t *subpkg;
- char *resolved = NULL;
-
- resolved = find_binpkg(name);
- IF_DEBUG(fprintf(stderr,
- "+Atom:
argv0(%s) resolved(%s)\n",
- name,
resolved));
-
- if (strlen(resolved) < 1) {
- warn("Cant find a
binpkg for %s from rdepend(%s)",
+ subpkg =
grab_binpkg_info(subatom); /* free me later */
+ if (subpkg == NULL) {
+ warn("Cannot find a
binpkg for %s from rdepend(%s)",
name,
pkg->RDEPEND);
atom_implode(subatom);
continue;
}
- /* ratom =
atom_explode(resolved); */
- subpkg =
grab_binpkg_info(resolved); /* free me later */
-
assert(subpkg != NULL);
IF_DEBUG(fprintf(stderr,
"+Subpkg: %s/%s\n",
subpkg->CATEGORY, subpkg->PF));
@@ -1182,7 +1168,8 @@ pkg_merge(int level, const depend_atom *atom, const
struct pkg_t *pkg)
} else if (mlen == 257+6 &&
magic[257] == 'u' && magic[258] == 's'
&&
magic[259] == 't' && magic[260] == 'a'
&&
- magic[261] == 'r' && magic[262] == '\0')
+ magic[261] == 'r' &&
+ (magic[262] == '\0' || magic[262] == '
'))
{
compr = "";
} else if (mlen >= 4 &&
@@ -1399,7 +1386,7 @@ pkg_merge(int level, const depend_atom *atom, const
struct pkg_t *pkg)
rmdir("../qmerge");
printf("%s>>>%s %s%s%s/%s%s%s\n",
- YELLOW, NORM, WHITE, atom->CATEGORY, NORM, CYAN,
pkg->PF, NORM);
+ YELLOW, NORM, WHITE, pkg->CATEGORY, NORM, CYAN,
pkg->PF, NORM);
tree_close_cat(cat_ctx);
tree_close(vdb);
@@ -1622,7 +1609,7 @@ pkg_verify_checksums(
}
if (pkg->MD5[0]) {
- if (md5 != NULL && strcmp(md5, pkg->MD5) == 0) {
+ if (strcmp(md5, pkg->MD5) == 0) {
if (display)
printf("MD5: [%sOK%s] %s %s/%s\n",
GREEN, NORM, md5,
atom->CATEGORY, pkg->PF);
@@ -1634,7 +1621,7 @@ pkg_verify_checksums(
}
}
- if (sha1 != NULL && pkg->SHA1[0]) {
+ if (pkg->SHA1[0]) {
if (strcmp(sha1, pkg->SHA1) == 0) {
if (display)
qprintf("SHA1: [%sOK%s] %s %s/%s\n",
@@ -1663,7 +1650,8 @@ pkg_fetch(int level, const depend_atom *atom, const
struct pkg_t *pkg)
/* qmerge -pv patch */
if (pretend) {
- if (!install) install++;
+ if (!install)
+ install++;
/* qprint_tree_node(level, atom, pkg); */
pkg_merge(level, atom, pkg);
return;
@@ -1679,13 +1667,12 @@ pkg_fetch(int level, const depend_atom *atom, const
struct pkg_t *pkg)
return;
}
- /* XXX: should do a size check here for partial downloads */
-
if (force_download && (access(buf, R_OK) == 0) &&
(pkg->SHA1[0] || pkg->MD5[0]))
{
if (pkg_verify_checksums(buf, pkg, atom, 0, 0) != 0)
- unlink(buf);
+ if (getenv("QMERGE") == NULL)
+ unlink(buf);
}
if (access(buf, R_OK) == 0) {
if (!pkg->SHA1[0] && !pkg->MD5[0]) {
@@ -1742,7 +1729,7 @@ print_Pkg(int full, const depend_atom *atom, const struct
pkg_t *pkg)
char *p = NULL;
char buf[512];
- printf("%s%s/%s%s:%s%s%s%s%s\n", BOLD, atom->CATEGORY, BLUE, pkg->PF,
pkg->SLOT, NORM,
+ printf("%s%s%s%s\n", atom_format("%[CAT]%[PF]%[SLOT]", atom),
!quiet ? " [" : "",
!quiet ? make_human_readable_str(pkg->SIZE, 1, KILOBYTE) : "",
!quiet ? " KiB]" : "");
@@ -1757,7 +1744,8 @@ print_Pkg(int full, const depend_atom *atom, const struct
pkg_t *pkg)
if (pkg->MD5[0])
printf(" %sMd5%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->MD5);
if (!pkg->MD5[0] && !pkg->SHA1[0])
- printf(" %sSums%s:%s %s(MISSING!)%s\n", DKGREEN, YELLOW, NORM,
RED, NORM);
+ printf(" %sSums%s:%s %s(MISSING!)%s\n",
+ DKGREEN, YELLOW, NORM, RED, NORM);
if (pkg->SLOT[0])
printf(" %sSlot%s:%s %s\n", DKGREEN, YELLOW, NORM, pkg->SLOT);
if (pkg->LICENSE[0])
@@ -1781,7 +1769,8 @@ print_Pkg(int full, const depend_atom *atom, const struct
pkg_t *pkg)
case OLDER: icolor = BLUE; break;
default: icolor = NORM; break;
}
- printf(" %sInstalled%s:%s %s%s%s\n", DKGREEN, YELLOW,
NORM, icolor, p, NORM);
+ printf(" %sInstalled%s:%s %s%s%s\n",
+ DKGREEN, YELLOW, NORM, icolor, p, NORM);
}
}
}
@@ -1833,453 +1822,70 @@ unmerge_packages(set *todo)
return ret;
}
-static FILE *
-open_binpkg_index(void)
-{
- FILE *fp;
- char *path;
-
- xasprintf(&path, "%s/portage/%s", port_tmpdir, Packages);
- fp = fopen(path, "r");
- if (fp)
- goto done;
- free(path);
-
- xasprintf(&path, "%s/%s", pkgdir, Packages);
- fp = fopen(path, "r");
- if (fp)
- goto done;
-
- /* This is normal when installing from local repo only. */
- warnp("Unable to open package file %s in %s/portage or %s",
- Packages, port_tmpdir, pkgdir);
- warn("Attempting to manually regen via `emaint binhost`");
-
- pid_t p;
- int status;
-
- char argv_emaint[] = "emaint";
- char argv_binhost[] = "binhost";
- char argv_fix[] = "--fix";
- char *argv[] = {
- argv_emaint,
- argv_binhost,
- argv_fix,
- NULL,
- };
-
- p = vfork();
- switch (p) {
- case 0:
- _exit(execvp(argv[0], argv));
- case -1:
- errp("vfork failed");
- }
- waitpid(p, &status, 0);
-
- fp = fopen(path, "r");
-
- done:
- free(path);
- return fp;
-}
-
+static tree_ctx *_grab_binpkg_info_tree = NULL;
static struct pkg_t *
-grab_binpkg_info(const char *name)
-{
- FILE *fp;
- char buf[BUFSIZ];
- char *p;
- depend_atom *atom;
-
- struct pkg_t Pkg;
- struct pkg_t *pkg = xzalloc(sizeof(struct pkg_t));
- struct pkg_t *rpkg = xzalloc(sizeof(struct pkg_t));
-
- static char best_match[sizeof(Pkg.PF)+2+sizeof(Pkg.CATEGORY)];
-
- best_match[0] = 0;
- strcpy(pkg->SLOT,"0");
-
- fp = open_binpkg_index();
-
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- if (*buf == '\n') {
- if (pkg->PF[0] && pkg->CATEGORY[0]) {
- int ret;
-
- snprintf(buf, sizeof(buf), "%s/%s",
pkg->CATEGORY, pkg->PF);
- if (strstr(buf, name) != NULL) {
- if (!best_match[0])
- snprintf(best_match,
sizeof(best_match), "%.*s",
-
(int)sizeof(best_match) - 1, buf);
-
- atom = atom_explode(buf);
- if (atom->PR_int) {
- snprintf(buf, sizeof(buf),
"%s/%s-%s-r%i",
- atom->CATEGORY,
atom->PN,
- atom->PV,
atom->PR_int);
- } else {
- snprintf(buf, sizeof(buf),
"%s/%s-%s",
- atom->CATEGORY,
atom->PN, atom->PV);
- }
- ret = atom_compare_str(name, buf);
- IF_DEBUG(fprintf(stderr,
- "===
atom_compare(%s, %s) = %d %s\n",
- name, buf, ret,
booga[ret]));
- /* buf(%s) depend(%s)\n", ret,
pkg->CATEGORY,
- * pkg->PF, name, pkg->RDEPEND); */
- switch (ret) {
- case EQUAL:
- case NEWER:
- snprintf(buf,
sizeof(buf), "%s/%s",
-
pkg->CATEGORY, pkg->PF);
- ret =
atom_compare_str(buf, best_match);
- if (ret == NEWER || ret
== EQUAL) {
-
snprintf(best_match, sizeof(best_match), "%.*s",
-
(int)sizeof(best_match) - 1, buf);
- memcpy(rpkg,
pkg, sizeof(struct pkg_t));
-
IF_DEBUG(fprintf(stderr,
-
"--- %s/%s depend(%s)\n",
-
rpkg->CATEGORY, rpkg->PF,
-
rpkg->RDEPEND));
- }
- case OLDER: break;
- default:
- break;
- }
- atom_implode(atom);
- }
- memset(pkg, 0, sizeof(struct pkg_t));
- strcpy(pkg->SLOT,"0");
- }
- continue;
- }
-
- if ((p = strchr(buf, '\n')) != NULL)
- *p = 0;
- if ((p = strchr(buf, ':')) == NULL)
- continue;
- if (p[1] != ' ')
- continue;
- *p = 0;
- p += 2;
-
- if (*buf) {
- /* we dont need all the info */
- if (strcmp(buf, "RDEPEND") == 0)
- snprintf(pkg->RDEPEND, sizeof(Pkg.RDEPEND),
"%.*s",
- (int)sizeof(Pkg.RDEPEND) - 1,
p);
- if (strcmp(buf, "PF") == 0)
- snprintf(pkg->PF, sizeof(Pkg.PF), "%.*s",
- (int)sizeof(Pkg.PF) - 1, p);
- if (strcmp(buf, "CATEGORY") == 0)
- snprintf(pkg->CATEGORY, sizeof(Pkg.CATEGORY),
"%.*s",
- (int)sizeof(Pkg.CATEGORY) - 1,
p);
- if (strcmp(buf, "REPO") == 0)
- snprintf(pkg->REPO, sizeof(Pkg.REPO), "%.*s",
- (int)sizeof(Pkg.REPO) - 1, p);
-
- if (strcmp(buf, "CPV") == 0) {
- if ((atom = atom_explode(p)) != NULL) {
- if (atom->PR_int) {
- snprintf(buf, sizeof(buf),
"%s-%s-r%i",
- atom->PN,
atom->PV, atom->PR_int);
- } else {
- snprintf(buf, sizeof(buf),
"%s-%s", atom->PN, atom->PV);
- }
- snprintf(pkg->PF, sizeof(Pkg.PF),
"%.*s",
- (int)sizeof(Pkg.PF) -
1, buf);
- snprintf(pkg->CATEGORY,
sizeof(Pkg.CATEGORY), "%.*s",
-
(int)sizeof(Pkg.CATEGORY) - 1, atom->CATEGORY);
- atom_implode(atom);
- }
- }
- if (strcmp(buf, "SLOT") == 0)
- snprintf(pkg->SLOT, sizeof(Pkg.SLOT), "%.*s",
- (int)sizeof(Pkg.SLOT) - 1, p);
- if (strcmp(buf, "USE") == 0)
- snprintf(pkg->USE, sizeof(Pkg.USE), "%.*s",
- (int)sizeof(Pkg.USE) - 1, p);
- /* checksums. We must have 1 or the other unless --*/
- if (strcmp(buf, "MD5") == 0)
- snprintf(pkg->MD5, sizeof(Pkg.MD5), "%.*s",
- (int)sizeof(Pkg.MD5) - 1, p);
- if (strcmp(buf, "SHA1") == 0)
- snprintf(pkg->SHA1, sizeof(Pkg.SHA1), "%.*s",
- (int)sizeof(Pkg.SHA1) - 1, p);
- }
- }
- fclose(fp);
- free(pkg);
- return rpkg;
-}
-
-static char *
-find_binpkg(const char *name)
+grab_binpkg_info(depend_atom *atom)
{
- FILE *fp;
- char buf[BUFSIZ];
- char *p;
- struct pkg_t Pkg;
- char PF[sizeof(Pkg.PF)];
- char CATEGORY[sizeof(Pkg.CATEGORY)];
-
- static char best_match[sizeof(Pkg.PF)+2+sizeof(Pkg.CATEGORY)];
-
- best_match[0] = 0;
- if (NULL == name)
- return best_match;
-
- fp = open_binpkg_index();
- PF[0] = CATEGORY[0] = '\0';
-
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- if (*buf == '\n') {
- if (PF[0] && CATEGORY[0]) {
- int ret;
- snprintf(buf, sizeof(buf), "%s/%s", CATEGORY,
PF);
- if (strstr(buf, name) != NULL) {
- depend_atom *atom;
-
- if (!best_match[0])
- snprintf(best_match,
sizeof(best_match), "%.*s",
-
(int)sizeof(best_match) - 1, buf);
-
- atom = atom_explode(buf);
- snprintf(buf, sizeof(buf), "%s/%s",
- atom->CATEGORY,
atom->PN);
- ret = atom_compare_str(name, buf);
- switch (ret) {
- case OLDER: break;
- case NEWER:
- case EQUAL:
- snprintf(buf,
sizeof(buf), "%s/%s", CATEGORY, PF);
- ret =
atom_compare_str(buf, best_match);
- if (ret == NEWER || ret
== EQUAL)
-
snprintf(best_match, sizeof(best_match), "%.*s",
-
(int)sizeof(best_match) - 1, buf);
- /* printf("[%s == %s] =
%d; %s/%s\n",
- * name, buf, ret,
CATEGORY, PF); */
- default:
- break;
- }
- atom_implode(atom);
- }
- }
- continue;
- }
-
- if ((p = strchr(buf, '\n')) != NULL)
- *p = 0;
- if ((p = strchr(buf, ':')) == NULL)
- continue;
- if (p[1] != ' ')
- continue;
- *p = 0;
- p += 2;
-
- if (*buf) {
- if (strcmp(buf, "CPV") == 0) {
- depend_atom *atom;
- if ((atom = atom_explode(p)) != NULL) {
- if (atom->PR_int) {
- snprintf(buf, sizeof(buf),
"%s-%s-r%i",
- atom->PN,
atom->PV, atom->PR_int);
- } else {
- snprintf(buf, sizeof(buf),
"%s-%s", atom->PN, atom->PV);
- }
- snprintf(PF, sizeof(PF), "%.*s",
(int)sizeof(PF) - 1, buf);
- snprintf(CATEGORY, sizeof(CATEGORY),
"%.*s",
- (int)sizeof(CATEGORY) -
1, atom->CATEGORY);
- atom_implode(atom);
- }
- }
- if (strcmp(buf, "PF") == 0)
- snprintf(PF, sizeof(PF), "%.*s",
(int)sizeof(PF) - 1, p);
- if (strcmp(buf, "CATEGORY") == 0)
- snprintf(CATEGORY, sizeof(CATEGORY), "%.*s",
- (int)sizeof(CATEGORY) - 1, p);
- }
- }
- fclose(fp);
- return best_match;
-}
-
-static int
-parse_packages(set *todo)
-{
- FILE *fp;
- int linelen;
- size_t buflen;
- char *buf, *p;
- struct pkg_t Pkg;
- depend_atom *pkg_atom;
- char repo[sizeof(Pkg.REPO)];
- depend_atom **todo_atoms = NULL;
- size_t todo_cnt = 0;
- size_t i;
-
- fp = open_binpkg_index();
- if (fp == NULL)
- return EXIT_FAILURE;
-
- buf = NULL;
- buflen = 0; /* make getline allocate */
- repo[0] = '\0';
-
- /* First consume the header with the common data. */
- while ((linelen = getline(&buf, &buflen, fp)) >= 0) {
- rmspace_len(buf, (size_t)linelen);
- if (buf[0] == '\0')
- break;
-
- if ((p = strchr(buf, ':')) == NULL)
- continue;
- if (p[1] != ' ')
- continue;
- *p = 0;
- p += 2;
-
- switch (*buf) {
- case 'R':
- if (!strcmp(buf, "REPO"))
- snprintf(repo, sizeof(repo), "%.*s",
(int)sizeof(repo) - 1, p);
- break;
+ tree_ctx *tree = _grab_binpkg_info_tree;
+ tree_match_ctx *tpkg;
+ struct pkg_t *pkg = NULL;
+ char path[BUFSIZ];
+ FILE *d;
+
+ /* reuse previously opened tree, so we really employ the cache
+ * from libq/tree */
+ if (tree == NULL) {
+ snprintf(path, sizeof(path), "%s/portage/Packages",
port_tmpdir);
+ /* we don't use ROOT on package tree here, operating on ROOT
+ * should be for package merges/unmerges, but be able to pull
+ * binpkgs from current system */
+ if ((d = fopen(path, "r")) != NULL) {
+ fclose(d);
+ snprintf(path, sizeof(path), "%s/portage", port_tmpdir);
+ tree = tree_open_binpkg("/", path);
+ } else {
+ tree = tree_open_binpkg("/", pkgdir);
}
- }
+ _grab_binpkg_info_tree = tree;
- pkg_atom = NULL;
- memset(&Pkg, 0, sizeof(Pkg));
- strcpy(Pkg.SLOT, "0");
-
- /* build list with exploded atoms for each access below */
- if (todo != NULL) {
- char **todo_strs;
- todo_cnt = list_set(todo, &todo_strs);
- todo_atoms = xmalloc(sizeof(*todo_atoms) * todo_cnt);
- for (i = 0; i < todo_cnt; i++)
- todo_atoms[i] = atom_explode(todo_strs[i]);
- free(todo_strs);
+ /* if opening the tree failed somehow, we can't return anything
*/
+ if (tree == NULL)
+ return NULL;
}
- /* Then walk all the package entries. */
- while (getline(&buf, &buflen, fp) != -1) {
- if (*buf == '\n') {
- if (pkg_atom) {
- if (search_pkgs && !todo) {
- print_Pkg(verbose, pkg_atom, &Pkg);
- } else {
- for (i = 0; i < todo_cnt; i++) {
- pkg_atom->REPO =
todo_atoms[i]->REPO ? Pkg.REPO : NULL;
- pkg_atom->SLOT =
todo_atoms[i]->SLOT ? Pkg.SLOT : NULL;
- if (atom_compare(pkg_atom,
todo_atoms[i]) == EQUAL) {
- if (search_pkgs)
-
print_Pkg(verbose, pkg_atom, &Pkg);
- else
- pkg_fetch(0,
pkg_atom, &Pkg);
- }
- }
- }
- atom_implode(pkg_atom);
- pkg_atom = NULL;
- }
- memset(&Pkg, 0, sizeof(Pkg));
- strcpy(Pkg.SLOT, "0");
- strcpy(Pkg.REPO, repo);
- continue;
- }
-
- if ((p = strchr(buf, '\n')) != NULL)
- *p = 0;
- if ((p = strchr(buf, ':')) == NULL)
- continue;
- if (p[1] != ' ')
- continue;
- *p = 0;
- p += 2;
-
- switch (*buf) {
- case 'U':
- if (strcmp(buf, "USE") == 0)
- snprintf(Pkg.USE, sizeof(Pkg.USE),
"%.*s",
- (int)sizeof(Pkg.USE) -
1, p);
- break;
- case 'P':
- if (strcmp(buf, "PF") == 0)
- snprintf(Pkg.PF, sizeof(Pkg.PF), "%.*s",
- (int)sizeof(Pkg.PF) -
1, p);
- break;
- case 'S':
- if (strcmp(buf, "SIZE") == 0)
- Pkg.SIZE = atol(p);
- if (strcmp(buf, "SLOT") == 0)
- snprintf(Pkg.SLOT, sizeof(Pkg.SLOT),
"%.*s",
- (int)sizeof(Pkg.SLOT) -
1, p);
- if (strcmp(buf, "SHA1") == 0)
- snprintf(Pkg.SHA1, sizeof(Pkg.SHA1),
"%.*s",
- (int)sizeof(Pkg.SHA1) -
1, p);
- break;
- case 'M':
- if (strcmp(buf, "MD5") == 0)
- snprintf(Pkg.MD5, sizeof(Pkg.MD5),
"%.*s",
- (int)sizeof(Pkg.MD5) -
1, p);
- break;
- case 'R':
- if (strcmp(buf, "REPO") == 0)
- snprintf(Pkg.REPO, sizeof(Pkg.REPO),
"%.*s",
- (int)sizeof(Pkg.REPO) -
1, p);
- if (strcmp(buf, "RDEPEND") == 0)
- snprintf(Pkg.RDEPEND,
sizeof(Pkg.RDEPEND), "%.*s",
-
(int)sizeof(Pkg.RDEPEND) - 1, p);
- break;
- case 'L':
- if (strcmp(buf, "LICENSE") == 0)
- snprintf(Pkg.LICENSE,
sizeof(Pkg.LICENSE), "%.*s",
-
(int)sizeof(Pkg.LICENSE) - 1, p);
- break;
- case 'C':
- if (strcmp(buf, "CATEGORY") == 0)
- snprintf(Pkg.CATEGORY,
sizeof(Pkg.CATEGORY), "%.*s",
-
(int)sizeof(Pkg.CATEGORY) - 1, p);
- if (strcmp(buf, "CPV") == 0) {
- if (pkg_atom != NULL) /* hypothetical
Coverity case */
- atom_implode(pkg_atom);
- if ((pkg_atom = atom_explode(p)) !=
NULL) {
- if (pkg_atom->PR_int)
- snprintf(Pkg.PF,
sizeof(Pkg.PF), "%s-%s-r%i",
-
pkg_atom->PN, pkg_atom->PV,
-
pkg_atom->PR_int);
- else
- snprintf(Pkg.PF,
sizeof(Pkg.PF), "%s-%s",
-
pkg_atom->PN, pkg_atom->PV);
- snprintf(Pkg.CATEGORY,
sizeof(Pkg.CATEGORY),
- "%.*s",
(int)sizeof(Pkg.CATEGORY) - 1,
-
pkg_atom->CATEGORY);
- }
- }
- break;
- case 'D':
- if (strcmp(buf, "DESC") == 0)
- snprintf(Pkg.DESC, sizeof(Pkg.DESC),
"%.*s",
- (int)sizeof(Pkg.DESC) -
1, p);
- break;
- default:
- break;
- }
+ tpkg = tree_match_atom(tree, atom,
+ TREE_MATCH_FIRST | TREE_MATCH_VIRTUAL |
TREE_MATCH_METADATA);
+ if (tpkg != NULL) {
+ depend_atom *tatom = tpkg->atom;
+ tree_pkg_meta *meta = tpkg->meta;
+ pkg = xzalloc(sizeof(struct pkg_t));
+
+ snprintf(pkg->PF, sizeof(pkg->PF), "%s", tatom->PF);
+ snprintf(pkg->CATEGORY, sizeof(pkg->CATEGORY), "%s",
tatom->CATEGORY);
+ if (meta->Q_DESCRIPTION != NULL)
+ snprintf(pkg->DESC, sizeof(pkg->DESC), "%s",
meta->Q_DESCRIPTION);
+ if (meta->Q_LICENSE != NULL)
+ snprintf(pkg->LICENSE, sizeof(pkg->LICENSE), "%s",
meta->Q_LICENSE);
+ if (meta->Q_RDEPEND != NULL)
+ snprintf(pkg->RDEPEND, sizeof(pkg->RDEPEND), "%s",
meta->Q_RDEPEND);
+ if (meta->Q_MD5 != NULL)
+ snprintf(pkg->MD5, sizeof(pkg->MD5), "%s", meta->Q_MD5);
+ if (meta->Q_SHA1 != NULL)
+ snprintf(pkg->SHA1, sizeof(pkg->SHA1), "%s",
meta->Q_SHA1);
+ if (meta->Q_USE != NULL)
+ snprintf(pkg->USE, sizeof(pkg->USE), "%s", meta->Q_USE);
+ if (meta->Q_repository != NULL)
+ snprintf(pkg->REPO, sizeof(pkg->REPO), "%s",
meta->Q_repository);
+ if (meta->Q_SLOT != NULL)
+ snprintf(pkg->REPO, sizeof(pkg->REPO), "%s",
meta->Q_SLOT);
+ if (meta->Q_SIZE != NULL)
+ pkg->SIZE = atoi(meta->Q_SIZE);
+
+ tree_match_close(tpkg);
}
- free(buf);
- fclose(fp);
- if (pkg_atom)
- atom_implode(pkg_atom);
-
- for (i = 0; i < todo_cnt; i++)
- atom_implode(todo_atoms[i]);
- free(todo_atoms);
-
- return EXIT_SUCCESS;
+ return pkg;
}
static set *
@@ -2366,10 +1972,40 @@ qmerge_add_set(char *buf, set *q)
static int
qmerge_run(set *todo)
{
- if (uninstall)
+ if (uninstall) {
return unmerge_packages(todo);
- else
- return parse_packages(todo);
+ } else {
+ if (todo == NULL && search_pkgs) {
+ /* disputable, this should be qlist -kIv or something */
+ warn("please use qlist -kI");
+
+ return EXIT_SUCCESS;
+ } else {
+ char **todo_strs;
+ size_t todo_cnt = list_set(todo, &todo_strs);
+ size_t i;
+ depend_atom *atom;
+ struct pkg_t *pkg;
+ int ret = EXIT_FAILURE;
+
+ for (i = 0; i < todo_cnt; i++) {
+ atom = atom_explode(todo_strs[i]);
+ pkg = grab_binpkg_info(atom);
+ if (pkg != NULL) {
+ if (search_pkgs)
+ print_Pkg(verbose, atom, pkg);
+ else
+ pkg_fetch(0, atom, pkg);
+ free(pkg);
+ ret = EXIT_SUCCESS;
+ }
+ atom_implode(atom);
+ }
+ free(todo_strs);
+
+ return ret;
+ }
+ }
}
int qmerge_main(int argc, char **argv)
@@ -2437,10 +2073,10 @@ int qmerge_main(int argc, char **argv)
if (uninstall) {
if (!prompt("OK to unmerge these packages"))
- return 0;
+ return EXIT_FAILURE;
} else {
if (!prompt("OK to merge these packages"))
- return 0;
+ return EXIT_FAILURE;
}
pretend = save_pretend;