From ecaf972db05f6b23514a747c4a503268658ac98d Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Fri, 2 Sep 2011 12:43:53 +0300 Subject: [PATCH] Add an API for creating real rpmScript items out of triggers, use it - Bury rpmScriptNew() into being internal helper in rpmscript - triggers and other scripts differ quite a bit in how their data is laid out in the header, especially args need "special attention". - Besides cleaning up things in the psm side, this technically makes trigger scripts runnable without having a header at hand. Of course currently trigger scripts are currently created and destroyed on the spot from headers so this is of academic interest... --- lib/psm.c | 50 +++++++++++++++++--------------------------------- lib/rpmscript.c | 37 +++++++++++++++++++++++++++++++++++-- lib/rpmscript.h | 3 +-- 3 files changed, 53 insertions(+), 37 deletions(-) diff --git a/lib/psm.c b/lib/psm.c index 5f04b49..c5ecbe4 100644 --- a/lib/psm.c +++ b/lib/psm.c @@ -481,8 +481,8 @@ static rpmRC handleOneTrigger(const rpmpsm psm, (void) rpmdsSetNoPromote(trigger, 1); while ((i = rpmdsNext(trigger)) >= 0) { - struct rpmtd_s tscripts, tprogs, tindexes, tflags; - headerGetFlags hgflags = HEADERGET_MINMEM; + struct rpmtd_s tindexes; + uint32_t tix; if (!(rpmdsFlags(trigger) & psm->sense)) continue; @@ -494,51 +494,35 @@ static rpmRC handleOneTrigger(const rpmpsm psm, if (!rpmdsAnyMatchesDep(sourceH, trigger, 1)) continue; - /* XXX FIXME: this leaks memory if scripts or progs retrieve fails */ - if (!(headerGet(trigH, RPMTAG_TRIGGERINDEX, &tindexes, hgflags) && - headerGet(trigH, RPMTAG_TRIGGERSCRIPTS, &tscripts, hgflags) && - headerGet(trigH, RPMTAG_TRIGGERSCRIPTPROG, &tprogs, hgflags))) { + if (!headerGet(trigH, RPMTAG_TRIGGERINDEX, &tindexes, HEADERGET_MINMEM)) continue; - } else { - int arg1 = rpmdbCountPackages(rpmtsGetRdb(ts), triggerName); - char ** triggerScripts = tscripts.data; - char ** triggerProgs = tprogs.data; - uint32_t * triggerIndices = tindexes.data; - uint32_t * triggerFlags = NULL; - uint32_t ix = triggerIndices[i]; - headerGet(trigH, RPMTAG_TRIGGERSCRIPTFLAGS, &tflags, hgflags); - triggerFlags = tflags.data; + if (rpmtdSetIndex(&tindexes, i) < 0) { + rpmtdFreeData(&tindexes); + continue; + } + + tix = rpmtdGetNumber(&tindexes); + if (triggersAlreadyRun == NULL || triggersAlreadyRun[tix] == 0) { + int arg1 = rpmdbCountPackages(rpmtsGetRdb(ts), triggerName); if (arg1 < 0) { /* XXX W2DO? fails as "execution of script failed" */ rc = RPMRC_FAIL; } else { + rpmScript script = rpmScriptFromTriggerTag(trigH, + triggertag(psm->sense), tix); arg1 += psm->countCorrection; + rc = runScript(psm, pfx.data, script, arg1, arg2); - if (triggersAlreadyRun == NULL || triggersAlreadyRun[ix] == 0) { - rpmScript script; + if (triggersAlreadyRun != NULL) + triggersAlreadyRun[tix] = 1; - script = rpmScriptNew(trigH, triggertag(psm->sense), - triggerScripts[ix], - triggerFlags ? triggerFlags[ix] : 0); - - script->args = xcalloc(2, sizeof(*script->args)); - script->args[0] = triggerProgs[ix]; - script->args[1] = NULL; - - rc = runScript(psm, pfx.data, script, arg1, arg2); - if (triggersAlreadyRun != NULL) - triggersAlreadyRun[ix] = 1; - - rpmScriptFree(script); - } + rpmScriptFree(script); } } rpmtdFreeData(&tindexes); - rpmtdFreeData(&tscripts); - rpmtdFreeData(&tprogs); /* * Each target/source header pair can only result in a single diff --git a/lib/rpmscript.c b/lib/rpmscript.c index 8067b85..f148eb5 100644 --- a/lib/rpmscript.c +++ b/lib/rpmscript.c @@ -364,8 +364,8 @@ static const char * tag2sln(rpmTagVal tag) return "%unknownscript"; } -rpmScript rpmScriptNew(Header h, rpmTagVal tag, const char *body, - rpmscriptFlags flags) +static rpmScript rpmScriptNew(Header h, rpmTagVal tag, const char *body, + rpmscriptFlags flags) { char *nevra = headerGetAsString(h, RPMTAG_NEVRA); rpmScript script = xcalloc(1, sizeof(*script)); @@ -390,6 +390,39 @@ rpmScript rpmScriptNew(Header h, rpmTagVal tag, const char *body, return script; } +rpmScript rpmScriptFromTriggerTag(Header h, rpmTagVal triggerTag, uint32_t ix) +{ + rpmScript script = NULL; + struct rpmtd_s tscripts, tprogs, tflags; + headerGetFlags hgflags = HEADERGET_MINMEM; + + headerGet(h, RPMTAG_TRIGGERSCRIPTS, &tscripts, hgflags); + headerGet(h, RPMTAG_TRIGGERSCRIPTPROG, &tprogs, hgflags); + headerGet(h, RPMTAG_TRIGGERSCRIPTFLAGS, &tflags, hgflags); + + if (rpmtdSetIndex(&tscripts, ix) >= 0 && rpmtdSetIndex(&tprogs, ix) >= 0) { + rpmscriptFlags sflags = 0; + const char *prog = rpmtdGetString(&tprogs); + + if (rpmtdSetIndex(&tflags, ix) >= 0) + sflags = rpmtdGetNumber(&tflags); + + script = rpmScriptNew(h, triggerTag, rpmtdGetString(&tscripts), sflags); + + /* hack up a hge-style NULL-terminated array */ + script->args = xmalloc(2 * sizeof(*script->args) + strlen(prog) + 1); + script->args[0] = (char *)(script->args + 2); + script->args[1] = NULL; + strcpy(script->args[0], prog); + } + + rpmtdFreeData(&tscripts); + rpmtdFreeData(&tprogs); + rpmtdFreeData(&tflags); + + return script; +} + rpmScript rpmScriptFromTag(Header h, rpmTagVal scriptTag) { rpmScript script = NULL; diff --git a/lib/rpmscript.h b/lib/rpmscript.h index 7f9ff3b..642090f 100644 --- a/lib/rpmscript.h +++ b/lib/rpmscript.h @@ -30,8 +30,7 @@ RPM_GNUC_INTERNAL rpmScript rpmScriptFromTag(Header h, rpmTagVal scriptTag); RPM_GNUC_INTERNAL -rpmScript rpmScriptNew(Header h, rpmTagVal tag, const char *body, - rpmscriptFlags flags); +rpmScript rpmScriptFromTriggerTag(Header h, rpmTagVal triggerTag, uint32_t ix); RPM_GNUC_INTERNAL rpmScript rpmScriptFree(rpmScript script); -- 2.7.4