All pastes #289315 Raw Edit

corrideat

public text v1 · immutable
#289315 ·published 2006-12-23 01:27 UTC
rendered paste body
/*
* 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  USA

Author: Ricardo I. Vieitez
Release 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 open
unBFile.open("./noubuntu.bot.log",ios::out); // Open the file
unBFile.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;

}