about summary refs log tree commit diff stats
path: root/src/iq.c
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2013-01-25 00:36:09 +0000
committerJames Booth <boothj5@gmail.com>2013-01-25 00:36:09 +0000
commit6b632625df37be70f221efc9d2a4adfca40786ed (patch)
tree5a7e782765eb2099317adebcfc677169e8fa890c /src/iq.c
parent183a66c939f04a43db8e7d0d7383fc90ee4e9683 (diff)
downloadprofani-tty-6b632625df37be70f221efc9d2a4adfca40786ed.tar.gz
Refactored iq.c to register iq handlers
Diffstat (limited to 'src/iq.c')
-rw-r--r--src/iq.c378
1 files changed, 167 insertions, 211 deletions
diff --git a/src/iq.c b/src/iq.c
index 15c2f801..960dd2c7 100644
--- a/src/iq.c
+++ b/src/iq.c
@@ -33,210 +33,159 @@
 #include "log.h"
 #include "stanza.h"
 
-static int _iq_error_handler(xmpp_conn_t * const conn,
-    xmpp_stanza_t * const stanza, xmpp_ctx_t * const ctx, const char * const id,
-    const char * const from);
-
-static int _roster_handler(xmpp_conn_t * const conn,
-    xmpp_stanza_t * const stanza, xmpp_ctx_t * const ctx,
-    const char * const id, const char * const type, const char * const from);
-static int _caps_response_handler(xmpp_conn_t * const conn,
-    xmpp_stanza_t * const stanza, xmpp_ctx_t * const ctx,
-    const char * const id, const char * const type, const char * const from);
-static int _caps_request_handler(xmpp_conn_t * const conn,
-    xmpp_stanza_t * const stanza, xmpp_ctx_t * const ctx,
-    const char * const id, const char * const type, const char * const from);
-static int _version_request_handler(xmpp_conn_t * const conn,
-    xmpp_stanza_t * const stanza, xmpp_ctx_t * const ctx,
-    const char * const id, const char * const type, const char * const from);
-
-int
-iq_handler(xmpp_conn_t * const conn,
-    xmpp_stanza_t * const stanza, void * const userdata)
+#define HANDLE(ns, type, func) xmpp_handler_add(conn, func, ns, STANZA_NAME_IQ, type, ctx)
+
+static int _iq_handle_error(xmpp_conn_t * const conn,
+    xmpp_stanza_t * const stanza, void * const userdata);
+static int _iq_handle_roster_set(xmpp_conn_t * const conn,
+    xmpp_stanza_t * const stanza, void * const userdata);
+static int _iq_handle_roster_result(xmpp_conn_t * const conn,
+    xmpp_stanza_t * const stanza, void * const userdata);
+static int _iq_handle_ping_get(xmpp_conn_t * const conn,
+    xmpp_stanza_t * const stanza, void * const userdata);
+static int _iq_handle_version_get(xmpp_conn_t * const conn,
+    xmpp_stanza_t * const stanza, void * const userdata);
+static int _iq_handle_discoinfo_get(xmpp_conn_t * const conn,
+    xmpp_stanza_t * const stanza, void * const userdata);
+static int _iq_handle_discoinfo_result(xmpp_conn_t * const conn,
+    xmpp_stanza_t * const stanza, void * const userdata);
+
+void
+iq_add_handlers(xmpp_conn_t * const conn, xmpp_ctx_t * const ctx)
 {
-    xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
-    char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
-    char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE);
-    char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
+    HANDLE(NULL,                STANZA_TYPE_ERROR,  _iq_handle_error);
+    HANDLE(XMPP_NS_ROSTER,      STANZA_TYPE_SET,    _iq_handle_roster_set);
+    HANDLE(XMPP_NS_ROSTER,      STANZA_TYPE_RESULT, _iq_handle_roster_result);
+    HANDLE(XMPP_NS_DISCO_INFO,  STANZA_TYPE_GET,    _iq_handle_discoinfo_get);
+    HANDLE(XMPP_NS_DISCO_INFO,  STANZA_TYPE_RESULT, _iq_handle_discoinfo_result);
+    HANDLE(STANZA_NS_VERSION,   STANZA_TYPE_GET,    _iq_handle_version_get);
+    HANDLE(STANZA_NS_PING,      STANZA_TYPE_GET,    _iq_handle_ping_get);
+}
 
