diff -Narup portage-utils-20070115/libq/atom_compare.c portage-utils-20070115.new/libq/atom_compare.c --- portage-utils-20070115/libq/atom_compare.c 2007-01-15 19:20:13.000000000 +0100 +++ portage-utils-20070115.new/libq/atom_compare.c 2007-01-15 19:21:58.239945916 +0100 @@ -43,11 +43,27 @@ int atom_compare(const depend_atom * con /* check version */ if (a1->PV && a2->PV) { + int i; char *s1, *s2; unsigned int n1, n2; /* first we compare the version [1.0]z_alpha1 */ s1 = a1->PV; s2 = a2->PV; + /* treat the case of svn/live/scm/cvs.. version */ + n1=n2=0; + for (i=0; iPV || a2->PV) return NOT_EQUAL; - +same_version: if (a1->PR_int == a2->PR_int) return EQUAL; else if (a1->PR_int < a2->PR_int) diff -Narup portage-utils-20070115/libq/atom_explode.c portage-utils-20070115.new/libq/atom_explode.c --- portage-utils-20070115/libq/atom_explode.c 2007-01-15 19:20:13.000000000 +0100 +++ portage-utils-20070115.new/libq/atom_explode.c 2007-01-15 19:21:58.248944543 +0100 @@ -13,8 +13,21 @@ typedef enum { VER_ALPHA=0, VER_BETA, VER_PRE, VER_RC, VER_NORM, VER_P } atom_suffixes; const char * const atom_suffixes_str[] = { "_alpha", "_beta", "_pre", "_rc", "_/*bogus*/", "_p", NULL }; +const struct { + const char *version; + const size_t version_len; +} atom_version_str[] = { + {"-scm", 4}, + {"-cvs", 4}, + {"-svn", 4}, + {"-live", 5}, + {"-9999", 5} +}; + + typedef struct { + char *OVERLAY; char *CATEGORY; char *PN; int PR_int; @@ -61,6 +74,16 @@ depend_atom *atom_explode(const char *at ret->suffix = VER_NORM; memcpy(ret->CATEGORY, atom, slen); + /* find the OVERLAY, if present */ + if ((ptr_tmp=strstr(ret->CATEGORY, "::"))) { + if (*(ptr_tmp+2)) + ret->OVERLAY = ptr_tmp + 2; + else + ret->OVERLAY = NULL; + *ptr_tmp = 0; + ptr_tmp = NULL; + } + /* break up the CATEOGRY and PVR */ if ((ptr = strrchr(ret->CATEGORY, '/')) != NULL) { ret->PN = ptr+1; @@ -144,6 +167,16 @@ eat_version: ret->PV = ptr_tmp+1; ret->PV[-1] = '\0'; goto found_pv; + } + + for (i=0; iPN, atom_version_str[i].version)) && ptr_tmp == ret->PN+strlen(ret->PN)-atom_version_str[i].version_len) + break; + + if (ptr_tmp && *ptr_tmp) { + ret->PV = ptr_tmp+1; + ret->PV[-1] = '\0'; + goto found_pv; } else { /* atom has no version */ ret->PV = ret->PVR = NULL; diff -Narup portage-utils-20070115/main.c portage-utils-20070115.new/main.c --- portage-utils-20070115/main.c 2007-01-15 19:20:12.000000000 +0100 +++ portage-utils-20070115.new/main.c 2007-01-15 19:21:58.257943170 +0100 @@ -71,6 +71,7 @@ int rematch(const char *, const char *, static char *rmspace(char *); void initialize_portage_env(void); +void initialize_overlays (char portdir_overlay[]); void initialize_ebuild_flat(void); void reinitialize_ebuild_flat(void); void reinitialize_as_needed(void); @@ -85,13 +86,24 @@ static int quiet = 0; static char pretend = 0; static char reinitialize = 0; static char reinitialize_metacache = 0; -static char portdir[_Q_PATH_MAX] = "/usr/portage"; static char portarch[20] = ""; -static char portvdb[] = "var/db/pkg"; +static char portvdb[_Q_PATH_MAX] = "var/db/pkg"; static char portcachedir[] = "metadata/cache"; static char portroot[_Q_PATH_MAX] = "/"; static char config_protect[_Q_PATH_MAX] = "/etc/"; +typedef struct overlay_t overlay_t; +struct overlay_t { + char name[64]; + char path[_Q_PATH_MAX]; + char cache[_Q_PATH_MAX]; + struct overlay_t *next; +}; + +static overlay_t *first_overlay = NULL; +/* temporary workaround ? */ +static overlay_t *overlay_gentoo = NULL; + char pkgdir[512] = "/usr/portage/packages/"; char port_tmpdir[512] = "/var/tmp/portage/"; @@ -201,10 +213,10 @@ static void usage(int status, const char for (i = 0; opts[i].name; ++i) { assert(help[i] != NULL); /* this assert is a life saver when adding new applets. */ if (opts[i].has_arg == no_argument) - printf(" -%c, --%-15s%s*%s %s\n", opts[i].val, + printf(" -%c, --%-16s%s*%s %s\n", opts[i].val, opts[i].name, RED, NORM, _(help[i])); else - printf(" -%c, --%-8s %s%s %s*%s %s\n", opts[i].val, + printf(" -%c, --%-9s %s%s %s*%s %s\n", opts[i].val, opts[i].name, DKBLUE, NORM, RED, NORM, _(help[i])); } exit(status); @@ -467,17 +479,85 @@ char *strincr_var(const char *name, char return (char *) value; } +void initialize_overlays (char portdir_overlay[]) +{ + short merror = 0; + char buf[BUFSIZE], file[_Q_PATH_MAX], *s, *p, *t; + overlay_t *cur_overlay; + FILE *repo_nameFP; + s = portdir_overlay; + + first_overlay = xmalloc(sizeof(*first_overlay)); + cur_overlay = first_overlay; + + while (*s) { + /* except on the first loop */ + if (s!=portdir_overlay) { + cur_overlay->next = xmalloc (sizeof (*cur_overlay->next)); + cur_overlay = cur_overlay->next; + } + cur_overlay->next = NULL; + + if ((p=strchr(s,' '))) + *p = 0; + + snprintf(cur_overlay->path, sizeof(cur_overlay->path), "%s%s", (strcmp(portroot, "/") ? portroot : ""), s); + + /* find the name for the overlay */ + snprintf(file, sizeof(file), "%s/profiles/repo_name", cur_overlay->path); + + if ((repo_nameFP = fopen(file, "r"))) { + if (!(fgets(buf, sizeof(buf),repo_nameFP))) + merror++; + rmspace(buf); + if ((t = strchr(buf,'\n'))) + *t = 0; + strncpy(cur_overlay->name, buf, sizeof(cur_overlay->name)); + + fclose(repo_nameFP); + } else + merror++; + + if (merror) { + /* delete trailing '/' */ + t = cur_overlay->path + strlen(cur_overlay->path) - 1; + if (*t == '/') + *t = 0; + strncpy(file, cur_overlay->path, sizeof(file)); + strncpy(cur_overlay->name, basename(file), sizeof(cur_overlay->name)); + merror=0; + } + + if (!strncmp(cur_overlay->name, "gentoo", sizeof(cur_overlay->name))) { + snprintf(cur_overlay->cache, sizeof(cur_overlay->cache), "%s/%s", cur_overlay->path, portcachedir); + overlay_gentoo = cur_overlay; + } else + strcpy(cur_overlay->cache, "/var/empty"); + + if (p) + s = p+1; /* because portdir_overlay has no trailing space */ + else + break; + } + +} + + void initialize_portage_env(void) { char nocolor = 0; int i, f; struct stat st; FILE *fp; + char tmp_portdir[_Q_PATH_MAX]; char buf[BUFSIZE], *s, *p; char profile[_Q_PATH_MAX], portage_file[_Q_PATH_MAX]; + char portdir_overlay[BUFSIZE] = ""; + const char *files[] = {portage_file, "/etc/make.globals", "/etc/make.conf"}; typedef enum { _Q_BOOL, _Q_STR, _Q_ISTR } var_types; + struct { const char *name; const size_t name_len; @@ -491,7 +571,8 @@ void initialize_portage_env(void) {"CONFIG_PROTECT", 14, _Q_STR, config_protect, sizeof(config_protect)}, {"NOCOLOR", 7, _Q_BOOL, &nocolor, 1}, {"FEATURES", 8, _Q_ISTR, features, sizeof(features)}, - {"PORTDIR", 7, _Q_STR, portdir, sizeof(portdir)}, + {"PORTDIR", 7, _Q_STR, tmp_portdir, sizeof(tmp_portdir)}, + {"PORTDIR_OVERLAY", 15, _Q_ISTR, portdir_overlay,sizeof(portdir_overlay)}, {"PORTAGE_BINHOST", 15, _Q_STR, binhost, sizeof(binhost)}, {"PORTAGE_TMPDIR", 14, _Q_STR, port_tmpdir, sizeof(port_tmpdir)}, {"PKGDIR", 6, _Q_STR, pkgdir, sizeof(pkgdir)}, @@ -589,6 +670,14 @@ void initialize_portage_env(void) no_colors(); else color_remap(); + + snprintf(tmp_portdir, sizeof(tmp_portdir), "%s/%s", (strcmp(portroot, "/") ? portroot : ""), portvdb); + strncpy(portvdb, tmp_portdir, sizeof(portvdb)); + strincr_var("PORTDIR_OVERLAY", tmp_portdir, portdir_overlay, sizeof(portdir_overlay)); + + /* now we initiliase the overlay chained list */ + initialize_overlays(portdir_overlay); + } enum { @@ -617,20 +706,25 @@ const char *initialize_flat(int cache_ty int a, b, c, d, e, i; int frac, secs, count; FILE *fp; + overlay_t *cur_overlay; a = b = c = d = e = i = 0; count = frac = secs = 0; + cur_overlay = first_overlay; cache_file = (cache_type == CACHE_EBUILD ? CACHE_EBUILD_FILE : CACHE_METADATA_FILE); - if (chdir(portdir) != 0) { - warnp("chdir to PORTDIR '%s' failed", portdir); - goto ret; - } - - if (cache_type == CACHE_METADATA && chdir(portcachedir) != 0) { - warnp("chdir to portage cache '%s/%s' failed", portdir, portcachedir); - goto ret; + /* SAM review without gentoo! */ + if (cache_type == CACHE_METADATA) { + if (chdir(overlay_gentoo->cache) != 0) { + warnp("chdir to portage cache '%s' failed", overlay_gentoo->cache); + goto ret; + } + } else { + if (chdir(overlay_gentoo->path) != 0) { + warnp("chdir to PORTDIR '%s' failed", overlay_gentoo->path); + goto ret; + } } if ((stat(cache_file, &st)) != (-1)) @@ -645,64 +739,87 @@ const char *initialize_flat(int cache_ty unlink(cache_file); if (errno != ENOENT) { - warnfp("unlinking '%s/%s' failed", portdir, cache_file); + /* SAM review without gentoo! */ + warnfp("unlinking '%s/%s' failed", overlay_gentoo->path, cache_file); goto ret; } + /* SAM review without gentoo! */ if ((fp = fopen(cache_file, "w")) == NULL) { - warnfp("opening '%s/%s' failed", portdir, cache_file); + warnfp("opening '%s/%s' failed", (cache_type == CACHE_EBUILD ? overlay_gentoo->path : overlay_gentoo->cache), cache_file); goto ret; } gettimeofday(&start, NULL); - if ((a = scandir(".", &category, filter_hidden, alphasort)) < 0) - goto ret; - - for (i = 0; i < a; i++) { - stat(category[i]->d_name, &st); - if (!S_ISDIR(st.st_mode)) - continue; - if (strchr(category[i]->d_name, '-') == NULL) - if ((strncmp(category[i]->d_name, "virtual", 7)) != 0) + do { + switch (cache_type) { + case CACHE_EBUILD: + if (chdir(cur_overlay->path) != 0) { + warnp("chdir to '%s' failed, skipping the %s repository", cur_overlay->path, cur_overlay->name); continue; - - if ((b = scandir(category[i]->d_name, &pn, filter_hidden, alphasort)) < 0) + } + break; + case CACHE_METADATA: + if (!strcmp(cur_overlay->cache, "/var/empty")) { + if (verbose) + warnp("No cache defined for the %s repository", cur_overlay->name); + continue; + } else if (chdir(cur_overlay->cache) != 0) { + warnp("chdir to '%s' failed, skipping the %s repository",cur_overlay->cache, cur_overlay->name); + continue; + } + break; + } + if ((a = scandir(".", &category, filter_hidden, alphasort)) < 0) continue; - for (c = 0; c < b; c++) { - char de[_Q_PATH_MAX]; - snprintf(de, sizeof(de), "%s/%s", category[i]->d_name, pn[c]->d_name); + for (i = 0; i < a; i++) { + stat(category[i]->d_name, &st); + if (!S_ISDIR(st.st_mode)) + continue; + if (strchr(category[i]->d_name, '-') == NULL) + if ((strncmp(category[i]->d_name, "virtual", 7)) != 0) + continue; - if (stat(de, &st) < 0) + if ((b = scandir(category[i]->d_name, &pn, filter_hidden, alphasort)) < 0) continue; + for (c = 0; c < b; c++) { + char de[_Q_PATH_MAX]; - switch (cache_type) { - case CACHE_EBUILD: - if (!S_ISDIR(st.st_mode)) + snprintf(de, sizeof(de), "%s/%s", category[i]->d_name, pn[c]->d_name); + + if (stat(de, &st) < 0) continue; - break; - case CACHE_METADATA: - if (S_ISREG(st.st_mode)) - fprintf(fp, "%s\n", de); - continue; - break; - } - if ((e = scandir(de, &eb, filter_hidden, alphasort)) < 0) - continue; - for (d = 0; d < e; d++) { - if ((p = strrchr(eb[d]->d_name, '.')) != NULL) - if (strcmp(p, ".ebuild") == 0) { - count++; - fprintf(fp, "%s/%s/%s\n", category[i]->d_name, pn[c]->d_name, eb[d]->d_name); - } + + switch (cache_type) { + case CACHE_EBUILD: + if (!S_ISDIR(st.st_mode)) + continue; + break; + case CACHE_METADATA: + if (S_ISREG(st.st_mode)) + fprintf(fp, "%s::%s\n", de, cur_overlay->name); + continue; + break; + } + if ((e = scandir(de, &eb, filter_hidden, alphasort)) < 0) + continue; + for (d = 0; d < e; d++) { + if ((p = strrchr(eb[d]->d_name, '.')) != NULL) + if (strcmp(p, ".ebuild") == 0) { + count++; + fprintf(fp, "%s/%s/%s::%s\n", category[i]->d_name, pn[c]->d_name, eb[d]->d_name, cur_overlay->name); + } + } + while (d--) free(eb[d]); + free(eb); } - while (d--) free(eb[d]); - free(eb); + while (b--) free(pn[b]); + free(pn); } - while (b--) free(pn[b]); - free(pn); - } + } while ((cur_overlay = cur_overlay->next)); + fclose(fp); while (a--) free(category[a]); free(category); @@ -721,7 +838,7 @@ const char *initialize_flat(int cache_ty warn("Finished %u entries in %d.%06d seconds", count, secs, frac); if (secs > 100) - warn("You should consider a faster file system such as reiserfs for PORTDIR='%s'", portdir); + warn("You should consider a faster file system such as reiserfs for repositories"); ret: return cache_file; } @@ -730,8 +847,8 @@ ret: void reinitialize_ebuild_flat(void) { - if ((chdir(portdir)) != 0) { - warnp("chdir to PORTDIR '%s' failed", portdir); + if ((chdir(first_overlay->path)) != 0) { + warnp("chdir to PORTDIR '%s' failed", first_overlay->path); return; } unlink(CACHE_EBUILD_FILE); @@ -766,8 +883,8 @@ typedef struct { } portage_cache; void cache_free(portage_cache *cache); -portage_cache *cache_read_file(const char *file); -portage_cache *cache_read_file(const char *file) +portage_cache *cache_read_file(char *file); +portage_cache *cache_read_file(char *file) { struct stat s; char *ptr; @@ -775,8 +892,12 @@ portage_cache *cache_read_file(const cha portage_cache *ret = NULL; size_t len; + if ((ptr = strstr(file, "::"))) + *ptr = 0; if ((f = fopen(file, "r")) == NULL) goto err; + if (ptr) + *ptr = ':'; if (fstat(fileno(f), &s) != 0) goto err; @@ -1004,10 +1125,20 @@ fuckit: return cpf; } +/* free overlays */ +void free_overlays(overlay_t *overlay); +void free_overlays(overlay_t *overlay) +{ + if (overlay->next) + free_overlays(overlay->next); + free(overlay); +} + void cleanup() { reinitialize_as_needed(); free_sets(virtuals); + free_overlays(first_overlay); fclose(stderr); } diff -Narup portage-utils-20070115/man/q.1 portage-utils-20070115.new/man/q.1 --- portage-utils-20070115/man/q.1 2007-01-15 19:20:12.000000000 +0100 +++ portage-utils-20070115.new/man/q.1 2007-01-15 19:21:58.265941950 +0100 @@ -61,11 +61,14 @@ quse qxpak : manipulate xpak archives .PP -Options: \fB\-[irmvqChV]\fR +Options: \fB\-[ilrmvqChV]\fR .TP \fB\-i\fR, \fB\-\-install\fR * Install symlinks for applets .TP +\fB\-l\fR, \fB\-\-ls\-overlays\fR +* List configured overlays +.TP \fB\-r\fR, \fB\-\-reinitialize\fR * Reinitialize ebuild cache .TP diff -Narup portage-utils-20070115/man/qgrep.1 portage-utils-20070115.new/man/qgrep.1 --- portage-utils-20070115/man/qgrep.1 2007-01-15 19:20:12.000000000 +0100 +++ portage-utils-20070115.new/man/qgrep.1 2007-01-15 19:21:58.273940729 +0100 @@ -16,6 +16,11 @@ Options: \fB\-[IiHcevqChV]\fR \fB\-H\fR, \fB\-\-with\-filename\fR * Print the filename for each match .TP +\fB\-o\fR, \fB\-\-overlay\fR + +.BR + * Only consider the overlay +.TP \fB\-c\fR, \fB\-\-count\fR * Only print a count of matching lines per FILE .TP diff -Narup portage-utils-20070115/man/qsearch.1 portage-utils-20070115.new/man/qsearch.1 --- portage-utils-20070115/man/qsearch.1 2007-01-15 19:20:12.000000000 +0100 +++ portage-utils-20070115.new/man/qsearch.1 2007-01-15 19:21:58.282939357 +0100 @@ -5,7 +5,7 @@ qsearch \- search pkgname/desc .B qsearch \fI\fR .SH DESCRIPTION -Options: \fB\-[acsSNHvqChV]\fR +Options: \fB\-[aco\fR:psSNHvqChV] .TP \fB\-a\fR, \fB\-\-all\fR * List the descriptions of every package in the cache @@ -13,6 +13,14 @@ Options: \fB\-[acsSNHvqChV]\fR \fB\-c\fR, \fB\-\-cache\fR * Use the portage cache .TP +\fB\-o\fR, \fB\-\-overlay\fR + +.BR + * Search only in the overlay +.TP +\fB\-p\fR, \fB\-\-show\-path\fR +* Show the path to the ebuild +.TP \fB\-s\fR, \fB\-\-search\fR * Regex search package basenames .TP diff -Narup portage-utils-20070115/man/quse.1 portage-utils-20070115.new/man/quse.1 --- portage-utils-20070115/man/quse.1 2007-01-15 19:20:12.000000000 +0100 +++ portage-utils-20070115.new/man/quse.1 2007-01-15 19:21:58.290938137 +0100 @@ -5,7 +5,7 @@ quse \- find pkgs using useflags .B quse \fI\fR .SH DESCRIPTION -Options: \fB\-[eavKLDF:NvqChV]\fR +Options: \fB\-[eao\fR:vKLDF:NvqChV] .TP \fB\-e\fR, \fB\-\-exact\fR * Show exact non regexp matching using strcmp @@ -13,6 +13,11 @@ Options: \fB\-[eavKLDF:NvqChV]\fR \fB\-a\fR, \fB\-\-all\fR * Show annoying things in IUSE .TP +\fB\-o\fR, \fB\-\-overlay\fR + +.BR + * Only consider the overlay +.TP \fB\-K\fR, \fB\-\-keywords\fR * Use the KEYWORDS vs IUSE .TP diff -Narup portage-utils-20070115/qatom.c portage-utils-20070115.new/qatom.c --- portage-utils-20070115/qatom.c 2007-01-15 19:20:12.000000000 +0100 +++ portage-utils-20070115.new/qatom.c 2007-01-15 19:21:58.299936764 +0100 @@ -60,6 +60,7 @@ int qatom_main(int argc, char **argv) printf(" r%i", atom->PR_int); if (verbose > 1) printf(" %c", (atom->letter ? : '-')); + printf(" %s", atom->OVERLAY); putchar('\n'); atom_implode(atom); } diff -Narup portage-utils-20070115/q.c portage-utils-20070115.new/q.c --- portage-utils-20070115/q.c 2007-01-15 19:20:12.000000000 +0100 +++ portage-utils-20070115.new/q.c 2007-01-15 19:21:58.309935238 +0100 @@ -7,15 +7,17 @@ * Copyright 2005-2006 Mike Frysinger - */ -#define Q_FLAGS "irm" COMMON_FLAGS +#define Q_FLAGS "ilrm" COMMON_FLAGS static struct option const q_long_opts[] = { {"install", no_argument, NULL, 'i'}, + {"ls-overlays", no_argument, NULL, 'l'}, {"reinitialize", no_argument, NULL, 'r'}, {"metacache", no_argument, NULL, 'm'}, COMMON_LONG_OPTS }; static const char *q_opts_help[] = { "Install symlinks for applets", + "List configured overlays", "Reinitialize ebuild cache", "Reinitialize metadata cache", COMMON_OPTS_HELP @@ -70,6 +72,7 @@ int q_main(int argc, char **argv) int i; char *p; APPLET func; + overlay_t * cur_overlay; if (argc == 0) return 1; @@ -89,6 +92,17 @@ int q_main(int argc, char **argv) COMMON_GETOPTS_CASES(q) case 'm': reinitialize_metacache = 1; break; case 'r': reinitialize = 1; break; + case 'l': { + printf("\n%sOverlay(s) :%s\n\n", GREEN, NORM); + cur_overlay=first_overlay; + do { + printf(" Name : %s%-20.20s%s \tlocation : %s%-60.60s%s \tmetadata : %s%-60.60s%s\n", + CYAN, cur_overlay->name, NORM, CYAN, cur_overlay->path, NORM, + CYAN, cur_overlay->cache, NORM); + } while ((cur_overlay=cur_overlay->next)); + fputc('\n', stdout); + return 0; + } case 'i': { char buf[_Q_PATH_MAX]; /* always bzero a buffer before using readlink() */ diff -Narup portage-utils-20070115/qcache.c portage-utils-20070115.new/qcache.c --- portage-utils-20070115/qcache.c 2007-01-15 19:20:12.000000000 +0100 +++ portage-utils-20070115.new/qcache.c 2007-01-15 19:21:58.317934018 +0100 @@ -512,10 +512,10 @@ int qcache_traverse(void (*func)(qcache_ int i, j, k, len, num_cat, num_pkg, num_ebuild; struct direct **categories, **packages, **ebuilds; - len = sizeof(char) * (strlen(QCACHE_EDB) + strlen(portdir) + 1); + len = sizeof(char) * (strlen(QCACHE_EDB) + strlen(overlay_gentoo->path) + 1); catpath = xmalloc(len); memset(catpath, 0, len); - snprintf(catpath, len, "%s%s", QCACHE_EDB, portdir); + snprintf(catpath, len, "%s%s", QCACHE_EDB, overlay_gentoo->path); if (-1 == (num_cat = scandir(catpath, &categories, qcache_file_select, alphasort))) { err("%s %s", catpath, strerror(errno)); @@ -527,10 +527,10 @@ int qcache_traverse(void (*func)(qcache_ /* traverse categories */ for (i = 0; i < num_cat; i++) { - len = sizeof(char) * (strlen(portdir) + strlen("/") + strlen(categories[i]->d_name) + 1); + len = sizeof(char) * (strlen(overlay_gentoo->path) + strlen("/") + strlen(categories[i]->d_name) + 1); pkgpath = xmalloc(len); memset(pkgpath, 0, len); - snprintf(pkgpath, len, "%s/%s", portdir, categories[i]->d_name); + snprintf(pkgpath, len, "%s/%s", overlay_gentoo->path, categories[i]->d_name); if (-1 == (num_pkg = scandir(pkgpath, &packages, qcache_file_select, alphasort))) { warn("%s %s", catpath, strerror(errno)); @@ -552,10 +552,10 @@ int qcache_traverse(void (*func)(qcache_ /* traverse packages */ for (j = 0; j < num_pkg; j++) { - len = sizeof(char) * (strlen(portdir) + strlen("/") + strlen(categories[i]->d_name) + strlen("/") + strlen(packages[j]->d_name) + 1); + len = sizeof(char) * (strlen(overlay_gentoo->path) + strlen("/") + strlen(categories[i]->d_name) + strlen("/") + strlen(packages[j]->d_name) + 1); ebuildpath = xmalloc(len); memset(ebuildpath, 0, len); - snprintf(ebuildpath, len, "%s/%s/%s", portdir, categories[i]->d_name, packages[j]->d_name); + snprintf(ebuildpath, len, "%s/%s/%s", overlay_gentoo->path, categories[i]->d_name, packages[j]->d_name); if (-1 == (num_ebuild = scandir(ebuildpath, &ebuilds, qcache_ebuild_select, qcache_vercmp))) { warn("%s %s", ebuildpath, strerror(errno)); @@ -773,10 +773,10 @@ void qcache_stats(qcache_data *data) for (i = 0; archlist[i]; i++) architectures++; - len = sizeof(char) * (strlen(QCACHE_EDB) + strlen(portdir) + 1); + len = sizeof(char) * (strlen(QCACHE_EDB) + strlen(overlay_gentoo->path) + 1); catpath = xmalloc(len); memset(catpath, 0, len); - snprintf(catpath, len, "%s%s", QCACHE_EDB, portdir); + snprintf(catpath, len, "%s%s", QCACHE_EDB, overlay_gentoo->path); if (-1 == (numcat = scandir(catpath, &categories, qcache_file_select, alphasort))) { err("%s %s", catpath, strerror(errno)); @@ -928,11 +928,11 @@ int qcache_init() char *filename; unsigned int len; - len = sizeof(char) * (strlen(portdir) + strlen("/profiles/arch.list") + 1); + len = sizeof(char) * (strlen(overlay_gentoo->path) + strlen("/profiles/arch.list") + 1); filename = xmalloc(len); memset(filename, 0, len); - snprintf(filename, len, "%s/profiles/arch.list", portdir); + snprintf(filename, len, "%s/profiles/arch.list", overlay_gentoo->path); if (NULL == (archlist = qcache_read_lines(filename))) { free(filename); diff -Narup portage-utils-20070115/qcheck.c portage-utils-20070115.new/qcheck.c --- portage-utils-20070115/qcheck.c 2007-01-15 19:20:12.000000000 +0100 +++ portage-utils-20070115.new/qcheck.c 2007-01-15 19:21:58.326932645 +0100 @@ -49,10 +49,10 @@ int qcheck_main(int argc, char **argv) if ((argc == optind) && !search_all) qcheck_usage(EXIT_FAILURE); - if (chdir(portroot)) - errp("could not chdir(%s) for ROOT", portroot); + if (chdir(portvdb)) + errp("could not chdir(%s) for VDB", portvdb); - if (chdir(portvdb) != 0 || (dir = opendir(".")) == NULL) + if ((dir = opendir(".")) == NULL) return EXIT_FAILURE; /* open /var/db/pkg */ @@ -84,7 +84,7 @@ int qcheck_main(int argc, char **argv) continue; } - snprintf(buf, sizeof(buf), "%s%s/%s/%s/CONTENTS", portroot, portvdb, + snprintf(buf, sizeof(buf), "%s/%s/%s/CONTENTS", portvdb, dentry->d_name, de->d_name); if ((fp = fopen(buf, "r")) == NULL) continue; @@ -199,7 +199,7 @@ free_and_more_hash: fclose(fp); if (qc_update) { fclose(fpx); - snprintf(buf, sizeof(buf), "%s%s/%s/%s/CONTENTS", portroot, portvdb, + snprintf(buf, sizeof(buf), "%s/%s/%s/CONTENTS", portvdb, dentry->d_name, de->d_name); strcpy(buffer, buf); strncat(buffer, "~", sizeof(buffer)); diff -Narup portage-utils-20070115/qdepends.c portage-utils-20070115.new/qdepends.c --- portage-utils-20070115/qdepends.c 2007-01-15 19:20:12.000000000 +0100 +++ portage-utils-20070115.new/qdepends.c 2007-01-15 19:21:58.335931273 +0100 @@ -359,10 +359,10 @@ int qdepends_main_vdb(const char *depend char depend[16384], use[8192]; dep_node *dep_tree; - if (chdir(portroot)) - errp("could not chdir(%s) for ROOT", portroot); + if (chdir(portvdb)) + errp("could not chdir(%s) for VDB", portvdb); - if (chdir(portvdb) != 0 || (dir = opendir(".")) == NULL) + if ((dir = opendir(".")) == NULL) return EXIT_FAILURE; /* open /var/db/pkg */ @@ -390,7 +390,7 @@ int qdepends_main_vdb(const char *depend continue; IF_DEBUG(warn("matched %s/%s", dentry->d_name, de->d_name)); - snprintf(buf, sizeof(buf), "%s%s/%s/%s/%s", portroot, portvdb, + snprintf(buf, sizeof(buf), "%s/%s/%s/%s", portvdb, dentry->d_name, de->d_name, depend_file); /* >=portage-2.1_pre3 wont ensure these files always exist. @@ -421,7 +421,7 @@ int qdepends_main_vdb(const char *depend printf("%s%s/%s%s%s: ", BOLD, dentry->d_name, BLUE, de->d_name, NORM); } - snprintf(buf, sizeof(buf), "%s%s/%s/%s/USE", portroot, portvdb, + snprintf(buf, sizeof(buf), "%s/%s/%s/USE", portvdb, dentry->d_name, de->d_name); if (access(buf, R_OK) != 0) { @@ -468,10 +468,10 @@ int qdepends_vdb_deep(const char *depend char depend[16384], use[8192]; dep_node *dep_tree; - if (chdir(portroot)) - errp("could not chdir(%s) for ROOT", portroot); + if (chdir(portvdb)) + errp("could not chdir(%s) for VDB", portvdb); - if (chdir(portvdb) != 0 || (dir = opendir(".")) == NULL) + if ((dir = opendir(".")) == NULL) return EXIT_FAILURE; /* open /var/db/pkg */ @@ -487,7 +487,7 @@ int qdepends_vdb_deep(const char *depend continue; IF_DEBUG(warn("matched %s/%s", dentry->d_name, de->d_name)); - snprintf(buf, sizeof(buf), "%s%s/%s/%s/%s", portroot, portvdb, + snprintf(buf, sizeof(buf), "%s/%s/%s/%s", portvdb, dentry->d_name, de->d_name, depend_file); if (access(buf, R_OK) != 0) @@ -504,7 +504,7 @@ int qdepends_vdb_deep(const char *depend IF_DEBUG(puts(depend)); IF_DEBUG(dep_dump_tree(dep_tree)); - snprintf(buf, sizeof(buf), "%s%s/%s/%s/USE", portroot, portvdb, + snprintf(buf, sizeof(buf), "%s/%s/%s/USE", portvdb, dentry->d_name, de->d_name); assert(eat_file(buf, use, sizeof(use)) == 1); for (ptr = use; *ptr; ++ptr) diff -Narup portage-utils-20070115/qfile.c portage-utils-20070115.new/qfile.c --- portage-utils-20070115/qfile.c 2007-01-15 19:20:12.000000000 +0100 +++ portage-utils-20070115.new/qfile.c 2007-01-15 19:21:58.336931120 +0100 @@ -600,16 +600,14 @@ int qfile_main(int argc, char **argv) if (nb_of_queries < 0) goto exit; - if (chdir(portroot) - || chdir(portvdb) != 0 - || (dir = opendir(".")) == NULL) { - warnp("could not chdir(ROOT/%s) for installed packages database", portvdb); + if (chdir(portvdb) != 0 || (dir = opendir(".")) == NULL) { + warnp("could not chdir(%s) for installed packages database", portvdb); goto exit; } /* Iteration over VDB categories */ while (nb_of_queries && (dentry = q_vdb_get_next_dir(dir))) { - snprintf(path, _Q_PATH_MAX, "%s/%s/%s", qfile_args->real_root, portvdb, dentry->d_name); + snprintf(path, _Q_PATH_MAX, "%s/%s", portvdb, dentry->d_name); qfile(path, (assume_root_prefix ? root_prefix : NULL), qfile_args); } diff -Narup portage-utils-20070115/qgrep.c portage-utils-20070115.new/qgrep.c --- portage-utils-20070115/qgrep.c 2007-01-15 19:20:12.000000000 +0100 +++ portage-utils-20070115.new/qgrep.c 2007-01-15 19:21:58.343930052 +0100 @@ -10,11 +10,12 @@ #ifdef APPLET_qgrep -#define QGREP_FLAGS "IiHce" COMMON_FLAGS +#define QGREP_FLAGS "IiHo:ce" COMMON_FLAGS static struct option const qgrep_long_opts[] = { {"invert-match", no_argument, NULL, 'I'}, {"ignore-case", no_argument, NULL, 'i'}, {"with-filename", no_argument, NULL, 'H'}, + {"overlay", a_argument, NULL, 'o'}, {"count", no_argument, NULL, 'c'}, {"regexp", no_argument, NULL, 'e'}, COMMON_LONG_OPTS @@ -23,6 +24,7 @@ static const char *qgrep_opts_help[] = { "Select non-matching lines", "Ignore case distinctions", "Print the filename for each match", + "Only consider the overlay", "Only print a count of matching lines per FILE", "Use PATTERN as a regular expression", COMMON_OPTS_HELP @@ -34,6 +36,8 @@ int qgrep_main(int argc, char **argv) { int i; int count = 0; + short myerror = 0, repo = 0, bad_overlay=0; + char overlay_name[64], repo_search[64]; char *p; char do_count, do_regex; char show_filename; @@ -42,10 +46,15 @@ int qgrep_main(int argc, char **argv) char buf0[BUFSIZ]; int reflags = REG_NOSUB; char invert_match = 0; + overlay_t *cur_overlay, *overlay_tmp; typedef char *(*FUNC) (char *, char *); FUNC strfunc = (FUNC) strstr; + cur_overlay = first_overlay; + overlay_name[0] = 0; + repo_search[0] = 0; + DBG("argc=%d argv[0]=%s argv[1]=%s", argc, argv[0], argc > 1 ? argv[1] : "NULL?"); @@ -58,12 +67,26 @@ int qgrep_main(int argc, char **argv) strfunc = (FUNC) strcasestr; reflags |= REG_ICASE; break; + case 'H': show_filename = 1; break; + case 'o': + repo = 1; + strncpy(repo_search, optarg, sizeof(repo_search)); + break; case 'c': do_count = 1; break; case 'e': do_regex = 1; break; - case 'H': show_filename = 1; break; COMMON_GETOPTS_CASES(qgrep) } } + + if (repo) { + do { + if (!strncmp(cur_overlay->name, repo_search, sizeof(cur_overlay->name))) + break; + } while ((cur_overlay=cur_overlay->next)); + if (NULL == cur_overlay) + err("%s : Unknown overlay, try 'q --ls-overlays'", repo_search); + } + if (argc == optind) qgrep_usage(EXIT_FAILURE); @@ -75,6 +98,51 @@ int qgrep_main(int argc, char **argv) FILE *newfp; if ((p = strchr(ebuild, '\n')) != NULL) *p = 0; + + /* find the overlay, we're working on, and change to the + * corresponding (location|cache) directory */ + if ((p = strchr(ebuild, ':'))) { + /* delete the ::overlay */ + *p = 0; + + /* restrict the search to one overlay if the users wants it */ + if (repo && strncmp(repo_search, p+2, sizeof(repo_search))) + continue; + if (bad_overlay && !strncmp(overlay_name, p+2, sizeof(overlay_name))) + continue; + else { + if (strncmp(overlay_name, p+2, sizeof(overlay_name))) { + overlay_tmp=first_overlay; + do { + if (!strncmp(overlay_tmp->name, p+2, sizeof(overlay_tmp->name))) + break; + } while ((overlay_tmp=overlay_tmp->next)); + + if (overlay_tmp) { + cur_overlay = overlay_tmp; + if (chdir(cur_overlay->path) != 0) { + warnp("chdir to '%s' failed", cur_overlay->path); + myerror = 1; + } else + bad_overlay = 0; + } else + myerror = 1; + + strncpy(overlay_name, p+2, sizeof(overlay_name)); + } + } + } else + myerror=1; + + if (myerror) { + if (!reinitialize) + warnf("(cache update pending) %s : Unknown overlay", overlay_name); + bad_overlay = 1; + myerror = 0; + reinitialize = 1; + continue; + } + if ((newfp = fopen(ebuild, "r")) != NULL) { unsigned int lineno = 0; count = 0; @@ -102,7 +170,7 @@ int qgrep_main(int argc, char **argv) count++; if (do_count) continue; if (verbose || show_filename) { - printf("%s:", ebuild); + printf("%s::%s:", cur_overlay->name, ebuild); if (verbose > 1) printf("%d:", lineno); printf(" "); } @@ -110,7 +178,7 @@ int qgrep_main(int argc, char **argv) } fclose(newfp); if (do_count && count) { - if (verbose || show_filename) printf("%s:", ebuild); + if (verbose || show_filename) printf("%s::%s:", cur_overlay->name, ebuild); printf("%d", count); puts(""); } diff -Narup portage-utils-20070115/qsearch.c portage-utils-20070115.new/qsearch.c --- portage-utils-20070115/qsearch.c 2007-01-15 19:20:12.000000000 +0100 +++ portage-utils-20070115.new/qsearch.c 2007-01-15 19:21:58.353928527 +0100 @@ -9,10 +9,12 @@ #ifdef APPLET_qsearch -#define QSEARCH_FLAGS "acsSNH" COMMON_FLAGS +#define QSEARCH_FLAGS "aco:psSNH" COMMON_FLAGS static struct option const qsearch_long_opts[] = { {"all", no_argument, NULL, 'a'}, {"cache", no_argument, NULL, 'c'}, + {"overlay", a_argument, NULL, 'o'}, + {"show-path", no_argument, NULL, 'p'}, {"search", no_argument, NULL, 's'}, {"desc", a_argument, NULL, 'S'}, {"name-only", no_argument, NULL, 'N'}, @@ -22,6 +24,8 @@ static struct option const qsearch_long_ static const char *qsearch_opts_help[] = { "List the descriptions of every package in the cache", "Use the portage cache", + "Search only in the overlay", + "Show the path to the ebuild", "Regex search package basenames", "Regex search package descriptions", "Only show package name", @@ -40,13 +44,22 @@ int qsearch_main(int argc, char **argv) char last[126] = ""; char dp[126] = ""; char bp[126] = ""; - char *p, *q, *str; + char debuild[126] = ""; + short repo = 0; + char repo_search[64]; + char *p, *q, *str, overlay_name[64]; char *search_me = NULL; - char show_homepage = 0, show_name_only = 0; + char show_homepage = 0, show_name_only = 0, show_path_to_ebuild = 0; char search_desc = 0, search_all = 0, search_name = 1, search_cache = CACHE_EBUILD; const char *search_vars[] = { "DESCRIPTION=", "HOMEPAGE=" }; size_t search_len; - int i, idx=0; + overlay_t *cur_overlay, *overlay_tmp; + int i, idx=0, myerror=0, bad_overlay=0; + + cur_overlay = first_overlay; + overlay_name[0] = 0; + repo_search[0] = 0; + str = NULL; DBG("argc=%d argv[0]=%s argv[1]=%s", argc, argv[0], argc > 1 ? argv[1] : "NULL?"); @@ -56,6 +69,8 @@ int qsearch_main(int argc, char **argv) COMMON_GETOPTS_CASES(qsearch) case 'a': search_all = 1; break; case 'c': search_cache = CACHE_METADATA; break; + case 'o': repo = 1; strncpy(repo_search, optarg, sizeof(repo_search)); break; + case 'p': show_path_to_ebuild = 1; break; case 's': search_desc = 0; search_name = 1; break; case 'S': search_desc = 1; search_name = 0; break; case 'N': show_name_only = 1; break; @@ -63,6 +78,18 @@ int qsearch_main(int argc, char **argv) } } + if (repo) { + do { + if (! strncmp(cur_overlay->name, repo_search, sizeof(cur_overlay->name))) + break; + } while ((cur_overlay=cur_overlay->next)); + if (NULL == cur_overlay) + err("%s : Unknown overlay, try 'q --ls-overlays'", repo_search); + if (search_cache == CACHE_METADATA && !strncmp(cur_overlay->cache,"/var/empty",sizeof(cur_overlay->cache))) + err("No cache defined for the '%s' overlay", cur_overlay->name); + } + + if (search_all) { search_desc = 1; search_name = 0; @@ -86,6 +113,60 @@ int qsearch_main(int argc, char **argv) if (!ebuild[0]) continue; + /* find the overlay, we're working on, and change to the + * corresponding (location|cache) directory */ + if ((p = strchr(ebuild, ':'))) { + /* separator is '::' */ + /* restrict the search to one overlay if the users wants it */ + if (repo && strncmp(repo_search, p+2, sizeof(repo_search))) + continue; + if (bad_overlay && !strncmp(overlay_name, p+2, sizeof(overlay_name))) + continue; + if (strncmp(overlay_name, p+2, sizeof(overlay_name))) { + last[0] = 0; + overlay_tmp=first_overlay; + do { + if (!strncmp(overlay_tmp->name, p+2, sizeof(overlay_tmp->name))) + break; + } while ((overlay_tmp=overlay_tmp->next)); + + if (overlay_tmp) { + cur_overlay=overlay_tmp; + switch (search_cache) { + case CACHE_EBUILD: + if (chdir(cur_overlay->path) != 0) { + warnp("chdir to '%s' failed", cur_overlay->path); + myerror = 1; + continue; + } else + bad_overlay = 0; + break; + case CACHE_METADATA: + if (chdir(cur_overlay->cache) != 0) { + warnp("chdir to '%s' failed, skipping the %s repository", cur_overlay->cache, cur_overlay->name); + myerror = 1; + continue; + } else + bad_overlay = 0; + break; + } + } else + myerror = 1; + strncpy(overlay_name, p+2, sizeof(overlay_name)); + } + } else + myerror++; + + if (myerror) { + if (!reinitialize) + warnf("(cache update pending) %s : Unknown overlay", overlay_name); + bad_overlay = 1; + myerror = 0; + reinitialize = 1; + continue; + } + + switch (search_cache) { case CACHE_METADATA: { @@ -93,11 +174,28 @@ int qsearch_main(int argc, char **argv) if ((pcache = cache_read_file(ebuild)) != NULL) { if ((strcmp(pcache->atom->PN, last)) != 0) { strncpy(last, pcache->atom->PN, sizeof(last)); - if ((rematch(search_me, (search_desc ? pcache->DESCRIPTION : ebuild), REG_EXTENDED | REG_ICASE)) == 0) - printf("%s%s/%s%s%s %s\n", BOLD, pcache->atom->CATEGORY, BLUE, - pcache->atom->PN, NORM, - (show_name_only ? "" : - (show_homepage ? pcache->HOMEPAGE : pcache->DESCRIPTION))); + if (!search_all && (rematch(search_me, (search_desc ? pcache->DESCRIPTION : ebuild), REG_EXTENDED | REG_ICASE)) != 0) { + cache_free(pcache); + continue; + } + + if (show_path_to_ebuild) { + /* delete the ::overlay */ + *p = 0; + strncpy(debuild, ebuild, sizeof(debuild)); + printf("%s%s/%s%s%s::%s\t %s%s/%s/\n", + BOLD, pcache->atom->CATEGORY, + BLUE, pcache->atom->PN, + YELLOW, pcache->atom->OVERLAY, NORM, + cur_overlay->path, dirname(debuild)); + } else { + printf("%s%s/%s%s%s::%s %s%s\n", + BOLD, pcache->atom->CATEGORY, + BLUE, pcache->atom->PN, + YELLOW, pcache->atom->OVERLAY, NORM, + (show_name_only ? "" : + (show_homepage ? pcache->HOMEPAGE : pcache->DESCRIPTION))); + } } cache_free(pcache); } else { @@ -110,6 +208,9 @@ int qsearch_main(int argc, char **argv) case CACHE_EBUILD: { FILE *ebuildfp; + /* delete the ::overlay */ + *p = 0; + str = xstrdup(ebuild); p = (char *) dirname(str); @@ -134,9 +235,18 @@ int qsearch_main(int argc, char **argv) /* doing operations with them. */ strncpy(dp, p, sizeof(dp)); strncpy(bp, p, sizeof(bp)); - printf("%s%s/%s%s%s %s\n", - BOLD, dirname(dp), BLUE, basename(bp), NORM, + strncpy(debuild, ebuild, sizeof(debuild)); + if (show_path_to_ebuild) { + printf("%s%s/%s%s%s::%s\t %s%s/%s/\n", + BOLD, dirname(dp), BLUE, basename(bp), + YELLOW, cur_overlay->name, NORM, + cur_overlay->path, dirname(debuild)); + } else { + printf("%s%s/%s%s%s::%s %s%s\n", + BOLD, dirname(dp), BLUE, basename(bp), + YELLOW, cur_overlay->name, NORM, (show_name_only ? "" : q)); + } break; } } diff -Narup portage-utils-20070115/quse.c portage-utils-20070115.new/quse.c --- portage-utils-20070115/quse.c 2007-01-15 19:20:12.000000000 +0100 +++ portage-utils-20070115.new/quse.c 2007-01-15 19:21:58.361927307 +0100 @@ -1,7 +1,7 @@ /* * Copyright 2005-2006 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 - * $Header: /var/cvsroot/gentoo-projects/portage-utils/quse.c,v 1.55 2007/01/09 13:15:43 vapier Exp $ + * $Header: /var/cvsroot/gentoo-projects/portage-utils/quse.c,v 1.54 2006/12/25 16:38:37 solar Exp $ * * Copyright 2005-2006 Ned Ludd - * Copyright 2005-2006 Mike Frysinger - @@ -14,10 +14,11 @@ quse -Ke -- nls */ -#define QUSE_FLAGS "eavKLDF:N" COMMON_FLAGS +#define QUSE_FLAGS "eao:vKLDF:N" COMMON_FLAGS static struct option const quse_long_opts[] = { {"exact", no_argument, NULL, 'e'}, {"all", no_argument, NULL, 'a'}, + {"overlay", a_argument, NULL, 'o'}, {"keywords", no_argument, NULL, 'K'}, {"license", no_argument, NULL, 'L'}, {"describe", no_argument, NULL, 'D'}, @@ -28,6 +29,7 @@ static struct option const quse_long_opt static const char *quse_opts_help[] = { "Show exact non regexp matching using strcmp", "Show annoying things in IUSE", + "Only consider the overlay", "Use the KEYWORDS vs IUSE", "Use the LICENSE vs IUSE", "Describe the USE flag", @@ -35,10 +37,10 @@ static const char *quse_opts_help[] = { "Only show package name", COMMON_OPTS_HELP }; -static const char quse_rcsid[] = "$Id: quse.c,v 1.55 2007/01/09 13:15:43 vapier Exp $"; +static const char quse_rcsid[] = "$Id: quse.c,v 1.54 2006/12/25 16:38:37 solar Exp $"; #define quse_usage(ret) usage(ret, QUSE_FLAGS, quse_long_opts, quse_opts_help, lookup_applet_idx("quse")) -int quse_describe_flag(int ind, int argc, char **argv); +int quse_describe_flag(int ind, short repo, char repo_search[], int argc, char **argv); char quse_name_only = 0; @@ -81,7 +83,7 @@ static void print_highlighted_use_flags( } } -int quse_describe_flag(int ind, int argc, char **argv) +int quse_describe_flag(int ind, short repo, char repo_search[], int argc, char **argv) { #define NUM_SEARCH_FILES ARR_SIZE(search_files) char buf[BUFSIZE], *p; @@ -91,115 +93,152 @@ int quse_describe_flag(int ind, int argc FILE *fp[NUM_SEARCH_FILES]; DIR *d; struct dirent *de; + overlay_t *cur_overlay; - for (i = 0; i < NUM_SEARCH_FILES; ++i) { - snprintf(buf, sizeof(buf), "%s/profiles/%s", portdir, search_files[i]); - if ((fp[i] = fopen(buf, "r")) == NULL) - warnp("skipping %s", search_files[i]); - } + cur_overlay=first_overlay; - for (i = ind; i < argc; i++) { - s = strlen(argv[i]); + do { + if (repo && strncmp(repo_search, cur_overlay->name, sizeof(repo_search))) + continue; + for (i = 0; i < NUM_SEARCH_FILES; ++i) { + snprintf(buf, sizeof(buf), "%s/profiles/%s", cur_overlay->path, search_files[i]); + if ((fp[i] = fopen(buf, "r")) == NULL) + if (verbose>2) + warnp("skipping %s for the %s overlay", search_files[i], cur_overlay->name); + } - for (f = 0; f < NUM_SEARCH_FILES; ++f) { - if (fp[f] == NULL) - continue; + for (i = ind; i < argc; i++) { + s = strlen(argv[i]); - while (fgets(buf, sizeof(buf), fp[f]) != NULL) { - if (buf[0] == '#' || buf[0] == '\n') + for (f = 0; f < NUM_SEARCH_FILES; ++f) { + if (fp[f] == NULL) continue; - if ((p = strrchr(buf, '\n')) != NULL) - *p = '\0'; + while (fgets(buf, sizeof(buf), fp[f]) != NULL) { + if (buf[0] == '#' || buf[0] == '\n') + continue; - switch (f) { - case 0: /* Global use.desc */ - if (!strncmp(buf, argv[i], s)) - if (buf[s] == ' ' && buf[s+1] == '-') { - printf(" %sglobal%s:%s%s%s: %s\n", BOLD, NORM, BLUE, argv[i], NORM, buf+s+3); - goto skip_file; - } - break; + if ((p = strrchr(buf, '\n')) != NULL) + *p = '\0'; - case 1: /* Local use.local.desc */ - if ((p = strchr(buf, ':')) == NULL) + switch (f) { + case 0: /* Global use.desc */ + if (!strncmp(buf, argv[i], s)) + if (buf[s] == ' ' && buf[s+1] == '-') { + if (overlay_gentoo && cur_overlay == overlay_gentoo) + printf(" %sglobal%s:%s%s%s: %s\n", BOLD, NORM, BLUE, argv[i], NORM, buf+s+3); + else + printf(" (%s) %sglobal%s:%s%s%s: %s\n", cur_overlay->name, BOLD, NORM, BLUE, argv[i], NORM, buf+s+3); + goto skip_file; + } break; - ++p; - if (!strncmp(p, argv[i], s)) { - if (p[s] == ' ' && p[s+1] == '-') { - *p = '\0'; - printf(" %slocal%s:%s%s%s:%s%s%s %s\n", BOLD, NORM, BLUE, argv[i], NORM, BOLD, buf, NORM, p+s+3); - } - } - break; - case 2: /* Architectures arch.list */ - if (!strcmp(buf, argv[i])) { - printf(" %sarch%s:%s%s%s: %s architecture\n", BOLD, NORM, BLUE, argv[i], NORM, argv[i]); - goto skip_file; - } - break; + case 1: /* Local use.local.desc */ + if ((p = strchr(buf, ':')) == NULL) + break; + ++p; + if (!strncmp(p, argv[i], s)) { + if (p[s] == ' ' && p[s+1] == '-') { + *p = '\0'; + if (overlay_gentoo && cur_overlay == overlay_gentoo) + printf(" %slocal%s:%s%s%s:%s%s%s %s\n", BOLD, NORM, BLUE, argv[i], NORM, BOLD, buf, NORM, p+s+3); + else + printf(" (%s) %slocal%s:%s%s%s:%s%s%s %s\n", cur_overlay->name, BOLD, NORM, BLUE, argv[i], NORM, BOLD, buf, NORM, p+s+3); + } + } + break; - case 3: /* Languages lang.desc */ - if (!strncmp(buf, argv[i], s)) - if (buf[s] == ' ' && buf[s+1] == '-') { - printf(" %slang%s:%s%s%s: %s lingua\n", BOLD, NORM, BLUE, argv[i], NORM, buf+s+3); + case 2: /* Architectures arch.list */ + if (!strcmp(buf, argv[i])) { + if (overlay_gentoo && cur_overlay == overlay_gentoo) + printf(" %sarch%s:%s%s%s: %s architecture\n", BOLD, NORM, BLUE, argv[i], NORM, argv[i]); + else + printf(" (%s) %sarch%s:%s%s%s: %s architecture\n", cur_overlay->name, BOLD, NORM, BLUE, argv[i], NORM, argv[i]); goto skip_file; } - break; + break; + + case 3: /* Languages lang.desc */ + if (!strncmp(buf, argv[i], s)) + if (buf[s] == ' ' && buf[s+1] == '-') { + if (overlay_gentoo && cur_overlay == overlay_gentoo) + printf(" %slang%s:%s%s%s: %s lingua\n", BOLD, NORM, BLUE, argv[i], NORM, buf+s+3); + else + printf(" (%s) %slang%s:%s%s%s: %s lingua\n", cur_overlay->name, BOLD, NORM, BLUE, argv[i], NORM, buf+s+3); + goto skip_file; + } + break; + } } - } skip_file: - rewind(fp[f]); + rewind(fp[f]); + } + + if (i == (argc - 1)) + for (f=0; fnext)); /* now scan the desc dir */ - snprintf(buf, sizeof(buf), "%s/profiles/desc/", portdir); - d = opendir(buf); - while ((de = readdir(d)) != NULL) { - if (strcmp(de->d_name+strlen(de->d_name)-5, ".desc")) + cur_overlay=first_overlay; + do { + if (repo && strncmp(repo_search, cur_overlay->name, sizeof(repo_search))) continue; - - snprintf(buf, sizeof(buf), "%s/profiles/desc/%s", portdir, de->d_name); - if ((fp[0]=fopen(buf, "r")) == NULL) { - warn("Could not open '%s' for reading; skipping", de->d_name); + snprintf(buf, sizeof(buf), "%s/profiles/desc/", cur_overlay->path); + if (!(d = opendir(buf))) { + if (verbose>2) + warn("Could not open %s -> skipping", buf); continue; } + while ((de = readdir(d)) != NULL) { + if (strcmp(de->d_name+strlen(de->d_name)-5, ".desc")) + continue; - while (fgets(buf, sizeof(buf), fp[0]) != NULL) { - if (buf[0] == '#' || buf[0] == '\n') + snprintf(buf, sizeof(buf), "%s/profiles/desc/%s", cur_overlay->path, de->d_name); + if ((fp[0]=fopen(buf, "r")) == NULL) { + warn("Could not open '%s' for reading; skipping", de->d_name); continue; + } - if ((p = strrchr(buf, '\n')) != NULL) - *p = '\0'; + while (fgets(buf, sizeof(buf), fp[0]) != NULL) { + if (buf[0] == '#' || buf[0] == '\n') + continue; - if ((p = strchr(buf, '-')) == NULL) { + if ((p = strrchr(buf, '\n')) != NULL) + *p = '\0'; + + if ((p = strchr(buf, '-')) == NULL) { invalid_line: - warn("Invalid line in '%s': %s", de->d_name, buf); - continue; - } - while (p[-1] != ' ' && p[1] != ' ') { - /* maybe the flag has a '-' in it ... */ - if ((p = strchr(p+1, '-')) == NULL) - goto invalid_line; - } - p[-1] = '\0'; - p += 2; + warn("Invalid line in '%s': %s", de->d_name, buf); + continue; + } + while (p[-1] != ' ' && p[1] != ' ') { + /* maybe the flag has a '-' in it ... */ + if ((p = strchr(p+1, '-')) == NULL) + goto invalid_line; + } + p[-1] = '\0'; + p += 2; - for (i = ind; i < argc; i++) - if (!strcmp(argv[i], buf)) - printf(" %s%s%s:%s%s%s: %s\n", BOLD, de->d_name, NORM, BLUE, argv[i], NORM, p); - } - close(f); - } - closedir(d); + for (i = ind; i < argc; i++) + if (!strcmp(argv[i], buf)) { + if (overlay_gentoo && cur_overlay == overlay_gentoo) + printf(" %s%s%s:%s%s%s: %s\n", BOLD, de->d_name, NORM, BLUE, argv[i], NORM, p); + else + printf(" (%s) %s%s%s:%s%s%s: %s\n", cur_overlay->name, BOLD, de->d_name, NORM, BLUE, argv[i], NORM, p); + } + } + fclose(fp[0]); + } + closedir(d); + } while ((cur_overlay=cur_overlay->next)); return 0; } @@ -207,6 +246,9 @@ int quse_main(int argc, char **argv) { FILE *fp; char *p; + short myerror = 0, repo = 0; + char repo_search[64]; + char overlay_name[64]; char buf0[_Q_PATH_MAX]; char buf1[_Q_PATH_MAX]; @@ -217,8 +259,13 @@ int quse_main(int argc, char **argv) const char *search_var = NULL; const char *search_vars[] = { "IUSE=", "KEYWORDS=", "LICENSE=", search_var }; short quse_all = 0; - int regexp_matching = 1, i, idx = 0; + int regexp_matching = 1, i, idx = 0, bad_overlay = 0; size_t search_len; + overlay_t *cur_overlay, *overlay_tmp; + + cur_overlay = first_overlay; + overlay_name[0] = 0; + repo_search[0] = 0; DBG("argc=%d argv[0]=%s argv[1]=%s", argc, argv[0], argc > 1 ? argv[1] : "NULL?"); @@ -227,6 +274,10 @@ int quse_main(int argc, char **argv) switch (i) { case 'e': regexp_matching = 0; break; case 'a': quse_all = 1; break; + case 'o': + repo = 1; + strncpy(repo_search, optarg, sizeof(repo_search)); + break; case 'K': idx = 1; break; case 'L': idx = 2; break; case 'D': idx = -1; break; @@ -235,13 +286,25 @@ int quse_main(int argc, char **argv) COMMON_GETOPTS_CASES(quse) } } - if (argc == optind && !quse_all && idx >= 0) + + if (repo) { + do { + if (!strncmp(cur_overlay->name, repo_search, sizeof(cur_overlay->name))) + break; + } while ((cur_overlay=cur_overlay->next)); + if (NULL == cur_overlay) + err("%s : Unknown overlay, try 'q --ls-overlays'", repo_search); + } + + if (argc == optind && !quse_all && idx >= 0) { + if (idx == 3) + free(search_vars[idx]); quse_usage(EXIT_FAILURE); + } if (idx == -1) - return quse_describe_flag(optind, argc, argv); + return quse_describe_flag(optind, repo, repo_search, argc, argv); - if (quse_all) optind = argc; initialize_ebuild_flat(); /* sets our pwd to $PORTDIR */ search_len = strlen(search_vars[idx]); @@ -253,6 +316,54 @@ int quse_main(int argc, char **argv) FILE *newfp; if ((p = strchr(ebuild, '\n')) != NULL) *p = 0; + if ((p = strchr(ebuild, ':'))) + { + /* delete the ::overlay */ + *p = 0; + if (repo && strncmp(repo_search, p+2, sizeof(repo_search))) + continue; + if (bad_overlay && !strncmp(overlay_name, p+2, sizeof(overlay_name))) + continue; + else { + if (strncmp(overlay_name, p+2, sizeof(overlay_name))) { + overlay_tmp=first_overlay; + do { + if (!strncmp(overlay_tmp->name, p+2, sizeof(overlay_tmp->name))) + break; + } while ((overlay_tmp=overlay_tmp->next)); + if (overlay_tmp) + { + cur_overlay = overlay_tmp; + if (chdir(cur_overlay->path) != 0) { + warnp("chdir to '%s' failed", cur_overlay->path); + myerror=1; + } else + bad_overlay = 0; + } else + myerror=1; + strncpy(overlay_name, p+2, sizeof(overlay_name)); + } + } + } else + myerror=1; + + if (myerror) { + if (!reinitialize) + warnf("(cache update pending) %s : Unknown overlay", overlay_name); + bad_overlay = 1; + myerror = 0; + reinitialize = 1; + continue; + } + + if ((quse_all) && optind!=argc) { + for (i=optind;i 3) printf("%s %s %s ", *user ? user : "MISSING", *revision ? revision : "MISSING", *date ? date : "MISSING"); - printf("%s%s%s ", CYAN, ebuild, NORM); - print_highlighted_use_flags(&buf0[search_len+1], optind, argc, argv); + printf("%s%s::%s%s ", CYAN, cur_overlay->name, ebuild, NORM); + if (quse_all) + print_highlighted_use_flags(&buf0[search_len+1], argc, argc, argv); + else + print_highlighted_use_flags(&buf0[search_len+1], optind, argc, argv); puts(NORM); if (verbose > 1) { char **ARGV = NULL; int ARGC = 0; makeargv(&buf0[search_len+1], &ARGC, &ARGV); if (ARGC > 0) { - quse_describe_flag(1, ARGC, ARGV); + quse_describe_flag(1, 0, repo_search, ARGC, ARGV); for (i = 0; i < ARGC; i++) free(ARGV[i]); free(ARGV); @@ -401,6 +515,8 @@ int quse_main(int argc, char **argv) } } fclose(fp); + if (idx == 3) + free(search_vars[idx]); return EXIT_SUCCESS; }