From a100cd6bca5b56ef4a8f3ec15ef39efe9d23f1f8 Mon Sep 17 00:00:00 2001 From: Ivy Foster Date: Thu, 25 Jan 2018 14:56:39 -0600 Subject: src/pacman/query.c: do not exit -Qo with error if file does not exist 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 Signed-off-by: Allan McRae --- 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..5c4e0314 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_missing && (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); -- cgit v1.2.3-70-g09d2