Minor code style changes

This commit is contained in:
James Booth
2016-11-08 23:17:59 +00:00
parent 3c9df4390c
commit ed75087e44
8 changed files with 436 additions and 403 deletions

View File

@@ -86,16 +86,19 @@ send_response(struct MHD_Connection* conn, const char* body, int status_code)
response = MHD_create_response_from_data(0, NULL, MHD_NO, MHD_YES); response = MHD_create_response_from_data(0, NULL, MHD_NO, MHD_YES);
} }
if (!response) if (!response) {
return MHD_NO; return MHD_NO;
}
int ret = MHD_queue_response(conn, status_code, response); int ret = MHD_queue_response(conn, status_code, response);
MHD_destroy_response(response); MHD_destroy_response(response);
return ret; return ret;
} }
int connection_cb(void* cls, struct MHD_Connection* conn, const char* url, const char* method, int
const char* version, const char* data, size_t* size, void** con_cls) connection_cb(void* cls, struct MHD_Connection* conn, const char* url, const char* method, const char* version,
const char* data, size_t* size, void** con_cls)
{ {
#ifdef PLATFORM_OSX #ifdef PLATFORM_OSX
pthread_setname_np("http"); pthread_setname_np("http");
@@ -129,18 +132,18 @@ int connection_cb(void* cls, struct MHD_Connection* conn, const char* url, const
*size = 0; *size = 0;
return MHD_YES; return MHD_YES;
} else { }
const char *id = NULL; const char *id = NULL;
const char *query = NULL; const char *query = NULL;
int res = 0;
switch (con_info->stbbr_op) { switch (con_info->stbbr_op) {
case STBBR_OP_SEND: case STBBR_OP_SEND:
{
server_send(con_info->body->str); server_send(con_info->body->str);
return send_response(conn, NULL, MHD_HTTP_OK); return send_response(conn, NULL, MHD_HTTP_OK);
}
case STBBR_OP_FOR: case STBBR_OP_FOR:
{
id = MHD_lookup_connection_value(conn, MHD_GET_ARGUMENT_KIND, "id"); id = MHD_lookup_connection_value(conn, MHD_GET_ARGUMENT_KIND, "id");
query = MHD_lookup_connection_value(conn, MHD_GET_ARGUMENT_KIND, "query"); query = MHD_lookup_connection_value(conn, MHD_GET_ARGUMENT_KIND, "query");
if (id && query) { if (id && query) {
@@ -158,26 +161,20 @@ int connection_cb(void* cls, struct MHD_Connection* conn, const char* url, const
} }
return send_response(conn, NULL, MHD_HTTP_BAD_REQUEST); return send_response(conn, NULL, MHD_HTTP_BAD_REQUEST);
}
case STBBR_OP_VERIFY: case STBBR_OP_VERIFY:
{ res = verify_any(con_info->body->str, TRUE);
int res = verify_any(con_info->body->str, TRUE);
if (res) { if (res) {
return send_response(conn, "true", MHD_HTTP_OK); return send_response(conn, "true", MHD_HTTP_OK);
} else { } else {
return send_response(conn, "false", MHD_HTTP_OK); return send_response(conn, "false", MHD_HTTP_OK);
} }
}
default: default:
{
return send_response(conn, NULL, MHD_HTTP_BAD_REQUEST); return send_response(conn, NULL, MHD_HTTP_BAD_REQUEST);
} }
} }
}
}
void request_completed(void* cls, struct MHD_Connection* conn, void
void** con_cls, enum MHD_RequestTerminationCode termcode) request_completed(void* cls, struct MHD_Connection* conn, void** con_cls, enum MHD_RequestTerminationCode termcode)
{ {
ConnectionInfo *con_info = (ConnectionInfo*) *con_cls; ConnectionInfo *con_info = (ConnectionInfo*) *con_cls;
if (con_info) { if (con_info) {

View File

@@ -41,75 +41,11 @@ static gboolean logready = FALSE;
static stbbr_log_t minlevel; static stbbr_log_t minlevel;
pthread_mutex_t loglock; pthread_mutex_t loglock;
gchar * static gchar* _xdg_get_data_home(void);
_xdg_get_data_home(void) static gchar* _get_main_log_file(void);
{ static gboolean _create_dir(char *name);
gchar *xdg_data_home = getenv("XDG_DATA_HOME"); static gboolean _mkdir_recursive(const char *dir);
if (xdg_data_home) static char* _levelstr(stbbr_log_t loglevel);
g_strstrip(xdg_data_home);
if (xdg_data_home && (strcmp(xdg_data_home, "") != 0)) {
return strdup(xdg_data_home);
} else {
GString *default_path = g_string_new(getenv("HOME"));
g_string_append(default_path, "/.local/share");
gchar *result = strdup(default_path->str);
g_string_free(default_path, TRUE);
return result;
}
}
static gchar *
_get_main_log_file(void)
{
gchar *xdg_data = _xdg_get_data_home();
GString *logfile = g_string_new(xdg_data);
g_string_append(logfile, "/stabber/logs/stabber");
g_string_append(logfile, ".log");
gchar *result = strdup(logfile->str);
free(xdg_data);
g_string_free(logfile, TRUE);
return result;
}
gboolean
_create_dir(char *name)
{
struct stat sb;
if (stat(name, &sb) != 0) {
if (errno != ENOENT || mkdir(name, S_IRWXU) != 0) {
return FALSE;
}
} else {
if ((sb.st_mode & S_IFDIR) != S_IFDIR) {
return FALSE;
}
}
return TRUE;
}
gboolean
_mkdir_recursive(const char *dir)
{
int i;
gboolean result = TRUE;
for (i = 1; i <= strlen(dir); i++) {
if (dir[i] == '/' || dir[i] == '\0') {
gchar *next_dir = g_strndup(dir, i);
result = _create_dir(next_dir);
g_free(next_dir);
if (!result) {
break;
}
}
}
return result;
}
void void
log_init(stbbr_log_t loglevel) log_init(stbbr_log_t loglevel)
@@ -131,22 +67,13 @@ log_init(stbbr_log_t loglevel)
pthread_mutex_unlock(&loglock); pthread_mutex_unlock(&loglock);
} }
static char*
_levelstr(stbbr_log_t loglevel)
{
switch (loglevel) {
case STBBR_LOGERROR: return "ERR";
case STBBR_LOGWARN: return "WRN";
case STBBR_LOGINFO: return "INF";
case STBBR_LOGDEBUG: return "DBG";
default: return "";
}
}
void void
log_println(stbbr_log_t loglevel, const char * const msg, ...) log_println(stbbr_log_t loglevel, const char * const msg, ...)
{ {
if (logready && loglevel >= minlevel) { if (!logready || loglevel < minlevel) {
return;
}
pthread_mutex_lock(&loglock); pthread_mutex_lock(&loglock);
va_list arg; va_list arg;
va_start(arg, msg); va_start(arg, msg);
@@ -174,7 +101,6 @@ log_println(stbbr_log_t loglevel, const char * const msg, ...)
va_end(arg); va_end(arg);
pthread_mutex_unlock(&loglock); pthread_mutex_unlock(&loglock);
} }
}
void void
log_close(void) log_close(void)
@@ -186,3 +112,86 @@ log_close(void)
logready = FALSE; logready = FALSE;
pthread_mutex_unlock(&loglock); pthread_mutex_unlock(&loglock);
} }
static gchar*
_xdg_get_data_home(void)
{
gchar *xdg_data_home = getenv("XDG_DATA_HOME");
if (xdg_data_home) {
g_strstrip(xdg_data_home);
}
if (xdg_data_home && (strcmp(xdg_data_home, "") != 0)) {
return strdup(xdg_data_home);
}
GString *default_path = g_string_new(getenv("HOME"));
g_string_append(default_path, "/.local/share");
gchar *result = strdup(default_path->str);
g_string_free(default_path, TRUE);
return result;
}
static gchar*
_get_main_log_file(void)
{
gchar *xdg_data = _xdg_get_data_home();
GString *logfile = g_string_new(xdg_data);
g_string_append(logfile, "/stabber/logs/stabber");
g_string_append(logfile, ".log");
gchar *result = strdup(logfile->str);
free(xdg_data);
g_string_free(logfile, TRUE);
return result;
}
static gboolean
_create_dir(char *name)
{
struct stat sb;
if (stat(name, &sb) != 0) {
if (errno != ENOENT || mkdir(name, S_IRWXU) != 0) {
return FALSE;
}
} else {
if ((sb.st_mode & S_IFDIR) != S_IFDIR) {
return FALSE;
}
}
return TRUE;
}
static gboolean
_mkdir_recursive(const char *dir)
{
int i;
gboolean result = TRUE;
for (i = 1; i <= strlen(dir); i++) {
if (dir[i] == '/' || dir[i] == '\0') {
gchar *next_dir = g_strndup(dir, i);
result = _create_dir(next_dir);
g_free(next_dir);
if (!result) {
break;
}
}
}
return result;
}
static char*
_levelstr(stbbr_log_t loglevel)
{
switch (loglevel) {
case STBBR_LOGERROR: return "ERR";
case STBBR_LOGWARN: return "WRN";
case STBBR_LOGINFO: return "INF";
case STBBR_LOGDEBUG: return "DBG";
default: return "";
}
}

