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.

Original-patch-by: Shankar <[email protected]>
Signed-off-by: Allan McRae <[email protected]>
---

This should address all comments I had when this was submitted a
few months back.

 src/pacman/query.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/src/pacman/query.c b/src/pacman/query.c
index 6b6a25d..038072f 100644
--- a/src/pacman/query.c
+++ b/src/pacman/query.c
@@ -56,10 +56,44 @@ static char *resolve_path(const char* file)
        return(str);
 }
 
+/* check if filename exists in PATH */
+static int search_path(char *filename, size_t size, struct stat * bufptr)
+{
+       char *envpath, *envpathsplit, *path, fullname[PATH_MAX+1];
+       int len;
+
+       if ((envpath = getenv("PATH")) == NULL) {
+               return(-1);
+       }
+       if ((envpath = envpathsplit = strdup(envpath)) == NULL) {
+               return(-1);
+       }
+
+       while ((path = strsep(&envpathsplit, ":")) != NULL) {
+               len = strlen(path);
+
+               /* strip the trailing slash if one exists */
+               while(path[len - 1] == '/') {
+                               path[--len] = '\0';
+               }
+
+               snprintf(fullname, sizeof(fullname), "%s/%s", path, filename);
+
+               if(stat(fullname, bufptr) == 0) {
+                       strncpy(filename, fullname, size);
+                       free(envpath);
+                       return(0);
+               }
+       }
+       free(envpath);
+       return(-1);
+}
+
 static int query_fileowner(alpm_list_t *targets)
 {
        int ret = 0;
        alpm_list_t *t;
+       size_t len=PATH_MAX+1;
 
        /* This code is here for safety only */
        if(targets == NULL) {
@@ -67,19 +101,31 @@ static int query_fileowner(alpm_list_t *targets)
                return(1);
        }
 
+       char *filename = calloc(len, sizeof(char));
+
        for(t = targets; t; t = alpm_list_next(t)) {
                int found = 0;
-               char *filename = alpm_list_getdata(t);
+               strncpy(filename, alpm_list_getdata(t), len);
                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, len, &buf) == -1) {
+                                       pm_fprintf(stderr, PM_LOG_ERROR, 
_("failed to read file '%s': %s\n"),
+                                               filename, strerror(errno));
+                                       ret++;
+                                       continue;
+                               }
+                       } else {
+                               pm_fprintf(stderr, PM_LOG_ERROR, _("failed to 
read file '%s': %s\n"),
+                                               filename, strerror(errno));
+                               ret++;
+                               continue;
+                       }
                }
 
                if(S_ISDIR(buf.st_mode)) {
@@ -140,6 +186,7 @@ static int query_fileowner(alpm_list_t *targets)
                free(rpath);
        }
 
+       free(filename);
        return ret;
 }
 
-- 
1.7.0.1


Reply via email to