From: Andrew Gregory <[email protected]>

Not allowing fileowner queries for directories was an unnecessary
limitation.  Queries for directories have poor performance due to
having to call real_path on every directory listed in every package's
file list.  Because more than one package will likely own a given
directory, all packages are checked when querying a directory instead
of bailing out after the first owner is found.

Signed-off-by: Andrew Gregory <[email protected]>
---
 src/pacman/query.c |   21 ++++++++++++---------
 1 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/pacman/query.c b/src/pacman/query.c
index 4c2ea81..c64f0d2 100644
--- a/src/pacman/query.c
+++ b/src/pacman/query.c
@@ -127,7 +127,7 @@ static int query_fileowner(alpm_list_t *targets)
         * iteration. */
        root = alpm_option_get_root(config->handle);
        rootlen = strlen(root);
-       if(rootlen + 1 > PATH_MAX) {
+       if(rootlen >= PATH_MAX) {
                /* we are in trouble here */
                pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, "");
                return 1;
@@ -142,6 +142,7 @@ static int query_fileowner(alpm_list_t *targets)
                struct stat buf;
                alpm_list_t *i;
                int found = 0;
+               int searchall = 0;
 
                filename = strdup(t->data);
 
@@ -164,12 +165,14 @@ static int query_fileowner(alpm_list_t *targets)
                        }
                }
 
+               /* make sure directories end with '/' */
                if(S_ISDIR(buf.st_mode)) {
-                       pm_printf(ALPM_LOG_ERROR,
-                               _("cannot determine ownership of directory 
'%s'\n"), filename);
-                       ret++;
-                       free(filename);
-                       continue;
+                       searchall = 1;
+                       size_t fnlen = strlen(filename);
+                       if(filename[fnlen-1] != '/'){
+                               filename = realloc(filename, sizeof(char) * 
(fnlen+2));
+                               strcat(filename, "/");
+                       }
                }
 
                bname = mbasename(filename);
@@ -192,7 +195,7 @@ static int query_fileowner(alpm_list_t *targets)
                }
                free(dname);
 
-               for(i = alpm_db_get_pkgcache(db_local); i && !found; i = 
alpm_list_next(i)) {
+               for(i = alpm_db_get_pkgcache(db_local); i && (searchall || 
!found); i = alpm_list_next(i)) {
                        alpm_pkg_t *info = i->data;
                        alpm_filelist_t *filelist = alpm_pkg_get_files(info);
                        size_t j;
@@ -211,10 +214,10 @@ static int query_fileowner(alpm_list_t *targets)
                                if(!rpath) {
                                        print_query_fileowner(filename, info);
                                        found = 1;
-                                       continue;
+                                       break;
                                }
 
-                               if(rootlen + 1 + strlen(pkgfile) > PATH_MAX) {
+                               if(rootlen + strlen(pkgfile) >= PATH_MAX) {
                                        pm_printf(ALPM_LOG_ERROR, _("path too 
long: %s%s\n"), root, pkgfile);
                                }
                                /* concatenate our file and the root path */
-- 
1.7.7.3


Reply via email to