So far so good...
Since it's working here is the other patch: portage2paludis.patch
portage2paludis.patch

diff -Narup portage-utils-20070504.new/main.c portage-utils-20070504.NEW/main.c --- portage-utils-20070504.new/main.c 2007-05-04 09:15:46.696444231 +0200 +++ portage-utils-20070504.NEW/main.c 2007-05-04 09:24:49.602620490 +0200 @@ -70,6 +70,14 @@ static char eat_file(const char *file, c int rematch(const char *, const char *, int); static char *rmspace(char *); +typedef struct repository_conf repository_conf; +struct repository_conf { + char location[_Q_PATH_MAX]; + char format[32]; + char cache[_Q_PATH_MAX]; + char write_cache[_Q_PATH_MAX]; +}; + typedef struct overlay_t overlay_t; struct overlay_t { char name[64]; @@ -83,8 +91,7 @@ struct overlay_t { static overlay_t *first_overlay = NULL; void initialize_portage_env(void); -void initialize_overlays (char portdir_overlay[]); -void initialize_ebuild_flat(short force); +void initialize_overlays(repository_conf *default_conf); void reinitialize_ebuild_flat(short force); void reinitialize_as_needed(void); void cleanup(void); @@ -99,17 +106,16 @@ static int max_categories = 200; static char pretend = 0; static char reinitialize = 0; static char reinitialize_metacache = 0; -static char portarch[20] = ""; -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/"; +/* static char portarch[20] = ""; */ +static char portvdb[_Q_PATH_MAX] = ""; +static char cache_file_dir[_Q_PATH_MAX]="var/cache/paludis"; +static char metacache_file_dir[_Q_PATH_MAX]="var/cache/paludis/metadata"; +static char repocachedir[] = "metadata/cache"; +static char portroot[_Q_PATH_MAX] = ""; +/* static char config_protect[_Q_PATH_MAX] = "/etc/"; */ -/* temporary workaround ? */ -static overlay_t *overlay_gentoo = NULL; - -char pkgdir[512] = "/usr/portage/packages/"; -char port_tmpdir[512] = "/var/tmp/portage/"; +char pkgdir[512] = "/var/paludis/repositories/gentoo/packages/"; +char port_tmpdir[512] = "/var/tmp/paludis/"; char binhost[1024] = PORTAGE_BINHOST; char features[2048] = "noman noinfo nodoc"; @@ -231,7 +237,8 @@ static void version_barf(const char *Id) # define VERSION "cvs" #endif printf("portage-utils-%s: compiled on %s\n%s\n" - "%s written for Gentoo by <solar and vapier @ gentoo.org>\n", + "%s written for Gentoo by <solar and vapier @ gentoo.org>\n" + "modified for overlay and paludis compatibility by s a m u e l e t h i e c @ h o t m a i l . c o m \n", VERSION, __DATE__, Id, argv0); exit(EXIT_SUCCESS); } @@ -485,58 +492,173 @@ char *strincr_var(const char *name, char return (char *) value; } -void initialize_overlays (char portdir_overlay[]) +void initialize_overlays(repository_conf *default_conf) { - short merror = 0; - int i; - char buf[BUFSIZE], file[_Q_PATH_MAX], category[32], *s, *p, *t; - overlay_t *cur_overlay; - FILE *fp; - s = portdir_overlay; + short merror = 0, first = 1; + int i, j; + char *s, *p, *t; + char buf[BUFSIZE], file[_Q_PATH_MAX], confdir[_Q_PATH_MAX], path[_Q_PATH_MAX]; + repository_conf repo_conf; + char category[32]; + FILE *CONFFILE, *fp; + DIR *CONFDIR; + struct dirent *f; + struct stat statcache; + overlay_t *cur_overlay; + + struct { + const char *name; + const size_t name_len; + char *value; + const size_t value_len; + } vars_to_read[] = { + /* order is important */ + {"ROOT", 4, portroot, sizeof(portroot)}, + {"location", 8, repo_conf.location, sizeof(repo_conf.location)}, + {"write_cache", 11, repo_conf.write_cache, sizeof(repo_conf.write_cache)}, + {"cache", 5, repo_conf.cache, sizeof(repo_conf.cache)}, + {"format", 6, repo_conf.format, sizeof(repo_conf.format)} + }; first_overlay = xmalloc(sizeof(*first_overlay)); - cur_overlay = 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; + snprintf(confdir, sizeof(confdir), "%s/etc/paludis/repositories", portroot); + + if (NULL == (CONFDIR = opendir(confdir))) + err("%s : could not open directory", confdir); + + while ((f = readdir(CONFDIR))) { + repo_conf.location[0] = 0; + repo_conf.cache[0] = 0; + repo_conf.write_cache[0] = 0; + repo_conf.format[0] = 0; + + if (f->d_name[0] == '.') + continue; + + snprintf(file, sizeof(file), "%s/%s", confdir, f->d_name); + + if (NULL == (CONFFILE = fopen(file, "r"))) + continue; + merror = 0; + + while (fgets(buf, sizeof(buf), CONFFILE )) { + rmspace(buf); + if (*buf == '#' || *buf == '\0') + continue; + for (i=1; i<ARR_SIZE(vars_to_read); ++i) { + if (buf[vars_to_read[i].name_len] != '=' && buf[vars_to_read[i].name_len] != ' ') + continue; + if (strncmp(buf, vars_to_read[i].name, vars_to_read[i].name_len)) + continue; + + /* make sure we handle spaces between the varname, the =, and the value: + * VAR=val VAR = val VAR="val" + */ + s = buf + vars_to_read[i].name_len; + if ((p = strchr(s, '=')) != NULL) + s = p + 1; + while (isspace(*s)) + ++s; + if (*s == '"' || *s == '\'') { + ++s; + s[strlen(s)-1] = '\0'; + } + + strncpy(vars_to_read[i].value, s, vars_to_read[i].value_len); + } + } + fclose(CONFFILE); + + /* set non-yet defined variable to their default value if available (confdir/repsoritory_defaults.conf) */ + if (default_conf != NULL) { + if (!repo_conf.format[0] && default_conf->format[0]) + strncpy(repo_conf.format, default_conf->format, sizeof(repo_conf.format)); + if (repo_conf.cache[0]!=0 && default_conf->cache[0]) + strncpy(repo_conf.cache, default_conf->cache, sizeof(repo_conf.cache)); + if (!repo_conf.write_cache[0] && default_conf->write_cache[0]) + strncpy(repo_conf.write_cache, default_conf->write_cache, sizeof(repo_conf.write_cache)); } - cur_overlay->next = NULL; - if ((p=strchr(s,' '))) - *p = 0; + if (!repo_conf.format[0]) + continue; - snprintf(cur_overlay->path, sizeof(cur_overlay->path), "%s%s", (strcmp(portroot, "/") ? portroot : ""), s); + /* delete trailing '/' */ + for (i=0; i<ARR_SIZE(vars_to_read); ++i) { + if ((p = strrchr(vars_to_read[i].value, '/')) && (p+1) && *(p+1)==0) + *p = 0; + } - /* find the name for the overlay */ - snprintf(file, sizeof(file), "%s/profiles/repo_name", cur_overlay->path); - if ((fp = fopen(file, "r"))) { - if (!(fgets(buf, sizeof(buf),fp))) - merror++; - rmspace(buf); - if ((t = strchr(buf,'\n'))) - *t = 0; - strncpy(cur_overlay->name, buf, sizeof(cur_overlay->name)); + if (strncmp(repo_conf.format, "ebuild", sizeof(repo_conf.format)) && strncmp(repo_conf.format, "vdb", sizeof(repo_conf.format))) + continue; - fclose(fp); - } else - merror++; + /* if the path begins with a variable such as ${ROOT}, $ROOT, or $location and so on + * we try to replace it with its value */ + for (i=1; i<ARR_SIZE(vars_to_read); ++i) { + path[0] = 0; + if (vars_to_read[i].value[0] == '$') { + p = strchr(vars_to_read[i].value, '/'); + *p = 0; + + if (vars_to_read[i].value[1]=='{' && *(p-1)=='}') { + *(p-1) = 0; + s = &vars_to_read[i].value[2]; + } else + s = &vars_to_read[i].value[1]; + + for (j=0; j<ARR_SIZE(vars_to_read); ++j) + if (!strcmp(s, vars_to_read[j].name)) { + strcpy(path, vars_to_read[j].value); + break; + } - 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; + /* put the slash back */ + *p = '/'; + strncat(path, p, sizeof(path)); + strcpy(vars_to_read[i].value, path); + } } + /* vdb location defined in etc/paludis/repositories/installed.conf */ + if (!strcmp("installed.conf", f->d_name) && !strcmp("vdb", repo_conf.format)) { + strncpy(portvdb, repo_conf.location, sizeof(portvdb)); + continue; + } + + if (!first) { + cur_overlay->next = xmalloc(sizeof(*(cur_overlay->next))); + cur_overlay = cur_overlay->next; + } + cur_overlay->next = NULL; + cur_overlay->cache[0] = 0; + + /* time to search for the overlay->name */ + snprintf(file, sizeof(file), "%s/profiles/repo_name", repo_conf.location); + if (NULL != (fp = fopen(file, "r"))) { + if (!(fgets(buf, sizeof(buf),fp))) + merror++; + rmspace(buf); + if ((t = strchr(buf,'\n'))) + *t = 0; + + strncpy(cur_overlay->name, buf, sizeof(cur_overlay->name)); + fclose(fp); + } else { + strcpy(cur_overlay->name, "x-"); + /* there is no trailing '/' */ + if ((p=strrchr(repo_conf.location,'/'))) + p = p+1; + else + p = repo_conf.location; + strncat(cur_overlay->name, p, sizeof(cur_overlay->name)); + } + + strncpy(cur_overlay->path, repo_conf.location, sizeof(cur_overlay->path)); + /* now we test if overlay/profiles/categories exist, and if it does we fill cur_overlay->categories */ snprintf(file, sizeof(file), "%s/profiles/categories", cur_overlay->path); - if ((fp = fopen(file, "r"))) { + if ((fp = fopen(file, "r"))) { cur_overlay->categories = xmalloc(max_categories*sizeof(char *)); i = 0; while (i < max_categories && (fgets(category, sizeof(category), fp))) { @@ -555,35 +677,53 @@ void initialize_overlays (char portdir_o } else cur_overlay->categories = NULL; - /* if the gentoo overlay is found, then we make a pointer to it */ - 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 + /* now we fill cur_overlay->cache */ + /* here the behaviour differs a bit from paludis: we use the write_cache key if available */ + /* and if cache != /var/empty */ + if (!repo_conf.cache[0] && (strstr(repo_conf.write_cache, "/var/empty") || !repo_conf.write_cache[0]) ) + snprintf(repo_conf.cache, sizeof(repo_conf.cache), "%s/%s", cur_overlay->path, repocachedir); + + if (!strstr(repo_conf.cache, "/var/empty")) { + if (repo_conf.cache[0] && stat(repo_conf.cache, &statcache) != -1 && S_ISDIR(statcache.st_mode)) + strcpy(cur_overlay->cache, repo_conf.cache); + else { + if (repo_conf.write_cache[0]) { + snprintf(repo_conf.cache, sizeof(repo_conf.cache), "%s/%s", repo_conf.write_cache, cur_overlay->name); + if (stat(repo_conf.cache, &statcache) != -1 && S_ISDIR(statcache.st_mode)) + strncpy(cur_overlay->cache, repo_conf.cache, sizeof(cur_overlay->cache)); + else + strncpy(cur_overlay->cache, "/var/empty", sizeof(cur_overlay->cache)); + } else + strncpy(cur_overlay->cache, "/var/empty", sizeof(cur_overlay->cache)); + } + } else strcpy(cur_overlay->cache, "/var/empty"); - if (p) - s = p+1; /* because portdir_overlay has no trailing space */ - else - break; + /* once we get there we have at least done with the first overlay */ + if (first) + first = 0; } - + closedir(CONFDIR); } - void initialize_portage_env(void) { char nocolor = 0; - int i, f; - struct stat st; + int i,f; + char tmp[_Q_PATH_MAX], repository_def_file[_Q_PATH_MAX]; + repository_conf *default_conf = xmalloc(sizeof *default_conf); FILE *fp; - char tmp_portdir[_Q_PATH_MAX]; char buf[BUFSIZE], *s, *p; +/* + struct stat st; + char tmp_portdir[_Q_PATH_MAX]; 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"}; +*/ + const char *files[] = {"portage_file", repository_def_file}; typedef enum { _Q_BOOL, _Q_STR, _Q_ISTR } var_types; struct { @@ -593,7 +733,7 @@ void initialize_portage_env(void) char *value; const size_t value_len; } vars_to_read[] = { - {"ACCEPT_LICENSE", 14, _Q_STR, accept_license, sizeof(accept_license)}, +/* {"ACCEPT_LICENSE", 14, _Q_STR, accept_license, sizeof(accept_license)}, {"INSTALL_MASK", 12, _Q_ISTR, install_mask, sizeof(install_mask)}, {"ARCH", 4, _Q_STR, portarch, sizeof(portarch)}, {"CONFIG_PROTECT", 14, _Q_STR, config_protect, sizeof(config_protect)}, @@ -605,12 +745,22 @@ void initialize_portage_env(void) {"PORTAGE_TMPDIR", 14, _Q_STR, port_tmpdir, sizeof(port_tmpdir)}, {"PKGDIR", 6, _Q_STR, pkgdir, sizeof(pkgdir)}, {"ROOT", 4, _Q_STR, portroot, sizeof(portroot)} +*/ + {"format", 6, _Q_STR, default_conf->format, sizeof(default_conf->format)}, + {"cache", 5, _Q_STR, default_conf->cache, sizeof(default_conf->cache)}, + {"write_cache", 11,_Q_STR, default_conf->write_cache, sizeof(default_conf->write_cache)} }; - if ((p = strchr(portroot, '/')) != NULL) - if (strlen(p) != 1) - strncat(portroot, "/", sizeof(portroot)); + default_conf->format[0] = 0; + default_conf->cache[0] = 0; + default_conf->write_cache[0] = 0; + + if ((s = getenv("ROOT"))) + strncpy(portroot, s, sizeof(portroot)); + else + portroot[0] = 0; +/* f = 0; if (readlink("/etc/make.profile", profile, sizeof(profile)) == -1) strcpy(profile, "/etc/make.profile"); @@ -618,10 +768,16 @@ void initialize_portage_env(void) memmove(profile+5, profile, strlen(profile)); memcpy(profile, "/etc/", 5); } +*/ + f=1; do { + /* if (f == 0) snprintf(portage_file, sizeof(portage_file), "%s/make.defaults", profile); IF_DEBUG(fprintf(stderr, "profile %s\n", files[f])); + */ + if (f == 1) + snprintf(repository_def_file, sizeof(repository_def_file), "%s/%s", portroot, "etc/paludis/repository_defaults.conf"); if ((fp=fopen(files[f], "r")) != NULL) { while (fgets(buf, sizeof(buf), fp) != NULL) { @@ -655,6 +811,9 @@ void initialize_portage_env(void) } } fclose(fp); + } else { + free(default_conf); + default_conf = NULL; } if (f > 0) { @@ -664,6 +823,7 @@ void initialize_portage_env(void) break; } +#if 0 /* everything below here is to figure out what the next parent is */ snprintf(portage_file, sizeof(portage_file), "%s/parent", profile); if (stat(portage_file, &st) == 0) { @@ -674,42 +834,23 @@ void initialize_portage_env(void) } else { f = 1; } +#endif } while (1); - /* finally, check the env */ - for (i=0; i<ARR_SIZE(vars_to_read); ++i) { - s = getenv(vars_to_read[i].name); - if (s != NULL) { - switch (vars_to_read[i].type) { - case _Q_BOOL: *vars_to_read[i].value = 1; break; - case _Q_STR: strncpy(vars_to_read[i].value, s, vars_to_read[i].value_len); break; - case _Q_ISTR: strincr_var(vars_to_read[i].name, s, vars_to_read[i].value, vars_to_read[i].value_len); break; - } - } - if (getenv("DEBUG") IF_DEBUG(|| 1)) { - fprintf(stderr, "%s = ", vars_to_read[i].name); - switch (vars_to_read[i].type) { - case _Q_BOOL: fprintf(stderr, "%i\n", *vars_to_read[i].value); break; - case _Q_STR: - case _Q_ISTR: fprintf(stderr, "%s\n", vars_to_read[i].value); break; - } - } - } - if (getenv("PORTAGE_QUIET") != NULL) - quiet = 1; - if (nocolor) no_colors(); else color_remap(); - /* we add the gentoo repository in the overlay list */ - strincr_var("PORTDIR_OVERLAY", tmp_portdir, portdir_overlay, sizeof(portdir_overlay)); - snprintf(tmp_portdir, sizeof(tmp_portdir), "%s/%s", (strcmp(portroot, "/") ? portroot : ""), portvdb); - strncpy(portvdb, tmp_portdir, sizeof(portvdb)); + snprintf(tmp,sizeof(tmp),"%s/%s", portroot, cache_file_dir); + strcpy(cache_file_dir, tmp); + snprintf(tmp,sizeof(tmp),"%s/%s", portroot, metacache_file_dir); + strcpy(metacache_file_dir, tmp); /* now we initialiase the overlay chained list */ - initialize_overlays(portdir_overlay); + initialize_overlays(default_conf); + if (default_conf) + free(default_conf); } @@ -747,19 +888,19 @@ const char *initialize_flat(int cache_ty cache_file = (cache_type == CACHE_EBUILD ? CACHE_EBUILD_FILE : CACHE_METADATA_FILE); - if (cache_type == CACHE_METADATA) { + if (cache_type == CACHE_METADATA) { /* if it's full path no need to chdir */ if (CACHE_METADATA_FILE[0] != '/' ) { - if (chdir(overlay_gentoo->cache) != 0) { - warnp("chdir to portage cache '%s' failed", overlay_gentoo->cache); + if (chdir(metacache_file_dir) != 0) { + warnp("chdir to cache '%s' failed", metacache_file_dir); goto ret; } } - } else { + } else { /* if it's full path no need to chdir */ if (CACHE_EBUILD_FILE[0] != '/' ) { - if (chdir(overlay_gentoo->path) != 0) { - warnp("chdir to PORTDIR '%s' failed", overlay_gentoo->path); + if (chdir(cache_file_dir) != 0) { + warnp("chdir to '%s' failed", cache_file_dir); goto ret; } } @@ -777,13 +918,13 @@ const char *initialize_flat(int cache_ty unlink(cache_file); if (errno != ENOENT) { - warnfp("unlinking '%s/%s' failed", (cache_type == CACHE_EBUILD ? overlay_gentoo->path : overlay_gentoo->cache), cache_file); + warnfp("unlinking '%s/%s' failed", (cache_type == CACHE_EBUILD ? cache_file_dir : metacache_file_dir), cache_file); warn("define CACHE_METADATA_FILE and/or CACHE_EBUILD_FILE to use different cache file"); goto ret; } if ((fp = fopen(cache_file, "w")) == NULL) { - warnfp("opening '%s/%s' failed", (cache_type == CACHE_EBUILD ? overlay_gentoo->path : overlay_gentoo->cache), cache_file); + warnfp("opening '%s/%s' failed", (cache_type == CACHE_EBUILD ? cache_file_dir : metacache_file_dir), cache_file); goto ret; } @@ -854,6 +995,7 @@ const char *initialize_flat(int cache_ty continue; break; } + if ((e = scandir(de, &eb, filter_hidden, alphasort)) < 0) continue; for (d = 0; d < e; d++) { @@ -1096,7 +1238,7 @@ char *grab_vdb_item(const char *item, co char *p; FILE *fp; - snprintf(buf, sizeof(buf), "%s%s/%s/%s/%s", portroot, portvdb, CATEGORY, PF, item); + snprintf(buf, sizeof(buf), "%s/%s/%s/%s", portvdb, CATEGORY, PF, item); if ((fp = fopen(buf, "r")) == NULL) return NULL; fgets(buf, sizeof(buf), fp); @@ -1127,9 +1269,6 @@ queue *get_vdb_atoms(void) assert(chdir(savecwd) == 0); - if (chdir(portroot) != 0) - goto fuckit; - if (chdir(portvdb) != 0) goto fuckit; diff -Narup portage-utils-20070504.new/man/qlop.1 portage-utils-20070504.NEW/man/qlop.1 --- portage-utils-20070504.new/man/qlop.1 2007-05-04 09:05:37.422392807 +0200 +++ portage-utils-20070504.NEW/man/qlop.1 2007-05-04 09:24:49.612618964 +0200 @@ -5,7 +5,7 @@ qlop \- emerge log analyzer .B qlop \fI<pkgname>\fR .SH DESCRIPTION -Options: \fB\-[gtluscf:F:HvqChV]\fR +Options: \fB\-[gtluso:cf\fR:F:HvqChV] .TP \fB\-g\fR, \fB\-\-gauge\fR * Gauge number of times a package has been merged @@ -25,6 +25,11 @@ Options: \fB\-[gtluscf:F:HvqChV]\fR \fB\-s\fR, \fB\-\-sync\fR * Show sync history .TP +\fB\-o\fR, \fB\-\-overlay\fR +<arg> +.BR +* Only consider the <arg> overlay +.TP \fB\-c\fR, \fB\-\-current\fR * Show current emerging packages .TP diff -Narup portage-utils-20070504.new/qfile.c portage-utils-20070504.NEW/qfile.c --- portage-utils-20070504.new/qfile.c 2007-05-04 09:05:54.589773816 +0200 +++ portage-utils-20070504.NEW/qfile.c 2007-05-04 09:24:49.620617744 +0200 @@ -541,11 +541,6 @@ int qfile_main(int argc, char **argv) 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; diff -Narup portage-utils-20070504.new/qlist.c portage-utils-20070504.NEW/qlist.c --- portage-utils-20070504.new/qlist.c 2007-05-04 09:05:37.420393112 +0200 +++ portage-utils-20070504.NEW/qlist.c 2007-05-04 09:24:49.629616371 +0200 @@ -137,6 +137,7 @@ int qlist_main(int argc, char **argv) char qlist_all = 0, just_pkgname = 0, dups_only = 0; char show_dir, show_obj, show_sym, show_slots, show_umap; struct dirent **de, **cat; + char overlay[64]; char buf[_Q_PATH_MAX]; char swap[_Q_PATH_MAX]; queue *sets = NULL; @@ -146,6 +147,7 @@ int qlist_main(int argc, char **argv) argc, argv[0], argc > 1 ? argv[1] : "NULL?"); show_dir = show_obj = show_sym = show_slots = show_umap = 0; + overlay[0] = 0; while ((i = GETOPT_LONG(QLIST, qlist, "")) != -1) { switch (i) { @@ -168,12 +170,8 @@ int qlist_main(int argc, char **argv) if ((argc == optind) && (!just_pkgname)) qlist_usage(EXIT_FAILURE); - if (chdir(portroot)) - errp("could not chdir(%s) for ROOT", portroot); - if (chdir(portvdb) != 0) - return EXIT_FAILURE; - + errp("could not chdir(%s) for VDB", portvdb); if ((dfd = scandir(".", &cat, filter_hidden, alphasort)) < 0) return EXIT_FAILURE; @@ -223,6 +221,9 @@ int qlist_main(int argc, char **argv) if ((i == argc) && (argc != optind)) continue; + if (verbose>1) + snprintf(overlay, sizeof(overlay), "::%s",grab_vdb_item("REPOSITORY", cat[j]->d_name, de[x]->d_name)); + if (just_pkgname) { if (dups_only) { pkgname = atom_explode(de[x]->d_name); @@ -242,9 +243,10 @@ int qlist_main(int argc, char **argv) slot = grab_vdb_item("SLOT", cat[j]->d_name, de[x]->d_name); /* display it */ - printf("%s%s/%s%s%s%s%s%s%s", BOLD, cat[j]->d_name, BLUE, + printf("%s%s/%s%s%s%s%s%s%s%s%s", BOLD, cat[j]->d_name, BLUE, (pkgname ? pkgname->PN : de[x]->d_name), NORM, - YELLOW, slot ? " ": "", slot ? slot : "", NORM); + YELLOW, overlay, + RED, slot ? " ": "", slot ? slot : "", NORM); puts(umapstr(show_umap, cat[j]->d_name, de[x]->d_name)); } if (pkgname) @@ -254,7 +256,7 @@ int qlist_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, cat[j]->d_name, de[x]->d_name); if (verbose > 1) @@ -312,9 +314,10 @@ int qlist_main(int argc, char **argv) char *slot = NULL; if (show_slots) slot = (char *) grab_vdb_item("SLOT", (const char *) atom->CATEGORY, (const char *) atom->P); - printf("%s%s/%s%s%s%s%s%s%s", BOLD, atom->CATEGORY, BLUE, + printf("%s%s/%s%s%s%s%s%s%s%s%s", BOLD, atom->CATEGORY, BLUE, (verbose ? atom->P : atom->PN), NORM, - YELLOW, slot ? " " : "", slot ? slot : "", NORM); + YELLOW, overlay, + RED, slot ? " " : "", slot ? slot : "", NORM); puts(umapstr(show_umap, atom->CATEGORY, atom->P)); } atom_implode(atom); diff -Narup portage-utils-20070504.new/qlop.c portage-utils-20070504.NEW/qlop.c --- portage-utils-20070504.new/qlop.c 2007-05-04 09:05:37.420393112 +0200 +++ portage-utils-20070504.NEW/qlop.c 2007-05-04 09:26:16.063430351 +0200 @@ -21,29 +21,35 @@ # include <sys/time.h> #endif -#define QLOP_DEFAULT_LOGFILE "/var/log/emerge.log" +#define QLOP_DEFAULT_LOGFILE "/var/log/paludis.log" -#define QLOP_FLAGS "gtluscf:F:H" COMMON_FLAGS +#define QLOP_FLAGS "egtpluso:cf:F:H" COMMON_FLAGS static struct option const qlop_long_opts[] = { + {"estimate", no_argument, NULL, 'e'}, {"gauge", no_argument, NULL, 'g'}, {"time", no_argument, NULL, 't'}, + {"pipe", no_argument, NULL, 'p'}, {"human", no_argument, NULL, 'H'}, {"list", no_argument, NULL, 'l'}, {"unlist", no_argument, NULL, 'u'}, {"sync", no_argument, NULL, 's'}, + {"overlay", a_argument, NULL, 'o'}, {"current", no_argument, NULL, 'c'}, {"logfile", a_argument, NULL, 'f'}, COMMON_LONG_OPTS }; static const char *qlop_opts_help[] = { + "with -t, estimate the time ignoring the version", "Gauge number of times a package has been merged", "Calculate merge time for a specific package", + "Pipe the output ouf paludis -ip to estimate building time ", "Print seconds in human readable format (needs -t)", "Show merge history", "Show unmerge history", "Show sync history", + "Do only consider the <arg> repository", "Show current emerging packages", "Read emerge logfile instead of " QLOP_DEFAULT_LOGFILE, COMMON_OPTS_HELP @@ -79,38 +85,49 @@ static const char *chop_ctime(time_t t) return ctime_out; } -unsigned long show_merge_times(char *package, const char *logfile, int average, char human_readable); -unsigned long show_merge_times(char *package, const char *logfile, int average, char human_readable) +unsigned long show_merge_times(char *package, const short repo, const char repo_search[], const char *logfile, int average, char human_readable, char estimate, char internal_call, int *not_found_counter); +unsigned long show_merge_times(char *package, const short repo, const char repo_search[], const char *logfile, int average, char human_readable, char estimate, char internal_call, int *not_found_counter) { FILE *fp; - char cat[126], buf[2][BUFSIZ]; - char *pkg, *p; + char catPN[BUFSIZ], catPNVo[BUFSIZ], buf[2][BUFSIZ], matched; + char *p, *q; unsigned long count, merge_time; time_t t[2]; - depend_atom *atom; + depend_atom *atom,*search; + int l; + long pos; t[0] = t[1] = 0UL; count = merge_time = 0; - cat[0] = 0; + matched = 0; + pos = 0; - if ((p = strchr(package, '/')) != NULL) { - pkg = p + 1; - strncpy(cat, package, sizeof(cat)); - if ((p = strchr(cat, '/')) != NULL) - *p = 0; - } else { - pkg = package; - } + if ((search = atom_explode(package)) == NULL ) + err("%s is not a valid atom", package); + if (!search->CATEGORY && !search->PN && !search->OVERLAY) + err("You need to specify at least an overlay, a category, or a package name"); - DBG("Searching for %s in %s\n", pkg, logfile); + DBG("Searching for %s in %s\n", package, logfile); if ((fp = fopen(logfile, "r")) == NULL) { warnp("Could not open logfile '%s'", logfile); - return 1; + /* merge time = 0 */ + return 0; } while ((fgets(buf[0], sizeof(buf[0]), fp)) != NULL) { - if (strstr(buf[0], pkg) == NULL) + if (matched) { + matched = 0; + continue; + } + /* len( time:{starting,finished} install of package ) = 41 */ + if (search->CATEGORY && !strstr(&buf[0][40], search->CATEGORY)) + continue; + + if (search->PN && !strstr(&buf[0][40], search->PN)) + continue; + + if (!estimate && search->OVERLAY && !strstr(&buf[0][40], search->OVERLAY)) continue; if ((p = strchr(buf[0], '\n')) != NULL) @@ -121,80 +138,155 @@ unsigned long show_merge_times(char *pac t[0] = atol(buf[0]); strcpy(buf[1], p + 1); rmspace(buf[1]); - if ((strncmp(buf[1], ">>> emerge (", 12)) == 0) { - char matched = 0; - if ((p = strchr(buf[1], ')')) == NULL) + if ((strncmp(buf[1], "starting install of package", 26)) == 0) { + p = &buf[1][28]; + if (repo && !strstr(p, repo_search)) continue; - *p = 0; - strcpy(buf[0], p + 1); - rmspace(buf[0]); - if ((p = strchr(buf[0], ' ')) == NULL) + + if ((q = strchr(p, ' ')) == NULL) continue; - *p = 0; + *q = 0; + + strcpy(buf[0], p); + rmspace(buf[0]); if ((atom = atom_explode(buf[0])) == NULL) continue; - if (*cat) { - if ((strcmp(cat, atom->CATEGORY) == 0) && (strcmp(pkg, atom->PN) == 0)) - matched = 1; - } else if (strcmp(pkg, atom->PN) == 0) - matched = 1; + if (search->CATEGORY && strcmp(atom->CATEGORY, search->CATEGORY)) { + atom_implode(atom); + continue; + } + + if (search->PN && *search->PN && strcmp(atom->PN, search->PN)) { + atom_implode(atom); + continue; + } + + if (!estimate) { + if (search->PV && strcmp(atom->PV, search->PV)) { + atom_implode(atom); + continue; + } + if (search->PR_int && atom->PR_int!=search->PR_int) { + atom_implode(atom); + continue; + } + if (search->OVERLAY && strcmp(atom->OVERLAY, search->OVERLAY)) { + atom_implode(atom); + continue; + } + } + + pos = ftell(fp); + matched = 1; if (matched) { - while ((fgets(buf[0], sizeof(buf[0]), fp)) != NULL) { - if ((p = strchr(buf[0], '\n')) != NULL) - *p = 0; - if ((p = strchr(buf[0], ':')) == NULL) + /* In case of simultaneous install, we search the corresponding */ + /* "finished install of package" pkg up to 25 lines after the 'starting line' */ + l=0; + snprintf(catPN, sizeof(catPN), "%s/%s", atom->CATEGORY, atom->PN); + snprintf(catPNVo, sizeof(catPNVo), "%s/%s-%s::%s", atom->CATEGORY, atom->PN, (atom->PR_int ? atom->PVR : atom->PV), atom->OVERLAY); + while ((fgets(buf[0], sizeof(buf[0]), fp)) != NULL && l++ < 25) { + if ((p = strchr(buf[0],':')) == NULL) + continue; + p = p+2; + if ((q = strchr(buf[0], '\n')) != NULL) + *q = 0; + + /* delete an eventual (n of N) */ + if ((q=strchr(p+28, ' '))) + *q = 0; + + /* Stop the search in case the package is already being reinstalled even in a different version/revision/overlay */ + if (!strncmp(p, "starting install", 16) && (q=strstr(p+28, catPN)) && q == (p+28)) + break; + + if (strncmp(p, "finished install of package", 26) != 0) + continue; + if (strcmp(p+28, catPNVo)) continue; - *p = 0; + + if ((p = strchr(buf[0], ':')) == NULL) + *p = 0; t[1] = atol(buf[0]); strcpy(buf[1], p + 1); rmspace(buf[1]); - if (*buf[1] == '*') - break; - if ((strncmp(buf[1], "::: completed emerge (", 22)) == 0) { - if (!average) { - strcpy(buf[1], ""); - if (verbose) { - if (atom->PR_int) - snprintf(buf[1], sizeof(buf[1]), "-%s-r%i", atom->PV, atom->PR_int); - else - snprintf(buf[1], sizeof(buf[1]), "-%s", atom->PV); - } - printf("%s%s%s%s: %s: ", BLUE, atom->PN, buf[1], NORM, chop_ctime(t[0])); - if (human_readable) - print_seconds_for_earthlings(t[1] - t[0]); - else - printf("%s%lu%s seconds", GREEN, (t[1] - t[0]), NORM); - puts(""); - } - merge_time += (t[1] - t[0]); - count++; - break; + + if (!average) { + strcpy(buf[1], ""); + if (verbose) + snprintf(buf[1], sizeof(buf[1]), "-%s%s::%s ", (atom->PR_int ? atom->PVR : atom->PV), YELLOW, atom->OVERLAY); + + printf("%s%s/%s%s%s%s: %s: ", GREEN, atom->CATEGORY, BLUE, atom->PN, buf[1], NORM, chop_ctime(t[0])); + if (human_readable) + print_seconds_for_earthlings(t[1] - t[0]); + else + printf("%s%lu%s seconds", GREEN, (t[1] - t[0]), NORM); + puts(""); } + merge_time += (t[1] - t[0]); + count++; + break; + } } atom_implode(atom); + /* time to go back where we were */ + fseek(fp, pos, SEEK_SET); } } fclose(fp); - if (count == 0) + if (count == 0) { + if (!quiet && !internal_call) + fprintf(stderr,"%s : not found\n", package); + if (not_found_counter != NULL) + *not_found_counter += 1; + + /* merge_time = 0 */ return 0; + } + + /* if show_merge_times is called by show_current, then this is all we need */ + if (internal_call) + return merge_time/count; + + printf("%s%s%s%s%s", GREEN, (search->CATEGORY ? search->CATEGORY : ""), (search->CATEGORY ? "/": ""), + BLUE, (search->PN ? search->PN : "")); + if (!estimate) + printf("%s%s%s%s%s", (search->PV ? "-" : ""), (search->PV ? (search->PR_int ? search->PVR : search->PV) : ""), + YELLOW, (search->OVERLAY ? "::" : ""), (search->OVERLAY ? search->OVERLAY : "")); + printf("%s : ", NORM); + if (average == 1) { - printf("%s%s%s: ", BLUE, pkg, NORM); if (human_readable) print_seconds_for_earthlings(merge_time / count); else - printf("%s%lu%s seconds average", GREEN, merge_time / count, NORM); - printf(" for %s%lu%s merges\n", GREEN, count, NORM); + printf("%s%lu%s seconds", GREEN, merge_time / count, NORM); + printf(" average for %s%lu%s merges%s", GREEN, count, NORM, (verbose>1 ? ", for a total time of " : "")); + + if (verbose>1) { + if (human_readable) + print_seconds_for_earthlings(merge_time); + else + printf("%s%lu%s seconds", GREEN, merge_time, NORM); + } + fputc('\n', stdout); } else { - printf("%s%s%s: %s%lu%s times\n", BLUE, pkg, NORM, GREEN, count, NORM); + printf("%s%lu%s times%s", GREEN, count, NORM, (verbose>1 ? ", for a total time of " : "")); + if (verbose>1) { + if (human_readable) + print_seconds_for_earthlings(merge_time); + else + printf("%s%lu%s seconds", GREEN, merge_time, NORM); + } + fputc('\n', stdout); } - return 0; + atom_implode(search); + return merge_time/count; } -void show_emerge_history(char listflag, int argc, char **argv, const char *logfile); -void show_emerge_history(char listflag, int argc, char **argv, const char *logfile) +void show_emerge_history(char listflag, const short repo, const char repo_search[], int argc, char **argv, const char *logfile); +void show_emerge_history(char listflag, const short repo, const char repo_search[], int argc, char **argv, const char *logfile) { FILE *fp; char buf[BUFSIZ], merged; @@ -222,23 +314,30 @@ void show_emerge_history(char listflag, if ((p = strchr(buf, ':')) == NULL) continue; *p = 0; - q = p + 3; + q = p + 2; t = (time_t) atol(buf); - if ((listflag & QLOP_LIST) && !strncmp(q, "::: completed emerge (", 22)) { + if ((listflag & QLOP_LIST) && !strncmp(q, "finished install of package", 25)) { merged = 1; - if ((p = strchr(q, ')')) == NULL) - continue; - q = p + 2; + p = strstr(q, "package"); + q = p + 1; if ((p = strchr(q, ' ')) == NULL) continue; - *p = 0; - } else if ((listflag & QLOP_UNLIST) && !strncmp(q, ">>> unmerge success: ", 21)) { + q = p + 1; + if (repo) { + if ((p = strstr(q, "::")) && strncmp(p+2, repo_search, sizeof(repo_search))) + continue; + } + } else if ((listflag & QLOP_UNLIST) && !strncmp(q, "finished uninstall of package", 29)) { merged = 0; - if ((p = strchr(q, ':')) == NULL) + p = strstr(q, "package"); + q = p + 1; + if ((p = strchr(q, ' ')) == NULL) continue; - q = p + 2; + q = p + 1; + if ((p = strchr(p, ':')) != NULL) + *p = 0; } else continue; @@ -258,8 +357,8 @@ void show_emerge_history(char listflag, fclose(fp); } -void show_sync_history(const char *logfile); -void show_sync_history(const char *logfile) +void show_sync_history(const char *logfile, const short repo, char repo_search[]); +void show_sync_history(const char *logfile, const short repo, char repo_search[]) { FILE *fp; char buf[BUFSIZ]; @@ -274,7 +373,10 @@ void show_sync_history(const char *logfi while ((fgets(buf, sizeof(buf), fp)) != NULL) { if (strlen(buf) < 35) continue; - if (strncmp(buf+12, "=== Sync completed with", 23) != 0) + if (strncmp(buf+12, "finished sync", 13) != 0) + continue; + + if (repo && strstr(buf, repo_search) == NULL) continue; if ((p = strchr(buf, '\n')) != NULL) @@ -282,32 +384,35 @@ void show_sync_history(const char *logfi if ((p = strchr(buf, ':')) == NULL) continue; *p = 0; - q = p+2; + q = p+1; t = (time_t)atol(buf); - if ((p = strstr(q, "with")) == NULL) + if ((p = strstr(q, "repository")) == NULL) continue; - q = p + 5; + q = p + 11; printf("%s >>> %s%s%s\n", chop_ctime(t), GREEN, q, NORM); } fclose(fp); } -void show_current_emerge(void); +void show_current_emerge(const char *logfile); #ifdef __linux__ -void show_current_emerge(void) +void show_current_emerge(const char *logfile) { DIR *proc; struct dirent *de; pid_t pid; + int pgid; char buf[BUFSIZE], bufstat[300]; char path[50]; - char *p, *q; + char *p, *q, *cat, *pnv; unsigned long long start_time = 0; + unsigned long avg_build_time = 0; double uptime_secs; time_t start_date; + overlay_t *overlay_tmp; if ((proc = opendir("/proc")) == NULL) { warnp("Could not open /proc"); @@ -319,15 +424,41 @@ void show_current_emerge(void) if ((pid = (pid_t)atol(de->d_name)) == 0) continue; - /* portage renames the cmdline so the package name is first */ snprintf(path, sizeof(path), "/proc/%i/cmdline", pid); if (!eat_file(path, buf, sizeof(buf))) continue; - if (buf[0] == '[' && (p = strchr(buf, ']')) != NULL && strstr(buf, "sandbox") != NULL) { - *p = '\0'; - p = buf+1; - q = p + strlen(p) + 1; + if (! strncmp(buf, "sandbox", 7)) { + /* 0123456789012345678 */ + if (!(p = strstr(&buf[8],"paludis/ebuild.bash"))) + continue; + + q = p + 20; + if (*q != '/') + continue; + + /* + * ex: /var/paludis/repositories/local/category/package_name/package_name_version.ebuild + * expected: + * q cat 0 pnv + */ + if (q == (pnv=strrchr(q, '/'))) + continue; + *pnv = 0; + pnv++; + if (q == (cat=strrchr(q, '/'))) + continue; + *cat = 0; + if (q == (cat=strrchr(q, '/'))) + continue; + *cat = 0; + cat++; + overlay_tmp=first_overlay; + do { + if (!strcmp(q, overlay_tmp->path)) + break; + } while ((overlay_tmp=overlay_tmp->next)); + /* overlay_tmp is NULL if not found, */ /* open the stat file to figure out how long we have been running */ snprintf(path, sizeof(path), "/proc/%i/stat", pid); @@ -337,17 +468,17 @@ void show_current_emerge(void) /* ripped from procps/proc/readproc.c */ if ((q = strchr(bufstat, ')')) == NULL) continue; - /* grab the start time */ + /* grab the start time and the pgid */ sscanf(q + 2, "%*c " - "%*d %*d %*d %*d %*d " + "%*d %d %*d %*d %*d " "%*u %*u %*u %*u %*u " "%*u %*u %*u %*u " "%*d %*d " "%*d " "%*d " "%Lu ", - &start_time); + &pgid, &start_time); /* get uptime */ if (!eat_file("/proc/uptime", bufstat, sizeof(bufstat))) continue; @@ -355,21 +486,71 @@ void show_current_emerge(void) /* figure out when this thing started and then show it */ start_date = time(0) - (uptime_secs - (start_time / HZ)); + sprintf(buf, "%s/%s", cat, pnv); printf( - " %s*%s %s%s%s\n" + " %s*%s %s%s::%s%s\n" " started: %s%s%s\n" " elapsed: ", /*%s%llu%s seconds\n",*/ - BOLD, NORM, BLUE, p, NORM, + BOLD, BLUE, buf, YELLOW, (overlay_tmp ? overlay_tmp->name : "Unknown-overlay"), NORM, GREEN, chop_ctime(start_date), NORM); print_seconds_for_earthlings(uptime_secs - (start_time / HZ)); + printf( "\n avg build time: "); + avg_build_time = show_merge_times(buf, 0, "", logfile, 1, 0, 1, 1, NULL); + if (avg_build_time) + print_seconds_for_earthlings(avg_build_time); + else + printf("not available"); puts(NORM); + if (verbose) { + FILE *fp; + int i=0, not_found_counter=0; + unsigned long totaltime = 0; + + snprintf(path, sizeof(path), "/var/tmp/%d-paludis-resume", pgid); + if (NULL == (fp = fopen(path, "r"))) + continue; + while ((fgets(buf, sizeof(buf), fp))) { + if ((p = strchr(buf, '\n'))) + *p = 0; + /* Checking if we have something that looks like an atom: cat/pkg::overlay */ + if (!strchr(buf,'/') || !strstr(buf,"::")) + continue; + if (verbose > 1) + printf(" %s*%s %s\n", RED, NORM, buf); + totaltime+=show_merge_times(buf, 0, "", logfile, 1, 0, 1, 1, &not_found_counter); + i++; + } + printf(" estimated time left: "); + if (totaltime == 0) + printf("infomation not found "); + else { + if (totaltime < (uptime_secs - (start_time / HZ))) + totaltime=0; + else + totaltime -= (uptime_secs - (start_time / HZ)); + if (totaltime == 0) + printf("should end at any time now"); + else + print_seconds_for_earthlings(totaltime); + } + if (i>1) + printf(" (%d packages)", i); + putc('\n', stdout); + + if (verbose > 1 && i>1) { + if (not_found_counter >= 1) + printf(" Missing time info for %s%d%s package%s\n", RED, not_found_counter, NORM,(not_found_counter>1 ? "s" : "")); + } + } + + } } closedir(proc); if (start_time == 0 && verbose) - puts("No emerge processes located"); + puts("No paludis processes located"); } #elif defined(__FreeBSD__) void show_current_emerge(void) @@ -380,6 +561,10 @@ void show_current_emerge(void) char *p, *q; time_t start_date = 0; + /* this would need to be written for paludis, but I don't really know *BSD */ + warn("You need to adapt the show_current_emerge(void) function for __FreeBSD__\n" + "this may be trivial, just do as in the __linux__ one, but as I can't test it, I didn't make it"); + if (! (kd = kvm_open("/dev/null", "/dev/null", "/dev/null", O_RDONLY, "kvm_open"))) { warnp("Could not open kvm: %s", kvm_geterr(kd)); return; @@ -430,25 +615,40 @@ void show_current_emerge(void) int qlop_main(int argc, char **argv) { - int i, average = 1; - char do_time, do_list, do_unlist, do_sync, do_current, do_human_readable = 0; - char *opt_logfile; + int i, average = 1, not_found_counter = 0; + unsigned long totaltime = 0; + char do_time, do_list, do_unlist, do_sync, do_current, do_estimation = 0, do_human_readable = 0, internal_call = 0, do_pipe = 0; + char *opt_logfile, *p, *q; + short repo; + char repo_search[64], buf[BUFSIZ]; const char *logfile = QLOP_DEFAULT_LOGFILE; + overlay_t *overlay_tmp; DBG("argc=%d argv[0]=%s argv[1]=%s", argc, argv[0], argc > 1 ? argv[1] : "NULL?"); opt_logfile = NULL; + repo = 0; + repo_search[0] = 0; do_time = do_list = do_unlist = do_sync = do_current = 0; while ((i = GETOPT_LONG(QLOP, qlop, "")) != -1) { switch (i) { COMMON_GETOPTS_CASES(qlop) + case 'e': do_estimation = 1; break; case 't': do_time = 1; break; + case 'p': do_pipe = do_estimation = do_time = 1; verbose+=1; break; case 'l': do_list = 1; break; case 'u': do_unlist = 1; break; - case 's': do_sync = 1; break; + case 's': + if (do_sync) err("Only use -s or -S once"); + do_sync = 1; + break; + case 'o': + repo = 1; + strncpy(repo_search, optarg, sizeof(repo_search)); + break; case 'c': do_current = 1; break; case 'g': do_time = 1; average = 0; break; case 'H': do_human_readable = 1; break; @@ -458,6 +658,16 @@ int qlop_main(int argc, char **argv) break; } } + if (repo) { + overlay_tmp = first_overlay; + do { + if (!strncmp(overlay_tmp->name, repo_search, sizeof(overlay_tmp->name))) + break; + } while ((overlay_tmp=overlay_tmp->next)); + if (NULL == overlay_tmp) + err("%s : Unknown overlay, try 'q --ls-overlays'", repo_search); + } + if (!do_list && !do_unlist && !do_time && !do_sync && !do_current) qlop_usage(EXIT_FAILURE); if (opt_logfile != NULL) @@ -467,19 +677,61 @@ int qlop_main(int argc, char **argv) argv += optind; if (do_list && do_unlist) - show_emerge_history(QLOP_LIST | QLOP_UNLIST, argc, argv, logfile); + show_emerge_history(QLOP_LIST | QLOP_UNLIST, repo, repo_search,argc, argv, logfile); else if (do_list) - show_emerge_history(QLOP_LIST, argc, argv, logfile); + show_emerge_history(QLOP_LIST, repo, repo_search, argc, argv, logfile); else if (do_unlist) - show_emerge_history(QLOP_UNLIST, argc, argv, logfile); + show_emerge_history(QLOP_UNLIST, repo, repo_search, argc, argv, logfile); if (do_current) - show_current_emerge(); + show_current_emerge(logfile); if (do_sync) - show_sync_history(logfile); + show_sync_history(logfile, repo, repo_search); if (do_time) { - for (i = 0; i < argc; ++i) - show_merge_times(argv[i], logfile, average, do_human_readable); + if (do_pipe) { + FILE *fp = stdin; + if (fp != NULL) { + i = 0; + while ((fgets(buf, sizeof(buf), fp))) { + if ((p = strchr(buf, '\n'))) + *p = 0; + /* in paludis -ip pkg, only lines beginning with '* ' contain cat/pkg::overlay + * we can ignore others */ + if (buf[0] != '*' || buf[1] != ' ') + continue; + p = buf +2; + if (*p == 0 || NULL == (q = strchr(p,' '))) + continue; + *q = 0; + /* Checking if we have something that looks like an atom: cat/pkg::overlay */ + if (!strchr(p,'/') || !strstr(p,"::")) + continue; + totaltime+=show_merge_times(p, repo, repo_search, logfile, average, do_human_readable, do_estimation, internal_call, &not_found_counter); + i++; + } + } + } else { + for (i = 0; i < argc; ++i) + totaltime+=show_merge_times(argv[i], repo, repo_search, logfile, average, do_human_readable, do_estimation, internal_call, &not_found_counter); + } + if ((do_pipe && i>1) || argc>1) { + fprintf(stdout,"Total estimated time: "); + if (totaltime == 0) + printf("infomation not found "); + else { + if (do_human_readable) + print_seconds_for_earthlings(totaltime); + else + printf("%s%lu%s seconds", GREEN, totaltime, NORM); + } + printf(" (%d packages)", (do_pipe ? i : argc)); + fputc('\n', stdout); + + if (verbose > 1) { + if (not_found_counter >= 1) + printf("Missing time info for %s%d%s package%s\n", RED, not_found_counter, NORM,(not_found_counter>1 ? "s" : "")); + } + } } if (opt_logfile) free(opt_logfile); @@ -490,3 +742,5 @@ int qlop_main(int argc, char **argv) #else DEFINE_APPLET_STUB(qlop) #endif +/* vim: set noet sts=8 sw=8 : */ + diff -Narup portage-utils-20070504.new/qpkg.c portage-utils-20070504.NEW/qpkg.c --- portage-utils-20070504.new/qpkg.c 2007-05-04 09:05:37.421392960 +0200 +++ portage-utils-20070504.NEW/qpkg.c 2007-05-04 09:24:49.646613778 +0200 @@ -150,8 +150,8 @@ int qpkg_main(int argc, char **argv) if (argc == optind) qpkg_usage(EXIT_FAILURE); - if (chdir(portroot)) - errp("could not chdir(%s) for ROOT", portroot); + if (chdir((strlen(portroot) ? portroot : "/"))) + errp("could not chdir(%s) for ROOT", (strlen(portroot) ? portroot : "/")); /* setup temp dirs */ i = 0; diff -Narup portage-utils-20070504.new/qsize.c portage-utils-20070504.NEW/qsize.c --- portage-utils-20070504.new/qsize.c 2007-05-04 09:05:37.421392960 +0200 +++ portage-utils-20070504.NEW/qsize.c 2007-05-04 09:24:49.654612558 +0200 @@ -68,10 +68,10 @@ int qsize_main(int argc, char **argv) if ((argc == optind) && !search_all) qsize_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; num_all_bytes = num_all_files = num_all_nonfiles = 0; @@ -91,9 +91,9 @@ int qsize_main(int argc, char **argv) /* see if this cat/pkg is requested */ if (!search_all) { + snprintf(buf, sizeof(buf), "%s/%s::%s", dentry->d_name, + de->d_name, grab_vdb_item("REPOSITORY", dentry->d_name, de->d_name)); for (i = optind; i < argc; ++i) { - snprintf(buf, sizeof(buf), "%s/%s", dentry->d_name, - de->d_name); if (rematch(argv[i], buf, REG_EXTENDED) == 0) break; if (rematch(argv[i], de->d_name, REG_EXTENDED) == 0) @@ -103,7 +103,7 @@ int qsize_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; @@ -128,8 +128,9 @@ int qsize_main(int argc, char **argv) num_all_files += num_files; num_all_nonfiles += num_nonfiles; if (!summary_only) { - printf("%s%s/%s%s%s: %lu files, %lu non-files, ", BOLD, - basename(dentry->d_name), BLUE, de->d_name, NORM, + printf("%s%s/%s%s%s::%s%s : %lu files, %lu non-files, ", BOLD, + basename(dentry->d_name), BLUE, de->d_name, + YELLOW, grab_vdb_item("REPOSITORY", dentry->d_name, de->d_name), NORM, (unsigned long)num_files, (unsigned long)num_nonfiles); if (disp_units) diff -Narup portage-utils-20070504.new/quse.c portage-utils-20070504.NEW/quse.c --- portage-utils-20070504.new/quse.c 2007-05-04 09:17:01.518029728 +0200 +++ portage-utils-20070504.NEW/quse.c 2007-05-04 09:24:49.655612405 +0200 @@ -282,7 +282,7 @@ int quse_main(int argc, char **argv) if (argc == optind && !quse_all && idx >= 0) { if (idx == 3) - free((char *)search_vars[idx]); + free((char *) search_vars[idx]); quse_usage(EXIT_FAILURE); }