2
0
Fork 0

merge from lp

This commit is contained in:
Thomas Porzelt 2008-07-23 22:26:38 +02:00
commit 191343333e
8 changed files with 258 additions and 30 deletions

View File

@ -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)) {

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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;
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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);