diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2010-03-11 12:06:49 +0200 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2010-03-11 12:06:49 +0200 |
commit | d370816ba508a33cc39252cbb9ba85dcd99504d5 (patch) | |
tree | 1eb5a3af5091ba2bb24a26709f5440f9b4f6b7a8 /build | |
parent | d0a959a571d7b34ea2263619b8cfba623a425c44 (diff) | |
download | librpm-tizen-d370816ba508a33cc39252cbb9ba85dcd99504d5.tar.gz librpm-tizen-d370816ba508a33cc39252cbb9ba85dcd99504d5.tar.bz2 librpm-tizen-d370816ba508a33cc39252cbb9ba85dcd99504d5.zip |
Support run-time macro and queryformat expansion on scriptlets
- Add per-scriptlet type flag tags to control special behavior.
- Add rpmlib dependency on scriptlet expansion - if a package relies
on scriptlet expansion it cannot be correctly installed with
a version of rpm that doesn't support it.
- Expansion is always an opt-in behavior, enabled with -q and/or -e argument
in spec. We can't just blindly expand even macros as there's no telling
%{} constructs might mean in whatever language is used for the script.
- Queryformat expansion requires great care with strange and ugly escapes
when writing scriptlets, but OTOH it permits access arbitrary header
data at runtime, which has previously been completely impossible.
- The handling of these expansions needs unifying for all scriptlet types,
the trigger scriptlet handling is uuugly. Macro expansion could be
transparently done from rpmScriptRun(), but because of their similar
syntax, macro expansion needs to happen before query format expansion,
and we dont have the header available in rpmScriptrun()
Diffstat (limited to 'build')
-rw-r--r-- | build/pack.c | 13 | ||||
-rw-r--r-- | build/parseScript.c | 33 | ||||
-rw-r--r-- | build/rpmspec.h | 1 |
3 files changed, 45 insertions, 2 deletions
diff --git a/build/pack.c b/build/pack.c index 1857257e4..fa947bff5 100644 --- a/build/pack.c +++ b/build/pack.c @@ -185,6 +185,7 @@ static int addFileToArrayTag(rpmSpec spec, const char *file, Header h, rpmTag ta static rpmRC processScriptFiles(rpmSpec spec, Package pkg) { struct TriggerFileEntry *p; + int addflags = 0; if (pkg->preInFile) { if (addFileToTag(spec, pkg->preInFile, pkg->header, RPMTAG_PREIN)) { @@ -237,8 +238,20 @@ static rpmRC processScriptFiles(rpmSpec spec, Package pkg) } } + /* if any trigger has flags, we need to add flags entry for all of them */ + for (p = pkg->triggerFiles; p != NULL; p = p->next) { + if (p->flags) { + addflags = 1; + break; + } + } + for (p = pkg->triggerFiles; p != NULL; p = p->next) { headerPutString(pkg->header, RPMTAG_TRIGGERSCRIPTPROG, p->prog); + if (addflags) { + headerPutUint32(pkg->header, RPMTAG_TRIGGERSCRIPTFLAGS, + &p->flags, 1); + } if (p->script) { headerPutString(pkg->header, RPMTAG_TRIGGERSCRIPTS, p->script); diff --git a/build/parseScript.c b/build/parseScript.c index c4249516e..32793c544 100644 --- a/build/parseScript.c +++ b/build/parseScript.c @@ -10,6 +10,7 @@ #include <rpm/rpmlog.h> #include "rpmio/rpmlua.h" +#include "lib/rpmscript.h" /* script flags */ #include "debug.h" @@ -17,7 +18,7 @@ /** */ static int addTriggerIndex(Package pkg, const char *file, - const char *script, const char *prog) + const char *script, const char *prog, rpmscriptFlags flags) { struct TriggerFileEntry *tfe; struct TriggerFileEntry *list = pkg->triggerFiles; @@ -37,6 +38,7 @@ static int addTriggerIndex(Package pkg, const char *file, tfe->fileName = (file) ? xstrdup(file) : NULL; tfe->script = (script && *script != '\0') ? xstrdup(script) : NULL; tfe->prog = xstrdup(prog); + tfe->flags = flags; tfe->index = index; tfe->next = NULL; @@ -70,6 +72,8 @@ int parseScript(rpmSpec spec, int parsePart) rpmTag tag = 0; rpmsenseFlags tagflags = 0; rpmTag progtag = 0; + rpmTag flagtag = 0; + rpmscriptFlags scriptFlags = 0; int flag = PART_SUBNAME; Package pkg; StringBuf sb = NULL; @@ -85,10 +89,14 @@ int parseScript(rpmSpec spec, int parsePart) const char *name = NULL; const char *prog = "/bin/sh"; const char *file = NULL; + int expand = 0; + int qformat = 1; struct poptOption optionsTable[] = { { NULL, 'p', POPT_ARG_STRING, &prog, 'p', NULL, NULL}, { NULL, 'n', POPT_ARG_STRING, &name, 'n', NULL, NULL}, { NULL, 'f', POPT_ARG_STRING, &file, 'f', NULL, NULL}, + { NULL, 'e', POPT_ARG_NONE, &expand, 'e', NULL, NULL}, + { NULL, 'q', POPT_ARG_NONE, &qformat, 'q', NULL, NULL}, { 0, 0, 0, 0, 0, NULL, NULL} }; @@ -97,42 +105,49 @@ int parseScript(rpmSpec spec, int parsePart) tag = RPMTAG_PREIN; tagflags = RPMSENSE_SCRIPT_PRE; progtag = RPMTAG_PREINPROG; + flagtag = RPMTAG_PREINFLAGS; partname = "%pre"; break; case PART_POST: tag = RPMTAG_POSTIN; tagflags = RPMSENSE_SCRIPT_POST; progtag = RPMTAG_POSTINPROG; + flagtag = RPMTAG_POSTINFLAGS; partname = "%post"; break; case PART_PREUN: tag = RPMTAG_PREUN; tagflags = RPMSENSE_SCRIPT_PREUN; progtag = RPMTAG_PREUNPROG; + flagtag = RPMTAG_PREUNFLAGS; partname = "%preun"; break; case PART_POSTUN: tag = RPMTAG_POSTUN; tagflags = RPMSENSE_SCRIPT_POSTUN; progtag = RPMTAG_POSTUNPROG; + flagtag = RPMTAG_POSTUNFLAGS; partname = "%postun"; break; case PART_PRETRANS: tag = RPMTAG_PRETRANS; tagflags = 0; progtag = RPMTAG_PRETRANSPROG; + flagtag = RPMTAG_PRETRANSFLAGS; partname = "%pretrans"; break; case PART_POSTTRANS: tag = RPMTAG_POSTTRANS; tagflags = 0; progtag = RPMTAG_POSTTRANSPROG; + flagtag = RPMTAG_POSTTRANSFLAGS; partname = "%posttrans"; break; case PART_VERIFYSCRIPT: tag = RPMTAG_VERIFYSCRIPT; tagflags = RPMSENSE_SCRIPT_VERIFY; progtag = RPMTAG_VERIFYSCRIPTPROG; + flagtag = RPMTAG_VERIFYSCRIPTFLAGS; partname = "%verifyscript"; break; case PART_TRIGGERPREIN: @@ -140,6 +155,7 @@ int parseScript(rpmSpec spec, int parsePart) tagflags = 0; reqtag = RPMTAG_TRIGGERPREIN; progtag = RPMTAG_TRIGGERSCRIPTPROG; + flagtag = RPMTAG_TRIGGERSCRIPTFLAGS; partname = "%triggerprein"; break; case PART_TRIGGERIN: @@ -147,6 +163,7 @@ int parseScript(rpmSpec spec, int parsePart) tagflags = 0; reqtag = RPMTAG_TRIGGERIN; progtag = RPMTAG_TRIGGERSCRIPTPROG; + flagtag = RPMTAG_TRIGGERSCRIPTFLAGS; partname = "%triggerin"; break; case PART_TRIGGERUN: @@ -154,6 +171,7 @@ int parseScript(rpmSpec spec, int parsePart) tagflags = 0; reqtag = RPMTAG_TRIGGERUN; progtag = RPMTAG_TRIGGERSCRIPTPROG; + flagtag = RPMTAG_TRIGGERSCRIPTFLAGS; partname = "%triggerun"; break; case PART_TRIGGERPOSTUN: @@ -161,6 +179,7 @@ int parseScript(rpmSpec spec, int parsePart) tagflags = 0; reqtag = RPMTAG_TRIGGERPOSTUN; progtag = RPMTAG_TRIGGERSCRIPTPROG; + flagtag = RPMTAG_TRIGGERSCRIPTFLAGS; partname = "%triggerpostun"; break; } @@ -247,6 +266,9 @@ int parseScript(rpmSpec spec, int parsePart) goto exit; } + scriptFlags |= expand ? RPMSCRIPT_EXPAND : 0; + scriptFlags |= qformat ? RPMSCRIPT_QFORMAT : 0; + sb = newStringBuf(); if ((rc = readLine(spec, STRIP_NOTHING)) > 0) { nextPart = PART_NONE; @@ -286,11 +308,15 @@ int parseScript(rpmSpec spec, int parsePart) progArgv[0], NULL, (tagflags | RPMSENSE_INTERP), 0); } + if (scriptFlags) { + rpmlibNeedsFeature(pkg->header, "ScriptletExpansion", "4.9.0-1"); + } + /* Trigger script insertion is always delayed in order to */ /* get the index right. */ if (tag == RPMTAG_TRIGGERSCRIPTS) { /* Add file/index/prog triple to the trigger file list */ - index = addTriggerIndex(pkg, file, p, progArgv[0]); + index = addTriggerIndex(pkg, file, p, progArgv[0], scriptFlags); /* Generate the trigger tags */ if ((rc = parseRCPOT(spec, pkg, reqargs, reqtag, index, tagflags))) @@ -319,6 +345,9 @@ int parseScript(rpmSpec spec, int parsePart) if (*p != '\0') { headerPutString(pkg->header, tag, p); } + if (scriptFlags) { + headerPutUint32(pkg->header, flagtag, &scriptFlags, 1); + } if (file) { switch (parsePart) { diff --git a/build/rpmspec.h b/build/rpmspec.h index c94467716..e3eac6cfc 100644 --- a/build/rpmspec.h +++ b/build/rpmspec.h @@ -24,6 +24,7 @@ struct TriggerFileEntry { char * fileName; char * script; char * prog; + uint32_t flags; struct TriggerFileEntry * next; }; |