pkgtools

morpheus pkg tools
git clone git://git.2f30.org/pkgtools
Log | Files | Refs | README | LICENSE

commit 23d9d9bfc6ac32d7013f8bfde99cdcc80df41c85
parent 733052f14734680a82e2f3a49de795e4032415a0
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Fri, 20 Jun 2014 16:38:50 +0200

preload and cache reject rules (per db context)

Signed-off-by: Hiltjo Posthuma <hiltjo@codemadness.org>

Diffstat:
Mdb.c | 92++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Mdb.h | 12++++++++++++
2 files changed, 78 insertions(+), 26 deletions(-)

diff --git a/db.c b/db.c @@ -18,19 +18,21 @@ #include "db.h" #include "util.h" -#define DBPATH "/var/pkg" +#define DBPATH "/var/pkg" +#define DBPATHREJECT "/etc/pkgtools/reject.conf" #define ARCHIVEBUFSIZ BUFSIZ -int fflag = 0; -int vflag = 0; - struct db { DIR *pkgdir; char prefix[PATH_MAX]; char path[PATH_MAX]; + struct rejrule *rejrules; struct pkg *head; }; +int fflag = 0; +int vflag = 0; + /* Request access to the db and initialize the context */ struct db * dbinit(const char *prefix) @@ -65,6 +67,7 @@ dbinit(const char *prefix) free(db); return NULL; } + db->rejrules = rejload(db->prefix); memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; @@ -303,6 +306,7 @@ dbfree(struct db *db) return -1; } closedir(db->pkgdir); + rejfree(db->rejrules); free(db); return 0; } @@ -649,26 +653,35 @@ err: path); } -int -rejmatch(struct db *db, const char *file) +void +rejfree(struct rejrule *list) +{ + struct rejrule *rule, *tmp; + rule = list; + while(rule) { + tmp = rule->next; + regfree(&(rule->preg)); + free(rule); + rule = tmp; + } +} + +struct rejrule * +rejload(const char *prefix) { + struct rejrule *rule, *next, *list = NULL; char rejpath[PATH_MAX]; FILE *fp; char *buf = NULL; size_t sz = 0; ssize_t len; - int match = 0, r; - regex_t preg; - - /* Skip initial '.' of "./" */ - if (strncmp(file, "./", 2) == 0) - file++; + int r; - estrlcpy(rejpath, db->prefix, sizeof(rejpath)); - estrlcat(rejpath, "/etc/pkgtools/reject.conf", sizeof(rejpath)); + estrlcpy(rejpath, prefix, sizeof(rejpath)); + estrlcat(rejpath, DBPATHREJECT, sizeof(rejpath)); if (!(fp = fopen(rejpath, "r"))) - return -1; + return NULL; while ((len = getline(&buf, &sz, fp)) != -1) { if (!len || buf[0] == '#' || buf[0] == '\n') @@ -676,29 +689,56 @@ rejmatch(struct db *db, const char *file) if (len > 0 && buf[len - 1] == '\n') buf[len - 1] = '\0'; - r = regcomp(&preg, buf, REG_NOSUB | REG_EXTENDED); + /* copy and add regex */ + rule = emalloc(sizeof(*rule)); + rule->next = NULL; + + r = regcomp(&(rule->preg), buf, REG_NOSUB | REG_EXTENDED); if (r != 0) { - regerror(r, &preg, buf, len); + regerror(r, &(rule->preg), buf, len); weprintf("invalid pattern: %s\n", buf); + rejfree(list); free(buf); fclose(fp); - return -1; + return NULL; } - r = regexec(&preg, file, 0, NULL, 0); - regfree(&preg); - if (r == REG_NOMATCH) - continue; - match = 1; - break; + + /* append to list: first item? or append to previous rule */ + if(!list) + list = next = rule; + else + next->next = rule; + next = rule; } free(buf); if (ferror(fp)) { weprintf("%s: read error:", rejpath); fclose(fp); - return -1; + rejfree(list); + return NULL; } - fclose(fp); + return list; +} + +int +rejmatch(struct db *db, const char *file) +{ + int match = 0, r; + struct rejrule *rule; + + /* Skip initial '.' of "./" */ + if (strncmp(file, "./", 2) == 0) + file++; + + for(rule = db->rejrules; rule; rule = rule->next) { + r = regexec(&(rule->preg), file, 0, NULL, 0); + if (r != REG_NOMATCH) { + match = 1; + break; + } + } + return match; } diff --git a/db.h b/db.h @@ -1,4 +1,8 @@ /* See LICENSE file for copyright and license details. */ + +#include <regex.h> +#include <sys/types.h> + struct pkgentry { /* full path */ char path[PATH_MAX]; @@ -7,6 +11,11 @@ struct pkgentry { struct pkgentry *next; }; +struct rejrule { + regex_t preg; + struct rejrule *next; +}; + struct pkg { char *name; char *version; @@ -33,4 +42,7 @@ struct pkg *pkgnew(char *); void pkgfree(struct pkg *); void parseversion(const char *, char **); void parsename(const char *, char **); +void rejfree(struct rejrule *); +struct rejrule * rejload(const char *); int rejmatch(struct db *, const char *); +struct rejrule * rejload(const char *);