[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