diff --git a/src/chat_session.c b/src/chat_session.c index 9a62c298..a2650b10 100644 --- a/src/chat_session.c +++ b/src/chat_session.c @@ -95,9 +95,7 @@ chat_session_set_composing(const char * const recipient) { ChatSession session = g_hash_table_lookup(sessions, recipient); - if (session == NULL) { - log_error("No chat session found for %s.", recipient); - } else { + if (session != NULL) { if (session->state != CHAT_STATE_COMPOSING) { session->sent = FALSE; } @@ -111,9 +109,7 @@ chat_session_no_activity(const char * const recipient) { ChatSession session = g_hash_table_lookup(sessions, recipient); - if (session == NULL) { - log_error("No chat session found for %s.", recipient); - } else { + if (session != NULL) { if (session->active_timer != NULL) { gdouble elapsed = g_timer_elapsed(session->active_timer, NULL); @@ -146,9 +142,7 @@ chat_session_set_sent(const char * const recipient) { ChatSession session = g_hash_table_lookup(sessions, recipient); - if (session == NULL) { - log_error("No chat session found for %s.", recipient); - } else { + if (session != NULL) { session->sent = TRUE; } } @@ -159,7 +153,6 @@ chat_session_get_sent(const char * const recipient) ChatSession session = g_hash_table_lookup(sessions, recipient); if (session == NULL) { - log_error("No chat session found for %s.", recipient); return FALSE; } else { return session->sent; @@ -178,7 +171,6 @@ chat_session_is_inactive(const char * const recipient) ChatSession session = g_hash_table_lookup(sessions, recipient); if (session == NULL) { - log_error("No chat session found for %s.", recipient); return FALSE; } else { return (session->state == CHAT_STATE_INACTIVE); @@ -191,7 +183,6 @@ chat_session_is_active(const char * const recipient) ChatSession session = g_hash_table_lookup(sessions, recipient); if (session == NULL) { - log_error("No chat session found for %s.", recipient); return FALSE; } else { return (session->state == CHAT_STATE_ACTIVE); @@ -203,9 +194,7 @@ chat_session_set_active(const char * const recipient) { ChatSession session = g_hash_table_lookup(sessions, recipient); - if (session == NULL) { - log_error("No chat session found for %s.", recipient); - } else { + if (session != NULL) { session->state = CHAT_STATE_ACTIVE; g_timer_start(session->active_timer); session->sent = TRUE; @@ -218,7 +207,6 @@ chat_session_is_paused(const char * const recipient) ChatSession session = g_hash_table_lookup(sessions, recipient); if (session == NULL) { - log_error("No chat session found for %s.", recipient); return FALSE; } else { return (session->state == CHAT_STATE_PAUSED); @@ -231,7 +219,6 @@ chat_session_is_gone(const char * const recipient) ChatSession session = g_hash_table_lookup(sessions, recipient); if (session == NULL) { - log_error("No chat session found for %s.", recipient); return FALSE; } else { return (session->state == CHAT_STATE_GONE); @@ -243,9 +230,7 @@ chat_session_set_gone(const char * const recipient) { ChatSession session = g_hash_table_lookup(sessions, recipient); - if (session == NULL) { - log_error("No chat session found for %s.", recipient); - } else { + if (session != NULL) { session->state = CHAT_STATE_GONE; } } @@ -256,7 +241,6 @@ chat_session_get_recipient_supports(const char * const recipient) ChatSession session = g_hash_table_lookup(sessions, recipient); if (session == NULL) { - log_error("No chat session found for %s.", recipient); return FALSE; } else { return session->recipient_supports; @@ -269,9 +253,7 @@ chat_session_set_recipient_supports(const char * const recipient, { ChatSession session = g_hash_table_lookup(sessions, recipient); - if (session == NULL) { - log_error("No chat session found for %s.", recipient); - } else { + if (session != NULL) { session->recipient_supports = recipient_supports; } } diff --git a/src/command.c b/src/command.c index 52f7fac9..facecd62 100644 --- a/src/command.c +++ b/src/command.c @@ -109,6 +109,7 @@ static gboolean _cmd_set_beep(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_notify(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_log(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_priority(gchar **args, struct cmd_help_t help); +static gboolean _cmd_set_reconnect(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_intype(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_flash(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_showsplash(gchar **args, struct cmd_help_t help); @@ -485,6 +486,18 @@ static struct cmd_t setting_commands[] = "Config file value : maxsize=bytes", NULL } } }, + { "/reconnect", + _cmd_set_reconnect, parse_args, 1, 1, + { "/reconnect seconds", "Set reconnect interval.", + { "/reconnect seconds", + "--------------------", + "Set the reconnect attempt interval in seconds for when the connection is lost.", + "A value of 0 will switch of reconnect attempts.", + "", + "Config file section : [jabber]", + "Config file value : reconnect=seconds", + NULL } } }, + { "/priority", _cmd_set_priority, parse_args, 1, 1, { "/priority ", "Set priority for connection.", @@ -1467,6 +1480,28 @@ _cmd_set_log(gchar **args, struct cmd_help_t help) return TRUE; } +static gboolean +_cmd_set_reconnect(gchar **args, struct cmd_help_t help) +{ + char *value = args[0]; + int intval; + + if (_strtoi(value, &intval, 0, INT_MAX) == 0) { + prefs_set_reconnect(intval); + if (intval == 0) { + cons_show("Reconnect disabled.", intval); + } else { + cons_show("Reconnect interval set to %d seconds.", intval); + } + } else { + cons_show("Usage: %s", help.usage); + } + + /* TODO: make 'level' subcommand for debug level */ + + return TRUE; +} + static gboolean _cmd_set_priority(gchar **args, struct cmd_help_t help) { diff --git a/src/jabber.c b/src/jabber.c index bb5f192f..84f5db40 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -48,6 +48,11 @@ static struct _jabber_conn_t { int priority; } jabber_conn; +// for auto reconnect +static char *saved_user; +static char *saved_password; +static GTimer *reconnect_timer; + 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, @@ -98,15 +103,22 @@ jabber_conn_status_t jabber_connect(const char * const user, const char * const passwd) { - log_info("Connecting as %s", user); + if (saved_user == NULL) { + saved_user = strdup(user); + } + if (saved_password == NULL) { + saved_password = strdup(passwd); + } + + log_info("Connecting as %s", saved_user); xmpp_initialize(); jabber_conn.log = _xmpp_get_file_logger(); jabber_conn.ctx = xmpp_ctx_new(NULL, jabber_conn.log); jabber_conn.conn = xmpp_conn_new(jabber_conn.ctx); - xmpp_conn_set_jid(jabber_conn.conn, user); - xmpp_conn_set_pass(jabber_conn.conn, passwd); + xmpp_conn_set_jid(jabber_conn.conn, saved_user); + xmpp_conn_set_pass(jabber_conn.conn, saved_password); if (jabber_conn.tls_disabled) xmpp_conn_disable_tls(jabber_conn.conn); @@ -141,10 +153,21 @@ jabber_disconnect(void) void jabber_process_events(void) { + // run xmpp event loop if connected, connecting or disconnecting if (jabber_conn.conn_status == JABBER_CONNECTED || jabber_conn.conn_status == JABBER_CONNECTING - || jabber_conn.conn_status == JABBER_DISCONNECTING) + || jabber_conn.conn_status == JABBER_DISCONNECTING) { xmpp_run_once(jabber_conn.ctx, 10); + + // check timer and reconnect if disconnected and timer set + } else if ((jabber_conn.conn_status == JABBER_DISCONNECTED) && + (reconnect_timer != NULL)) { + if (g_timer_elapsed(reconnect_timer, NULL) > (prefs_get_reconnect() * 1.0)) { + log_debug("Attempting reconncet as %s", saved_user); + jabber_connect(saved_user, saved_password); + } + } + } void @@ -400,6 +423,8 @@ jabber_get_status(void) void jabber_free_resources(void) { + saved_user = NULL; + saved_password = NULL; chat_sessions_clear(); xmpp_conn_release(jabber_conn.conn); xmpp_ctx_free(jabber_conn.ctx); @@ -624,6 +649,7 @@ _connection_handler(xmpp_conn_t * const conn, { xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata; + // login success if (status == XMPP_CONN_CONNECT) { const char *jid = xmpp_conn_get_jid(conn); prof_handle_login_success(jid); @@ -637,26 +663,56 @@ _connection_handler(xmpp_conn_t * const conn, _jabber_roster_request(); jabber_conn.conn_status = JABBER_CONNECTED; jabber_conn.presence = PRESENCE_ONLINE; + + if (reconnect_timer != NULL) { + g_timer_destroy(reconnect_timer); + reconnect_timer = NULL; + } + } else { // received close stream response from server after disconnect if (jabber_conn.conn_status == JABBER_DISCONNECTING) { jabber_conn.conn_status = JABBER_DISCONNECTED; jabber_conn.presence = PRESENCE_OFFLINE; + if (saved_user != NULL) { + free(saved_user); + saved_user = NULL; + } + if (saved_password != NULL) { + free(saved_password); + saved_password = NULL; + } // lost connection for unkown reason } else if (jabber_conn.conn_status == JABBER_CONNECTED) { prof_handle_lost_connection(); + reconnect_timer = g_timer_new(); xmpp_stop(ctx); jabber_conn.conn_status = JABBER_DISCONNECTED; jabber_conn.presence = PRESENCE_OFFLINE; // login attempt failed } else { - prof_handle_failed_login(); - xmpp_stop(ctx); - jabber_conn.conn_status = JABBER_DISCONNECTED; - jabber_conn.presence = PRESENCE_OFFLINE; + if (reconnect_timer == NULL) { + prof_handle_failed_login(); + if (saved_user != NULL) { + free(saved_user); + saved_user = NULL; + } + if (saved_password != NULL) { + free(saved_password); + saved_password = NULL; + } + xmpp_stop(ctx); + jabber_conn.conn_status = JABBER_DISCONNECTED; + jabber_conn.presence = PRESENCE_OFFLINE; + } else { + xmpp_stop(ctx); + g_timer_start(reconnect_timer); + jabber_conn.conn_status = JABBER_DISCONNECTED; + jabber_conn.presence = PRESENCE_OFFLINE; + } } } } diff --git a/src/preferences.c b/src/preferences.c index a44af242..b2db3123 100644 --- a/src/preferences.c +++ b/src/preferences.c @@ -240,6 +240,19 @@ prefs_set_priority(gint value) _save_prefs(); } +gint +prefs_get_reconnect(void) +{ + return g_key_file_get_integer(prefs, "jabber", "reconnect", NULL); +} + +void +prefs_set_reconnect(gint value) +{ + g_key_file_set_integer(prefs, "jabber", "reconnect", value); + _save_prefs(); +} + gboolean prefs_get_vercheck(void) { diff --git a/src/preferences.h b/src/preferences.h index f4547b07..bde18e59 100644 --- a/src/preferences.h +++ b/src/preferences.h @@ -76,6 +76,8 @@ void prefs_set_max_log_size(gint value); gint prefs_get_max_log_size(void); void prefs_set_priority(gint value); gint prefs_get_priority(void); +void prefs_set_reconnect(gint value); +gint prefs_get_reconnect(void); void prefs_add_login(const char *jid); diff --git a/src/windows.c b/src/windows.c index c105c48e..70a2d310 100644 --- a/src/windows.c +++ b/src/windows.c @@ -1103,6 +1103,15 @@ cons_prefs(void) cons_show("Priority : %d", prefs_get_priority()); + gint reconnect_interval = prefs_get_reconnect(); + if (reconnect_interval == 0) { + cons_show("Reconnect interval : OFF"); + } else if (remind_period == 1) { + cons_show("Reconnect interval : 1 second"); + } else { + cons_show("Reconnect interval : %d seconds", reconnect_interval); + } + cons_show(""); if (current_index == 0) {