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