View File

@@ -76,11 +76,12 @@ prime_get_passwd(void)
void void
prime_for_id(const char *id, char *stream) prime_for_id(const char *id, char *stream)
{ {
if (idstubs) { if (!idstubs) {
log_println(STBBR_LOGDEBUG, "Received stub for id: %s, stanza: %s", id, stream); return;
g_hash_table_insert(idstubs, strdup(id), strdup(stream));
} }
log_println(STBBR_LOGDEBUG, "Received stub for id: %s, stanza: %s", id, stream);
g_hash_table_insert(idstubs, strdup(id), strdup(stream));
} }
char* char*
@@ -92,13 +93,14 @@ prime_get_for_id(const char *id)
void void
prime_for_query(const char *query, char *stream) prime_for_query(const char *query, char *stream)
{ {
if (querystubs) { if (!querystubs) {
log_println(STBBR_LOGDEBUG, "Received stub for query: %s, stanza: %s", query, stream); return;
}
log_println(STBBR_LOGDEBUG, "Received stub for query: %s, stanza: %s", query, stream);
XMPPStanza *stanza = stanza_parse(stream); XMPPStanza *stanza = stanza_parse(stream);
g_hash_table_insert(querystubs, strdup(query), stanza); g_hash_table_insert(querystubs, strdup(query), stanza);
} }
}
XMPPStanza* XMPPStanza*
prime_get_for_query(const char *query) prime_get_for_query(const char *query)

