/** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USAAuthor: Ricardo I. VieitezRelease date: 01-May-2006 (XXI)Designed for GNU/Linux*/#include <iostream>#include <fstream>#include <sys/types.h>#include <sys/socket.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <sys/uio.h>#include <netinet/in.h>#include <netdb.h>#include <fcntl.h>#include <sys/stat.h>#include <time.h>#include <errno.h>#include "irc.h" /* irc Class */using namespace std;int cij;bool irc::copyval(char* &dest, const char* src){ if(dest) { if (strlen(src) > strlen(dest)) { delete [] dest; dest=new char[strlen(src)+1]; // If can't obtain memory, return false if (!dest) return false; } } else { dest=new char[strlen(src)+1]; // If can't obtain memory, return false if (!dest) return false; } strcpy(dest,src); return true;}irc::irc() : m_iPort(0), m_pszServer(NULL), m_pszNick(NULL), m_pszUsern(NULL), m_pszRealn(NULL), m_pszNS(NULL), m_pszChannel(NULL), m_bQ(false) {}bool irc::setServer(const char * pszArray) { return copyval(m_pszServer,pszArray);}bool irc::setPort(const int num) { m_iPort=num; if (m_iPort==num) return true; else return false;}bool irc::setNick(const char * pszArray) { return copyval(m_pszNick,pszArray);}bool irc::Name(const char * pszArray1, const char * pszArray2) { return copyval(m_pszUsern,pszArray1) && copyval(m_pszRealn,pszArray2);}bool irc::setNS(const char * pszArray) { return copyval(m_pszNS,pszArray);}bool irc::setChannel(const char * pszArray) { return copyval(m_pszChannel,pszArray);}void irc::receive(int m_iSock, char *pszRBuff){ int cii=0;char cchar[2]; while (cchar[0]!= '\n') { if (read(m_iSock, cchar, 1) == -1) return; strcpy (pszRBuff + cii, cchar); pszRBuff[++cii] = 0; }}void irc::ssend(int m_iSock,char *pszSBuff,bool bOut){ write(m_iSock,pszSBuff,strlen(pszSBuff)); if (bOut) cout << "-> " << pszSBuff << "\n";}bool irc::servConnect() {fstream unBFile; // Files to openunBFile.open("./noubuntu.bot.log",ios::out); // Open the fileunBFile.seekg(0,ios::end);start: printf("***\n*** STARTING BOT...\n***\n"); // Start socket // Iniciar socket m_iSoc=socket(AF_INET,SOCK_STREAM,0); // If could'n open socket // Si no se pudo abrir el socket if(m_iSoc==-1) { cerr << "Couldn't open socket"; return false; } // If couldn't resolve server address // Si no se pudo resolver la direccin del servidor m_server=gethostbyname(m_pszServer); if(m_server==NULL) { cerr << "Couldn't resolve server address"; return false; } // Opening connection // Abriendo conexin m_connection.sin_family=AF_INET; m_connection.sin_addr=*(struct in_addr *)m_server->h_addr; m_connection.sin_port=htons(m_iPort); // Connect // Conectar m_iStatus=connect(m_iSoc,(struct sockaddr *)&m_connection,sizeof(m_connection)); // If there was a connection error // Si hubo un error de conexin if(m_iStatus==-1) { cerr << "Connection error. Trying again..."; close(m_iSoc); sleep(5); goto start; } // Change to Identify mode // Cambiar al modo Identificacin m_mode=IDENTIFY; // Main loop // Bucle principal while(1) { switch(m_mode) { // If Restart needed // En el modo Restart case RESTART: goto start; break; // Identify mode // Modo Identificacin case IDENTIFY: // Send Nick information // Enviar informacin de Nick sprintf(cBuf,"NICK %s\n",m_pszNick); ssend(m_iSoc,cBuf); // Send user info (such as username and realname) // Enviar informacin de usuario (como nombre de usuario y nombre real) sprintf(cBuf,"USER %s %s %s %s\n",m_pszUsern,m_pszNick,m_pszNick,m_pszRealn); ssend(m_iSoc,cBuf); p=cBuf; m_eFlag=OK; // Change to Idle mode // Cambiar a modo Idle m_mode=IDLE; // Idle mode // En modo Idle case IDLE: // Read buffer // Leer del buffer m_iStatus=read(m_iSoc,p,1); if(!m_iStatus && !m_bQ) { close(m_iSoc); m_mode=RESTART; } // If bot is exiting // Si el bot est terminando if (m_bQ) { close(m_iSoc); printf("***\n*** QUITING (requested)...\n***\n"); exit(0); } // If there are too much lines, set flag Overflow // Si hay muchas lneas, marcar con bandera "desbordamiento" if(p-cBuf>=BUF_LEN-3) { m_eFlag=OVERFLOW; if(*p!='\n') { p=cBuf; break; } } // Overflow mode // Si est la bandera Desbordamiento if (m_eFlag==OVERFLOW) { cout << "-> __OVERFLOW__\n"; unBFile.write("-> __OVERFLOW__\n",sizeof("-> __OVERFLOW__\n")); bzero(cBuf,sizeof(cBuf)); m_eFlag=OK; break; } // Clean buffer // Limpiar buffer bzero(cBuf,sizeof(cBuf)); // Receive buffer // Recibir buffer receive(m_iSoc,cBuf); // PONG server // PONG al servidor// sprintf(cBuf2,"%s PONG %s :475869159",m_pszServer,m_pszServer);// sprintf(cBuf3,":%s PONG %s :475869159",m_pszServer,m_pszServer); if (strstr(cBuf,cBuf2) == NULL || strstr(cBuf,cBuf3) != NULL) { cout << cBuf; // Output buf if (strstr(cBuf,"PRIVMSG") && strstr(cBuf,"@") && strstr(cBuf,"!") && strstr(cBuf," ") && strstr(cBuf,":") && strcasestr(cBuf,m_pszChannel)) { bzero(cBuf2,sizeof(cBuf2)); sprintf(cBuf2,"<%s> %s",msgInfo().nick,(msgInfo().msg)+1); unBFile.write(cBuf2,sizeof(cBuf2)); cout << cBuf2; } } // Intelligent bot BotAction(); bzero(cBuf2,sizeof(cBuf2)); bzero(cBuf3,sizeof(cBuf3)); if (strstr(cBuf,"MOTD")) // MODT Received { ssend(m_iSoc,"USERHOST GNU-A-CPP-Bot\n"); // Send User host ssend(m_iSoc,"PING :475869159\n"); // Ping server if (m_pszNS) { sprintf(cBuf,"NS IDENTIFY %s\n",m_pszNS); // Send NickServ info ssend(m_iSoc,cBuf,false); cout << "Sent NickServ information\n";sleep(2); } sprintf(cBuf,"JOIN %s\n",m_pszChannel); // Join a channel ssend(m_iSoc,cBuf); sprintf(cBuf,"NOTICE %s :%s bot activated\n",m_pszChannel,m_pszNick); ssend(m_iSoc,cBuf); }// ssend(m_iSoc,"PING :475869159\n",false); // Ping server // Ping mode // Modo PING if (strstr(cBuf,"PING")) { bzero(cBuf2,sizeof(cBuf2)); cij=0; while(cBuf[cij] != ':') cij++; memcpy(cBuf2,&cBuf[cij],strlen(cBuf)-cij-1); sprintf(cBuf,"PONG %s\n",cBuf2); cout << "---------- " << cBuf; ssend(m_iSoc,cBuf); } break; default: break; } } return 0;}