diff options
author | Laurent Ghigonis <laurent@p1sec.com> | 2013-09-14 22:54:26 +0200 |
---|---|---|
committer | Laurent Ghigonis <laurent@p1sec.com> | 2013-09-14 22:54:26 +0200 |
commit | 7b9757a32c3d31fd8ae70ec3ed56a17e522ee311 (patch) | |
tree | 58530e1c78fe23dd4ad53dca014b6f11260f46db | |
parent | tcp server (diff) | |
download | glouglou-7b9757a32c3d31fd8ae70ec3ed56a17e522ee311.tar.xz glouglou-7b9757a32c3d31fd8ae70ec3ed56a17e522ee311.zip |
work on modules
-rw-r--r-- | v3/glougloud/glougloud_mod_net/glougloud_mod_net.c | 26 | ||||
-rw-r--r-- | v3/glougloud/glougloud_modules.h | 22 | ||||
-rw-r--r-- | v3/glougloud/viz.c | 110 | ||||
-rw-r--r-- | v3/libglouglou/libglouglou.h | 2 | ||||
-rw-r--r-- | v3/libglouglou/utils.c | 19 |
5 files changed, 146 insertions, 33 deletions
diff --git a/v3/glougloud/glougloud_mod_net/glougloud_mod_net.c b/v3/glougloud/glougloud_mod_net/glougloud_mod_net.c new file mode 100644 index 0000000..ec6d93c --- /dev/null +++ b/v3/glougloud/glougloud_mod_net/glougloud_mod_net.c @@ -0,0 +1,26 @@ +#include <glougloud.h> + +char * +ggdmodviz_text_get(struct glougloud_cli *cli, char *op, char *target) +{ + +} + +void * +ggdmodviz_netstream_get(struct glougloud_cli *cli, char *notification) +{ + +} + +int +ggdmodviz_conf_set(struct glougloud_cli *cli, void *conf) +{ + +} + +char * +ggdmodprobe_redis_get(struct glougloud_probe *prb, + struct glouglou_packet *pkt) +{ + +} diff --git a/v3/glougloud/glougloud_modules.h b/v3/glougloud/glougloud_modules.h new file mode 100644 index 0000000..732fb08 --- /dev/null +++ b/v3/glougloud/glougloud_modules.h @@ -0,0 +1,22 @@ +/* + * Header for glougloud modules + * (both probes and viz modules) + */ + +enum ggdviz_cli_type { + GGDVIZ_CLI_TCP = 0, + GGDVIZ_CLI_WS = 1 +}; + +struct ggdviz_cli { + LIST_ENTRY(servtcp_cli) entry; + int id; + enum ggdviz_cli_type type; + union { + struct tcp { + struct bufferevent *bev; + struct addr addr; + }; + } +}; + diff --git a/v3/glougloud/viz.c b/v3/glougloud/viz.c index a46d253..c8265ba 100644 --- a/v3/glougloud/viz.c +++ b/v3/glougloud/viz.c @@ -17,40 +17,102 @@ struct glougloud_viz { struct event_base *evb; struct modules *mods; redisAsyncContext *rc; + /* clients list */ + LIST_HEAD(, ggdviz_cli) clients; + uint clients_count; + uint clients_ids_counter; + /* servers */ struct { struct evconnlistener *listener; - LIST_HEAD(, servtcp_cli) clients; - int clients_count; } servtcp; - uint clients_ids_counter; }; -struct servtcp_cli { - LIST_ENTRY(servtcp_cli) entry; +struct modviz_dl { int id; - struct bufferevent *bev; - struct addr addr; + char (*ggdmodviz_text_get)(struct glougloud_cli *, char *); }; struct glougloud *_ggd; struct glougloud_viz *_viz; +void * +_modules_cb_dlsym(void *handle) +{ + struct modviz_dl *dl = NULL; + void *sym; + + dl = xcalloc(1, sizeof(struct modviz_dl)); + if (!(sym = dlsym(handle, "glougloud_module_id"))) + goto err; + dl->id = *((uint *)sym); + dlerror(); // clear errors + if (!(sym = dlsym(handle, "ggdmodviz_text_get"))) + goto err; + dl->ggdmodviz_text_get = sym; + dlerror(); // clear errors + + return dl; +err: + if (dl) + free(dl); + return NULL; +} + int _modules_load(void) { _viz->evb = event_base_new(); - _viz->mods = modules_load(GLOUGLOUD_MOD_PATH, NULL); + _viz->mods = modules_load(GLOUGLOUD_MOD_PATH, _modules_cb_dlsym); return 0; } +/* + * XXX notify modules + * notif = extract reply->str + * foreach module + * if ! module match dbname + * continue + * foreach client + * module_viz_send(cli, notif) + */ +/* "pmessage","__key*__:*","__keyevent@0__:set","foo" */ static void _redis_cb_notification(redisAsyncContext *c, void *r, void *privdata) { - redisReply *reply = r; + redisReply *reply; + struct mod *m; + char *ntf_type, *ntf_pattern, *ntf_event, *ntf_target, *ntf_event_type, *ntf_op; + uint ntf_db; + int i; + + reply = r; if (!reply) return; - /* XXX notify modules */ + + notification = reply->str; + i = sscanf(reply->str, "\"%s\",\"%s\",\"%s\",\"%s\", + &ntf_type, &ntf_pattern, &ntf_event, &ntf_target); + if (i <= 3) { + log_notice("viz: error parsing redis notification !"); + return; + } + i = sscanf(ntf_event, "__%s@%d__:%s", + &ntf_event_type, &ntf_db, &ntf_op); + if (i <= 3) { + log_notice("viz: error parsing redis notification event type !"); + return; + } + + LIST_FOREACH(m, &_viz->mods, entry) { + if (m->dl->id != ntf_id) + continue; + LIST_FOREACH(cli, &_viz->clients, entry) { + m->dl->ggdmodviz_text_get(cli, ntf_op, ntf_target); + } + } + + log_debug("viz: redis cb_notification: %s", reply->str); } @@ -82,7 +144,7 @@ _redis_connect(void) if (_viz->rc->err) return -1; redisAsyncCommand(_viz->rc, _redis_cb_notification, "event", - "SUBSCRIBE __keyevent@ggd__:*"); + "SUBSCRIBE __keyevent@0__:*"); return 0; } @@ -98,14 +160,15 @@ _redis_disconnect(void) struct servtcp_cli * _servtcp_cli_add(struct sockaddr *sa, struct bufferevent *bev) { - struct servtcp_cli *cli; + struct ggdviz_cli *cli; - cli = xcalloc(1, sizeof(struct servtcp_cli)); + cli = xcalloc(1, sizeof(struct ggdviz_cli)); cli->id = _viz->clients_ids_counter; _viz->clients_ids_counter++; - cli->bev = bev; - addr_ston(sa, &cli->addr); - LIST_INSERT_HEAD(&_viz->servtcp.clients, cli, entry); + cli->type = GGDVIZ_CLI_TCP; + cli->tcp.bev = bev; + addr_ston(sa, &cli->tcp.addr); + LIST_INSERT_HEAD(&_viz->clients, cli, entry); log_debug("viz: _servtcp_cli_add, cli %d %s", cli->id, addr_ntoa(&cli->addr)); @@ -115,18 +178,18 @@ _servtcp_cli_add(struct sockaddr *sa, struct bufferevent *bev) } void -_servtcp_cli_del(struct servtcp_cli *cli) +_servtcp_cli_del(struct ggdviz_cli *cli) { bufferevent_free(cli->bev); LIST_REMOVE(cli, entry); - _viz->servtcp.clients_count--; + _viz->clients_count--; free(cli); } static void _servtcp_cb_read(struct bufferevent *bev, void *user_data) { - struct servtcp_cli *cli; + struct ggdviz_cli *cli; struct evbuffer *buf; char *line; size_t len; @@ -141,7 +204,7 @@ _servtcp_cb_read(struct bufferevent *bev, void *user_data) static void _servtcp_cb_event(struct bufferevent *bev, short events, void *user_data) { - struct servtcp_cli *cli; + struct ggdviz_cli *cli; cli = user_data; if (events & BEV_EVENT_EOF) { @@ -159,7 +222,7 @@ _servtcp_cb_listener(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sa, int socklen, void *user_data) { - struct servtcp_cli *cli; + struct ggdviz_cli *cli; struct bufferevent *bev; bev = bufferevent_socket_new(_viz->evb, fd, BEV_OPT_CLOSE_ON_FREE); @@ -207,8 +270,9 @@ _servtcp_stop(void) evconnlistener_free(_viz->servtcp.listener); _viz->servtcp.listener = NULL; - LIST_FOREACH_SAFE(cli, &_viz->servtcp.clients, entry, clitmp) - _servtcp_cli_del(cli); + LIST_FOREACH_SAFE(cli, &_viz->clients, entry, clitmp) + if (cli->type == GGDVIZ_CLI_TCP) + _servtcp_cli_del(cli); } int diff --git a/v3/libglouglou/libglouglou.h b/v3/libglouglou/libglouglou.h index 27a2464..9d615c4 100644 --- a/v3/libglouglou/libglouglou.h +++ b/v3/libglouglou/libglouglou.h @@ -114,6 +114,8 @@ void log_fatal(const char *, ...); struct mod { LIST_ENTRY(mod) entry; void *handle; + char *name; + void *dl; }; struct modules { LIST_HEAD(, mod) list; diff --git a/v3/libglouglou/utils.c b/v3/libglouglou/utils.c index a3581c2..60601e1 100644 --- a/v3/libglouglou/utils.c +++ b/v3/libglouglou/utils.c @@ -107,15 +107,16 @@ droppriv(char *user, int do_chroot, char *chroot_path) endpwent(); } -/* Loads modules from path and returns a list of handles */ +/* Loads modules from path and returns a list of handles + * If cb_dlsym() is not null, it is called for every module */ struct modules * -modules_load(char *path, char *check_sym) { +modules_load(char *path, void *(cb_dlsym)(void *)) { struct modules *modules; struct mod *mod; DIR *d; struct dirent *ent; - int n; - void *handle, *sym; + int n, sym_ok, modid; + void *handle, *dl; modules = xcalloc(1, sizeof(struct modules)); @@ -130,14 +131,12 @@ modules_load(char *path, char *check_sym) { if (!handle) continue; dlerror(); // clear errors - if (check_sym) { - sym = dlsym(handle, check_sym); - if (!sym) - continue; - dlerror(); // clear errors - } + if (cb_dlsym) + dl = cb_dlsym(handle); mod = xcalloc(1, sizeof(struct mod)); mod->handle = handle; + mod->name = strdup(ent->d_name); + mod->dl = dl; LIST_INSERT_HEAD(&modules->list, mod, entry); modules->count++; } |