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