From: Andrew Gregory <andrew.gregory.8@gmail.com> 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 <andrew.gregory.8@gmail.com> --- 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