View File

@@ -53,17 +53,17 @@
#define STREAM_END "</stream:stream>" #define STREAM_END "</stream:stream>"
pthread_mutex_t send_queue_lock; pthread_mutex_t send_queue_lock;
static GList *send_queue; static GList *send_queue;
static XMPPClient *client; static XMPPClient *client;
static void _shutdown(void);
static int listen_socket; static int listen_socket;
static pthread_t server_thread; static pthread_t server_thread;
static gboolean kill_recv = FALSE; static gboolean kill_recv = FALSE;
static gboolean httpapi_run = FALSE; static gboolean httpapi_run = FALSE;
static void _shutdown(void);
static void* _start_server_cb(void* userdata);
void void
write_stream(const char * const stream) write_stream(const char * const stream)
{ {
@@ -225,24 +225,28 @@ void
id_callback(const char *id) id_callback(const char *id)
{ {
char *stream = prime_get_for_id(id); char *stream = prime_get_for_id(id);
if (stream) { if (!stream) {
return;
}
log_println(STBBR_LOGINFO, "--> ID callback fired for '%s'", id); log_println(STBBR_LOGINFO, "--> ID callback fired for '%s'", id);
write_stream(stream); write_stream(stream);
} }
}
void void
query_callback(const char *query, const char *id) query_callback(const char *query, const char *id)
{ {
XMPPStanza *stanza = prime_get_for_query(query); XMPPStanza *stanza = prime_get_for_query(query);
if (stanza) { if (!stanza) {
return;
}
log_println(STBBR_LOGINFO, "--> QUERY callback fired for '%s'", query); log_println(STBBR_LOGINFO, "--> QUERY callback fired for '%s'", query);
stanza_set_id(stanza, id); stanza_set_id(stanza, id);
char *stream = stanza_to_string(stanza); char *stream = stanza_to_string(stanza);
write_stream(stream); write_stream(stream);
free(stream); free(stream);
} }
}
void void
server_wait_for(char *id) server_wait_for(char *id)
@@ -258,54 +262,6 @@ server_wait_for(char *id)
} }
} }
void*
_start_server_cb(void* userdata)
{
#ifdef PLATFORM_OSX
pthread_setname_np("stbr");
#else
prctl(PR_SET_NAME, "stbr");
#endif
struct sockaddr_in client_addr;
// listen socket non blocking
int res = fcntl(listen_socket, F_SETFL, fcntl(listen_socket, F_GETFL, 0) | O_NONBLOCK);
if (res == -1) {
log_println(STBBR_LOGERROR, "Error setting nonblocking on listen socket: %s", strerror(errno));
return NULL;
}
log_println(STBBR_LOGINFO, "Waiting for incoming connection...");
// wait for connection
int c = sizeof(struct sockaddr_in);
int client_socket;
errno = 0;
while ((client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, (socklen_t*)&c)) == -1) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
log_println(STBBR_LOGERROR, "Accept failed: %s", strerror(errno));
return NULL;
}
errno = 0;
usleep(1000 * 5);
}
// client socket non blocking
res = fcntl(client_socket, F_SETFL, fcntl(client_socket, F_GETFL, 0) | O_NONBLOCK);
if (res == -1) {
log_println(STBBR_LOGERROR, "Error setting nonblocking on client socket: %s", strerror(errno));
return NULL;
}
client = xmppclient_new(client_addr, client_socket);
parser_init(stream_start_callback, auth_callback, id_callback, query_callback);
read_stream();
return NULL;
}
int int
server_run(stbbr_log_t loglevel, int port, int httpport) server_run(stbbr_log_t loglevel, int port, int httpport)
{ {
@@ -401,11 +357,61 @@ server_send(char *stream)
void void
server_stop(void) server_stop(void)
{ {
if (!kill_recv) { if (kill_recv) {
return;
}
log_println(STBBR_LOGINFO, "SERVER STOP"); log_println(STBBR_LOGINFO, "SERVER STOP");
kill_recv = TRUE; kill_recv = TRUE;
pthread_join(server_thread, NULL); pthread_join(server_thread, NULL);
} }
static void*
_start_server_cb(void* userdata)
{
#ifdef PLATFORM_OSX
pthread_setname_np("stbr");
#else
prctl(PR_SET_NAME, "stbr");
#endif
struct sockaddr_in client_addr;
// listen socket non blocking
int res = fcntl(listen_socket, F_SETFL, fcntl(listen_socket, F_GETFL, 0) | O_NONBLOCK);
if (res == -1) {
log_println(STBBR_LOGERROR, "Error setting nonblocking on listen socket: %s", strerror(errno));
return NULL;
}
log_println(STBBR_LOGINFO, "Waiting for incoming connection...");
// wait for connection
int c = sizeof(struct sockaddr_in);
int client_socket;
errno = 0;
while ((client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, (socklen_t*)&c)) == -1) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
log_println(STBBR_LOGERROR, "Accept failed: %s", strerror(errno));
return NULL;
}
errno = 0;
usleep(1000 * 5);
}
// client socket non blocking
res = fcntl(client_socket, F_SETFL, fcntl(client_socket, F_GETFL, 0) | O_NONBLOCK);
if (res == -1) {
log_println(STBBR_LOGERROR, "Error setting nonblocking on client socket: %s", strerror(errno));
return NULL;
}
client = xmppclient_new(client_addr, client_socket);
parser_init(stream_start_callback, auth_callback, id_callback, query_callback);
read_stream();
return NULL;
} }
static void static void

