about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-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;