static int parseNoSource(rpmSpec spec, const char * field, rpmTagVal tag) { const char *f, *fe; const char *name; int flag; uint32_t num; if (tag == RPMTAG_NOSOURCE) { flag = RPMBUILD_ISSOURCE; name = "source"; } else { flag = RPMBUILD_ISPATCH; name = "patch"; } fe = field; for (f = fe; *f != '\0'; f = fe) { struct Source *p; SKIPWHITE(f); if (*f == '\0') break; fe = f; SKIPNONWHITE(fe); if (*fe != '\0') fe++; if (parseUnsignedNum(f, &num)) { rpmlog(RPMLOG_ERR, _("line %d: Bad number: %s\n"), spec->lineNum, f); return RPMRC_FAIL; } if (! (p = findSource(spec, num, flag))) { rpmlog(RPMLOG_ERR, _("line %d: Bad no%s number: %u\n"), spec->lineNum, name, num); return RPMRC_FAIL; } p->flags |= RPMBUILD_ISNO; } return 0; }
int parseNoSource(Spec spec, const char * field, rpmTag tag) { const char *f, *fe; const char *name; rpmuint32_t num, flag; if (tag == RPMTAG_NOSOURCE) { flag = RPMFILE_SOURCE; name = "source"; } else { flag = RPMFILE_PATCH; name = "patch"; } fe = field; for (f = fe; *f != '\0'; f = fe) { struct Source *p; SKIPWHITE(f); if (*f == '\0') break; fe = f; SKIPNONWHITE(fe); if (*fe != '\0') fe++; if (parseNum(f, &num)) { rpmlog(RPMLOG_ERR, _("line %d: Bad number: %s\n"), spec->lineNum, f); return RPMRC_FAIL; } if (! (p = findSource(spec, num, flag))) { rpmlog(RPMLOG_ERR, _("line %d: Bad no%s number: %d\n"), spec->lineNum, name, num); return RPMRC_FAIL; } p->flags |= RPMFILE_GHOST; } return RPMRC_OK; }
rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpmTagVal tagN, int index, rpmsenseFlags tagflags) { const char *r, *re, *v, *ve; const char *emsg = NULL; char * N = NULL, * EVR = NULL; rpmTagVal nametag = RPMTAG_NOT_FOUND; rpmsenseFlags Flags; Header h = pkg->header; /* everything except buildrequires go here */ rpmRC rc = RPMRC_FAIL; /* assume failure */ switch (tagN) { default: case RPMTAG_REQUIREFLAGS: nametag = RPMTAG_REQUIRENAME; tagflags |= RPMSENSE_ANY; break; case RPMTAG_PROVIDEFLAGS: nametag = RPMTAG_PROVIDENAME; break; case RPMTAG_OBSOLETEFLAGS: nametag = RPMTAG_OBSOLETENAME; break; case RPMTAG_CONFLICTFLAGS: nametag = RPMTAG_CONFLICTNAME; break; case RPMTAG_ORDERFLAGS: nametag = RPMTAG_ORDERNAME; break; case RPMTAG_PREREQ: /* XXX map legacy PreReq into Requires(pre,preun) */ nametag = RPMTAG_REQUIRENAME; tagflags |= (RPMSENSE_SCRIPT_PRE|RPMSENSE_SCRIPT_PREUN); break; case RPMTAG_TRIGGERPREIN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERPREIN; break; case RPMTAG_TRIGGERIN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERIN; break; case RPMTAG_TRIGGERPOSTUN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERPOSTUN; break; case RPMTAG_TRIGGERUN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERUN; break; case RPMTAG_BUILDPREREQ: case RPMTAG_BUILDREQUIRES: nametag = RPMTAG_REQUIRENAME; tagflags |= RPMSENSE_ANY; h = spec->buildRestrictions; break; case RPMTAG_BUILDCONFLICTS: nametag = RPMTAG_CONFLICTNAME; h = spec->buildRestrictions; break; } for (r = field; *r != '\0'; r = re) { SKIPWHITE(r); if (*r == '\0') break; Flags = (tagflags & ~RPMSENSE_SENSEMASK); /* * Tokens must begin with alphanumeric, _, or /, but we don't know * the spec's encoding so we only check what we can: plain ascii. */ if (isascii(r[0]) && !(risalnum(r[0]) || r[0] == '_' || r[0] == '/')) { emsg = _("Dependency tokens must begin with alpha-numeric, '_' or '/'"); goto exit; } re = r; SKIPNONWHITE(re); N = xmalloc((re-r) + 1); rstrlcpy(N, r, (re-r) + 1); /* Parse EVR */ v = re; SKIPWHITE(v); ve = v; SKIPNONWHITE(ve); re = v; /* ==> next token (if no EVR found) starts here */ /* Check for possible logical operator */ if (ve > v) { const struct ReqComp *rc; for (rc = ReqComparisons; rc->token != NULL; rc++) { if ((ve-v) != strlen(rc->token) || !rstreqn(v, rc->token, (ve-v))) continue; if (r[0] == '/') { emsg = _("Versioned file name not permitted"); goto exit; } Flags |= rc->sense; /* now parse EVR */ v = ve; SKIPWHITE(v); ve = v; SKIPNONWHITE(ve); break; } } if (Flags & RPMSENSE_SENSEMASK) { if (*v == '\0' || ve == v) { emsg = _("Version required"); goto exit; } EVR = xmalloc((ve-v) + 1); rstrlcpy(EVR, v, (ve-v) + 1); if (rpmCharCheck(spec, EVR, ve-v, ".-_+:%{}")) goto exit; re = ve; /* ==> next token after EVR string starts here */ } else EVR = NULL; if (addReqProv(h, nametag, N, EVR, Flags, index)) { emsg = _("invalid dependency"); goto exit; } N = _free(N); EVR = _free(EVR); } rc = RPMRC_OK; exit: if (emsg) { /* Automatic dependencies don't relate to spec lines */ if (tagflags & (RPMSENSE_FIND_REQUIRES|RPMSENSE_FIND_PROVIDES)) { rpmlog(RPMLOG_ERR, "%s: %s\n", emsg, r); } else { rpmlog(RPMLOG_ERR, _("line %d: %s: %s\n"), spec->lineNum, emsg, spec->line); } } free(N); free(EVR); return rc; }
rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpmTagVal tagN, int index, rpmsenseFlags tagflags) { const char *r, *re, *v, *ve; char *emsg = NULL; char * N = NULL, * EVR = NULL; rpmTagVal nametag = RPMTAG_NOT_FOUND; rpmsenseFlags Flags; rpmds *pdsp = NULL; rpmRC rc = RPMRC_FAIL; /* assume failure */ switch (tagN) { default: case RPMTAG_REQUIREFLAGS: nametag = RPMTAG_REQUIRENAME; tagflags |= RPMSENSE_ANY; break; case RPMTAG_RECOMMENDFLAGS: nametag = RPMTAG_RECOMMENDNAME; break; case RPMTAG_SUGGESTFLAGS: nametag = RPMTAG_SUGGESTNAME; break; case RPMTAG_SUPPLEMENTFLAGS: nametag = RPMTAG_SUPPLEMENTNAME; break; case RPMTAG_ENHANCEFLAGS: nametag = RPMTAG_ENHANCENAME; break; case RPMTAG_PROVIDEFLAGS: nametag = RPMTAG_PROVIDENAME; break; case RPMTAG_OBSOLETEFLAGS: nametag = RPMTAG_OBSOLETENAME; break; case RPMTAG_CONFLICTFLAGS: nametag = RPMTAG_CONFLICTNAME; break; case RPMTAG_ORDERFLAGS: nametag = RPMTAG_ORDERNAME; break; case RPMTAG_PREREQ: /* XXX map legacy PreReq into Requires(pre,preun) */ nametag = RPMTAG_REQUIRENAME; tagflags |= (RPMSENSE_SCRIPT_PRE|RPMSENSE_SCRIPT_PREUN); break; case RPMTAG_TRIGGERPREIN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERPREIN; break; case RPMTAG_TRIGGERIN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERIN; break; case RPMTAG_TRIGGERPOSTUN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERPOSTUN; break; case RPMTAG_TRIGGERUN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERUN; break; case RPMTAG_BUILDPREREQ: case RPMTAG_BUILDREQUIRES: nametag = RPMTAG_REQUIRENAME; tagflags |= RPMSENSE_ANY; break; case RPMTAG_BUILDCONFLICTS: nametag = RPMTAG_CONFLICTNAME; break; case RPMTAG_FILETRIGGERIN: nametag = RPMTAG_FILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERIN; break; case RPMTAG_FILETRIGGERUN: nametag = RPMTAG_FILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERUN; break; case RPMTAG_FILETRIGGERPOSTUN: nametag = RPMTAG_FILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERPOSTUN; break; case RPMTAG_TRANSFILETRIGGERIN: nametag = RPMTAG_TRANSFILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERIN; break; case RPMTAG_TRANSFILETRIGGERUN: nametag = RPMTAG_TRANSFILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERUN; break; case RPMTAG_TRANSFILETRIGGERPOSTUN: nametag = RPMTAG_TRANSFILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERPOSTUN; break; } for (r = field; *r != '\0'; r = re) { SKIPWHITE(r); if (*r == '\0') break; Flags = (tagflags & ~RPMSENSE_SENSEMASK); if (r[0] == '(') { struct parseRCPOTRichData data; if (nametag != RPMTAG_REQUIRENAME && nametag != RPMTAG_CONFLICTNAME && nametag != RPMTAG_RECOMMENDNAME && nametag != RPMTAG_SUPPLEMENTNAME && nametag != RPMTAG_SUGGESTNAME && nametag != RPMTAG_ENHANCENAME) { rasprintf(&emsg, _("No rich dependencies allowed for this type")); goto exit; } data.spec = spec; data.sb = newStringBuf(); if (rpmrichParse(&r, &emsg, parseRCPOTRichCB, &data) != RPMRC_OK) { freeStringBuf(data.sb); goto exit; } if (addReqProv(pkg, nametag, getStringBuf(data.sb), NULL, Flags | RPMSENSE_RICH, index)) { rasprintf(&emsg, _("invalid dependency")); freeStringBuf(data.sb); goto exit; } freeStringBuf(data.sb); re = r; continue; } re = r; SKIPNONWHITE(re); N = xmalloc((re-r) + 1); rstrlcpy(N, r, (re-r) + 1); /* Parse EVR */ EVR = NULL; v = re; SKIPWHITE(v); ve = v; SKIPNONWHITE(ve); re = v; /* ==> next token (if no EVR found) starts here */ /* Check for possible logical operator */ if (ve > v) { rpmsenseFlags sense = rpmParseDSFlags(v, ve - v); if (sense) { Flags |= sense; /* now parse EVR */ v = ve; SKIPWHITE(v); ve = v; SKIPNONWHITE(ve); if (*v == '\0' || ve == v) { rasprintf(&emsg, _("Version required")); goto exit; } EVR = xmalloc((ve-v) + 1); rstrlcpy(EVR, v, (ve-v) + 1); re = ve; /* ==> next token after EVR string starts here */ } } /* check that dependency is well-formed */ if (checkDep(spec, N, EVR, &emsg)) goto exit; if (nametag == RPMTAG_FILETRIGGERNAME || nametag == RPMTAG_TRANSFILETRIGGERNAME) { if (N[0] != '/') { rasprintf(&emsg, _("Only absolute paths are allowed in " "file triggers")); } } /* Deny more "normal" triggers fired by the same pakage. File triggers are ok */ pdsp = packageDependencies(pkg, nametag); rpmdsInit(*pdsp); if (nametag == RPMTAG_TRIGGERNAME) { while (rpmdsNext(*pdsp) >= 0) { if (rstreq(rpmdsN(*pdsp), N) && ((rpmdsFlags(*pdsp) & tagflags))) { rasprintf(&emsg, _("Trigger fired by the same package " "is already defined in spec file")); goto exit; } } } if (addReqProv(pkg, nametag, N, EVR, Flags, index)) { rasprintf(&emsg, _("invalid dependency")); goto exit; } N = _free(N); EVR = _free(EVR); } rc = RPMRC_OK; exit: if (emsg) { int lvl = (rc == RPMRC_OK) ? RPMLOG_WARNING : RPMLOG_ERR; /* Automatic dependencies don't relate to spec lines */ if (tagflags & (RPMSENSE_FIND_REQUIRES|RPMSENSE_FIND_PROVIDES)) { rpmlog(lvl, "%s: %s\n", emsg, r); } else { rpmlog(lvl, _("line %d: %s: %s\n"), spec->lineNum, emsg, spec->line); } free(emsg); } _free(N); _free(EVR); return rc; }