merge from lp
This commit is contained in:
commit
191343333e
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
/* #include "valgrind/valgrind.h" */
|
||||
#include "base.h"
|
||||
#include "ev.h"
|
||||
|
||||
#define REMOVE_PATH_FROM_FILE 1
|
||||
#if REMOVE_PATH_FROM_FILE
|
||||
|
|
157
src/plugin.c
157
src/plugin.c
|
@ -2,18 +2,75 @@
|
|||
#include "plugin.h"
|
||||
#include "log.h"
|
||||
|
||||
static server_option* find_option(server *srv, const char *key) {
|
||||
return (server_option*) g_hash_table_lookup(srv->options, key);
|
||||
static plugin* plugin_new(const gchar *name) {
|
||||
plugin *p = g_slice_new0(plugin);
|
||||
p->name = name;
|
||||
return p;
|
||||
}
|
||||
|
||||
gboolean parse_option(server *srv, const char *key, option *opt, option_set *mark) {
|
||||
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 *name) {
|
||||
return (server_option*) g_hash_table_lookup(srv->options, name);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -65,3 +122,91 @@ void release_option(server *srv, option_set *mark) { /** Does not free the optio
|
|||
}
|
||||
mark->value = NULL;
|
||||
}
|
||||
|
||||
gboolean plugin_register(server *srv, const gchar *name, PluginInit init) {
|
||||
plugin *p;
|
||||
|
||||
if (!init) {
|
||||
ERROR(srv, "Module '%s' needs an init function", name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_hash_table_lookup(srv->plugins, name)) {
|
||||
ERROR(srv, "Module '%s' already registered", name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
p = plugin_new(name);
|
||||
g_hash_table_insert(srv->plugins, (gchar*) p->name, p);
|
||||
|
||||
init(srv, p);
|
||||
|
||||
if (p->options) {
|
||||
size_t i;
|
||||
server_option *so;
|
||||
const plugin_option *po;
|
||||
|
||||
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->name,
|
||||
so->p ? so->p->name : "<none>",
|
||||
p->name);
|
||||
plugin_free(srv, p);
|
||||
return FALSE;
|
||||
}
|
||||
so = g_slice_new0(server_option);
|
||||
so->type = po->type;
|
||||
so->parse_option = po->parse_option;
|
||||
so->free_option = po->free_option;
|
||||
so->index = g_hash_table_size(srv->options);
|
||||
so->module_index = i;
|
||||
so->p = p;
|
||||
g_hash_table_insert(srv->options, (gchar*) po->name, so);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
57
src/plugin.h
57
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,32 +31,48 @@ 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;
|
||||
const char *name; /**< name of the plugin */
|
||||
const gchar *name; /**< name of the plugin */
|
||||
|
||||
gpointer data; /**< private plugin data */
|
||||
|
||||
PluginFree *free; /**< called before plugin is unloaded */
|
||||
PluginFree free; /**< called before plugin is unloaded */
|
||||
|
||||
plugin_option *options;
|
||||
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,18 @@ struct server_option {
|
|||
option_type type;
|
||||
};
|
||||
|
||||
LI_API gboolean plugin_register(server *srv, const gchar *name, PluginInit *init);
|
||||
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);
|
||||
LI_API void release_option(server *srv, option_set *mark); /**< Does not free the option_set memory */
|
||||
|
|
19
src/server.c
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();
|
||||
srv->actions = action_list_new();
|
||||
|
||||
|
@ -17,8 +30,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 */
|
||||
|
|
|
@ -10,7 +10,11 @@ struct server {
|
|||
struct action_list *actions;
|
||||
|
||||
size_t option_count;
|
||||
|
||||
GHashTable *options;
|
||||
GHashTable *actions;
|
||||
GHashTable *setups;
|
||||
|
||||
gpointer *option_def_values;
|
||||
|
||||
gboolean exiting;
|
||||
|
@ -27,7 +31,6 @@ struct server {
|
|||
};
|
||||
|
||||
|
||||
|
||||
server* server_new();
|
||||
void server_free(server* srv);
|
||||
|
||||
|
|
Loading…
Reference in New Issue