summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am2
-rw-r--r--src/mod_cml.c38
-rw-r--r--src/mod_cml.h12
-rw-r--r--src/mod_cml_funcs.c67
-rw-r--r--src/mod_cml_logic.c15
5 files changed, 121 insertions, 13 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 7d01d0be..be69b28d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -71,7 +71,7 @@ endif
lib_LTLIBRARIES += mod_cml.la
mod_cml_la_SOURCES = mod_cml.c mod_cml_funcs.c mod_cml_logic.c
mod_cml_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
-mod_cml_la_LIBADD = $(MYSQL_LIBS) $(common_libadd)
+mod_cml_la_LIBADD = $(MEMCACHE_LIB) $(common_libadd)
lib_LTLIBRARIES += mod_trigger_b4_dl.la
mod_trigger_b4_dl_la_SOURCES = mod_trigger_b4_dl.c
diff --git a/src/mod_cml.c b/src/mod_cml.c
index acae66f6..640415b5 100644
--- a/src/mod_cml.c
+++ b/src/mod_cml.c
@@ -50,6 +50,13 @@ FREE_FUNC(mod_cml_free) {
buffer_free(s->ext);
+ buffer_free(s->mc_namespace);
+ array_free(s->mc_hosts);
+
+#if defined(HAVE_MEMCACHE_H)
+ if (s->mc) mc_free(s->mc);
+#endif
+
free(s);
}
free(p->config_storage);
@@ -77,7 +84,9 @@ SETDEFAULTS_FUNC(mod_cml_set_defaults) {
size_t i = 0;
config_values_t cv[] = {
- { "cml.extension", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
+ { "cml.extension", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
+ { "cml.memcache-hosts", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
+ { "cml.memcache-namespace", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@@ -90,14 +99,41 @@ SETDEFAULTS_FUNC(mod_cml_set_defaults) {
s = malloc(sizeof(plugin_config));
s->ext = buffer_init();
+ s->mc_hosts = array_init();
+ s->mc_namespace = buffer_init();
cv[0].destination = s->ext;
+ cv[1].destination = s->mc_hosts;
+ cv[2].destination = s->mc_namespace;
p->config_storage[i] = s;
if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
return HANDLER_ERROR;
}
+
+ if (s->mc_hosts->used) {
+#if defined(HAVE_MEMCACHE_H)
+ size_t k;
+ s->mc = mc_new();
+
+ for (k = 0; k < s->mc_hosts->used; k++) {
+ data_string *ds = (data_string *)s->mc_hosts->data[k];
+
+ if (0 != mc_server_add4(s->mc, ds->value->ptr)) {
+ log_error_write(srv, __FILE__, __LINE__, "sb",
+ "connection to host failed:",
+ ds->value);
+
+ return HANDLER_ERROR;
+ }
+ }
+#else
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "memcache support is not compiled in but cml.memcache-hosts is set, aborting");
+ return HANDLER_ERROR;
+#endif
+ }
}
return HANDLER_GO_ON;
diff --git a/src/mod_cml.h b/src/mod_cml.h
index 45b3c062..89cd09e9 100644
--- a/src/mod_cml.h
+++ b/src/mod_cml.h
@@ -7,6 +7,10 @@
#include "stream.h"
+#if defined(HAVE_MEMCACHE_H)
+#include <memcache.h>
+#endif
+
#define plugin_data mod_cache_plugin_data
typedef enum { UNSET, PART, TIMES, MINUS, PLUS, OR, AND, GT, LT, GE, LE, EQ, NE } tnode_op_t;
@@ -45,6 +49,11 @@ typedef struct {
typedef struct {
buffer *ext;
+ array *mc_hosts;
+ buffer *mc_namespace;
+#if defined(HAVE_MEMCACHE_H)
+ struct memcache *mc;
+#endif
} plugin_config;
typedef struct {
@@ -86,7 +95,8 @@ void tnode_val_array_reset(tnode_val_array *tva);
CACHE_FUNC_PROTO(f_unix_time_now);
CACHE_FUNC_PROTO(f_file_mtime);
-CACHE_FUNC_PROTO(f_memcache_get);
CACHE_FUNC_PROTO(f_memcache_exists);
+CACHE_FUNC_PROTO(f_memcache_get_string);
+CACHE_FUNC_PROTO(f_memcache_get_long);
#endif
diff --git a/src/mod_cml_funcs.c b/src/mod_cml_funcs.c
index 43db70d9..902fd5a6 100644
--- a/src/mod_cml_funcs.c
+++ b/src/mod_cml_funcs.c
@@ -61,8 +61,10 @@ CACHE_FUNC_PROTO(f_file_mtime) {
return 0;
}
+#ifdef HAVE_MEMCACHE_H
CACHE_FUNC_PROTO(f_memcache_exists) {
- UNUSED(srv);
+ char *r;
+
UNUSED(con);
if (p->params->ptr[0]->type != T_NODE_VALUE_STRING) {
@@ -74,13 +76,24 @@ CACHE_FUNC_PROTO(f_memcache_exists) {
}
tnode_prepare_long(result);
- VAL_LONG(result) = 0;
+
+ if (NULL == (r = mc_aget(p->conf.mc,
+ CONST_BUF_LEN(p->params->ptr[0]->data.str)))) {
+
+ VAL_LONG(result) = 0;
+ return 0;
+ }
+
+ free(r);
+
+ VAL_LONG(result) = 1;
return 0;
}
-CACHE_FUNC_PROTO(f_memcache_get) {
- UNUSED(srv);
+CACHE_FUNC_PROTO(f_memcache_get_string) {
+ char *r;
+
UNUSED(con);
if (p->params->ptr[0]->type != T_NODE_VALUE_STRING) {
@@ -90,8 +103,52 @@ CACHE_FUNC_PROTO(f_memcache_get) {
return -1;
}
+ log_error_write(srv, __FILE__, __LINE__, "sb",
+ "f_memcache_get: couldn't find:",
+ p->params->ptr[0]->data.str);
+
+ if (NULL == (r = mc_aget(p->conf.mc,
+ p->params->ptr[0]->data.str->ptr, p->params->ptr[0]->data.str->used - 1))) {
+ log_error_write(srv, __FILE__, __LINE__, "sb",
+ "f_memcache_get: couldn't find:",
+ p->params->ptr[0]->data.str);
+ return -1;
+ }
tnode_prepare_string(result);
- buffer_copy_string_buffer(VAL_STRING(result), p->params->ptr[0]->data.str);
+ buffer_copy_string(VAL_STRING(result), r);
+
+ free(r);
+
+ return 0;
+}
+
+CACHE_FUNC_PROTO(f_memcache_get_long) {
+ char *r;
+
+ UNUSED(con);
+
+ if (p->params->ptr[0]->type != T_NODE_VALUE_STRING) {
+ log_error_write(srv, __FILE__, __LINE__, "sd",
+ "f_memcache_get: I need a string:",
+ p->params->ptr[0]->type);
+ return -1;
+ }
+
+
+
+ if (NULL == (r = mc_aget(p->conf.mc,
+ CONST_BUF_LEN(p->params->ptr[0]->data.str)))) {
+ log_error_write(srv, __FILE__, __LINE__, "sb",
+ "f_memcache_get: couldn't find:",
+ p->params->ptr[0]->data.str);
+ return -1;
+ }
+
+ tnode_prepare_long(result);
+ VAL_LONG(result) = strtol(r, NULL, 10);
+
+ free(r);
return 0;
}
+#endif
diff --git a/src/mod_cml_logic.c b/src/mod_cml_logic.c
index 2a47e8e9..313a9ce1 100644
--- a/src/mod_cml_logic.c
+++ b/src/mod_cml_logic.c
@@ -165,8 +165,11 @@ int cache_trigger_parse(server *srv, connection *con, plugin_data *p, buffer *t
cache_trigger_functions f[] = {
{ "file.mtime", 1, f_file_mtime },
{ "unix.time.now", 0, f_unix_time_now },
+#ifdef HAVE_MEMCACHE_H
{ "memcache.exits", 1, f_memcache_exists },
- { "memcache.get", 1, f_memcache_get },
+ { "memcache.get_string", 1, f_memcache_get_string },
+ { "memcache.get_long", 1, f_memcache_get_long },
+#endif
{ NULL, 0, NULL },
};
@@ -480,12 +483,13 @@ int cache_trigger_eval(server *srv, connection *con, plugin_data *p, tnode *t) {
}
} else if (IS_STRING(t->l) && IS_STRING(t->r)) {
if (-1 == cache_ops_string(t, t->l, t->r)) {
- fprintf(stderr, "%s.%d: cache_ops_string failed\n", __FILE__, __LINE__);
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "cache_ops_string failed");
return -1;
}
} else {
- fprintf(stderr, "%s.%d: typemismatch\n",
- __FILE__, __LINE__);
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "typemismatch");
return -1;
}
@@ -505,7 +509,8 @@ int cache_trigger(server *srv, connection *con, plugin_data *p) {
}
if (-1 == cache_trigger_eval(srv, con, p, t)) {
- fprintf(stderr, "%s.%d: cache_trigger_eval failed\n", __FILE__, __LINE__);
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "cache_trigger_eval failed");
return -1;
}