Support Forums

Full Version: C IRC bot skeleton
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Well, simply put I wrote this IRC bot 'skeleton' in C. It's still widely open for improvements, this is like a 'rough draft,' so to speak. I'm sharing this in hopes I could get some input and constructive criticism. Good or bad, all criticism is appreciated...anything that would help me improve it, that is. So far it simply idles in IRC and pongs when pinged by the server and says "sup %s" where %s is the nick of the person who said its nick...but that's all a skeleton should be. Tongue

Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <arpa/inet.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){

    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));

    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);
}


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
Awesome lol, definetly a great skeleton. I wish I would have looked here before googling for an hour ;_;
Very nice skeleton. How long did it take in all for this "rough draft" ?
(04-05-2010, 06:48 PM)Fallen Wrote: [ -> ]Awesome lol, definetly a great skeleton. I wish I would have looked here before googling for an hour ;_;

Thanks Fallen, and yeah I had that trouble too, so I just thought I'd waste time and make my own.


(04-05-2010, 09:12 PM)php Wrote: [ -> ]Very nice skeleton. How long did it take in all for this "rough draft" ?

Thanks. It took a few days to work on it off and on. It was worth it.
Wow, it looks good. Keep up with the nice coding.
This is good, do you think you could do a C++ one, as well?
Fallen wrote a nice one in C++ here.
Awesome job coding that dude it's pretty sick.
Best one I've seen, out of many languages. Foolin' wit it now Big Grin
--off topic--
-no hate intended--
( why are all IRC Bot sources here for linux? )
Pages: 1 2