--- rpm-5.4.9/lib/psm.c.trigger_args~ 2012-05-15 03:08:19.198093824 +0200 +++ rpm-5.4.9/lib/psm.c 2012-05-15 03:14:25.545079818 +0200 @@ -610,28 +610,37 @@ static int exitChroot(rpmpsm psm, int in * @return RPMRC_OK on success */ static rpmRC runEmbeddedScript(rpmpsm psm, const char * sln, HE_t Phe, - const char *script, int arg1, int arg2) + const char *script, int arg1, int arg2, ARGV_t matches) /*@globals fileSystem, internalState @*/ /*@modifies psm, fileSystem, internalState @*/ { - char * av[] = { NULL, NULL, NULL, NULL }; + char ** av = NULL; int pwdFdno = -1; int rootFdno = -1; rpmRC rc = RPMRC_OK; int xx = 0; rpmuint32_t * ssp = NULL; int inChroot = enterChroot(psm, &pwdFdno, &rootFdno); + size_t len = 4 + (matches ? argvCount(matches) : 0); if (psm->sstates != NULL) ssp = psm->sstates + tag2slx(psm->scriptTag); if (ssp != NULL) *ssp |= (RPMSCRIPT_STATE_EMBEDDED|RPMSCRIPT_STATE_EXEC); - av[0] = (char *) Phe->p.argv[0]; + av = alloca(len * sizeof(*av)); if (arg1 >= 0) (void) sprintf((av[1] = (char *) alloca(32)), "%d", arg1); + else + av[1] = NULL; if (arg2 >= 0) (void) sprintf((av[2] = (char *) alloca(32)), "%d", arg2); + else + av[2] = NULL; + if (matches) + memcpy(&av[3], argvData(matches), argvCount(matches) * sizeof(*argvData(matches))); + av[len-1] = NULL; + #if defined(WITH_LUA) if (!strcmp(Phe->p.argv[0], "")) { @@ -776,7 +785,7 @@ static const char * ldconfig_path = "/sb * @return RPMRC_OK on success */ static rpmRC runScript(rpmpsm psm, Header h, const char * sln, HE_t Phe, - const char * script, int arg1, int arg2) + const char * script, int arg1, int arg2, ARGV_t matches) /*@globals ldconfig_done, rpmGlobalMacroContext, h_errno, fileSystem, internalState@*/ /*@modifies psm, ldconfig_done, rpmGlobalMacroContext, @@ -843,7 +852,7 @@ assert(he->p.str != NULL); rpmlog(RPMLOG_DEBUG, D_("%s: %s(%s) running %s scriptlet.\n"), psm->stepName, tag2sln(psm->scriptTag), NVRA, Phe->p.argv[0]); - rc = runEmbeddedScript(psm, sln, Phe, body, arg1, arg2); + rc = runEmbeddedScript(psm, sln, Phe, body, arg1, arg2, matches); #endif goto exit; } @@ -870,12 +879,12 @@ assert(he->p.str != NULL); (F_ISSET(psm, UNORDERED) ? "a" : "")); if (Phe->p.argv == NULL) { - argv = (const char **) alloca(5 * sizeof(*argv)); + argv = alloca(5 + (matches ? argvCount(matches) : 0 ) * sizeof(*argv)); argv[0] = "/bin/sh"; argc = 1; ldconfig_done = 0; } else { - argv = (const char **) alloca((Phe->c + 4) * sizeof(*argv)); + argv = alloca((Phe->c + 4) + (matches ? argvCount(matches) : 0 ) * sizeof(*argv)); memcpy(argv, Phe->p.argv, Phe->c * sizeof(*argv)); argc = Phe->c; ldconfig_done = (ldconfig_path && !strcmp(argv[0], ldconfig_path) @@ -959,6 +968,10 @@ assert(he->p.str != NULL); sprintf(av, "%d", arg2); argv[argc++] = av; } + if (matches) { + memcpy(&argv[argc], argvData(matches), argvCount(matches) * sizeof(*argvData(matches))); + argc += argvCount(matches); + } } argv[argc] = NULL; @@ -1199,7 +1212,7 @@ assert(fi->h != NULL); Phe->p.argv[0] = argv0 = rpmExpand(Phe->p.argv[0], NULL); rc = runScript(psm, fi->h, tag2sln(psm->scriptTag), Phe, - She->p.str, psm->scriptArg, -1); + She->p.str, psm->scriptArg, -1, NULL); exit: argv0 = _free(argv0); @@ -1280,6 +1293,7 @@ static rpmRC handleOneTrigger(const rpmp while ((i = rpmdsNext(Tds)) >= 0) { rpmuint32_t Flags = rpmdsFlags(Tds); char * depName; + ARGV_t matches = NULL; int bingo; /* Skip triggers that are not in this context. */ @@ -1313,7 +1327,7 @@ static rpmRC handleOneTrigger(const rpmp if (xx < 0) /*@innercontinue@*/ continue; bingo = 1; - /*@innerbreak@*/ break; + argvAdd(&matches, N); } (void)rpmdsFree(ds); ds = NULL; @@ -1347,7 +1361,6 @@ static rpmRC handleOneTrigger(const rpmp continue; /* Coerce strings into header argv return. */ - /* XXX FIXME: permit trigger scripts with arguments. */ { int index = Ihe->p.ui32p[i]; const char * s = Phe->p.argv[index]; char * t; @@ -1362,11 +1375,12 @@ static rpmRC handleOneTrigger(const rpmp *t = '\0'; if (runScript(psm, triggeredH, "%trigger", he, - She->p.argv[index], arg1, arg2)) + She->p.argv[index], arg1, arg2, matches)) rc = RPMRC_FAIL; he->p.ptr = _free(he->p.ptr); } + argvFree(matches); } mire = mireFree(mire);