]> source.dussan.org Git - rspamd.git/commitdiff
* Add api for creating XML-rpc calls
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 9 Jun 2011 13:33:07 +0000 (17:33 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 9 Jun 2011 13:33:07 +0000 (17:33 +0400)
src/lua/lua_xmlrpc.c
src/printf.c
src/printf.h
src/util.h

index 7f08eef34d0a51d109563c0bd19ebde8ed7236b1..f0ba2d6c035b0b3c3c80b65537d47f935f0d8836 100644 (file)
 
 
 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)
 {
index 7bdb61cc34cf7d6028c9ba2b53df578ddc8b1166..a8bf0fdb103ca8f7c961c988cce216b35e5b6d53 100644 (file)
@@ -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;
        }
 
index 74f665a2df61ae96fca71838e3ff12d7d1e9a4e3..0d41bdc8099becde3c5a5366d42926f6f64c98d6 100644 (file)
  */
 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_ */
index 1c29ba91d14c94e09850c064b58ab3c09c08a8fe..73d96c7595c6c84bb9cd65be14c60f1fe7cccf14 100644 (file)
@@ -119,16 +119,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
  *