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