about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2015-08-05 00:26:29 +0100
committerJames Booth <boothj5@gmail.com>2015-08-05 00:26:29 +0100
commit2a92169351f88ab3bfe1acf15628878c5e8ef520 (patch)
treecfe4e15ac713ac2f1538591069860d86e3dbc2e8
parentde747e3d46c1be9e3256716d8939148e0bc07a35 (diff)
downloadprofani-tty-2a92169351f88ab3bfe1acf15628878c5e8ef520.tar.gz
Use id handler for software version requests, handle errors
-rw-r--r--src/ui/core.c18
-rw-r--r--src/ui/ui.h1
-rw-r--r--src/xmpp/iq.c33
-rw-r--r--src/xmpp/stanza.c6
-rw-r--r--tests/functionaltests/functionaltests.c1
-rw-r--r--tests/functionaltests/test_software.c25
-rw-r--r--tests/functionaltests/test_software.h1
7 files changed, 78 insertions, 7 deletions
diff --git a/src/ui/core.c b/src/ui/core.c
index bbaebe31..9cbd873a 100644
--- a/src/ui/core.c
+++ b/src/ui/core.c
@@ -2792,6 +2792,24 @@ ui_hide_roster(void)
     }
 }
 
+void
+ui_handle_software_version_error(const char * const roomjid, const char * const message)
+{
+    GString *message_str = g_string_new("");
+
+    ProfWin *window = wins_get_console();
+    g_string_printf(message_str, "Could not get software version");
+
+    if (message) {
+        g_string_append(message_str, ": ");
+        g_string_append(message_str, message);
+    }
+
+    win_print(window, '-', 0, NULL, 0, THEME_ERROR, "", message_str->str);
+
+    g_string_free(message_str, TRUE);
+}
+
 static void
 _win_show_history(ProfChatWin *chatwin, const char * const contact)
 {
diff --git a/src/ui/ui.h b/src/ui/ui.h
index fd81f68a..d22a5c7f 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -203,6 +203,7 @@ void ui_redraw_all_room_rosters(void);
 void ui_show_all_room_rosters(void);
 void ui_hide_all_room_rosters(void);
 gboolean ui_chat_win_exists(const char * const barejid);
+void ui_handle_software_version_error(const char * const roomjid, const char * const message);
 
 gboolean ui_tidy_wins(void);
 void ui_prune_wins(void);
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index 18abad36..7ed44363 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -67,10 +67,10 @@ typedef struct p_room_info_data_t {
 static int _error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
 static int _ping_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
 static int _version_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
+static int _version_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
 static int _disco_info_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
 static int _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
 static int _room_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
-static int _version_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
 static int _disco_items_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
 static int _disco_items_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
 static int _destroy_room_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata);
@@ -103,7 +103,6 @@ iq_add_handlers(void)
     HANDLE(XMPP_NS_DISCO_ITEMS, STANZA_TYPE_RESULT, _disco_items_result_handler);
 
     HANDLE(STANZA_NS_VERSION,   STANZA_TYPE_GET,    _version_get_handler);
-    HANDLE(STANZA_NS_VERSION,   STANZA_TYPE_RESULT, _version_result_handler);
 
     HANDLE(STANZA_NS_PING,      STANZA_TYPE_GET,    _ping_get_handler);
 
@@ -301,6 +300,10 @@ iq_send_software_version(const char * const fulljid)
     xmpp_conn_t * const conn = connection_get_conn();
     xmpp_ctx_t * const ctx = connection_get_ctx();
     xmpp_stanza_t *iq = stanza_create_software_version_iq(ctx, fulljid);
+
+    char *id = xmpp_stanza_get_id(iq);
+    xmpp_id_handler_add(conn, _version_result_handler, id, NULL);
+
     xmpp_send(conn, iq);
     xmpp_stanza_release(iq);
 }
@@ -836,16 +839,34 @@ _version_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
         log_debug("IQ version result handler fired.");
     }
 
