added channel rejoin faker (session recover)
[TransparentIRC.git] / src / UserSession.c
index 8b90299df4dcf40fac073954edff9fd9db1240e9..644332f416873916749342181a2238f18a25223a 100644 (file)
@@ -45,6 +45,8 @@ static void usersession_close(struct UserSession *session) {
         userclient_close(session->client);
     if(session->irc)
         ircclient_close(session->irc);
+    if(session->timer)
+        iohandler_close(session->timer);
     
     if(session->prev)
         session->prev->next = session->next;
@@ -62,6 +64,8 @@ static void usersession_close(struct UserSession *session) {
 
 /* ****************** EXTERNAL EVENTS ****************** */
 
+static void usersession_timer_callback(struct IOEvent *event);
+
 void usersession_error(struct UserSession *session, char *error) {
     if(session->client) {
         iohandler_printf(session->client->iofd, ":*TransparentIRC!TransIRC@TransparentIRC.system.notification NOTICE %s :[TransparentIRC] ERROR: %s", session->nick, error);
@@ -71,8 +75,21 @@ void usersession_error(struct UserSession *session, char *error) {
 
 void usersession_client_close(struct UserSession *session) {
     session->client = NULL;
+    if(!session->irc || !session->irc->fully_connected) {
+        usersession_close(session);
+        return;
+    }
     session->idle_since = time(0);
-    
+    if(!session->timer) {
+        int timeout_sec = get_int_field("session.timeout");
+        if(timeout_sec) {
+            struct timeval timeout;
+            gettimeofday(&timeout, NULL);
+            timeout.tv_sec += timeout_sec;
+            session->timer = iohandler_timer(timeout, usersession_timer_callback);
+            session->timer->data = session;
+        }
+    }
 }
 
 void usersession_client_raw(struct UserSession *session, char *raw) {
@@ -87,6 +104,17 @@ void usersession_client_notification(struct UserSession *session, char *notifica
     }
 }
 
+static void usersession_timer_callback(struct IOEvent *event) {
+    struct UserSession *session = event->iofd->data;
+    switch(event->type) {
+        case IOEVENT_TIMEOUT:
+            usersession_close(session);
+            break;
+        default:
+            break;
+    }
+}
+
 /* ****************** LOGIN FUNCTIONS ****************** */
 
 static void usersession_login_accept(struct UserLogin *login);
@@ -150,6 +178,10 @@ static void usersession_login_accept(struct UserLogin *login) {
             userclient_close(active_session->client);
         } //active_session->client is now NULL
         active_session->client = login->client;
+        if(active_session->timer) {
+            iohandler_close(active_session->timer);
+            active_session->timer = NULL;
+        }
         userclient_login_successful(login, active_session, 1);
     } else {
         int sessionlimit = get_int_field("auth.session_limit");