View File

@@ -32,6 +32,11 @@ typedef struct parse_state_t {
XMPPStanza *curr_stanza; XMPPStanza *curr_stanza;
} ParseState; } ParseState;
static void _start_element(void *data, const char *element, const char **attributes);
static void _end_element(void *data, const char *element);
static void _handle_data(void *data, const char *content, int length);
static void _attrs_free(XMPPAttr *attr);
XMPPStanza* XMPPStanza*
stanza_new(const char *name, const char **attributes) stanza_new(const char *name, const char **attributes)
{ {
@@ -40,7 +45,6 @@ stanza_new(const char *name, const char **attributes)
stanza->content = NULL; stanza->content = NULL;
stanza->children = NULL; stanza->children = NULL;
stanza->attrs = NULL; stanza->attrs = NULL;
if (attributes[0]) {
int i; int i;
for (i = 0; attributes[i]; i += 2) { for (i = 0; attributes[i]; i += 2) {
XMPPAttr *attr = malloc(sizeof(XMPPAttr)); XMPPAttr *attr = malloc(sizeof(XMPPAttr));
@@ -48,7 +52,6 @@ stanza_new(const char *name, const char **attributes)
attr->value = strdup(attributes[i+1]); attr->value = strdup(attributes[i+1]);
stanza->attrs = g_list_append(stanza->attrs, attr); stanza->attrs = g_list_append(stanza->attrs, attr);
} }
}
return stanza; return stanza;
} }
@@ -258,20 +261,13 @@ stanza_get_query_request(XMPPStanza *stanza)
return xmlns; return xmlns;
} }
static void
_attrs_free(XMPPAttr *attr)
{
if (attr) {
free(attr->name);
free(attr->value);
free(attr);
}
}
void void
stanza_free(XMPPStanza *stanza) stanza_free(XMPPStanza *stanza)
{ {
if (stanza) { if (!stanza) {
return;
}
free(stanza->name); free(stanza->name);
if (stanza->content) { if (stanza->content) {
g_string_free(stanza->content, TRUE); g_string_free(stanza->content, TRUE);
@@ -280,10 +276,27 @@ stanza_free(XMPPStanza *stanza)
g_list_free_full(stanza->children, (GDestroyNotify)stanza_free); g_list_free_full(stanza->children, (GDestroyNotify)stanza_free);
free(stanza); free(stanza);
} }
XMPPStanza*
stanza_parse(char *stanza_text)
{
ParseState *state = malloc(sizeof(ParseState));
state->depth = 0;
state->curr_stanza = NULL;
XML_Parser parser = XML_ParserCreate(NULL);
XML_SetElementHandler(parser, _start_element, _end_element);
XML_SetCharacterDataHandler(parser, _handle_data);
XML_SetUserData(parser, state);
XML_Parse(parser, stanza_text, strlen(stanza_text), 0);
XML_ParserFree(parser);
return state->curr_stanza;
} }
static void static void
start_element(void *data, const char *element, const char **attributes) _start_element(void *data, const char *element, const char **attributes)
{ {
ParseState *state = data; ParseState *state = data;
@@ -300,7 +313,7 @@ start_element(void *data, const char *element, const char **attributes)
} }
static void static void
end_element(void *data, const char *element) _end_element(void *data, const char *element)
{ {
ParseState *state = data; ParseState *state = data;
@@ -313,7 +326,7 @@ end_element(void *data, const char *element)
} }
static void static void
handle_data(void *data, const char *content, int length) _handle_data(void *data, const char *content, int length)
{ {
ParseState *state = data; ParseState *state = data;
@@ -324,20 +337,14 @@ handle_data(void *data, const char *content, int length)
g_string_append_len(state->curr_stanza->content, content, length); g_string_append_len(state->curr_stanza->content, content, length);
} }
XMPPStanza * static void
stanza_parse(char *stanza_text) _attrs_free(XMPPAttr *attr)
{ {
ParseState *state = malloc(sizeof(ParseState)); if (!attr) {
state->depth = 0; return;
state->curr_stanza = NULL; }
XML_Parser parser = XML_ParserCreate(NULL); free(attr->name);
XML_SetElementHandler(parser, start_element, end_element); free(attr->value);
XML_SetCharacterDataHandler(parser, handle_data); free(attr);
XML_SetUserData(parser, state);
XML_Parse(parser, stanza_text, strlen(stanza_text), 0);
XML_ParserFree(parser);
return state->curr_stanza;
} }

View File

@@ -32,6 +32,9 @@
pthread_mutex_t stanzas_lock; pthread_mutex_t stanzas_lock;
static GList *stanzas; static GList *stanzas;
static int _xmpp_attr_equal(XMPPAttr *attr1, XMPPAttr *attr2);
static int _stanzas_equal(XMPPStanza *first, XMPPStanza *second);
int int
stanzas_contains_id(char *id) stanzas_contains_id(char *id)
{ {
@@ -63,6 +66,64 @@ stanzas_add(XMPPStanza *stanza)
pthread_mutex_unlock(&stanzas_lock); pthread_mutex_unlock(&stanzas_lock);
} }
int
stanzas_verify_any(XMPPStanza *stanza)
{
pthread_mutex_lock(&stanzas_lock);
if (!stanzas) {
pthread_mutex_unlock(&stanzas_lock);
return 0;
}
GList *curr = g_list_last(stanzas);
while (curr) {
XMPPStanza *curr_stanza = curr->data;
if (_stanzas_equal(stanza, curr_stanza) == 0) {
pthread_mutex_unlock(&stanzas_lock);
return 1;
}
curr = g_list_previous(curr);
}
pthread_mutex_unlock(&stanzas_lock);
return 0;
}
int
stanzas_verify_last(XMPPStanza *stanza)
{
pthread_mutex_lock(&stanzas_lock);
if (!stanzas) {
pthread_mutex_unlock(&stanzas_lock);
return 0;
}
GList *last = g_list_last(stanzas);
if (!last) {
pthread_mutex_unlock(&stanzas_lock);
return 0;
}
XMPPStanza *last_stanza = (XMPPStanza *)last->data;
int res = _stanzas_equal(stanza, last_stanza);
pthread_mutex_unlock(&stanzas_lock);
if (res == 0) {
return 1;
} else {
return 0;
}
}
void
stanzas_free_all(void)
{
pthread_mutex_lock(&stanzas_lock);
g_list_free_full(stanzas, (GDestroyNotify)stanza_free);
stanzas = NULL;
pthread_mutex_unlock(&stanzas_lock);
}
static int static int
_xmpp_attr_equal(XMPPAttr *attr1, XMPPAttr *attr2) _xmpp_attr_equal(XMPPAttr *attr1, XMPPAttr *attr2)
{ {
@@ -148,61 +209,3 @@ _stanzas_equal(XMPPStanza *first, XMPPStanza *second)
return 0; return 0;
} }
int
stanzas_verify_any(XMPPStanza *stanza)
{
pthread_mutex_lock(&stanzas_lock);
if (!stanzas) {
pthread_mutex_unlock(&stanzas_lock);
return 0;
}
GList *curr = g_list_last(stanzas);
while (curr) {
XMPPStanza *curr_stanza = curr->data;
if (_stanzas_equal(stanza, curr_stanza) == 0) {
pthread_mutex_unlock(&stanzas_lock);
return 1;
}
curr = g_list_previous(curr);
}
pthread_mutex_unlock(&stanzas_lock);
return 0;
}
int
stanzas_verify_last(XMPPStanza *stanza)
{
pthread_mutex_lock(&stanzas_lock);
if (!stanzas) {
pthread_mutex_unlock(&stanzas_lock);
return 0;
}
GList *last = g_list_last(stanzas);
if (!last) {
pthread_mutex_unlock(&stanzas_lock);
return 0;
}
XMPPStanza *last_stanza = (XMPPStanza *)last->data;
int res = _stanzas_equal(stanza, last_stanza);
pthread_mutex_unlock(&stanzas_lock);
if (res == 0) {
return 1;
} else {
return 0;
}
}
void
stanzas_free_all(void)
{
pthread_mutex_lock(&stanzas_lock);
g_list_free_full(stanzas, (GDestroyNotify)stanza_free);
stanzas = NULL;
pthread_mutex_unlock(&stanzas_lock);
}

View File

@@ -42,8 +42,59 @@ static auth_func auth_cb = NULL;
static id_func id_cb = NULL; static id_func id_cb = NULL;
static query_func query_cb = NULL; static query_func query_cb = NULL;
static void _start_element(void *data, const char *element, const char **attributes);
static void _end_element(void *data, const char *element);
static void _handle_data(void *data, const char *content, int length);
void
parser_init(stream_start_func startcb, auth_func authcb, id_func idcb, query_func querycb)
{
if (curr_string) {
g_string_free(curr_string, TRUE);
}
curr_string = g_string_new("");
stream_start_cb = startcb;
auth_cb = authcb;
id_cb = idcb;
query_cb = querycb;
parser = XML_ParserCreate(NULL);
XML_SetElementHandler(parser, _start_element, _end_element);
XML_SetCharacterDataHandler(parser, _handle_data);
}
int
parser_feed(char *chunk, int len)
{
g_string_append_len(curr_string, chunk, len);
int res = XML_Parse(parser, chunk, len, 0);
parser_reset();
return res;
}
void
parser_close(void)
{
XML_ParserFree(parser);
parser = NULL;
}
void
parser_reset(void)
{
if (do_reset != 1) {
return;
}
parser_close();
parser_init(stream_start_cb, auth_cb, id_cb, query_cb);
do_reset = 0;
}
static void static void
start_element(void *data, const char *element, const char **attributes) _start_element(void *data, const char *element, const char **attributes)
{ {
if (g_strcmp0(element, "stream:stream") == 0) { if (g_strcmp0(element, "stream:stream") == 0) {
log_println(STBBR_LOGINFO, "RECV: %s", curr_string->str); log_println(STBBR_LOGINFO, "RECV: %s", curr_string->str);
@@ -66,14 +117,15 @@ start_element(void *data, const char *element, const char **attributes)
} }
static void static void
end_element(void *data, const char *element) _end_element(void *data, const char *element)
{ {
depth--; depth--;
if (depth > 0) { if (depth > 0) {
stanza_add_child(curr_stanza->parent, curr_stanza); stanza_add_child(curr_stanza->parent, curr_stanza);
curr_stanza = curr_stanza->parent; curr_stanza = curr_stanza->parent;
} else { return;
}
log_println(STBBR_LOGINFO, "RECV: %s", curr_string->str); log_println(STBBR_LOGINFO, "RECV: %s", curr_string->str);
stanzas_add(curr_stanza); stanzas_add(curr_stanza);
if (stanza_get_child_by_ns(curr_stanza, "jabber:iq:auth")) { if (stanza_get_child_by_ns(curr_stanza, "jabber:iq:auth")) {
@@ -91,10 +143,9 @@ end_element(void *data, const char *element)
do_reset = 1; do_reset = 1;
} }
}
static void static void
handle_data(void *data, const char *content, int length) _handle_data(void *data, const char *content, int length)
{ {
if (!curr_stanza->content) { if (!curr_stanza->content) {
curr_stanza->content = g_string_new(""); curr_stanza->content = g_string_new("");
@@ -102,47 +153,3 @@ handle_data(void *data, const char *content, int length)
g_string_append_len(curr_stanza->content, content, length); g_string_append_len(curr_stanza->content, content, length);
} }
void
parser_init(stream_start_func startcb, auth_func authcb, id_func idcb, query_func querycb)
{
if (curr_string) {
g_string_free(curr_string, TRUE);
}
curr_string = g_string_new("");
stream_start_cb = startcb;
auth_cb = authcb;
id_cb = idcb;
query_cb = querycb;
parser = XML_ParserCreate(NULL);
XML_SetElementHandler(parser, start_element, end_element);
XML_SetCharacterDataHandler(parser, handle_data);
}
int
parser_feed(char *chunk, int len)
{
g_string_append_len(curr_string, chunk, len);
int res = XML_Parse(parser, chunk, len, 0);
parser_reset();
return res;
}
void
parser_close(void)
{
XML_ParserFree(parser);
parser = NULL;
}
void
parser_reset(void)
{
if (do_reset == 1) {
parser_close();
parser_init(stream_start_cb, auth_cb, id_cb, query_cb);
do_reset = 0;
}
}

View File

@@ -48,7 +48,10 @@ xmppclient_new(struct sockaddr_in client_addr, int socket)
void void
xmppclient_end_session(XMPPClient *client) xmppclient_end_session(XMPPClient *client)
{ {
if (client) { if (!client) {
return;
}
if (client->sock) { if (client->sock) {
shutdown(client->sock, 2); shutdown(client->sock, 2);
while (recv(client->sock, NULL, 1, 0) > 0) {} while (recv(client->sock, NULL, 1, 0) > 0) {}
@@ -60,4 +63,3 @@ xmppclient_end_session(XMPPClient *client)
free(client->resource); free(client->resource);
free(client); free(client);
} }
}