/** * Execute triggers. * @todo Trigger on any provides, not just package NVR. * @param ts transaction set * @param te transaction element * @param sense trigger type * @param sourceH header of trigger source * @param trigH header of triggered package * @param arg2 * @param triggersAlreadyRun * @return */ static rpmRC handleOneTrigger(rpmts ts, rpmte te, rpmsenseFlags sense, Header sourceH, Header trigH, int countCorrection, int arg2, unsigned char * triggersAlreadyRun) { rpmds trigger = rpmdsInit(rpmdsNew(trigH, RPMTAG_TRIGGERNAME, 0)); struct rpmtd_s pfx; const char * sourceName = headerGetString(sourceH, RPMTAG_NAME); const char * triggerName = headerGetString(trigH, RPMTAG_NAME); rpmRC rc = RPMRC_OK; int i; if (trigger == NULL) return rc; headerGet(trigH, RPMTAG_INSTPREFIXES, &pfx, HEADERGET_ALLOC|HEADERGET_ARGV); (void) rpmdsSetNoPromote(trigger, 1); while ((i = rpmdsNext(trigger)) >= 0) { uint32_t tix; if (!(rpmdsFlags(trigger) & sense)) continue; if (!rstreq(rpmdsN(trigger), sourceName)) continue; /* XXX Trigger on any provided dependency, not just the package NEVR */ if (!rpmdsAnyMatchesDep(sourceH, trigger, 1)) continue; tix = rpmdsTi(trigger); 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(sense), tix); arg1 += countCorrection; rc = runScript(ts, te, pfx.data, script, arg1, arg2); if (triggersAlreadyRun != NULL) triggersAlreadyRun[tix] = 1; rpmScriptFree(script); } } /* * Each target/source header pair can only result in a single * script being run. */ break; } rpmtdFreeData(&pfx); rpmdsFree(trigger); return rc; }
/* * Run all file triggers in header h * @param searchMode 0 match trigger prefixes against files in te * 1 match trigger prefixes against files in whole ts * 2 match trigger prefixes against files in whole * rpmdb */ static int runHandleTriggersInPkg(rpmts ts, rpmte te, Header h, rpmsenseFlags sense, rpmscriptTriggerModes tm, int searchMode, int ti) { int nerrors = 0; rpmds rpmdsTriggers, rpmdsTrigger; rpmfiles files = NULL; matchFilesIter mfi = NULL; rpmScript script; struct rpmtd_s installPrefixes; char *(*inputFunc)(void *); rpmdsTriggers = rpmdsNew(h, triggerDsTag(tm), 0); rpmdsTrigger = rpmdsFilterTi(rpmdsTriggers, ti); /* * Now rpmdsTrigger contains all dependencies belonging to one trigger * with trigger index tix. Have a look at the first one to check flags. */ if ((rpmdsNext(rpmdsTrigger) >= 0) && (rpmdsFlags(rpmdsTrigger) & sense)) { switch (searchMode) { case 0: /* Create iterator over files in te that this trigger matches */ files = rpmteFiles(te); mfi = matchFilesIterator(rpmdsTrigger, files); break; case 1: /* Create iterator over files in ts that this trigger matches */ mfi = matchDBFilesIterator(rpmdsTrigger, ts, 1); break; case 2: /* Create iterator over files in whole rpmd that this trigger matches */ mfi = matchDBFilesIterator(rpmdsTrigger, ts, 0); break; } /* If this trigger matches any file then run trigger script */ if (!matchFilesEmpty(mfi)) { script = rpmScriptFromTriggerTag(h, triggertag(sense), tm, ti); headerGet(h, RPMTAG_INSTPREFIXES, &installPrefixes, HEADERGET_ALLOC|HEADERGET_ARGV); /* * As input function set function to get next file from * matching file iterator. As parameter for this function * set matching file iterator. Input function will be called * during execution of trigger script in order to get data * that will be passed as stdin to trigger script. To get * these data from lua script function rpm.input() can be used. */ inputFunc = (char *(*)(void *)) matchFilesNext; rpmScriptSetNextFileFunc(script, inputFunc, mfi); nerrors += runScript(ts, te, installPrefixes.data, script, 0, 0); rpmtdFreeData(&installPrefixes); rpmScriptFree(script); } rpmfilesFree(files); matchFilesIteratorFree(mfi); } rpmdsFree(rpmdsTrigger); rpmdsFree(rpmdsTriggers); return nerrors; }