session->realname = NULL;
}
+static struct IRCUser ircclient_parse_user(char *from) {
+ struct IRCUser user;
+ char *a = from, *b = from;
+ while(*b != '!') {
+ b++;
+ }
+ user.nick = a;
+ if(!*b) {
+ user.ident = "";
+ user.host = "";
+ return user;
+ }
+ *b = '\0';
+ b++;
+ a = b;
+ while(*b && *b != '@') {
+ b++;
+ }
+ user.ident = a;
+ if(!*b) {
+ user.host = "";
+ return user;
+ }
+ *b = '\0';
+ b++;
+ user.host = b;
+ return user;
+}
+
static void ircclient_recv(struct IRCClient *client, char *line) {
struct UserSession *session = client->session;
char *argv[MAXNUMPARAMS];
pass_to_client = 0;
}
} else {
+ if(!stricmp(argv[1], "001")) {
+ free(session->nick);
+ session->nick = strdup(argv[2]);
+ client->fully_connected = 1;
+ }
if(!stricmp(argv[1], "001") ||
!stricmp(argv[1], "002") ||
!stricmp(argv[1], "003") ||
else
client->recover_header = new_line;
}
+ } else if(!stricmp(argv[1], "JOIN")) {
+ struct IRCUser from = ircclient_parse_user(argv[0]);
+ if(!stricmp(from.nick, session->nick)) {
+ struct IRCChannel *lchannel = NULL, *channel = malloc(sizeof(*channel));
+ if(client->channel)
+ for(lchannel = client->channel; lchannel->next; lchannel = lchannel->next) {}
+ channel->name = strdup(argv[2]);
+ channel->next = NULL;
+ channel->prev = lchannel;
+ if(lchannel)
+ lchannel->next = channel;
+ else
+ client->channel = channel;
+ }
+ } else if(!stricmp(argv[1], "PART")) {
+ struct IRCUser from = ircclient_parse_user(argv[0]);
+ if(!stricmp(from.nick, session->nick)) {
+ struct IRCChannel *channel;
+ for(channel = client->channel; channel; channel = channel->next) {
+ if(!stricmp(channel->name, argv[2])) {
+ if(channel->prev)
+ channel->prev->next = channel->next;
+ else
+ client->channel = channel->next;
+ if(channel->next)
+ channel->next->prev = channel->prev;
+ free(channel->name);
+ free(channel);
+ break;
+ }
+ }
+ }
+ } else if(!stricmp(argv[1], "KICK")) {
+ if(!stricmp(argv[3], session->nick)) {
+ struct IRCChannel *channel;
+ for(channel = client->channel; channel; channel = channel->next) {
+ if(!stricmp(channel->name, argv[2])) {
+ if(channel->prev)
+ channel->prev->next = channel->next;
+ else
+ client->channel = channel->next;
+ if(channel->next)
+ channel->next->prev = channel->prev;
+ free(channel->name);
+ free(channel);
+ break;
+ }
+ }
+ }
+ } else if(!stricmp(argv[1], "NICK")) {
+ struct IRCUser from = ircclient_parse_user(argv[0]);
+ if(!stricmp(from.nick, session->nick)) {
+ free(session->nick);
+ session->nick = strdup(argv[2]);
+ }
}
}
if(pass_to_client)
for(recover_line = client->recover_header; recover_line; recover_line = recover_line->next) {
usersession_client_raw(session, recover_line->line);
}
-
+ struct IRCChannel *channel;
+ char raw[LINELEN];
+ for(channel = client->channel; channel; channel = channel->next) {
+ sprintf(raw, ":%s!%s@TransparentIRC.session.recover JOIN %s", client->session->nick, client->session->username, channel->name);
+ usersession_client_raw(session, raw);
+
+ sprintf(raw, "NAMES %s", channel->name);
+ ircclient_send(client, raw);
+ }
}
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;
/* ****************** 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);
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) {
}
}
+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);
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");