From a95afc43831336a8dfcf8ade6861d43c7a733d34 Mon Sep 17 00:00:00 2001 From: Michal Domonkos Date: Mon, 16 Aug 2021 17:22:04 +0200 Subject: [PATCH] Add support for RPMDBI_BASENAMES on file queries There are legitimate reasons (such as rhbz#1940895 or the included test) for wanting the former behavior where all file states were considered in file queries prior to commit 9ad57bda4a82b9847826daa766b4421d877bb3d9, so celebrate the tenth anniversary of that commit by adding a CLI switch (a new package selector) for that, as contemplated back then. Resolves: rhbz#1940895 --- docs/man/rpm.8.md | 11 ++++++++++- lib/poptQV.c | 4 ++++ lib/query.c | 7 +++++-- lib/rpmcli.h | 1 + tests/rpmquery.at | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 3 deletions(-) diff --git a/docs/man/rpm.8.md b/docs/man/rpm.8.md index 323f68c3e7..fbb6cdc383 100644 --- a/docs/man/rpm.8.md +++ b/docs/man/rpm.8.md @@ -57,7 +57,7 @@ select-options -------------- \[*PACKAGE\_NAME*\] \[**-a,\--all \[***SELECTOR*\]\] \[**-f,\--file -***FILE*\] \[**-g,\--group ***GROUP*\] \[**-p,\--package +***FILE*\] \[**\--path ***PATH*\] \[**-g,\--group ***GROUP*\] \[**-p,\--package ***PACKAGE\_FILE*\] \[**\--hdrid ***SHA1*\] \[**\--pkgid ***MD5*\] \[**\--tid ***TID*\] \[**\--querybynumber ***HDRNUM*\] \[**\--triggeredby ***PACKAGE\_NAME*\] \[**\--whatprovides @@ -667,6 +667,15 @@ name starts with \"b\". substituted in place of the package manifest as additional *PACKAGE\_FILE* arguments to the query. +**\--path ***PATH* + +: Query package owning *PATH*. Like **\--file**, but not limited to installed + files only, i.e. *PATH* will be matched against all files in the database, + not just those in the *normal* or *net shared* state. Useful when querying + a partially installed package, such as one that was installed with the + **\--excludepath** option. See the description of **\--state** for a list + of all possible file states. + **\--pkgid ***MD5* : Query package that contains a given package identifier, i.e. the diff --git a/lib/poptQV.c b/lib/poptQV.c index d9d1fad759..f7ed8720cc 100644 --- a/lib/poptQV.c +++ b/lib/poptQV.c @@ -27,6 +27,7 @@ struct rpmQVKArguments_s rpmQVKArgs; #define POPT_WHATENHANCES -1014 #define POPT_WHATOBSOLETES -1015 #define POPT_WHATCONFLICTS -1016 +#define POPT_QUERYBYPATH -1017 /* ========== Query/Verify/Signature source args */ static void rpmQVSourceArgCallback( poptContext con, @@ -58,6 +59,7 @@ static void rpmQVSourceArgCallback( poptContext con, case POPT_WHATSUPPLEMENTS: qva->qva_source |= RPMQV_WHATSUPPLEMENTS; break; case POPT_WHATENHANCES: qva->qva_source |= RPMQV_WHATENHANCES; break; case POPT_TRIGGEREDBY: qva->qva_source |= RPMQV_TRIGGEREDBY; break; + case POPT_QUERYBYPATH: qva->qva_source |= RPMQV_PATH_ALL; break; case POPT_QUERYBYPKGID: qva->qva_source |= RPMQV_PKGID; break; case POPT_QUERYBYHDRID: qva->qva_source |= RPMQV_HDRID; break; case POPT_QUERYBYTID: qva->qva_source |= RPMQV_TID; break; @@ -81,6 +83,8 @@ struct poptOption rpmQVSourcePoptTable[] = { N_("rpm checksig mode"), NULL }, { "file", 'f', 0, 0, 'f', N_("query/verify package(s) owning file"), "FILE" }, + { "path", '\0', 0, 0, POPT_QUERYBYPATH, + N_("query/verify package(s) owning file (all states)"), "PATH" }, { "group", 'g', 0, 0, 'g', N_("query/verify package(s) in group"), "GROUP" }, { "package", 'p', 0, 0, 'p', diff --git a/lib/query.c b/lib/query.c index d09aa2aaf3..b81d8c7708 100644 --- a/lib/query.c +++ b/lib/query.c @@ -445,6 +445,7 @@ 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; for (s = arg; *s != '\0'; s++) @@ -463,8 +464,10 @@ static rpmdbMatchIterator initQueryIterator(QVA_t qva, rpmts ts, const char * ar fn = xstrdup(arg); (void) rpmCleanPath(fn); - /* XXX Add a switch to enable former BASENAMES behavior? */ - mi = rpmtsInitIterator(ts, RPMDBI_INSTFILENAMES, fn, 0); + rpmDbiTagVal tag = RPMDBI_INSTFILENAMES; + if (qva->qva_source == RPMQV_PATH_ALL) + tag = RPMDBI_BASENAMES; + mi = rpmtsInitIterator(ts, tag, fn, 0); if (mi == NULL) mi = rpmtsInitIterator(ts, RPMDBI_PROVIDENAME, fn, 0); diff --git a/lib/rpmcli.h b/lib/rpmcli.h index 41165c3c0c..906fe99513 100644 --- a/lib/rpmcli.h +++ b/lib/rpmcli.h @@ -81,6 +81,7 @@ rpmcliFini(poptContext optCon); enum rpmQVSources_e { RPMQV_PACKAGE = 0, /*!< ... from package name db search. */ RPMQV_PATH, /*!< ... from file path db search. */ + RPMQV_PATH_ALL, /*!< ... from file path db search (all states). */ RPMQV_ALL, /*!< ... from each installed package. */ RPMQV_RPM, /*!< ... from reading binary rpm package. */ RPMQV_GROUP, /*!< ... from group db search. */ diff --git a/tests/rpmquery.at b/tests/rpmquery.at index ff2ea54c3b..db8671b264 100644 --- a/tests/rpmquery.at +++ b/tests/rpmquery.at @@ -219,6 +219,40 @@ runroot rpm \ []) AT_CLEANUP +AT_SETUP([rpm -qf on non-installed file]) +AT_KEYWORDS([query]) +AT_CHECK([ +RPMDB_INIT +runroot rpm \ + --nodeps \ + --excludedocs \ + -i /data/RPMS/hello-1.0-1.i386.rpm +runroot rpm \ + -qf /usr/share/doc/hello-1.0/FAQ +], +[1], +[], +[error: file /usr/share/doc/hello-1.0/FAQ: No such file or directory +]) +AT_CLEANUP + +AT_SETUP([rpm -q --path on non-installed file]) +AT_KEYWORDS([query]) +AT_CHECK([ +RPMDB_INIT +runroot rpm \ + --nodeps \ + --excludedocs \ + -i /data/RPMS/hello-1.0-1.i386.rpm +runroot rpm \ + -q --path /usr/share/doc/hello-1.0/FAQ +], +[0], +[hello-1.0-1.i386 +], +[]) +AT_CLEANUP + # ------------------------------ AT_SETUP([integer array query]) AT_KEYWORDS([query])