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

Allan McRae allan at archlinux.org
Tue Jun 18 01:36:01 EDT 2013


On 18/06/13 08:27, Patrick Steinhardt wrote:
> 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

This approach is fine to me.  Anyone else want to comment?

What needs done:
1) documentation in pacman.conf.5
2) NoUpgrade should be handled exactly the same as NoExtract

>  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
> 
> 
> 
> 



More information about the pacman-dev mailing list