From: Ivy Foster <iff@escondida.tk> Query operations act on the local db, not the filesystem. Also, a valid use case for -Qo is to discover what package owns a deleted file so it can be reinstalled. Closes FS#55856. Signed-off-by: Ivy Foster <iff@escondida.tk> --- My apologies for missing the earlier patch's problems with missing dirs. Frankly, I don't know how I missed it. This one really, honest-to-goodness *does* find missing dirs, as long the user passes the dirname with a slash at the end, as well as missing files. Enjoy! src/pacman/query.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/pacman/query.c b/src/pacman/query.c index 91ca78a7..39f8dabf 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -160,7 +160,7 @@ static int query_fileowner(alpm_list_t *targets) alpm_list_t *i; size_t len; unsigned int found = 0; - int is_dir; + int is_dir = 0, is_missing = 0; if((filename = strdup(t->data)) == NULL) { goto targcleanup; @@ -175,27 +175,21 @@ static int query_fileowner(alpm_list_t *targets) len = strlen(filename) - 1; while(len > 0 && filename[len] == '/') { filename[len--] = '\0'; + /* If a non-dir file exists, S_ISDIR will correct this later. */ + is_dir = 1; } if(lstat(filename, &buf) == -1) { + is_missing = 1; /* 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_printf(ALPM_LOG_ERROR, _("failed to find '%s' in PATH: %s\n"), - filename, strerror(errno)); - goto targcleanup; - } - } else { - pm_printf(ALPM_LOG_ERROR, _("failed to read file '%s': %s\n"), - filename, strerror(errno)); - goto targcleanup; + if ((strchr(filename, '/') == NULL) && (search_path(&filename, &buf) == 0)) { + is_missing = 0; } } if(!lrealpath(filename, rpath)) { - pm_printf(ALPM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"), - filename, strerror(errno)); - goto targcleanup; + /* Can't canonicalize path, try to proceed anyway */ + strncpy(rpath, filename, PATH_MAX); } if(strncmp(rpath, root, rootlen) != 0) { @@ -206,7 +200,7 @@ static int query_fileowner(alpm_list_t *targets) rel_path = rpath + rootlen; - if((is_dir = S_ISDIR(buf.st_mode))) { + if((is_missing && is_dir) || (is_dir = S_ISDIR(buf.st_mode))) { size_t rlen = strlen(rpath); if(rlen + 2 >= PATH_MAX) { pm_printf(ALPM_LOG_ERROR, _("path too long: %s/\n"), rpath); -- 2.16.1