diff --git a/lib/rpmplugins.c b/lib/rpmplugins.c index d533b708a5..c721cadbca 100644 --- a/lib/rpmplugins.c +++ b/lib/rpmplugins.c @@ -264,17 +264,51 @@ rpmRC rpmpluginsCallPsmPost(rpmPlugins plugins, rpmte te) return rc; } -rpmRC rpmpluginsCallScriptSetup(rpmPlugins plugins, char* path) +rpmRC rpmpluginsCallScriptletPre(rpmPlugins plugins, const char *s_name, int type) { - rpmRC (*hookFunc)(char*); + rpmRC (*hookFunc)(const char*, int); int i; rpmRC rc = RPMRC_OK; const char *name = NULL; for (i = 0; i < plugins->count; i++) { name = plugins->names[i]; - RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_SCRIPT_SETUP); - if (hookFunc(path) == RPMRC_FAIL) + RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_SCRIPTLET_PRE); + if (hookFunc(s_name, type) == RPMRC_FAIL) + rc = RPMRC_FAIL; + } + + return rc; +} + +rpmRC rpmpluginsCallScriptletForkPost(rpmPlugins plugins, const char *path, int type) +{ + rpmRC (*hookFunc)(const char*, int); + int i; + rpmRC rc = RPMRC_OK; + const char *name = NULL; + + for (i = 0; i < plugins->count; i++) { + name = plugins->names[i]; + RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_SCRIPTLET_FORK_POST); + if (hookFunc(path, type) == RPMRC_FAIL) + rc = RPMRC_FAIL; + } + + return rc; +} + +rpmRC rpmpluginsCallScriptletPost(rpmPlugins plugins, const char *s_name, int type, int res) +{ + rpmRC (*hookFunc)(const char*, int, int); + int i; + rpmRC rc = RPMRC_OK; + const char *name = NULL; + + for (i = 0; i < plugins->count; i++) { + name = plugins->names[i]; + RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_SCRIPTLET_POST); + if (hookFunc(s_name, type, res) == RPMRC_FAIL) rc = RPMRC_FAIL; } diff --git a/lib/rpmplugins.h b/lib/rpmplugins.h index 153b8a99b8..ffb8fe1619 100644 --- a/lib/rpmplugins.h +++ b/lib/rpmplugins.h @@ -22,8 +22,10 @@ extern "C" { #define PLUGINHOOK_PSM_PRE_FUNC pluginhook_psm_pre #define PLUGINHOOK_PSM_POST_FUNC pluginhook_psm_post - -#define PLUGINHOOK_SCRIPT_SETUP_FUNC pluginhook_script_setup + +#define PLUGINHOOK_SCRIPTLET_PRE_FUNC pluginhook_scriptlet_pre +#define PLUGINHOOK_SCRIPTLET_FORK_POST_FUNC pluginhook_scriptlet_fork_post +#define PLUGINHOOK_SCRIPTLET_POST_FUNC pluginhook_scriptlet_post enum rpmPluginHook_e { PLUGINHOOK_NONE = 0, @@ -37,9 +39,18 @@ enum rpmPluginHook_e { PLUGINHOOK_TSM_POST = 1 << 7, PLUGINHOOK_PSM_PRE = 1 << 8, PLUGINHOOK_PSM_POST = 1 << 9, - PLUGINHOOK_SCRIPT_SETUP = 1 << 10 + PLUGINHOOK_SCRIPTLET_PRE = 1 << 10, + PLUGINHOOK_SCRIPTLET_FORK_POST = 1 << 11, + PLUGINHOOK_SCRIPTLET_POST = 1 << 12 }; +/* indicates the way the scriptlet is executed */ +typedef enum rpmScriptletExecutionFlow_e { + RPMSCRIPTLET_NONE = 0, + RPMSCRIPTLET_FORK = 1 << 0, + RPMSCRIPTLET_EXEC = 1 << 1 +} rpmScriptletExecutionFlow; + typedef rpmFlags rpmPluginHook; /** \ingroup rpmplugins @@ -167,12 +178,32 @@ rpmRC rpmpluginsCallPsmPre(rpmPlugins plugins, rpmte te); rpmRC rpmpluginsCallPsmPost(rpmPlugins plugins, rpmte te); /** \ingroup rpmplugins - * Call the script setup plugin hook + * Call the pre scriptlet execution plugin hook + * @param plugins plugins structure + * @param s_name scriptlet name + * @param type indicates the scriptlet execution flow, see rpmScriptletExecutionFlow + * @return RPMRC_OK on success, RPMRC_FAIL otherwise + */ +rpmRC rpmpluginsCallScriptletPre(rpmPlugins plugins, const char *s_name, int type); + +/** \ingroup rpmplugins + * Call the post fork scriptlet plugin hook. + * @param plugins plugins structure + * @param path scriptlet path + * @param type indicates the scriptlet execution flow, see rpmScriptletExecutionFlow + * @return RPMRC_OK on success, RPMRC_FAIL otherwise + */ +rpmRC rpmpluginsCallScriptletForkPost(rpmPlugins plugins, const char *path, int type); + +/** \ingroup rpmplugins + * Call the post scriptlet execution plugin hook * @param plugins plugins structure - * @param path script path + * @param s_name scriptlet name + * @param type indicates the scriptlet execution flow, see rpmScriptletExecutionFlow + * @param res scriptlet execution result code * @return RPMRC_OK on success, RPMRC_FAIL otherwise */ -rpmRC rpmpluginsCallScriptSetup(rpmPlugins plugins, char* path); +rpmRC rpmpluginsCallScriptletPost(rpmPlugins plugins, const char *s_name, int type, int res); #ifdef __cplusplus } diff --git a/lib/rpmscript.c b/lib/rpmscript.c index f8c5fc74a3..a27251c9a8 100644 --- a/lib/rpmscript.c +++ b/lib/rpmscript.c @@ -29,7 +29,7 @@ struct rpmScript_s { /** * Run internal Lua script. */ -static rpmRC runLuaScript(int selinux, ARGV_const_t prefixes, +static rpmRC runLuaScript(rpmPlugins plugins, int selinux, ARGV_const_t prefixes, const char *sname, rpmlogLvl lvl, FD_t scriptFd, ARGV_t * argvp, const char *script, int arg1, int arg2) { @@ -93,7 +93,7 @@ static rpmRC runLuaScript(int selinux, ARGV_const_t prefixes, static const char * const SCRIPT_PATH = "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin"; -static void doScriptExec(rpmPlugins plugins, int selinux, ARGV_const_t argv, ARGV_const_t prefixes, +static void doScriptExec(int selinux, ARGV_const_t argv, ARGV_const_t prefixes, FD_t scriptFd, FD_t out) { int pipes[2]; @@ -171,10 +171,7 @@ static void doScriptExec(rpmPlugins plugins, int selinux, ARGV_const_t argv, ARG } if (xx == 0) { - /* Run script setup hook for all plugins */ - if (rpmpluginsCallScriptSetup(plugins, argv[0]) != RPMRC_FAIL) { - xx = execv(argv[0], argv); - } + xx = execv(argv[0], argv); } } _exit(127); /* exit 127 for compatibility with bash(1) */ @@ -263,7 +260,13 @@ static rpmRC runExtScript(rpmPlugins plugins, int selinux, ARGV_const_t prefixes } else if (pid == 0) {/* Child */ rpmlog(RPMLOG_DEBUG, "%s: execv(%s) pid %d\n", sname, *argvp[0], (unsigned)getpid()); - doScriptExec(plugins, selinux, *argvp, prefixes, scriptFd, out); + + /* Run scriptlet post fork hook for all plugins */ + if (rpmpluginsCallScriptletForkPost(plugins, *argvp[0], RPMSCRIPTLET_FORK | RPMSCRIPTLET_EXEC) != RPMRC_FAIL) { + doScriptExec(selinux, *argvp, prefixes, scriptFd, out); + } else { + _exit(126); /* exit 126 for compatibility with bash(1) */ + } } do { @@ -307,6 +310,7 @@ rpmRC rpmScriptRun(rpmScript script, int arg1, int arg2, FD_t scriptFd, ARGV_t args = NULL; rpmlogLvl lvl = warn_only ? RPMLOG_WARNING : RPMLOG_ERR; rpmRC rc; + int script_type = RPMSCRIPTLET_FORK | RPMSCRIPTLET_EXEC; if (script == NULL) return RPMRC_OK; @@ -316,12 +320,24 @@ rpmRC rpmScriptRun(rpmScript script, int arg1, int arg2, FD_t scriptFd, } else { argvAdd(&args, "/bin/sh"); } + + if (rstreq(args[0], "")) + script_type = RPMSCRIPTLET_NONE; - if (rstreq(args[0], "")) { - rc = runLuaScript(selinux, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2); - } else { - rc = runExtScript(plugins, selinux, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2); + /* Run scriptlet pre hook for all plugins */ + rc = rpmpluginsCallScriptletPre(plugins, script->descr, script_type); + + if (rc != RPMRC_FAIL) { + if (script_type & RPMSCRIPTLET_EXEC) { + rc = runExtScript(plugins, selinux, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2); + } else { + rc = runLuaScript(plugins, selinux, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2); + } } + + /* Run scriptlet post hook for all plugins */ + rpmpluginsCallScriptletPost(plugins, script->descr, script_type, rc); + argvFree(args); return rc; diff --git a/plugins/plugin.h b/plugins/plugin.h index cf49f8a97f..dec3bfd235 100644 --- a/plugins/plugin.h +++ b/plugins/plugin.h @@ -25,5 +25,7 @@ rpmRC PLUGINHOOK_TSM_POST_FUNC(rpmts ts); rpmRC PLUGINHOOK_PSM_PRE_FUNC(rpmte te); rpmRC PLUGINHOOK_PSM_POST_FUNC(rpmte te); -/*per script plugin hooks */ -rpmRC PLUGINHOOK_SCRIPT_SETUP_FUNC(char* path); +/*per scriptlet plugin hooks */ +rpmRC PLUGINHOOK_SCRIPTLET_PRE_FUNC(const char *s_name, int type); +rpmRC PLUGINHOOK_SCRIPTLET_FORK_POST_FUNC(const char *path, int type); +rpmRC PLUGINHOOK_SCRIPTLET_POST_FUNC(const char *s_name, int type, int res);