[Rpm-maint] [PATCH 2/2] Recognize "<epoch>:" as a part of a label (ticket #117)
Ales Kozumplik
akozumpl at redhat.com
Fri Nov 11 11:09:15 UTC 2011
- for instance this works now:
$ rpm -q perl-4:5.14.1-188.fc16.x86_64
perl-5.14.1-188.fc16.x86_64
---
lib/rpmdb.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
index e249998..4c0af2d 100644
--- a/lib/rpmdb.c
+++ b/lib/rpmdb.c
@@ -118,6 +118,29 @@ static unsigned int uintId(unsigned int a)
}
/** \ingroup dbi
+ * Return (newly allocated) integer of the epoch.
+ * @param s version string optionally containing epoch number
+ * @retval version only the version part of s
+ * @return newly allocated epoch integer
+ */
+static int * splitEpoch(const char *s, const char **version)
+{
+ int e;
+ int *epoch = NULL;
+ char *end;
+
+ *version = s;
+
+ e = strtol(s, &end, 10);
+ if (*end == ':') {
+ *version = end + 1;
+ epoch = rmalloc(sizeof(*epoch));
+ *epoch = e;
+ }
+ return epoch;
+}
+
+/** \ingroup dbi
* Return handle for an index database.
* @param db rpm database
* @param rpmtag rpm tag
@@ -1026,6 +1049,7 @@ int rpmdbCountPackages(rpmdb db, const char * name)
* @param db rpmdb handle
* @param dbc index database cursor
* @param name package name
+ * @param epoch package epoch
* @param version package version (can be a pattern)
* @param release package release (can be a pattern)
* @retval matches set of header instances that match
@@ -1033,6 +1057,7 @@ int rpmdbCountPackages(rpmdb db, const char * name)
*/
static rpmRC dbiFindMatches(rpmdb db, dbiCursor dbc,
const char * name,
+ int * epoch,
const char * version,
const char * release,
dbiIndexSet * matches)
@@ -1045,7 +1070,7 @@ static rpmRC dbiFindMatches(rpmdb db, dbiCursor dbc,
if (rc != 0) {
return (rc == DB_NOTFOUND) ? RPMRC_NOTFOUND : RPMRC_FAIL;
- } else if (version == NULL && release == NULL) {
+ } else if (epoch == NULL && version == NULL && release == NULL) {
return RPMRC_OK;
}
@@ -1075,6 +1100,14 @@ static rpmRC dbiFindMatches(rpmdb db, dbiCursor dbc,
}
h = rpmdbNextIterator(mi);
+
+ if (epoch && h) {
+ struct rpmtd_s td;
+ headerGet(h, RPMTAG_EPOCH, &td, HEADERGET_MINMEM);
+ if (*epoch != rpmtdGetNumber(&td))
+ h = NULL;
+ rpmtdFreeData(&td);
+ }
if (h)
(*matches)->recs[gotMatches++] = (*matches)->recs[i];
else
@@ -1101,7 +1134,7 @@ exit:
* @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[-version[-release]] string
+ * @param arg name[-[epoch:]version[-release]] string
* @retval matches set of header instances that match
* @return RPMRC_OK on match, RPMRC_NOMATCH or RPMRC_FAIL
*/
@@ -1110,25 +1143,27 @@ static rpmRC dbiFindByLabel(rpmdb db, dbiIndex dbi, const char * arg,
{
size_t arglen = (arg != NULL) ? strlen(arg) : 0;
char localarg[arglen+1];
+ int * epoch;
+ const char * version;
const char * release;
char * s;
char c;
int brackets;
rpmRC rc;
dbiCursor dbc;
-
+
if (arglen == 0) return RPMRC_NOTFOUND;
dbc = dbiCursorInit(dbi, 0);
/* did they give us just a name? */
- rc = dbiFindMatches(db, dbc, arg, NULL, NULL, matches);
+ rc = dbiFindMatches(db, dbc, arg, NULL, NULL, NULL, matches);
if (rc != RPMRC_NOTFOUND)
goto exit;
/* FIX: double indirection */
*matches = dbiIndexSetFree(*matches);
- /* maybe a name and a release */
+ /* maybe a name-[epoch:]version ? */
s = stpcpy(localarg, arg);
c = '\0';
@@ -1154,13 +1189,16 @@ static rpmRC dbiFindByLabel(rpmdb db, dbiIndex dbi, const char * arg,
}
*s = '\0';
- rc = dbiFindMatches(db, dbc, localarg, s + 1, NULL, matches);
+
+ epoch = splitEpoch(s + 1, &version);
+ rc = dbiFindMatches(db, dbc, localarg, epoch, version, NULL, matches);
+ rfree(epoch);
if (rc != RPMRC_NOTFOUND) goto exit;
/* FIX: double indirection */
*matches = dbiIndexSetFree(*matches);
-
- /* how about name-version-release? */
+
+ /* how about name-[epoch:]version-release? */
release = s + 1;
@@ -1187,7 +1225,9 @@ static rpmRC dbiFindByLabel(rpmdb db, dbiIndex dbi, const char * arg,
*s = '\0';
/* FIX: *matches may be NULL. */
- rc = dbiFindMatches(db, dbc, localarg, s + 1, release, matches);
+ epoch = splitEpoch(s + 1, &version);
+ rc = dbiFindMatches(db, dbc, localarg, epoch, version, release, matches);
+ rfree(epoch);
exit:
dbiCursorFree(dbc);
return rc;
--
1.7.6.4
More information about the Rpm-maint
mailing list