From f80f8fbeb959756c583f2242d1c4b75f12b766ee Mon Sep 17 00:00:00 2001 From: Tollef Fog Heen Date: Wed, 26 Dec 2007 10:07:11 +0100 Subject: [PATCH] Configuration for filters added Filters can now be configured using SYSCONFDIR/filters.d. There's a known memory bug here somewhere, but this is a useful checkpoint. Also, does not exclude .dpkg-old and similar files from filters.d. --- lib/dpkg.h | 1 + lib/myopt.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/myopt.h | 8 +++++ src/archives.c | 52 ++++++++++++++++++++----------- 4 files changed, 127 insertions(+), 17 deletions(-) diff --git a/lib/dpkg.h b/lib/dpkg.h index ff3ac9ac..f1e0c41e 100644 --- a/lib/dpkg.h +++ b/lib/dpkg.h @@ -181,6 +181,7 @@ extern const char printforhelp[]; umask(022); /* Make sure all our status databases are readable. */\ if (loadcfg)\ loadcfgfile(prog, cmdinfos);\ + loadfilters();\ myopt(argv,cmdinfos);\ } while (0) diff --git a/lib/myopt.c b/lib/myopt.c index 5aed2f33..3a066c93 100644 --- a/lib/myopt.c +++ b/lib/myopt.c @@ -25,6 +25,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -164,3 +169,81 @@ void myopt(const char *const **argvp, const struct cmdinfo *cmdinfos) { } } } + +struct filterlist *filters = NULL; + +void loadfilter(char *fn) { + FILE* file; + char linebuf[1024]; + + file = fopen(fn, "r"); + if (!file) { + warningf(_("failed to open filter file `%.255s' for reading"), fn); + return; + } + + while (fgets(linebuf, sizeof(linebuf), file)) { + struct filterlist *filter; + + if (linebuf[0] == '#' || linebuf[0] == '\n') { + continue; + } + + if (linebuf[strlen(linebuf) - 1] == '\n') + linebuf[strlen(linebuf) - 1] = '\0'; + + if (linebuf[0] == '+') { + filter->positive = 1; + } else if (linebuf[0] == '-') { + filter->positive = 0; + } else { + warningf(_("Invalid filter line: `%.255s'"), linebuf); + } + + filter = malloc(sizeof(struct filterlist)); + if (!filter) { + ohshite(_("Error allocating memory for filter entry")); + } + + filter->filterstring = malloc(strlen(linebuf)); + if (!filter->filterstring) { + ohshite(_("Error allocating memory for filter entry")); + } + strcpy(filter->filterstring, &linebuf[1]); + filter->next = filters; + filters = filter; + } + + if (ferror(file)) ohshite(_("read error in configuration file `%.255s'"), fn); + if (fclose(file)) ohshite(_("error closing configuration file `%.255s'"), fn); + +} + +void loadfilters() { + struct dirent *dent; + char *dirname = CONFIGDIR "/filters.d"; + DIR *dir = opendir(dirname); + if (!dir) { + if (errno == ENOENT) { + return NULL; + } else { + ohshite(_("Error opening filters.d")); + } + } + + while ((dent = readdir(dir)) != NULL) { + struct stat statbuf; + char *file = malloc(strlen(dirname) + 1 + strlen(dent->d_name) + 1); + if (!file) + ohshite(_("Error allocating memory for file")); + sprintf(file, "%s/%s", dirname, dent->d_name); + if (stat(file, &statbuf) != 0) { + ohshite(_("Error stating file")); + } + if (S_ISREG(statbuf.st_mode)) { + loadfilter(file); + } + free(file); + } + closedir(dir); +} diff --git a/lib/myopt.h b/lib/myopt.h index cb59f824..ffa27e3a 100644 --- a/lib/myopt.h +++ b/lib/myopt.h @@ -39,4 +39,12 @@ struct cmdinfo { void myfileopt(const char* fn, const struct cmdinfo* cmdinfos); void myopt(const char *const **argvp, const struct cmdinfo *cmdinfos); void loadcfgfile(const char *prog, const struct cmdinfo *cmdinfos); +void loadfilter(char *fn); + +struct filterlist { + int positive; + char *filterstring; + struct filterlist *next; +}; + #endif /* MYOPT_H */ diff --git a/src/archives.c b/src/archives.c index 3dd715a9..3e9e4954 100644 --- a/src/archives.c +++ b/src/archives.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #define obstack_chunk_alloc m_malloc @@ -367,6 +368,8 @@ static int linktosameexistingdir(const struct TarInfo *ti, return 1; } +extern struct filterlist *filters; + int tarobject(struct TarInfo *ti) { static struct varbuf conffderefn, hardlinkfn, symlinkfn; const char *usename; @@ -403,24 +406,39 @@ int tarobject(struct TarInfo *ti) { nifd->namenode->divert && nifd->namenode->divert->useinstead ? nifd->namenode->divert->useinstead->name : ""); - if (strcmp(ti->Name, "./usr/share/doc/pkg-config/copyright") == 0) { - struct filenamenode *fnn = findnamenode(ti->Name, 0); - fnn->flags &= ~fnnf_new_inarchive; - obstack_free(&tar_obs, nifd); - tc->newfilesp= oldnifd; - *oldnifd = 0; - - /* We need to advance the tar file to the next object, so read the - * file data and set it to oblivion. - */ - if ((ti->Type == NormalFile0) || (ti->Type == NormalFile1)) { - char fnamebuf[256]; - fd_null_copy(tc->backendpipe, ti->Size, _("gobble replaced file `%.255s'"),quote_filename(fnamebuf,256,ti->Name)); - r= ti->Size % TARBLKSZ; - if (r > 0) r= safe_read(tc->backendpipe,databuf,TARBLKSZ - r); + if (filters) { + int remove = 0; + struct filterlist *f = filters; + while (f) { + debug(dbg_eachfile, "tarobject comparing '%s' and '%s'", &ti->Name[1], f->filterstring); + /* if (f->positive && remove == 1) { + remove = 0; + break; + }*/ + if (fnmatch(f->filterstring, &ti->Name[1], 0) == 0) { + remove = 1; + debug(dbg_eachfile, "tarobject removing %s", ti->Name); + } + f = f->next; + } + if (remove) { + struct filenamenode *fnn = findnamenode(ti->Name, 0); + fnn->flags &= ~fnnf_new_inarchive; + obstack_free(&tar_obs, nifd); + tc->newfilesp= oldnifd; + *oldnifd = 0; + + /* We need to advance the tar file to the next object, so read the + * file data and set it to oblivion. + */ + if ((ti->Type == NormalFile0) || (ti->Type == NormalFile1)) { + char fnamebuf[256]; + fd_null_copy(tc->backendpipe, ti->Size, _("gobble replaced file `%.255s'"),quote_filename(fnamebuf,256,ti->Name)); + r= ti->Size % TARBLKSZ; + if (r > 0) r= safe_read(tc->backendpipe,databuf,TARBLKSZ - r); + } + return 0; } - - return 0; } if (nifd->namenode->divert && nifd->namenode->divert->camefrom) { -- 2.39.5