- fine-grained Requires, remove install PreReq's from Requires db.
authorjbj <devnull@localhost>
Sun, 12 Nov 2000 11:11:49 +0000 (11:11 +0000)
committerjbj <devnull@localhost>
Sun, 12 Nov 2000 11:11:49 +0000 (11:11 +0000)
CVS patchset: 4258
CVS date: 2000/11/12 11:11:49

12 files changed:
CHANGES
build/files.c
build/parsePreamble.c
build/parseReqs.c
build/parseScript.c
build/parseSpec.c
build/reqprov.c
lib/depends.c
lib/rpmdb.c
lib/rpmlib.h
lib/rpmlibprov.c
tools/rpmsort.c

diff --git a/CHANGES b/CHANGES
index 5aeb713..edcae51 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -29,6 +29,7 @@
        - 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.
index 424f5c2..d34332c 100644 (file)
@@ -1747,9 +1747,30 @@ DepMsg_t depMsgs[] = {
   { "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 },
@@ -1794,20 +1815,23 @@ static int generateDepends(Spec spec, Package pkg,
     }
 
     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;
@@ -1815,7 +1839,7 @@ static int generateDepends(Spec spec, Package pkg,
        }
 
        /* 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]);
@@ -1855,8 +1879,12 @@ static int generateDepends(Spec spec, Package pkg,
        }
 
        /* 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) {
@@ -1874,9 +1902,9 @@ static void printDepMsg(DepMsg_t *dm, int count, const char **names,
 {
     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;
index c35b32c..7cd2e20 100644 (file)
@@ -67,9 +67,8 @@ static int parseSimplePart(char *line, /*@out@*/char **name, /*@out@*/int *flag)
     }
     
     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;
@@ -92,14 +91,69 @@ static int parseYesNo(char *s)
     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++;
     }
 
@@ -336,7 +390,10 @@ static int handlePreambleTag(Spec spec, Package pkg, int tag, const char *macro,
     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 != ':'))
@@ -509,15 +566,34 @@ static int handlePreambleTag(Spec spec, Package pkg, int tag, const char *macro,
        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:
@@ -583,8 +659,8 @@ static struct PreambleRec {
     {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"},
@@ -593,8 +669,8 @@ static struct PreambleRec {
     {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"},
@@ -621,38 +697,38 @@ static int findPreambleTag(Spec spec, /*@out@*/int *tag, /*@out@*/char **macro,
        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;
@@ -693,18 +769,16 @@ int parsePreamble(Spec spec, int initialPackage)
            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;
@@ -715,21 +789,18 @@ int parsePreamble(Spec spec, int initialPackage)
                             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;
-           }
        }
     }
 
@@ -741,25 +812,20 @@ int parsePreamble(Spec spec, int initialPackage)
     }
 
     /* 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;
 }
index 3f5c5df..4c27df5 100644 (file)
@@ -90,7 +90,7 @@ int parseRCPOT(Spec spec, Package pkg, const char *field, int tag,
        if (*r == '\0')
            break;
 
-       flags = tagflags;
+       flags = (tagflags & ~RPMSENSE_SENSEMASK);
 
        /* Tokens must begin with alphanumeric, _, or / */
        if (!(isalnum(r[0]) || r[0] == '_' || r[0] == '/')) {
index aede861..b0c9bed 100644 (file)
@@ -71,10 +71,11 @@ int parseScript(Spec spec, int parsePart)
     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];
@@ -91,43 +92,51 @@ int parseScript(Spec spec, int parsePart)
     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";
@@ -160,9 +169,8 @@ int parseScript(Spec spec, int parsePart)
                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;
@@ -174,9 +182,8 @@ int parseScript(Spec spec, int parsePart)
                 spec->lineNum,
                 poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
                 spec->line);
-       FREE(argv);
-       poptFreeContext(optCon);
-       return RPMERR_BADSPEC;
+       rc = RPMERR_BADSPEC;
+       goto exit;
     }
 
     if (poptPeekArg(optCon)) {
@@ -186,60 +193,54 @@ int parseScript(Spec spec, int parsePart)
            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.                                   */
@@ -248,18 +249,13 @@ int parseScript(Spec spec, int parsePart)
        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:
@@ -280,11 +276,19 @@ int parseScript(Spec spec, int parsePart)
            }
        }
     }
+    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;
 }
index d0a1da4..292c2c6 100644 (file)
@@ -45,26 +45,21 @@ static inline void initParts(struct PartRec *p)
 
 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)
