This change adds a new type of the rpm plugin, called transaction plugin and a 
set of initial hooks for this plugin.
The hooks are:

PLUGINHOOK_TSM_PRE
Pre-transaction hook that is called before an rpm transaction begins
PLUGINHOOK_TSM_POST
Post-transaction hook that is called after an rpm transaction ends
PLUGINHOOK_PSM_PRE
Pre-transaction-element hook that is called before an rpm transaction-element 
is processed
PLUGINHOOK_PSM_POST
Post-transaction-element hook that is called after an rpm transaction-element 
is processed
PLUGINHOOK_SCRIPT_SETUP
Per-script hook that is called once for each rpm mainainers script that is 
present in the package

Each hook is called for every plugin that have this hook registered.
The avaliable transaction plugins can be specified in macros.in via 
transaction_plugins element.
---
 lib/psm.c         |    3 +-
 lib/rpmplugins.c  |  118 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/rpmplugins.h  |   64 ++++++++++++++++++++++++++++-
 lib/rpmscript.c   |   17 +++++---
 lib/rpmscript.h   |    2 +-
 lib/rpmte.c       |   14 ++++++-
 lib/transaction.c |   39 ++++++++++++++++++
 plugins/plugin.h  |   14 +++++++
 8 files changed, 260 insertions(+), 11 deletions(-)

diff --git a/lib/psm.c b/lib/psm.c
index 8f5376d..1a0c27e 100644
--- a/lib/psm.c
+++ b/lib/psm.c
@@ -23,6 +23,7 @@
 #include "lib/rpmfi_internal.h" /* XXX replaced/states... */
 #include "lib/rpmte_internal.h"        /* XXX internal apis */
 #include "lib/rpmdb_internal.h" /* rpmdbAdd/Remove */
+#include "lib/rpmts_internal.h" /* ts->plugins */
 #include "lib/rpmscript.h"
 
 #include "debug.h"
@@ -421,7 +422,7 @@ static rpmRC runScript(rpmpsm psm, ARGV_const_t prefixes,
 
     rpmswEnter(rpmtsOp(psm->ts, RPMTS_OP_SCRIPTLETS), 0);
     rc = rpmScriptRun(script, arg1, arg2, sfd,
-                     prefixes, warn_only, selinux);
+                     prefixes, warn_only, selinux, psm->ts->plugins);
     rpmswExit(rpmtsOp(psm->ts, RPMTS_OP_SCRIPTLETS), 0);
 
     /* Map warn-only errors to "notfound" for script stop callback */
diff --git a/lib/rpmplugins.c b/lib/rpmplugins.c
index 9098aa5..bb44f34 100644
--- a/lib/rpmplugins.c
+++ b/lib/rpmplugins.c
@@ -110,6 +110,39 @@ rpmRC rpmpluginsAddCollectionPlugin(rpmPlugins plugins, 
const char *name)
     return rc;
 }
 
+rpmRC rpmpluginsAddTransactionPlugin(rpmPlugins plugins, const char *name)
+{
+    char *path;
+    char *options;
+    int rc = RPMRC_FAIL;
+
+    path = rpmExpand("%{?__transaction_",name, "}", NULL);
+    if (!path || rstreq(path, "")) {
+       rpmlog(RPMLOG_INFO, _("Failed to expand %%__transaction_%s macro\n"), 
name);
+       goto exit;
+    }
+
+    /* split the options from the path */
+#define SKIPSPACE(s)    { while (*(s) &&  risspace(*(s))) (s)++; }
+#define SKIPNONSPACE(s) { while (*(s) && !risspace(*(s))) (s)++; }
+    options = path;
+    SKIPNONSPACE(options);
+    if (risspace(*options)) {
+       *options = '\0';
+       options++;
+       SKIPSPACE(options);
+    }
+    if (*options == '\0') {
+       options = NULL;
+    }
+
+    rc = rpmpluginsAdd(plugins, name, path, options);
+
+  exit:
+    _free(path);
+    return rc;
+}
+
 rpmPlugins rpmpluginsFree(rpmPlugins plugins)
 {
     int i;
@@ -195,3 +228,88 @@ rpmRC rpmpluginsCallCollectionPreRemove(rpmPlugins 
plugins, const char *name)
     RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_COLL_PRE_REMOVE);
     return hookFunc();
 }
