diff --git a/lib/depends.c b/lib/depends.c index 28a4a784d..1d8ce1f8a 100644 --- a/lib/depends.c +++ b/lib/depends.c @@ -690,6 +690,17 @@ retry: goto unsatisfied; } + char * N = rpmdsN(dep); + if (strstr(N, "uname(") == N) { + if (tsmem->uname == NULL) + rpmdsUnamePool(rpmtsPool(ts), &(tsmem->uname)); + + if (tsmem->uname != NULL && rpmdsSearch(tsmem->uname, dep) >= 0) { + rpmdsNotify(dep, "(uname provides)", rc); + goto exit; + } + } + /* Dont look at pre-requisites of already installed packages */ if (!adding && isTransientReq(dsflags)) goto exit; diff --git a/lib/rpmds.c b/lib/rpmds.c index f7ee76392..754969e39 100644 --- a/lib/rpmds.c +++ b/lib/rpmds.c @@ -2,6 +2,7 @@ * \file lib/rpmds.c */ #include "system.h" +#include #include #include /* rpmvercmp */ @@ -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; + + if (uname(&un) < 0) + goto exit; + + rc = rpmdsNSAdd(pool, dsp, NS, "sysname", un.sysname, RPMSENSE_EQUAL); + if (rc < 0) + goto exit; + rc = rpmdsNSAdd(pool, dsp, NS, "nodename", un.nodename, RPMSENSE_EQUAL); + if (rc < 0) + goto exit; + rc = rpmdsNSAdd(pool, dsp, NS, "release", un.release, RPMSENSE_EQUAL); + if (rc < 0) + goto exit; + rc = rpmdsNSAdd(pool, dsp, NS, "machine", un.machine, RPMSENSE_EQUAL); + if (rc < 0) + goto exit; +#if defined(__linux__) + rc = rpmdsNSAdd(pool, dsp, NS, "domainname", un.domainname, RPMSENSE_EQUAL); + if (rc < 0) + goto exit; +#endif +exit: + /* freeze the pool to save memory, but only if private pool */ + if (*dsp && (*dsp)->pool != pool) + rpmstrPoolFreeze((*dsp)->pool, 0); + return (rc < 0) ? -1 : 0; +} + +int rpmdsUname(rpmds * dsp) +{ + 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 +++ b/lib/rpmts_internal.h @@ -21,6 +21,7 @@ typedef struct tsMembers_s { rpmal addedPackages; /*!< Set of packages being installed. */ rpmds rpmlib; /*!< rpmlib() dependency set. */ + rpmds uname; /*!< uname() dependency set. */ rpmte * order; /*!< Packages sorted by dependencies. */ int orderCount; /*!< No. of transaction elements. */ int orderAlloced; /*!< No. of allocated transaction elements. */