about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2012-10-21 11:37:11 -0700
committerJames Booth <boothj5@gmail.com>2012-10-21 11:37:11 -0700
commit382e961563eb9e4d31d3ad111a41569b7fa78fa6 (patch)
treeafdbde8745e87f17c6525203a28010bf6f52d466
parent4e05e919b257906c2fef824c9a1745c259d4af20 (diff)
parent46b8a21cfb49d64dbb190b38192934df25de0fb8 (diff)
downloadprofani-tty-382e961563eb9e4d31d3ad111a41569b7fa78fa6.tar.gz
Merge pull request #46 from pasis/master
Improved error handling. Handles when user does not exist at server, and when the server cannot be contacted (for example if the server name is typed incorrectly in the JID). 
-rw-r--r--src/jabber.c32
-rw-r--r--src/profanity.c18
-rw-r--r--src/profanity.h1
-rw-r--r--src/ui.h1
-rw-r--r--src/windows.c73
5 files changed, 96 insertions, 29 deletions
diff --git a/src/jabber.c b/src/jabber.c
index c8caf415..d7809b03 100644
--- a/src/jabber.c
+++ b/src/jabber.c
@@ -255,6 +255,32 @@ static int
 _message_handler(xmpp_conn_t * const conn, 
     xmpp_stanza_t * const stanza, void * const userdata)
 {
+    char *type;
+    char *from;
+
+    type = xmpp_stanza_get_attribute(stanza, "type");
+    from = xmpp_stanza_get_attribute(stanza, "from");
+
+    if (strcmp(type, "error") == 0) {
+        char *err_msg = NULL;
+        xmpp_stanza_t *error = xmpp_stanza_get_child_by_name(stanza, "error");
+        if (error == NULL) {
+            log_debug("error message without <error/> received");
+            return 1;
+        } else {
+            xmpp_stanza_t *err_cond = xmpp_stanza_get_children(error);
+            if (err_cond == NULL) {
+                log_debug("error message without <defined-condition/> received");
+                return 1;
+            } else {
+                err_msg = xmpp_stanza_get_name(err_cond);
+            }
+            // TODO: process 'type' attribute from <error/> [RFC6120, 8.3.2]
+        }
+        prof_handle_error_message(from, err_msg);
+        return 1;
+    }
+
     xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, "body");
 
     // if no message, check for chatstates
@@ -265,7 +291,6 @@ _message_handler(xmpp_conn_t * const conn,
                 // active
             } else if (xmpp_stanza_get_child_by_name(stanza, "composing") != NULL) {
                 // composing
-                char *from = xmpp_stanza_get_attribute(stanza, "from");
                 prof_handle_typing(from);
             }
         }
@@ -274,12 +299,7 @@ _message_handler(xmpp_conn_t * const conn,
     }
 
     // message body recieved
-    char *type = xmpp_stanza_get_attribute(stanza, "type");
-    if(strcmp(type, "error") == 0)
-        return 1;
-
     char *message = xmpp_stanza_get_text(body);
-    char *from = xmpp_stanza_get_attribute(stanza, "from");
     prof_handle_incoming_message(from, message);
 
     return 1;
diff --git a/src/profanity.c b/src/profanity.c
index 0b909935..7795389d 100644
--- a/src/profanity.c
+++ b/src/profanity.c
@@ -115,6 +115,24 @@ prof_handle_incoming_message(char *from, char *message)
 }
 
 void
