Browse Source

Added "actions" and "setups" to the plugin api

personal/stbuehler/wip
Stefan Bühler 14 years ago
parent
commit
57701f997d
  1. 24
      src/actions.c
  2. 23
      src/actions.h
  3. 2
      src/base.h
  4. 117
      src/plugin.c
  5. 50
      src/plugin.h
  6. 19
      src/server.c
  7. 4
      src/server.h

24
src/actions.c

@ -12,7 +12,6 @@ struct action_stack_element {
};
action *action_new_setting(server *srv, GString *name, option *value) {
option_set setting;
if (!parse_option(srv, name->str, value, &setting)) {
@ -28,6 +27,29 @@ action *action_new_setting(server *srv, GString *name, option *value) {
return a;
}
action *action_new_function(server *srv, const char *name, option *value) {
action *a;
action_func af;
server_action *sa;
if (NULL == (sa = g_hash_table_lookup(srv->actions, name))) {
ERROR(srv, "Action '%s' doesn't exist", name);
return NULL;
}
if (!sa->create_action(srv, sa->p ? sa->p->data : NULL, value, &af)) {
ERROR(srv, "Action '%s' creation failed", name);
return NULL;
}
a = g_slice_new(action);
a->refcount = 1;
a->type = ACTION_TFUNCTION;
a->value.function = af;
return a;
}
void action_release(action *a) {
assert(a->refcount > 0);
if (!(--a->refcount)) {

23
src/actions.h

@ -31,7 +31,15 @@ struct action_stack {
};
struct server; struct connection;
typedef action_result (*action_func)(struct server *srv, struct connection *con, void* param);
typedef action_result (*ActionFunc)(struct server *srv, struct connection *con, gpointer param);
typedef void (*ActionFree)(struct server *srv, gpointer param);
struct action_func {
ActionFunc func;
ActionFree free;
gpointer param;
};
typedef struct action_func action_func;
#include "condition.h"
#include "plugin.h"
@ -55,10 +63,7 @@ struct action {
action_list* target; /** action target to jump to if condition is fulfilled */
} condition;
struct {
action_func func;
gpointer param;
} function;
action_func function;
} value;
};
@ -76,8 +81,8 @@ LI_API action_result action_execute(server *srv, connection *con);
/* create new action */
action *action_new_setting(server *srv, GString *name, option *value);
action *action_new_function();
action *action_new_condition_string(comp_key_t comp, comp_operator_t op, GString *str);
action *action_new_condition_int(comp_key_t comp, comp_operator_t op, guint64 i);
LI_API action *action_new_setting(server *srv, GString *name, option *value);
LI_API action *action_new_function(server *srv, const char *name, option *value);
LI_API action *action_new_condition_string(comp_key_t comp, comp_operator_t op, GString *str);
LI_API action *action_new_condition_int(comp_key_t comp, comp_operator_t op, guint64 i);
#endif

2
src/base.h

@ -13,8 +13,8 @@ typedef struct connection connection;
#include "server.h"
#include "plugin.h"
#include "actions.h"
#include "plugin.h"
#include "request.h"
#include "log.h"

117
src/plugin.c

@ -8,25 +8,69 @@ static plugin* plugin_new(const gchar *name) {
return p;
}
void plugin_free(plugin *p) {
static void plugin_free_options(server *srv, plugin *p) {
size_t i;
const plugin_option *po;
server_option *so;
if (!p->options) return;
for (i = 0; (po = &p->options[i])->name; i++) {
if (NULL == (so = g_hash_table_lookup(srv->options, po->name))) break;
if (so->p != p) break;
g_hash_table_remove(srv->options, po->name);
}
}
static void plugin_free_actions(server *srv, plugin *p) {
size_t i;
const plugin_action *pa;
server_action *sa;
if (!p->actions) return;
for (i = 0; (pa = &p->actions[i])->name; i++) {
if (NULL == (sa = g_hash_table_lookup(srv->actions, pa->name))) break;
if (sa->p != p) break;
g_hash_table_remove(srv->actions, pa->name);
}
}
static void plugin_free_setups(server *srv, plugin *p) {
size_t i;
const plugin_setup *ps;
server_setup *ss;
if (!p->setups) return;
for (i = 0; (ps = &p->setups[i])->name; i++) {
if (NULL == (ss = g_hash_table_lookup(srv->setups, ps->name))) break;
if (ss->p != p) break;
g_hash_table_remove(srv->setups, ps->name);
}
}
void plugin_free(server *srv, plugin *p) {
if (!p) return;
g_hash_table_remove(srv->plugins, p->name);
plugin_free_options(srv, p);
plugin_free_actions(srv, p);
plugin_free_setups(srv, p);
g_slice_free(plugin, p);
}
static server_option* find_option(server *srv, const char *key) {
return (server_option*) g_hash_table_lookup(srv->options, key);
static server_option* find_option(server *srv, const char *name) {
return (server_option*) g_hash_table_lookup(srv->options, name);
}
gboolean parse_option(server *srv, const char *key, option *opt, option_set *mark) {
gboolean parse_option(server *srv, const char *name, option *opt, option_set *mark) {
server_option *sopt;
if (!srv || !key || !mark) return FALSE;
if (!srv || !name || !mark) return FALSE;
sopt = find_option(srv, key);
sopt = find_option(srv, name);
if (!sopt) {
ERROR(srv, "Unknown option '%s'", key);
ERROR(srv, "Unknown option '%s'", name);
return FALSE;
}
@ -102,13 +146,14 @@ gboolean plugin_register(server *srv, const gchar *name, PluginInit init) {
server_option *so;
const plugin_option *po;
for (i = 0; (po = &p->options[i])->key; i++) {
if (NULL != (so = (server_option*)g_hash_table_lookup(srv->options, po->key))) {
for (i = 0; (po = &p->options[i])->name; i++) {
if (NULL != (so = (server_option*)g_hash_table_lookup(srv->options, po->name))) {
ERROR(srv, "Option '%s' already registered by plugin '%s', unloading '%s'",
po->key,
po->name,
so->p ? so->p->name : "<none>",
p->name);
break;
plugin_free(srv, p);
return FALSE;
}
so = g_slice_new0(server_option);
so->type = po->type;
@ -117,19 +162,49 @@ gboolean plugin_register(server *srv, const gchar *name, PluginInit init) {
so->index = g_hash_table_size(srv->options);
so->module_index = i;
so->p = p;
g_hash_table_insert(srv->options, (gchar*) po->key, so);
g_hash_table_insert(srv->options, (gchar*) po->name, so);
}
}
if (po->key) {
while (i-- > 0) {
po = &p->options[i];
g_slice_free(server_option, g_hash_table_lookup(srv->options, po->key));
g_hash_table_remove(srv->options, po->key);
if (p->actions) {
size_t i;
server_action *sa;
const plugin_action *pa;
for (i = 0; (pa = &p->actions[i])->name; i++) {
if (NULL != (sa = (server_action*)g_hash_table_lookup(srv->actions, pa->name))) {
ERROR(srv, "Action '%s' already registered by plugin '%s', unloading '%s'",
pa->name,
sa->p ? sa->p->name : "<none>",
p->name);
plugin_free(srv, p);
return FALSE;
}
g_hash_table_remove(srv->plugins, p->name);
if (p->free) p->free(srv, p);
plugin_free(p);
return FALSE;
sa = g_slice_new0(server_action);
sa->create_action = pa->create_action;
sa->p = p;
g_hash_table_insert(srv->actions, (gchar*) pa->name, sa);
}
}
if (p->setups) {
size_t i;
server_setup *ss;
const plugin_setup *ps;
for (i = 0; (ps = &p->setups[i])->name; i++) {
if (NULL != (ss = (server_setup*)g_hash_table_lookup(srv->setups, ps->name))) {
ERROR(srv, "Setup '%s' already registered by plugin '%s', unloading '%s'",
ps->name,
ss->p ? ss->p->name : "<none>",
p->name);
plugin_free(srv, p);
return FALSE;
}
ss = g_slice_new0(server_setup);
ss->setup = ps->setup;
ss->p = p;
g_hash_table_insert(srv->setups, (gchar*) ps->name, ss);
}
}

50
src/plugin.h

@ -10,6 +10,18 @@ typedef struct plugin_option plugin_option;
struct server_option;
typedef struct server_option server_option;
struct plugin_action;
typedef struct plugin_action plugin_action;
struct server_action;
typedef struct server_action server_action;
struct plugin_setup;
typedef struct plugin_setup plugin_setup;
struct server_setup;
typedef struct server_setup server_setup;
#define INIT_FUNC(x) \
LI_EXPORT void * x(server *srv, plugin *)
@ -19,12 +31,15 @@ typedef struct server_option server_option;
#include "base.h"
#include "options.h"
#include "actions.h"
#include "module.h"
typedef void (*PluginInit) (server *srv, plugin *p);
typedef void (*PluginFree) (server *srv, plugin *p);
typedef gboolean (*PluginParseOption) (server *srv, gpointer p_d, size_t ndx, option *opt, gpointer *value);
typedef void (*PluginFreeOption) (server *srv, gpointer p_d, size_t ndx, gpointer value);
typedef void (*PluginInit) (server *srv, plugin *p);
typedef void (*PluginFree) (server *srv, plugin *p);
typedef gboolean (*PluginParseOption) (server *srv, gpointer p_d, size_t ndx, option *opt, gpointer *value);
typedef void (*PluginFreeOption) (server *srv, gpointer p_d, size_t ndx, gpointer value);
typedef gboolean (*PluginCreateAction) (server *srv, gpointer p_d, option *opt, action_func *func);
typedef gboolean (*PluginSetup) (server *srv, gpointer p_d, option *opt);
struct plugin {
size_t version;
@ -35,16 +50,29 @@ struct plugin {
PluginFree free; /**< called before plugin is unloaded */
const plugin_option *options;
const plugin_action *actions;
const plugin_setup *setups;
};
struct plugin_option {
const gchar *key;
const gchar *name;
option_type type;
PluginParseOption parse_option;
PluginFreeOption free_option;
};
struct plugin_action {
const gchar *name;
PluginCreateAction create_action;
};
struct plugin_setup {
const gchar *name;
PluginSetup setup;
};
/* Internal structures */
struct server_option {
plugin *p;
@ -61,7 +89,17 @@ struct server_option {
option_type type;
};
LI_API void plugin_free(plugin *p);
struct server_action {
plugin *p;
PluginCreateAction create_action;
};
struct server_setup {
plugin *p;
PluginSetup setup;
};
LI_API void plugin_free(server *srv, plugin *p);
LI_API gboolean plugin_register(server *srv, const gchar *name, PluginInit init);
LI_API gboolean parse_option(server *srv, const char *key, option *opt, option_set *mark);

19
src/server.c

@ -2,11 +2,24 @@
#include "base.h"
#include "log.h"
static void server_option_free(gpointer _so) {
g_slice_free(server_option, _so);
}
static void server_action_free(gpointer _sa) {
g_slice_free(server_action, _sa);
}
static void server_setup_free(gpointer _ss) {
g_slice_free(server_setup, _ss);
}
server* server_new() {
server* srv = g_slice_new0(server);
srv->plugins = g_hash_table_new(g_str_hash, g_str_equal);
srv->options = g_hash_table_new(g_str_hash, g_str_equal);
srv->options = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, server_option_free);
srv->actions = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, server_action_free);
srv->setups = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, server_setup_free);
srv->mutex = g_mutex_new();
return srv;
@ -16,8 +29,10 @@ void server_free(server* srv) {
if (!srv) return;
/* TODO */
g_hash_table_destroy(srv->plugins);
g_hash_table_destroy(srv->options);
g_hash_table_destroy(srv->actions);
g_hash_table_destroy(srv->setups);
g_hash_table_destroy(srv->plugins);
g_mutex_free(srv->mutex);
/* free logs */

4
src/server.h

@ -6,8 +6,10 @@ struct server {
GHashTable *plugins;
size_t option_count;
GHashTable *options;
GHashTable *actions;
GHashTable *setups;
gpointer *option_def_values;
gboolean exiting;

Loading…
Cancel
Save