+
+rpmRC rpmpluginsCallTsmPre(rpmPlugins plugins, rpmts ts)
+{
+    rpmRC (*hookFunc)(rpmts);
+    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_TSM_PRE);
+       if ( hookFunc(ts) == RPMRC_FAIL )
+               rc = RPMRC_FAIL;
+    }
+
+    return rc;
+}
+
+rpmRC rpmpluginsCallTsmPost(rpmPlugins plugins, rpmts ts)
+{
+    rpmRC (*hookFunc)(rpmts);
+    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_TSM_POST);
+       if ( hookFunc(ts) == RPMRC_FAIL )
+               rc = RPMRC_FAIL;
+    }
+
+    return rc;
+}
+
+rpmRC rpmpluginsCallPsmPre(rpmPlugins plugins, rpmte te)
+{
+    rpmRC (*hookFunc)(rpmte);
+    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_PSM_PRE);
+       if ( hookFunc(te) == RPMRC_FAIL )
+               rc = RPMRC_FAIL;
+    }
+
+    return rc;
+}
+
+rpmRC rpmpluginsCallPsmPost(rpmPlugins plugins, rpmte te)
+{
+    rpmRC (*hookFunc)(rpmte);
+    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_PSM_POST);
+       if ( hookFunc(te) == RPMRC_FAIL )
+               rc = RPMRC_FAIL;
+    }
+
+    return rc;
+}
+
+rpmRC rpmpluginsCallScriptSetup(rpmPlugins plugins, char* path)
+{
+    rpmRC (*hookFunc)(char*);
+    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 )
+               rc = RPMRC_FAIL;
+    }
+
+    return rc;
+}
diff --git a/lib/rpmplugins.h b/lib/rpmplugins.h
index 7985559..b30f80d 100644
--- a/lib/rpmplugins.h
+++ b/lib/rpmplugins.h
@@ -11,11 +11,20 @@ extern "C" {
 
 #define PLUGINHOOK_INIT_FUNC                   pluginhook_init
 #define PLUGINHOOK_CLEANUP_FUNC                        pluginhook_cleanup
+
 #define PLUGINHOOK_OPENTE_FUNC                 pluginhook_opente
 #define PLUGINHOOK_COLL_POST_ADD_FUNC          pluginhook_coll_post_add
 #define PLUGINHOOK_COLL_POST_ANY_FUNC          pluginhook_coll_post_any
 #define PLUGINHOOK_COLL_PRE_REMOVE_FUNC                
pluginhook_coll_pre_remove
 
+#define PLUGINHOOK_TSM_PRE_FUNC                        pluginhook_tsm_pre
+#define PLUGINHOOK_TSM_POST_FUNC               pluginhook_tsm_post
+
+#define PLUGINHOOK_PSM_PRE_FUNC                        pluginhook_psm_pre
+#define PLUGINHOOK_PSM_POST_FUNC               pluginhook_psm_post
+ 
+#define PLUGINHOOK_SCRIPT_SETUP_FUNC           pluginhook_script_setup
+
 enum rpmPluginHook_e {
     PLUGINHOOK_NONE            = 0,
     PLUGINHOOK_INIT            = 1 << 0,
@@ -23,7 +32,12 @@ enum rpmPluginHook_e {
     PLUGINHOOK_OPENTE          = 1 << 2,
     PLUGINHOOK_COLL_POST_ADD   = 1 << 3,
     PLUGINHOOK_COLL_POST_ANY   = 1 << 4,
-    PLUGINHOOK_COLL_PRE_REMOVE = 1 << 5
+    PLUGINHOOK_COLL_PRE_REMOVE = 1 << 5,
+    PLUGINHOOK_TSM_PRE         = 1 << 6,
+    PLUGINHOOK_TSM_POST                = 1 << 7,
+    PLUGINHOOK_PSM_PRE         = 1 << 8,                       
+    PLUGINHOOK_PSM_POST                = 1 << 9,               
+    PLUGINHOOK_SCRIPT_SETUP    = 1 << 10
 };
 
 typedef rpmFlags rpmPluginHook;
@@ -61,6 +75,14 @@ rpmRC rpmpluginsAdd(rpmPlugins plugins, const char *name, 
const char *path, cons
 rpmRC rpmpluginsAddCollectionPlugin(rpmPlugins plugins, const char *name);
 
 /** \ingroup rpmplugins
+ * Add and open a transaction plugin
+ * @param plugins      plugins structure to add a transaction plugin to
+ * @param name         name of transaction plugin to open
+ * @return             RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmpluginsAddTransactionPlugin(rpmPlugins plugins, const char *name);
+
+/** \ingroup rpmplugins
  * Determine if a plugin has been added already
  * @param plugins      plugins structure
  * @param name         name of plugin to check
@@ -119,6 +141,46 @@ rpmRC rpmpluginsCallCollectionPostAny(rpmPlugins plugins, 
const char *name);
  */
 rpmRC rpmpluginsCallCollectionPreRemove(rpmPlugins plugins, const char *name);
 
+/** \ingroup rpmplugins
+ * Call the pre transaction plugin hook
+ * @param plugins      plugins structure
+ * @param ts           processed transaction
+ * @return             RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmpluginsCallTsmPre(rpmPlugins plugins, rpmts ts);
+
+/** \ingroup rpmplugins
+ * Call the post transaction plugin hook
+ * @param plugins      plugins structure
+ * @param ts           processed transaction
+ * @return             RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmpluginsCallTsmPost(rpmPlugins plugins, rpmts ts);
+
+/** \ingroup rpmplugins
+ * Call the post transaction element plugin hook
+ * @param plugins      plugins structure
+ * @param te           processed transaction element
+ * @return             RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmpluginsCallPsmPre(rpmPlugins plugins, rpmte te);
+
+/** \ingroup rpmplugins
+ * Call the post transaction element plugin hook
+ * @param plugins      plugins structure
+ * @param te           processed transaction element
+ * @return             RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmpluginsCallPsmPost(rpmPlugins plugins, rpmte te);
+
+/** \ingroup rpmplugins
+ * Call the script setup plugin hook
+ * @param plugins      plugins structure
+ * @param path         script path
+ * @return             RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmpluginsCallScriptSetup(rpmPlugins plugins, char* path);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/rpmscript.c b/lib/rpmscript.c
index 57c24c6..d1e042c 100644
--- a/lib/rpmscript.c
+++ b/lib/rpmscript.c
@@ -14,6 +14,8 @@
 #include "rpmio/rpmlua.h"
 #include "lib/rpmscript.h"
 
+#include "lib/rpmplugins.h"     /* rpm plugins hooks */
+
 #include "debug.h"
 
 struct rpmScript_s {
@@ -91,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(int selinux, ARGV_const_t argv, ARGV_const_t prefixes,
+static void doScriptExec(rpmPlugins plugins, int selinux, ARGV_const_t argv, 
ARGV_const_t prefixes,
                        FD_t scriptFd, FD_t out)
 {
     int pipes[2];
@@ -169,7 +171,10 @@ static void doScriptExec(int selinux, ARGV_const_t argv, 
ARGV_const_t prefixes,
        }
 
        if (xx == 0) {
-           xx = execv(argv[0], argv);
+                /* Run script setup hook for all plugins */
+                if (rpmpluginsCallScriptSetup(plugins, argv[0]) != RPMRC_FAIL) 
{
+                       xx = execv(argv[0], argv);
+                }
        }
     }
     _exit(127); /* exit 127 for compatibility with bash(1) */
@@ -202,7 +207,7 @@ exit:
 /**
  * Run an external script.
  */
-static rpmRC runExtScript(int selinux, ARGV_const_t prefixes,
+static rpmRC runExtScript(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)
 {
@@ -258,7 +263,7 @@ static rpmRC runExtScript(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(selinux, *argvp, prefixes, scriptFd, out);
+       doScriptExec(plugins, selinux, *argvp, prefixes, scriptFd, out);
     }
 
     do {
@@ -297,7 +302,7 @@ exit:
 }
 
 rpmRC rpmScriptRun(rpmScript script, int arg1, int arg2, FD_t scriptFd,
-                  ARGV_const_t prefixes, int warn_only, int selinux)
+                  ARGV_const_t prefixes, int warn_only, int selinux, 
rpmPlugins plugins)
 {
     ARGV_t args = NULL;
     rpmlogLvl lvl = warn_only ? RPMLOG_WARNING : RPMLOG_ERR;
@@ -315,7 +320,7 @@ rpmRC rpmScriptRun(rpmScript script, int arg1, int arg2, 
FD_t scriptFd,
     if (rstreq(args[0], "<lua>")) {
        rc = runLuaScript(selinux, prefixes, script->descr, lvl, scriptFd, 
&args, script->body, arg1, arg2);
     } else {
-       rc = runExtScript(selinux, prefixes, script->descr, lvl, scriptFd, 
&args, script->body, arg1, arg2);
+       rc = runExtScript(plugins, selinux, prefixes, script->descr, lvl, 
scriptFd, &args, script->body, arg1, arg2);
     }
     argvFree(args);
 
diff --git a/lib/rpmscript.h b/lib/rpmscript.h
index 7d584bc..852735b 100644
--- a/lib/rpmscript.h
+++ b/lib/rpmscript.h
@@ -29,7 +29,7 @@ rpmScript rpmScriptFree(rpmScript script);
 
 RPM_GNUC_INTERNAL
 rpmRC rpmScriptRun(rpmScript script, int arg1, int arg2, FD_t scriptFd,
-                   ARGV_const_t prefixes, int warn_only, int selinux);
+                   ARGV_const_t prefixes, int warn_only, int selinux, 
rpmPlugins plugins);
 
 RPM_GNUC_INTERNAL
 rpmTagVal rpmScriptTag(rpmScript script);
diff --git a/lib/rpmte.c b/lib/rpmte.c
index 35b8e3e..5972505 100644
--- a/lib/rpmte.c
+++ b/lib/rpmte.c
@@ -941,7 +941,7 @@ int rpmteProcess(rpmte te, pkgGoal goal)
     int scriptstage = (goal != PKG_INSTALL && goal != PKG_ERASE);
     int test = (rpmtsFlags(te->ts) & RPMTRANS_FLAG_TEST);
     int reset_fi = (scriptstage == 0 && test == 0);
-    int failed = 1;
+    int failed = 0;
 
     /* Dont bother opening for elements without pre/posttrans scripts */
     if (goal == PKG_PRETRANS || goal == PKG_POSTTRANS) {
@@ -955,7 +955,17 @@ int rpmteProcess(rpmte te, pkgGoal goal)
     }
 
     if (rpmteOpen(te, reset_fi)) {
-       failed = rpmpsmRun(te->ts, te, goal);
+
+       /* Run pre transaction element hook for all plugins */
+       if (goal != PKG_PRETRANS && goal != PKG_POSTTRANS) {
+               failed = rpmpluginsCallPsmPre(rpmtsPlugins(te->ts), te);
+       }
+       if (!failed) {
+               failed = rpmpsmRun(te->ts, te, goal);
+               /* Run post transaction element hook for all plugins*/
+               if (goal != PKG_PRETRANS && goal != PKG_POSTTRANS)
+                       failed = rpmpluginsCallPsmPost(rpmtsPlugins(te->ts), 
te);
+               }
        rpmteClose(te, reset_fi);
     }
     
diff --git a/lib/transaction.c b/lib/transaction.c
index c05d3af..3d25347 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -21,6 +21,8 @@
 #include "lib/rpmts_internal.h"
 #include "rpmio/rpmhook.h"
 
+#include "lib/rpmplugins.h"
+
 /* XXX FIXME: merge with existing (broken?) tests in system.h */
 /* portability fiddles */
 #if STATFS_IN_SYS_STATVFS
@@ -1414,6 +1416,30 @@ static int rpmtsProcess(rpmts ts)
     return rc;
 }
 
+static rpmRC rpmteSetupTransactionPlugins(rpmts ts)
+{
+    rpmRC rc = 0;
+    char *plugins = NULL, *plugin = NULL;
+    char delims[] = ",";
+
+    plugins = rpmExpand("%{?__transaction_plugins}", NULL);
+    if (!plugins || rstreq(plugins, "")) {
+        rpmlog(RPMLOG_INFO, _("Failed to expand %%__transaction_plugins 
macro\n"));
+       return -1;
+    }
+
+    plugin = strtok(plugins, delims);
+    while(plugin != NULL) {
+       rpmlog(RPMLOG_DEBUG, _("plugin is %s\n"), plugin);
+        if (!rpmpluginsPluginAdded(ts->plugins, (const char*)plugin)) {
+               rc = rpmpluginsAddTransactionPlugin(ts->plugins, (const 
char*)plugin);
+        }
+        plugin = strtok(NULL, delims);
+    }
+    free(plugins);
+    return rc;
+}
+
 int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
 {
     int rc = -1; /* assume failure */
@@ -1441,11 +1467,19 @@ int rpmtsRun(rpmts ts, rpmps okProbs, 
rpmprobFilterFlags ignoreSet)
        goto exit;
     }
 
+
+    rc = rpmteSetupTransactionPlugins(ts);
+
     rpmtsSetupCollections(ts);
 
     /* Check package set for problems */
     tsprobs = checkProblems(ts);
 
+    /* Run pre transaction hook for all plugins */
+    if ( rpmpluginsCallTsmPre(ts->plugins, ts) == RPMRC_FAIL) {
+       goto exit;
+    }
+
     /* Run pre-transaction scripts, but only if there are no known
      * problems up to this point and not disabled otherwise. */
     if (!((rpmtsFlags(ts) & (RPMTRANS_FLAG_BUILD_PROBS|RPMTRANS_FLAG_NOPRE))
@@ -1489,6 +1523,11 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags 
ignoreSet)
        runTransScripts(ts, PKG_POSTTRANS);
     }
 
+    /* Run post transaction hook for all plugins */
+    if ( rpmpluginsCallTsmPost(ts->plugins, ts) == RPMRC_FAIL) {
+       goto exit;
+    }
+
 exit:
     /* Finish up... */
     (void) umask(oldmask);
diff --git a/plugins/plugin.h b/plugins/plugin.h
index 5156f93..cf49f8a 100644
--- a/plugins/plugin.h
+++ b/plugins/plugin.h
@@ -7,9 +7,23 @@
 #include "lib/rpmplugins.h"
 #include "lib/rpmchroot.h"
 
+/* general plugin hooks */
 rpmRC PLUGINHOOK_INIT_FUNC(rpmts ts, const char * name, const char * opts);
 rpmRC PLUGINHOOK_CLEANUP_FUNC(void);
+
+/* collection plugin hooks */
 rpmRC PLUGINHOOK_OPENTE_FUNC(rpmte te);
 rpmRC PLUGINHOOK_COLL_POST_ANY_FUNC(void);
 rpmRC PLUGINHOOK_COLL_POST_ADD_FUNC(void);
 rpmRC PLUGINHOOK_COLL_PRE_REMOVE_FUNC(void);
+
+/* per transaction plugin hooks */
+rpmRC PLUGINHOOK_TSM_PRE_FUNC(rpmts ts);
+rpmRC PLUGINHOOK_TSM_POST_FUNC(rpmts ts);
+
+/* per transaction element plugin hooks */
+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);
-- 
1.7.9.5

_______________________________________________
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint

Reply via email to