-    if (g_strcmp0(type, "error") == 0) {
-        return _iq_error_handler(conn, stanza, ctx, id, from);
-    }
-/*
-    if (g_strcmp0(type, "get") == 0) {
-        return _iq_get_handler(conn, stanza, ctx, id, from);
-    }
+static int
+_iq_handle_error(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
+    void * const userdata)
+{
+    const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
 
-    if (g_strcmp0(type, "set") == 0) {
-        return _iq_set_handler(conn, stanza, ctx, id, from);
+    if (id != NULL) {
+        log_error("IQ error received, id: %s.", id);
+    } else {
+        log_error("IQ error recieved.");
     }
 
-    if (g_strcmp0(type, "result") == 0) {
-        return _iq_result_handler(conn, stanza, ctx, id, from);
-    }
-*/
-    // handle the initial roster request
-    if (g_strcmp0(id, "roster") == 0) {
-        return _roster_handler(conn, stanza, ctx, id, type, from);
+    return 1;
+}
 
-    // handle caps responses
-    } else if ((id != NULL) && (g_str_has_prefix(id, "disco")) &&
-            (g_strcmp0(type, "result") == 0)) {
-        return _caps_response_handler(conn, stanza, ctx, id, type, from);
+static int
+_iq_handle_roster_set(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
+    void * const userdata)
+{
+    xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
+    xmpp_stanza_t *item =
+        xmpp_stanza_get_child_by_name(query, STANZA_NAME_ITEM);
 
-    // handle caps requests
-    } else if (stanza_is_caps_request(stanza)) {
-        return _caps_request_handler(conn, stanza, ctx, id, type, from);
+    if (item == NULL) {
+        return 1;
+    }
 
-    } else if (stanza_is_version_request(stanza)) {
-        return _version_request_handler(conn, stanza, ctx, id, type, from);
+    const char *jid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID);
+    const char *sub = xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION);
+    if (g_strcmp0(sub, "remove") == 0) {
+        contact_list_remove(jid);
+        return 1;
+    }
 
-    // handle iq
-    } else {
-        char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE);
-        if (type == NULL) {
-            return TRUE;
-        }
+    gboolean pending_out = FALSE;
+    const char *ask = xmpp_stanza_get_attribute(item, STANZA_ATTR_ASK);
+    if ((ask != NULL) && (strcmp(ask, "subscribe") == 0)) {
+        pending_out = TRUE;
+    }
 
-        // handle roster update
-        if (strcmp(type, STANZA_TYPE_SET) == 0) {
+    contact_list_update_subscription(jid, sub, pending_out);
 
-            xmpp_stanza_t *query =
-                xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
-            if (query == NULL) {
-                return TRUE;
-            }
+    return 1;
+}
 
-            char *xmlns = xmpp_stanza_get_attribute(query, STANZA_ATTR_XMLNS);
-            if (xmlns == NULL) {
-                return TRUE;
-            }
-            if (strcmp(xmlns, XMPP_NS_ROSTER) != 0) {
-                return TRUE;
-            }
+static int
+_iq_handle_roster_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
+    void * const userdata)
+{
+    const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
 
-            xmpp_stanza_t *item =
-                xmpp_stanza_get_child_by_name(query, STANZA_NAME_ITEM);
-            if (item == NULL) {
-                return TRUE;
-            }
+    // handle initial roster response
+    if (g_strcmp0(id, "roster") == 0) {
+        xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
+        xmpp_stanza_t *item = xmpp_stanza_get_children(query);
 
+        while (item != NULL) {
             const char *jid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID);
+            const char *name = xmpp_stanza_get_attribute(item, STANZA_ATTR_NAME);
             const char *sub = xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION);
-            if (g_strcmp0(sub, "remove") == 0) {
-                contact_list_remove(jid);
-                return TRUE;
-            }
 
             gboolean pending_out = FALSE;
             const char *ask = xmpp_stanza_get_attribute(item, STANZA_ATTR_ASK);
-            if ((ask != NULL) && (strcmp(ask, "subscribe") == 0)) {
+            if (g_strcmp0(ask, "subscribe") == 0) {
                 pending_out = TRUE;
             }
 
-            contact_list_update_subscription(jid, sub, pending_out);
-
-            return TRUE;
-
-        // handle server ping
-        } else if (strcmp(type, STANZA_TYPE_GET) == 0) {
-            xmpp_stanza_t *ping = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_PING);
-            if (ping == NULL) {
-                return TRUE;
-            }
-
-            char *xmlns = xmpp_stanza_get_attribute(ping, STANZA_ATTR_XMLNS);
-            if (xmlns == NULL) {
-                return TRUE;
-            }
-
-            if (strcmp(xmlns, STANZA_NS_PING) != 0) {
-                return TRUE;
-            }
+            gboolean added = contact_list_add(jid, name, "offline", NULL, sub,
+                pending_out);
 
-            char *to = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TO);
-            char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
-            if ((from == NULL) || (to == NULL)) {
-                return TRUE;
+            if (!added) {
+                log_warning("Attempt to add contact twice: %s", jid);
             }
 
-            xmpp_stanza_t *pong = xmpp_stanza_new(ctx);
-            xmpp_stanza_set_name(pong, STANZA_NAME_IQ);
-            xmpp_stanza_set_attribute(pong, STANZA_ATTR_TO, from);
-            xmpp_stanza_set_attribute(pong, STANZA_ATTR_FROM, to);
-            xmpp_stanza_set_attribute(pong, STANZA_ATTR_TYPE, STANZA_TYPE_RESULT);
-            if (id != NULL) {
-                xmpp_stanza_set_attribute(pong, STANZA_ATTR_ID, id);
-            }
-
-            xmpp_send(conn, pong);
-            xmpp_stanza_release(pong);
-
-            return TRUE;
-        } else {
-            return TRUE;
+            item = xmpp_stanza_get_next(item);
         }
