On 11/05/10 04:02, Dan McGee wrote:
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

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);
        }



Reply via email to