Signed-off-by: Andrew Gregory <[email protected]>
---
 src/pacman/query.c | 90 +++++++++++-------------------------------------------
 1 file changed, 17 insertions(+), 73 deletions(-)

diff --git a/src/pacman/query.c b/src/pacman/query.c
index f051571..6befcae 100644
--- a/src/pacman/query.c
+++ b/src/pacman/query.c
@@ -133,11 +133,11 @@ static int query_fileowner(alpm_list_t *targets)
        packages = alpm_db_get_pkgcache(db_local);
 
        for(t = targets; t; t = alpm_list_next(t)) {
-               char *filename = NULL, *dname = NULL, *rpath = NULL;
-               const char *bname;
+               char *filename = NULL;
+               char rpath[PATH_MAX], *rel_path;
                struct stat buf;
                alpm_list_t *i;
-               size_t len, is_dir, bname_len, pbname_len;
+               size_t len, is_dir;
                unsigned int found = 0;
 
                if((filename = strdup(t->data)) == NULL) {
@@ -165,82 +165,28 @@ static int query_fileowner(alpm_list_t *targets)
                        }
                }
 
-               is_dir = S_ISDIR(buf.st_mode) ? 1 : 0;
-               if(is_dir) {
-                       /* the entire filename is safe to resolve if we know it 
points to a dir,
-                        * and it's necessary in case it ends in . or .. */
-                       dname = realpath(filename, NULL);
-                       bname = mbasename(dname);
-                       rpath = mdirname(dname);
-               } else {
-                       bname = mbasename(filename);
-                       dname = mdirname(filename);
-                       rpath = realpath(dname, NULL);
-               }
-
-               bname_len = strlen(bname);
-               pbname_len = bname_len + is_dir;
-
-               if(!dname || !rpath) {
+               if(!lrealpath(filename, rpath)) {
                        pm_printf(ALPM_LOG_ERROR, _("cannot determine real path 
for '%s': %s\n"),
                                        filename, strerror(errno));
                        goto targcleanup;
                }
 
-               for(i = packages; i && (!found || is_dir); i = 
alpm_list_next(i)) {
-                       alpm_pkg_t *info = i->data;
-                       alpm_filelist_t *filelist = alpm_pkg_get_files(info);
-                       size_t j;
-
-                       for(j = 0; j < filelist->count; j++) {
-                               const alpm_file_t *file = filelist->files + j;
-                               char *ppath;
-                               const char *pkgfile = file->name;
-                               size_t pkgfile_len = strlen(pkgfile);
-
-                               /* make sure pkgfile and target are of the same 
type */
-                               if(is_dir != (pkgfile[pkgfile_len - 1] == '/')) 
{
-                                       continue;
-                               }
-
-                               /* make sure pkgfile is long enough */
-                               if(pkgfile_len < pbname_len) {
-                                       continue;
-                               }
-
-                               /* make sure pbname_len takes us to the start 
of a path component */
-                               if(pbname_len != pkgfile_len && 
pkgfile[pkgfile_len - pbname_len - 1] != '/') {
-                                       continue;
-                               }
+               if(strncmp(rpath, path, rootlen) != 0) {
+                       /* file is outside root, we know nothing can own it */
+                       pm_printf(ALPM_LOG_ERROR, _("No package owns %s\n"), 
filename);
+                       goto targcleanup;
+               }
 
-                               /* compare basename with bname */
-                               if(strncmp(pkgfile + pkgfile_len - pbname_len, 
bname, bname_len) != 0) {
-                                       continue;
-                               }
+               rel_path = rpath + rootlen;
 
-                               /* concatenate our dirname and the root path */
-                               if(rootlen + 1 + pkgfile_len - pbname_len > 
PATH_MAX) {
-                                       path[rootlen] = '\0'; /* reset path for 
error message */
-                                       pm_printf(ALPM_LOG_ERROR, _("path too 
long: %s%s\n"), path, pkgfile);
-                                       continue;
-                               }
-                               strncpy(path + rootlen, pkgfile, pkgfile_len - 
pbname_len);
-                               path[rootlen + pkgfile_len - pbname_len] = '\0';
-
-                               ppath = realpath(path, NULL);
-                               if(!ppath) {
-                                       pm_printf(ALPM_LOG_ERROR, _("cannot 
determine real path for '%s': %s\n"),
-                                                       path, strerror(errno));
-                                       continue;
-                               }
+               if((is_dir = S_ISDIR(buf.st_mode))) {
+                       strcat(rpath, "/");
+               }
 
-                               if(strcmp(ppath, rpath) == 0) {
-                                       print_query_fileowner(filename, info);
-                                       found = 1;
-                                       free(ppath);
-                                       break;
-                               }
-                               free(ppath);
+               for(i = packages; i && (!found || is_dir); i = 
alpm_list_next(i)) {
+                       if(alpm_filelist_contains(alpm_pkg_get_files(i->data), 
rel_path)) {
+                               print_query_fileowner(rpath, i->data);
+                               found = 1;
                        }
                }
                if(!found) {
@@ -252,8 +198,6 @@ targcleanup:
                        ret++;
                }
                free(filename);
-               free(rpath);
-               free(dname);
        }
 
        return ret;
-- 
1.8.2.1


Reply via email to