c7b760
From 5e26aa82fb1792c0441131db8dc87976d2d653bb 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
c7b760
Combined with d1aebda01033bc8ba0d748b49f6fad9a5c0caa3f and backported
c7b760
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
c7b760
index 99af2585a..330fd956f 100644
c7b760
--- a/lib/rpmcli.h
c7b760
+++ b/lib/rpmcli.h
c7b760
@@ -82,6 +82,7 @@ rpmcliFini(poptContext optCon);
c7b760
 enum rpmQVSources_e {
c7b760
     RPMQV_PACKAGE = 0,	/*!< ... from package name db search. */
c7b760
     RPMQV_PATH,		/*!< ... from file path db search. */
c7b760
+    RPMQV_PATH_ALL,	/*!< ... from file path db search (all states). */
c7b760
     RPMQV_ALL,		/*!< ... from each installed package. */
c7b760
     RPMQV_RPM, 		/*!< ... from reading binary rpm package. */
c7b760
     RPMQV_GROUP,	/*!< ... from group db search. */
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
-- 
c7b760
2.33.1
c7b760