-    }
-}
 
-static int
-_iq_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
-    xmpp_ctx_t * const ctx, const char * const id, const char * const from)
-{
-    if (id != NULL) {
-        log_error("IQ error received, id: %s.", id);
-    } else {
-        log_error("IQ error recieved.");
+        /* TODO: Save somehow last presence show and use it for initial
+         *       presence rather than PRESENCE_ONLINE. It will be helpful
+         *       when I set dnd status and reconnect for some reason */
+        // send initial presence
+        jabber_update_presence(PRESENCE_ONLINE, NULL, 0);
     }
 
     return 1;
 }
 
 static int
-_roster_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
-    xmpp_ctx_t * const ctx, const char * const id, const char * const type,
-    const char * const from)
+_iq_handle_ping_get(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
+    void * const userdata)
 {
-    xmpp_stanza_t *query, *item;
-
-    query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
-    item = xmpp_stanza_get_children(query);
-
-    while (item != NULL) {
-        const char *jid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID);
-        const char *name = xmpp_stanza_get_attribute(item, STANZA_ATTR_NAME);
-        const char *sub = xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION);
-
-        gboolean pending_out = FALSE;
-        const char *ask = xmpp_stanza_get_attribute(item, STANZA_ATTR_ASK);
-        if (g_strcmp0(ask, "subscribe") == 0) {
-            pending_out = TRUE;
-        }
+    xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
+    const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
+    const char *to = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TO);
+    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
 
-        gboolean added = contact_list_add(jid, name, "offline", NULL, sub,
-            pending_out);
+    if ((from == NULL) || (to == NULL)) {
+        return 1;
+    }
 
-        if (!added) {
-            log_warning("Attempt to add contact twice: %s", jid);
-        }
+    xmpp_stanza_t *pong = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(pong, STANZA_NAME_IQ);
+    xmpp_stanza_set_attribute(pong, STANZA_ATTR_TO, from);
+    xmpp_stanza_set_attribute(pong, STANZA_ATTR_FROM, to);
+    xmpp_stanza_set_attribute(pong, STANZA_ATTR_TYPE, STANZA_TYPE_RESULT);
 
-        item = xmpp_stanza_get_next(item);
+    if (id != NULL) {
+        xmpp_stanza_set_attribute(pong, STANZA_ATTR_ID, id);
     }
 
-    /* TODO: Save somehow last presence show and use it for initial
-     *       presence rather than PRESENCE_ONLINE. It will be helpful
-     *       when I set dnd status and reconnect for some reason */
-    // send initial presence
-    jabber_update_presence(PRESENCE_ONLINE, NULL, 0);
+    xmpp_send(conn, pong);
+    xmpp_stanza_release(pong);
 
     return 1;
 }
 
 static int
