Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
C IRC bot skeleton
#11
(11-23-2010, 08:08 PM)Old Dirty Bastard Wrote: --off topic--
-no hate intended--
( why are all IRC Bot sources here for linux? )

Code:
#ifdef NIX
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#endif

#ifdef WIN32
#define _WIN32_WINNT 0x0501 //Minimum winapi "version" to use
#include <winsock2.h>
#include <ws2tcpip.h>
#define close closesocket
#endif

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#define BUFSIZE 512
#define PSYCHO  NULL

/***********************
* argv[1] -> host
* argv[2] -> port
* argv[3] -> chan
* argv[4] -> nick
* argv[5] -> user
***********************/

struct irc_data {
    char nick[32];
    char user[32];
    char host[64];
    char chan[32];
    char message[512];
    int is_ready;
};

void die(const char*,int);
void parse_data(char*,struct irc_data**);
int  sayc(int,const char*,const char*, ...);

int main(int argc, char **argv){
    
    #ifdef WIN32
    WSADATA wsaData;
    WORD wVersionRequested = MAKEWORD(2, 2);
    if (WSAStartup(wVersionRequested, &wsaData) != 0) {
        fprintf(stderr,"Winsock error");
    }
    #endif
    
    if(argc!=6){
        fprintf(stderr,"usage: %s <host> <port> <chan> <nick> <ident>\n",argv[0]);
        exit(1);
    }

    const char *host = argv[1];
    const char *port = argv[2];
    const char *chan = argv[3];
    const char *nick = argv[4];
    const char *user = argv[5];

    char buff[BUFSIZE], ip[INET_ADDRSTRLEN];
    int sfd,status,sent,recvd,i;
    struct addrinfo hints,*serv;
    struct sockaddr_in *sip;
    struct irc_data *irc = malloc(sizeof(struct irc_data));

    memset(&hints,0,sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;

    if((status=getaddrinfo(host,port,&hints,&serv))<0)
        die("getaddrinfo",status);
    if((sfd=socket(serv->ai_family,serv->ai_socktype,serv->ai_protocol))<0)
        die("socket",sfd);
    if((status=connect(sfd,serv->ai_addr,serv->ai_addrlen))<0)
        die("connect",status);

    sip = (struct sockaddr_in*)serv->ai_addr;
    //inet_ntop(serv->ai_family,&sip->sin_addr,ip,sizeof(ip)); No idea why Psycho put this here since he is not storing the result.

    snprintf(buff,BUFSIZE,"USER %s 8 * :\x50\x73\x79\x63\x68\x6F\x20\x42\x6F\x74\r\nNICK %s\r\nJOIN #%s\r\n",user,nick,chan);
    if((sent=send(sfd,buff,strlen(buff),0))<0)
        die("send",sent);

    while((recvd=recv(sfd,buff,BUFSIZE-1,0))>=0){
        buff[recvd-1]=0;
        puts(buff);
        parse_data(buff,&irc);
        if(irc->is_ready)
            if(strstr(irc->message,nick) != NULL)
                sayc(sfd,irc->chan,"sup %s",irc->nick);
        if(sscanf(buff,"PING :%s",buff)==1){
            snprintf(buff,BUFSIZE,"PONG :%s",buff);
            if(send(sfd,buff,strlen(buff),0)>0)
                puts("PONG!");
            else puts("PONG failed...just sayin");
        }
        
    }
    free(irc);
    close(sfd);
    freeaddrinfo(serv);
    
    #ifdef WIN32
    WSACleanup ();
    #endif
    
    return 0;
}


void die(const char *msg, int err){
    fprintf(stderr,"%s: %s\n",msg,gai_strerror(err));
    exit(1);
}

void parse_data(char *buff,struct irc_data **fat){
    if(sscanf(buff,":%[^!]!%[^@]@%[^ ] %*[^ ] %[^ :] :%[^\r\n]",(*fat)->nick,(*fat)->user,(*fat)->host,(*fat)->chan,(*fat)->message) == 5){
        (*fat)->is_ready = 1;
        if((*fat)->chan[0] != '#') strcpy((*fat)->chan,(*fat)->nick);
    } else (*fat)->is_ready = 0;
}

int sayc(int sockfd, const char *chan, const char *fmt, ...){
    char msg[BUFSIZE], k[BUFSIZE];    //need to change sizes..do it later
    va_list list;
    va_start(list,fmt);
    vsnprintf(k,BUFSIZE,fmt,list);
    snprintf(msg,BUFSIZE,"PRIVMSG %s :%s\r\n",chan,k); //potential problem with \r\n being truncated if string is too large..do it later
    va_end(list);
    return send(sockfd,msg,strlen(msg),0);
}
// Psycho

BAM and it can now be compiled for *nix or windows. Make sure to define WIN32 and link winsock2 if you want to compile it for windows or NIX if you want to compile it for some unix-like operating system. How I compile it:
For windows:
Code:
i586-mingw32msvc-cc -DWIN32 ircbot.c -o ircbot.exe -lws2_32
For Linux:
Code:
cc -DNIX ircbot.c -o ircbot
Reply
#12
Nice share pyscho Smile
Reply
#13
Amazing, works under linux Smile
Thanks alot Salmon
Reply
#14
Thanks for the share, I'm sure this will help a lot of people out!
Hope to see more from you soon Smile
Reply
#15
This is going to be very useful for me, thank you so much for sharing this with us all.
[Image: dHtHt.png]

Learning C++
Reply
#16
Well, sorry for takeing up an old thread, but I really have to say, that i really like your code!

There's just one thing i don't get: My Client (in this case XChat), tells me that the real name from this bot is "Psycho Bot", but where do you set that Name? I don't get it out of the source code.


Thanks

~ Tectu
Reply
#17
What a cool bot source thank you for your share you kind sir Smile
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  IRC Class Libaray 1.1 - C++ IRC bots made easy delme 19 8,158 09-22-2011, 06:43 AM
Last Post: Mike.X.
  Runescape Bot? #Nix 7 3,894 08-28-2011, 11:54 AM
Last Post: Bigandrewgold
  [C++] IRC Bot. wchar_t 25 15,456 06-05-2011, 12:30 AM
Last Post: USN

Forum Jump:


Users browsing this thread: 1 Guest(s)