From: Allan McRae <[email protected]>

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 <[email protected]>
Signed-off-by: Allan McRae <[email protected]>
Signed-off-by: Dan McGee <[email protected]>
---

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

 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;
+       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"),
+                                                       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);
        }
 
-- 
1.7.1


Reply via email to