From e3d440de9f5079debe0a7fce7358fcffa2c0b1e1 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Tue, 12 Nov 2024 12:54:19 +0200 Subject: [PATCH] Eliminate realpath(), rpmGetPath() and rpmCleanPath() uses in query code Take advantage of std::filesystem for current directory and canonical path construction, and our own new path manipulation stuff for the rest. Generally speaking there shouldn't be any functional changes here, but we do intentionally disable macro expansion on the path name lookup here now that we can. rpmGetPath() would expand macros, but this made no sense whatsoever in this context because the result is appended to current directory. --- lib/query.cc | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/lib/query.cc b/lib/query.cc index 7b36ee015e..761725fcf6 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -5,6 +5,9 @@ #include "system.h" +#include +#include + #include #include #include @@ -16,11 +19,12 @@ #include #include #include -#include /* rpmCleanPath */ +#include #include #include "rpmgi.hh" #include "manifest.hh" +#include "rpmmacro_internal.hh" #include "debug.h" @@ -405,43 +409,40 @@ static rpmdbMatchIterator initQueryIterator(QVA_t qva, rpmts ts, const char * ar /* fallthrough on absolute and relative paths */ case RPMQV_PATH: case RPMQV_PATH_ALL: - { char * fn; + { std::string fn; for (s = arg; *s != '\0'; s++) if (!(*s == '.' || *s == '/')) break; if (*s == '\0') { - fn = realpath(arg, NULL); - if (!fn) - fn = xstrdup(arg); + std::error_code ec {}; + fn = std::filesystem::canonical(arg); + if (ec) + fn = rpm::normalize_path(arg); } else if (*arg != '/') { - char *curDir = rpmGetCwd(); - fn = (char *) rpmGetPath(curDir, "/", arg, NULL); - free(curDir); - } else - fn = xstrdup(arg); - (void) rpmCleanPath(fn); + fn = rpm::join_path({std::filesystem::current_path(), arg}, false); + } else { + fn = rpm::normalize_path(arg); + } rpmDbiTagVal tag = RPMDBI_INSTFILENAMES; if (qva->qva_source == RPMQV_PATH_ALL) tag = RPMDBI_BASENAMES; - mi = rpmtsInitIterator(ts, tag, fn, 0); + mi = rpmtsInitIterator(ts, tag, fn.c_str(), 0); if (mi == NULL) - mi = rpmtsInitIterator(ts, RPMDBI_PROVIDENAME, fn, 0); + mi = rpmtsInitIterator(ts, RPMDBI_PROVIDENAME, fn.c_str(), 0); if (mi == NULL) { struct stat sb; - char * full_fn = rpmGetPath(rpmtsRootDir(ts), fn, NULL); - if (lstat(full_fn, &sb) != 0) - rpmlog(RPMLOG_ERR, _("file %s: %s\n"), fn, strerror(errno)); + auto full_fn = rpm::join_path({rpmtsRootDir(ts), fn}, false); + if (lstat(full_fn.c_str(), &sb) != 0) + rpmlog(RPMLOG_ERR, _("file %s: %s\n"), fn.c_str(), strerror(errno)); else rpmlog(RPMLOG_NOTICE, - _("file %s is not owned by any package\n"), fn); - free(full_fn); + _("file %s is not owned by any package\n"), fn.c_str()); } - free(fn); } break; case RPMQV_DBOFFSET: