aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2011-06-09 17:33:07 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2011-06-09 17:33:07 +0400
commit25591d79bad7c201ee12717cde3c6c39e39e48e5 (patch)
tree996d5e14b47ee8dd11e826d1c02767f7e513bf1a
parent8c23f93d02fb111baa27e8141b13d6fe658bb155 (diff)
downloadrspamd-25591d79bad7c201ee12717cde3c6c39e39e48e5.tar.gz
rspamd-25591d79bad7c201ee12717cde3c6c39e39e48e5.zip
* Add api for creating XML-rpc calls
-rw-r--r--src/lua/lua_xmlrpc.c100
-rw-r--r--src/printf.c12
-rw-r--r--src/printf.h14
-rw-r--r--src/util.h10
4 files changed, 119 insertions, 17 deletions
diff --git a/src/lua/lua_xmlrpc.c b/src/lua/lua_xmlrpc.c
index 7f08eef34..f0ba2d6c0 100644
--- a/src/lua/lua_xmlrpc.c
+++ b/src/lua/lua_xmlrpc.c
@@ -25,9 +25,11 @@
LUA_FUNCTION_DEF (xmlrpc, parse_reply);
+LUA_FUNCTION_DEF (xmlrpc, make_request);
static const struct luaL_reg xmlrpclib_m[] = {
LUA_INTERFACE_DEF (xmlrpc, parse_reply),
+ LUA_INTERFACE_DEF (xmlrpc, make_request),
{"__tostring", lua_class_tostring},
{NULL, NULL}
};
@@ -362,7 +364,7 @@ xmlrpc_error (GMarkupParseContext *context, GError *error, gpointer user_data)
msg_err ("xmlrpc parser error: %s", error->message, ud->parser_state);
}
-gint
+static gint
lua_xmlrpc_parse_reply (lua_State *L)
{
const gchar *data;
@@ -395,6 +397,102 @@ lua_xmlrpc_parse_reply (lua_State *L)
return 1;
}
+static gint
+lua_xmlrpc_parse_table (lua_State *L, gint pos, gchar *databuf, gint pr, gsize size)
+{
+ gint r = pr;
+
+ r += rspamd_snprintf (databuf + r, size - r, "<struct>");
+ lua_pushnil (L); /* first key */
+ while (lua_next (L, pos) != 0) {
+ /* uses 'key' (at index -2) and 'value' (at index -1) */
+ if (lua_type (L, -2) != LUA_TSTRING) {
+ /* Ignore non sting keys */
+ lua_pop(L, 1);
+ continue;
+ }
+ r += rspamd_snprintf (databuf + r, size - r, "<member><name>%s</name><value>",
+ lua_tostring (L, -2));
+ switch (lua_type (L, -1)) {
+ case LUA_TNUMBER:
+ r += rspamd_snprintf (databuf + r, size - r, "<int>%d</int>",
+ lua_tointeger (L, -1));
+ break;
+ case LUA_TBOOLEAN:
+ r += rspamd_snprintf (databuf + r, size - r, "<boolean>%d</boolean>",
+ lua_toboolean (L, -1) ? 1 : 0);
+ break;
+ case LUA_TSTRING:
+ r += rspamd_snprintf (databuf + r, size - r, "<string>%s</string>",
+ lua_tostring (L, -1));
+ break;
+ case LUA_TTABLE:
+ /* Recursive call */
+ r += lua_xmlrpc_parse_table (L, -1, databuf, r, sizeof (databuf));
+ break;
+ }
+ r += rspamd_snprintf (databuf + r, size - r, "</value></member>");
+ /* removes 'value'; keeps 'key' for next iteration */
+ lua_pop(L, 1);
+ }
+ r += rspamd_snprintf (databuf + r, size - r, "</struct>");
+
+ return r - pr;
+}
+
+/*
+ * Internal limitation: xmlrpc request must NOT be more than
+ * BUFSIZ * 2 (16384 bytes)
+ */
+static gint
+lua_xmlrpc_make_request (lua_State *L)
+{
+ gchar databuf[BUFSIZ * 2];
+ const gchar *func;
+ gint r, top, i;
+
+ func = luaL_checkstring (L, 1);
+
+ if (func) {
+ r = rspamd_snprintf (databuf, sizeof(databuf),
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<methodCall><methodName>%s</methodName><params>",
+ func);
+ /* Extract arguments */
+ top = lua_gettop (L);
+ /* Get additional options */
+ for (i = 2; i <= top; i++) {
+ r += rspamd_snprintf (databuf + r, sizeof (databuf) - r, "<param><value>");
+ switch (lua_type (L, i)) {
+ case LUA_TNUMBER:
+ r += rspamd_snprintf (databuf + r, sizeof (databuf) - r, "<int>%d</int>",
+ lua_tointeger (L, i));
+ break;
+ case LUA_TBOOLEAN:
+ r += rspamd_snprintf (databuf + r, sizeof (databuf) - r, "<boolean>%d</boolean>",
+ lua_toboolean (L, i) ? 1 : 0);
+ break;
+ case LUA_TSTRING:
+ r += rspamd_snprintf (databuf + r, sizeof (databuf) - r, "<string>%s</string>",
+ lua_tostring (L, i));
+ break;
+ case LUA_TTABLE:
+ r += lua_xmlrpc_parse_table (L, i, databuf, r, sizeof (databuf));
+ break;
+ }
+ r += rspamd_snprintf (databuf + r, sizeof (databuf) - r, "</value></param>");
+ }
+
+ r += rspamd_snprintf (databuf + r, sizeof (databuf) - r, "</params></methodCall>");
+ lua_pushlstring (L, databuf, r);
+ }
+ else {
+ lua_pushnil (L);
+ }
+
+ return 1;
+}
+
gint
luaopen_xmlrpc (lua_State * L)
{
diff --git a/src/printf.c b/src/printf.c
index 7bdb61cc3..a8bf0fdb1 100644
--- a/src/printf.c
+++ b/src/printf.c
@@ -138,7 +138,7 @@ rspamd_sprintf (gchar *buf, const gchar *fmt, ...)
gint
-rspamd_snprintf (gchar *buf, size_t max, const gchar *fmt, ...)
+rspamd_snprintf (gchar *buf, glong max, const gchar *fmt, ...)
{
gchar *p;
va_list args;
@@ -152,13 +152,17 @@ rspamd_snprintf (gchar *buf, size_t max, const gchar *fmt, ...)
}
gchar *
-rspamd_escape_string (gchar *dst, const gchar *src, gsize len)
+rspamd_escape_string (gchar *dst, const gchar *src, glong len)
{
gchar *buf = dst, *last = dst + len;
guint8 c;
const gchar *p = src;
gunichar uc;
+ if (len <= 0) {
+ return dst;
+ }
+
while (*p && buf < last) {
/* Detect utf8 */
uc = g_utf8_get_char_validated (p, last - buf);
@@ -202,7 +206,7 @@ rspamd_escape_string (gchar *dst, const gchar *src, gsize len)
}
gchar *
-rspamd_vsnprintf (gchar *buf, size_t max, const gchar *fmt, va_list args)
+rspamd_vsnprintf (gchar *buf, glong max, const gchar *fmt, va_list args)
{
gchar *p, zero, *last;
gint d;
@@ -213,7 +217,7 @@ rspamd_vsnprintf (gchar *buf, size_t max, const gchar *fmt, va_list args)
guint width, sign, hex, max_width, frac_width, i;
f_str_t *v;
- if (max == 0) {
+ if (max <= 0) {
return buf;
}
diff --git a/src/printf.h b/src/printf.h
index 74f665a2d..0d41bdc80 100644
--- a/src/printf.h
+++ b/src/printf.h
@@ -55,7 +55,17 @@
*/
gint rspamd_sprintf (gchar *buf, const gchar *fmt, ...);
gint rspamd_fprintf (FILE *f, const gchar *fmt, ...);
-gint rspamd_snprintf (gchar *buf, size_t max, const gchar *fmt, ...);
-gchar *rspamd_vsnprintf (gchar *buf, size_t max, const gchar *fmt, va_list args);
+gint rspamd_snprintf (gchar *buf, glong max, const gchar *fmt, ...);
+gchar *rspamd_vsnprintf (gchar *buf, glong max, const gchar *fmt, va_list args);
+
+/*
+ * Escape rspamd string to write it to log file or other 7 bit prefferable places
+ *
+ * @param dst destination string
+ * @param src source string
+ * @param len length of destination buffer
+ * @return pointer to end of buffer
+ */
+gchar * rspamd_escape_string (gchar *dst, const gchar *src, glong len);
#endif /* PRINTF_H_ */
diff --git a/src/util.h b/src/util.h
index 1c29ba91d..73d96c759 100644
--- a/src/util.h
+++ b/src/util.h
@@ -120,16 +120,6 @@ void g_ptr_array_unref (GPtrArray *array);
gsize rspamd_strlcpy (gchar *dst, const gchar *src, gsize siz);
/*
- * Escape rspamd string to write it to log file or other 7 bit prefferable places
- *
- * @param dst destination string
- * @param src source string
- * @param len length of destination buffer
- * @return pointer to end of buffer
- */
-gchar * rspamd_escape_string (gchar *dst, const gchar *src, gsize len);
-
-/*
* Convert process type to its name
*
* @param type numeric type