added channel rejoin faker (session recover)
[TransparentIRC.git] / src / UserSession.c
index 136b7674b2d3d0be9ad8c9eea7d890c40c07920d..644332f416873916749342181a2238f18a25223a 100644 (file)
@@ -19,6 +19,7 @@
 #include "UserClient.h"
 #include "ConfigParser.h"
 #include "tools.h"
+#include "IRCClient.h"
 
 static struct UserSession *usersessions = NULL;
 
@@ -39,10 +40,13 @@ static struct UserSession *usersession_add(char *username, char *password, char
     return session;
 }
 
-/*
 static void usersession_close(struct UserSession *session) {
     if(session->client)
         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;
@@ -53,22 +57,45 @@ static void usersession_close(struct UserSession *session) {
     free(session->username);
     free(session->password);
     free(session->nick);
+    if(session->realname)
+        free(session->realname);
     free(session);
 }
-*/
 
-/* ****************** SESSION FUNCTIONS ****************** */
+/* ****************** EXTERNAL EVENTS ****************** */
 
-static void usersession_initialize_session(struct UserSession *session) {
-    
-}
+static void usersession_timer_callback(struct IOEvent *event);
 
-/* ****************** EXTERNAL EVENTS ****************** */
+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);
+    }
+    usersession_close(session);
+}
 
 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) {
+    if(session->client) {
+        iohandler_printf(session->client->iofd, "%s", raw);
+    }
 }
 
 void usersession_client_notification(struct UserSession *session, char *notification) {
@@ -77,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);
@@ -140,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");
@@ -152,8 +194,10 @@ static void usersession_login_accept(struct UserLogin *login) {
             userclient_login_failed(login, "Could not create Session.");
             return;
         }
+        active_session->client = login->client;
+        active_session->realname = strdup(login->realname);
+        ircclient_initialize(active_session, login);
         userclient_login_successful(login, active_session, 0);
-        usersession_initialize_session(active_session);
     }
 }
 
@@ -196,6 +240,18 @@ static void usersession_login_callback(struct IOEvent *event) {
                 if(argc < 2) return;
                 if(!stricmp(argv[0], "CLASS")) {
                     login->session_class = strdup(argv[1]);
+                } else if(!stricmp(argv[0], "SERVER")) {
+                    login->server_address = strdup(argv[1]);
+                    if(argc > 2) {
+                        login->server_override_port = 1;
+                        if(argv[2][0] == '+') {
+                            argv[2]++;
+                            login->server_ssl = 1;
+                        }
+                        login->server_port = atoi(argv[2]);
+                    }
+                } else if(!stricmp(argv[0], "BIND")) {
+                    login->bind_address = strdup(argv[1]);
                 }
                 
             }