From bfc9e9a72e6061d90f1545671b7602abf3f0a093 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Thu, 18 Oct 2012 18:18:44 +0300 Subject: [PATCH] handle error messages from server --- src/jabber.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- src/profanity.c | 18 ++++++++++++++++++ src/profanity.h | 1 + src/ui.h | 1 + src/windows.c | 27 +++++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/jabber.c b/src/jabber.c index c8caf415..70162cc4 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -42,6 +42,18 @@ static struct _jabber_conn_t { int tls_disabled; } jabber_conn; +typedef struct _err_code_tbl_t { + int code; + char *condition; +} err_code_tbl_t; + +static err_code_tbl_t err_code_tbl[] = { + {404, "recipient-unavailable"}, + {503, "service-unavailable"}, + {0, NULL}, // termination line +}; + +static char *_get_xmpp_err_by_code(const char * const err_code); static log_level_t _get_log_level(xmpp_log_level_t xmpp_level); static xmpp_log_level_t _get_xmpp_log_level(); static void _xmpp_file_logger(void * const userdata, @@ -275,8 +287,23 @@ _message_handler(xmpp_conn_t * const conn, // message body recieved char *type = xmpp_stanza_get_attribute(stanza, "type"); - if(strcmp(type, "error") == 0) + if(strcmp(type, "error") == 0) { + // error message received + char *from = xmpp_stanza_get_attribute(stanza, "from"); + char *err_msg = NULL; + xmpp_stanza_t *error = xmpp_stanza_get_child_by_name(stanza, "error"); + if (error) { + xmpp_stanza_t *err_cond = xmpp_stanza_get_children(error); + if (err_cond) { + err_msg = xmpp_stanza_get_name(err_cond); + } else { + char *err_code = xmpp_stanza_get_attribute(error, "code"); + err_msg = _get_xmpp_err_by_code(err_code); + } + } + prof_handle_error_message(from, err_msg); return 1; + } char *message = xmpp_stanza_get_text(body); char *from = xmpp_stanza_get_attribute(stanza, "from"); @@ -436,6 +463,25 @@ _presence_handler(xmpp_conn_t * const conn, return 1; } +static char * +_get_xmpp_err_by_code(const char * const err_code) +{ + int code; + int i = 0; + + if (err_code == NULL) + return NULL; + + code = atoi(err_code); + while (err_code_tbl[i].code != 0) { + if (err_code_tbl[i].code == code) { + return err_code_tbl[i].condition; + } + } + + return NULL; +} + static log_level_t _get_log_level(xmpp_log_level_t xmpp_level) { diff --git a/src/profanity.c b/src/profanity.c index 0b909935..7795389d 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -114,6 +114,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) { 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 a303b3c7..6b0a85e3 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,24 @@ 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); + } +} + #ifdef HAVE_LIBNOTIFY static void _win_notify(const char * const message, int timeout, @@ -898,6 +917,14 @@ _win_show_message(WINDOW *win, const char * const message) wprintw(win, "%s\n", 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) {