[Rpm-maint] [PATCH 1/6] Update the plugin architecture to allow for remembering state
Steve Lawrence
slawrence at tresys.com
Mon Aug 30 20:32:27 UTC 2010
This moves most of the plugin logic to a new rpmplugins file with a
struct and functions for managing plugins, allowing for plugins to carry
state. This also adds init and cleanup hooks for plugins to initialize
and cleanup their state, and a new 'open te' hook allowing plugins to
read and save information from transaction elements.
This also generalizes the plugin architecture a bit so it isn't so
specific to collections.
---
Makefile.am | 1 +
lib/Makefile.am | 2 +-
lib/collections.h | 26 -------
lib/rpmplugins.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++
lib/rpmplugins.h | 123 +++++++++++++++++++++++++++++++
lib/rpmte.c | 136 ++++++++++-------------------------
lib/rpmte_internal.h | 7 ++
lib/rpmts.c | 10 +++
lib/rpmts.h | 7 ++
lib/rpmts_internal.h | 2 +
lib/rpmtypes.h | 2 +
lib/transaction.c | 6 +-
plugins/Makefile.am | 2 +-
plugins/collection.h | 12 ---
plugins/exec.c | 29 ++++++-
plugins/plugin.h | 15 ++++
preinstall.am | 4 +
17 files changed, 437 insertions(+), 145 deletions(-)
delete mode 100644 lib/collections.h
create mode 100644 lib/rpmplugins.c
create mode 100644 lib/rpmplugins.h
delete mode 100644 plugins/collection.h
create mode 100644 plugins/plugin.h
diff --git a/Makefile.am b/Makefile.am
index 87e812f..798549a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -67,6 +67,7 @@ pkginclude_HEADERS += lib/rpmte.h
pkginclude_HEADERS += lib/rpmts.h
pkginclude_HEADERS += lib/rpmtypes.h
pkginclude_HEADERS += lib/rpmvf.h
+pkginclude_HEADERS += lib/rpmplugins.h
pkginclude_HEADERS += build/rpmbuild.h
pkginclude_HEADERS += build/rpmfc.h
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 1357c7c..d34588e 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -34,7 +34,7 @@ librpm_la_SOURCES = \
verify.c rpmlock.c rpmlock.h misc.h \
rpmscript.h rpmscript.c legacy.c merge.c \
rpmliblua.c rpmliblua.h rpmchroot.c rpmchroot.h \
- collections.h
+ rpmplugins.c rpmplugins.h
librpm_la_LDFLAGS = -version-info 1:0:0
diff --git a/lib/collections.h b/lib/collections.h
deleted file mode 100644
index 78fbaec..0000000
--- a/lib/collections.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _COLLECTIONS_H
-#define _COLLECTIONS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef rpmRC(*collHookFunc) (rpmts, const char *, const char *);
-
-#define COLLHOOK_POST_ADD_FUNC post_add
-#define COLLHOOK_POST_ANY_FUNC post_any
-#define COLLHOOK_PRE_REMOVE_FUNC pre_remove
-
-#define COLLECTION_HOOKS collection_hooks
-typedef enum rpmCollHook_e {
- COLLHOOK_NONE = 0,
- COLLHOOK_POST_ADD = 1 << 0,
- COLLHOOK_POST_ANY = 1 << 1,
- COLLHOOK_PRE_REMOVE = 1 << 2
-} rpmCollHook;
-
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _COLLECTIONS_H */
diff --git a/lib/rpmplugins.c b/lib/rpmplugins.c
new file mode 100644
index 0000000..e97d088
--- /dev/null
+++ b/lib/rpmplugins.c
@@ -0,0 +1,198 @@
+
+#include "system.h"
+
+#include <rpm/rpmmacro.h>
+#include <rpm/rpmtypes.h>
+#include <rpm/rpmlog.h>
+#include <rpm/rpmstring.h>
+#include <rpm/rpmts.h>
+
+#include <rpm/rpmplugins.h>
+
+#define STR1(x) #x
+#define STR(x) STR1(x)
+
+struct rpmPlugins_s {
+ void **handles;
+ ARGV_t names;
+ int count;
+ rpmts ts;
+};
+
+static int rpmpluginsGetPluginIndex(rpmPlugins plugins, const char *name)
+{
+ int i;
+ for (i = 0; i < plugins->count; i++) {
+ if (rstreq(plugins->names[i], name)) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static rpmRC rpmpluginsHookIsSupported(void *handle, rpmPluginHook hook)
+{
+ rpmPluginHook *supportedHooks =
+ (rpmPluginHook *) dlsym(handle, STR(PLUGIN_HOOKS));
+ return (*supportedHooks & hook);
+}
+
+int rpmpluginsPluginAdded(rpmPlugins plugins, const char *name)
+{
+ return (rpmpluginsGetPluginIndex(plugins, name) >= 0);
+}
+
+rpmPlugins rpmpluginsNew(rpmts ts)
+{
+ rpmPlugins plugins = xcalloc(1, sizeof(*plugins));
+ plugins->ts = ts;
+ return plugins;
+}
+
+rpmRC rpmpluginsAdd(rpmPlugins plugins, const char *name, const char *path,
+ const char *opts)
+{
+ rpmPluginHook *supportedHooks;
+ char *error;
+
+ void *handle = dlopen(path, RTLD_LAZY);
+ if (!handle) {
+ rpmlog(RPMLOG_ERR, _("Failed to dlopen %s %s\n"), path, dlerror());
+ return RPMRC_FAIL;
+ }
+
+ /* make sure the plugin has the supported hooks flag */
+ supportedHooks = (rpmPluginHook *) dlsym(handle, STR(PLUGIN_HOOKS));
+ if ((error = dlerror()) != NULL) {
+ rpmlog(RPMLOG_ERR, _("Failed to resolve symbol %s: %s\n"),
+ STR(PLUGIN_HOOKS), error);
+ return RPMRC_FAIL;
+ }
+
+ argvAdd(&plugins->names, name);
+ plugins->handles = xrealloc(plugins->handles, (plugins->count + 1) * sizeof(*plugins->handles));
+ plugins->handles[plugins->count] = handle;
+ plugins->count++;
+
+ return rpmpluginsCallInit(plugins, name, opts);
+}
+
+rpmRC rpmpluginsAddCollectionPlugin(rpmPlugins plugins, const char *name)
+{
+ char *path;
+ char *options;
+ int rc = RPMRC_FAIL;
+
+ path = rpmExpand("%{?__collection_", name, "}", NULL);
+ if (!path || rstreq(path, "")) {
+ rpmlog(RPMLOG_ERR, _("Failed to expand %%__collection_%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;
+ for (i = 0; i < plugins->count; i++) {
+ rpmpluginsCallCleanup(plugins, plugins->names[i]);
+ dlclose(plugins->handles[i]);
+ }
+ plugins->handles = _free(plugins->handles);
+ plugins->names = argvFree(plugins->names);
+ plugins->ts = NULL;
+ _free(plugins);
+
+ return NULL;
+}
+
+
+/* Common define for all rpmpluginsCall* hook functions */
+#define RPMPLUGINS_SET_HOOK_FUNC(hook) \
+ void *handle = NULL; \
+ int index; \
+ char * error; \
+ index = rpmpluginsGetPluginIndex(plugins, name); \
+ if (index < 0) { \
+ rpmlog(RPMLOG_ERR, _("Plugin %s not loaded\n"), name); \
+ return RPMRC_FAIL; \
+ } \
+ handle = plugins->handles[index]; \
+ if (!handle) { \
+ rpmlog(RPMLOG_ERR, _("Plugin %s not loaded\n"), name); \
+ return RPMRC_FAIL; \
+ } \
+ if (!rpmpluginsHookIsSupported(handle, hook)) { \
+ return RPMRC_OK; \
+ } \
+ *(void **)(&hookFunc) = dlsym(handle, STR(hook##_FUNC)); \
+ if ((error = dlerror()) != NULL) { \
+ rpmlog(RPMLOG_ERR, _("Failed to resolve %s plugin symbol %s: %s\n"), name, STR(hook##_FUNC), error); \
+ return RPMRC_FAIL; \
+ } \
+ if (rpmtsFlags(plugins->ts) & (RPMTRANS_FLAG_TEST | RPMTRANS_FLAG_JUSTDB)) { \
+ return RPMRC_OK; \
+ } \
+ rpmlog(RPMLOG_DEBUG, "Plugin: calling hook %s in %s plugin\n", STR(hook##_FUNC), name);
+
+rpmRC rpmpluginsCallInit(rpmPlugins plugins, const char *name, const char *opts)
+{
+ rpmRC (*hookFunc)(rpmts, const char *, const char *);
+ RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_INIT);
+ return hookFunc(plugins->ts, name, opts);
+}
+
+rpmRC rpmpluginsCallCleanup(rpmPlugins plugins, const char *name)
+{
+ rpmRC (*hookFunc)(void);
+ RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_CLEANUP);
+ return hookFunc();
+}
+
+rpmRC rpmpluginsCallOpenTE(rpmPlugins plugins, const char *name, rpmte te)
+{
+ rpmRC (*hookFunc)(rpmte);
+ RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_OPENTE);
+ return hookFunc(te);
+}
+
+rpmRC rpmpluginsCallCollectionPostAdd(rpmPlugins plugins, const char *name)
+{
+ rpmRC (*hookFunc)(void);
+ RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_COLL_POST_ADD);
+ return hookFunc();
+}
+
+rpmRC rpmpluginsCallCollectionPostAny(rpmPlugins plugins, const char *name)
+{
+ rpmRC (*hookFunc)(void);
+ RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_COLL_POST_ANY);
+ return hookFunc();
+}
+
+rpmRC rpmpluginsCallCollectionPreRemove(rpmPlugins plugins, const char *name)
+{
+ rpmRC (*hookFunc)(void);
+ RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_COLL_PRE_REMOVE);
+ return hookFunc();
+}
diff --git a/lib/rpmplugins.h b/lib/rpmplugins.h
new file mode 100644
index 0000000..ae82865
--- /dev/null
+++ b/lib/rpmplugins.h
@@ -0,0 +1,123 @@
+#ifndef _PLUGINS_H
+#define _PLUGINS_H
+
+#include <rpm/rpmtypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PLUGIN_HOOKS plugin_hooks
+
+#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
+
+typedef enum rpmPluginHook_e {
+ PLUGINHOOK_NONE = 0,
+ PLUGINHOOK_INIT = 1 << 0,
+ PLUGINHOOK_CLEANUP = 1 << 1,
+ PLUGINHOOK_OPENTE = 1 << 2,
+ PLUGINHOOK_COLL_POST_ADD = 1 << 3,
+ PLUGINHOOK_COLL_POST_ANY = 1 << 4,
+ PLUGINHOOK_COLL_PRE_REMOVE = 1 << 5
+} rpmPluginHook;
+
+/** \ingroup rpmplugins
+ * Create a new plugins structure
+ * @param ts transaction set
+ * @return new plugin structure
+ */
+rpmPlugins rpmpluginsNew(rpmts ts);
+
+/** \ingroup rpmplugins
+ * Destroy a plugins structure
+ * @param plugins plugins structure to destroy
+ * @return NULL always
+ */
+rpmPlugins rpmpluginsFree(rpmPlugins plugins);
+
+/** \ingroup rpmplugins
+ * Add and open a plugin
+ * @param plugins plugins structure to add a plugin to
+ * @param name name to access plugin
+ * @param path path of plugin to open
+ * @param opts options to pass to the plugin
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmpluginsAdd(rpmPlugins plugins, const char *name, const char *path, const char *opts);
+
+/** \ingroup rpmplugins
+ * Add and open a collection plugin
+ * @param plugins plugins structure to add a collection plugin to
+ * @param name name of collection to open
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmpluginsAddCollectionPlugin(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
+ * @return 1 if plugin name has already been added, 0 otherwise
+ */
+int rpmpluginsPluginAdded(rpmPlugins plugins, const char *name);
+
+
+/** \ingroup rpmplugins
+ * Call the init plugin hook
+ * @param plugins plugins structure
+ * @param name name of plugin
+ * @param opts plugin options
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmpluginsCallInit(rpmPlugins plugins, const char *name, const char *opts);
+
+/** \ingroup rpmplugins
+ * Call the cleanup plugin hook
+ * @param plugins plugins structure
+ * @param name name of plugin
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmpluginsCallCleanup(rpmPlugins plugins, const char *name);
+
+/** \ingroup rpmplugins
+ * Call the open te plugin hook
+ * @param plugins plugins structure
+ * @param name name of plugin
+ * @param te transaction element opened
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmpluginsCallOpenTE(rpmPlugins plugins, const char *name, rpmte te);
+
+/** \ingroup rpmplugins
+ * Call the collection post add plugin hook
+ * @param plugins plugins structure
+ * @param name name of plugin
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmpluginsCallCollectionPostAdd(rpmPlugins plugins, const char *name);
+
+/** \ingroup rpmplugins
+ * Call the collection post any plugin hook
+ * @param plugins plugins structure
+ * @param name name of plugin
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmpluginsCallCollectionPostAny(rpmPlugins plugins, const char *name);
+
+/** \ingroup rpmplugins
+ * Call the collection pre remove plugin hook
+ * @param plugins plugins structure
+ * @param name name of plugin
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmpluginsCallCollectionPreRemove(rpmPlugins plugins, const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _PLUGINS_H */
diff --git a/lib/rpmte.c b/lib/rpmte.c
index ee86957..316ed5b 100644
--- a/lib/rpmte.c
+++ b/lib/rpmte.c
@@ -12,8 +12,8 @@
#include <rpm/rpmts.h>
#include <rpm/rpmdb.h>
#include <rpm/rpmlog.h>
+#include <rpm/rpmplugins.h>
-#include "lib/collections.h"
#include "lib/rpmte_internal.h"
#include "debug.h"
@@ -816,126 +816,66 @@ rpmfs rpmteGetFileStates(rpmte te) {
return te->fs;
}
-static int rpmteRunCollection(rpmte te, const char *collname,
- rpmCollHook hook)
+rpmRC rpmteSetupCollectionPlugins(rpmte te)
{
-#define STR1(x) #x
-#define STR(x) STR1(x)
-
- void *handle = NULL;
- collHookFunc hookFunc;
- const char *hookFuncSym;
- rpmCollHook *pluginHooks;
- char *plugin;
- char *options;
- char *error;
-
- int rc = RPMRC_FAIL;
- if (rpmtsFlags(te->ts) & RPMTRANS_FLAG_NOCOLLECTIONS) {
- return RPMRC_OK;
- }
-
- plugin = rpmExpand("%{?__collection_", collname, "}", NULL);
- if (!plugin || rstreq(plugin, "")) {
- rpmlog(RPMLOG_ERR, _("Failed to expand %%__collection_%s macro\n"),
- collname);
- goto exit;
- }
-
- /* split the options from the plugin string */
-#define SKIPSPACE(s) { while (*(s) && risspace(*(s))) (s)++; }
-#define SKIPNONSPACE(s) { while (*(s) && !risspace(*(s))) (s)++; }
- options = plugin;
- SKIPNONSPACE(options);
- if (risspace(*options)) {
- *options = '\0';
- options++;
- SKIPSPACE(options);
- }
- if (*options == '\0') {
- options = NULL;
- }
-
- handle = dlopen(plugin, RTLD_LAZY);
- if (!handle) {
- rpmlog(RPMLOG_ERR, _("Failed to open %s: %s\n"), plugin, dlerror());
- goto exit;
- }
-
- dlerror();
-
- pluginHooks = (rpmCollHook *) dlsym(handle, STR(COLLECTION_HOOKS));
- if ((error = dlerror()) != NULL) {
- rpmlog(RPMLOG_ERR, _("Failed to resolve symbol: %s\n"),
- STR(COLLECTION_HOOKS));
- goto exit;
- }
-
- if (!(*pluginHooks & hook)) {
- /* plugin doesn't support this hook, exit */
- rc = RPMRC_OK;
- goto exit;
- }
-
- switch (hook) {
- case COLLHOOK_POST_ADD:
- hookFuncSym = STR(COLLHOOK_POST_ADD_FUNC);
- break;
- case COLLHOOK_POST_ANY:
- hookFuncSym = STR(COLLHOOK_POST_ANY_FUNC);
- break;
- case COLLHOOK_PRE_REMOVE:
- hookFuncSym = STR(COLLHOOK_PRE_REMOVE_FUNC);
- break;
- default:
- goto exit;
- }
+ ARGV_const_t colls = rpmteCollections(te);
+ rpmPlugins plugins = rpmtsPlugins(te->ts);
+ rpmRC rc = RPMRC_OK;
- *(void **) (&hookFunc) = dlsym(handle, hookFuncSym);
- if ((error = dlerror()) != NULL) {
- rpmlog(RPMLOG_ERR, _("Failed to resolve symbol %s: %s\n"),
- hookFuncSym, error);
- goto exit;
+ if (!colls) {
+ return rc;
}
- if (rpmtsFlags(te->ts) & (RPMTRANS_FLAG_TEST | RPMTRANS_FLAG_JUSTDB)) {
- /* don't perform the action if --test or --justdb are set */
- rc = RPMRC_OK;
- } else {
- rc = (*hookFunc) (te->ts, collname, options);
+ rpmteOpen(te, 0);
+ for (; colls && *colls; colls++) {
+ if (!rpmpluginsPluginAdded(plugins, *colls)) {
+ rc = rpmpluginsAddCollectionPlugin(plugins, *colls);
+ if (rc != RPMRC_OK) {
+ break;
+ }
+ }
+ rc = rpmpluginsCallOpenTE(plugins, *colls, te);
+ if (rc != RPMRC_OK) {
+ break;
+ }
}
-
- exit:
- if (handle)
- dlclose(handle);
- _free(plugin);
+ rpmteClose(te, 0);
return rc;
}
-static rpmRC rpmteRunAllCollections(rpmte te, rpmCollHook hook)
+static rpmRC rpmteRunAllCollections(rpmte te, rpmPluginHook hook)
{
ARGV_const_t colls;
+ rpmRC(*collHook) (rpmPlugins, const char *);
rpmRC rc = RPMRC_OK;
+ if (rpmtsFlags(te->ts) & RPMTRANS_FLAG_NOCOLLECTIONS) {
+ goto exit;
+ }
+
switch (hook) {
- case COLLHOOK_POST_ADD:
+ case PLUGINHOOK_COLL_POST_ADD:
colls = te->lastInCollectionsAdd;
+ collHook = rpmpluginsCallCollectionPostAdd;
break;
- case COLLHOOK_POST_ANY:
+ case PLUGINHOOK_COLL_POST_ANY:
colls = te->lastInCollectionsAny;
+ collHook = rpmpluginsCallCollectionPostAny;
break;
- case COLLHOOK_PRE_REMOVE:
+ case PLUGINHOOK_COLL_PRE_REMOVE:
colls = te->firstInCollectionsRemove;
+ collHook = rpmpluginsCallCollectionPreRemove;
break;
default:
- colls = NULL;
+ goto exit;
}
for (; colls && *colls; colls++) {
- rpmteRunCollection(te, *colls, hook);
+ rc = collHook(rpmtsPlugins(te->ts), *colls);
}
+ exit:
return rc;
}
@@ -953,15 +893,15 @@ int rpmteProcess(rpmte te, pkgGoal goal)
}
}
- rpmteRunAllCollections(te, COLLHOOK_PRE_REMOVE);
+ rpmteRunAllCollections(te, PLUGINHOOK_COLL_PRE_REMOVE);
if (rpmteOpen(te, reset_fi)) {
failed = rpmpsmRun(te->ts, te, goal);
rpmteClose(te, reset_fi);
}
- rpmteRunAllCollections(te, COLLHOOK_POST_ADD);
- rpmteRunAllCollections(te, COLLHOOK_POST_ANY);
+ rpmteRunAllCollections(te, PLUGINHOOK_COLL_POST_ADD);
+ rpmteRunAllCollections(te, PLUGINHOOK_COLL_POST_ANY);
/* XXX should %pretrans failure fail the package install? */
if (failed && !scriptstage) {
diff --git a/lib/rpmte_internal.h b/lib/rpmte_internal.h
index 2425868..4f1a9f9 100644
--- a/lib/rpmte_internal.h
+++ b/lib/rpmte_internal.h
@@ -134,6 +134,13 @@ int rpmteAddToLastInCollectionAny(rpmte te, const char * collname);
RPM_GNUC_INTERNAL
int rpmteAddToFirstInCollectionRemove(rpmte te, const char * collname);
+/** \ingroup rpmte
+ * Sends the open te plugin hook for each plugins with the transaction element open
+ * @param te transaction element
+ * @return 0 on success, non-zero on error
+ */
+RPM_GNUC_INTERNAL
+rpmRC rpmteSetupCollectionPlugins(rpmte te);
#endif /* _RPMTE_INTERNAL_H */
diff --git a/lib/rpmts.c b/lib/rpmts.c
index 43966e9..506742e 100644
--- a/lib/rpmts.c
+++ b/lib/rpmts.c
@@ -19,6 +19,7 @@
#include <rpm/rpmfi.h>
#include <rpm/rpmlog.h>
#include <rpm/rpmte.h>
+#include <rpm/rpmplugins.h>
#include "rpmio/digest.h"
#include "lib/rpmal.h"
@@ -615,6 +616,8 @@ rpmts rpmtsFree(rpmts ts)
ts->netsharedPaths = argvFree(ts->netsharedPaths);
ts->installLangs = argvFree(ts->installLangs);
+ ts->plugins = rpmpluginsFree(ts->plugins);
+
if (_rpmts_stats)
rpmtsPrintStats(ts);
@@ -825,6 +828,11 @@ rpmop rpmtsOp(rpmts ts, rpmtsOpX opx)
return op;
}
+rpmPlugins rpmtsPlugins(rpmts ts)
+{
+ return (ts != NULL ? ts->plugins : NULL);
+}
+
int rpmtsSetNotifyCallback(rpmts ts,
rpmCallbackFunction notify, rpmCallbackData notifyData)
{
@@ -900,6 +908,8 @@ rpmts rpmtsCreate(void)
ts->nrefs = 0;
+ ts->plugins = rpmpluginsNew(ts);
+
return rpmtsLink(ts);
}
diff --git a/lib/rpmts.h b/lib/rpmts.h
index 8ea01f3..50fdd01 100644
--- a/lib/rpmts.h
+++ b/lib/rpmts.h
@@ -514,6 +514,13 @@ rpm_color_t rpmtsSetPrefColor(rpmts ts, rpm_color_t color);
rpmop rpmtsOp(rpmts ts, rpmtsOpX opx);
/** \ingroup rpmts
+ * Get the plugins associated with a transaction set
+ * @param ts transaction set
+ * @return plugins
+ */
+rpmPlugins rpmtsPlugins(rpmts ts);
+
+/** \ingroup rpmts
* Set transaction notify callback function and argument.
*
* @warning This call must be made before rpmtsRun() for
diff --git a/lib/rpmts_internal.h b/lib/rpmts_internal.h
index 1a16457..4a4de45 100644
--- a/lib/rpmts_internal.h
+++ b/lib/rpmts_internal.h
@@ -62,6 +62,8 @@ struct rpmts_s {
rpmSpec spec; /*!< Spec file control structure. */
+ rpmPlugins plugins; /*!< Transaction plugins */
+
int nrefs; /*!< Reference count. */
};
diff --git a/lib/rpmtypes.h b/lib/rpmtypes.h
index 434ba16..197516e 100644
--- a/lib/rpmtypes.h
+++ b/lib/rpmtypes.h
@@ -72,6 +72,8 @@ typedef void * rpmCallbackData;
typedef struct rpmPubkey_s * rpmPubkey;
typedef struct rpmKeyring_s * rpmKeyring;
+typedef struct rpmPlugins_s * rpmPlugins;
+
typedef struct rpmgi_s * rpmgi;
typedef struct rpmSpec_s * rpmSpec;
diff --git a/lib/transaction.c b/lib/transaction.c
index 31abe4f..7e1d42d 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -1108,7 +1108,7 @@ static int runTransScripts(rpmts ts, pkgGoal goal)
return 0; /* what to do about failures? */
}
-static int rpmtsDetermineCollectionPoints(rpmts ts)
+static int rpmtsSetupCollections(rpmts ts)
{
/* seenCollectionsPost and TEs are basically a key-value pair. each item in
* seenCollectionsPost is a collection that has been seen from any package,
@@ -1139,6 +1139,8 @@ static int rpmtsDetermineCollectionPoints(rpmts ts)
}
}
+ rpmteSetupCollectionPlugins(p);
+
for (collname = rpmteCollections(p); collname && *collname; collname++) {
/* figure out if we've seen this collection in post before */
for (i = 0; i < numSeenPost && strcmp(*collname, seenCollectionsPost[i]); i++) {
@@ -1426,7 +1428,7 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
goto exit;
}
- rpmtsDetermineCollectionPoints(ts);
+ rpmtsSetupCollections(ts);
/* Check package set for problems */
tsprobs = checkProblems(ts);
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 41a9ca4..07560f0 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -15,5 +15,5 @@ pluginsdir = $(rpmconfigdir)/plugins
plugins_LTLIBRARIES = exec.la
-exec_la_SOURCES = collection.h exec.c
+exec_la_SOURCES = plugin.h exec.c
exec_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la
diff --git a/plugins/collection.h b/plugins/collection.h
deleted file mode 100644
index e0818d6..0000000
--- a/plugins/collection.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "system.h"
-
-#include <rpm/rpmlib.h>
-#include <rpm/rpmlog.h>
-#include <rpm/rpmts.h>
-
-#include "lib/collections.h"
-#include "lib/rpmchroot.h"
-
-rpmRC COLLHOOK_POST_ANY_FUNC(rpmts ts, const char * collname, const char * options);
-rpmRC COLLHOOK_POST_ADD_FUNC(rpmts ts, const char * collname, const char * options);
-rpmRC COLLHOOK_PRE_REMOVE_FUNC(rpmts ts, const char * collname, const char * options);
diff --git a/plugins/exec.c b/plugins/exec.c
index ab2536f..fd25f2b 100644
--- a/plugins/exec.c
+++ b/plugins/exec.c
@@ -1,11 +1,30 @@
-#include "collection.h"
+#include "plugin.h"
#include <sys/wait.h>
-rpmCollHook COLLECTION_HOOKS = COLLHOOK_POST_ANY;
+static char * options;
+static char * name;
-rpmRC COLLHOOK_POST_ANY_FUNC(rpmts ts, const char *collname,
- const char *options)
+rpmPluginHook PLUGIN_HOOKS = \
+ PLUGINHOOK_INIT | \
+ PLUGINHOOK_CLEANUP | \
+ PLUGINHOOK_COLL_POST_ANY;
+
+rpmRC PLUGINHOOK_INIT_FUNC(rpmts ts, const char *name, const char *opts)
+{
+ options = strdup(opts);
+ name = strdup(name);
+ return RPMRC_OK;
+}
+
+rpmRC PLUGINHOOK_CLEANUP_FUNC(void)
+{
+ options = _free(options);
+ name = _free(name);
+ return RPMRC_OK;
+}
+
+rpmRC PLUGINHOOK_COLL_POST_ANY_FUNC(void)
{
int rc = RPMRC_FAIL;
@@ -16,7 +35,7 @@ rpmRC COLLHOOK_POST_ANY_FUNC(rpmts ts, const char *collname,
if (options) {
int status = system(options);
if (!WIFEXITED(status) || WEXITSTATUS(status)) {
- rpmlog(RPMLOG_ERR, "%s collection action failed\n", collname);
+ rpmlog(RPMLOG_ERR, "%s collection action failed\n", name);
goto exit;
}
}
diff --git a/plugins/plugin.h b/plugins/plugin.h
new file mode 100644
index 0000000..5156f93
--- /dev/null
+++ b/plugins/plugin.h
@@ -0,0 +1,15 @@
+#include "system.h"
+
+#include <rpm/rpmlib.h>
+#include <rpm/rpmlog.h>
+#include <rpm/rpmts.h>
+
+#include "lib/rpmplugins.h"
+#include "lib/rpmchroot.h"
+
+rpmRC PLUGINHOOK_INIT_FUNC(rpmts ts, const char * name, const char * opts);
+rpmRC PLUGINHOOK_CLEANUP_FUNC(void);
+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);
diff --git a/preinstall.am b/preinstall.am
index ab3a072..7f64837 100644
--- a/preinstall.am
+++ b/preinstall.am
@@ -110,6 +110,10 @@ include/rpm/rpmvf.h: lib/rpmvf.h include/rpm/$(dirstamp)
$(INSTALL_DATA) $(top_srcdir)/lib/rpmvf.h include/rpm/rpmvf.h
BUILT_SOURCES += include/rpm/rpmvf.h
CLEANFILES += include/rpm/rpmvf.h
+include/rpm/rpmplugins.h: lib/rpmplugins.h include/rpm/$(dirstamp)
+ $(INSTALL_DATA) $(top_srcdir)/lib/rpmplugins.h include/rpm/rpmplugins.h
+BUILT_SOURCES += include/rpm/rpmplugins.h
+CLEANFILES += include/rpm/rpmplugins.h
include/rpm/rpmbuild.h: build/rpmbuild.h include/rpm/$(dirstamp)
$(INSTALL_DATA) $(top_srcdir)/build/rpmbuild.h include/rpm/rpmbuild.h
BUILT_SOURCES += include/rpm/rpmbuild.h
--
1.6.2.5
More information about the Rpm-maint
mailing list