From 6ee4a512b7cd25eaff6754d51388f50fcbe40237 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Carlos=20R=C3=ADos=20V?= Date: Wed, 21 Jan 2009 02:56:06 -0300 Subject: [PATCH] Added a command parser ( irc_md.c irc_cmd.h ) =) --- .b_socket.c.swp | Bin 12288 -> 0 bytes .config.c.swp | Bin 12288 -> 0 bytes .config.h.swp | Bin 12288 -> 0 bytes Makefile | 5 +++ asdf.c | 19 +++++++++ b_socket.c | 88 +++++++++++++++++++++++++++++++++------ b_socket.c~ | 40 ------------------ b_socket.h | 21 +++++++--- cbot.conf | 11 +++-- config.c | 5 +++ config.c~ | 41 ------------------ config.h | 11 +++-- config.h~ | 30 ------------- irc_cmd.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ irc_cmd.h | 26 ++++++++++++ plan | 12 +++--- 16 files changed, 294 insertions(+), 142 deletions(-) delete mode 100644 .b_socket.c.swp delete mode 100644 .config.c.swp delete mode 100644 .config.h.swp create mode 100644 Makefile create mode 100644 asdf.c delete mode 100644 b_socket.c~ delete mode 100644 config.c~ delete mode 100644 config.h~ create mode 100644 irc_cmd.c create mode 100644 irc_cmd.h diff --git a/.b_socket.c.swp b/.b_socket.c.swp deleted file mode 100644 index 3cc3eaa5149113f918cda7877cc8791ad7883b4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcwPel00001 literal 12288 zcwX(A&ui0Q7{}k~Y0jxAIFIi-9BpZvc5Y7SHW;Oov2~lPn+KJUrf=G~HYrIunKHe3 z7IB{RFHuAf-V{Ob4-ou;=w0ySH%-!{8#tJ!$@8I~rFrtc&-*^_`(DaY$*#|r_+(~` zfm4hn9@gf69j&u(ImT4Wv^RyNuzhHn;^O#zjljJip`=z!N2u+kubZHMkB7P=Z5{!Jj7>`vE_~*YFj50=MA? zyamf}3Z8>Q@cSTRZ{Rcd6t2Q6a1wq!&e#|D0q(%Z@Bv(hc{l;HP=aUSZ_N1HI)AoVe+vm6EzV;%jPrIZ z#Vc)16PDY*-xBKPuDrqX6whVH##6jhzAUd4iwnVcx9fUC#B+(e-XN&J5UR5$31*+3 zQFPg@r}wTQjL6*m{^6{9i=5`(mv}dYrZn}&R+!R#?rgP07-?CiW2$B&9HgXd2=3H{ zpR7ApO*r9tdwY?d(JfWBg|+D}K{VDfEz~vYKJtnh^>?U~DhOvHQ^M@a%Y_BGe08-r zTgvZg=aqt1vvcy=QhB9V@Y*y*({@XajFnAsTfZYrEgr-Y;n0rNRvjKx!oyxk%+O1T z6VSV|{=up%mcQTEvE36l{gmEDbPjCRPoQ;A>-02VT3cM?3Fc1H8iuFZhHg96OnoL2Q>>OE>4w`j8n(A=Dag?icd#h6 q-La}}x*^7s2Sh?we6SV=f#FQ@@V$DT=I)#J!Rf?`@^*_yVSfNHh4dy(_+iCAT=k$EsSu~xEsg?2_x}KjA;It6y zPd3Y2L#{ZO7Q)ubY)fs4KGc-FcD0`oc+?D7us2jtu$Aw4n|ZsR8^bVz(g>W%8zbV% z%=A?FaV&L-&YfNE=fyA#!!QiPFwB2MP#+SHaXprN&Lr2Njw{1348t%C!!QiPFh>`w zBE*m5LcACj(f|L=-~XRRh1i20LUYg==<6vVzCa(LSI{%)DYOUeLMu=ax&WPrzKsa+ z0rH^|bQ$`7Qi%7^8|XE(1wDW~Cd0Z(Zr2 zr(?MBM=vAww$wfS;;p79We1~>M2VUhe+`*HH*8Em=A%vYc}eZij>KH7N{?<^eg!^C z$CL1UN8u$ER8VD7UeQ2G05oPw`(vn?r zR9*V%-{Yoq>R%1%a7s04jJ1gq681c4Mwn6Oq{4ipK56%hovZCX9lUPwUO% zCUOXZ^~eCep?h&K1ZGUl$LML2N)6u*JmniC?b&X0iy92GJ@G(AnT7Ris6hMzO|G)& diff --git a/.config.h.swp b/.config.h.swp deleted file mode 100644 index b5edfdcf413c73107e2abb431e1973925bd1e0fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcwPel00001 literal 12288 zcwX(A&ubGw6vtmmZ*8^cMX|^;Jw!vAv}x6Xcq*nwtcqwarKFqP+3sLE6K5w4BI-@> z(7(a|!T-UV|A8L73F05&oBh$4M2xg2<$d7GX6EhNdGmd9NXWLAx0_pdvswpY9-wx# z-<+O~;M)p-Z*+Vpj0Y1q(Bj70q??G>`2%ZyTicqiRVeqX(WEqnVNOfWhD+;nuv%YP zcEiQu6+D0L>7*=%VHk#C7=~f~BW$+-Z|FLejW1`{!pN0j7=~dOhG7_nVVHjxF96t{ z0r*aG|NrN||397uct?6mx<{HPeLe&5ffSQ=Nt>hwX@PW!^mPv46X}TbisX~FNUNj; z(nZn*(wA9)_as3ok)}w6*|dfqGk>a +#include + +#include "config.h" +#include "b_socket.h" + +int main( void ){ + + int x = IRC_RECONNECT; + struct _config *config = NULL; + config = set_config(); + + while( x == IRC_RECONNECT ){ + x = set_socket( config ); + } + + return 0; + +} diff --git a/b_socket.c b/b_socket.c index 63e3a36..7a10986 100644 --- a/b_socket.c +++ b/b_socket.c @@ -1,30 +1,36 @@ -/* b_socket.c - cbot socket set up +/* b_socket.c - cbot socket set up * ====================================================== * ********************************************************/ #include #include +#include +#include #include +#include #include #include #include "b_socket.h" #include "config.h" +#include "irc_cmd.h" int set_socket( struct _config *config ){ - if( config == NULL ) - return 0; + if( config == NULL ){ + printf("\n***ERROR*** There was an error with the configuration file.\n"); + return ERROR_EXIT; + } char buffer[1025]; + struct addrinfo hints, *res; int remote_socket; - struct addrinfo servaddr, *res; - memset( &servaddr, 0, sizeof(servaddr) ); - servaddr.ai_family = AF_UNSPEC; - servaddr.ai_socktype = SOCK_STREAM; + memset( &hints, 0, sizeof hints ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; - getaddrinfo( config->irc_server, config->irc_port, &servaddr, &res ); + getaddrinfo( config->irc_server, config->irc_port, &hints, &res ); /* Make the socket */ remote_socket = socket( res->ai_family, res->ai_socktype, res->ai_protocol); @@ -32,16 +38,74 @@ int set_socket( struct _config *config ){ /* connect! */ connect( remote_socket, res->ai_addr, res->ai_addrlen ); + + /*** SET NICK ***/ + char NICK[25]; + sprintf( NICK, "NICK %s\n", config->irc_nick); + send( remote_socket, NICK, strlen(NICK), 0 ); + + + /*** SET USER ***/ + char USER[256]; + sprintf( USER, "USER %s %s haha :%s\n", config->username, config->irc_server, config->irc_name ); + send( remote_socket, USER, strlen(USER), 0 ); + + // sleep(1); + + /*** JOIN INTO THE `config->irc_channel' ***/ + char JOIN[128]; + sprintf( JOIN, "JOIN %s\n", config->irc_channel ); + send( remote_socket, JOIN, strlen(JOIN), 0 ); + + struct irc_msg *IRCmsg; + while(1){ - recv( remote_socket, buffer, 1024, MSG_PEEK ); - printf( "\n%s", buffer ); + + if( recv( remote_socket, buffer, 1024, 0 ) > 0 ) + printf( "%s", buffer ); + + IRCmsg = irc_parser( buffer, config ); + + if( IRCmsg != NULL ){ + if(IRCmsg->type == EXIT_RESTART){ + send( remote_socket, IRCmsg->msg, strlen(IRCmsg->msg), 0); + printf("$BOT > %s", IRCmsg->msg_log); + /* CLOSE, FREE & EXIT! */ + close( remote_socket ); + freeaddrinfo( res ); + free( config ); + free(IRCmsg); + return IRC_RECONNECT; + } + + if(IRCmsg->type == NORMAL_MSG){ + send( remote_socket, IRCmsg->msg, strlen(IRCmsg->msg), 0 ); + printf("$BOT > %s", IRCmsg->msg_log); + } + + if(IRCmsg->type == EXIT){ + printlog(IRCmsg->msg_log); + /* CLOSE, FREE & EXIT! */ + close( remote_socket ); + freeaddrinfo( res ); + free( config ); + free(IRCmsg); + + return SUCCESS_EXIT; + } + + free(IRCmsg); + } + + /* Clean the buffer */ + memset( buffer, 0, sizeof(buffer) ); } - + /* CLOSE & FREE!! */ close( remote_socket ); freeaddrinfo( res ); free( config ); - return 1; + return SUCCESS_EXIT; } diff --git a/b_socket.c~ b/b_socket.c~ deleted file mode 100644 index 36f24a2..0000000 --- a/b_socket.c~ +++ /dev/null @@ -1,40 +0,0 @@ -/* b_socket.c - cbot socket set up - * ====================================================== - * - ********************************************************/ - -#include -#include -#include -#include -#include - -#include "b_socket.h" -#include "config.h" - -int set_socket( struct _config *config ){ - if( config == NULL ) - return 0; - - int remote_socket; - struct addrinfo servaddr, *res; - - memset( &servaddr, 0, sizeof(servaddr) ); - servaddr.ai_family = AF_UNSPEC; - servaddr.ai_socktype = SOCK_STREAM; - - getaddrinfo( config->irc_server, config->irc_port, &servaddr, &res ); - - /* Make the socket */ - remote_socket = socket( res->ai_family, res->ai_socktype, res->ai_protocol); - - /* connect! */ - connect( remote_socket, res->ai_addr, res->ai_addrlen ); - - - /* FREE!! */ - freeaddrinfo( res ); - free( config ); - - return 1; -} diff --git a/b_socket.h b/b_socket.h index 64c7d8e..49ddf20 100644 --- a/b_socket.h +++ b/b_socket.h @@ -1,7 +1,7 @@ /* b_socket.h - Prototypes of the sockets in the IRC bot. * ====================================================== * - * This file contains the prototypes of the function(s) + * This file contains the prototypes of the function(s) * that will be used by the bot to stablish a connection * between the IRC server and the IRC bot. ***********************************************************/ @@ -9,12 +9,23 @@ #ifndef _B_SOCKET_H #define _B_SOCKET_H -/* The `set_socket' function will (as the name says) set the +#include "config.h" + +#define IRC_RECONNECT 1 +#define ERROR_EXIT -1 +#define SUCCESS_EXIT 0 + +/* Other macros */ +#define printlog(MSG) printf("$BOT > %s", MSG) + +/* The `set_socket' function will (as the name says) set the * socket which allow the comunication between the IRC server - * and the bot. This function need a pointer to a + * and the bot. This function need a pointer to a * `struct _config' structure which contains the information - * of the connection. This function return an 'int' which is - * a file (socket) descriptor. + * of the connection (such as the server, nick, and so on). + * This function return an `int' value, this value is defined + * in the macros (IRC_RECONNECT, ERROR_EXIT, SUCCESS_EXIT) + * before in this file. ***********************************************************/ int set_socket( struct _config *config ); diff --git a/cbot.conf b/cbot.conf index 9c81db6..1894c96 100644 --- a/cbot.conf +++ b/cbot.conf @@ -1,4 +1,7 @@ -server: irc.cl -port: 6667 -channel: #coding -nick: Cbot +server: irc.cl +port: 6667 +channel: #linuxers +nick: Cbot +name: Cbot, a bot written in C. +username: the-bot +master: crosvera diff --git a/config.c b/config.c index 1b28814..6f80382 100644 --- a/config.c +++ b/config.c @@ -6,6 +6,7 @@ *******************************************************************/ #include +#include #include #include @@ -34,8 +35,12 @@ struct _config *set_config( void ){ fscanf( c_file, "port: %s\n", config->irc_port ); fscanf( c_file, "channel: %s\n", config->irc_channel ); fscanf( c_file, "nick: %s\n", config->irc_nick ); + fscanf( c_file, "name: %[^\n]\n", config->irc_name ); + fscanf( c_file, "username: %[^\n]\n", config->username ); + fscanf( c_file, "master: %s\n", config->master ); fclose( c_file ); /* Close the `CONFIG_FILE' */ + return config; } diff --git a/config.c~ b/config.c~ deleted file mode 100644 index b19dba0..0000000 --- a/config.c~ +++ /dev/null @@ -1,41 +0,0 @@ -/* config.c - Functions which reads a config file to set the bot - * =============================================================== - * - * The `CONFIG_FILE' macro is set in `config.h', this macro - * sets the path where the config file is. - *******************************************************************/ - -#include -#include -#include - -#include "config.h" - -struct _config *set_config( void ){ - FILE *c_file = NULL; - struct _config *config = NULL; - - /* Now we open the `CONFIG_FILE'. If an error happend, show a - * message, and return NULL. - ****************************************************************/ - c_file = fopen( CONFIG_FILE, "r" ); - if( c_file == (FILE *)NULL ){ - fprintf( stderr, "\n%s: %s\n", CONFIG_FILE, strerror( errno ) ); - return (struct _config *)NULL; - } - - config = (struct _config *) malloc( sizeof(struct _config) ); - - - /* Now we read the `CONFIG_FILE' and store the info into - * the config structure. - ***************************************************************/ - fscanf( c_file, "server: %s\n", config->irc_server ); - fscanf( c_file, "port: %d\n", &config->irc_port ); - fscanf( c_file, "channel: %s\n", config->irc_channel ); - fscanf( c_file, "nick: %s\n", config->irc_nick ); - - fclose( c_file ); /* Close the `CONFIG_FILE' */ - - return config; -} diff --git a/config.h b/config.h index 84d878e..303eb94 100644 --- a/config.h +++ b/config.h @@ -15,10 +15,13 @@ * the config file. ************************************************************/ struct _config{ - char irc_server[128]; - char irc_port[5]; - char irc_channel[30]; - char irc_nick[30]; + char irc_server[129]; + char irc_port[6]; + char irc_channel[16]; + char irc_nick[16]; + char irc_name[30]; + char username[30]; + char master[16]; }; /* The `set_config' function will read CONFIG_FILE and will diff --git a/config.h~ b/config.h~ deleted file mode 100644 index aaf51d0..0000000 --- a/config.h~ +++ /dev/null @@ -1,30 +0,0 @@ -/* config.h - Prototypes of the configuration's functions - * ======================================================== - * - * This file contains the prototypes of the functions which - * reads the config file. This config file will contains - * the IRC server, port , channel where the bot will - * connect, and the nickname of the bot. - ************************************************************/ -#ifndef _CONFIG_H -#define _CONFIG_H - -#define CONFIG_FILE "./cbot.conf" - -/* The follow structure sets the information that contains - * the config file. - ************************************************************/ -struct _config{ - char irc_server[128]; - int irc_port; - char irc_channel[30]; - char irc_nick[30]; -}; - -/* The `set_config' function will read CONFIG_FILE and will - * set the information required to the irc-bot. The required - * information will be stored into a `_config' structure. - ***********************************************************/ -struct _config *set_config( void ); - -#endif /* _CONFIG_H */ diff --git a/irc_cmd.c b/irc_cmd.c new file mode 100644 index 0000000..06a1332 --- /dev/null +++ b/irc_cmd.c @@ -0,0 +1,127 @@ +/* irc_cmd.c - Functions which allows parse and execute + * a set of commands into the IRC bot. + * ===================================================== + * + * + **********************************************************/ + +#include +#include +#include + +#include "irc_cmd.h" +#include "config.h" + +static struct irc_msg *master_command( const char *raw_msg, struct _config *config ){ + + char *ptr = NULL, *msg_to_send = NULL; + struct irc_msg *IRCmsg = NULL; + + /* Did `config->master'said something important like a command to the bot ? + * ***REMEMBER*** these commands must be sent via a PRIVMSG to the bot from + * the `config->master'. + ***************************************************************************/ + char *PRIVMSG = (char *)calloc( 1 + + strlen("PRIVMSG ") + strlen(config->irc_nick), sizeof(char) ); + + sprintf( PRIVMSG, "PRIVMSG %s ", config->irc_nick ); + int privmsg_len = strlen(PRIVMSG); + + if( strncmp(PRIVMSG, raw_msg, privmsg_len) == 0 ){ + /* What command did `config->master` sent ? */ + + /** the !say command? **/ + ptr = strstr( &raw_msg[privmsg_len], ":!say " ); + if( ptr != NULL ){ + IRCmsg = (struct irc_msg *)malloc( sizeof(struct irc_msg) ); + + msg_to_send = (char *)calloc( 1 + + strlen(&ptr[6]) + strlen("PRIVMSG :") + strlen(config->irc_channel) , sizeof(char) ); + sprintf(msg_to_send, "PRIVMSG %s :%s", config->irc_channel, &ptr[6]); + + IRCmsg->type = NORMAL_MSG; + IRCmsg->msg = msg_to_send; + IRCmsg->msg_log = msg_to_send; + + return IRCmsg; + }/*** END !say COMMAND */ + + /** The !quit command? **/ + ptr = strstr( &raw_msg[privmsg_len], ":!quit"); + if( ptr != NULL ){ + IRCmsg = (struct irc_msg *)malloc( sizeof(struct irc_msg) ); + + IRCmsg->type = EXIT; + IRCmsg->msg = NULL; + IRCmsg->msg_log = "EXIT command recived from the master.... BYE!\n"; + + return IRCmsg; + }/*** END !quit COMMAND **/ + + /** The !raw command? **/ + ptr = strstr( &raw_msg[privmsg_len], ":!raw"); + if( ptr != NULL ){ + IRCmsg = (struct irc_msg *)malloc( sizeof(struct irc_msg) ); + + IRCmsg->type = NORMAL_MSG; + IRCmsg->msg = &ptr[6]; + IRCmsg->msg_log = &ptr[6]; + + return IRCmsg; + } + + } + + return (struct irc_msg *)NULL; +} + +struct irc_msg *irc_parser( const char *raw_entry, struct _config *config ){ + struct irc_msg *IRCmsg = NULL; + IRCmsg = (struct irc_msg *)malloc( sizeof(struct irc_msg) ); + + char *msg_to_send = NULL, *ptr = NULL; + + + if( *raw_entry == ':' ){ + /* Did the `config->master' said something? */ + if( strncmp(&raw_entry[1], config->master, strlen(config->master)) == 0 ){ + /* Now we search the possition after the first ' ' in `raw_entry' + * because that is the location of the message. */ + ptr = strchr( raw_entry, ' ' ); + ptr++; + + return master_command( ptr, config ); + } + + }else{ + /* Search the location after the first ' ' in `raw_entry' */ + ptr = strchr( raw_entry, ' ' ); + ptr++; + + /***PING RESPONSE***/ + if( strncmp( raw_entry, "PING", 4 ) == 0 ){ + msg_to_send = (char *)calloc(4 + strlen(&raw_entry[5]), sizeof(char)); + sprintf( msg_to_send, "PONG %s", &raw_entry[5] ); + IRCmsg->type = NORMAL_MSG; + IRCmsg->msg = msg_to_send; + IRCmsg->msg_log = msg_to_send; + + return IRCmsg; + } + + /***KILL RESPONSE***/ + char *kill_msg = NULL; + kill_msg = (char *)calloc(7 + strlen(config->irc_nick), sizeof(char)); + sprintf( kill_msg, "KILL %s\n", config->irc_nick); + if( strncmp(kill_msg, ptr, strlen(kill_msg) ) == 0 ){ + char *msg2log = "\n*** The bot was killed, time to re-connect!!***\n"; + IRCmsg->type = EXIT_RESTART; + IRCmsg->msg = NULL; + IRCmsg->msg_log = msg2log; + + return IRCmsg; + } + } + + return NULL; +} diff --git a/irc_cmd.h b/irc_cmd.h new file mode 100644 index 0000000..1b81908 --- /dev/null +++ b/irc_cmd.h @@ -0,0 +1,26 @@ +/* irc_cmd.h - Prototypes of the functions which allows + * parse and execute a set of commands into the IRC bot + * ===================================================== + * + * + **********************************************************/ + +#include "config.h" + +#define NORMAL_MSG 0 +#define EXIT_RESTART 1 +#define EXIT 2 + + +/* The follow structure will be filled with the `irc_parser' + * function, and will save some basic information about a + * message sent to the channel. + ***********************************************************/ +struct irc_msg{ + int type; /* Type of the message */ + char *msg; /* The message to send*/ + char *msg_log; /* The message to send to the log */ +}; + +struct irc_msg *irc_parser( const char *raw_entry, struct _config *config ); + diff --git a/plan b/plan index 38dc6ba..3295d72 100644 --- a/plan +++ b/plan @@ -2,16 +2,16 @@ PLAN: ^^^^^ Make an IRC bot in ANSI C. -It must be able to access to a data-base (PostgreSQL) to read and save +It must be able to access to a data-base (SQLite) to read and save information - quotes, actions, etc... - and should respond to a basic command set. --------- -------------- ---------- -| CBot |<-->| PostgreSQL |<---| Quotes | --------- -------------- ==========---- - Î Î-----| Dictionary | - | ------------ -------------- +-------- ---------- ---------- +| CBot |<-->| SQLite |<---| Quotes | +-------- ---------- ==========---- + Î Î------| Dictionary | + | ------------ -------------- +----| Commands | | ============--- +--->| Config file | -- 2.11.4.GIT