about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/chat_session.c30
-rw-r--r--src/command.c35
-rw-r--r--src/jabber.c72
-rw-r--r--src/preferences.c13
-rw-r--r--src/preferences.h2
-rw-r--r--src/windows.c9
6 files changed, 129 insertions, 32 deletions
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 <value>", "Set priority for connection.",
@@ -1468,6 +1481,28 @@ _cmd_set_log(gchar **args, struct cmd_help_t help)
 }
 
 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)
 {
     char *value = args[0];
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) {