- load headers as single contiguous region.
- add region marker as RPM_BIN_TYPE in packages and database.
- fix: don't headerCopy() relocateable packages if not relocating.
+ - fine-grained Requires, remove install PreReq's from Requires db.
3.0.6 -> 4.0
- use DIRNAMES/BASENAMES/DIRINDICES not FILENAMES in packages and db.
{ "Provides", { "%{__find_provides}", NULL, NULL, NULL },
RPMTAG_PROVIDENAME, RPMTAG_PROVIDEVERSION, RPMTAG_PROVIDEFLAGS,
0, -1 },
- { "PreReq", { "%{__find_prereq}", NULL, NULL, NULL },
+ { "PreReq", { NULL, NULL, NULL, NULL },
RPMTAG_REQUIRENAME, RPMTAG_REQUIREVERSION, RPMTAG_REQUIREFLAGS,
RPMSENSE_PREREQ, 0 },
+ { "Requires(interp)", { NULL, "interp", NULL, NULL },
+ -1, -1, RPMTAG_REQUIREFLAGS,
+ _notpre(RPMSENSE_INTERP), 0 },
+ { "Requires(rpmlib)", { NULL, "rpmlib", NULL, NULL },
+ -1, -1, RPMTAG_REQUIREFLAGS,
+ _notpre(RPMSENSE_RPMLIB), 0 },
+ { "Requires(verify)", { NULL, "verify", NULL, NULL },
+ -1, -1, RPMTAG_REQUIREFLAGS,
+ RPMSENSE_SCRIPT_VERIFY, 0 },
+ { "Requires(pre)", { NULL, "pre", NULL, NULL },
+ -1, -1, RPMTAG_REQUIREFLAGS,
+ _notpre(RPMSENSE_SCRIPT_PRE), 0 },
+ { "Requires(post)", { NULL, "post", NULL, NULL },
+ -1, -1, RPMTAG_REQUIREFLAGS,
+ _notpre(RPMSENSE_SCRIPT_POST), 0 },
+ { "Requires(preun)", { NULL, "preun", NULL, NULL },
+ -1, -1, RPMTAG_REQUIREFLAGS,
+ _notpre(RPMSENSE_SCRIPT_PREUN), 0 },
+ { "Requires(postun)", { NULL, "postun", NULL, NULL },
+ -1, -1, RPMTAG_REQUIREFLAGS,
+ _notpre(RPMSENSE_SCRIPT_POSTUN), 0 },
{ "Requires", { "%{__find_requires}", NULL, NULL, NULL },
-1, -1, RPMTAG_REQUIREFLAGS, /* XXX inherit name/version arrays */
RPMSENSE_PREREQ, RPMSENSE_PREREQ },
}
for (dm = depMsgs; dm->msg != NULL; dm++) {
- int i, tag;
+ int i, tag, tagflags;
tag = (dm->ftag > 0) ? dm->ftag : dm->ntag;
+ tagflags = 0;
switch(tag) {
case RPMTAG_PROVIDEFLAGS:
if (!pkg->autoProv)
continue;
failnonzero = 1;
+ tagflags = RPMSENSE_FIND_PROVIDES;
break;
case RPMTAG_REQUIREFLAGS:
if (!pkg->autoReq)
continue;
failnonzero = 0;
+ tagflags = RPMSENSE_FIND_REQUIRES;
break;
default:
continue;
}
/* Get the script name to run */
- myargv[0] = rpmExpand(dm->argv[0], NULL);
+ myargv[0] = (dm->argv[0] ? rpmExpand(dm->argv[0], NULL) : NULL);
if (!(myargv[0] && *myargv[0] != '%')) {
free(myargv[0]);
}
/* Parse dependencies into header */
- rc = parseRCPOT(spec, pkg, getStringBuf(readBuf), tag, 0,
- multiLib > 1 ? RPMSENSE_MULTILIB : 0);
+ tagflags &= ~RPMSENSE_MULTILIB;
+ if (multiLib > 1)
+ tagflags |= RPMSENSE_MULTILIB;
+ else
+ tagflags &= ~RPMSENSE_MULTILIB;
+ rc = parseRCPOT(spec, pkg, getStringBuf(readBuf), tag, 0, tagflags);
freeStringBuf(readBuf);
if (rc) {
{
int hasVersions = (versions != NULL);
int hasFlags = (flags != NULL);
- int i, bingo;
+ int bingo = 0;
+ int i;
- bingo = 0;
for (i = 0; i < count; i++, names++, versions++, flags++) {
if (hasFlags && !((*flags & dm->mask) ^ dm->xor))
continue;
}
if (!strcmp(tok, "-n")) {
- if (!(tok = strtok(NULL, " \t\n"))) {
+ if (!(tok = strtok(NULL, " \t\n")))
return 1;
- }
*flag = PART_NAME;
} else {
*flag = PART_SUBNAME;
return 1;
}
+struct tokenBits {
+ const char * name;
+ int bits;
+};
+
+static struct tokenBits installScriptBits[] = {
+ { "interp", RPMSENSE_INTERP },
+ { "prereq", RPMSENSE_PREREQ },
+ { "preun", RPMSENSE_SCRIPT_PREUN },
+ { "pre", RPMSENSE_SCRIPT_PRE },
+ { "postun", RPMSENSE_SCRIPT_POSTUN },
+ { "post", RPMSENSE_SCRIPT_POST },
+ { "rpmlib", RPMSENSE_RPMLIB },
+ { "verify", RPMSENSE_SCRIPT_VERIFY },
+ { NULL, 0 }
+};
+
+static struct tokenBits buildScriptBits[] = {
+ { "prep", RPMSENSE_SCRIPT_PREP },
+ { "build", RPMSENSE_SCRIPT_BUILD },
+ { "install", RPMSENSE_SCRIPT_INSTALL },
+ { "clean", RPMSENSE_SCRIPT_CLEAN },
+ { NULL, 0 }
+};
+
+static int parseBits(const char * s, struct tokenBits * tokbits, int * bp)
+{
+ struct tokenBits *tb;
+ const char *se;
+ int bits = 0;
+ int c = 0;
+
+ if (s) {
+ while (*s) {
+ while ((c = *s) && isspace(c)) s++;
+ se = s;
+ while ((c = *se) && isalpha(c)) se++;
+ if (s == se)
+ break;
+ for (tb = tokbits; tb->name; tb++) {
+ if (strlen(tb->name) == (se-s) && !strncmp(tb->name, s, (se-s)))
+ break;
+ }
+ if (tb->name == NULL)
+ break;
+ bits |= tb->bits;
+ while ((c = *se) && isspace(c)) se++;
+ if (c != ',')
+ break;
+ s = ++se;
+ }
+ }
+ if (c == 0 && *bp) *bp = bits;
+ return (c ? RPMERR_BADSPEC : 0);
+}
+
static inline char * findLastChar(char * s)
{
char *res = s;
while (*s) {
- if (! isspace(*s)) {
+ if (! isspace(*s))
res = s;
- }
s++;
}
char *end;
char **array;
int multiToken = 0;
- int num, rc, len;
+ int tagflags;
+ int len;
+ int num;
+ int rc;
/* Find the start of the "field" and strip trailing space */
while ((*field) && (*field != ':'))
if ((rc = parseNoSource(spec, field, tag)))
return rc;
break;
- case RPMTAG_OBSOLETEFLAGS:
- case RPMTAG_PROVIDEFLAGS:
- case RPMTAG_BUILDREQUIRES:
- case RPMTAG_BUILDCONFLICTS:
case RPMTAG_BUILDPREREQ:
+ case RPMTAG_BUILDREQUIRES:
+ if ((rc = parseBits(lang, buildScriptBits, &tagflags))) {
+ rpmError(RPMERR_BADSPEC,
+ _("line %d: Bad %s: qualifiers: %s"),
+ spec->lineNum, tagName(tag), spec->line);
+ return rc;
+ }
+ if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags)))
+ return rc;
+ break;
case RPMTAG_REQUIREFLAGS:
- case RPMTAG_CONFLICTFLAGS:
case RPMTAG_PREREQ:
- if ((rc = parseRCPOT(spec, pkg, field, tag, 0, 0)))
+ if ((rc = parseBits(lang, installScriptBits, &tagflags))) {
+ rpmError(RPMERR_BADSPEC,
+ _("line %d: Bad %s: qualifiers: %s"),
+ spec->lineNum, tagName(tag), spec->line);
+ return rc;
+ }
+ if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags)))
+ return rc;
+ break;
+ case RPMTAG_BUILDCONFLICTS:
+ case RPMTAG_CONFLICTFLAGS:
+ case RPMTAG_OBSOLETEFLAGS:
+ case RPMTAG_PROVIDEFLAGS:
+ tagflags = 0;
+ if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags)))
return rc;
break;
case RPMTAG_EXCLUDEARCH:
{RPMTAG_EXCLUSIVEOS, 0, 0, "exclusiveos"},
{RPMTAG_ICON, 0, 0, "icon"},
{RPMTAG_PROVIDEFLAGS, 0, 0, "provides"},
- {RPMTAG_REQUIREFLAGS, 0, 0, "requires"},
- {RPMTAG_PREREQ, 0, 0, "prereq"},
+ {RPMTAG_REQUIREFLAGS, 0, 1, "requires"},
+ {RPMTAG_PREREQ, 0, 1, "prereq"},
{RPMTAG_CONFLICTFLAGS, 0, 0, "conflicts"},
{RPMTAG_OBSOLETEFLAGS, 0, 0, "obsoletes"},
{RPMTAG_PREFIXES, 0, 0, "prefixes"},
{RPMTAG_BUILDARCHS, 0, 0, "buildarchitectures"},
{RPMTAG_BUILDARCHS, 0, 0, "buildarch"},
{RPMTAG_BUILDCONFLICTS, 0, 0, "buildconflicts"},
- {RPMTAG_BUILDPREREQ, 0, 0, "buildprereq"},
- {RPMTAG_BUILDREQUIRES, 0, 0, "buildrequires"},
+ {RPMTAG_BUILDPREREQ, 0, 1, "buildprereq"},
+ {RPMTAG_BUILDREQUIRES, 0, 1, "buildrequires"},
{RPMTAG_AUTOREQPROV, 0, 0, "autoreqprov"},
{RPMTAG_AUTOREQ, 0, 0, "autoreq"},
{RPMTAG_AUTOPROV, 0, 0, "autoprov"},
if (!strncasecmp(spec->line, p->token, p->len))
break;
}
-
if (p->token == NULL)
return 1;
s = spec->line + p->len;
SKIPSPACE(s);
- if (! p->multiLang) {
+ switch (p->multiLang) {
+ default:
+ case 0:
/* Unless this is a source or a patch, a ':' better be next */
if (p->tag != RPMTAG_SOURCE && p->tag != RPMTAG_PATCH) {
- if (*s != ':') {
- return 1;
- }
+ if (*s != ':') return 1;
}
*lang = '\0';
- } else {
- if (*s != ':') {
- if (*s != '(') return 1;
- s++;
- SKIPSPACE(s);
- while (! isspace(*s) && *s != ')') {
- *lang++ = *s++;
- }
- *lang = '\0';
- SKIPSPACE(s);
- if (*s != ')') return 1;
- s++;
- SKIPSPACE(s);
- if (*s != ':') return 1;
- } else {
+ break;
+ case 1: /* Parse optional ( <token> ). */
+ if (*s == ':') {
strcpy(lang, RPMBUILD_DEFAULT_LANG);
+ break;
}
+ if (*s != '(') return 1;
+ s++;
+ SKIPSPACE(s);
+ while (!isspace(*s) && *s != ')')
+ *lang++ = *s++;
+ *lang = '\0';
+ SKIPSPACE(s);
+ if (*s != ')') return 1;
+ s++;
+ SKIPSPACE(s);
+ if (*s != ':') return 1;
+ break;
}
*tag = p->tag;
const char * mainName;
headerNVR(spec->packages->header, &mainName, NULL, NULL);
sprintf(fullName, "%s-%s", mainName, name);
- } else {
+ } else
strcpy(fullName, name);
- }
headerAddEntry(pkg->header, RPMTAG_NAME, RPM_STRING_TYPE, fullName, 1);
}
if ((rc = readLine(spec, STRIP_TRAILINGSPACE | STRIP_COMMENTS)) > 0) {
nextPart = PART_NONE;
} else {
- if (rc) {
+ if (rc)
return rc;
- }
while (! (nextPart = isPart(spec->line))) {
/* Skip blank lines */
linep = spec->line;
spec->lineNum, spec->line);
return RPMERR_BADSPEC;
}
- if (handlePreambleTag(spec, pkg, tag, macro, lang)) {
+ if (handlePreambleTag(spec, pkg, tag, macro, lang))
return RPMERR_BADSPEC;
- }
- if (spec->buildArchitectures && !spec->inBuildArchitectures) {
+ if (spec->buildArchitectures && !spec->inBuildArchitectures)
return PART_BUILDARCHITECTURES;
- }
}
if ((rc =
readLine(spec, STRIP_TRAILINGSPACE | STRIP_COMMENTS)) > 0) {
nextPart = PART_NONE;
break;
}
- if (rc) {
+ if (rc)
return rc;
- }
}
}
}
/* XXX Skip valid arch check if not building binary package */
- if (!spec->anyarch && checkForValidArchitectures(spec)) {
- return RPMERR_BADSPEC;
- }
+ if (!spec->anyarch && checkForValidArchitectures(spec))
+ return RPMERR_BADSPEC;
- if (pkg == spec->packages) {
+ if (pkg == spec->packages)
fillOutMainPackage(pkg->header);
- }
- if (checkForDuplicates(pkg->header, fullName)) {
+ if (checkForDuplicates(pkg->header, fullName))
return RPMERR_BADSPEC;
- }
- if (pkg != spec->packages) {
+ if (pkg != spec->packages)
headerCopyTags(spec->packages->header, pkg->header, copyTagsDuringParse);
- }
- if (checkForRequired(pkg->header, fullName)) {
+ if (checkForRequired(pkg->header, fullName))
return RPMERR_BADSPEC;
- }
return nextPart;
}
if (*r == '\0')
break;
- flags = tagflags;
+ flags = (tagflags & ~RPMSENSE_SENSEMASK);
/* Tokens must begin with alphanumeric, _, or / */
if (!(isalnum(r[0]) || r[0] == '_' || r[0] == '/')) {
char *partname = NULL;
int reqtag = 0;
int tag = 0;
+ int tagflags = 0;
int progtag = 0;
int flag = PART_SUBNAME;
Package pkg;
- StringBuf sb;
+ StringBuf sb = NULL;
int nextPart;
int index;
char reqargs[BUFSIZ];
switch (parsePart) {
case PART_PRE:
tag = RPMTAG_PREIN;
+ tagflags = RPMSENSE_SCRIPT_PRE;
progtag = RPMTAG_PREINPROG;
partname = "%pre";
break;
case PART_POST:
tag = RPMTAG_POSTIN;
+ tagflags = RPMSENSE_SCRIPT_POST;
progtag = RPMTAG_POSTINPROG;
partname = "%post";
break;
case PART_PREUN:
tag = RPMTAG_PREUN;
+ tagflags = RPMSENSE_SCRIPT_PREUN;
progtag = RPMTAG_PREUNPROG;
partname = "%preun";
break;
case PART_POSTUN:
tag = RPMTAG_POSTUN;
+ tagflags = RPMSENSE_SCRIPT_POSTUN;
progtag = RPMTAG_POSTUNPROG;
partname = "%postun";
break;
case PART_VERIFYSCRIPT:
tag = RPMTAG_VERIFYSCRIPT;
+ tagflags = RPMSENSE_SCRIPT_VERIFY;
progtag = RPMTAG_VERIFYSCRIPTPROG;
partname = "%verifyscript";
break;
case PART_TRIGGERIN:
tag = RPMTAG_TRIGGERSCRIPTS;
+ tagflags = 0;
reqtag = RPMTAG_TRIGGERIN;
progtag = RPMTAG_TRIGGERSCRIPTPROG;
partname = "%triggerin";
break;
case PART_TRIGGERUN:
tag = RPMTAG_TRIGGERSCRIPTS;
+ tagflags = 0;
reqtag = RPMTAG_TRIGGERUN;
progtag = RPMTAG_TRIGGERSCRIPTPROG;
partname = "%triggerun";
break;
case PART_TRIGGERPOSTUN:
tag = RPMTAG_TRIGGERSCRIPTS;
+ tagflags = 0;
reqtag = RPMTAG_TRIGGERPOSTUN;
progtag = RPMTAG_TRIGGERSCRIPTPROG;
partname = "%triggerpostun";
rpmError(RPMERR_BADSPEC,
_("line %d: script program must begin "
"with \'/\': %s"), spec->lineNum, prog);
- FREE(argv);
- poptFreeContext(optCon);
- return RPMERR_BADSPEC;
+ rc = RPMERR_BADSPEC;
+ goto exit;
}
} else if (arg == 'n') {
flag = PART_NAME;
spec->lineNum,
poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
spec->line);
- FREE(argv);
- poptFreeContext(optCon);
- return RPMERR_BADSPEC;
+ rc = RPMERR_BADSPEC;
+ goto exit;
}
if (poptPeekArg(optCon)) {
rpmError(RPMERR_BADSPEC, _("line %d: Too many names: %s"),
spec->lineNum,
spec->line);
- FREE(argv);
- poptFreeContext(optCon);
- return RPMERR_BADSPEC;
+ rc = RPMERR_BADSPEC;
+ goto exit;
}
}
if (lookupPackage(spec, name, flag, &pkg)) {
rpmError(RPMERR_BADSPEC, _("line %d: Package does not exist: %s"),
spec->lineNum, spec->line);
- FREE(argv);
- poptFreeContext(optCon);
- return RPMERR_BADSPEC;
+ rc = RPMERR_BADSPEC;
+ goto exit;
}
if (tag != RPMTAG_TRIGGERSCRIPTS) {
if (headerIsEntry(pkg->header, progtag)) {
rpmError(RPMERR_BADSPEC, _("line %d: Second %s"),
spec->lineNum, partname);
- FREE(argv);
- poptFreeContext(optCon);
- return RPMERR_BADSPEC;
+ rc = RPMERR_BADSPEC;
+ goto exit;
}
}
if ((rc = poptParseArgvString(prog, &progArgc, &progArgv))) {
rpmError(RPMERR_BADSPEC, _("line %d: Error parsing %s: %s"),
spec->lineNum, partname, poptStrerror(rc));
- FREE(argv);
- poptFreeContext(optCon);
- return RPMERR_BADSPEC;
+ rc = RPMERR_BADSPEC;
+ goto exit;
}
sb = newStringBuf();
if ((rc = readLine(spec, STRIP_NOTHING)) > 0) {
nextPart = PART_NONE;
} else {
- if (rc) {
- return rc;
- }
+ if (rc)
+ goto exit;
while (! (nextPart = isPart(spec->line))) {
appendStringBuf(sb, spec->line);
if ((rc = readLine(spec, STRIP_NOTHING)) > 0) {
nextPart = PART_NONE;
break;
}
- if (rc) {
- return rc;
- }
+ if (rc)
+ goto exit;
}
}
stripTrailingBlanksStringBuf(sb);
p = getStringBuf(sb);
- addReqProv(spec, pkg->header, RPMSENSE_PREREQ, prog, NULL, 0);
+ addReqProv(spec, pkg->header, (tagflags | RPMSENSE_INTERP), prog, NULL, 0);
/* Trigger script insertion is always delayed in order to */
/* get the index right. */
index = addTriggerIndex(pkg, file, p, prog);
/* Generate the trigger tags */
- if ((rc = parseRCPOT(spec, pkg, reqargs, reqtag, index, 0))) {
- freeStringBuf(sb);
- FREE(progArgv);
- FREE(argv);
- poptFreeContext(optCon);
- return rc;
- }
+ if ((rc = parseRCPOT(spec, pkg, reqargs, reqtag, index, tagflags)))
+ goto exit;
} else {
headerAddEntry(pkg->header, progtag, RPM_STRING_TYPE, prog, 1);
- if (*p) {
+ if (*p)
headerAddEntry(pkg->header, tag, RPM_STRING_TYPE, p, 1);
- }
+
if (file) {
switch (parsePart) {
case PART_PRE:
}
}
}
+ rc = nextPart;
- freeStringBuf(sb);
- FREE(progArgv);
- FREE(argv);
- poptFreeContext(optCon);
+exit:
+ if (sb)
+ freeStringBuf(sb);
+ if (progArgv) {
+ FREE(progArgv);
+ }
+ if (argv) {
+ FREE(argv);
+ }
+ if (optCon)
+ poptFreeContext(optCon);
- return nextPart;
+ return rc;
}
rpmParseState isPart(const char *line)
{
- char c;
struct PartRec *p;
if (partList[0].len == 0)
initParts(partList);
for (p = partList; p->token != NULL; p++) {
- if (! strncasecmp(line, p->token, p->len)) {
- c = *(line + p->len);
- if (c == '\0' || isspace(c)) {
- break;
- }
- }
+ char c;
+ if (strncasecmp(line, p->token, p->len))
+ continue;
+ c = *(line + p->len);
+ if (c == '\0' || isspace(c))
+ break;
}
- if (p->token) {
- return p->part;
- } else {
- return PART_NONE;
- }
+ return (p->token ? p->part : PART_NONE);
}
static int matchTok(const char *token, const char *line)
void handleComments(char *s)
{
SKIPSPACE(s);
- if (*s == '#') {
+ if (*s == '#')
*s = '\0';
- }
}
static void forceIncludeFile(Spec spec, const char * fileName)
nametag = RPMTAG_PROVIDENAME;
versiontag = RPMTAG_PROVIDEVERSION;
flagtag = RPMTAG_PROVIDEFLAGS;
+ extra = flag & RPMSENSE_FIND_PROVIDES;
} else if (flag & RPMSENSE_OBSOLETES) {
nametag = RPMTAG_OBSOLETENAME;
versiontag = RPMTAG_OBSOLETEVERSION;
nametag = RPMTAG_REQUIRENAME;
versiontag = RPMTAG_REQUIREVERSION;
flagtag = RPMTAG_REQUIREFLAGS;
- extra = RPMSENSE_PREREQ;
+ extra = flag & _ALL_REQUIRES_MASK;
} else if (flag & RPMSENSE_TRIGGER) {
nametag = RPMTAG_TRIGGERNAME;
versiontag = RPMTAG_TRIGGERVERSION;
nametag = RPMTAG_REQUIRENAME;
versiontag = RPMTAG_REQUIREVERSION;
flagtag = RPMTAG_REQUIREFLAGS;
+ extra = flag & _ALL_REQUIRES_MASK;
}
flag = (flag & (RPMSENSE_SENSEMASK | RPMSENSE_MULTILIB)) | extra;
(void) stpcpy( stpcpy( stpcpy(reqname, "rpmlib("), feature), ")");
/* XXX 1st arg is unused */
- return addReqProv(NULL, h, RPMSENSE_PREREQ|(RPMSENSE_LESS|RPMSENSE_EQUAL),
+ return addReqProv(NULL, h, RPMSENSE_RPMLIB|(RPMSENSE_LESS|RPMSENSE_EQUAL),
reqname, featureEVR, 0);
}
return rc;
}
-#if 0
+/*
+ * XXX Hack to remove known Red Hat dependency loops, will be removed
+ * Real Soon Now.
+ */
+#define DEPENDENCY_WHITEOUT
+
+#if defined(DEPENDENCY_WHITEOUT)
static struct badDeps_s {
const char * pname;
const char * qname;
} badDeps[] = {
-#if 0
{ "libtermcap", "bash" },
{ "modutils", "vixie-cron" },
- { "XFree86", "Mesa" },
{ "ypbind", "yp-tools" },
- { "pango-gtkbeta", "pango-gtkbeta-devel" },
{ "ghostscript-fonts", "ghostscript" },
+ /* 7.0 only */
+ { "pango-gtkbeta-devel", "pango-gtkbeta" },
+ { "XFree86", "Mesa" },
+ { "compat-glibc", "db2" },
+ { "compat-glibc", "db1" },
+ { "pam", "initscripts" },
+ { "kernel", "initscripts" },
+ { "initscripts", "sysklogd" },
+ /* 6.2 */
+ { "egcs-c++", "libstdc++" },
+ /* 6.1 */
+ { "pilot-link-devel", "pilot-link" },
+ /* 5.2 */
+ { "pam", "pamconfig" },
+#if 0
/* ================= */
{ "usermode", "util-linux" },
{ "chkfontpath", "SysVinit" },
for (bdp = badDeps; bdp->pname != NULL; bdp++) {
if (!strcmp(p->name, bdp->pname) && !strcmp(q->name, bdp->qname)) {
+#if 0
fprintf(stderr, "*** avoiding %s Requires: %s\n", p->name, q->name);
+#endif
return 1;
}
}
}
}
+static inline const char * identifyDepend(int_32 f) {
+ if (isLegacyPreReq(f))
+ return "PreReq:";
+ f = _notpre(f);
+ if (f & RPMSENSE_SCRIPT_PRE)
+ return "Requires(pre):";
+ if (f & RPMSENSE_SCRIPT_POST)
+ return "Requires(post):";
+ if (f & RPMSENSE_SCRIPT_PREUN)
+ return "Requires(preun):";
+ if (f & RPMSENSE_SCRIPT_POSTUN)
+ return "Requires(postun):";
+ if (f & RPMSENSE_SCRIPT_VERIFY)
+ return "Requires(verify):";
+ if (f & RPMSENSE_FIND_REQUIRES)
+ return "Requires(auto):";
+ return "Requires:";
+}
+
/**
- * Find (and eliminate PreReq's) "q <- p" relation in dependency loop.
+ * Find (and eliminate co-requisites) "q <- p" relation in dependency loop.
* Search all successors of q for instance of p. Format the specific relation,
- * (e.g. p contains "Requires: q"). Unlink and free PreReq: successor node(s).
+ * (e.g. p contains "Requires: q"). Unlink and free co-requisite (i.e.
+ * pure Requires: dependencies) successor node(s).
* @param q sucessor (i.e. package required by p)
* @param p predecessor (i.e. package that "Requires: q")
- * @param zap eliminate PreReq's ?
+ * @param zap max. no. of co-requisites to remove (-1 is all)?
+ * @retval nzaps address of no. of relations removed
* @return (possibly NULL) formatted "q <- p" releation (malloc'ed)
*/
static /*@owned@*/ /*@null@*/ const char *
if (tsi->tsi_suc != p)
continue;
j = tsi->tsi_reqx;
- dp = printDepend( ((p->requireFlags[j] & RPMSENSE_PREREQ)
- ? "PreReq:" : "Requires:"),
+ dp = printDepend( identifyDepend(p->requireFlags[j]),
p->requires[j], p->requiresEVR[j], p->requireFlags[j]);
/*
* PreReq: /bin/sh
* to fail.
*/
- if (zap && (p->requireFlags[j] & RPMSENSE_PREREQ)) {
+ if (zap && !(p->requireFlags[j] & RPMSENSE_PREREQ)) {
rpmMessage(RPMMESS_WARNING,
_("removing %s-%s-%s \"%s\" from tsort relations.\n"),
p->name, p->version, p->release, dp);
free(tsi);
if (nzaps)
(*nzaps)++;
+ if (zap)
+ zap--;
}
break;
}
}
/**
+ * Record next "q <- p" relation (i.e. "p" requires "q").
+ * @param rpmdep rpm transaction set
+ * @param p predecessor (i.e. package that "Requires: q")
+ * @param selected boolean package selected array
+ * @param j relation index
+ * @return 0 always
+ */
+static inline int addRelation( const rpmTransactionSet rpmdep,
+ struct availablePackage * p, unsigned char * selected, int j)
+{
+ struct availablePackage * q;
+ struct tsortInfo * tsi;
+ int matchNum;
+
+ q = alSatisfiesDepend(&rpmdep->addedPackages, NULL, NULL,
+ p->requires[j], p->requiresEVR[j], p->requireFlags[j]);
+
+ /* Ordering depends only on added package relations. */
+ if (q == NULL)
+ return 0;
+
+ /* Avoid rpmlib feature dependencies. */
+ if (!strncmp(p->requires[j], "rpmlib(", sizeof("rpmlib(")-1))
+ return 0;
+
+#if defined(DEPENDENCY_WHITEOUT)
+ /* Avoid certain dependency relations. */
+ if (ignoreDep(p, q))
+ return 0;
+#endif
+
+ /* Avoid redundant relations. */
+ /* XXX FIXME: add control bit. */
+ matchNum = q - rpmdep->addedPackages.list;
+ if (selected[matchNum])
+ return 0;
+ selected[matchNum] = 1;
+
+ /* T3. Record next "q <- p" relation (i.e. "p" requires "q"). */
+ p->tsi.tsi_count++;
+ tsi = xmalloc(sizeof(*tsi));
+ tsi->tsi_suc = p;
+ tsi->tsi_reqx = j;
+ tsi->tsi_next = q->tsi.tsi_next;
+ q->tsi.tsi_next = tsi;
+ return 0;
+}
+
+/**
* Compare ordered list entries by index (qsort/bsearch).
* @param a 1st ordered list entry
* @param b 2nd ordered list entry
selected[matchNum] = 1;
/* T2. Next "q <- p" relation. */
+
+ /* First, do pre-requisites. */
for (j = 0; j < p->requiresCount; j++) {
- /* Avoid rpmlib feature dependencies. */
- if (!strncmp(p->requires[j], "rpmlib(", sizeof("rpmlib(")-1))
- continue;
+ /* Skip if not %pre/%post requires or legacy prereq. */
-#if 0
- /* XXX FIXME: add control bit. */
- /* Only PreReq:'s determine order (for now). */
- if (!_depends_debug && !(p->requireFlags[j] & RPMSENSE_PREREQ))
+ if (isErasePreReq(p->requireFlags[j]) ||
+ !( isInstallPreReq(p->requireFlags[j]) ||
+ isLegacyPreReq(p->requireFlags[j]) ))
continue;
-#endif
- /* Ordering depends only on added package relations. */
- q = alSatisfiesDepend(&rpmdep->addedPackages, NULL, NULL,
- p->requires[j], p->requiresEVR[j], p->requireFlags[j]);
- if (q == NULL) continue;
+ /* T3. Record next "q <- p" relation (i.e. "p" requires "q"). */
+ (void) addRelation(rpmdep, p, selected, j);
-#if 0
- /* Avoid certain dependency relations. */
- if (ignoreDep(p, q)) continue;
-#endif
+ }
+
+ /* Then do co-requisites. */
+ for (j = 0; j < p->requiresCount; j++) {
+
+ /* Skip if %pre/%post requires or legacy prereq. */
- /* Avoid redundant relations. */
- /* XXX FIXME: add control bit. */
- matchNum = q - rpmdep->addedPackages.list;
- if (selected[matchNum]) continue;
- selected[matchNum] = 1;
+ if (isErasePreReq(p->requireFlags[j]) ||
+ ( isInstallPreReq(p->requireFlags[j]) ||
+ isLegacyPreReq(p->requireFlags[j]) ))
+ continue;
/* T3. Record next "q <- p" relation (i.e. "p" requires "q"). */
- p->tsi.tsi_count++;
- tsi = xmalloc(sizeof(*tsi));
- tsi->tsi_suc = p;
- tsi->tsi_reqx = j;
- tsi->tsi_next = q->tsi.tsi_next;
- q->tsi.tsi_next = tsi;
+ (void) addRelation(rpmdep, p, selected, j);
+
}
}
printed = 1;
}
- /* Find (and destroy if PreReq:) "q <- p" relation. */
+ /* Find (and destroy if co-requisite) "q <- p" relation. */
dp = zapRelation(q, p, 1, &nzaps);
/* Print next member of loop. */
int rpmtype = 0;
int rpmcnt = 0;
int rpmtag;
+ int_32 * requireFlags;
int i, j;
dbi = NULL;
+ requireFlags = NULL;
rpmtag = dbiTags[dbix];
switch (rpmtag) {
rpmvals = baseNames;
rpmcnt = count;
break;
+ case RPMTAG_REQUIRENAME:
+ headerGetEntry(h, rpmtag, &rpmtype, (void **)&rpmvals, &rpmcnt);
+ headerGetEntry(h, RPMTAG_REQUIREFLAGS, NULL,
+ (void **)&requireFlags, NULL);
+ break;
default:
- headerGetEntry(h, rpmtag, &rpmtype,
- (void **) &rpmvals, &rpmcnt);
+ headerGetEntry(h, rpmtag, &rpmtype, (void **)&rpmvals, &rpmcnt);
break;
}
* included the tagNum only for files.
*/
switch (dbi->dbi_rpmtag) {
+ case RPMTAG_REQUIRENAME:
+ /* Filter out install prerequisites. */
+ if (requireFlags && isInstallPreReq(requireFlags[i])) {
+ rpmMessage(RPMMESS_DEBUG, ("%6d %s\n"), i, rpmvals[i]);
+ continue;
+ }
+ rec->tagNum = i;
+ break;
case RPMTAG_TRIGGERNAME:
if (i) { /* don't add duplicates */
for (j = 0; j < i; j++) {
if (j < i)
continue;
}
- /*@fallthrough@*/
+ rec->tagNum = i;
+ break;
default:
rec->tagNum = i;
break;
*/
typedef enum rpmsenseFlags_e {
RPMSENSE_ANY = 0,
- RPMSENSE_SERIAL = (1 << 0), /*!< @todo Legacy. */
+ RPMSENSE_SERIAL = (1 << 0), /*!< @todo Legacy. */
RPMSENSE_LESS = (1 << 1),
RPMSENSE_GREATER = (1 << 2),
RPMSENSE_EQUAL = (1 << 3),
RPMSENSE_PROVIDES = (1 << 4), /* only used internally by builds */
RPMSENSE_CONFLICTS = (1 << 5), /* only used internally by builds */
- RPMSENSE_PREREQ = (1 << 6),
+ RPMSENSE_PREREQ = (1 << 6), /*!< @todo Legacy. */
RPMSENSE_OBSOLETES = (1 << 7), /* only used internally by builds */
- RPMSENSE_TRIGGERIN = (1 << 16),
- RPMSENSE_TRIGGERUN = (1 << 17),
- RPMSENSE_TRIGGERPOSTUN= (1 << 18),
+ RPMSENSE_INTERP = (1 << 8), /*!< Interpreter used by scriptlet. */
+ RPMSENSE_SCRIPT_PRE = ((1 << 9)|RPMSENSE_PREREQ), /*!< %pre dependency. */
+ RPMSENSE_SCRIPT_POST = ((1 << 10)|RPMSENSE_PREREQ), /*!< %post dependency. */
+ RPMSENSE_SCRIPT_PREUN = ((1 << 11)|RPMSENSE_PREREQ), /*!< %preun dependency. */
+ RPMSENSE_SCRIPT_POSTUN = ((1 << 12)|RPMSENSE_PREREQ), /*!< %postun dependency. */
+ RPMSENSE_SCRIPT_VERIFY = (1 << 13), /*!< %verify dependency. */
+ RPMSENSE_FIND_REQUIRES = (1 << 14), /*!< find-requires generated dependency. */
+ RPMSENSE_FIND_PROVIDES = (1 << 15), /*!< find-provides generated dependency. */
+
+ RPMSENSE_TRIGGERIN = (1 << 16), /*!< %triggerin dependency. */
+ RPMSENSE_TRIGGERUN = (1 << 17), /*!< %triggerun dependency. */
+ RPMSENSE_TRIGGERPOSTUN = (1 << 18), /*!< %triggerpostun dependency. */
RPMSENSE_MULTILIB = (1 << 19),
+ RPMSENSE_SCRIPT_PREP = (1 << 20), /*!< %prep build dependency. */
+ RPMSENSE_SCRIPT_BUILD = (1 << 21), /*!< %build build dependency. */
+ RPMSENSE_SCRIPT_INSTALL = (1 << 22),/*!< %install build dependency. */
+ RPMSENSE_SCRIPT_CLEAN = (1 << 23), /*!< %clean build dependency. */
+ RPMSENSE_RPMLIB = ((1 << 24) | RPMSENSE_PREREQ), /*!< rpmlib(feature) dependency. */
+ RPMSENSE_TRIGGERPREIN = (1 << 25) /*!< @todo Implement %triggerprein. */
+
} rpmsenseFlags;
#define RPMSENSE_SENSEMASK 15 /* Mask to get senses, ie serial, */
#define isDependsMULTILIB(_dflags) ((_dflags) & RPMSENSE_MULTILIB)
+#define _ALL_REQUIRES_MASK (\
+ RPMSENSE_INTERP | \
+ RPMSENSE_SCRIPT_PRE | \
+ RPMSENSE_SCRIPT_POST | \
+ RPMSENSE_SCRIPT_PREUN | \
+ RPMSENSE_SCRIPT_POSTUN | \
+ RPMSENSE_SCRIPT_VERIFY | \
+ RPMSENSE_FIND_REQUIRES | \
+ RPMSENSE_SCRIPT_PREP | \
+ RPMSENSE_SCRIPT_BUILD | \
+ RPMSENSE_SCRIPT_INSTALL | \
+ RPMSENSE_SCRIPT_CLEAN | \
+ RPMSENSE_RPMLIB )
+
+#define _notpre(_x) ((_x) & ~RPMSENSE_PREREQ)
+#define _INSTALL_ONLY_MASK \
+ _notpre(RPMSENSE_SCRIPT_PRE|RPMSENSE_SCRIPT_POST|RPMSENSE_RPMLIB)
+#define _ERASE_ONLY_MASK \
+ _notpre(RPMSENSE_SCRIPT_PREUN|RPMSENSE_SCRIPT_POSTUN)
+
+#define isLegacyPreReq(_x) (((_x) & _ALL_REQUIRES_MASK) == RPMSENSE_PREREQ)
+#define isInstallPreReq(_x) ((_x) & _INSTALL_ONLY_MASK)
+#define isErasePreReq(_x) ((_x) & _ERASE_ONLY_MASK)
+
#define xfree(_p) free((void *)_p)
/* ==================================================================== */
int featureFlags;
const char * featureDescription;
} rpmlibProvides[] = {
- { "rpmlib(VersionedDependencies)", "3.0.3-1", RPMSENSE_EQUAL,
+ { "rpmlib(VersionedDependencies)", "3.0.3-1",
+ (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
"PreReq:, Provides:, and Obsoletes: dependencies support versions." },
- { "rpmlib(CompressedFileNames)", "3.0.4-1", RPMSENSE_EQUAL,
+ { "rpmlib(CompressedFileNames)", "3.0.4-1",
+ (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
"file names stored as (dirName,BaseName,dirIndex) tuple, not as path."},
- { "rpmlib(PayloadIsBzip2)", "3.0.5-1", RPMSENSE_EQUAL,
+ { "rpmlib(PayloadIsBzip2)", "3.0.5-1",
+ (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
"package payload compressed using bzip2." },
- { "rpmlib(PayloadFilesHavePrefix)", "4.0-1", RPMSENSE_EQUAL,
+ { "rpmlib(PayloadFilesHavePrefix)", "4.0-1",
+ (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
"package payload files have \"./\" prefix." },
- { "rpmlib(ExplicitPackageProvide)", "4.0-1", RPMSENSE_EQUAL,
+ { "rpmlib(ExplicitPackageProvide)", "4.0-1",
+ (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
"package name-version-release not implicitly provided." },
{ NULL, NULL, 0 }
};
extern int _depends_debug;
+static int noDeps = 0;
+
static int
do_tsort(const char *fileArgv[])
{
}
- { struct rpmDependencyConflict * conflicts = NULL;
+ if (!noDeps) {
+ struct rpmDependencyConflict * conflicts = NULL;
int numConflicts = 0;
rc = rpmdepCheck(ts, &conflicts, &numConflicts);
}
static struct poptOption optionsTable[] = {
+ { "nodeps", '\0', 0, &noDeps, 0, NULL, NULL},
{ "verbose", 'v', 0, 0, 'v', NULL, NULL},
{ NULL, 0, 0, 0, 0, NULL, NULL}
};