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 <vsele...@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

_______________________________________________
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint

Reply via email to