From: "Fabian Groffen" <grobian@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/portage-utils:master commit in: /
Date: Thu, 25 Apr 2019 09:22:11 +0000 (UTC) [thread overview]
Message-ID: <1555780746.86d662abd0216a49a6c2abee915e64d5c649cef2.grobian@gentoo> (raw)
commit: 86d662abd0216a49a6c2abee915e64d5c649cef2
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sat Apr 20 17:19:06 2019 +0000
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sat Apr 20 17:19:06 2019 +0000
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=86d662ab
qcache: rewrite to use new libq/cache
This fixes qcache for Prefix and no longer needs q's cache files.
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
qcache.c | 1012 ++++++++++++++++++++++++--------------------------------------
1 file changed, 396 insertions(+), 616 deletions(-)
diff --git a/qcache.c b/qcache.c
index f3252d7..7c5ae42 100644
--- a/qcache.c
+++ b/qcache.c
@@ -2,7 +2,8 @@
* Copyright 2005-2019 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
- * Copyright 2006 Thomas A. Cort - <tcort@gentoo.org>
+ * Copyright 2006 Thomas A. Cort - <tcort@gentoo.org>
+ * Copyright 2019- Fabian Groffen - <grobian@gentoo.org>
*/
#include "main.h"
@@ -52,42 +53,24 @@ static const char * const qcache_opts_help[] = {
};
#define qcache_usage(ret) usage(ret, QCACHE_FLAGS, qcache_long_opts, qcache_opts_help, NULL, lookup_applet_idx("qcache"))
-/********************************************************************/
-/* Structs */
-/********************************************************************/
-
typedef struct {
- const char *overlay;
- const char *category;
- const char *package;
- const char *ebuild;
- portage_cache *cache_data;
- unsigned char cur;
- unsigned char num;
+ depend_atom *qatom;
+ depend_atom *lastatom;
+ int *keywordsbuf;
+ size_t keywordsbuflen;
+ const char *arch;
+ cache_pkg_cb *runfunc;
} qcache_data;
-/********************************************************************/
-/* Global Variables */
-/********************************************************************/
-
-static set *archs;
-static char **archlist;
-static int archlist_count;
+static set *archs = NULL;
+static char **archlist = NULL;
+static size_t archlist_count;
static size_t arch_longest_len;
const char status[3] = {'-', '~', '+'};
-int qcache_skip, qcache_test_arch;
-char *qcache_matchpkg = NULL, *qcache_matchcat = NULL;
-
-/********************************************************************/
-/* Enumerations */
-/********************************************************************/
+int qcache_test_arch = 0;
enum { none = 0, testing, stable, minus };
-/********************************************************************/
-/* Keyword functions */
-/********************************************************************/
-
/*
* int decode_status(char c);
*
@@ -109,8 +92,6 @@ decode_status(char c)
}
/*
- * int decode_arch(const char *arch);
- *
* Decode the architecture string
*
* IN:
@@ -138,8 +119,6 @@ decode_arch(const char *arch)
}
/*
- * void print_keywords(char *category, char *ebuild, int *keywords);
- *
* Prints the keywords to stdout
*
* IN:
@@ -150,31 +129,24 @@ static void
print_keywords(const char *category, const char *ebuild, int *keywords)
{
char **arch = archlist;
- int a;
- char *package;
+ size_t a;
- package = xstrdup(ebuild);
- package[strlen(ebuild)-7] = '\0';
-
- printf("%s%s/%s%s%s ", BOLD, category, BLUE, package, NORM);
+ printf("%s%s/%s%s%s ", BOLD, category, BLUE, ebuild, NORM);
for (a = 0; a < archlist_count; a++) {
switch (keywords[a]) {
case stable:
printf("%s%c%s%s ", GREEN, status[keywords[a]], arch[a], NORM);
break;
case testing:
- printf("%s%c%s%s ", YELLOW, status[keywords[a]], arch[0], NORM);
+ printf("%s%c%s%s ", YELLOW, status[keywords[a]], arch[a], NORM);
break;
}
}
printf("\n");
- free(package);
}
/*
- * int read_keywords(char *s, int *keywords);
- *
* Read the KEYWORDS string and decode the values
*
* IN:
@@ -188,7 +160,8 @@ read_keywords(char *s, int *keywords)
{
char *arch, delim[2] = { ' ', '\0' };
size_t slen;
- int a;
+ size_t a;
+ int i;
if (!s)
return -1;
@@ -206,138 +179,18 @@ read_keywords(char *s, int *keywords)
arch = strtok(s, delim);
do {
- a = decode_arch(arch);
- if (a == -1)
+ i = decode_arch(arch);
+ if (i == -1)
continue;
- keywords[a] = decode_status(arch[0]);
+ keywords[i] = decode_status(arch[0]);
} while ((arch = strtok(NULL, delim)));
return 0;
}
/*
- * portage_cache *qcache_read_cache_file(const char *file);
- *
- * Read a file from the edb cache and store data in portage_cache.
- *
- * IN:
- * const char *filename - cache file to read
- * OUT:
- * portage_cache *pkg - cache data
- * ERR:
- * NULL is returned when an error occurs.
- */
-static portage_cache *
-qcache_read_cache_file(const char *filename)
-{
- struct stat s;
- char *buf;
- FILE *f;
- portage_cache *ret = NULL;
- int linelen;
- size_t len, buflen;
-
- if ((f = fopen(filename, "r")) == NULL)
- goto err;
-
- if (fstat(fileno(f), &s) != 0) {
- fclose(f);
- goto err;
- }
-
- buf = NULL;
- len = sizeof(*ret) + s.st_size + 1;
- ret = xzalloc(len);
-
- while ((linelen = getline(&buf, &buflen, f)) >= 0) {
- rmspace_len(buf, (size_t)linelen);
-
- if (strncmp(buf, "DEPEND=", 7) == 0)
- ret->DEPEND = xstrdup(buf + 7);
-
- if (strncmp(buf, "DESCRIPTION=", 12) == 0)
- ret->DESCRIPTION = xstrdup(buf + 12);
-
- if (strncmp(buf, "HOMEPAGE=", 9) == 0)
- ret->HOMEPAGE = xstrdup(buf + 9);
-
- if (strncmp(buf, "INHERITED=", 10) == 0)
- ret->INHERITED = xstrdup(buf + 10);
-
- if (strncmp(buf, "IUSE=", 4) == 0)
- ret->IUSE = xstrdup(buf + 4);
-
- if (strncmp(buf, "KEYWORDS=", 9) == 0)
- ret->KEYWORDS = xstrdup(buf + 9);
-
- if (strncmp(buf, "LICENSE=", 8) == 0)
- ret->LICENSE = xstrdup(buf + 8);
-
- if (strncmp(buf, "PDEPEND=", 8) == 0)
- ret->PDEPEND = xstrdup(buf + 8);
-
- if (strncmp(buf, "PROVIDE=", 8) == 0)
- ret->PROVIDE = xstrdup(buf + 8);
-
- if (strncmp(buf, "RDEPEND=", 8) == 0)
- ret->RDEPEND = xstrdup(buf + 8);
-
- if (strncmp(buf, "RESTRICT=", 9) == 0)
- ret->RESTRICT = xstrdup(buf + 9);
-
- if (strncmp(buf, "SLOT=", 5) == 0)
- ret->SLOT = xstrdup(buf + 5);
-
- if (strncmp(buf, "SRC_URI=", 8) == 0)
- ret->SRC_URI = xstrdup(buf + 8);
- }
-
- free(buf);
- ret->atom = atom_explode(filename);
- fclose(f);
-
- return ret;
-
- err:
- if (ret)
- cache_free(ret);
- return NULL;
-}
-
-/*
- * void qcache_free_data(portage_cache *cache);
- *
- * free()'s a portage_cache
- *
- * IN:
- * portage_cache *cache - the portage_cache to be free()'d
- */
-static void
-qcache_free_data(portage_cache *cache)
-{
- int i;
- char **c;
-
- if (!cache)
- errf("Cache is empty !");
-
- for (i = 0, c = (char**) cache; i < 15; i++)
- if (c[i])
- free(c[i]);
-
- atom_implode(cache->atom);
- free(cache);
-}
-
-/********************************************************************/
-/* Comparison functions */
-/********************************************************************/
-
-/*
- * int qcache_vercmp(const void *x, const void *y);
- *
* Compare 2 struct dirent d_name strings based with atom_compare_str().
- * Used with dirscan() to sort ebuild filenames by version.
+ * Used with dirscan() to sort ebuild filenames by version, reversed.
*
* IN:
* 2 (const struct dirent **) with d_name filled in
@@ -350,357 +203,163 @@ static int
qcache_vercmp(const struct dirent **x, const struct dirent **y)
{
switch (atom_compare_str((*x)->d_name, (*y)->d_name)) {
- case NEWER: return -1;
- case OLDER: return 1;
- default: return 0;
- }
-}
-
-/********************************************************************/
-/* Selection functions */
-/********************************************************************/
-
-/*
- * int qcache_file_select(const struct dirent *entry);
- *
- * Selects filenames that do not begin with '.' and are not name "metadata.xml"
- * or that file matches ".cpickle"
- *
- * IN:
- * const struct dirent *entry - entry to check
- * OUT:
- * int - 0 if filename begins with '.' or is "metadata.xml", otherwise 1
- */
-static int
-qcache_file_select(const struct dirent *entry)
-{
- return !(entry->d_name[0] == '.' ||
- (strcmp(entry->d_name, "metadata.xml") == 0) ||
- (strstr(entry->d_name, ".cpickle") != 0));
-}
-
-/*
- * int qcache_ebuild_select(const struct dirent *entry);
- *
- * Select filenames that end in ".ebuild"
- *
- * IN:
- * const struct dirent *entry - entry to check
- * OUT:
- * int - 1 if the filename ends in ".ebuild", otherwise 0
- */
-static int
-qcache_ebuild_select(const struct dirent *entry)
-{
- return ((strlen(entry->d_name) > 7) &&
- !strcmp(entry->d_name+strlen(entry->d_name)-7, ".ebuild"));
-}
-
-/********************************************************************/
-/* Traversal function */
-/********************************************************************/
-
-static void qcache_load_arches(const char *overlay);
-
-/*
- * int qcache_traverse(void (*func)(qcache_data*));
- *
- * visit every version of every package of every category in the tree
- *
- * IN:
- * void (*func)(qcache_data*) - function to call
- * OUT:
- * int - 0 on success.
- * ERR:
- * exit or return -1 on failure.
- */
-static int
-qcache_traverse_overlay(void (*func)(qcache_data*), const char *overlay)
-{
- qcache_data data = {
- .overlay = overlay,
- };
- char *catpath, *pkgpath, *ebuildpath, *cachepath;
- int i, j, k, len, num_cat, num_pkg, num_ebuild;
- struct dirent **categories, **packages, **ebuilds;
-
- xasprintf(&catpath, "%s/metadata/md5-cache", overlay);
-
- if (-1 == (num_cat = scandir(catpath, &categories,
- qcache_file_select, alphasort)))
- {
- errp("%s", catpath);
- free(catpath);
+ case EQUAL: return 0;
+ case NEWER: return -1;
+ case OLDER: return 1;
+ default: return strcmp((*x)->d_name, (*y)->d_name);
}
-
- if (!num_cat)
- warn("%s is empty!", catpath);
-
- /* traverse categories */
- for (i = 0; i < num_cat; i++) {
- xasprintf(&pkgpath, "%s/%s", overlay, categories[i]->d_name);
-
- if (-1 == (num_pkg = scandir(pkgpath, &packages,
- qcache_file_select, alphasort)))
- {
- if (errno != ENOENT)
- warnp("Found a cache dir, but unable to process %s", pkgpath);
- free(categories[i]);
- free(pkgpath);
- continue;
- }
-
- if (qcache_matchcat) {
- if (strcmp(categories[i]->d_name, qcache_matchcat) != 0) {
- scandir_free(packages, num_pkg);
- free(categories[i]);
- free(pkgpath);
- continue;
- }
- }
-
- /* traverse packages */
- for (j = 0; j < num_pkg; j++) {
- xasprintf(&ebuildpath, "%s/%s/%s",
- overlay, categories[i]->d_name, packages[j]->d_name);
-
- if (-1 == (num_ebuild = scandir(ebuildpath, &ebuilds,
- qcache_ebuild_select, qcache_vercmp)))
- {
- /* Do not complain about spurious files */
- if (errno != ENOTDIR)
- warnp("%s", ebuildpath);
- free(packages[j]);
- free(ebuildpath);
- continue;
- }
-
- if (qcache_matchpkg) {
- if (strcmp(packages[j]->d_name, qcache_matchpkg) != 0) {
- scandir_free(ebuilds, num_ebuild);
- free(packages[j]);
- free(ebuildpath);
- continue;
- }
- }
-
- qcache_skip = 0;
-
- /* traverse ebuilds */
- data.num = num_ebuild;
- for (k = 0; k < num_ebuild; k++) {
- len = xasprintf(&cachepath, "%s/%s/%s",
- catpath, categories[i]->d_name, ebuilds[k]->d_name);
- cachepath[len - 7] = '\0'; /* remove ".ebuild" */
-
- data.category = categories[i]->d_name;
- data.package = packages[j]->d_name;
- data.ebuild = ebuilds[k]->d_name;
- data.cur = k + 1;
- data.cache_data = qcache_read_cache_file(cachepath);
-
- if (data.cache_data != NULL) {
- if (!qcache_skip)
- func(&data);
-
- qcache_free_data(data.cache_data);
- } else {
- static bool warned = false;
- if (!warned) {
- warned = true;
- warnp("unable to read cache '%s'\n"
- "\tperhaps you need to `egencache`?", cachepath);
- }
- }
-
- free(ebuilds[k]);
- free(cachepath);
- }
-
- free(packages[j]);
- free(ebuilds);
- free(ebuildpath);
- }
-
- free(categories[i]);
- free(packages);
- free(pkgpath);
- }
-
- free(categories);
- free(catpath);
-
- return 0;
}
static int
-qcache_traverse(void (*func)(qcache_data*))
+qcache_imlate(cache_pkg_ctx *pkg_ctx, void *priv)
{
- int ret;
- size_t n;
- const char *overlay;
+ size_t a;
+ qcache_data *data = (qcache_data *)priv;
- /* Preload all the arches. Not entirely correctly (as arches are bound
- * to overlays if set), but oh well. */
- array_for_each(overlays, n, overlay)
- qcache_load_arches(overlay);
-
- ret = 0;
- array_for_each(overlays, n, overlay)
- ret |= qcache_traverse_overlay(func, overlay);
-
- func(NULL);
-
- return ret;
-}
-
-/********************************************************************/
-/* functors */
-/********************************************************************/
-
-static void
-qcache_imlate(qcache_data *data)
-{
- int *keywords;
- int a;
-
- if (!data)
- return;
-
- keywords = xmalloc(sizeof(*keywords) * archlist_count);
-
- if (read_keywords(data->cache_data->KEYWORDS, keywords) < 0) {
- if (verbose)
- warn("Failed to read keywords for %s%s/%s%s%s",
- BOLD, data->category, BLUE, data->ebuild, NORM);
- free(keywords);
- return;
- }
-
- switch (keywords[qcache_test_arch]) {
+ switch (data->keywordsbuf[qcache_test_arch]) {
case stable:
- qcache_skip = 1;
case none:
case minus:
break;
default:
- for (a = 0; a < archlist_count && !qcache_skip; ++a) {
- if (keywords[a] != stable)
+ /* match if any of the other arches have stable keywords */
+ for (a = 0; a < archlist_count; a++) {
+ if (data->keywordsbuf[a] != stable)
continue;
- qcache_skip = 1;
- print_keywords(data->category, data->ebuild, keywords);
+ print_keywords(pkg_ctx->cat_ctx->name, pkg_ctx->name,
+ data->keywordsbuf);
+
+ return EXIT_SUCCESS;
}
}
- free(keywords);
+
+ return EXIT_FAILURE;
}
-static void
-qcache_not(qcache_data *data)
+static int
+qcache_not(cache_pkg_ctx *pkg_ctx, void *priv)
{
- int *keywords;
-
- if (!data)
- return;
+ qcache_data *data = (qcache_data *)priv;
- keywords = xmalloc(sizeof(*keywords) * archlist_count);
-
- if (read_keywords(data->cache_data->KEYWORDS, keywords) < 0) {
- if (verbose)
- warn("Failed to read keywords for %s%s/%s%s%s",
- BOLD, data->category, BLUE, data->ebuild, NORM);
- free(keywords);
- return;
- }
-
- if (keywords[qcache_test_arch] == testing ||
- keywords[qcache_test_arch] == stable)
+ if (data->keywordsbuf[qcache_test_arch] != testing &&
+ data->keywordsbuf[qcache_test_arch] != stable)
{
- qcache_skip = 1;
- } else if (data->cur == data->num) {
- printf("%s%s/%s%s%s\n", BOLD, data->category, BLUE,
- data->package, NORM);
+ print_keywords(pkg_ctx->cat_ctx->name, pkg_ctx->name,
+ data->keywordsbuf);
+ return EXIT_SUCCESS;
}
- free(keywords);
+ return EXIT_FAILURE;
}
-static void
-qcache_all(qcache_data *data)
+static int
+qcache_all(cache_pkg_ctx *pkg_ctx, void *priv)
{
- int *keywords;
-
- if (!data)
- return;
-
- keywords = xmalloc(sizeof(*keywords) * archlist_count);
-
- if (read_keywords(data->cache_data->KEYWORDS, keywords) < 0) {
- if (verbose)
- warn("Failed to read keywords for %s%s/%s%s%s",
- BOLD, data->category, BLUE, data->ebuild, NORM);
- free(keywords);
- return;
- }
+ qcache_data *data = (qcache_data *)priv;
- if (keywords[qcache_test_arch] == stable ||
- keywords[qcache_test_arch] == testing)
+ if (data->keywordsbuf[qcache_test_arch] == stable ||
+ data->keywordsbuf[qcache_test_arch] == testing)
{
- qcache_skip = 1;
- printf("%s%s/%s%s%s\n", BOLD, data->category, BLUE,
- data->package, NORM);
+ print_keywords(pkg_ctx->cat_ctx->name, pkg_ctx->name,
+ data->keywordsbuf);
+ return EXIT_SUCCESS;
}
- free(keywords);
+ return EXIT_FAILURE;
}
-static void
-qcache_dropped(qcache_data *data)
+static int
+qcache_dropped(cache_pkg_ctx *pkg_ctx, void *priv)
{
- static int possible = 0;
- int *keywords, i;
-
- if (!data)
- return;
-
- if (data->cur == 1)
- possible = 0;
-
- keywords = xmalloc(sizeof(*keywords) * archlist_count);
-
- if (read_keywords(data->cache_data->KEYWORDS, keywords) < 0) {
- if (verbose)
- warn("Failed to read keywords for %s%s/%s%s%s",
- BOLD, data->category, BLUE, data->ebuild, NORM);
- free(keywords);
- return;
+ static bool candidate = false;
+ static char pkg1[_Q_PATH_MAX];
+ static char pkg2[_Q_PATH_MAX];
+ static char *lastpkg = pkg1;
+ static char *curpkg = pkg2;
+ static char candpkg[_Q_PATH_MAX];
+ static int *candkwds = NULL;
+ static size_t candkwdslen = 0;
+
+ qcache_data *data = (qcache_data *)priv;
+ size_t i;
+ char *p;
+
+ /* a keyword is "dropped", if:
+ * - the keyword is present (stable or testing) in earlier ebuilds
+ * - there are other stable or testing keywords in the ebuild being
+ * evaluated
+ * - the keyword is absent, thus not explicitly removed -keyword */
+
+ /* mutt-1.10.4: amd64
+ * mutt-1.11.1: amd64 ppc64
+ * mutt-1.15.1: amd64 <-- this ebuild for ppc64
+ * mutt-9999: */
+
+ p = lastpkg;
+ lastpkg = curpkg;
+ curpkg = p;
+ if (pkg_ctx != NULL) {
+ snprintf(curpkg, _Q_PATH_MAX, "%s/%s",
+ pkg_ctx->cat_ctx->name, pkg_ctx->name);
+ } else {
+ curpkg[0] = '\0';
}
-
- if (keywords[qcache_test_arch] == testing ||
- keywords[qcache_test_arch] == stable)
+ if (atom_compare_str(lastpkg, curpkg) == NOT_EQUAL)
{
- qcache_skip = 1;
+ /* different package, reset */
+ candidate = false;
+ }
- if (possible) {
- printf("%s%s/%s%s%s\n", BOLD, data->category, BLUE,
- data->package, NORM);
- }
+ if (data == NULL) {
+ if (candkwds != NULL)
+ free(candkwds);
+ return EXIT_SUCCESS;
+ }
- free(keywords);
- return;
+ if (candkwdslen < data->keywordsbuflen) {
+ candkwds = xrealloc(candkwds,
+ data->keywordsbuflen * sizeof(candkwds[0]));
+ candkwdslen = data->keywordsbuflen;
}
- if (!possible) {
- /* don't count newer versions with "-*" keywords */
- for (i = 0; i < archlist_count; ++i) {
- if (keywords[i] == stable || keywords[i] == testing) {
- possible = 1;
- break;
+ /* explicitly removed? */
+ if (data->keywordsbuf[qcache_test_arch] == minus)
+ return EXIT_FAILURE;
+
+ /* got a keyword? */
+ if (data->keywordsbuf[qcache_test_arch] == testing ||
+ data->keywordsbuf[qcache_test_arch] == stable)
+ {
+ if (candidate) {
+ p = strchr(candpkg, '/');
+ if (p != NULL) {
+ *p++ = '\0';
+ print_keywords(candpkg, p, candkwds);
}
+ candidate = false;
}
+ return EXIT_SUCCESS; /* suppress further hits for this package */
}
- free(keywords);
+ /* do others have keywords? */
+ for (i = 0; i < archlist_count; i++) {
+ if (data->keywordsbuf[i] == stable || data->keywordsbuf[i] == testing) {
+ /* we don't have a keyword, others do: candidate */
+ break;
+ }
+ }
+ if (i == archlist_count)
+ return EXIT_FAILURE;
+
+ /* keep the "highest" candidate */
+ if (!candidate) {
+ memcpy(candkwds, data->keywordsbuf,
+ data->keywordsbuflen * sizeof(candkwds[0]));
+ memcpy(candpkg, curpkg, _Q_PATH_MAX);
+ candidate = true;
+ }
+ return EXIT_FAILURE;
}
static void
@@ -712,36 +371,54 @@ print_seconds_for_earthlings(const unsigned long t)
mm = tt % 60; tt /= 60;
hh = tt % 24; tt /= 24;
dd = tt;
- if (dd) printf("%s%u%s day%s, ", GREEN, dd, NORM, (dd == 1 ? "" : "s"));
- if (hh) printf("%s%u%s hour%s, ", GREEN, hh, NORM, (hh == 1 ? "" : "s"));
- if (mm) printf("%s%u%s minute%s, ", GREEN, mm, NORM, (mm == 1 ? "" : "s"));
+ if (dd)
+ printf("%s%u%s day%s, ", GREEN, dd, NORM, (dd == 1 ? "" : "s"));
+ if (hh)
+ printf("%s%u%s hour%s, ", GREEN, hh, NORM, (hh == 1 ? "" : "s"));
+ if (mm)
+ printf("%s%u%s minute%s, ", GREEN, mm, NORM, (mm == 1 ? "" : "s"));
printf("%s%u%s second%s", GREEN, ss, NORM, (ss == 1 ? "" : "s"));
}
-static void
-qcache_stats(qcache_data *data)
+static int
+qcache_stats(cache_pkg_ctx *pkg_ctx, void *priv)
{
static time_t runtime;
- static set *allcats;
- static const char *last_overlay;
static int numpkg = 0;
static int numebld = 0;
- static int numcat;
+ static int numcat = 0;
static int *packages_stable;
static int *packages_testing;
static int *current_package_keywords;
- static int *keywords;
- int a;
+ static const char *lastcat = NULL;
+ static char lastpkg[_Q_PATH_MAX];
+
+ size_t a;
+ depend_atom *atom;
+ qcache_data *data = (qcache_data *)priv;
/* Is this the last time we'll be called? */
if (!data) {
char **arch;
const char border[] = "------------------------------------------------------------------";
+ /* include stats for last package */
+ for (a = 0; a < archlist_count; a++) {
+ switch (current_package_keywords[a]) {
+ case stable:
+ packages_stable[a]++;
+ break;
+ case testing:
+ packages_testing[a]++;
+ default:
+ break;
+ }
+ }
+
printf("+%.*s+\n", 25, border);
printf("| general statistics |\n");
printf("+%.*s+\n", 25, border);
- printf("| %s%13s%s | %s%7d%s |\n",
+ printf("| %s%13s%s | %s%7zd%s |\n",
GREEN, "architectures", NORM, BLUE, archlist_count, NORM);
printf("| %s%13s%s | %s%7d%s |\n",
GREEN, "categories", NORM, BLUE, numcat, NORM);
@@ -783,81 +460,49 @@ qcache_stats(qcache_data *data)
free(packages_stable);
free(packages_testing);
- free(keywords);
free(current_package_keywords);
- free_set(allcats);
- return;
+ return EXIT_SUCCESS;
}
- if (last_overlay != data->overlay) {
- DIR *dir;
- struct dirent *de;
- char *catpath;
-
- runtime = time(NULL);
-
- xasprintf(&catpath, "%s/metadata/md5-cache", data->overlay);
- dir = opendir(catpath);
- while ((de = readdir(dir))) {
- /* Look for all the directories in this path. */
-#if defined(DT_UNKNOWN) && defined(DT_DIR)
- if (de->d_type == DT_UNKNOWN)
-#endif
- {
- struct stat s;
- char spath[_Q_PATH_MAX * 2];
- snprintf(spath, sizeof(spath), "%s/%s", catpath, de->d_name);
- if (lstat(spath, &s) != 0)
- continue;
- if (!S_ISDIR(s.st_mode))
- continue;
- }
-#if defined(DT_UNKNOWN) && defined(DT_DIR)
- else if (de->d_type != DT_DIR)
- continue;
-#endif
-
- if (de->d_name[0] != '.') {
- bool ok;
- allcats = add_set_unique(de->d_name, allcats, &ok);
- if (ok)
- ++numcat;
- }
- }
- closedir(dir);
- free(catpath);
-
- last_overlay = data->overlay;
- }
-
- if (!numpkg) {
+ if (numpkg == 0) {
+ runtime = time(NULL);
packages_stable =
xcalloc(archlist_count, sizeof(*packages_stable));
packages_testing =
xcalloc(archlist_count, sizeof(*packages_testing));
- keywords =
- xcalloc(archlist_count, sizeof(*keywords));
current_package_keywords =
xcalloc(archlist_count, sizeof(*current_package_keywords));
}
- if (data->cur == 1) {
+ if (lastcat != pkg_ctx->cat_ctx->name)
+ numcat++;
+ lastcat = pkg_ctx->cat_ctx->name;
+
+ atom = atom_explode(pkg_ctx->name);
+ if (atom && strcmp(lastpkg, atom->PN) != 0) {
+ for (a = 0; a < archlist_count; a++) {
+ switch (current_package_keywords[a]) {
+ case stable:
+ packages_stable[a]++;
+ break;
+ case testing:
+ packages_testing[a]++;
+ default:
+ break;
+ }
+ }
+
numpkg++;
+ snprintf(lastpkg, sizeof(lastpkg), "%s", atom->PN);
memset(current_package_keywords, 0,
archlist_count * sizeof(*current_package_keywords));
}
- ++numebld;
+ atom_implode(atom);
- memset(keywords, 0, archlist_count * sizeof(*keywords));
- if (read_keywords(data->cache_data->KEYWORDS, keywords) < 0) {
- if (verbose)
- warn("Failed to read keywords for %s%s/%s%s%s",
- BOLD, data->category, BLUE, data->ebuild, NORM);
- return;
- }
+ numebld++;
- for (a = 0; a < archlist_count; ++a) {
- switch (keywords[a]) {
+ for (a = 0; a < archlist_count; a++) {
+ switch (data->keywordsbuf[a]) {
case stable:
current_package_keywords[a] = stable;
break;
@@ -869,65 +514,140 @@ qcache_stats(qcache_data *data)
}
}
- if (data->cur == data->num) {
- for (a = 0; a < archlist_count; ++a) {
- switch (current_package_keywords[a]) {
- case stable:
- packages_stable[a]++;
- break;
- case testing:
- packages_testing[a]++;
- default:
- break;
+ return EXIT_FAILURE;
+}
+
+static int
+qcache_testing_only(cache_pkg_ctx *pkg_ctx, void *priv)
+{
+ static bool candidate = false;
+ static char pkg1[_Q_PATH_MAX];
+ static char pkg2[_Q_PATH_MAX];
+ static char *lastpkg = pkg1;
+ static char *curpkg = pkg2;
+ static char candpkg[_Q_PATH_MAX];
+ static int *candkwds = NULL;
+ static size_t candkwdslen = 0;
+
+ qcache_data *data = (qcache_data *)priv;
+ char *p;
+
+ p = lastpkg;
+ lastpkg = curpkg;
+ curpkg = p;
+ if (pkg_ctx != NULL) {
+ snprintf(curpkg, _Q_PATH_MAX, "%s/%s",
+ pkg_ctx->cat_ctx->name, pkg_ctx->name);
+ } else {
+ curpkg[0] = '\0';
+ }
+ if (atom_compare_str(lastpkg, curpkg) == NOT_EQUAL)
+ {
+ /* different package, print if candidate */
+ if (candidate) {
+ p = strchr(candpkg, '/');
+ if (p != NULL) {
+ *p++ = '\0';
+ print_keywords(candpkg, p, candkwds);
}
+ candidate = false;
}
}
+
+ if (data == NULL) {
+ if (candkwds != NULL)
+ free(candkwds);
+ return EXIT_SUCCESS;
+ }
+
+ if (candkwdslen < data->keywordsbuflen) {
+ candkwds = xrealloc(candkwds,
+ data->keywordsbuflen * sizeof(candkwds[0]));
+ candkwdslen = data->keywordsbuflen;
+ }
+
+ /* explicitly removed or unkeyworded? */
+ if (data->keywordsbuf[qcache_test_arch] == minus ||
+ data->keywordsbuf[qcache_test_arch] == none)
+ return EXIT_FAILURE;
+
+ /* got a stable keyword? */
+ if (data->keywordsbuf[qcache_test_arch] == stable)
+ return EXIT_SUCCESS; /* suppress further hits for this package */
+
+ /* must be testing at this point */
+
+ /* keep the "highest" candidate */
+ if (!candidate) {
+ memcpy(candkwds, data->keywordsbuf,
+ data->keywordsbuflen * sizeof(candkwds[0]));
+ memcpy(candpkg, curpkg, _Q_PATH_MAX);
+ candidate = true;
+ }
+ return EXIT_FAILURE;
}
-static void
-qcache_testing_only(qcache_data *data)
+static int
+qcache_results_cb(cache_pkg_ctx *pkg_ctx, void *priv)
{
- static int possible = 0;
int *keywords;
+ qcache_data *data = (qcache_data *)priv;
+ char buf[_Q_PATH_MAX];
+ depend_atom *patom = NULL;
+ cache_pkg_meta *meta;
+ int ret;
- if (!data)
- return;
-
- if (data->cur == 1)
- possible = 0;
+ snprintf(buf, sizeof(buf), "%s/%s",
+ pkg_ctx->cat_ctx->name, pkg_ctx->name);
+ patom = atom_explode(buf);
+ if (patom == NULL)
+ return EXIT_FAILURE;
- keywords = xmalloc(sizeof(*keywords) * archlist_count);
+ if (data->qatom != NULL &&
+ atom_compare(patom, data->qatom) != EQUAL)
+ {
+ atom_implode(patom);
+ return EXIT_FAILURE;
+ }
- if (read_keywords(data->cache_data->KEYWORDS, keywords) < 0) {
- if (verbose)
- warn("Failed to read keywords for %s%s/%s%s%s",
- BOLD, data->category, BLUE, data->ebuild, NORM);
- free(keywords);
- return;
+ if (data->lastatom != NULL &&
+ atom_compare(data->lastatom, patom) != NOT_EQUAL)
+ {
+ atom_implode(patom);
+ return EXIT_SUCCESS;
}
- if (keywords[qcache_test_arch] == stable) {
- qcache_skip = 1;
- free(keywords);
- return;
+ keywords = data->keywordsbuf;
+ meta = cache_pkg_read(pkg_ctx);
+ if (meta == NULL) {
+ atom_implode(patom);
+ return EXIT_FAILURE;
}
- /* the qcache_test_arch must have at least 1 ~arch keyword */
- if (keywords[qcache_test_arch] == testing)
- possible = 1;
+ if (read_keywords(meta->KEYWORDS, keywords) < 0) {
+ if (verbose)
+ warn("Failed to read keywords for %s%s/%s%s%s",
+ BOLD, pkg_ctx->cat_ctx->name, BLUE, pkg_ctx->name, NORM);
+ atom_implode(patom);
+ return EXIT_FAILURE;
+ }
- if (data->cur == data->num && possible) {
- printf("%s%s/%s%s%s\n", BOLD, data->category, BLUE,
- data->package, NORM);
+ ret = data->runfunc(pkg_ctx, priv);
+
+ if (ret == EXIT_SUCCESS) {
+ /* store CAT/PN in lastatom */
+ patom->P = patom->PN;
+ patom->PVR = patom->PN;
+ patom->PR_int = 0;
+ data->lastatom = patom;
+ patom = NULL;
+ } else {
+ atom_implode(patom);
}
- free(keywords);
+ return EXIT_SUCCESS;
}
-/********************************************************************/
-/* Misc functions */
-/********************************************************************/
-
static void
qcache_load_arches(const char *overlay)
{
@@ -937,11 +657,12 @@ qcache_load_arches(const char *overlay)
size_t buflen;
char *buf;
- xasprintf(&filename, "%s/profiles/arch.list", overlay);
+ xasprintf(&filename, "%s/%s/profiles/arch.list", portroot, overlay);
fp = fopen(filename, "re");
if (!fp)
goto done;
+ clear_set(archs);
archlist_count = 0;
arch_longest_len = 0;
buf = NULL;
@@ -956,13 +677,17 @@ qcache_load_arches(const char *overlay)
bool ok;
archs = add_set_unique(buf, archs, &ok);
if (ok) {
- ++archlist_count;
- arch_longest_len = MAX(arch_longest_len, strlen(buf));
+ archlist_count++;
+ buflen = strlen(buf);
+ if (arch_longest_len < buflen)
+ arch_longest_len = buflen;
}
}
free(buf);
/* materialise into a list */
+ if (archlist != NULL)
+ free(archlist);
list_set(archs, &archlist);
fclose(fp);
@@ -970,30 +695,51 @@ qcache_load_arches(const char *overlay)
free(filename);
}
-/*
- * int qcache_free();
- *
- * Deallocate variables (archlist)
- */
-static void
-qcache_free(void)
+static int
+qcache_traverse(cache_pkg_cb func, void *priv)
{
- free(archlist);
- free_set(archs);
-}
+ int ret;
+ size_t n;
+ const char *overlay;
+ qcache_data *data = (qcache_data *)priv;
-/********************************************************************/
-/* main */
-/********************************************************************/
+ /* Preload all the arches. Not entirely correctly (as arches are bound
+ * to overlays if set), but oh well. */
+ array_for_each(overlays, n, overlay)
+ qcache_load_arches(overlay);
+
+ /* allocate memory (once) for the list used by various funcs */
+ if (archlist_count > data->keywordsbuflen) {
+ data->keywordsbuf = xrealloc(data->keywordsbuf,
+ archlist_count * sizeof(data->keywordsbuf[0]));
+ data->keywordsbuflen = archlist_count;
+ }
+
+ qcache_test_arch = decode_arch(data->arch);
+ if (qcache_test_arch == -1)
+ return EXIT_FAILURE;
+
+ data->runfunc = func;
+ ret = 0;
+ array_for_each(overlays, n, overlay)
+ ret |= cache_foreach_pkg_sorted(portroot, overlay,
+ qcache_results_cb, priv, NULL, qcache_vercmp);
+
+ return ret;
+}
int qcache_main(int argc, char **argv)
{
- int i, action = 0;
+ int i;
+ char action = '\0';
+ qcache_data data;
+ char *pkg = NULL;
+ char *cat = NULL;
while ((i = GETOPT_LONG(QCACHE, qcache, "")) != -1) {
switch (i) {
- case 'p': qcache_matchpkg = optarg; break;
- case 'c': qcache_matchcat = optarg; break;
+ case 'p': pkg = optarg; break;
+ case 'c': cat = optarg; break;
case 'i':
case 'd':
case 't':
@@ -1010,22 +756,56 @@ int qcache_main(int argc, char **argv)
}
}
+ data.arch = NULL;
if (optind < argc)
- qcache_test_arch = decode_arch(argv[optind]);
+ data.arch = argv[optind];
- if ((qcache_test_arch == -1 && action != 's') || optind + 1 < argc)
+ if ((data.arch == NULL && action != 's') || optind + 1 < argc)
qcache_usage(EXIT_FAILURE);
+ if (cat != NULL) {
+ char buf[_Q_PATH_MAX];
+
+ snprintf(buf, sizeof(buf), "%s/%s", cat, pkg == NULL ? "" : pkg);
+ data.qatom = atom_explode(buf);
+ if (data.qatom == NULL) {
+ warnf("invalid cat/pkg: %s\n", buf);
+ return EXIT_FAILURE;
+ }
+ } else if (pkg != NULL) {
+ data.qatom = atom_explode(pkg);
+ if (data.qatom == NULL) {
+ warnf("invalid pkg: %s\n", pkg);
+ return EXIT_FAILURE;
+ }
+ } else {
+ data.qatom = NULL;
+ }
+
+ archs = create_set();
+ data.lastatom = NULL;
+ data.keywordsbuf = NULL;
+ data.keywordsbuflen = 0;
+
switch (action) {
- case 'i': return qcache_traverse(qcache_imlate);
- case 'd': return qcache_traverse(qcache_dropped);
- case 't': return qcache_traverse(qcache_testing_only);
- case 's': return qcache_traverse(qcache_stats);
- case 'a': return qcache_traverse(qcache_all);
- case 'n': return qcache_traverse(qcache_not);
+ case 'i': i = qcache_traverse(qcache_imlate, &data); break;
+ case 'd': i = qcache_traverse(qcache_dropped, &data);
+ i = qcache_dropped(NULL, NULL); break;
+ case 't': i = qcache_traverse(qcache_testing_only, &data);
+ i = qcache_testing_only(NULL, NULL); break;
+ case 's': data.arch = "amd64"; /* doesn't matter, need to be set */
+ i = qcache_traverse(qcache_stats, &data);
+ i = qcache_stats(NULL, NULL); break;
+ case 'a': i = qcache_traverse(qcache_all, &data); break;
+ case 'n': i = qcache_traverse(qcache_not, &data); break;
+ default: i = -2; break;
}
- qcache_free();
- qcache_usage(EXIT_FAILURE);
- return EXIT_FAILURE;
+ if (data.qatom != NULL)
+ atom_implode(data.qatom);
+ free(archlist);
+ free_set(archs);
+ if (i == -2)
+ qcache_usage(EXIT_FAILURE);
+ return i;
}
next reply other threads:[~2019-04-25 9:22 UTC|newest]
Thread overview: 593+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-25 9:22 Fabian Groffen [this message]
-- strict thread matches above, loose matches on Subject: below --
2024-12-02 7:26 [gentoo-commits] proj/portage-utils:master commit in: / Fabian Groffen
2024-07-03 19:44 Fabian Groffen
2024-06-28 19:51 Fabian Groffen
2024-06-27 19:19 Fabian Groffen
2024-04-20 13:05 Fabian Groffen
2024-03-29 11:22 Fabian Groffen
2024-03-29 10:58 Fabian Groffen
2024-03-29 10:57 Fabian Groffen
2024-01-02 13:16 Fabian Groffen
2024-01-02 13:16 Fabian Groffen
2024-01-02 7:57 Fabian Groffen
2024-01-01 10:37 Fabian Groffen
2023-12-20 21:32 Mike Frysinger
2023-07-18 6:28 Fabian Groffen
2023-07-18 6:28 Fabian Groffen
2023-04-21 19:11 Fabian Groffen
2023-03-01 21:00 Fabian Groffen
2023-02-22 20:06 Fabian Groffen
2023-02-07 8:10 Fabian Groffen
2022-12-15 9:13 Fabian Groffen
2022-12-15 9:03 Fabian Groffen
2022-12-15 9:03 Fabian Groffen
2022-11-16 8:59 Fabian Groffen
2022-08-29 8:44 Fabian Groffen
2022-08-29 8:44 Fabian Groffen
2022-08-28 12:26 Fabian Groffen
2022-08-28 12:26 Fabian Groffen
2022-06-14 6:36 Fabian Groffen
2022-05-26 14:53 Fabian Groffen
2022-05-20 17:15 Fabian Groffen
2022-04-06 19:31 Fabian Groffen
2022-02-27 12:29 Fabian Groffen
2022-02-23 11:57 Fabian Groffen
2022-02-23 11:57 Fabian Groffen
2022-02-12 18:31 Fabian Groffen
2022-02-12 18:31 Fabian Groffen
2022-02-12 18:31 Fabian Groffen
2022-02-12 17:13 Fabian Groffen
2022-02-12 17:13 Fabian Groffen
2022-02-12 17:13 Fabian Groffen
2022-02-12 17:13 Fabian Groffen
2022-02-12 17:13 Fabian Groffen
2022-02-12 16:14 Fabian Groffen
2022-02-07 7:16 Fabian Groffen
2022-02-06 15:21 Fabian Groffen
2022-02-06 14:51 Fabian Groffen
2022-02-06 14:29 Fabian Groffen
2022-02-06 14:29 Fabian Groffen
2022-01-31 8:01 Fabian Groffen
2021-12-31 15:36 Fabian Groffen
2021-12-31 15:36 Fabian Groffen
2021-12-31 15:36 Fabian Groffen
2021-12-29 12:20 Fabian Groffen
2021-12-27 18:13 Fabian Groffen
2021-12-26 13:59 Fabian Groffen
2021-12-25 9:15 Fabian Groffen
2021-12-23 12:55 Fabian Groffen
2021-12-21 11:30 Fabian Groffen
2021-12-13 8:39 Fabian Groffen
2021-12-13 8:39 Fabian Groffen
2021-12-13 8:39 Fabian Groffen
2021-11-13 14:27 Fabian Groffen
2021-11-13 14:27 Fabian Groffen
2021-11-07 10:53 Fabian Groffen
2021-10-09 12:03 Fabian Groffen
2021-10-03 11:15 Fabian Groffen
2021-10-03 8:54 Fabian Groffen
2021-09-27 18:14 Fabian Groffen
2021-07-06 6:43 Fabian Groffen
2021-07-05 8:40 Fabian Groffen
2021-07-01 10:07 Fabian Groffen
2021-07-01 10:05 Fabian Groffen
2021-06-30 6:26 Fabian Groffen
2021-06-24 6:44 Fabian Groffen
2021-06-23 7:14 Fabian Groffen
2021-06-21 20:04 Fabian Groffen
2021-06-17 6:27 Fabian Groffen
2021-06-16 20:11 Fabian Groffen
2021-06-16 19:21 Fabian Groffen
2021-06-16 19:21 Fabian Groffen
2021-06-16 19:21 Fabian Groffen
2021-06-16 19:21 Fabian Groffen
2021-06-16 19:21 Fabian Groffen
2021-06-16 19:21 Fabian Groffen
2021-06-16 19:19 Fabian Groffen
2021-06-01 19:43 Fabian Groffen
2021-06-01 19:43 Fabian Groffen
2021-05-31 19:14 Fabian Groffen
2021-05-15 12:19 Fabian Groffen
2021-05-10 9:16 Fabian Groffen
2021-05-02 11:32 Fabian Groffen
2021-05-02 11:25 Fabian Groffen
2021-05-02 11:25 Fabian Groffen
2021-05-01 19:32 Fabian Groffen
2021-05-01 8:40 Fabian Groffen
2021-03-13 20:32 Fabian Groffen
2021-02-20 12:06 Fabian Groffen
2021-02-20 11:44 Fabian Groffen
2021-02-20 11:44 Fabian Groffen
2021-02-17 20:23 Fabian Groffen
2020-11-29 9:13 Fabian Groffen
2020-11-21 10:53 Fabian Groffen
2020-11-21 10:45 Fabian Groffen
2020-11-21 10:00 Fabian Groffen
2020-11-21 9:53 Fabian Groffen
2020-11-21 8:53 Fabian Groffen
2020-11-14 17:06 Fabian Groffen
2020-11-14 17:06 Fabian Groffen
2020-11-13 9:32 Fabian Groffen
2020-10-04 19:30 Fabian Groffen
2020-10-04 19:06 Fabian Groffen
2020-10-04 18:46 Fabian Groffen
2020-10-04 18:44 Fabian Groffen
2020-10-04 12:33 Fabian Groffen
2020-10-04 11:54 Fabian Groffen
2020-10-04 11:31 Fabian Groffen
2020-10-04 11:09 Fabian Groffen
2020-08-17 14:34 Fabian Groffen
2020-08-17 13:08 Fabian Groffen
2020-08-17 13:08 Fabian Groffen
2020-08-14 10:44 Fabian Groffen
2020-08-14 10:09 Fabian Groffen
2020-08-14 9:35 Fabian Groffen
2020-08-14 9:35 Fabian Groffen
2020-08-02 7:39 Fabian Groffen
2020-07-08 8:12 Fabian Groffen
2020-06-28 19:11 Fabian Groffen
2020-06-28 15:58 Fabian Groffen
2020-06-27 9:38 Fabian Groffen
2020-06-27 9:38 Fabian Groffen
2020-05-25 19:01 Fabian Groffen
2020-05-25 18:29 Fabian Groffen
2020-05-25 18:25 Fabian Groffen
2020-05-25 18:08 Fabian Groffen
2020-05-25 18:05 Fabian Groffen
2020-05-25 11:20 Fabian Groffen
2020-05-25 11:12 Fabian Groffen
2020-05-25 10:43 Fabian Groffen
2020-05-25 10:43 Fabian Groffen
2020-05-21 11:13 Fabian Groffen
2020-05-17 12:35 Fabian Groffen
2020-05-17 12:35 Fabian Groffen
2020-05-17 12:35 Fabian Groffen
2020-05-17 12:35 Fabian Groffen
2020-05-17 8:27 Fabian Groffen
2020-05-17 8:27 Fabian Groffen
2020-05-17 8:15 Fabian Groffen
2020-05-16 18:51 Fabian Groffen
2020-05-16 14:30 Fabian Groffen
2020-05-16 13:06 Fabian Groffen
2020-05-16 13:06 Fabian Groffen
2020-05-02 8:45 Fabian Groffen
2020-04-27 7:46 Fabian Groffen
2020-02-21 8:50 Fabian Groffen
2020-02-21 8:18 Fabian Groffen
2020-01-31 14:45 Fabian Groffen
2020-01-31 13:26 Fabian Groffen
2020-01-31 13:26 Fabian Groffen
2020-01-31 13:26 Fabian Groffen
2020-01-31 10:49 Fabian Groffen
2020-01-31 10:49 Fabian Groffen
2020-01-31 10:49 Fabian Groffen
2020-01-26 19:31 Fabian Groffen
2020-01-25 12:20 Fabian Groffen
2020-01-25 12:20 Fabian Groffen
2020-01-25 12:11 Fabian Groffen
2020-01-25 10:01 Fabian Groffen
2020-01-25 9:45 Fabian Groffen
2020-01-25 9:11 Fabian Groffen
2020-01-25 9:11 Fabian Groffen
2020-01-25 9:03 Fabian Groffen
2020-01-25 9:03 Fabian Groffen
2020-01-25 9:03 Fabian Groffen
2020-01-25 9:03 Fabian Groffen
2020-01-25 9:03 Fabian Groffen
2020-01-22 20:11 Fabian Groffen
2020-01-22 20:11 Fabian Groffen
2020-01-22 20:11 Fabian Groffen
2020-01-22 20:04 Fabian Groffen
2020-01-22 20:04 Fabian Groffen
2020-01-22 20:04 Fabian Groffen
2020-01-22 20:04 Fabian Groffen
2020-01-22 19:54 Fabian Groffen
2020-01-22 19:54 Fabian Groffen
2020-01-22 19:54 Fabian Groffen
2020-01-22 19:54 Fabian Groffen
2020-01-22 19:54 Fabian Groffen
2020-01-22 19:54 Fabian Groffen
2020-01-22 19:54 Fabian Groffen
2020-01-20 19:54 Fabian Groffen
2020-01-19 19:36 Fabian Groffen
2020-01-19 19:36 Fabian Groffen
2020-01-19 19:36 Fabian Groffen
2020-01-19 19:36 Fabian Groffen
2020-01-19 19:36 Fabian Groffen
2020-01-19 19:36 Fabian Groffen
2020-01-19 19:09 Fabian Groffen
2020-01-19 19:09 Fabian Groffen
2020-01-19 19:09 Fabian Groffen
2020-01-19 19:09 Fabian Groffen
2020-01-19 19:09 Fabian Groffen
2020-01-19 19:09 Fabian Groffen
2020-01-19 19:09 Fabian Groffen
2020-01-19 19:09 Fabian Groffen
2020-01-19 16:40 Fabian Groffen
2020-01-19 16:37 Fabian Groffen
2020-01-19 16:37 Fabian Groffen
2020-01-19 12:37 Fabian Groffen
2020-01-19 12:37 Fabian Groffen
2020-01-19 12:37 Fabian Groffen
2020-01-19 12:37 Fabian Groffen
2020-01-19 12:37 Fabian Groffen
2020-01-19 12:37 Fabian Groffen
2020-01-19 12:37 Fabian Groffen
2020-01-19 12:37 Fabian Groffen
2020-01-18 13:09 Fabian Groffen
2020-01-06 8:03 Fabian Groffen
2020-01-06 7:36 Fabian Groffen
2020-01-05 16:08 Fabian Groffen
2020-01-05 16:08 Fabian Groffen
2020-01-05 16:08 Fabian Groffen
2020-01-05 13:28 Fabian Groffen
2020-01-04 20:02 Fabian Groffen
2020-01-04 19:48 Fabian Groffen
2020-01-04 13:28 Fabian Groffen
2020-01-04 10:44 Fabian Groffen
2020-01-04 10:38 Fabian Groffen
2020-01-04 10:27 Fabian Groffen
2020-01-04 10:20 Fabian Groffen
2020-01-03 15:05 Fabian Groffen
2020-01-03 14:58 Fabian Groffen
2020-01-03 10:36 Fabian Groffen
2020-01-02 20:27 Fabian Groffen
2020-01-02 20:00 Fabian Groffen
2020-01-02 15:32 Fabian Groffen
2020-01-02 15:09 Fabian Groffen
2020-01-02 15:09 Fabian Groffen
2020-01-02 14:07 Fabian Groffen
2020-01-02 14:07 Fabian Groffen
2020-01-02 14:07 Fabian Groffen
2020-01-02 14:07 Fabian Groffen
2020-01-02 11:55 Fabian Groffen
2020-01-02 9:47 Fabian Groffen
2020-01-01 19:57 Fabian Groffen
2019-12-31 9:10 Fabian Groffen
2019-12-31 9:05 Fabian Groffen
2019-12-29 12:35 Fabian Groffen
2019-12-29 9:57 Fabian Groffen
2019-12-27 21:45 Fabian Groffen
2019-12-27 21:14 Fabian Groffen
2019-12-27 19:16 Fabian Groffen
2019-12-14 17:01 Fabian Groffen
2019-12-14 17:01 Fabian Groffen
2019-12-14 17:01 Fabian Groffen
2019-12-08 11:53 Fabian Groffen
2019-11-29 13:56 Fabian Groffen
2019-11-29 13:22 Fabian Groffen
2019-11-25 19:51 Fabian Groffen
2019-11-25 19:39 Fabian Groffen
2019-11-19 20:28 Fabian Groffen
2019-11-19 20:28 Fabian Groffen
2019-11-17 15:12 Fabian Groffen
2019-11-17 15:12 Fabian Groffen
2019-11-17 15:12 Fabian Groffen
2019-11-17 15:12 Fabian Groffen
2019-11-17 15:12 Fabian Groffen
2019-11-15 13:52 Fabian Groffen
2019-11-13 18:19 Fabian Groffen
2019-11-13 12:59 Fabian Groffen
2019-11-13 12:53 Fabian Groffen
2019-11-13 12:53 Fabian Groffen
2019-11-09 10:35 Fabian Groffen
2019-10-27 12:23 Fabian Groffen
2019-10-20 10:11 Fabian Groffen
2019-10-12 12:47 Fabian Groffen
2019-10-03 11:50 Fabian Groffen
2019-09-29 12:18 Fabian Groffen
2019-09-28 13:28 Fabian Groffen
2019-09-28 13:06 Fabian Groffen
2019-09-26 19:28 Fabian Groffen
2019-09-26 19:28 Fabian Groffen
2019-09-26 14:06 Fabian Groffen
2019-09-26 14:06 Fabian Groffen
2019-09-21 20:23 Fabian Groffen
2019-09-21 20:17 Fabian Groffen
2019-09-21 19:53 Fabian Groffen
2019-09-10 18:25 Fabian Groffen
2019-08-17 8:37 Fabian Groffen
2019-07-18 17:55 Fabian Groffen
2019-07-14 18:51 Fabian Groffen
2019-07-14 16:27 Fabian Groffen
2019-07-14 16:27 Fabian Groffen
2019-07-14 16:00 Fabian Groffen
2019-07-14 13:09 Fabian Groffen
2019-07-14 13:09 Fabian Groffen
2019-07-14 8:37 Fabian Groffen
2019-06-27 8:54 Fabian Groffen
2019-06-26 19:32 Fabian Groffen
2019-06-19 10:44 Fabian Groffen
2019-06-13 10:52 Fabian Groffen
2019-06-13 9:28 Fabian Groffen
2019-06-13 8:41 Fabian Groffen
2019-06-11 17:55 Fabian Groffen
2019-06-10 18:38 Fabian Groffen
2019-06-10 15:29 Fabian Groffen
2019-06-10 13:31 Fabian Groffen
2019-06-10 12:50 Fabian Groffen
2019-06-10 10:12 Fabian Groffen
2019-06-10 10:09 Fabian Groffen
2019-06-10 10:09 Fabian Groffen
2019-06-10 10:09 Fabian Groffen
2019-06-10 10:09 Fabian Groffen
2019-06-10 10:09 Fabian Groffen
2019-06-09 9:23 Fabian Groffen
2019-06-08 18:42 Fabian Groffen
2019-06-08 18:25 Fabian Groffen
2019-06-08 18:13 Fabian Groffen
2019-06-08 18:13 Fabian Groffen
2019-06-08 18:13 Fabian Groffen
2019-06-08 18:13 Fabian Groffen
2019-06-07 12:20 Fabian Groffen
2019-06-06 13:52 Fabian Groffen
2019-06-06 13:46 Fabian Groffen
2019-06-06 13:46 Fabian Groffen
2019-06-06 8:14 Fabian Groffen
2019-06-05 7:57 Fabian Groffen
2019-05-30 10:23 Fabian Groffen
2019-05-30 10:09 Fabian Groffen
2019-05-30 8:55 Fabian Groffen
2019-05-25 16:04 Fabian Groffen
2019-05-25 14:54 Fabian Groffen
2019-05-25 14:04 Fabian Groffen
2019-05-25 12:19 Fabian Groffen
2019-05-24 12:26 Fabian Groffen
2019-05-22 8:54 Fabian Groffen
2019-05-21 14:42 Fabian Groffen
2019-05-21 14:37 Fabian Groffen
2019-05-21 14:12 Fabian Groffen
2019-05-21 14:12 Fabian Groffen
2019-05-20 12:15 Fabian Groffen
2019-05-20 10:46 Fabian Groffen
2019-05-16 17:13 Fabian Groffen
2019-05-16 17:13 Fabian Groffen
2019-05-16 17:13 Fabian Groffen
2019-05-16 17:13 Fabian Groffen
2019-05-16 13:18 Fabian Groffen
2019-05-15 9:42 Fabian Groffen
2019-05-13 13:39 Fabian Groffen
2019-05-12 9:58 Fabian Groffen
2019-05-12 9:58 Fabian Groffen
2019-05-12 9:58 Fabian Groffen
2019-05-11 11:11 Fabian Groffen
2019-05-11 7:14 Fabian Groffen
2019-05-11 7:14 Fabian Groffen
2019-05-11 7:14 Fabian Groffen
2019-05-11 7:14 Fabian Groffen
2019-05-10 15:32 Fabian Groffen
2019-05-10 15:32 Fabian Groffen
2019-05-10 7:30 Fabian Groffen
2019-05-10 7:30 Fabian Groffen
2019-05-10 7:30 Fabian Groffen
2019-05-07 6:19 Fabian Groffen
2019-05-07 6:19 Fabian Groffen
2019-05-06 16:04 Fabian Groffen
2019-05-06 6:41 Fabian Groffen
2019-05-04 17:23 Fabian Groffen
2019-05-04 11:53 Fabian Groffen
2019-05-03 11:45 Fabian Groffen
2019-05-03 8:50 Fabian Groffen
2019-05-03 8:50 Fabian Groffen
2019-05-03 8:50 Fabian Groffen
2019-05-03 8:50 Fabian Groffen
2019-05-02 16:09 Fabian Groffen
2019-05-02 8:29 Fabian Groffen
2019-04-30 8:02 Fabian Groffen
2019-04-30 7:54 Fabian Groffen
2019-04-28 18:10 Fabian Groffen
2019-04-27 9:01 Fabian Groffen
2019-04-27 8:33 Fabian Groffen
2019-04-25 17:36 Fabian Groffen
2019-04-25 9:48 Fabian Groffen
2019-04-25 9:48 Fabian Groffen
2019-04-25 9:48 Fabian Groffen
2019-04-25 9:22 Fabian Groffen
2019-04-25 9:22 Fabian Groffen
2019-04-25 9:22 Fabian Groffen
2019-04-14 10:52 Fabian Groffen
2019-03-27 20:52 Fabian Groffen
2019-03-27 20:37 Fabian Groffen
2019-03-27 20:18 Fabian Groffen
2019-03-18 13:14 Fabian Groffen
2019-03-18 13:14 Fabian Groffen
2019-03-18 13:14 Fabian Groffen
2019-03-12 8:05 Fabian Groffen
2019-03-01 13:51 Fabian Groffen
2019-02-28 18:37 Fabian Groffen
2019-02-28 18:37 Fabian Groffen
2019-02-27 21:18 Fabian Groffen
2019-02-27 20:53 Fabian Groffen
2019-02-23 15:22 Fabian Groffen
2018-12-28 9:08 Fabian Groffen
2018-12-24 16:02 Fabian Groffen
2018-12-20 18:24 Fabian Groffen
2018-12-20 18:24 Fabian Groffen
2018-12-09 10:42 Fabian Groffen
2018-11-20 14:25 Fabian Groffen
2018-10-26 13:50 Fabian Groffen
2018-10-26 13:50 Fabian Groffen
2018-08-06 7:25 Fabian Groffen
2018-08-06 7:25 Fabian Groffen
2018-08-01 13:28 Fabian Groffen
2018-07-18 20:20 Fabian Groffen
2018-06-28 9:35 Fabian Groffen
2018-06-28 9:35 Fabian Groffen
2018-05-18 16:58 Fabian Groffen
2018-05-18 12:19 Fabian Groffen
2018-05-18 12:19 Fabian Groffen
2018-05-18 10:15 Fabian Groffen
2018-04-18 13:58 Fabian Groffen
2018-04-17 20:12 Fabian Groffen
2018-04-15 15:41 Fabian Groffen
2018-04-15 15:38 Fabian Groffen
2018-04-09 7:15 Fabian Groffen
2018-04-09 7:15 Fabian Groffen
2018-04-04 13:16 Fabian Groffen
2018-04-03 20:13 Fabian Groffen
2018-04-03 13:39 Fabian Groffen
2018-04-02 17:27 Fabian Groffen
2018-04-01 10:22 Fabian Groffen
2018-04-01 10:22 Fabian Groffen
2018-03-31 6:54 Fabian Groffen
2018-03-31 6:54 Fabian Groffen
2018-03-31 6:54 Fabian Groffen
2018-03-31 6:54 Fabian Groffen
2018-03-30 5:56 Fabian Groffen
2018-03-30 5:56 Fabian Groffen
2018-03-26 19:08 Fabian Groffen
2018-03-25 14:00 Fabian Groffen
2018-03-23 20:17 Fabian Groffen
2018-03-23 20:17 Fabian Groffen
2018-03-23 15:27 Fabian Groffen
2018-03-23 15:27 Fabian Groffen
2018-03-23 13:17 Fabian Groffen
2018-03-23 11:29 Fabian Groffen
2018-03-23 11:08 Fabian Groffen
2018-03-23 9:37 Fabian Groffen
2018-01-08 12:33 Fabian Groffen
2018-01-08 12:33 Fabian Groffen
2017-12-29 11:45 Fabian Groffen
2017-12-29 11:45 Fabian Groffen
2017-12-29 11:45 Fabian Groffen
2017-11-27 7:55 Robin H. Johnson
2017-11-27 7:55 Robin H. Johnson
2017-02-07 3:03 Mike Frysinger
2016-12-29 2:33 Mike Frysinger
2016-12-29 2:25 Mike Frysinger
2016-12-29 2:25 Mike Frysinger
2016-12-29 2:25 Mike Frysinger
2016-12-29 2:25 Mike Frysinger
2016-12-29 2:25 Mike Frysinger
2016-12-29 2:25 Mike Frysinger
2016-12-20 19:15 Mike Frysinger
2016-12-20 16:55 Mike Frysinger
2016-11-27 5:46 Mike Frysinger
2016-11-27 5:46 Mike Frysinger
2016-11-27 5:46 Mike Frysinger
2016-11-27 1:52 Mike Frysinger
2016-11-27 1:50 Mike Frysinger
2016-11-27 0:00 Mike Frysinger
2016-11-26 23:48 Mike Frysinger
2016-11-26 23:46 Mike Frysinger
2016-11-26 23:24 Mike Frysinger
2016-11-26 23:17 Mike Frysinger
2016-11-15 3:34 Mike Frysinger
2016-11-15 3:34 Mike Frysinger
2016-11-15 3:34 Mike Frysinger
2016-11-15 3:34 Mike Frysinger
2016-11-15 3:34 Mike Frysinger
2016-11-12 17:17 Mike Frysinger
2016-06-21 20:53 Mike Frysinger
2016-06-20 3:22 Mike Frysinger
2016-04-04 15:47 Mike Frysinger
2016-04-01 21:42 Mike Frysinger
2016-04-01 21:42 Mike Frysinger
2016-03-28 4:53 Mike Frysinger
2016-03-28 4:53 Mike Frysinger
2016-03-28 4:53 Mike Frysinger
2016-02-22 20:37 Mike Frysinger
2016-02-22 20:37 Mike Frysinger
2016-02-22 20:37 Mike Frysinger
2016-02-22 20:37 Mike Frysinger
2016-02-17 7:15 Mike Frysinger
2016-02-14 1:26 Mike Frysinger
2016-02-14 1:26 Mike Frysinger
2016-02-14 1:26 Mike Frysinger
2016-01-29 5:53 Mike Frysinger
2016-01-05 0:25 Mike Frysinger
2015-12-17 5:06 Mike Frysinger
2015-12-17 5:06 Mike Frysinger
2015-12-17 5:06 Mike Frysinger
2015-12-17 5:06 Mike Frysinger
2015-11-28 2:44 Mike Frysinger
2015-11-28 2:44 Mike Frysinger
2015-11-28 2:44 Mike Frysinger
2015-11-28 2:44 Mike Frysinger
2015-11-28 2:44 Mike Frysinger
2015-11-28 2:44 Mike Frysinger
2015-11-28 2:44 Mike Frysinger
2015-11-28 2:44 Mike Frysinger
2015-11-28 2:44 Mike Frysinger
2015-11-28 2:44 Mike Frysinger
2015-11-28 2:44 Mike Frysinger
2015-11-28 2:44 Mike Frysinger
2015-11-26 10:52 Mike Frysinger
2015-11-26 10:52 Mike Frysinger
2015-11-26 10:39 Mike Frysinger
2015-11-26 10:39 Mike Frysinger
2015-11-26 10:39 Mike Frysinger
2015-11-26 10:39 Mike Frysinger
2015-11-26 10:39 Mike Frysinger
2015-11-26 10:39 Mike Frysinger
2015-11-26 10:39 Mike Frysinger
2015-11-26 8:59 Mike Frysinger
2015-11-26 8:00 Mike Frysinger
2015-09-15 18:27 Mike Frysinger
2015-06-23 8:58 Mike Frysinger
2015-06-06 6:20 Mike Frysinger
2015-06-06 6:20 Mike Frysinger
2015-06-06 6:20 Mike Frysinger
2015-06-06 6:20 Mike Frysinger
2015-06-03 15:44 Mike Frysinger
2015-06-03 15:44 Mike Frysinger
2015-05-31 8:31 Mike Frysinger
2015-05-19 17:37 Mike Frysinger
2015-05-19 17:37 Mike Frysinger
2015-05-19 17:37 Mike Frysinger
2015-05-19 17:37 Mike Frysinger
2015-05-19 17:37 Mike Frysinger
2015-05-19 17:37 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-24 1:26 Mike Frysinger
2015-02-21 18:06 Mike Frysinger
2015-02-21 0:00 Mike Frysinger
2015-02-21 0:00 Mike Frysinger
2015-02-20 22:28 Mike Frysinger
2015-02-19 7:49 Mike Frysinger
2014-10-19 16:56 Mike Frysinger
2014-06-16 18:01 Mike Frysinger
2014-03-16 6:34 Mike Frysinger
2014-03-16 6:34 Mike Frysinger
2014-03-16 6:14 Mike Frysinger
2014-03-16 6:14 Mike Frysinger
2014-03-16 6:14 Mike Frysinger
2014-03-15 6:02 Mike Frysinger
2014-03-11 4:53 Mike Frysinger
2014-03-11 4:53 Mike Frysinger
2014-03-10 8:45 Mike Frysinger
2014-03-10 8:45 Mike Frysinger
2014-03-10 8:45 Mike Frysinger
2014-03-10 6:00 Mike Frysinger
2014-03-10 6:00 Mike Frysinger
2014-03-10 6:00 Mike Frysinger
2014-03-10 6:00 Mike Frysinger
2014-03-10 6:00 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
2014-03-08 5:51 Mike Frysinger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1555780746.86d662abd0216a49a6c2abee915e64d5c649cef2.grobian@gentoo \
--to=grobian@gentoo.org \
--cc=gentoo-commits@lists.gentoo.org \
--cc=gentoo-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox