[pacman-dev] [PATCH] Allow -Qo to perform a functional 'which'

Allan McRae allan at archlinux.org
Tue May 11 01:10:11 CEST 2010


On 11/05/10 04:02, Dan McGee wrote:
> From: Allan McRae<allan at archlinux.org>
>
> When pacman queries the ownership of an object that is not a path, it will
> check in the users PATH for a match. Implements FS#8798.
>
> Dan: did some small refactoring and error message changes when PATH is
> searched and nothing is found.
>
> Original-patch-by: Shankar<jatheendra at gmail.com>
> Signed-off-by: Allan McRae<allan at archlinux.org>
> Signed-off-by: Dan McGee<dan at archlinux.org>
> ---
>
> I think I just had some NIH and did a bit more refactoring than strictly
> necessary, but I thought I'd at least send this along. I think it gets all the
> error messaging tweaked up to be a bit more useful.
>
>
> -Dan

Looks good to me.  Couple of minor comments.

>
>   src/pacman/query.c |   65 ++++++++++++++++++++++++++++++++++++++++++++++++----
>   1 files changed, 60 insertions(+), 5 deletions(-)
>
> diff --git a/src/pacman/query.c b/src/pacman/query.c
> index 6010fd0..a882328 100644
> --- a/src/pacman/query.c
> +++ b/src/pacman/query.c
> @@ -56,9 +56,49 @@ static char *resolve_path(const char* file)
>   	return(str);
>   }
>
> +/* check if filename exists in PATH */
> +static int search_path(char **filename, struct stat *bufptr)
> +{
> +	char *envpath, *envpathsplit, *path;
> +	char *fullname;

These are the same type now so can go back on one line.

> +	size_t flen;
> +
> +	if ((envpath = getenv("PATH")) == NULL) {
> +		return(-1);
> +	}
> +	if ((envpath = envpathsplit = strdup(envpath)) == NULL) {
> +		return(-1);
> +	}
> +
> +	flen = strlen(*filename);
> +
> +	while ((path = strsep(&envpathsplit, ":")) != NULL) {
> +		size_t plen = strlen(path);
> +
> +		/* strip the trailing slash if one exists */
> +		while(path[plen - 1] == '/') {
> +				path[--plen] = '\0';
> +		}
> +
> +		fullname = malloc(plen + flen + 2);
> +		sprintf(fullname, "%s/%s", path, *filename);
> +
> +		if(lstat(fullname, bufptr) == 0) {
> +			free(*filename);
> +			*filename = fullname;
> +			free(envpath);
> +			return(0);
> +		}
> +		free(fullname);
> +	}
> +	free(envpath);
> +	return(-1);
> +}
> +
>   static int query_fileowner(alpm_list_t *targets)
>   {
>   	int ret = 0;
> +	char *filename;
>   	alpm_list_t *t;
>
>   	/* This code is here for safety only */
> @@ -69,23 +109,36 @@ static int query_fileowner(alpm_list_t *targets)
>
>   	for(t = targets; t; t = alpm_list_next(t)) {
>   		int found = 0;
> -		char *filename = alpm_list_getdata(t);
> +		filename = strdup(alpm_list_getdata(t));
>   		char *bname, *dname, *rpath;
>   		const char *root;
>   		struct stat buf;
>   		alpm_list_t *i, *j;
>
>   		if(lstat(filename,&buf) == -1) {
> -			pm_fprintf(stderr, PM_LOG_ERROR, _("failed to read file '%s': %s\n"),
> -					filename, strerror(errno));
> -			ret++;
> -			continue;
> +			/*  if it is not a path but a program name, then check in PATH */
> +			if(strchr(filename, '/') == NULL) {
> +				if(search_path(&filename,&buf) == -1) {
> +					pm_fprintf(stderr, PM_LOG_ERROR, _("failed to find '%s' on PATH: %s\n"),

"on PATH" vs "in PATH"?

> +							filename, strerror(errno));
> +					ret++;
> +					free(filename);
> +					continue;
> +				}
> +			} else {
> +				pm_fprintf(stderr, PM_LOG_ERROR, _("failed to read file '%s': %s\n"),
> +						filename, strerror(errno));
> +				ret++;
> +				free(filename);
> +				continue;
> +			}
>   		}
>
>   		if(S_ISDIR(buf.st_mode)) {
>   			pm_fprintf(stderr, PM_LOG_ERROR,
>   				_("cannot determine ownership of a directory\n"));
>   			ret++;
> +			free(filename);
>   			continue;
>   		}
>
> @@ -97,6 +150,7 @@ static int query_fileowner(alpm_list_t *targets)
>   		if(!rpath) {
>   			pm_fprintf(stderr, PM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"),
>   					filename, strerror(errno));
> +			free(filename);
>   			free(rpath);
>   			ret++;
>   			continue;
> @@ -137,6 +191,7 @@ static int query_fileowner(alpm_list_t *targets)
>   			pm_fprintf(stderr, PM_LOG_ERROR, _("No package owns %s\n"), filename);
>   			ret++;
>   		}
> +		free(filename);
>   		free(rpath);
>   	}
>



More information about the pacman-dev mailing list