From 2898b655a1d79f32a6ee630f4771d39f729d825c Mon Sep 17 00:00:00 2001 From: Tollef Fog Heen Date: Sun, 20 Jul 2008 22:51:15 +0200 Subject: [PATCH] Handle /usr/*/share/*/copyright include patterns Try to parse the fnmatch string a bit and match it piecewise to see if we have something that our directory might fit and if so reinclude it. --- src/filters.c | 85 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 13 deletions(-) diff --git a/src/filters.c b/src/filters.c index 75031ff4..2f567841 100644 --- a/src/filters.c +++ b/src/filters.c @@ -192,25 +192,84 @@ do_filter_should_skip(struct TarInfo *ti) } } - if (remove) { + if (remove && ti->Type == Directory) { debug(dbg_eachfile, "tarobject seeing if '%s' needs to be reincluded", &ti->Name[1]); for (f = filters; f != NULL; f = f->next) { - char *pattern; - - pattern = m_malloc(strlen(ti->Name) + 1); - strcpy(pattern, &ti->Name[1]); - strcat(pattern, "*"); - - if ((f->positive == 1) && - (ti->Type == Directory) && - (fnmatch(pattern, f->filterstring, 0) == 0)) { - remove = 0; - debug(dbg_eachfile, "tarobject reincluding %s", - ti->Name); + char *pattern, *fs, *t; + + if (f->positive != 1) + continue; + + pattern = m_strdup(&ti->Name[1]); + t = pattern; + fs = f->filterstring; + + while (1) { + if (*t == *fs && *t != '\0') { + t++; + fs++; + continue; + } + if (*t == '\0') { + /* End of string, we win! */ + debug(dbg_eachfile, "do_filter reincluding %s", + ti->Name); + remove = 0; + break; + } + if (*fs == '?') { + fs++; + t++; + continue; + } + if (*fs == '*') { + char *fs_pc = m_strdup(fs); + char *t_pc = m_strdup(t); + char *tmp; + + tmp = index(fs_pc, '/'); + if (tmp != NULL) { + *tmp = '\0'; + } + + tmp = index(t_pc, '/'); + if (tmp != NULL) { + *tmp = '\0'; + } + + debug(dbg_eachfile, "do_filter fnmatch(%s, %s)", + fs_pc, t_pc); + + if (fnmatch(fs_pc, t_pc, FNM_PATHNAME) == 0 && + index(t, '/') == NULL) { + debug(dbg_eachfile, "do_filter reincluding %s", + ti->Name); + remove = 0; + } + + free (fs_pc); + free (t_pc); + + if (index(t, '/') != NULL) { + fs++; + t = index(t, '/'); + debug(dbg_eachfile, "do_filter 2(%s, %s)", + fs, t); + + continue; + } + + break; + } + if (*fs != *t) { + /* Different, so just break */ + break; + } } + free(pattern); } } -- 2.39.5