+prof_handle_error_message(const char *from, const char *err_msg)
+{
+    char *msg, *fmt;
+
+    if (err_msg != NULL) {
+        fmt = "Error received from server: %s";
+        msg = (char *)malloc(strlen(err_msg) + strlen(fmt) - 1);
+        if (msg == NULL)
+            goto loop_out;
+        sprintf(msg, fmt, err_msg);
+        cons_bad_show(msg);
+        free(msg);
+    }
+loop_out:
+    win_show_error_msg(from, err_msg);
+}
+
+void
 prof_handle_login_success(const char *jid)
 {
     const char *msg = " logged in successfully.";
diff --git a/src/profanity.h b/src/profanity.h
index 3731f2c1..3d37d85e 100644
--- a/src/profanity.h
+++ b/src/profanity.h
@@ -37,6 +37,7 @@ void prof_handle_typing(char *from);
 void prof_handle_contact_online(char *contact, char *show, char *status);
 void prof_handle_contact_offline(char *contact, char *show, char *status);
 void prof_handle_incoming_message(char *from, char *message);
+void prof_handle_error_message(const char *from, const char *err_msg);
 void prof_handle_roster(GSList *roster);
 
 #endif
diff --git a/src/ui.h b/src/ui.h
index 66a41e07..d1d56276 100644
--- a/src/ui.h
+++ b/src/ui.h
@@ -88,6 +88,7 @@ int win_in_chat(void);
 char *win_get_recipient(void);
 void win_show_typing(const char * const from);
 void win_show_incomming_msg(const char * const from, const char * const message);
+void win_show_error_msg(const char * const from, const char *err_msg);
 void win_show_outgoing_msg(const char * const from, const char * const to, 
     const char * const message);
 void win_handle_special_keys(const int * const ch);
diff --git a/src/windows.c b/src/windows.c
index 8ffc5005..bc39bfb3 100644
--- a/src/windows.c
+++ b/src/windows.c
@@ -73,6 +73,7 @@ static void _win_switch_if_active(const int i);
 static void _win_show_time(WINDOW *win);
 static void _win_show_user(WINDOW *win, const char * const user, const int colour);
 static void _win_show_message(WINDOW *win, const char * const message);
+static void _win_show_error_msg(WINDOW *win, const char * const message);
 static void _show_status_string(WINDOW *win, const char * const from, 
     const char * const show, const char * const status, const char * const pre, 
     const char * const default_show);
@@ -302,6 +303,27 @@ win_show_incomming_msg(const char * const from, const char * const message)
 #endif
 }
 
+void
+win_show_error_msg(const char * const from, const char *err_msg)
+{
+    int win_index;
+    WINDOW *win;
+
+    if (from == NULL || err_msg == NULL)
+        return;
+
+    win_index = _find_prof_win_index(from);
+    // chat window exists
+    if (win_index < NUM_WINS) {
+        win = _wins[win_index].win;
+        _win_show_time(win);
+        _win_show_error_msg(win, err_msg);
+        if (win_index == _curr_prof_win) {
+            dirty = TRUE;
+        }
+    }
+}
+
 #ifdef HAVE_LIBNOTIFY
 static void
 _win_notify(const char * const message, int timeout, 
@@ -371,38 +393,35 @@ win_show_outgoing_msg(const char * const from, const char * const to,
 {
     // if the contact is offline, show a message
     PContact contact = contact_list_get_contact(to);
-    
-    if (contact == NULL) {
-        cons_show("%s is not one of your contacts.");
-    } else {
-        int win_index = _find_prof_win_index(to);
-        WINDOW *win = NULL;
-
-        // create new window
-        if (win_index == NUM_WINS) {
-            win_index = _new_prof_win(to);
-            win = _wins[win_index].win;
-            
-            if (prefs_get_chlog() && prefs_get_history()) {
-                _win_show_history(win, win_index, to);
-            }
+    int win_index = _find_prof_win_index(to);
+    WINDOW *win = NULL;
 
+    // create new window
+    if (win_index == NUM_WINS) {
+        win_index = _new_prof_win(to);
+        win = _wins[win_index].win;
+
+        if (prefs_get_chlog() && prefs_get_history()) {
+            _win_show_history(win, win_index, to);
+        }
+
+        if (contact != NULL) {
             if (strcmp(p_contact_show(contact), "offline") == 0) {
                 const char const *show = p_contact_show(contact);
                 const char const *status = p_contact_status(contact);
                 _show_status_string(win, to, show, status, "--", "offline");
             }
-
-        // use existing window
-        } else {
-            win = _wins[win_index].win;
         }
 
-        _win_show_time(win);
-        _win_show_user(win, from, 0);
-        _win_show_message(win, message);
-        _win_switch_if_active(win_index);
+    // use existing window
+    } else {
+        win = _wins[win_index].win;
     }
+
+    _win_show_time(win);
+    _win_show_user(win, from, 0);
+    _win_show_message(win, message);
+    _win_switch_if_active(win_index);
 }
 
 void
@@ -902,6 +921,14 @@ _win_show_message(WINDOW *win, const char * const message)
 }
 
 static void
+_win_show_error_msg(WINDOW *win, const char * const message)
+{
+    wattron(win, COLOUR_ERR);
+    wprintw(win, "%s\n", message);
+    wattroff(win, COLOUR_ERR);
+}
+
+static void
 _current_window_refresh(void)
 {
     int rows, cols;