}
+ char * N = rpmdsN(dep);
-+ if (strstr(N, "uname") == N) {
++ if (strstr(N, "uname(") == N) {
+ if (tsmem->uname == NULL)
-+ rpmdsUnamePool(rpmtsPool(ts), &(tsmem->uname), NULL);
++ rpmdsUnamePool(rpmtsPool(ts), &(tsmem->uname));
+
+ if (tsmem->uname != NULL && rpmdsSearch(tsmem->uname, dep) >= 0) {
+ rpmdsNotify(dep, "(uname provides)", rc);
#include <rpm/rpmtypes.h>
#include <rpm/rpmlib.h> /* rpmvercmp */
-@@ -1596,3 +1597,51 @@ rpmRC rpmdsParseRichDep(rpmds dep, rpmds *leftds, rpmds *rightds, rpmrichOp *op,
+@@ -1596,3 +1597,60 @@ rpmRC rpmdsParseRichDep(rpmds dep, rpmds *leftds, rpmds *rightds, rpmrichOp *op,
return rc;
}
++/**
++ * Merge a single provides, wrapping N as "NS(N)".
++ */
++static int rpmdsNSAdd(rpmstrPool pool, rpmds *dsp, const char * NS,
++ const char *N, const char *EVR, rpmsenseFlags Flags)
++{
++ char *t;
++ rpmds ds;
++ int rc;
++
++ t = (char *) alloca(strlen(NS)+sizeof("()")+strlen(N));
++ *t = '\0';
++ (void) stpcpy( stpcpy( stpcpy( stpcpy(t, NS), "("), N), ")");
++
++ ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME, t, EVR, Flags);
++ rc = rpmdsMerge(dsp, ds);
++ rpmdsFree(ds);
++ return rc;
++}
++
+int rpmdsUnamePool(rpmstrPool pool, rpmds * dsp)
+{
+ int rc = -1;
+ static const char * NS = "uname";
+ struct utsname un;
-+ rpmds ds;
+
+ if (uname(&un) < 0)
+ goto exit;
+
-+ ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME, "uname(sysname)", un.sysname, RPMSENSE_EQUAL);
-+ rc = rpmdsMerge(dsp, ds);
-+ rpmdsFree(ds);
++ rc = rpmdsNSAdd(pool, dsp, NS, "sysname", un.sysname, RPMSENSE_EQUAL);
+ if (rc < 0)
+ goto exit;
-+ ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME, "uname(nodename)", un.nodename, RPMSENSE_EQUAL);
-+ rc = rpmdsMerge(dsp, ds);
-+ rpmdsFree(ds);
++ rc = rpmdsNSAdd(pool, dsp, NS, "nodename", un.nodename, RPMSENSE_EQUAL);
+ if (rc < 0)
+ goto exit;
-+ ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME, "uname(release)", un.release, RPMSENSE_EQUAL);
-+ rc = rpmdsMerge(dsp, ds);
-+ rpmdsFree(ds);
++ rc = rpmdsNSAdd(pool, dsp, NS, "release", un.release, RPMSENSE_EQUAL);
+ if (rc < 0)
+ goto exit;
-+ ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME, "uname(machine)", un.machine, RPMSENSE_EQUAL);
-+ rc = rpmdsMerge(dsp, ds);
-+ rpmdsFree(ds);
++ rc = rpmdsNSAdd(pool, dsp, NS, "machine", un.machine, RPMSENSE_EQUAL);
+ if (rc < 0)
+ goto exit;
+#if defined(__linux__)
-+ ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME, "uname(domainname)", un.domainname, RPMSENSE_EQUAL);
-+ rc = rpmdsMerge(dsp, ds);
-+ rpmdsFree(ds);
++ rc = rpmdsNSAdd(pool, dsp, NS, "domainname", un.domainname, RPMSENSE_EQUAL);
+ if (rc < 0)
+ goto exit;
+#endif
+{
+ return rpmdsUnamePool(NULL, dsp);
+}
+diff --git a/lib/rpmds.h b/lib/rpmds.h
+index 90d54aa27..558252c04 100644
+--- a/lib/rpmds.h
++++ b/lib/rpmds.h
+@@ -412,6 +412,13 @@ int rpmdsNVRMatchesDep(const Header h, const rpmds req, int nopromote);
+ */
+ int rpmdsRpmlib(rpmds * dsp, const void * tblp);
+
++/**
++ * Load uname provides into a dependency set.
++ * @retval *dsp (loaded) dependency set
++ * @return 0 on success
++ */
++int rpmdsUname(rpmds * dsp);
++
+ /** \ingroup rpmds
+ * Create and load a dependency set.
+ * @param pool shared string pool (or NULL for private pool)
+@@ -468,6 +475,14 @@ rpmds rpmdsSinglePoolTix(rpmstrPool pool, rpmTagVal tagN,
+ */
+ int rpmdsRpmlibPool(rpmstrPool pool, rpmds * dsp, const void * tblp);
+
++/**
++ * Load uname provides into a dependency set.
++ * @param pool shared string pool (or NULL for private pool)
++ * @retval *dsp (loaded) dependency set
++ * @return 0 on success
++ */
++int rpmdsUnamePool(rpmstrPool pool, rpmds * dsp);
++
+
+ typedef enum rpmrichOp_e {
+ RPMRICHOP_SINGLE = 1,
diff --git a/lib/rpmts_internal.h b/lib/rpmts_internal.h
index e69ef2584..ecdb12f0c 100644
--- a/lib/rpmts_internal.h