pkgtools

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

commit a481a96a344e1d9ea76c4e76fefd3846eac142cf
parent 1a5cc52e44acdbe8b2cf4ccf22022a4cc9e96476
Author: sin <sin@2f30.org>
Date:   Fri, 20 Jun 2014 13:08:39 +0100

Add support for /etc/pkgtools/reject.conf

The format of the file is a single regex per line matching
the entries in a package.  The entries in a package start with
'./' which is skipped for the regex matching so in essence a
regex ^etc/.*$ will match etc/passwd which appears in the package
as ./etc/passwd.

Keep in mind that regex matches are only checked against files
in a package and *not* the filesystem.

All commands obey the reject matches.

installpkg and installpkg -f will *not* install a file if there is
a regex match for that file.

removepkg and removepkg -f will *not* remove a file if there is a
regex match for that file.

Filesystem collisions for rejected files will still be reported
installpkg -f will bypass those checks and it will still reject the
files.

An upcoming patch will move the rejected files to some other place
on the filesystem.

The database entry for the package will include all the original
files even if some of them were rejected.  It is up to the user to ensure
that rejected files are properly handled.

Notice that installpkg will reject files even if they do not exist
on the filesystem.  The rejection operation applies when installing,
removing and upgrading packages.

Diffstat:
Mdb.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdb.h | 4++++
2 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/db.c b/db.c @@ -7,6 +7,7 @@ #include <fcntl.h> #include <ftw.h> #include <limits.h> +#include <regex.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> @@ -367,6 +368,7 @@ dbpkgload(struct db *db, struct pkg *pkg) estrlcpy(pe->path, db->prefix, sizeof(pe->path)); estrlcat(pe->path, "/", sizeof(pe->path)); estrlcat(pe->path, buf, sizeof(pe->path)); + estrlcpy(pe->rpath, buf, sizeof(pe->rpath)); pe->next = pkg->head; pkg->head = pe; } @@ -428,6 +430,10 @@ dbpkginstall(struct db *db, const char *file) weprintf("chdir %s:", cwd); return -1; } + if (rejmatch(db, archive_entry_pathname(entry)) > 0) { + weprintf("rejecting %s\n", archive_entry_pathname(entry)); + continue; + } flags = ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_SECURE_NODOTDOT; if (fflag == 1) @@ -486,6 +492,11 @@ dbpkgremove(struct db *db, const char *name) } for (pe = pkg->head; pe; pe = pe->next) { + if (rejmatch(db, pe->rpath) > 0) { + weprintf("rejecting %s\n", pe->rpath); + continue; + } + if (lstat(pe->path, &sb) < 0) { weprintf("lstat %s:", pe->path); continue; @@ -516,6 +527,8 @@ dbpkgremove(struct db *db, const char *name) if (fflag == 1) { /* prune empty directories as well */ for (pe = pkg->head; pe; pe = pe->next) { + if (rejmatch(db, pe->rpath) > 0) + continue; if (dblinks(db, pe->path) > 1) continue; nftw(pe->path, rmemptydir, 1, FTW_DEPTH); @@ -655,3 +668,51 @@ err: eprintf("%s: invalid package filename\n", path); } + +int +rejmatch(struct db *db, const char *file) +{ + char rejpath[PATH_MAX]; + FILE *fp; + char *buf = NULL; + size_t sz = 0; + ssize_t len; + int match = 0, r; + regex_t preg; + + estrlcpy(rejpath, db->prefix, sizeof(rejpath)); + estrlcat(rejpath, "/etc/pkgtools/reject.conf", sizeof(rejpath)); + + if (!(fp = fopen(rejpath, "r"))) + return -1; + + while ((len = getline(&buf, &sz, fp)) != -1) { + if (len > 0 && buf[len - 1] == '\n') + buf[len - 1] = '\0'; + /* Skip initial './' */ + r = regcomp(&preg, buf + 2, REG_NOSUB | REG_EXTENDED); + if (r != 0) { + regerror(r, &preg, buf, len); + weprintf("invalid pattern: %s\n", buf); + free(buf); + fclose(fp); + return -1; + } + r = regexec(&preg, file, 0, NULL, 0); + regfree(&preg); + if (r == REG_NOMATCH) + continue; + match = 1; + break; + } + free(buf); + if (ferror(fp)) { + weprintf("%s: read error:", rejpath); + fclose(fp); + return -1; + } + + fclose(fp); + + return match; +} diff --git a/db.h b/db.h @@ -1,6 +1,9 @@ /* See LICENSE file for copyright and license details. */ struct pkgentry { + /* full path */ char path[PATH_MAX]; + /* relative path */ + char rpath[PATH_MAX]; struct pkgentry *next; }; @@ -29,3 +32,4 @@ struct pkg *pkgnew(char *); void pkgfree(struct pkg *); void parseversion(const char *, char **); void parsename(const char *, char **); +int rejmatch(struct db *, const char *);