[Rpm-maint] [PATCH 1/7] lib/rpmdb.c: dbiFindMatches and dbiFindByLabelArch take into account the disttag

Vladimir D. Seleznev vseleznv at altlinux.org
Tue Oct 23 05:48:18 UTC 2018


ALT Linux Team distributions use disttag to differ various package
builds of the same package NEVR, so dbiFindByLabelArch tries to match
the package against name[-[epoch:]version[-release[-disttag]]][.arch].

Signed-off-by: Vladimir D. Seleznev <vseleznv at altlinux.org>
---
 lib/rpmdb.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 53 insertions(+), 7 deletions(-)

diff --git a/lib/rpmdb.c b/lib/rpmdb.c
index 323c4439e..c1fabe615 100644
--- a/lib/rpmdb.c
+++ b/lib/rpmdb.c
@@ -731,13 +731,14 @@ int rpmdbCountPackages(rpmdb db, const char * name)
 }
 
 /**
- * Attempt partial matches on name[-version[-release]][.arch] strings.
+ * Attempt partial matches on name[-version[-release[-disttag]]][.arch] strings.
  * @param db		rpmdb handle
  * @param dbi		index database
  * @param name		package name
  * @param epoch 	package epoch (-1 for any epoch)
  * @param version	package version (can be a pattern)
  * @param release	package release (can be a pattern)
+ * @param disttag	package disttag (can be a pattern)
  * @param arch		package arch (can be a pattern)
  * @retval matches	set of header instances that match
  * @return 		RPMRC_OK on match, RPMRC_NOMATCH or RPMRC_FAIL
@@ -747,6 +748,7 @@ static rpmRC dbiFindMatches(rpmdb db, dbiIndex dbi,
 		int64_t epoch,
 		const char * version,
 		const char * release,
+		const char * disttag,
 		const char * arch,
 		dbiIndexSet * matches)
 {
@@ -761,7 +763,7 @@ static rpmRC dbiFindMatches(rpmdb db, dbiIndex dbi,
 	goto exit;
     
     /* If we got matches on name and nothing else was specified, we're done */
-    if (epoch < 0 && version == NULL && release == NULL && arch == NULL)
+    if (epoch < 0 && version == NULL && release == NULL && disttag == NULL && arch == NULL)
 	goto exit;
 
     /* Make sure the version and release match. */
@@ -788,6 +790,12 @@ static rpmRC dbiFindMatches(rpmdb db, dbiIndex dbi,
 	    rc = RPMRC_FAIL;
 	    goto exit;
 	}
+	if (disttag &&
+	    rpmdbSetIteratorRE(mi, RPMTAG_DISTTAG, RPMMIRE_DEFAULT, disttag))
+	{
+	    rc = RPMRC_FAIL;
+	    goto exit;
+	}
 	if (arch &&
 	    rpmdbSetIteratorRE(mi, RPMTAG_ARCH, RPMMIRE_DEFAULT, arch))
 	{
@@ -825,12 +833,13 @@ exit:
 }
 
 /**
- * Lookup by name, name-version, and finally by name-version-release.
+ * Lookup by name, name-version, name-vesrion-release and finally by
+ * name-version-release-disttag.
  * Both version and release can be patterns.
  * @todo Name must be an exact match, as name is a db key.
  * @param db		rpmdb handle
  * @param dbi		index database handle (always RPMDBI_NAME)
- * @param arg		name[-[epoch:]version[-release]] string
+ * @param arg		name[-[epoch:]version[-release[-disttag]]] string
  * @param arglen	length of arg
  * @param arch		possible arch string (or NULL)
  * @retval matches	set of header instances that match
@@ -844,6 +853,7 @@ static rpmRC dbiFindByLabelArch(rpmdb db, dbiIndex dbi,
     int64_t epoch;
     const char * version;
     const char * release;
+    const char * disttag;
     char * s;
     char c;
     int brackets;
@@ -855,7 +865,7 @@ static rpmRC dbiFindByLabelArch(rpmdb db, dbiIndex dbi,
     localarg[arglen] = '\0';
 
     /* did they give us just a name? */
-    rc = dbiFindMatches(db, dbi, localarg, -1, NULL, NULL, arch, matches);
+    rc = dbiFindMatches(db, dbi, localarg, -1, NULL, NULL, NULL, arch, matches);
     if (rc != RPMRC_NOTFOUND)
 	goto exit;
 
@@ -890,7 +900,7 @@ static rpmRC dbiFindByLabelArch(rpmdb db, dbiIndex dbi,
     *s = '\0';
 
     epoch = splitEpoch(s + 1, &version);
-    rc = dbiFindMatches(db, dbi, localarg, epoch, version, NULL, arch, matches);
+    rc = dbiFindMatches(db, dbi, localarg, epoch, version, NULL, NULL, arch, matches);
     if (rc != RPMRC_NOTFOUND) goto exit;
 
     /* FIX: double indirection */
@@ -924,7 +934,43 @@ static rpmRC dbiFindByLabelArch(rpmdb db, dbiIndex dbi,
     *s = '\0';
    	/* FIX: *matches may be NULL. */
     epoch = splitEpoch(s + 1, &version);
-    rc = dbiFindMatches(db, dbi, localarg, epoch, version, release, arch, matches);
+    rc = dbiFindMatches(db, dbi, localarg, epoch, version, release, NULL, arch, matches);
+    if (rc != RPMRC_NOTFOUND) goto exit;
+
+    /* FIX: double indirection */
+    *matches = dbiIndexSetFree(*matches);
+
+    /* and about name-[epoch:]version-release-disttag? */
+
+    disttag = release;
+    release = s + 1;
+
+    c = '\0';
+    brackets = 0;
+    for (; s > localarg; s--) {
+	switch (*s) {
+	case '[':
+	    brackets = 1;
+	    break;
+	case ']':
+	    if (c != '[') brackets = 0;
+	    break;
+	}
+	if (!brackets && c && *s == '-')
+	    break;
+	c = *s;
+    }
+
+    if (s == localarg) {
+	rc = RPMRC_NOTFOUND;
+	goto exit;
+    }
+
+    *s = '\0';
+       /* FIX: *matches may be NULL. */
+    epoch = splitEpoch(s + 1, &version);
+    rc = dbiFindMatches(db, dbi, localarg, epoch, version, release, disttag, arch, matches);
+
 exit:
     return rc;
 }
-- 
2.17.2



More information about the Rpm-maint mailing list