Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 107119 Details for
Bug 154405
app-portage/portage-utils: add overlays support
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
overlay-support.patch
overlay-support.patch (text/plain), 71.89 KB, created by
samLT
on 2007-01-15 20:42:05 UTC
(
hide
)
Description:
overlay-support.patch
Filename:
MIME Type:
Creator:
samLT
Created:
2007-01-15 20:42:05 UTC
Size:
71.89 KB
patch
obsolete
>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; i<ARR_SIZE(atom_version_str); ++i) { >+ if (!strcmp(s1,&atom_version_str[i].version[1])) >+ n1=1; >+ if (!strcmp(s2,&atom_version_str[i].version[1])) >+ n2=1; >+ } >+ if (n1+n2) { >+ if (n1==n2) >+ goto same_version; >+ else >+ return (n1<n2 ? OLDER : NEWER); >+ } >+ > while (s1 || s2) { > if (s1 && s2) { > /* deal with leading zeros */ >@@ -101,7 +117,7 @@ int atom_compare(const depend_atom * con > /* fall through to -r# check below */ > } else if (a1->PV || 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; i<ARR_SIZE(atom_version_str); ++i) >+ if ((ptr_tmp = strstr(ret->PN, 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<arg>%s %s*%s %s\n", opts[i].val, >+ printf(" -%c, --%-9s %s<arg>%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 <useflag> > qxpak <misc args> > : 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 >+<arg> >+.BR >+ * Only consider the <arg> 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<regex>\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 >+<arg> >+.BR >+ * Search only in the <arg> 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<useflag>\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 >+<arg> >+.BR >+ * Only consider the <arg> 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 - <vapier@gentoo.org> > */ > >-#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/qfile.c.orig portage-utils-20070115.new/qfile.c.orig >--- portage-utils-20070115/qfile.c.orig 1970-01-01 01:00:00.000000000 +0100 >+++ portage-utils-20070115.new/qfile.c.orig 2007-01-15 19:21:05.010066468 +0100 >@@ -0,0 +1,662 @@ >+/* >+ * Copyright 2005-2006 Gentoo Foundation >+ * Distributed under the terms of the GNU General Public License v2 >+ * $Header: /var/cvsroot/gentoo-projects/portage-utils/qfile.c,v 1.42 2007/01/13 19:17:39 solar Exp $ >+ * >+ * Copyright 2005-2006 Ned Ludd - <solar@gentoo.org> >+ * Copyright 2005-2006 Mike Frysinger - <vapier@gentoo.org> >+ */ >+ >+#ifdef APPLET_qfile >+ >+#define QFILE_MAX_MAX_ARGS 5000000 >+#define QFILE_DEFAULT_MAX_ARGS 5000 >+#define QFILE_DEFAULT_MAX_ARGS_STR "5000" >+ >+#define QFILE_FLAGS "ef:m:oRx:" COMMON_FLAGS >+static struct option const qfile_long_opts[] = { >+ {"exact", no_argument, NULL, 'e'}, >+ {"from", a_argument, NULL, 'f'}, >+ {"max-args", a_argument, NULL, 'm'}, >+ {"orphans", no_argument, NULL, 'o'}, >+ {"root-prefix", no_argument, NULL, 'R'}, >+ {"exclude", a_argument, NULL, 'x'}, >+ COMMON_LONG_OPTS >+}; >+static const char *qfile_opts_help[] = { >+ "Exact match", >+ "Read arguments from file <arg> (\"-\" for stdin)", >+ "Treat from file arguments by groups of <arg> (defaults to " QFILE_DEFAULT_MAX_ARGS_STR ")", >+ "List orphan files", >+ "Assume arguments are already prefixed by $ROOT", >+ "Don't look in package <arg>", >+ COMMON_OPTS_HELP >+}; >+static char qfile_rcsid[] = "$Id: qfile.c,v 1.42 2007/01/13 19:17:39 solar Exp $"; >+#define qfile_usage(ret) usage(ret, QFILE_FLAGS, qfile_long_opts, qfile_opts_help, lookup_applet_idx("qfile")) >+ >+static inline short qfile_is_prefix(const char* path, const char* prefix, int prefix_length) >+{ >+ return !prefix_length >+ || (strlen(path) >= prefix_length >+ && (path[prefix_length] == '/' || path[prefix_length] == '\0') >+ && !strncmp(path, prefix, prefix_length)); >+} >+ >+typedef struct { >+ int length; >+ char **basenames; >+ char **dirnames; >+ char **realdirnames; >+ char *bn_firstchars; >+ short *non_orphans; >+ char *real_root; >+ char *exclude_pkg; >+ char *exclude_slot; >+} qfile_args_t; >+ >+void qfile(char *, const char *, qfile_args_t *); >+void qfile(char *path, const char *root, qfile_args_t *args) >+{ >+ FILE *fp; >+ DIR *dir; >+ struct dirent *dentry; >+ char *entry_basename; >+ char *entry_dirname; >+ char *p; >+ char buf[1024]; >+ char pkg[126]; >+ depend_atom *atom; >+ int i, path_ok; >+ char bn_firstchar; >+ char *real_root = args->real_root; >+ char **base_names = args->basenames; >+ char **dir_names = args->dirnames; >+ char **real_dir_names = args->realdirnames; >+ char *bn_firstchars = args->bn_firstchars; >+ short *non_orphans = args->non_orphans; >+ >+ if (chdir(path) != 0 || (dir = opendir(".")) == NULL) >+ return; >+ >+ while ((dentry = readdir(dir))) { >+ if (dentry->d_name[0] == '.') >+ continue; >+ >+ snprintf(pkg, sizeof(pkg), "%s/%s", basename(path), dentry->d_name); >+ atom = NULL; /* Will be exploded once at most, as needed. */ >+ >+ /* If exclude_pkg is not NULL, check it. We are looking for files >+ * collisions, and must exclude one package. >+ */ >+ if (args->exclude_pkg != NULL) { >+ if (strncmp(args->exclude_pkg, pkg, sizeof(pkg)) == 0) >+ goto check_pkg_slot; /* CAT/PF matches */ >+ if (strcmp(args->exclude_pkg, dentry->d_name) == 0) >+ goto check_pkg_slot; /* PF matches */ >+ if ((atom = atom_explode(pkg)) == NULL >+ || atom->PN == NULL || atom->CATEGORY == NULL) { >+ warn("invalid atom %s", pkg); >+ goto dont_skip_pkg; >+ } >+ snprintf(buf, sizeof(buf), "%s/%s", atom->CATEGORY, atom->PN); >+ if (strncmp(args->exclude_pkg, buf, sizeof(buf)) != 0 >+ && strcmp(args->exclude_pkg, atom->PN) != 0) >+ goto dont_skip_pkg; /* "(CAT/)?PN" doesn't match */ >+check_pkg_slot: /* Also compare slots, if any was specified */ >+ if (args->exclude_slot == NULL) { >+ if (atom != NULL) >+ atom_implode(atom); >+ continue; /* "(CAT/)?(PN|PF)" matches, and no SLOT specified */ >+ } >+ buf[0] = '0'; buf[1] = '\0'; >+ xasprintf(&p, "%s/%s/SLOT", path, dentry->d_name); >+ if ((fp = fopen(p, "r")) != NULL) { >+ free(p); >+ if (fgets(buf, sizeof(buf), fp) != NULL) >+ if ((p = strchr(buf, '\n')) != NULL) >+ *p = 0; >+ fclose(fp); >+ } else { >+ free(p); >+ } >+ if (strncmp(args->exclude_slot, buf, sizeof(buf)) == 0) { >+ if (atom != NULL) >+ atom_implode(atom); >+ continue; /* "(CAT/)?(PN|PF):SLOT" matches */ >+ } >+ } >+dont_skip_pkg: /* End of the package exclusion tests. */ >+ >+ xasprintf(&p, "%s/%s/CONTENTS", path, dentry->d_name); >+ if ((fp = fopen(p, "r")) == NULL) { >+ free(p); >+ if (atom != NULL) >+ atom_implode(atom); >+ continue; >+ } >+ free(p); >+ >+ while ((fgets(buf, sizeof(buf), fp)) != NULL) { >+ contents_entry *e; >+ e = contents_parse_line(buf); >+ if (!e) >+ continue; >+ >+ /* much faster than using basename(), since no need to strdup */ >+ if ((entry_basename = strrchr(e->name, '/')) == NULL) >+ continue; >+ entry_basename++; >+ >+ /* used to cut the number of strcmp() calls */ >+ bn_firstchar = entry_basename[0]; >+ >+ for (i = 0; i < args->length; i++) { >+ if (base_names[i] == NULL) >+ continue; >+ if (non_orphans != NULL && non_orphans[i]) >+ continue; >+ path_ok = (dir_names[i] == NULL && real_dir_names[i] == NULL); >+ >+ if (bn_firstchar != bn_firstchars[i] >+ || strcmp(entry_basename, base_names[i])) >+ continue; >+ >+ >+ if (!path_ok) { >+ /* check the full filepath ... */ >+ entry_dirname = xstrdup(e->name); >+ if ((p = strrchr(entry_dirname, '/')) == NULL) { >+ free(entry_dirname); >+ continue; >+ } >+ if (p == entry_dirname) >+ /* (e->name == "/foo") ==> dirname == "/" */ >+ *(p + 1) = '\0'; >+ else >+ *p = '\0'; >+ if (dir_names[i] != NULL && >+ strcmp(entry_dirname, dir_names[i]) == 0) >+ /* dir_name == dirname(CONTENTS) */ >+ path_ok = 1; >+ else if (real_dir_names[i] != NULL && >+ strcmp(entry_dirname, real_dir_names[i]) == 0) >+ /* real_dir_name == dirname(CONTENTS) */ >+ path_ok = 1; >+ else { >+ char rpath[_Q_PATH_MAX+1]; >+ char *fullpath = entry_dirname; >+ errno = 0; >+ if (real_root != NULL && real_root[0] != '\0') >+ xasprintf(&fullpath, "%s%s", real_root, entry_dirname); >+ realpath(fullpath, rpath); >+ if (errno != 0) { >+ if (verbose) { >+ warnp("Could not read real path of \"%s\" (from %s)", fullpath, pkg); >+ warn("We'll never know whether \"%s/%s\" was a result for your query...", >+ entry_dirname, entry_basename); >+ } >+ } else if (!qfile_is_prefix(rpath, real_root, strlen(real_root))) { >+ if (verbose) >+ warn("Real path of \"%s\" is not under ROOT: %s", fullpath, rpath); >+ } else if (dir_names[i] != NULL && >+ strcmp(rpath + strlen(real_root), dir_names[i]) == 0) >+ /* dir_name == realpath(dirname(CONTENTS)) */ >+ path_ok = 1; >+ else if (real_dir_names[i] != NULL && >+ strcmp(rpath + strlen(real_root), real_dir_names[i]) == 0) >+ /* real_dir_name == realpath(dirname(CONTENTS)) */ >+ path_ok = 1; >+ if (fullpath != entry_dirname) >+ free(fullpath); >+ } >+ free(entry_dirname); >+ } >+ if (!path_ok) >+ continue; >+ >+ if (non_orphans == NULL) { >+ if (atom == NULL && (atom = atom_explode(pkg)) == NULL) { >+ warn("invalid atom %s", pkg); >+ continue; >+ } >+ >+ printf("%s%s/%s%s%s", BOLD, atom->CATEGORY, BLUE, >+ (exact ? dentry->d_name : atom->PN), NORM); >+ if (quiet) >+ puts(""); >+ else if (root != NULL) >+ printf(" (%s%s)\n", root, e->name); >+ else >+ printf(" (%s)\n", e->name); >+ >+ } else { >+ non_orphans[i] = 1; >+ } >+ found++; >+ } >+ } >+ fclose(fp); >+ if (atom != NULL) >+ atom_implode(atom); >+ } >+ closedir(dir); >+ >+ return; >+} >+ >+qfile_args_t *create_qfile_args(); >+qfile_args_t *create_qfile_args() >+{ >+ qfile_args_t *qfile_args; >+ >+ qfile_args = xmalloc(sizeof(qfile_args_t)); >+ >+ memset(qfile_args, 0, sizeof(qfile_args_t)); >+ return qfile_args; >+} >+ >+void destroy_qfile_args(qfile_args_t *); >+void destroy_qfile_args(qfile_args_t *qfile_args) >+{ >+ int i; >+ >+ for (i = 0; i < qfile_args->length; ++i) { >+ if (qfile_args->basenames != NULL && qfile_args->basenames[i] != NULL) >+ free(qfile_args->basenames[i]); >+ if (qfile_args->dirnames != NULL && qfile_args->dirnames[i] != NULL) >+ free(qfile_args->dirnames[i]); >+ if (qfile_args->realdirnames != NULL && qfile_args->realdirnames[i] != NULL) >+ free(qfile_args->realdirnames[i]); >+ } >+ >+ if (qfile_args->basenames != NULL) >+ free(qfile_args->basenames); >+ if (qfile_args->dirnames != NULL) >+ free(qfile_args->dirnames); >+ if (qfile_args->realdirnames != NULL) >+ free(qfile_args->realdirnames); >+ >+ if (qfile_args->bn_firstchars != NULL) >+ free(qfile_args->bn_firstchars); >+ >+ if (qfile_args->non_orphans != NULL) >+ free(qfile_args->non_orphans); >+ >+ if (qfile_args->real_root != NULL) >+ free(qfile_args->real_root); >+ >+ if (qfile_args->exclude_pkg != NULL) >+ free(qfile_args->exclude_pkg); >+ /* don't free qfile_args->exclude_slot, it's the same chunk */ >+ >+ memset(qfile_args, 0, sizeof(qfile_args_t)); >+} >+ >+int prepare_qfile_args(const int, const char **, >+ const short, const short, const char *, qfile_args_t *); >+int prepare_qfile_args(const int argc, const char **argv, >+ const short assume_root_prefix, const short search_orphans, >+ const char *exclude_pkg_arg, qfile_args_t *qfile_args) >+{ >+ int i; >+ int nb_of_queries = argc; >+ char *pwd = NULL; >+ int real_root_length; >+ char *real_root = NULL; >+ char **basenames = NULL; >+ char **dirnames = NULL; >+ char **realdirnames = NULL; >+ char *basenames_firstchars = NULL; >+ char tmppath[_Q_PATH_MAX+1]; >+ char abspath[_Q_PATH_MAX+1]; >+ >+ /* Try to get $PWD. Must be absolute, with no trailing slash. */ >+ if ((pwd = getenv("PWD")) != NULL && pwd[0] == '/') { >+ pwd = xstrdup(pwd); >+ if ((pwd[strlen(pwd) - 1] == '/')) >+ pwd[strlen(pwd) - 1] = '\0'; >+ } else >+ pwd = NULL; >+ >+ /* Get realpath of $ROOT, with no trailing slash */ >+ if (portroot[0] == '/') >+ strncpy(tmppath, portroot, _Q_PATH_MAX); >+ else if (pwd != NULL) >+ snprintf(tmppath, _Q_PATH_MAX, "%s/%s", pwd, portroot); >+ else { >+ free(pwd); >+ warn("Could not get absolute path for ROOT (\"%s\"), because of missing or not absolute $PWD", tmppath); >+ return -1; >+ } >+ errno = 0; >+ realpath(tmppath, abspath); >+ if (errno != 0) { >+ free(pwd); >+ warnp("Could not read real path of ROOT (\"%s\")", tmppath); >+ return -1; >+ } >+ if (strlen(abspath) == 1) >+ abspath[0] = '\0'; >+ real_root = xstrdup(abspath); >+ real_root_length = strlen(real_root); >+ >+ /* For each argument, we store its basename, its absolute dirname, >+ * and the realpath of its dirname. Dirnames and their realpaths >+ * are stored without their $ROOT prefix, but $ROOT is used when >+ * checking realpaths. >+ */ >+ basenames = xcalloc(argc, sizeof(char*)); >+ dirnames = xcalloc(argc, sizeof(char*)); >+ realdirnames = xcalloc(argc, sizeof(char*)); >+ /* For optimization of qfile(), we also give it an array of the first char >+ * of each basename. This way we avoid numerous strcmp() calls. >+ */ >+ basenames_firstchars = xcalloc(argc, sizeof(char)); >+ >+ for (i = 0; i < argc; ++i) { >+ /* Record basename, but if it is ".", ".." or "/" */ >+ strncpy(abspath, argv[i], _Q_PATH_MAX); /* strncopy so that "argv" can be "const" */ >+ strncpy(tmppath, basename(abspath), _Q_PATH_MAX); >+ if ((strlen(tmppath) > 2) || >+ (strncmp(tmppath, "..", strlen(tmppath)) >+ && strncmp(tmppath, "/", strlen(tmppath)))) >+ { >+ basenames[i] = xstrdup(tmppath); >+ basenames_firstchars[i] = basenames[i][0]; >+ /* If there is no "/" in the argument, then it's over. >+ * (we are searching a simple file name) >+ */ >+ if (strchr(argv[i], '/') == NULL) >+ continue; >+ } >+ >+ /* Make sure we have an absolute path available (with "realpath(ROOT)" prefix) */ >+ if (argv[i][0] == '/') { >+ if (assume_root_prefix) >+ strncpy(abspath, argv[i], _Q_PATH_MAX); >+ else >+ snprintf(abspath, _Q_PATH_MAX, "%s%s", real_root, argv[i]); >+ } else if (pwd != NULL) { >+ if (assume_root_prefix) >+ snprintf(abspath, _Q_PATH_MAX, "%s/%s", pwd, argv[i]); >+ else >+ snprintf(abspath, _Q_PATH_MAX, "%s%s/%s", real_root, pwd, argv[i]); >+ } else { >+ warn("$PWD was not found in environment, or is not an absolute path"); >+ goto skip_query_item; >+ } >+ >+ if (basenames[i] != NULL) { >+ /* Get both the dirname and its realpath. This paths will >+ * have no trailing slash, but if it is the only char (ie., >+ * when searching for "/foobar"). >+ */ >+ strncpy(tmppath, abspath, _Q_PATH_MAX); >+ strncpy(abspath, dirname(tmppath), _Q_PATH_MAX); >+ if (abspath[real_root_length] == '\0') >+ strncat(abspath, "/", 1); >+ dirnames[i] = xstrdup(abspath + real_root_length); >+ errno = 0; >+ realpath(abspath, tmppath); >+ if (errno != 0) { >+ if (verbose) { >+ warnp("Could not read real path of \"%s\"", abspath); >+ warn("Results for query item \"%s\" may be inaccurate.", argv[i]); >+ } >+ continue; >+ } >+ if (!qfile_is_prefix(tmppath, real_root, real_root_length)) { >+ warn("Real path of \"%s\" is not under ROOT: %s", abspath, tmppath); >+ goto skip_query_item; >+ } >+ if (tmppath[real_root_length] == '\0') >+ strncat(tmppath, "/", 1); >+ if (strcmp(dirnames[i], tmppath + real_root_length)) >+ realdirnames[i] = xstrdup(tmppath + real_root_length); >+ } else { >+ /* No basename means we are looking for something like "/foo/bar/.." >+ * Dirname is meaningless here, we can only get realpath of the full >+ * path and then split it. >+ */ >+ errno = 0; >+ realpath(abspath, tmppath); >+ if (errno != 0) { >+ warnp("Could not read real path of \"%s\"", abspath); >+ goto skip_query_item; >+ } >+ if (!qfile_is_prefix(tmppath, real_root, real_root_length)) { >+ warn("Real path of \"%s\" is not under ROOT: %s", abspath, tmppath); >+ goto skip_query_item; >+ } >+ strncpy(abspath, tmppath, _Q_PATH_MAX); >+ basenames[i] = xstrdup(basename(abspath)); >+ basenames_firstchars[i] = basenames[i][0]; >+ strncpy(abspath, dirname(tmppath), _Q_PATH_MAX); >+ if (tmppath[real_root_length] == '\0') >+ strncat(tmppath, "/", 1); >+ realdirnames[i] = xstrdup(abspath + real_root_length); >+ } >+ continue; >+ >+ skip_query_item: >+ --nb_of_queries; >+ warn("Skipping query item \"%s\".", argv[i]); >+ if (basenames[i] != NULL) free(basenames[i]); >+ if (dirnames[i] != NULL) free(dirnames[i]); >+ if (realdirnames[i] != NULL) free(realdirnames[i]); >+ basenames[i] = dirnames[i] = realdirnames[i] = NULL; >+ } >+ >+ if (pwd != NULL) >+ free(pwd); >+ >+ qfile_args->real_root = real_root; >+ qfile_args->basenames = basenames; >+ qfile_args->dirnames = dirnames; >+ qfile_args->realdirnames = realdirnames; >+ qfile_args->bn_firstchars = basenames_firstchars; >+ qfile_args->length = argc; >+ >+ if (search_orphans) { >+ qfile_args->non_orphans = xcalloc(argc, sizeof(short)); >+ memset(qfile_args->non_orphans, 0, argc); >+ } >+ >+ if (exclude_pkg_arg != NULL) { >+ qfile_args->exclude_pkg = xstrdup(exclude_pkg_arg); >+ if ((qfile_args->exclude_slot = strchr(qfile_args->exclude_pkg, ':')) != NULL) >+ *qfile_args->exclude_slot++ = '\0'; >+ /* Maybe this should be atom-exploded instead (to check syntax, etc.) */ >+ } >+ >+ return nb_of_queries; >+} >+ >+int qfile_main(int argc, char **argv) >+{ >+ DIR *dir; >+ struct dirent *dentry; >+ int i, nb_of_queries; >+ char *p; >+ short search_orphans = 0; >+ short assume_root_prefix = 0; >+ char *root_prefix = NULL; >+ char *exclude_pkg_arg = NULL; >+ qfile_args_t *qfile_args = NULL; >+ int qargc = 0; >+ char **qargv = NULL; >+ short done = 0; >+ FILE *args_file = NULL; >+ int max_args = QFILE_DEFAULT_MAX_ARGS; >+ char path[_Q_PATH_MAX]; >+ >+ DBG("argc=%d argv[0]=%s argv[1]=%s", >+ argc, argv[0], argc > 1 ? argv[1] : "NULL?"); >+ >+ while ((i = GETOPT_LONG(QFILE, qfile, "")) != -1) { >+ switch (i) { >+ COMMON_GETOPTS_CASES(qfile) >+ case 'e': exact = 1; break; >+ case 'f': >+ if (args_file != NULL) { >+ warn("Don't use -f twice!"); >+ goto exit; >+ } >+ if (strcmp(optarg, "-") == 0) >+ args_file = stdin; >+ else if ((args_file = fopen(optarg, "r")) == NULL) { >+ warnp("%s", optarg); >+ goto exit; >+ } >+ break; >+ case 'm': >+ errno = 0; >+ max_args = strtol(optarg, &p, 10); >+ if (errno != 0) { >+ warnp("%s: not a valid integer", optarg); >+ goto exit; >+ } else if (p == optarg || *p != '\0') { >+ warn("%s: not a valid integer", optarg); >+ goto exit; >+ } >+ if (max_args <= 0 || max_args > QFILE_MAX_MAX_ARGS) { >+ warn("%s: silly value!", optarg); >+ goto exit; >+ } >+ break; >+ case 'o': search_orphans = 1; break; >+ case 'R': assume_root_prefix = 1; break; >+ case 'x': >+ if (exclude_pkg_arg != NULL) { >+ warn("--exclude can only be used once."); >+ goto exit; >+ } >+ exclude_pkg_arg = optarg; >+ break; >+ } >+ } >+ if (!exact && verbose) exact++; >+ if ((argc == optind) && (args_file == NULL)) >+ qfile_usage(EXIT_FAILURE); >+ >+ if ((args_file == NULL) && (max_args != QFILE_DEFAULT_MAX_ARGS)) >+ warn("--max-args is only used when reading arguments from a file (with -f)"); >+ >+ if (chdir(portroot)) { >+ warnp("could not chdir(%s) for ROOT", portroot); >+ goto exit; >+ } >+ >+ if (chdir(portvdb) != 0) { >+ warnp("could not chdir(ROOT/%s) for installed packages database", portvdb); >+ goto exit; >+ } >+ >+ /* Get a copy of $ROOT, with no trailing slash >+ * (this one is just for qfile(...) output) >+ */ >+ root_prefix = xstrdup(portroot); >+ if (root_prefix[strlen(root_prefix) - 1] == '/') >+ root_prefix[strlen(root_prefix) - 1] = '\0'; >+ >+ /* Are we using --from ? */ >+ if (args_file == NULL) { >+ qargc = argc - optind; >+ qargv = argv + optind; >+ done = 1; >+ } else { >+ qargv = xcalloc(max_args, sizeof(char*)); >+ } >+ >+ do { /* This block may be repeated if using --from with a big files list */ >+ if (args_file != NULL) { >+ qargc = 0; >+ /* Read up to max_args files from the input file */ >+ while ((fgets(path, _Q_PATH_MAX, args_file)) != NULL) { >+ if ((p = strchr(path, '\n')) != NULL) >+ *p = '\0'; >+ if (path == p) continue; >+ qargv[qargc] = xstrdup(path); >+ qargc++; >+ if (qargc >= max_args) break; >+ } >+ } >+ >+ if (qargc == 0) break; >+ >+ if (qfile_args == NULL) { /* qfile_args is allocated only once */ >+ if ((qfile_args = create_qfile_args()) == NULL) { >+ warn("Out of memory"); >+ goto exit; >+ } >+ } else { >+ destroy_qfile_args(qfile_args); >+ } >+ >+ /* Prepare the qfile(...) arguments structure */ >+ nb_of_queries = prepare_qfile_args(qargc, (const char **) qargv, >+ assume_root_prefix, search_orphans, exclude_pkg_arg, qfile_args); >+ 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); >+ 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); >+ qfile(path, (assume_root_prefix ? root_prefix : NULL), qfile_args); >+ } >+ >+ if (qfile_args->non_orphans != NULL) { >+ /* display orphan files */ >+ for (i = 0; i < qfile_args->length; i++) { >+ if (qfile_args->non_orphans[i]) >+ continue; >+ if (qfile_args->basenames[i] != NULL) { >+ found = 0; /* ~inverse return code (as soon as an orphan is found, return non-zero) */ >+ if (!quiet) >+ printf("%s\n", qargv[i]); >+ else break; >+ } >+ } >+ } >+ >+ if (args_file != NULL && qargv != NULL) { >+ for (i = 0; i < qargc; i++) { >+ if (qargv[i] != NULL) free(qargv[i]); >+ qargv[i] = NULL; >+ } >+ } >+ } while (args_file != NULL && qargc == max_args); >+ >+exit: >+ >+ if (args_file != NULL && qargv != NULL) { >+ for (i = 0; i < qargc; i++) >+ if (qargv[i] != NULL) free(qargv[i]); >+ free(qargv); >+ } >+ >+ if (args_file != NULL && args_file != stdin) >+ fclose(args_file); >+ >+ if (qfile_args != NULL) { >+ destroy_qfile_args(qfile_args); >+ free(qfile_args); >+ } >+ >+ if (root_prefix != NULL) >+ free(root_prefix); >+ >+ return (found ? EXIT_SUCCESS : EXIT_FAILURE); >+} >+ >+#else >+DEFINE_APPLET_STUB(qfile) >+#endif >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 <arg> 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 <arg> 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 - <solar@gentoo.org> > * Copyright 2005-2006 Mike Frysinger - <vapier@gentoo.org> >@@ -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 <arg> 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; f<NUM_SEARCH_FILES; ++f) >+ if (fp[f]) { >+ fclose(fp[f]); >+ fp[f] = NULL; >+ } > } >- } > >- for (f=0; f<NUM_SEARCH_FILES; ++f) >- if (fp[f] != NULL) >- fclose(fp[f]); >+ } while ((cur_overlay=cur_overlay->next)); > > /* 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<argc;i++) >+ if ((strstr(ebuild,argv[i]))) >+ break; >+ if (i==argc) >+ continue; >+ } >+ > if ((newfp = fopen(ebuild, "r")) != NULL) { > unsigned int lineno = 0; > char revision[sizeof(buf0)]; >@@ -376,15 +487,18 @@ 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); >- 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; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 154405
:
101420
|
101495
|
101520
|
101575
|
101690
|
101699
|
101723
|
101730
|
101779
|
101954
|
102433
|
102434
|
104816
|
107119
|
107120
|
107183
|
107184
|
107450