aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Ghigonis <laurent@p1sec.com>2013-09-14 22:54:26 +0200
committerLaurent Ghigonis <laurent@p1sec.com>2013-09-14 22:54:26 +0200
commit7b9757a32c3d31fd8ae70ec3ed56a17e522ee311 (patch)
tree58530e1c78fe23dd4ad53dca014b6f11260f46db
parenttcp server (diff)
downloadglouglou-7b9757a32c3d31fd8ae70ec3ed56a17e522ee311.tar.xz
glouglou-7b9757a32c3d31fd8ae70ec3ed56a17e522ee311.zip
work on modules
-rw-r--r--v3/glougloud/glougloud_mod_net/glougloud_mod_net.c26
-rw-r--r--v3/glougloud/glougloud_modules.h22
-rw-r--r--v3/glougloud/viz.c110
-rw-r--r--v3/libglouglou/libglouglou.h2
-rw-r--r--v3/libglouglou/utils.c19
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++;
}