@@ -96,9 +91,8 @@ 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)
index 7a4ec38..f96158e 100644 (file)
@@ -23,6 +23,7 @@ int addReqProv(/*@unused@*/ Spec spec, Header h,
        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;
@@ -35,7 +36,7 @@ int addReqProv(/*@unused@*/ Spec spec, Header h,
        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;
@@ -46,6 +47,7 @@ int addReqProv(/*@unused@*/ Spec spec, Header h,
        nametag = RPMTAG_REQUIRENAME;
        versiontag = RPMTAG_REQUIREVERSION;
        flagtag = RPMTAG_REQUIREFLAGS;
+       extra = flag & _ALL_REQUIRES_MASK;
     }
 
     flag = (flag & (RPMSENSE_SENSEMASK | RPMSENSE_MULTILIB)) | extra;
@@ -114,6 +116,6 @@ int rpmlibNeedsFeature(Header h, const char * feature, const char * featureEVR)
     (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);
 }
index 62f8b86..78f39f6 100644 (file)
@@ -1364,18 +1364,36 @@ static int checkDependentConflicts(rpmTransactionSet rpmdep,
     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" },
@@ -1392,7 +1410,9 @@ static int ignoreDep(struct availablePackage * p, struct availablePackage * q)
 
     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;
        }
     }
@@ -1419,13 +1439,34 @@ static void markLoop(struct tsortInfo * tsi, struct availablePackage * q)
     }
 }
 
+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 *
@@ -1447,8 +1488,7 @@ zapRelation(struct availablePackage * q, struct availablePackage * p,
        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]);
 
        /*
@@ -1459,7 +1499,7 @@ zapRelation(struct availablePackage * q, struct availablePackage * p,
         *      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);
@@ -1470,6 +1510,8 @@ zapRelation(struct availablePackage * q, struct availablePackage * p,
            free(tsi);
            if (nzaps)
                (*nzaps)++;
+           if (zap)
+               zap--;
        }
        break;
     }
@@ -1477,6 +1519,55 @@ zapRelation(struct availablePackage * q, struct availablePackage * p,
 }
 
 /**
+ * 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
@@ -1531,42 +1622,35 @@ int rpmdepOrder(rpmTransactionSet rpmdep)
        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);
+
        }
     }
 
@@ -1678,7 +1762,7 @@ rescan:
                    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. */
index 2971172..ef0e897 100644 (file)
@@ -1902,9 +1902,11 @@ int rpmdbAdd(rpmdb rpmdb, Header h)
            int rpmtype = 0;
            int rpmcnt = 0;
            int rpmtag;
+           int_32 * requireFlags;
            int i, j;
 
            dbi = NULL;
+           requireFlags = NULL;
            rpmtag = dbiTags[dbix];
 
            switch (rpmtag) {
@@ -1935,9 +1937,13 @@ int rpmdbAdd(rpmdb rpmdb, Header h)
                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;
            }
 
@@ -1984,6 +1990,14 @@ int rpmdbAdd(rpmdb rpmdb, Header h)
                 * 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++) {
@@ -1993,7 +2007,8 @@ int rpmdbAdd(rpmdb rpmdb, Header h)
                        if (j < i)
                            continue;
                    }
-                   /*@fallthrough@*/
+                   rec->tagNum = i;
+                   break;
                default:
                    rec->tagNum = i;
                    break;
index 29b06c2..e416aba 100644 (file)
@@ -320,18 +320,34 @@ typedef   enum rpmfileAttrs_e {
  */
 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, */
@@ -342,6 +358,30 @@ typedef    enum rpmsenseFlags_e {
 
 #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)
 
 /* ==================================================================== */
index ca5a718..e115098 100644 (file)
@@ -12,15 +12,20 @@ static struct rpmlibProvides {
     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 }
 };
index 3b2bdcb..f45c25c 100644 (file)
@@ -8,6 +8,8 @@
 
 extern int _depends_debug;
 
+static int noDeps = 0;
+
 static int
 do_tsort(const char *fileArgv[])
 {
@@ -57,7 +59,8 @@ do_tsort(const char *fileArgv[])
 
     }
 
-    {  struct rpmDependencyConflict * conflicts = NULL;
+    if (!noDeps) {
+       struct rpmDependencyConflict * conflicts = NULL;
        int numConflicts = 0;
 
        rc = rpmdepCheck(ts, &conflicts, &numConflicts);
@@ -126,6 +129,7 @@ exit:
 }
 
 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}
 };