+    char *type = xmpp_stanza_get_type(stanza);
+    char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
+
+    if (g_strcmp0(type, STANZA_TYPE_RESULT) != 0) {
+        if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
+            char *error_message = stanza_get_error_message(stanza);
+            ui_handle_software_version_error(from, error_message);
+            free(error_message);
+        } else {
+            ui_handle_software_version_error(from, "unknown error");
+            log_error("Software version result with unrecognised type attribute.");
+        }
+
+        return 0;
+    }
+
     const char *jid = xmpp_stanza_get_attribute(stanza, "from");
 
     xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
     if (query == NULL) {
-        return 1;
+        log_error("Software version result recieved with no query element.");
+        return 0;
     }
 
     char *ns = xmpp_stanza_get_ns(query);
     if (g_strcmp0(ns, STANZA_NS_VERSION) != 0) {
-        return 1;
+        log_error("Software version result recieved without namespace.");
+        return 0;
     }
 
     char *name_str = NULL;
@@ -880,7 +901,7 @@ _version_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
 
     jid_destroy(jidp);
 
-    return 1;
+    return 0;
 }
 
 static int
@@ -1567,4 +1588,4 @@ _disco_items_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stan
     g_slist_free_full(items, (GDestroyNotify)_item_destroy);
 
     return 1;
-}
\ No newline at end of file
+}
diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c
index be85c330..bb32932a 100644
--- a/src/xmpp/stanza.c
+++ b/src/xmpp/stanza.c
@@ -877,7 +877,11 @@ stanza_create_software_version_iq(xmpp_ctx_t *ctx, const char * const fulljid)
     xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
     xmpp_stanza_set_name(iq, STANZA_NAME_IQ);
     xmpp_stanza_set_type(iq, STANZA_TYPE_GET);
-    xmpp_stanza_set_id(iq, "sv");
+
+    char *id = create_unique_id("sv");
+    xmpp_stanza_set_id(iq, id);
+    free(id);
+
     xmpp_stanza_set_attribute(iq, "to", fulljid);
 
     xmpp_stanza_t *query = xmpp_stanza_new(ctx);
diff --git a/tests/functionaltests/functionaltests.c b/tests/functionaltests/functionaltests.c
index a253fe63..cbedf401 100644
--- a/tests/functionaltests/functionaltests.c
+++ b/tests/functionaltests/functionaltests.c
@@ -79,6 +79,7 @@ int main(int argc, char* argv[]) {
 
         PROF_FUNC_TEST(send_software_version_request),
         PROF_FUNC_TEST(display_software_version_result),
+        PROF_FUNC_TEST(shows_message_when_software_version_error),
     };
 
     return run_tests(all_tests);
diff --git a/tests/functionaltests/test_software.c b/tests/functionaltests/test_software.c
index aeb3f8f5..9b063c20 100644
--- a/tests/functionaltests/test_software.c
+++ b/tests/functionaltests/test_software.c
@@ -57,3 +57,28 @@ display_software_version_result(void **state)
     prof_output_exact("Name    : Profanity");
     prof_output_exact("Version : 0.4.7dev.master.2cb2f83");
 }
+
+void
+shows_message_when_software_version_error(void **state)
+{
+    prof_connect();
+    stbbr_send(
+        "<presence to=\"stabber@localhost\" from=\"buddy1@localhost/mobile\">"
+            "<priority>10</priority>"
+            "<status>I'm here</status>"
+        "</presence>"
+    );
+    prof_output_exact("Buddy1 (mobile) is online, \"I'm here\"");
+
+    stbbr_for_query("jabber:iq:version",
+        "<iq id=\"*\" lang=\"en\" type=\"error\" to=\"stabber@localhost/profanity\" from=\"buddy1@localhost/laptop\">"
+            "<query xmlns=\"jabber:iq:version\"/>"
+            "<error code=\"503\" type=\"cancel\">"
+                "<service-unavailable xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>"
+            "</error>"
+        "</iq>"
+    );
+    prof_input("/software buddy1@localhost/laptop");
+
+    prof_output_exact("Could not get software version: service-unavailable");
+}
diff --git a/tests/functionaltests/test_software.h b/tests/functionaltests/test_software.h
index b031e264..985d7002 100644
--- a/tests/functionaltests/test_software.h
+++ b/tests/functionaltests/test_software.h
@@ -1,3 +1,4 @@
 void send_software_version_request(void **state);
 void display_software_version_result(void **state);
+void shows_message_when_software_version_error(void **state);