Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
C IRC bot skeleton
#1
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
<Aoi-chan> everyone's first vi session. ^C^C^X^X^X^XquitqQ!qdammit[esc]qwertyuiopasdfghjkl;:xwhat
Reply
#2
Awesome lol, definetly a great skeleton. I wish I would have looked here before googling for an hour ;_;
[Image: nv70ad.png]
Terrorcore, unleash, extermination
Hyper real, cold blood, determination
fudge them, I like this sensation
Incredible, I from the annihilation
Reply
#3
Very nice skeleton. How long did it take in all for this "rough draft" ?
Reply
#4
(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.
<Aoi-chan> everyone's first vi session. ^C^C^X^X^X^XquitqQ!qdammit[esc]qwertyuiopasdfghjkl;:xwhat
Reply
#5
Wow, it looks good. Keep up with the nice coding.
Reply
#6
This is good, do you think you could do a C++ one, as well?
Reply
#7
Fallen wrote a nice one in C++ here.
<Aoi-chan> everyone's first vi session. ^C^C^X^X^X^XquitqQ!qdammit[esc]qwertyuiopasdfghjkl;:xwhat
Reply
#8
Awesome job coding that dude it's pretty sick.
Reply
#9
Best one I've seen, out of many languages. Foolin' wit it now Big Grin
Reply
#10
--off topic--
-no hate intended--
( why are all IRC Bot sources here for linux? )
slowly getting better
Reply


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

Forum Jump:


Users browsing this thread: 2 Guest(s)