diff options
Diffstat (limited to 'build/rpmfc.c')
-rw-r--r-- | build/rpmfc.c | 775 |
1 files changed, 410 insertions, 365 deletions
diff --git a/build/rpmfc.c b/build/rpmfc.c index f8e340288..2fbfc69ab 100644 --- a/build/rpmfc.c +++ b/build/rpmfc.c @@ -1,6 +1,7 @@ #include "system.h" #include <errno.h> +#include <libgen.h> #include <sys/select.h> #include <sys/wait.h> #include <signal.h> @@ -16,6 +17,7 @@ #include <rpm/rpmfi.h> #include <rpm/rpmstrpool.h> +#include "lib/rpmfi_internal.h" /* rpmfiles stuff for now */ #include "build/rpmbuild_internal.h" #include "debug.h" @@ -32,13 +34,24 @@ typedef struct rpmfcAttr_s { struct matchRule excl; } * rpmfcAttr; +typedef struct { + int fileIx; + rpmds dep; +} rpmfcFileDep; + +typedef struct { + rpmfcFileDep *data; + int size; + int alloced; +} rpmfcFileDeps; + /** */ struct rpmfc_s { + Package pkg; int nfiles; /*!< no. of files */ int fknown; /*!< no. of classified files */ int fwhite; /*!< no. of "white" files */ - int ix; /*!< current file index */ int skipProv; /*!< Don't auto-generate Provides:? */ int skipReq; /*!< Don't auto-generate Requires:? */ char *buildRoot; /*!< (Build) root dir */ @@ -54,11 +67,9 @@ struct rpmfc_s { ARGI_t fddictn; /*!< (no. files) file depends dictionary no. entries */ ARGI_t ddictx; /*!< (no. dependencies) file->dependency mapping */ rpmstrPool cdict; /*!< file class dictionary */ - rpmstrPool ddict; /*!< file depends dictionary */ + rpmfcFileDeps fileDeps; /*!< file dependency mapping */ - rpmds provides; /*!< (no. provides) package provides */ - rpmds requires; /*!< (no. requires) package requires */ - rpmds supplements; /*!< (no. supplements) package supplements */ + rpmstrPool pool; /*!< general purpose string storage */ }; struct rpmfcTokens_s { @@ -87,22 +98,62 @@ static void ruleFree(struct matchRule *rule) argvFree(rule->flags); } -static char *rpmfcAttrMacro(const char *name, - const char *attr_prefix, const char *attr) +static char *rpmfcAttrMacroV(const char *arg, va_list args) { - char *ret; - if (attr_prefix && attr_prefix[0] != '\0') - ret = rpmExpand("%{?__", name, "_", attr_prefix, "_", attr, "}", NULL); - else - ret = rpmExpand("%{?__", name, "_", attr, "}", NULL); - return rstreq(ret, "") ? _free(ret) : ret; + const char *s; + int blen; + char *buf = NULL, *obuf; + char *pe; + va_list args2; + + if (arg == NULL || rstreq(arg, "")) + return NULL; + + va_copy(args2, args); + blen = sizeof("%{?_") - 1; + for (s = arg; s != NULL; s = va_arg(args, const char *)) { + blen += sizeof("_") - 1 + strlen(s); + } + blen += sizeof("}") - 1; + + buf = xmalloc(blen + 1); + + pe = buf; + pe = stpcpy(pe, "%{?_"); + for (s = arg; s != NULL; s = va_arg(args2, const char *)) { + *pe++ = '_'; + pe = stpcpy(pe, s); + } + va_end(args2); + *pe++ = '}'; + *pe = '\0'; + + obuf = rpmExpand(buf, NULL); + free(buf); + + return rstreq(obuf, "") ? _free(obuf) : obuf; } -static regex_t *rpmfcAttrReg(const char *name, - const char *attr_prefix, const char *attr) +static char *rpmfcAttrMacro(const char *arg, ...) +{ + va_list args; + char *s; + + va_start(args, arg); + s = rpmfcAttrMacroV(arg, args); + va_end(args); + return s; +} + +static regex_t *rpmfcAttrReg(const char *arg, ...) { regex_t *reg = NULL; - char *pattern = rpmfcAttrMacro(name, attr_prefix, attr); + char *pattern; + va_list args; + + va_start(args, arg); + pattern = rpmfcAttrMacroV(arg, args); + va_end(args); if (pattern) { reg = xcalloc(1, sizeof(*reg)); if (regcomp(reg, pattern, REG_EXTENDED) != 0) { @@ -122,10 +173,19 @@ static rpmfcAttr rpmfcAttrNew(const char *name) attr->name = xstrdup(name); for (struct matchRule **rule = rules; rule && *rule; rule++) { const char *prefix = (*rule == &attr->incl) ? NULL : "exclude"; - char *flags = rpmfcAttrMacro(name, prefix, "flags"); + char *flags; + + if (prefix) { + flags = rpmfcAttrMacro(name, prefix, "flags", NULL); - (*rule)->path = rpmfcAttrReg(name, prefix, "path"); - (*rule)->magic = rpmfcAttrReg(name, prefix, "magic"); + (*rule)->path = rpmfcAttrReg(name, prefix, "path", NULL); + (*rule)->magic = rpmfcAttrReg(name, prefix, "magic", NULL); + } else { + flags = rpmfcAttrMacro(name, "flags", NULL); + + (*rule)->path = rpmfcAttrReg(name, "path", NULL); + (*rule)->magic = rpmfcAttrReg(name, "magic", NULL); + } (*rule)->flags = argvSplitString(flags, ",", ARGV_SKIPEMPTY); argvSort((*rule)->flags, NULL); @@ -163,16 +223,17 @@ static int rpmfcExpandAppend(ARGV_t * argvp, ARGV_const_t av) return 0; } -static rpmds rpmdsSingleNS(rpmTagVal tagN, const char *namespace, +static rpmds rpmdsSingleNS(rpmstrPool pool, + rpmTagVal tagN, const char *namespace, const char * N, const char * EVR, rpmsenseFlags Flags) { rpmds ds = NULL; if (namespace) { char *NSN = rpmExpand(namespace, "(", N, ")", NULL); - ds = rpmdsSingle(tagN, NSN, EVR, Flags); + ds = rpmdsSinglePool(pool, tagN, NSN, EVR, Flags); free(NSN); } else { - ds = rpmdsSingle(tagN, N, EVR, Flags); + ds = rpmdsSinglePool(pool, tagN, N, EVR, Flags); } return ds; } @@ -208,8 +269,6 @@ static StringBuf getOutputFrom(ARGV_t argv, child = fork(); if (child == 0) { - /* NSPR messes with SIGPIPE, reset to default for the kids */ - signal(SIGPIPE, SIG_DFL); close(toProg[1]); close(fromProg[0]); @@ -369,6 +428,12 @@ int rpmfcExec(ARGV_const_t av, StringBuf sb_stdin, StringBuf * sb_stdoutp, buf_stdin_len = strlen(buf_stdin); } + if (_rpmfc_debug) { + char *cmd = argvJoin(xav, " "); + rpmlog(RPMLOG_DEBUG, "Executing %s on %s\n", cmd, buf_stdin); + free(cmd); + } + /* Read output from exec'd helper. */ sb = getOutputFrom(xav, buf_stdin, buf_stdin_len, failnonzero, buildRoot); @@ -397,15 +462,15 @@ static void argvAddUniq(ARGV_t * argvp, const char * key) #define hasAttr(_a, _n) (argvSearch((_a), (_n), NULL) != NULL) -static void rpmfcAddFileDep(rpmstrPool ddict, int ix, rpmds ds, char deptype) +static void rpmfcAddFileDep(rpmfcFileDeps *fileDeps, rpmds ds, int ix) { - if (ds) { - char *key = NULL; - rasprintf(&key, "%08d%c %s %s 0x%08x", ix, deptype, - rpmdsN(ds), rpmdsEVR(ds), rpmdsFlags(ds)); - rpmstrPoolId(ddict, key, 1); - free(key); + if (fileDeps->size == fileDeps->alloced) { + fileDeps->alloced <<= 2; + fileDeps->data = xrealloc(fileDeps->data, + fileDeps->alloced * sizeof(fileDeps->data[0])); } + fileDeps->data[fileDeps->size].fileIx = ix; + fileDeps->data[fileDeps->size++].dep = ds; } static ARGV_t runCmd(const char *nsdep, const char *depname, @@ -424,7 +489,7 @@ static ARGV_t runCmd(const char *nsdep, const char *depname, appendLineStringBuf(sb_stdin, fn); if (rpmfcExec(av, sb_stdin, &sb_stdout, 0, buildRoot) == 0) { - argvSplit(&output, getStringBuf(sb_stdout), " \t\n\r"); + argvSplit(&output, getStringBuf(sb_stdout), "\n\r"); } argvFree(av); @@ -436,74 +501,77 @@ static ARGV_t runCmd(const char *nsdep, const char *depname, return output; } +struct addReqProvDataFc { + rpmfc fc; + const char *namespace; + regex_t *exclude; +}; + +static rpmRC addReqProvFc(void *cbdata, rpmTagVal tagN, + const char * N, const char * EVR, rpmsenseFlags Flags, + int index) +{ + struct addReqProvDataFc *data = cbdata; + rpmfc fc = data->fc; + const char *namespace = data->namespace; + regex_t *exclude = data->exclude; + + rpmds ds = rpmdsSingleNS(fc->pool, tagN, namespace, N, EVR, Flags); + /* Add to package and file dependencies unless filtered */ + if (regMatch(exclude, rpmdsDNEVR(ds)+2) == 0) + rpmfcAddFileDep(&fc->fileDeps, ds, index); + + return RPMRC_OK; +} + /** * Run per-interpreter dependency helper. * @param fc file classifier + * @param ix file index * @param nsdep class name for interpreter (e.g. "perl") * @param depname "provides" or "requires" - * @param depsp fc->provides or fc->requires * @param dsContext RPMSENSE_FIND_PROVIDES or RPMSENSE_FIND_REQUIRES * @param tagN RPMTAG_PROVIDENAME or RPMTAG_REQUIRENAME - * @return 0 + * @return 0 on success */ -static int rpmfcHelper(rpmfc fc, const char *nsdep, const char *depname, - rpmds *depsp, rpmsenseFlags dsContext, rpmTagVal tagN) +static int rpmfcHelper(rpmfc fc, int ix, + const char *nsdep, const char *depname, + rpmsenseFlags dsContext, rpmTagVal tagN) { ARGV_t pav = NULL; - const char * fn = fc->fn[fc->ix]; + const char * fn = fc->fn[ix]; char *namespace = NULL; int pac; + int rc = 0; regex_t *exclude = NULL; regex_t *exclude_from = NULL; + regex_t *global_exclude_from = NULL; /* If the entire path is filtered out, there's nothing more to do */ - exclude_from = rpmfcAttrReg(depname, "exclude", "from"); + exclude_from = rpmfcAttrReg(depname, "exclude", "from", NULL); if (regMatch(exclude_from, fn+fc->brlen)) goto exit; + global_exclude_from = rpmfcAttrReg("global", depname, "exclude", "from", NULL); + if (regMatch(global_exclude_from, fn+fc->brlen)) + goto exit; + pav = runCmd(nsdep, depname, fc->buildRoot, fn); if (pav == NULL) goto exit; pac = argvCount(pav); - namespace = rpmfcAttrMacro(nsdep, NULL, "namespace"); - exclude = rpmfcAttrReg(depname, NULL, "exclude"); - - for (int i = 0; i < pac; i++) { - rpmds ds = NULL; - const char *N = pav[i]; - const char *EVR = ""; - rpmsenseFlags Flags = dsContext; - if (pav[i+1] && strchr("=<>", *pav[i+1])) { - i++; - for (const char *s = pav[i]; *s; s++) { - switch(*s) { - default: - break; - case '=': - Flags |= RPMSENSE_EQUAL; - break; - case '<': - Flags |= RPMSENSE_LESS; - break; - case '>': - Flags |= RPMSENSE_GREATER; - break; - } - } - i++; - EVR = pav[i]; - } - - ds = rpmdsSingleNS(tagN, namespace, N, EVR, Flags); + namespace = rpmfcAttrMacro(nsdep, "namespace", NULL); + exclude = rpmfcAttrReg(depname, "exclude", NULL); - /* Add to package and file dependencies unless filtered */ - if (regMatch(exclude, rpmdsDNEVR(ds)+2) == 0) { - (void) rpmdsMerge(depsp, ds); - rpmfcAddFileDep(fc->ddict, fc->ix, ds, tagN == RPMTAG_PROVIDENAME ? 'P' : 'R'); - } + struct addReqProvDataFc data; + data.fc = fc; + data.namespace = namespace; + data.exclude = exclude; - rpmdsFree(ds); + for (int i = 0; i < pac; i++) { + if (parseRCPOT(NULL, fc->pkg, pav[i], tagN, ix, dsContext, addReqProvFc, &data)) + rc++; } argvFree(pav); @@ -512,55 +580,8 @@ static int rpmfcHelper(rpmfc fc, const char *nsdep, const char *depname, exit: regFree(exclude_from); - return 0; -} - -/** - * Run per-interpreter Provides: dependency helper. - * @param fc file classifier - * @param nsdep class name for interpreter (e.g. "perl") - * @return 0 - */ -static int rpmfcHelperProvides(rpmfc fc, const char * nsdep) -{ - if (fc->skipProv) - return 0; - - rpmfcHelper(fc, nsdep, "provides", &fc->provides, RPMSENSE_FIND_PROVIDES, RPMTAG_PROVIDENAME); - - return 0; -} - -/** - * Run per-interpreter Requires: dependency helper. - * @param fc file classifier - * @param nsdep class name for interpreter (e.g. "perl") - * @return 0 - */ -static int rpmfcHelperRequires(rpmfc fc, const char * nsdep) -{ - if (fc->skipReq) - return 0; - - rpmfcHelper(fc, nsdep, "requires", &fc->requires, RPMSENSE_FIND_REQUIRES, RPMTAG_REQUIRENAME); - - return 0; -} - -/** - * Run per-interpreter Supplements: dependency helper. - * @param fc file classifier - * @param nsdep class name for interpreter (e.g. "perl") - * @return 0 - */ -static int rpmfcHelperSupplements(rpmfc fc, const char * nsdep) -{ - if (fc->skipReq) - return 0; - - rpmfcHelper(fc, nsdep, "supplements", &fc->supplements, RPMSENSE_FIND_REQUIRES|RPMSENSE_STRONG|RPMSENSE_MISSINGOK, RPMTAG_ENHANCESNAME); - - return 0; + regFree(global_exclude_from); + return rc; } /* Only used for elf coloring and controlling RPMTAG_FILECLASS inclusion now */ @@ -635,7 +656,7 @@ static int matches(const struct matchRule *rule, } } -static void rpmfcAttributes(rpmfc fc, const char *ftype, const char *fullpath) +static void rpmfcAttributes(rpmfc fc, int ix, const char *ftype, const char *fullpath) { const char *path = fullpath + fc->brlen; int is_executable = 0; @@ -652,7 +673,7 @@ static void rpmfcAttributes(rpmfc fc, const char *ftype, const char *fullpath) /* Add attributes on libmagic type & path pattern matches */ if (matches(&(*attr)->incl, ftype, path, is_executable)) - argvAddTokens(&fc->fattrs[fc->ix], (*attr)->name); + argvAddTokens(&fc->fattrs[ix], (*attr)->name); } } @@ -676,39 +697,34 @@ static rpm_color_t rpmfcColor(const char * fmstr) void rpmfcPrint(const char * msg, rpmfc fc, FILE * fp) { - rpm_color_t fcolor; int ndx; int dx; int fx; -int nprovides; -int nrequires; - if (fp == NULL) fp = stderr; if (msg) fprintf(fp, "===================================== %s\n", msg); -nprovides = rpmdsCount(fc->provides); -nrequires = rpmdsCount(fc->requires); - if (fc) for (fx = 0; fx < fc->nfiles; fx++) { - rpmsid cx = fc->fcdictx[fx] + 1; /* id's are one off */ - fcolor = fc->fcolor[fx]; - ARGV_t fattrs = fc->fattrs[fx]; - fprintf(fp, "%3d %s", fx, fc->fn[fx]); - if (fcolor != RPMFC_BLACK) + if (_rpmfc_debug) { + rpmsid cx = fc->fcdictx[fx] + 1; /* id's are one off */ + rpm_color_t fcolor = fc->fcolor[fx]; + ARGV_t fattrs = fc->fattrs[fx]; + + if (fcolor != RPMFC_BLACK) fprintf(fp, "\t0x%x", fc->fcolor[fx]); - else + else fprintf(fp, "\t%s", rpmstrPoolStr(fc->cdict, cx)); - if (fattrs) { - char *attrs = argvJoin(fattrs, ","); - fprintf(fp, " [%s]", attrs); - free(attrs); - } else { - fprintf(fp, " [none]"); + if (fattrs) { + char *attrs = argvJoin(fattrs, ","); + fprintf(fp, " [%s]", attrs); + free(attrs); + } else { + fprintf(fp, " [none]"); + } } fprintf(fp, "\n"); @@ -724,32 +740,16 @@ assert(fx < fc->fddictn->nvals); const char * depval; unsigned char deptype; unsigned ix; + rpmds ds; ix = fc->ddictx->vals[dx++]; deptype = ((ix >> 24) & 0xff); ix &= 0x00ffffff; depval = NULL; - switch (deptype) { - default: -assert(depval != NULL); - break; - case 'P': - if (nprovides > 0) { -assert(ix < nprovides); - (void) rpmdsSetIx(fc->provides, ix-1); - if (rpmdsNext(fc->provides) >= 0) - depval = rpmdsDNEVR(fc->provides); - } - break; - case 'R': - if (nrequires > 0) { -assert(ix < nrequires); - (void) rpmdsSetIx(fc->requires, ix-1); - if (rpmdsNext(fc->requires) >= 0) - depval = rpmdsDNEVR(fc->requires); - } - break; - } + ds = rpmfcDependencies(fc, rpmdsDToTagN(deptype)); + (void) rpmdsSetIx(ds, ix-1); + if (rpmdsNext(ds) >= 0) + depval = rpmdsDNEVR(ds); if (depval) fprintf(fp, "\t%s\n", depval); } @@ -771,16 +771,19 @@ rpmfc rpmfcFree(rpmfc fc) free(fc->fattrs); free(fc->fcolor); free(fc->fcdictx); + free(fc->pkg); argiFree(fc->fddictx); argiFree(fc->fddictn); argiFree(fc->ddictx); - rpmstrPoolFree(fc->ddict); + for (int i = 0; i < fc->fileDeps.size; i++) { + rpmdsFree(fc->fileDeps.data[i].dep); + } + free(fc->fileDeps.data); + rpmstrPoolFree(fc->cdict); - rpmdsFree(fc->provides); - rpmdsFree(fc->requires); - rpmdsFree(fc->supplements); + rpmstrPoolFree(fc->pool); memset(fc, 0, sizeof(*fc)); /* trash and burn */ free(fc); } @@ -794,6 +797,11 @@ rpmfc rpmfcCreate(const char *buildRoot, rpmFlags flags) fc->buildRoot = xstrdup(buildRoot); fc->brlen = strlen(buildRoot); } + fc->pool = rpmstrPoolCreate(); + fc->pkg = xcalloc(1, sizeof(*fc->pkg)); + fc->fileDeps.alloced = 10; + fc->fileDeps.data = xmalloc(fc->fileDeps.alloced * + sizeof(fc->fileDeps.data[0])); return fc; } @@ -802,97 +810,183 @@ rpmfc rpmfcNew(void) return rpmfcCreate(NULL, 0); } +rpmds rpmfcDependencies(rpmfc fc, rpmTagVal tag) +{ + if (fc) { + return *packageDependencies(fc->pkg, tag); + } + return NULL; +} + rpmds rpmfcProvides(rpmfc fc) { - return (fc != NULL ? fc->provides : NULL); + return rpmfcDependencies(fc, RPMTAG_PROVIDENAME); } rpmds rpmfcRequires(rpmfc fc) { - return (fc != NULL ? fc->requires : NULL); + return rpmfcDependencies(fc, RPMTAG_REQUIRENAME); +} + +rpmds rpmfcRecommends(rpmfc fc) +{ + return rpmfcDependencies(fc, RPMTAG_RECOMMENDNAME); +} + +rpmds rpmfcSuggests(rpmfc fc) +{ + return rpmfcDependencies(fc, RPMTAG_SUGGESTNAME); } rpmds rpmfcSupplements(rpmfc fc) { - return (fc != NULL ? fc->supplements : NULL); + return rpmfcDependencies(fc, RPMTAG_SUPPLEMENTNAME); } -rpmRC rpmfcApply(rpmfc fc) +rpmds rpmfcEnhances(rpmfc fc) { - const char * s; - char * se; - rpmds ds; - const char * N; - const char * EVR; - rpmsenseFlags Flags; - unsigned char deptype; - int nddict; + return rpmfcDependencies(fc, RPMTAG_ENHANCENAME); +} + +rpmds rpmfcConflicts(rpmfc fc) +{ + return rpmfcDependencies(fc, RPMTAG_CONFLICTNAME); +} + +rpmds rpmfcObsoletes(rpmfc fc) +{ + return rpmfcDependencies(fc, RPMTAG_OBSOLETENAME); +} + + +/* Versioned deps are less than unversioned deps */ +static int cmpVerDeps(const void *a, const void *b) +{ + rpmfcFileDep *fDepA = (rpmfcFileDep *) a; + rpmfcFileDep *fDepB = (rpmfcFileDep *) b; + + int aIsVersioned = rpmdsFlags(fDepA->dep) & RPMSENSE_SENSEMASK ? 1 : 0; + int bIsVersioned = rpmdsFlags(fDepB->dep) & RPMSENSE_SENSEMASK ? 1 : 0; + + return bIsVersioned - aIsVersioned; +} + +/* Sort by index */ +static int cmpIndexDeps(const void *a, const void *b) +{ + rpmfcFileDep *fDepA = (rpmfcFileDep *) a; + rpmfcFileDep *fDepB = (rpmfcFileDep *) b; + + return fDepA->fileIx - fDepB->fileIx; +} + +/* + * Remove unversioned deps if corresponding versioned deps exist but only + * if the versioned dependency has the same type and the same color as the versioned. + */ +static void rpmfcNormalizeFDeps(rpmfc fc) +{ + rpmstrPool versionedDeps = rpmstrPoolCreate(); + rpmfcFileDep *normalizedFDeps = xmalloc(fc->fileDeps.size * + sizeof(normalizedFDeps[0])); + int ix = 0; + char *depStr; + + /* Sort. Versioned dependencies first */ + qsort(fc->fileDeps.data, fc->fileDeps.size, sizeof(fc->fileDeps.data[0]), + cmpVerDeps); + + for (int i = 0; i < fc->fileDeps.size; i++) { + switch (rpmdsTagN(fc->fileDeps.data[i].dep)) { + case RPMTAG_REQUIRENAME: + case RPMTAG_RECOMMENDNAME: + case RPMTAG_SUGGESTNAME: + rasprintf(&depStr, "%08x_%c_%s", + fc->fcolor[fc->fileDeps.data[i].fileIx], + rpmdsD(fc->fileDeps.data[i].dep), + rpmdsN(fc->fileDeps.data[i].dep)); + + if (rpmdsFlags(fc->fileDeps.data[i].dep) & RPMSENSE_SENSEMASK) { + /* preserve versioned require dependency */ + normalizedFDeps[ix++] = fc->fileDeps.data[i]; + rpmstrPoolId(versionedDeps, depStr, 1); + } else if (!rpmstrPoolId(versionedDeps, depStr, 0)) { + /* preserve unversioned require dep only if versioned dep doesn't exist */ + normalizedFDeps[ix++] =fc-> fileDeps.data[i]; + } else { + rpmdsFree(fc->fileDeps.data[i].dep); + } + free(depStr); + break; + default: + /* Preserve all non-require dependencies */ + normalizedFDeps[ix++] = fc->fileDeps.data[i]; + break; + } + } + rpmstrPoolFree(versionedDeps); + + free(fc->fileDeps.data); + fc->fileDeps.data = normalizedFDeps; + fc->fileDeps.size = ix; +} + +static rpmRC rpmfcApplyInternal(rpmfc fc) +{ + rpmds ds, * dsp; int previx; unsigned int val; int dix; int ix; /* Generate package and per-file dependencies. */ - for (fc->ix = 0; fc->ix < fc->nfiles && fc->fn[fc->ix] != NULL; fc->ix++) { - for (ARGV_t fattr = fc->fattrs[fc->ix]; fattr && *fattr; fattr++) { - rpmfcHelperProvides(fc, *fattr); - rpmfcHelperRequires(fc, *fattr); - rpmfcHelperSupplements(fc, *fattr); + for (ix = 0; ix < fc->nfiles && fc->fn[ix] != NULL; ix++) { + for (ARGV_t fattr = fc->fattrs[ix]; fattr && *fattr; fattr++) { + if (!fc->skipProv) { + rpmfcHelper(fc, ix, *fattr, "provides", + RPMSENSE_FIND_PROVIDES, RPMTAG_PROVIDENAME); + } + if (!fc->skipReq) { + rpmfcHelper(fc, ix, *fattr, "requires", + RPMSENSE_FIND_REQUIRES, RPMTAG_REQUIRENAME); + rpmfcHelper(fc, ix, *fattr, "recommends", + RPMSENSE_FIND_REQUIRES, RPMTAG_RECOMMENDNAME); + rpmfcHelper(fc, ix, *fattr, "suggests", + RPMSENSE_FIND_REQUIRES, RPMTAG_SUGGESTNAME); + rpmfcHelper(fc, ix, *fattr, "supplements", + RPMSENSE_FIND_REQUIRES, RPMTAG_SUPPLEMENTNAME); + rpmfcHelper(fc, ix, *fattr, "enhances", + RPMSENSE_FIND_REQUIRES, RPMTAG_ENHANCENAME); + rpmfcHelper(fc, ix, *fattr, "conflicts", + RPMSENSE_FIND_REQUIRES, RPMTAG_CONFLICTNAME); + rpmfcHelper(fc, ix, *fattr, "obsoletes", + RPMSENSE_FIND_REQUIRES, RPMTAG_OBSOLETENAME); + } } } /* No more additions after this, freeze pool to minimize memory use */ - rpmstrPoolFreeze(fc->ddict, 0); + + rpmfcNormalizeFDeps(fc); + for (int i = 0; i < fc->fileDeps.size; i++) { + ds = fc->fileDeps.data[i].dep; + rpmdsMerge(packageDependencies(fc->pkg, rpmdsTagN(ds)), ds); + } + + /* Sort by index */ + qsort(fc->fileDeps.data, fc->fileDeps.size, + sizeof(fc->fileDeps.data[0]), cmpIndexDeps); /* Generate per-file indices into package dependencies. */ - nddict = rpmstrPoolNumStr(fc->ddict); previx = -1; - for (rpmsid id = 1; id <= nddict; id++) { - s = rpmstrPoolStr(fc->ddict, id); - - /* Parse out (file#,deptype,N,EVR,Flags) */ - ix = strtol(s, &se, 10); - if ( se == NULL ) { - rpmlog(RPMLOG_ERR, _("Conversion of %s to long integer failed.\n"), s); - return RPMRC_FAIL; - } - - deptype = *se++; - se++; - N = se; - while (*se && *se != ' ') - se++; - *se++ = '\0'; - EVR = se; - while (*se && *se != ' ') - se++; - *se++ = '\0'; - Flags = strtol(se, NULL, 16); - - dix = -1; - switch (deptype) { - default: - break; - case 'P': - ds = rpmdsSingle(RPMTAG_PROVIDENAME, N, EVR, Flags); - dix = rpmdsFind(fc->provides, ds); - rpmdsFree(ds); - break; - case 'R': - ds = rpmdsSingle(RPMTAG_REQUIRENAME, N, EVR, Flags); - dix = rpmdsFind(fc->requires, ds); - rpmdsFree(ds); - break; - case 'S': - ds = rpmdsSingle(RPMTAG_ENHANCESNAME, N, EVR, Flags); - dix = rpmdsFind(fc->supplements, ds); - ds = rpmdsFree(ds); - break; - } - + for (int i = 0; i < fc->fileDeps.size; i++) { + ds = fc->fileDeps.data[i].dep; + ix = fc->fileDeps.data[i].fileIx; + dsp = packageDependencies(fc->pkg, rpmdsTagN(ds)); + dix = rpmdsFind(*dsp, ds); if (dix < 0) continue; - val = (deptype << 24) | (dix & 0x00ffffff); + val = (rpmdsD(ds) << 24) | (dix & 0x00ffffff); argiAdd(&fc->ddictx, -1, val); if (previx != ix) { @@ -901,8 +995,8 @@ rpmRC rpmfcApply(rpmfc fc) } if (fc->fddictn && fc->fddictn->vals) fc->fddictn->vals[ix]++; - } + } return RPMRC_OK; } @@ -960,7 +1054,6 @@ rpmRC rpmfcClassify(rpmfc fc, ARGV_t argv, rpm_mode_t * fmode) /* Build (sorted) file class dictionary. */ fc->cdict = rpmstrPoolCreate(); - fc->ddict = rpmstrPoolCreate(); ms = magic_open(msflags); if (ms == NULL) { @@ -974,13 +1067,13 @@ rpmRC rpmfcClassify(rpmfc fc, ARGV_t argv, rpm_mode_t * fmode) goto exit; } - for (fc->ix = 0; fc->ix < fc->nfiles; fc->ix++) { + for (int ix = 0; ix < fc->nfiles; ix++) { rpmsid ftypeId; const char * ftype; - const char * s = argv[fc->ix]; + const char * s = argv[ix]; size_t slen = strlen(s); int fcolor = RPMFC_BLACK; - rpm_mode_t mode = (fmode ? fmode[fc->ix] : 0); + rpm_mode_t mode = (fmode ? fmode[ix] : 0); int is_executable = (mode & (S_IXUSR|S_IXGRP|S_IXOTH)); switch (mode & S_IFMT) { @@ -1026,15 +1119,15 @@ rpmRC rpmfcClassify(rpmfc fc, ARGV_t argv, rpm_mode_t * fmode) rpmlog(RPMLOG_DEBUG, "%s: %s\n", s, ftype); /* Save the path. */ - fc->fn[fc->ix] = xstrdup(s); + fc->fn[ix] = xstrdup(s); /* Add (filtered) file coloring */ fcolor |= rpmfcColor(ftype); /* Add attributes based on file type and/or path */ - rpmfcAttributes(fc, ftype, s); + rpmfcAttributes(fc, ix, ftype, s); - fc->fcolor[fc->ix] = fcolor; + fc->fcolor[ix] = fcolor; /* Add to file class dictionary and index array */ if (fcolor != RPMFC_WHITE && (fcolor & RPMFC_INCLUDE)) { @@ -1045,7 +1138,7 @@ rpmRC rpmfcClassify(rpmfc fc, ARGV_t argv, rpm_mode_t * fmode) fc->fwhite++; } /* Pool id's start from 1, for headers we want it from 0 */ - fc->fcdictx[fc->ix] = ftypeId - 1; + fc->fcdictx[ix] = ftypeId - 1; } rc = RPMRC_OK; @@ -1101,6 +1194,12 @@ static struct DepMsg_s depMsgs[] = { { "Requires(postun)", { NULL, "postun", NULL, NULL }, -1, -1, RPMTAG_REQUIREFLAGS, RPMSENSE_SCRIPT_POSTUN, 0 }, + { "Requires(pretrans)", { NULL, "pretrans", NULL, NULL }, + -1, -1, RPMTAG_REQUIREFLAGS, + RPMSENSE_PRETRANS, 0 }, + { "Requires(posttrans)", { NULL, "posttrans", NULL, NULL }, + -1, -1, RPMTAG_REQUIREFLAGS, + RPMSENSE_POSTTRANS, 0 }, { "Requires", { "%{?__find_requires}", NULL, NULL, NULL }, -1, -1, RPMTAG_REQUIREFLAGS, /* XXX inherit name/version arrays */ RPMSENSE_FIND_REQUIRES|RPMSENSE_TRIGGERIN|RPMSENSE_TRIGGERUN|RPMSENSE_TRIGGERPOSTUN|RPMSENSE_TRIGGERPREIN, 0 }, @@ -1110,12 +1209,18 @@ static struct DepMsg_s depMsgs[] = { { "Obsoletes", { "%{?__find_obsoletes}", NULL, NULL, NULL }, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEVERSION, RPMTAG_OBSOLETEFLAGS, 0, -1 }, - { "Enhances", { "%{?__find_enhances}", NULL, NULL, NULL }, - RPMTAG_ENHANCESNAME, RPMTAG_ENHANCESVERSION, RPMTAG_ENHANCESFLAGS, - RPMSENSE_STRONG, RPMSENSE_STRONG }, + { "Recommends", { "%{?__find_recommends}", NULL, NULL, NULL }, + RPMTAG_RECOMMENDNAME, RPMTAG_RECOMMENDVERSION, RPMTAG_RECOMMENDFLAGS, + 0, -1 }, + { "Suggests", { "%{?__find_suggests}", NULL, NULL, NULL }, + RPMTAG_SUGGESTNAME, RPMTAG_SUGGESTVERSION, RPMTAG_SUGGESTFLAGS, + 0, -1 }, { "Supplements", { "%{?__find_supplements}", NULL, NULL, NULL }, - RPMTAG_ENHANCESNAME, RPMTAG_ENHANCESVERSION, RPMTAG_ENHANCESFLAGS, - RPMSENSE_STRONG, 0 }, + RPMTAG_SUPPLEMENTNAME, RPMTAG_SUPPLEMENTVERSION, RPMTAG_SUPPLEMENTFLAGS, + 0, -1 }, + { "Enhances", { "%{?__find_enhances}", NULL, NULL, NULL }, + RPMTAG_ENHANCENAME, RPMTAG_ENHANCEVERSION, RPMTAG_ENHANCEFLAGS, + 0, -1 }, { NULL, { NULL, NULL, NULL, NULL }, 0, 0, 0, 0, 0 } }; @@ -1123,7 +1228,7 @@ static DepMsg_t DepMsgs = depMsgs; /** */ -static void printDeps(Header h) +static void printDeps(rpmfc fc) { DepMsg_t dm; rpmds ds = NULL; @@ -1133,8 +1238,7 @@ static void printDeps(Header h) for (dm = DepMsgs; dm->msg != NULL; dm++) { if (dm->ntag != -1) { - rpmdsFree(ds); - ds = rpmdsNew(h, dm->ntag, 0); + ds = rpmfcDependencies(fc, dm->ntag); } if (dm->ftag == 0) continue; @@ -1161,18 +1265,16 @@ static void printDeps(Header h) if (bingo) rpmlog(RPMLOG_NOTICE, "\n"); } - rpmdsFree(ds); } -static rpmRC rpmfcGenerateDependsHelper(const rpmSpec spec, Package pkg, rpmfi fi) +static rpmRC rpmfcApplyExternal(rpmfc fc) { StringBuf sb_stdin = newStringBuf(); rpmRC rc = RPMRC_OK; /* Create file manifest buffer to deliver to dependency finder. */ - fi = rpmfiInit(fi, 0); - while (rpmfiNext(fi) >= 0) - appendLineStringBuf(sb_stdin, rpmfiFN(fi)); + for (int i = 0; i < fc->nfiles; i++) + appendLineStringBuf(sb_stdin, fc->fn[i]); for (DepMsg_t dm = DepMsgs; dm->msg != NULL; dm++) { rpmTagVal tag = (dm->ftag > 0) ? dm->ftag : dm->ntag; @@ -1181,25 +1283,23 @@ static rpmRC rpmfcGenerateDependsHelper(const rpmSpec spec, Package pkg, rpmfi f StringBuf sb_stdout = NULL; int failnonzero = (tag == RPMTAG_PROVIDEFLAGS); - switch(tag) { + switch (tag) { case RPMTAG_PROVIDEFLAGS: - if (!pkg->autoProv) + if (fc->skipProv) continue; tagflags = RPMSENSE_FIND_PROVIDES; break; case RPMTAG_REQUIREFLAGS: - if (!pkg->autoReq) + case RPMTAG_RECOMMENDFLAGS: + case RPMTAG_SUGGESTFLAGS: + case RPMTAG_SUPPLEMENTFLAGS: + case RPMTAG_ENHANCEFLAGS: + case RPMTAG_CONFLICTFLAGS: + case RPMTAG_OBSOLETEFLAGS: + if (fc->skipReq) continue; tagflags = RPMSENSE_FIND_REQUIRES; break; - case RPMTAG_ENHANCESFLAGS: - if (!pkg->autoProv) - continue; - failnonzero = 0; - tagflags = RPMSENSE_FIND_REQUIRES | RPMSENSE_MISSINGOK; - if (strcmp(dm->msg, "Supplements") == 0) - tagflags |= RPMSENSE_STRONG; - break; default: continue; break; @@ -1210,7 +1310,7 @@ static rpmRC rpmfcGenerateDependsHelper(const rpmSpec spec, Package pkg, rpmfi f free(s); if (rpmfcExec(dm->argv, sb_stdin, &sb_stdout, - failnonzero, spec->buildRoot) == -1) + failnonzero, fc->buildRoot) == -1) continue; if (sb_stdout == NULL) { @@ -1220,7 +1320,7 @@ static rpmRC rpmfcGenerateDependsHelper(const rpmSpec spec, Package pkg, rpmfi f } /* Parse dependencies into header */ - rc = parseRCPOT(spec, pkg, getStringBuf(sb_stdout), tag, 0, tagflags); + rc = parseRCPOT(NULL, fc->pkg, getStringBuf(sb_stdout), dm->ntag != -1 ? dm->ntag : RPMTAG_REQUIRENAME, 0, tagflags, addReqProvPkg, NULL); freeStringBuf(sb_stdout); if (rc) { @@ -1234,11 +1334,26 @@ static rpmRC rpmfcGenerateDependsHelper(const rpmSpec spec, Package pkg, rpmfi f return rc; } +rpmRC rpmfcApply(rpmfc fc) +{ + rpmRC rc; + /* If new-fangled dependency generation is disabled ... */ + if (!rpmExpandNumeric("%{?_use_internal_dependency_generator}")) { + /* ... then generate dependencies using %{__find_requires} et al. */ + rpmlog(RPMLOG_WARNING, + _("Deprecated external dependency generator is used!\n")); + rc = rpmfcApplyExternal(fc); + } else { + /* ... otherwise generate per-file dependencies */ + rc = rpmfcApplyInternal(fc); + } + return rc; +} + rpmRC rpmfcGenerateDepends(const rpmSpec spec, Package pkg) { - rpmfi fi = pkg->cpioList; + rpmfi fi = rpmfilesIter(pkg->cpioList, RPMFI_ITER_FWD); rpmfc fc = NULL; - ARGV_t av = NULL; rpm_mode_t * fmode = NULL; int ac = rpmfiFC(fi); int genConfigDeps = 0; @@ -1250,82 +1365,46 @@ rpmRC rpmfcGenerateDepends(const rpmSpec spec, Package pkg) if (ac <= 0) goto exit; - /* Skip packages that have dependency generation disabled. */ - if (! (pkg->autoReq || pkg->autoProv)) - goto exit; - - /* If new-fangled dependency generation is disabled ... */ - if (!rpmExpandNumeric("%{?_use_internal_dependency_generator}")) { - /* ... then generate dependencies using %{__find_requires} et al. */ - rc = rpmfcGenerateDependsHelper(spec, pkg, fi); - goto exit; - } - /* Extract absolute file paths in argv format. */ - av = xcalloc(ac+1, sizeof(*av)); fmode = xcalloc(ac+1, sizeof(*fmode)); fi = rpmfiInit(fi, 0); while ((idx = rpmfiNext(fi)) >= 0) { /* Does package have any %config files? */ genConfigDeps |= (rpmfiFFlags(fi) & RPMFILE_CONFIG); - - av[idx] = xstrdup(rpmfiFN(fi)); fmode[idx] = rpmfiFMode(fi); } - av[ac] = NULL; fc = rpmfcCreate(spec->buildRoot, 0); + free(fc->pkg); + fc->pkg = pkg; fc->skipProv = !pkg->autoProv; fc->skipReq = !pkg->autoReq; - /* Copy (and delete) manually generated dependencies to dictionary. */ - if (!fc->skipProv) { - rpmds ds = rpmdsNew(pkg->header, RPMTAG_PROVIDENAME, 0); - rpmdsMerge(&fc->provides, ds); - rpmdsFree(ds); - - headerDel(pkg->header, RPMTAG_PROVIDENAME); - headerDel(pkg->header, RPMTAG_PROVIDEVERSION); - headerDel(pkg->header, RPMTAG_PROVIDEFLAGS); - + if (!fc->skipProv && genConfigDeps) { /* Add config dependency, Provides: config(N) = EVR */ - if (genConfigDeps) { - ds = rpmdsSingleNS(RPMTAG_PROVIDENAME, "config", - rpmdsN(pkg->ds), rpmdsEVR(pkg->ds), - (RPMSENSE_EQUAL|RPMSENSE_CONFIG)); - rpmdsMerge(&fc->provides, ds); - rpmdsFree(ds); - } + rpmds ds = rpmdsSingleNS(fc->pool, RPMTAG_PROVIDENAME, "config", + rpmdsN(pkg->ds), rpmdsEVR(pkg->ds), + (RPMSENSE_EQUAL|RPMSENSE_CONFIG)); + rpmdsMerge(packageDependencies(pkg, RPMTAG_PROVIDENAME), ds); + rpmdsFree(ds); } - - if (!fc->skipReq) { - rpmds ds = rpmdsNew(pkg->header, RPMTAG_REQUIRENAME, 0); - rpmdsMerge(&fc->requires, ds); + if (!fc->skipReq && genConfigDeps) { + rpmds ds = rpmdsSingleNS(fc->pool, RPMTAG_REQUIRENAME, "config", + rpmdsN(pkg->ds), rpmdsEVR(pkg->ds), + (RPMSENSE_EQUAL|RPMSENSE_CONFIG)); + rpmdsMerge(packageDependencies(pkg, RPMTAG_REQUIRENAME), ds); rpmdsFree(ds); - - headerDel(pkg->header, RPMTAG_REQUIRENAME); - headerDel(pkg->header, RPMTAG_REQUIREVERSION); - headerDel(pkg->header, RPMTAG_REQUIREFLAGS); - - /* Add config dependency, Requires: config(N) = EVR */ - if (genConfigDeps) { - ds = rpmdsSingleNS(RPMTAG_REQUIRENAME, "config", - rpmdsN(pkg->ds), rpmdsEVR(pkg->ds), - (RPMSENSE_EQUAL|RPMSENSE_CONFIG)); - rpmdsMerge(&fc->requires, ds); - rpmdsFree(ds); - } } /* Build file class dictionary. */ - rc = rpmfcClassify(fc, av, fmode); + rc = rpmfcClassify(fc, pkg->dpaths, fmode); if ( rc != RPMRC_OK ) goto exit; /* Build file/package dependency dictionary. */ rc = rpmfcApply(fc); - if ( rc != RPMRC_OK ) + if (rc != RPMRC_OK) goto exit; /* Add per-file colors(#files) */ @@ -1343,54 +1422,18 @@ rpmRC rpmfcGenerateDepends(const rpmSpec spec, Package pkg) /* Add per-file classes(#files) */ headerPutUint32(pkg->header, RPMTAG_FILECLASS, fc->fcdictx, fc->nfiles); - /* Add Provides: */ - if (!fc->skipProv) { - rpmds pi = rpmdsInit(fc->provides); - while (rpmdsNext(pi) >= 0) { - rpmsenseFlags flags = rpmdsFlags(pi); - - headerPutString(pkg->header, RPMTAG_PROVIDENAME, rpmdsN(pi)); - headerPutString(pkg->header, RPMTAG_PROVIDEVERSION, rpmdsEVR(pi)); - headerPutUint32(pkg->header, RPMTAG_PROVIDEFLAGS, &flags, 1); - } - } - - /* Add Requires: */ - if (!fc->skipReq) { - rpmds pi = rpmdsInit(fc->requires); - while (rpmdsNext(pi) >= 0) { - rpmsenseFlags flags = rpmdsFlags(pi); - - headerPutString(pkg->header, RPMTAG_REQUIRENAME, rpmdsN(pi)); - headerPutString(pkg->header, RPMTAG_REQUIREVERSION, rpmdsEVR(pi)); - headerPutUint32(pkg->header, RPMTAG_REQUIREFLAGS, &flags, 1); - } - } - - /* Add Supplements: */ - if (!fc->skipReq) { - rpmds pi = rpmdsInit(fc->supplements); - while (rpmdsNext(pi) >= 0) { - rpmsenseFlags flags = rpmdsFlags(pi); - - headerPutString(pkg->header, RPMTAG_ENHANCESNAME, rpmdsN(pi)); - headerPutString(pkg->header, RPMTAG_ENHANCESVERSION, rpmdsEVR(pi)); - headerPutUint32(pkg->header, RPMTAG_ENHANCESFLAGS, &flags, 1); - } - } - /* Add dependency dictionary(#dependencies) */ if (rpmtdFromArgi(&td, RPMTAG_DEPENDSDICT, fc->ddictx)) { headerPut(pkg->header, &td, HEADERPUT_DEFAULT); - } - /* Add per-file dependency (start,number) pairs (#files) */ - if (rpmtdFromArgi(&td, RPMTAG_FILEDEPENDSX, fc->fddictx)) { - headerPut(pkg->header, &td, HEADERPUT_DEFAULT); - } + /* Add per-file dependency (start,number) pairs (#files) */ + if (rpmtdFromArgi(&td, RPMTAG_FILEDEPENDSX, fc->fddictx)) { + headerPut(pkg->header, &td, HEADERPUT_DEFAULT); + } - if (rpmtdFromArgi(&td, RPMTAG_FILEDEPENDSN, fc->fddictn)) { - headerPut(pkg->header, &td, HEADERPUT_DEFAULT); + if (rpmtdFromArgi(&td, RPMTAG_FILEDEPENDSN, fc->fddictn)) { + headerPut(pkg->header, &td, HEADERPUT_DEFAULT); + } } @@ -1403,12 +1446,14 @@ rpmRC rpmfcGenerateDepends(const rpmSpec spec, Package pkg) free(msg); } exit: - printDeps(pkg->header); + printDeps(fc); /* Clean up. */ + if (fc) + fc->pkg = NULL; free(fmode); rpmfcFree(fc); - argvFree(av); + rpmfiFree(fi); return rc; } |