pkgtools

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

commit 86ea9d526dc78b71570b5465274eaf04cd6a5b65
parent c3989c1d2a8f334a44a2fd133f527ed0ce039dc0
Author: sin <sin@2f30.org>
Date:   Mon,  9 Jun 2014 14:35:11 +0100

Add primitive ref counting to removepkg

Prune empty dirs only if the package refcount for that dir
is 1.

Diffstat:
Mremovepkg.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+), 0 deletions(-)

diff --git a/removepkg.c b/removepkg.c @@ -13,6 +13,7 @@ #include <unistd.h> #include "util.h" +static int numrefs(const char *); static int rmemptydir(const char *, const struct stat *, int, struct FTW *); static int removepkg(const char *); @@ -104,6 +105,61 @@ main(int argc, char *argv[]) } static int +numrefs(const char *f) +{ + DIR *dir; + struct dirent *dp; + FILE *fp; + char path[PATH_MAX]; + char buf[BUFSIZ], *p; + int refs = 0; + + dir = opendir("var/pkg"); + if (!dir) { + fprintf(stderr, "opendir %s: %s\n", "var/pkg", + strerror(errno)); + exit(EXIT_FAILURE); + } + + while ((dp = readdir(dir))) { + if (strcmp(dp->d_name, ".") == 0 || + strcmp(dp->d_name, "..") == 0) + continue; + + strlcpy(path, "var/pkg/", sizeof(path)); + strlcat(path, dp->d_name, sizeof(path)); + + fp = fopen(path, "r"); + if (!fp) { + fprintf(stderr, "fopen %s: %s\n", path, + strerror(errno)); + exit(EXIT_FAILURE); + } + + while (fgets(buf, sizeof(buf), fp)) { + p = strrchr(buf, '\n'); + if (p) + *p = '\0'; + if (buf[0] == '\0') + continue; + if (strcmp(buf, f) == 0) + refs++; + } + if (ferror(fp)) { + fprintf(stderr, "I/O error while processing %s\n", path); + fclose(fp); + return 1; + } + + fclose(fp); + } + + closedir(dir); + + return refs; +} + +static int rmemptydir(const char *f, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { @@ -193,6 +249,8 @@ removepkg(const char *f) *p = '\0'; if (buf[0] == '\0') continue; + if (numrefs(buf) > 1) + continue; nftw(buf, rmemptydir, 1, FTW_DEPTH); } if (ferror(fp)) {