From 3b0bdfeb86ce9d6a80b15e1c6ece85e3ccde605b Mon Sep 17 00:00:00 2001 From: James Booth Date: Thu, 14 May 2015 23:53:05 +0100 Subject: [PATCH] Added stanza callbacks --- .gitignore | 2 + src/server/parser.c | 122 ++++++++++++++++++++++++++++++++----- src/server/parser.h | 9 ++- src/server/server.c | 145 +++++++++++++++++++++----------------------- 4 files changed, 185 insertions(+), 93 deletions(-) diff --git a/.gitignore b/.gitignore index 416c696..53dcda0 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,6 @@ src/stamp-h1 .codelite/ stabber.project stabber.workspace +compile_commands.json +stabber.tags diff --git a/src/server/parser.c b/src/server/parser.c index 9db75c4..d89a05b 100644 --- a/src/server/parser.c +++ b/src/server/parser.c @@ -4,22 +4,106 @@ #include #include "server/parser.h" +#include "server/xmppclient.h" static int depth = 0; static int do_reset = 0; -GString *text = NULL; static XML_Parser parser; +static stream_start_func stream_start_cb = NULL; +static stream_end_func stream_end_cb = NULL; +static auth_func auth_cb = NULL; +static XMPPClient *xmppclient; + +typedef struct xmpp_attr_t { + const char *name; + const char *value; +} XMPPAttr; + +typedef struct xmpp_stanza_t { + const char *name; + GList *attrs; + GList *children; + GString *content; + struct xmpp_stanza_t *parent; +} XMPPStanza; + +static XMPPStanza *curr_stanza; +static GList *stanzas; + +void +show_stanza(XMPPStanza *stanza) +{ + printf("NAME : %s\n", stanza->name); + + if (stanza->content && stanza->content->len > 0) { + printf("CONTENT: %s\n", stanza->content->str); + } + + if (stanza->attrs) { + GList *curr_attr = stanza->attrs; + while (curr_attr) { + XMPPAttr *attr = curr_attr->data; + printf("ATTR : %s='%s'\n", attr->name, attr->value); + + curr_attr = g_list_next(curr_attr); + } + } + + if (stanza->children) { + printf("CHILDREN:\n"); + GList *curr_child = stanza->children; + while (curr_child) { + XMPPStanza *child = curr_child->data; + show_stanza(child); + curr_child = g_list_next(curr_child); + } + } +} + +void +parser_show_stanzas(void) +{ + GList *curr = stanzas; + while (curr) { + XMPPStanza *stanza = curr->data; + show_stanza(stanza); + printf("\n"); + curr = g_list_next(curr); + } +} static void start_element(void *data, const char *element, const char **attribute) { int i; - printf("LEVEL: %d\n", depth); - printf("ELEM: %s\n", element); + if (g_strcmp0(element, "stream:stream") == 0) { + stream_start_cb(xmppclient); + do_reset = 1; + return; + } - for (i = 0; attribute[i]; i += 2) { - printf(" ATTR: %s='%s'\n", attribute[i], attribute[i + 1]); + XMPPStanza *stanza = malloc(sizeof(XMPPStanza)); + stanza->name = strdup(element); + stanza->content = NULL; + stanza->children = NULL; + if (attribute[0]) { + for (i = 0; attribute[i]; i += 2) { + XMPPAttr *attr = malloc(sizeof(XMPPAttr)); + attr->name = strdup(attribute[i]); + attr->value = strdup(attribute[i+1]); + stanza->attrs = g_list_append(stanza->attrs, attr); + } + } else { + stanza->attrs = NULL; + } + + if (depth == 0) { + curr_stanza = stanza; + curr_stanza->parent = NULL; + } else { + stanza->parent = curr_stanza; + curr_stanza = stanza; } depth++; @@ -28,32 +112,38 @@ start_element(void *data, const char *element, const char **attribute) static void end_element(void *data, const char *element) { - if (text) { - printf(" TEXT: %s\n", text->str); - g_string_free(text, TRUE); - text = NULL; + depth--; + + if (depth > 0) { + curr_stanza->parent->children = g_list_append(curr_stanza->parent->children, curr_stanza); + curr_stanza = curr_stanza->parent; + } else { + stanzas = g_list_append(stanzas, curr_stanza); } - 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(""); + if (!curr_stanza->content) { + curr_stanza->content = g_string_new(""); } - g_string_append_len(text, content, length); + g_string_append_len(curr_stanza->content, content, length); } void -parser_init(void) +parser_init(XMPPClient *client, stream_start_func startcb, stream_end_func endcb, auth_func authcb) { + xmppclient = client; + stream_start_cb = startcb; + stream_end_cb = endcb; + auth_cb = authcb; + parser = XML_ParserCreate(NULL); XML_SetElementHandler(parser, start_element, end_element); XML_SetCharacterDataHandler(parser, handle_data); @@ -76,7 +166,7 @@ parser_reset(void) { if (do_reset == 1) { parser_close(); - parser_init(); + parser_init(xmppclient, stream_start_cb, stream_end_cb, auth_cb); do_reset = 0; } } diff --git a/src/server/parser.h b/src/server/parser.h index 46123c2..de2b1eb 100644 --- a/src/server/parser.h +++ b/src/server/parser.h @@ -1,9 +1,16 @@ #ifndef __H_PARSER #define __H_PARSER -void parser_init(void); +#include "server/xmppclient.h" + +typedef void (*stream_start_func)(void * const userdata); +typedef void (*stream_end_func)(void * const userdata); +typedef void (*auth_func)(void * const userdata); + +void parser_init(XMPPClient *client, stream_start_func startcb, stream_end_func endcb, auth_func authcb); int parser_feed(char *chunk, int len); void parser_close(void); void parser_reset(void); +void parser_show_stanzas(void); #endif diff --git a/src/server/server.c b/src/server/server.c index bbf120b..d70698d 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -9,12 +9,14 @@ #include "server/parser.h" #define XML_START "" -#define STREAM_REQ "" -#define STREAM_RESP "" + +#define STREAM_RESP "" #define FEATURES "" + #define AUTH_REQ "stabberpasswordprofanity" #define AUTH_RESP "" -#define END_STREAM "" + +#define STREAM_END "" int listen_for_xmlstart(XMPPClient *client) @@ -26,6 +28,8 @@ listen_for_xmlstart(XMPPClient *client) GString *stream = g_string_new(""); errno = 0; while ((read_size = recv(client->sock, buf, 1, 0)) > 0) { + printf("%c", buf[0]); + fflush(stdout); g_string_append_len(stream, buf, read_size); memset(buf, 0, sizeof(buf)); if (g_strcmp0(stream->str, XML_START) == 0) { @@ -48,13 +52,13 @@ listen_for_xmlstart(XMPPClient *client) return -1; } - printf("RECV: %s\n", XML_START); + printf("\n"); fflush(stdout); return 0; } int -listen_for(XMPPClient *client, const char * const stanza) +listen_to(XMPPClient *client) { int read_size; char buf[2]; @@ -63,11 +67,12 @@ listen_for(XMPPClient *client, const char * const stanza) 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_strcmp0(stream->str, stanza) == 0) { - break; - } } // error @@ -85,8 +90,6 @@ listen_for(XMPPClient *client, const char * const stanza) return -1; } - printf("RECV: %s\n", stanza); - fflush(stdout); return 0; } @@ -104,75 +107,32 @@ send_to(XMPPClient *client, const char * const stanza) fflush(stdout); } -int -debug_client(XMPPClient *client) +void +stream_start_callback(void *userdata) { - int read_size; - char buf[2]; - memset(buf, 0, sizeof(buf)); - - GString *stream = g_string_new(""); - errno = 0; - while ((read_size = recv(client->sock, buf, 1, 0)) > 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)) { - break; - } - } - - // error - if (read_size == -1) { - perror("Error receiving on connection"); - xmppclient_end_session(client); - g_string_free(stream, TRUE); - return -1; - - // client closed - } else if (read_size == 0) { - printf("\n%s:%d - Client disconnected.\n", client->ip, client->port); - xmppclient_end_session(client); - g_string_free(stream, TRUE); - return -1; - } - - return 0; -} - -void connection_handler(XMPPClient *client) -{ - int res = listen_for_xmlstart(client); - if (res == -1) { - return; - } - - res = listen_for(client, STREAM_REQ); - if (res == -1) { - return; - } - + printf("\n--> Stream start callback fired\n"); + XMPPClient *client = (XMPPClient*)userdata; + send_to(client, XML_START); send_to(client, STREAM_RESP); send_to(client, FEATURES); + printf("RECV: "); +} - res = listen_for(client, AUTH_REQ); - if (res == -1) { - return; - } - +void +auth_callback(void *userdata) +{ + printf("\n--> Auth callback fired\n"); + XMPPClient *client = (XMPPClient*)userdata; send_to(client, AUTH_RESP); + printf("RECV: "); +} - res = debug_client(client); - if (res == -1) { - return; - } - - printf("\nEnd stream receieved\n"); - xmppclient_end_session(client); - fflush(stdout); - return; +void +stream_end_callback(void *userdata) +{ + printf("\n--> Stream end callback fired\n"); + XMPPClient *client = (XMPPClient*)userdata; + send_to(client, STREAM_END); } int main(int argc , char *argv[]) @@ -239,8 +199,6 @@ int main(int argc , char *argv[]) return 0; } - parser_init(); - puts("Waiting for incoming connections..."); // connection accept @@ -253,8 +211,43 @@ int main(int argc , char *argv[]) } XMPPClient *client = xmppclient_new(client_addr, client_socket); + parser_init(client, stream_start_callback, stream_end_callback, auth_callback); + printf("RECV: "); + int res = listen_for_xmlstart(client); + if (res == -1) { + return 0; + } - connection_handler(client); + printf("RECV: "); + listen_to(client); + + parser_show_stanzas(); + +// +// res = listen_for(client, STREAM_REQ); +// if (res == -1) { +// return; +// } +// +// send_to(client, STREAM_RESP); +// send_to(client, FEATURES); +// +// res = listen_for(client, AUTH_REQ); +// if (res == -1) { +// return; +// } +// +// send_to(client, AUTH_RESP); +// +// res = debug_client(client); +// if (res == -1) { +// return; +// } +// +// printf("\nEnd stream receieved\n"); +// xmppclient_end_session(client); +// fflush(stdout); +// return; parser_close();