X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2FIRCClient.c;h=eee86b1f8162d78e6f4fc81cc0416dfed58b17ef;hb=2d411320c5f1fbfff3862f5fa8c1f1e6b7b6f9d0;hp=46e030ea45ff47600042dbf9d21dc9a76ed2ae7a;hpb=8889b0aee1dc430e735e2a0df462fd0aeee63847;p=TransparentIRC.git diff --git a/src/IRCClient.c b/src/IRCClient.c index 46e030e..eee86b1 100644 --- a/src/IRCClient.c +++ b/src/IRCClient.c @@ -53,6 +53,12 @@ void ircclient_close(struct IRCClient *client) { client->session->irc = NULL; iohandler_printf(client->iofd, "QUIT :[TransparentIRC] Quit"); iohandler_close(client->iofd); + struct IRCLine *recover_line, *next_line; + for(recover_line = client->recover_header; recover_line; recover_line = next_line) { + next_line = recover_line->next; + free(recover_line->line); + free(recover_line); + } free(client); } @@ -66,6 +72,35 @@ static void ircclient_handshake(struct IRCClient *client) { 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]; @@ -85,7 +120,89 @@ static void ircclient_recv(struct IRCClient *client, char *line) { 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") || + !stricmp(argv[1], "004") || + !stricmp(argv[1], "005") || + !stricmp(argv[1], "375") || + !stricmp(argv[1], "372") || + !stricmp(argv[1], "376") + ) { + //save these raw's for recovering the connection later + struct IRCLine *recover_line = NULL, *new_line; + if(client->recover_header) + for(recover_line = client->recover_header; recover_line->next; recover_line = recover_line->next) {}; + new_line = malloc(sizeof(*new_line)); + if(new_line) { + new_line->line = strdup(line); + new_line->next = NULL; + if(recover_line) + recover_line->next = new_line; + 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) usersession_client_raw(session, line); @@ -114,3 +231,21 @@ static void ircclient_callback(struct IOEvent *event) { void ircclient_send(struct IRCClient *client, char *line) { iohandler_printf(client->iofd, "%s", line); } + +void ircclient_recover_session(struct UserSession *session) { + struct IRCClient *client = session->irc; + //replay header + struct IRCLine *recover_line; + 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); + } +}