-_version_request_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
-    xmpp_ctx_t * const ctx, const char * const id, const char * const type,
-    const char * const from)
+_iq_handle_version_get(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
+    void * const userdata)
 {
+    xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
+    const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
+    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
+
     if (from != NULL) {
         xmpp_stanza_t *response = xmpp_stanza_new(ctx);
         xmpp_stanza_set_name(response, STANZA_NAME_IQ);
@@ -279,12 +228,14 @@ _version_request_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
 }
 
 static int
-_caps_request_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
-    xmpp_ctx_t * ctx, const char * const id, const char * const type,
-    const char * const from)
+_iq_handle_discoinfo_get(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
+    void * const userdata)
 {
+    xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
+    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
+
     xmpp_stanza_t *incoming_query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
-    char *node_str = xmpp_stanza_get_attribute(incoming_query, STANZA_ATTR_NODE);
+    const char *node_str = xmpp_stanza_get_attribute(incoming_query, STANZA_ATTR_NODE);
 
     if (from != NULL && node_str != NULL) {
         xmpp_stanza_t *response = xmpp_stanza_new(ctx);
@@ -304,71 +255,76 @@ _caps_request_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
 }
 
 static int
-_caps_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
-    xmpp_ctx_t * ctx, const char * const id, const char * const type,
-    const char * const from)
+_iq_handle_discoinfo_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
+    void * const userdata)
 {
-    xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
-    char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE);
-    if (node == NULL) {
-        return 1;
-    }
+    const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
 
-    char *caps_key = NULL;
+    if ((id != NULL) && (g_str_has_prefix(id, "disco"))) {
+        xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
+        char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE);
+        if (node == NULL) {
+            return 1;
+        }
 
-    // xep-0115
-    if (g_strcmp0(id, "disco") == 0) {
-        caps_key = strdup(node);
+        char *caps_key = NULL;
 
-        // validate sha1
-        gchar **split = g_strsplit(node, "#", -1);
-        char *given_sha1 = split[1];
-        char *generated_sha1 = caps_create_sha1_str(query);
+        // xep-0115
+        if (g_strcmp0(id, "disco") == 0) {
+            caps_key = strdup(node);
 
-        if (g_strcmp0(given_sha1, generated_sha1) != 0) {
-            log_info("Invalid SHA1 recieved for caps.");
+            // validate sha1
+            gchar **split = g_strsplit(node, "#", -1);
+            char *given_sha1 = split[1];
+            char *generated_sha1 = caps_create_sha1_str(query);
+
+            if (g_strcmp0(given_sha1, generated_sha1) != 0) {
+                log_info("Invalid SHA1 recieved for caps.");
+                FREE_SET_NULL(generated_sha1);
+                g_strfreev(split);
+
+                return 1;
+            }
             FREE_SET_NULL(generated_sha1);
             g_strfreev(split);
 
+        // non supported hash, or legacy caps
+        } else {
+            caps_key = strdup(id + 6);
+        }
+
+        // already cached
+        if (caps_contains(caps_key)) {
+            log_info("Client info already cached.");
             return 1;
         }
-        FREE_SET_NULL(generated_sha1);
-        g_strfreev(split);
 
-    // non supported hash, or legacy caps
-    } else {
-        caps_key = strdup(id + 6);
-    }
+        xmpp_stanza_t *identity = xmpp_stanza_get_child_by_name(query, "identity");
 
-    // already cached
-    if (caps_contains(caps_key)) {
-        log_info("Client info already cached.");
-        return 1;
-    }
+        if (identity == NULL) {
+            return 1;
+        }
 
-    xmpp_stanza_t *identity = xmpp_stanza_get_child_by_name(query, "identity");
+        const char *category = xmpp_stanza_get_attribute(identity, "category");
+        if (category == NULL) {
+            return 1;
+        }
 
-    if (identity == NULL) {
-        return 1;
-    }
+        if (strcmp(category, "client") != 0) {
+            return 1;
+        }
 
-    const char *category = xmpp_stanza_get_attribute(identity, "category");
-    if (category == NULL) {
-        return 1;
-    }
+        const char *name = xmpp_stanza_get_attribute(identity, "name");
+        if (name == 0) {
+            return 1;
+        }
 
-    if (strcmp(category, "client") != 0) {
-        return 1;
-    }
+        caps_add(caps_key, name);
+
+        free(caps_key);
 
-    const char *name = xmpp_stanza_get_attribute(identity, "name");
-    if (name == 0) {
+        return 1;
+    } else {
         return 1;
     }
-
-    caps_add(caps_key, name);
-
-    free(caps_key);
-
-    return 1;
 }