diff -Narup portage-utils-20061111/applets.h portage-utils-20061111.new/applets.h --- portage-utils-20061111/applets.h 2006-11-11 23:37:20.000000000 +0100 +++ portage-utils-20061111.new/applets.h 2006-11-12 23:01:40.622006159 +0100 @@ -53,7 +53,6 @@ struct applet_t { {"qcheck", qcheck_main, "", "verify mtimes/digests"}, {"qdepends", qdepends_main, "", "show dependency info"}, {"qfile", qfile_main, "", "list all pkgs owning files"}, - {"qglsa", qglsa_main, " ", "check GLSAs against system"}, {"qgrep", qgrep_main, "", "grep in ebuilds"}, {"qlist", qlist_main, "", "list files owned by pkgname"}, {"qlop", qlop_main, "", "emerge log analyzer"}, @@ -65,6 +64,7 @@ struct applet_t { {"qtbz2", qtbz2_main, "", "manipulate tbz2 packages"}, {"quse", quse_main, "", "find pkgs using useflags"}, {"qxpak", qxpak_main, "", "manipulate xpak archives"}, + {"qglsa", qglsa_main, " ", NULL}, /* "check GLSAs against system" */ /* aliases for equery capatability */ diff -Narup portage-utils-20061111/main.c portage-utils-20061111.new/main.c --- portage-utils-20061111/main.c 2006-11-11 23:37:20.000000000 +0100 +++ portage-utils-20061111.new/main.c 2006-11-12 23:21:57.582000119 +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,21 @@ 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 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]; + struct overlay_t *next; +}; + +static overlay_t *overlay_gentoo = NULL; + char pkgdir[512] = "/usr/portage/packages/"; char port_tmpdir[512] = "/var/tmp/portage/"; @@ -201,10 +210,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); @@ -469,17 +478,79 @@ 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; + cur_overlay = overlay_gentoo; + + while (*s) { + cur_overlay->next = xmalloc ( sizeof (*cur_overlay->next)); + cur_overlay = cur_overlay->next; + cur_overlay->next = NULL; + + if ( (p=strchr(s,' '))) + *p = 0; + + strncpy(cur_overlay->path, s, sizeof(cur_overlay->path)); + + /* find the name for the overlay */ + strncpy(file, cur_overlay->path, _Q_PATH_MAX); + strncat(file, "/profiles/repo_name", _Q_PATH_MAX); + 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(cur_overlay->name, basename(cur_overlay->path), sizeof(cur_overlay->name)); + merror=0; + } + + if (p) + s = p+1; + 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 portdir_overlay[2048] = ""; + char buf[BUFSIZE], *s, *p; char profile[_Q_PATH_MAX], portage_file[_Q_PATH_MAX]; + 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; @@ -493,13 +564,19 @@ 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)}, {"ROOT", 4, _Q_STR, portroot, sizeof(portroot)} }; + overlay_gentoo = (overlay_t*) xmalloc(sizeof(*overlay_gentoo)); + strcpy(overlay_gentoo->name,"gentoo"); + strcpy(overlay_gentoo->path,"/usr/portage"); + overlay_gentoo->next = NULL; + if ((p = strchr(portroot, '/')) != NULL) if (strlen(p) != 1) strncat(portroot, "/", sizeof(portroot)); @@ -591,6 +668,13 @@ void initialize_portage_env(void) no_colors(); else color_remap(); + + + strncpy(overlay_gentoo->path, tmp_portdir, sizeof(overlay_gentoo->path)); + + /* now we initiliase the overlay chained list with overlay_gentoo as the first 'item' */ + initialize_overlays(portdir_overlay); + } enum { @@ -619,19 +703,21 @@ 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 = overlay_gentoo; cache_file = (cache_type == CACHE_EBUILD ? CACHE_EBUILD_FILE : CACHE_METADATA_FILE); - if (chdir(portdir) != 0) { - warnp("chdir to PORTDIR '%s' failed", portdir); + if (chdir(overlay_gentoo->path) != 0) { + warnp("chdir to PORTDIR '%s' failed", overlay_gentoo->path); goto ret; } if (cache_type == CACHE_METADATA && chdir(portcachedir) != 0) { - warnp("chdir to portage cache '%s/%s' failed", portdir, portcachedir); + warnp("chdir to portage cache '%s/%s' failed", overlay_gentoo->path, portcachedir); goto ret; } @@ -647,64 +733,71 @@ const char *initialize_flat(int cache_ty unlink(cache_file); if (errno != ENOENT) { - warnfp("unlinking '%s/%s' failed", portdir, cache_file); + warnfp("unlinking '%s/%s' failed", overlay_gentoo->path, cache_file); goto ret; } if ((fp = fopen(cache_file, "w")) == NULL) { - warnfp("opening '%s/%s' failed", portdir, cache_file); + warnfp("opening '%s/%s' failed", overlay_gentoo->path, 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 { + if ( cur_overlay == overlay_gentoo || chdir(cur_overlay->path) == 0) { + if ((a = scandir(".", &category, filter_hidden, alphasort)) < 0) continue; - if ((b = scandir(category[i]->d_name, &pn, filter_hidden, alphasort)) < 0) - continue; - for (c = 0; c < b; c++) { - char de[_Q_PATH_MAX]; + 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; - snprintf(de, sizeof(de), "%s/%s", category[i]->d_name, pn[c]->d_name); + if ((b = scandir(category[i]->d_name, &pn, filter_hidden, alphasort)) < 0) + continue; + for (c = 0; c < b; c++) { + char de[_Q_PATH_MAX]; - if (stat(de, &st) < 0) - continue; + snprintf(de, sizeof(de), "%s/%s", category[i]->d_name, pn[c]->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\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); + if (stat(de, &st) < 0) + continue; + + 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\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/%s\n", cur_overlay->name, category[i]->d_name, pn[c]->d_name, eb[d]->d_name); + } } + while (d--) free(eb[d]); + free(eb); + } + while (b--) free(pn[b]); + free(pn); } - while (d--) free(eb[d]); - free(eb); - } - while (b--) free(pn[b]); - free(pn); - } + } else + warnp("chdir to '%s' failed, skipping the %s repository", cur_overlay->path, cur_overlay->name); + + } while ( (cur_overlay = cur_overlay->next)); + fclose(fp); while (a--) free(category[a]); free(category); @@ -723,7 +816,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 PORTDIR='%s'", overlay_gentoo->path); ret: return cache_file; } @@ -732,8 +825,8 @@ ret: void reinitialize_ebuild_flat(void) { - if ((chdir(portdir)) != 0) { - warnp("chdir to PORTDIR '%s' failed", portdir); + if ((chdir(overlay_gentoo->path)) != 0) { + warnp("chdir to PORTDIR '%s' failed", overlay_gentoo->path); return; } unlink(CACHE_EBUILD_FILE); @@ -1006,10 +1099,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(overlay_gentoo); fclose(stderr); } diff -Narup portage-utils-20061111/q.c portage-utils-20061111.new/q.c --- portage-utils-20061111/q.c 2006-11-11 23:37:20.000000000 +0100 +++ portage-utils-20061111.new/q.c 2006-11-12 23:01:40.785981231 +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,15 @@ 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=overlay_gentoo; + do { + printf(" Name : %s%-20.20s%s \tlocation : %s%s%s\n", CYAN, cur_overlay->name, NORM, CYAN, cur_overlay->path, 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-20061111/qcache.c portage-utils-20061111.new/qcache.c --- portage-utils-20061111/qcache.c 2006-11-11 23:37:20.000000000 +0100 +++ portage-utils-20061111.new/qcache.c 2006-11-12 23:01:40.829974543 +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-20061111/qgrep.c portage-utils-20061111.new/qgrep.c --- portage-utils-20061111/qgrep.c 2006-11-11 23:37:20.000000000 +0100 +++ portage-utils-20061111.new/qgrep.c 2006-11-12 23:12:21.511576134 +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,7 +36,9 @@ int qgrep_main(int argc, char **argv) { int i; int count = 0; - char *p; + short myerror = 0, repo = 0; + char overlay_name[64], repo_search[64]; + char *p, *str; char do_count, do_regex; char show_filename; FILE *fp; @@ -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 = overlay_gentoo; + 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,9 +67,13 @@ 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) } } @@ -73,6 +86,38 @@ int qgrep_main(int argc, char **argv) return 1; while ((fgets(ebuild, sizeof(ebuild), fp)) != NULL) { FILE *newfp; + if ( ( p = strchr(ebuild, ':'))) + { + *p = 0; + str = p+2; /* separator is '::' */ + p = ebuild; + if ( repo && strncmp(repo_search, p, sizeof( repo_search))) + continue; + if ( strcmp(overlay_name, p)) + { + overlay_tmp=overlay_gentoo; + do { + if ( ! strncmp(overlay_tmp->name, p, sizeof(overlay_tmp->name))) + break; + } while ((overlay_tmp=overlay_tmp->next)); + if ( ! strncmp(overlay_tmp->name, p, sizeof(overlay_tmp->name))) + { + cur_overlay = overlay_tmp; + if (chdir(cur_overlay->path) != 0) { + warnp("chdir to PORTDIR '%s' failed", cur_overlay->path); + myerror=1; + } + } else + myerror=1; + if ( myerror) { + myerror=0; + continue; + } + strncpy(overlay_name, cur_overlay->name, sizeof(overlay_name)); + } + strcpy(ebuild, str) ; + } + if ((p = strchr(ebuild, '\n')) != NULL) *p = 0; if ((newfp = fopen(ebuild, "r")) != NULL) { @@ -102,7 +147,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(" "); } diff -Narup portage-utils-20061111/qsearch.c portage-utils-20061111.new/qsearch.c --- portage-utils-20061111/qsearch.c 2006-11-11 23:37:20.000000000 +0100 +++ portage-utils-20061111.new/qsearch.c 2006-11-12 23:19:52.999939471 +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,20 @@ int qsearch_main(int argc, char **argv) char last[126] = ""; char dp[126] = ""; char bp[126] = ""; - char *p, *q, *str; + 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; + + cur_overlay = overlay_gentoo; + 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?"); @@ -56,6 +67,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; @@ -93,11 +106,22 @@ 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 ((rematch(search_me, (search_desc ? pcache->DESCRIPTION : ebuild), REG_EXTENDED | REG_ICASE)) == 0) { + if ( show_path_to_ebuild) { + printf("%s%s/%s%s%s::%s\t %s%s/%s/\n", + BOLD, pcache->atom->CATEGORY, + BLUE, pcache->atom->PN, + YELLOW,cur_overlay->name, NORM, + cur_overlay->path, dirname(ebuild)); + } else { + printf("%s%s/%s%s%s::%s %s%s\n", + BOLD, pcache->atom->CATEGORY, + BLUE, pcache->atom->PN, + YELLOW,cur_overlay->name, NORM, + (show_name_only ? "" : + (show_homepage ? pcache->HOMEPAGE : pcache->DESCRIPTION))); + } + } } cache_free(pcache); } else { @@ -110,6 +134,40 @@ int qsearch_main(int argc, char **argv) case CACHE_EBUILD: { FILE *ebuildfp; + if ( ( p = strchr(ebuild, ':'))) + { + *p = 0; + str = p+2; /* separator is '::' */ + p = ebuild; + if ( repo && strncmp( repo_search, p, sizeof(repo_search))) + continue; + if ( strcmp(overlay_name, p)) + { + overlay_tmp=overlay_gentoo; + do { + if ( ! strncmp(overlay_tmp->name, p, sizeof(overlay_tmp->name))) + break; + } while ((overlay_tmp=overlay_tmp->next)); + if ( ! strncmp(overlay_tmp->name, p, sizeof(overlay_tmp->name))) + { + cur_overlay = overlay_tmp; + if (chdir(cur_overlay->path) != 0) { + warnp("chdir to '%s' failed", cur_overlay->path); + myerror=1; + } + } else + myerror=1; + if ( myerror) { + if (!reinitialize) + warnfp("(cache update pending) %s::%s", p, ebuild); + reinitialize = 1; + break; + } + strncpy(overlay_name, cur_overlay->name, sizeof(overlay_name)); + } + strcpy(ebuild, str) ; /* separator is '::' */ + } + str = xstrdup(ebuild); p = (char *) dirname(str); @@ -134,9 +192,17 @@ 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, + 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(ebuild)); + } 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-20061111/quse.c portage-utils-20061111.new/quse.c --- portage-utils-20061111/quse.c 2006-11-11 23:37:21.000000000 +0100 +++ portage-utils-20061111.new/quse.c 2006-11-12 23:06:47.776311607 +0100 @@ -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", @@ -38,7 +40,7 @@ static const char *quse_opts_help[] = { static const char quse_rcsid[] = "$Id: quse.c,v 1.53 2006/11/09 00:18:05 vapier 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,121 +93,162 @@ 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=overlay_gentoo; - 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 ) + 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 ( 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 ( 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 ( 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 ( 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=overlay_gentoo; + 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 ) + 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 = strrchr(buf, '\n')) != NULL) + *p = '\0'; - if ((p = strchr(buf, '-')) == NULL) { + 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 ( 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; } int quse_main(int argc, char **argv) { FILE *fp; - char *p; + char *p, *str; + short myerror = 0, repo = 0; + char repo_search[64]; + char overlay_name[64]; char buf0[_Q_PATH_MAX]; char buf1[_Q_PATH_MAX]; @@ -218,6 +261,11 @@ int quse_main(int argc, char **argv) short quse_all = 0; int regexp_matching = 1, i, idx = 0; size_t search_len; + overlay_t *cur_overlay, *overlay_tmp; + + cur_overlay = overlay_gentoo; + 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?"); @@ -226,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; @@ -234,11 +286,14 @@ int quse_main(int argc, char **argv) COMMON_GETOPTS_CASES(quse) } } - if (argc == optind && !quse_all && idx >= 0) + 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 */ @@ -250,6 +305,41 @@ int quse_main(int argc, char **argv) return 1; while ((fgets(ebuild, sizeof(ebuild), fp)) != NULL) { FILE *newfp; + if ( ( p = strchr(ebuild, ':'))) + { + *p = 0; + str = p+2; /* separator is '::' */ + p = ebuild; + if ( repo && strncmp( repo_search, p, sizeof(repo_search))) + continue; + if ( strcmp(overlay_name, p)) + { + overlay_tmp=overlay_gentoo; + do { + if ( ! strncmp(overlay_tmp->name, p, sizeof(overlay_tmp->name))) + break; + } while ((overlay_tmp=overlay_tmp->next)); + if ( ! strncmp(overlay_tmp->name, p, sizeof(overlay_tmp->name))) + { + cur_overlay = overlay_tmp; + if (chdir(cur_overlay->path) != 0) { + warnp("chdir to PORTDIR '%s' failed", cur_overlay->path); + myerror=1; + } + } else + myerror=1; + if ( myerror) { + if (!reinitialize) + warnf("(cache update pending) %s : %s", ebuild, strerror(errno)); + reinitialize = 1; + myerror=0; + continue; + } + strncpy(overlay_name, cur_overlay->name, sizeof(overlay_name)); + } + strcpy(ebuild, str) ; + } + if ((p = strchr(ebuild, '\n')) != NULL) *p = 0; if ((newfp = fopen(ebuild, "r")) != NULL) { @@ -375,7 +465,7 @@ int quse_main(int argc, char **argv) if (verbose > 3) printf("%s %s %s ", *user ? user : "MISSING", *revision ? revision : "MISSING", *date ? date : "MISSING"); - printf("%s%s%s ", CYAN, ebuild, NORM); + printf("%s%s::%s%s ", CYAN, cur_overlay->name, ebuild, NORM); print_highlighted_use_flags(&buf0[search_len+1], optind, argc, argv); puts(NORM); if (verbose > 1) { @@ -383,7 +473,7 @@ int quse_main(int argc, char **argv) int ARGC = 0; makeargv(&buf0[search_len+1], &ARGC, &ARGV); if (ARGC > 0) { - quse_describe_flag(1, ARGC, ARGV); + quse_describe_flag(1, repo, repo_search, ARGC, ARGV); for (i = 0; i < ARGC; i++) free(ARGV[i]); free(ARGV);