michal-grzedzicki / rpms / rpm

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