From 43f4080339c6f11fff432d5358d7538bf5136bf6 Mon Sep 17 00:00:00 2001 From: James Booth Date: Tue, 12 May 2015 21:24:13 +0100 Subject: [PATCH] Parse XML --- .gitignore | 7 +++- Makefile.am | 2 +- configure.ac | 7 +++- src/server/parser.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ src/server/parser.h | 9 +++++ src/server/server.c | 22 ++++++++--- 6 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 src/server/parser.c create mode 100644 src/server/parser.h diff --git a/.gitignore b/.gitignore index fac8c0f..416c696 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +core +server Makefile Makefile.in aclocal.m4 @@ -13,11 +15,12 @@ src/server/.deps/ src/server/.dirstamp src/server/clients.o src/server/server.o +src/server/parser.o +src/server/xmppclient.o + src/stamp-h1 .codelite/ stabber.project stabber.workspace -server - diff --git a/Makefile.am b/Makefile.am index 9952823..02615d3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,2 +1,2 @@ bin_PROGRAMS = server -server_SOURCES = src/server/server.c src/server/xmppclient.h src/server/xmppclient.c +server_SOURCES = src/server/server.c src/server/xmppclient.h src/server/xmppclient.c src/server/parser.h src/server/parser.c diff --git a/configure.ac b/configure.ac index 1533ea7..edd91c0 100644 --- a/configure.ac +++ b/configure.ac @@ -14,10 +14,13 @@ AC_PROG_CC PKG_CHECK_MODULES([glib], [glib-2.0 >= 2.26], [], [AC_MSG_ERROR([glib 2.26 or higher is required])]) +PKG_CHECK_MODULES([expat], [expat >= 2.0.0], [], + [AC_MSG_ERROR([expat 2.0.0 or higher is required])]) + AM_CFLAGS="-Wall -Wno-deprecated-declarations" AM_CFLAGS="$AM_CFLAGS -Wunused -Werror" -AM_CPPFLAGS="$AM_CPPFLAGS $glib_CFLAGS" -LIBS="$glib_LIBS $LIBS" +AM_CPPFLAGS="$AM_CPPFLAGS $glib_CFLAGS $expat_CFLAGS" +LIBS="$glib_LIBS $expat_LIBS $LIBS" AC_SUBST(AM_CFLAGS) AC_SUBST(AM_CPPFLAGS) diff --git a/src/server/parser.c b/src/server/parser.c new file mode 100644 index 0000000..08f34c9 --- /dev/null +++ b/src/server/parser.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include + +#include "server/parser.h" + +static int depth = 0; +static int do_reset = 0; +GString *text = NULL; +static XML_Parser parser; + +static void +start_element(void *data, const char *element, const char **attribute) +{ + int i; + + printf("LEVEL: %d\n", depth); + printf("ELEM: %s\n", element); + + for (i = 0; attribute[i]; i += 2) { + printf(" ATTR: %s='%s'\n", attribute[i], attribute[i + 1]); + } + + depth++; +} + +static void +end_element(void *data, const char *element) +{ +// int i; +// for (i = 0; i < depth; i++) { +// printf(" "); +// } + +// if (last_content) { +// printf("%s Contents: \"%s\"\n", element, last_content); +// } +// + if (text) { + printf(" TEXT: %s\n", text->str); + g_string_free(text, TRUE); + text = NULL; + } + + depth--; + if (depth == 0) { + do_reset = 1; + printf("\n"); + } +} + +static void +handle_data(void *data, const char *content, int length) +{ + if (!text) { + text = g_string_new(""); + } + + g_string_append_len(text, content, length); +} + +void +parser_init(void) +{ + parser = XML_ParserCreate(NULL); + XML_SetElementHandler(parser, start_element, end_element); + XML_SetCharacterDataHandler(parser, handle_data); +} + +int +parser_feed(char *chunk, int len) +{ + return XML_Parse(parser, chunk, len, 0); +} + +void +parser_close(void) +{ + XML_ParserFree(parser); +} + +void +parser_reset(void) +{ + if (do_reset == 1) { + parser_close(); + parser_init(); + do_reset = 0; + } +} diff --git a/src/server/parser.h b/src/server/parser.h new file mode 100644 index 0000000..46123c2 --- /dev/null +++ b/src/server/parser.h @@ -0,0 +1,9 @@ +#ifndef __H_PARSER +#define __H_PARSER + +void parser_init(void); +int parser_feed(char *chunk, int len); +void parser_close(void); +void parser_reset(void); + +#endif diff --git a/src/server/server.c b/src/server/server.c index d70f36d..372137a 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -6,8 +6,10 @@ #include #include "server/xmppclient.h" +#include "server/parser.h" -#define STREAM_REQ "" +#define XML_START "" +#define STREAM_REQ "" #define STREAM_RESP "" #define FEATURES "" #define AUTH_REQ "stabberpasswordprofanity" @@ -72,14 +74,12 @@ debug_client(XMPPClient *client) char buf[2]; memset(buf, 0, sizeof(buf)); - printf("RECV: "); - fflush(stdout); - GString *stream = g_string_new(""); errno = 0; while ((read_size = recv(client->sock, buf, 1, 0)) > 0) { - printf("%c", buf[0]); + parser_feed(buf, 1); fflush(stdout); + parser_reset(); g_string_append_len(stream, buf, read_size); memset(buf, 0, sizeof(buf)); if (g_str_has_suffix(stream->str, END_STREAM)) { @@ -107,7 +107,12 @@ debug_client(XMPPClient *client) void connection_handler(XMPPClient *client) { - int res = listen_for(client, STREAM_REQ); + int res = listen_for(client, XML_START); + if (res == -1) { + return; + } + + res = listen_for(client, STREAM_REQ); if (res == -1) { return; } @@ -196,6 +201,9 @@ int main(int argc , char *argv[]) perror("Listen failed"); return 0; } + + parser_init(); + puts("Waiting for incoming connections..."); // connection accept @@ -211,6 +219,8 @@ int main(int argc , char *argv[]) connection_handler(client); + parser_close(); + while (recv(listen_socket, NULL, 1, 0) > 0) {} shutdown(listen_socket, 2); close(listen_socket);