From 11eba8f198deef48153c2c3cef6b5db084ca738c Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Sat, 20 Jun 2015 21:05:09 +0200 Subject: [PATCH] Added function ZakCgiMain::parse_stdin (works only with text attachments). --- configure.ac | 5 ++- src/main.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.h | 2 + tests/env.c | 65 ++++++++++++++++++++++++++++ 4 files changed, 190 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index df737bf..18a42b6 100644 --- a/configure.ac +++ b/configure.ac @@ -31,8 +31,9 @@ AC_PROG_RANLIB # Checks for libraries. PKG_CHECK_MODULES(ZAKCGI, [glib-2.0 >= 2.36 - gobject-2.0 >= 2.36 - gio-unix-2.0 >= 2.36]) + gobject-2.0 >= 2.36 + gio-2.0 >= 2.36 + gio-unix-2.0 >= 2.36]) AC_SUBST(ZAKCGI_CFLAGS) AC_SUBST(ZAKCGI_LIBS) diff --git a/src/main.c b/src/main.c index 491ac4e..b79be44 100644 --- a/src/main.c +++ b/src/main.c @@ -21,6 +21,9 @@ #endif #include +#include + +#include #include @@ -238,12 +241,129 @@ gchar l, NULL, &error); + if (error != NULL) + { + syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "error reading stdin: %s", error->message); + } } } return ret; } +GHashTable +*zak_cgi_main_parse_stdin (const gchar *buf, const gchar *boundary) +{ + GHashTable *ht; + + gchar *_boundary; + + gchar **v_boundary; + guint l_v_boundary; + + guint i_v_boundary; + + ht = NULL; + + _boundary = g_strdup_printf ("--%s", boundary); + v_boundary = g_strsplit (buf, _boundary, -1); + if (v_boundary != NULL) + { + gchar *eol; + gchar *deol; + + eol = g_strdup_printf ("%c%c", 13, 10); + deol = g_strdup_printf ("%s%s", eol, eol); + + ht = g_hash_table_new (g_str_hash, g_str_equal); + + l_v_boundary = g_strv_length (v_boundary); + for (i_v_boundary = 1; i_v_boundary < l_v_boundary - 1; i_v_boundary++) + { + gchar *first_line; + gchar *end_line; + gchar **v_content; + gchar **parts; + guint l_v_content; + guint i_v_content; + + gchar *param_name; + gchar *param_name_file; + gchar *param_value; + + GValue *gval; + + end_line = g_strstr_len (v_boundary[i_v_boundary] + 2, -1, eol); + first_line = g_strndup (v_boundary[i_v_boundary], strlen (v_boundary[i_v_boundary]) - strlen (end_line)); + + v_content = g_strsplit (first_line, ";", -1); + l_v_content = g_strv_length (v_content); + + parts = g_strsplit (v_content[1], "=", 2); + param_name = g_strndup (parts[1] + 1, strlen (parts[1]) - 2); + param_name[strlen (parts[1]) - 2] = '\0'; + g_strfreev (parts); + + if (l_v_content == 3) + { + parts = g_strsplit (v_content[2], "=", 2); + param_name_file = g_strndup (parts[1] + 1, strlen (parts[1]) - 2); + param_name_file[strlen (parts[1]) - 2] = '\0'; + g_strfreev (parts); + } + + g_strfreev (v_content); + g_free (first_line); + + end_line = g_strstr_len (v_boundary[i_v_boundary], -1, deol); + if (l_v_content == 3) + { + param_value = g_strndup (end_line + 4, strlen (end_line + 4) - 2); + param_value[ strlen (end_line + 4) - 2] = '\0'; + } + else + { + param_value = g_strdup (end_line + 4); + } + + gval = g_new0 (GValue, 1); + + if (l_v_content == 3) + { + GPtrArray *ar; + + ar = g_ptr_array_new (); + g_ptr_array_add (ar, g_strdup (param_name_file)); + g_ptr_array_add (ar, g_strdup (param_value)); + + g_value_init (gval, G_TYPE_PTR_ARRAY); + g_value_take_boxed (gval, ar); + } + else + { + g_value_init (gval, G_TYPE_STRING); + g_value_set_string (gval, g_strdup (param_value)); + } + + g_hash_table_replace (ht, g_strdup (param_name), gval); + + g_free (param_name); + g_free (param_value); + if (l_v_content == 3) + { + g_free (param_name_file); + } + } + + g_strfreev (v_boundary); + g_free (deol); + g_free (eol); + } + g_free (_boundary); + + return ht; +} + /* PRIVATE */ static void zak_cgi_main_set_property (GObject *object, diff --git a/src/main.h b/src/main.h index a672caa..0dd24d9 100644 --- a/src/main.h +++ b/src/main.h @@ -60,6 +60,8 @@ GHashTable *zak_cgi_main_get_parameters (void); gchar *zak_cgi_main_get_stdin (void); +GHashTable *zak_cgi_main_parse_stdin (const gchar *buf, const gchar *boundary); + G_END_DECLS diff --git a/tests/env.c b/tests/env.c index 3706965..acd40bd 100644 --- a/tests/env.c +++ b/tests/env.c @@ -16,6 +16,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include + +#include + #include int @@ -23,6 +28,7 @@ main (int argc, char *argv[]) { gchar *env; GString *str; + GHashTable *ht; env = zak_cgi_main_dump_env (); @@ -34,12 +40,71 @@ main (int argc, char *argv[]) g_free (env); env = zak_cgi_main_get_stdin (); + syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "stdin: %s", env); if (env != NULL) { g_string_append_printf (str, "

\n" "%s", env); + + const gchar *content_type = g_getenv ("CONTENT_TYPE"); + gchar **splitted = g_strsplit (content_type, ";", -1); + if (g_strv_length (splitted) == 2) + { + gchar **boundary = g_strsplit (splitted[1], "=", 2); + + ht = zak_cgi_main_parse_stdin (env, boundary[1]); + + GHashTableIter iter; + + gpointer key; + gpointer value; + + if (g_hash_table_size (ht) > 0) + { + g_string_append_printf (str, "

\n\n"); + + g_hash_table_iter_init (&iter, ht); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + if (G_VALUE_HOLDS (value, G_TYPE_BOXED)) + { + GPtrArray *ar = (GPtrArray *)g_value_get_boxed ((GValue *)value); + + g_string_append_printf (str, "\n", + (gchar *)key, (gchar *)g_ptr_array_index (ar, 0)); + + /* save the file to tmp */ + GFile *gfile; + GFileIOStream *iostream; + GOutputStream *ostream; + + iostream = NULL; + gfile = g_file_new_tmp (g_strdup_printf ("cgi-XXXXXX-%s", (gchar *)g_ptr_array_index (ar, 0)), + &iostream, + NULL); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream)); + g_output_stream_write (ostream, + (gchar *)g_ptr_array_index (ar, 1), + strlen ((gchar *)g_ptr_array_index (ar, 1)), + NULL, + NULL); + g_output_stream_close (ostream, NULL, NULL); + } + else + { + g_string_append_printf (str, "\n", + (gchar *)key, (gchar *)g_value_get_string ((GValue *)value)); + } + } + + g_string_append_printf (str, "
%s%s
%s%s
\n"); + } + } + g_strfreev (splitted); + g_free (env); } -- 2.49.0