507a44
From 013cd4ba63c35fa75feeccde0022d56e68bc5845 Mon Sep 17 00:00:00 2001
686848
From: Michal Domonkos <mdomonko@redhat.com>
686848
Date: Mon, 16 Aug 2021 18:21:02 +0200
686848
Subject: [PATCH] Add support for RPMDBI_BASENAMES on file queries
686848
686848
There are legitimate reasons (such as rhbz#1940895 or the included test)
686848
for wanting the former behavior where all file states were considered in
686848
file queries prior to commit 9ad57bda4a82b9847826daa766b4421d877bb3d9,
686848
so celebrate the tenth anniversary of that commit by adding a CLI switch
686848
(a new package selector --path), as contemplated back then.
686848
686848
Update the man page for --file to reflect it's current behavior and make
686848
--path that more obvious.
686848
686848
Resolves: rhbz#1940895
686848
507a44
Combined with:
507a44
d1aebda01033bc8ba0d748b49f6fad9a5c0caa3f
507a44
f62b6d27cd741406a52a7e9c5b1d6f581dbd3af8
507a44
507a44
Backported for 4.14.3.
686848
---
686848
 doc/rpm.8         |  9 ++++++--
686848
 lib/poptQV.c      |  6 +++++-
686848
 lib/query.c       |  7 +++++--
686848
 lib/rpmcli.h      |  1 +
686848
 tests/rpmquery.at | 52 +++++++++++++++++++++++++++++++++++++++++++++++
686848
 5 files changed, 70 insertions(+), 5 deletions(-)
686848
686848
diff --git a/doc/rpm.8 b/doc/rpm.8
686848
index 15a3db25f..74604c8ec 100644
686848
--- a/doc/rpm.8
686848
+++ b/doc/rpm.8
686848
@@ -57,7 +57,7 @@ rpm \- RPM Package Manager
686848
 .PP
686848
 
686848
  [\fB\fIPACKAGE_NAME\fB\fR]
686848
- [\fB-a,--all [\fISELECTOR\fR]\fR] [\fB-f,--file \fIFILE\fB\fR]
686848
+ [\fB-a,--all [\fISELECTOR\fR]\fR] [\fB-f,--file \fIFILE\fB\fR] [\fB--path \fIPATH\fB\fR]
686848
  [\fB-g,--group \fIGROUP\fB\fR] {\fB-p,--package \fIPACKAGE_FILE\fB\fR]
686848
  [\fB--hdrid \fISHA1\fB\fR] [\fB--pkgid \fIMD5\fB\fR] [\fB--tid \fITID\fB\fR]
686848
  [\fB--querybynumber \fIHDRNUM\fB\fR] [\fB--triggeredby \fIPACKAGE_NAME\fB\fR]
686848
@@ -555,7 +555,7 @@ starts with "b".
686848
 List duplicated packages.
686848
 .TP
686848
 \fB-f, --file \fIFILE\fB\fR
686848
-Query package owning \fIFILE\fR.
686848
+Query package owning installed \fIFILE\fR.
686848
 .TP
686848
 \fB--filecaps\fR
686848
 List file names with POSIX1.e capabilities.
686848
@@ -598,6 +598,11 @@ that will be expanded to paths that are substituted in place of
686848
 the package manifest as additional \fIPACKAGE_FILE\fR
686848
 arguments to the query.
686848
 .TP
686848
+\fB--path \fIPATH\fB\fR
686848
+Query package(s) owning \fIPATH\fR, whether the file is installed or not.
686848
+Multiple packages may own a \fIPATH\fR, but the file is only owned by the
686848
+package installed last.
686848
+.TP
686848
 \fB--pkgid \fIMD5\fB\fR
686848
 Query package that contains a given package identifier, i.e. the
686848
 \fIMD5\fR digest of the combined header and
686848
diff --git a/lib/poptQV.c b/lib/poptQV.c
686848
index 9021d7b3c..f752d8b82 100644
686848
--- a/lib/poptQV.c
686848
+++ b/lib/poptQV.c
686848
@@ -27,6 +27,7 @@ struct rpmQVKArguments_s rpmQVKArgs;
686848
 #define POPT_WHATENHANCES	-1014
686848
 #define POPT_WHATOBSOLETES	-1015
686848
 #define POPT_WHATCONFLICTS	-1016
686848
+#define POPT_QUERYBYPATH	-1017
686848
 
686848
 /* ========== Query/Verify/Signature source args */
686848
 static void rpmQVSourceArgCallback( poptContext con,
686848
@@ -58,6 +59,7 @@ static void rpmQVSourceArgCallback( poptContext con,
686848
     case POPT_WHATSUPPLEMENTS: qva->qva_source |= RPMQV_WHATSUPPLEMENTS; break;
686848
     case POPT_WHATENHANCES: qva->qva_source |= RPMQV_WHATENHANCES; break;
686848
     case POPT_TRIGGEREDBY: qva->qva_source |= RPMQV_TRIGGEREDBY; break;
686848
+    case POPT_QUERYBYPATH: qva->qva_source |= RPMQV_PATH_ALL; break;
686848
     case POPT_QUERYBYPKGID: qva->qva_source |= RPMQV_PKGID; break;
686848
     case POPT_QUERYBYHDRID: qva->qva_source |= RPMQV_HDRID; break;
686848
     case POPT_QUERYBYTID: qva->qva_source |= RPMQV_TID; break;
686848
@@ -80,7 +82,9 @@ struct poptOption rpmQVSourcePoptTable[] = {
686848
  { "checksig", 'K', POPT_ARGFLAG_DOC_HIDDEN, NULL, 'K',
686848
 	N_("rpm checksig mode"), NULL },
686848
  { "file", 'f', 0, 0, 'f',
686848
-	N_("query/verify package(s) owning file"), "FILE" },
686848
+	N_("query/verify package(s) owning installed file"), "FILE" },
686848
+ { "path", '\0', 0, 0, POPT_QUERYBYPATH,
686848
+	N_("query/verify package(s) owning path, installed or not"), "PATH" },
686848
  { "group", 'g', 0, 0, 'g',
686848
 	N_("query/verify package(s) in group"), "GROUP" },
686848
  { "package", 'p', 0, 0, 'p',
686848
diff --git a/lib/query.c b/lib/query.c
686848
index 26cdecf10..e6ea1fa2d 100644
686848
--- a/lib/query.c
686848
+++ b/lib/query.c
686848
@@ -440,6 +440,7 @@ static rpmdbMatchIterator initQueryIterator(QVA_t qva, rpmts ts, const char * ar
686848
 	}
686848
 	/* fallthrough on absolute and relative paths */
686848
     case RPMQV_PATH:
686848
+    case RPMQV_PATH_ALL:
686848
     {   char * fn;
686848
 
686848
 	for (s = arg; *s != '\0'; s++)
686848
@@ -458,8 +459,10 @@ static rpmdbMatchIterator initQueryIterator(QVA_t qva, rpmts ts, const char * ar
686848
 	    fn = xstrdup(arg);
686848
 	(void) rpmCleanPath(fn);
686848
 
686848
-	/* XXX Add a switch to enable former BASENAMES behavior? */
686848
-	mi = rpmtsInitIterator(ts, RPMDBI_INSTFILENAMES, fn, 0);
686848
+	rpmDbiTagVal tag = RPMDBI_INSTFILENAMES;
686848
+	if (qva->qva_source == RPMQV_PATH_ALL)
686848
+	    tag = RPMDBI_BASENAMES;
686848
+	mi = rpmtsInitIterator(ts, tag, fn, 0);
686848
 	if (mi == NULL)
686848
 	    mi = rpmtsInitIterator(ts, RPMDBI_PROVIDENAME, fn, 0);
686848
 
686848
diff --git a/lib/rpmcli.h b/lib/rpmcli.h
507a44
index 99af2585a..c0d07d137 100644
686848
--- a/lib/rpmcli.h
686848
+++ b/lib/rpmcli.h
507a44
@@ -102,6 +102,7 @@ enum rpmQVSources_e {
507a44
     RPMQV_SPECBUILTRPMS,	/*!< ... from pkgs which would be built from spec */
507a44
     RPMQV_WHATOBSOLETES,	/*!< ... from obsoletes db search. */
507a44
     RPMQV_WHATCONFLICTS,	/*!< ... from conflicts db search. */
686848
+    RPMQV_PATH_ALL,	/*!< ... from file path db search (all states). */
507a44
 };
507a44
 
507a44
 typedef rpmFlags rpmQVSources;
686848
diff --git a/tests/rpmquery.at b/tests/rpmquery.at
686848
index 36c62339a..ad580f664 100644
686848
--- a/tests/rpmquery.at
686848
+++ b/tests/rpmquery.at
686848
@@ -194,6 +194,58 @@ runroot rpm \
686848
 
686848
 AT_CLEANUP
686848
 
686848
+# ------------------------------
686848
+# query a package by a file
686848
+AT_SETUP([rpm -qf])
686848
+AT_KEYWORDS([query])
686848
+AT_CHECK([
686848
+RPMDB_INIT
686848
+runroot rpm \
686848
+  --nodeps \
686848
+  -i /data/RPMS/hello-1.0-1.i386.rpm
686848
+runroot rpm \
686848
+  -qf /usr/local/bin/hello
686848
+],
686848
+[0],
686848
+[hello-1.0-1.i386
686848
+],
686848
+[])
686848
+AT_CLEANUP
686848
+
686848
+AT_SETUP([rpm -qf on non-installed file])
686848
+AT_KEYWORDS([query])
686848
+AT_CHECK([
686848
+RPMDB_INIT
686848
+runroot rpm \
686848
+  --nodeps \
686848
+  --excludedocs \
686848
+  -i /data/RPMS/hello-1.0-1.i386.rpm
686848
+runroot rpm \
686848
+  -qf /usr/share/doc/hello-1.0/FAQ
686848
+],
686848
+[1],
686848
+[],
686848
+[error: file /usr/share/doc/hello-1.0/FAQ: No such file or directory
686848
+])
686848
+AT_CLEANUP
686848
+
686848
+AT_SETUP([rpm -q --path on non-installed file])
686848
+AT_KEYWORDS([query])
686848
+AT_CHECK([
686848
+RPMDB_INIT
686848
+runroot rpm \
686848
+  --nodeps \
686848
+  --excludedocs \
686848
+  -i /data/RPMS/hello-1.0-1.i386.rpm
686848
+runroot rpm \
686848
+  -q --path /usr/share/doc/hello-1.0/FAQ
686848
+],
686848
+[0],
686848
+[hello-1.0-1.i386
686848
+],
686848
+[])
686848
+AT_CLEANUP
686848
+
686848
 # ------------------------------
686848
 AT_SETUP([integer array query])
686848
 AT_KEYWORDS([query])
686848
-- 
507a44
2.35.1
686848