[pacman-dev] [PATCH] Enable inverted patterns in NoExtract.

Patrick Steinhardt steinhardt.ptk at gmail.com
Mon Jun 17 18:27:32 EDT 2013


It is now possible to invert patterns in NoExtract. This feature
allows users to whitelist certain files that were previously
blacklisted by another entry in NoExtract.
---

This patch is another approach to my use case with blacklisting
all but some files in /usr/share/locale by being able to invert
patterns. An inverted pattern will result in a previously
blacklisted file to be whitelisted again. Subsequent matches will
always override previous ones. The following NoExtract clause
will thus result in all files in /usr/share/locale except en_US/*
and locale.alias being skipped:

NoExtract = usr/share/locale/*
NoExtract = !usr/share/locale/en_US/*
NoExtract = !usr/share/locale/locale.alias

 lib/libalpm/add.c  |  2 +-
 lib/libalpm/util.c | 32 ++++++++++++++++++++++++++++++++
 lib/libalpm/util.h |  1 +
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index c20e7c6..78f1ae2 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -183,7 +183,7 @@ static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
 	}
 
 	/* if a file is in NoExtract then we never extract it */
-	if(alpm_list_find(handle->noextract, entryname, _alpm_fnmatch)) {
+	if(_alpm_fnmatch_patterns(handle->noextract, entryname) == 0) {
 		_alpm_log(handle, ALPM_LOG_DEBUG, "%s is in NoExtract,"
 				" skipping extraction of %s\n",
 				entryname, filename);
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index f84fb66..1382889 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -1249,6 +1249,38 @@ int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int a
 	return ret;
 }
 
+/** Checks whether a string matches at least one shell wildcard pattern.
+ * Checks for matches with fnmatch. Matches are inverted by prepending
+ * patterns with an exclamation mark. Preceding exclamation marks may be
+ * escaped. Subsequent matches override previous ones.
+ * @param patterns patterns to match against
+ * @param string string to check against pattern
+ * @return 0 if string matches pattern, negative if they don't match and
+ * positive if the last match was inverted
+ */
+int _alpm_fnmatch_patterns(alpm_list_t *patterns, const char *string)
+{
+	int result = -1;
+	alpm_list_t *i;
+	char *pattern;
+	short inverted;
+
+	for(i = patterns; i; i = i->next) {
+		pattern = i->data;
+
+		inverted = pattern[0] == '!';
+		if(inverted || pattern[0] == '\\') {
+			pattern++;
+		}
+
+		if(_alpm_fnmatch(pattern, string) == 0) {
+			result = inverted;
+		}
+	}
+
+	return result;
+}
+
 /** Checks whether a string matches a shell wildcard pattern.
  * Wrapper around fnmatch.
  * @param pattern pattern to match against
diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h
index 56031f3..24b7c22 100644
--- a/lib/libalpm/util.h
+++ b/lib/libalpm/util.h
@@ -140,6 +140,7 @@ alpm_time_t _alpm_parsedate(const char *line);
 int _alpm_raw_cmp(const char *first, const char *second);
 int _alpm_raw_ncmp(const char *first, const char *second, size_t max);
 int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode);
+int _alpm_fnmatch_patterns(alpm_list_t *patterns, const char *string);
 int _alpm_fnmatch(const void *pattern, const void *string);
 
 #ifndef HAVE_STRSEP
-- 
1.8.3.1

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://mailman.archlinux.org/pipermail/pacman-dev/attachments/20130618/4089a2b7/attachment.asc>


More information about the pacman-dev mailing list