diff options
author | FreeArtMan <dos21h@gmail.com> | 2016-08-21 10:14:02 +0100 |
---|---|---|
committer | FreeArtMan <dos21h@gmail.com> | 2016-08-21 10:14:02 +0100 |
commit | 4945e55956878279f04562fe55f48d8071bb5e46 (patch) | |
tree | af89a45b108471531cf250ff6c593b1a84c143ce | |
parent | e6add15b639d94ddf9cc0f00e2e0d12ebbae5597 (diff) | |
download | code-snippets-4945e55956878279f04562fe55f48d8071bb5e46.tar.gz code-snippets-4945e55956878279f04562fe55f48d8071bb5e46.zip |
Mini irc 'bot' supports 3 commands. Also can do echo replay on PM or chat message
-rw-r--r-- | mini_irc/Makefile | 2 | ||||
-rw-r--r-- | mini_irc/mini_irc.c | 373 |
2 files changed, 375 insertions, 0 deletions
diff --git a/mini_irc/Makefile b/mini_irc/Makefile new file mode 100644 index 0000000..aaa89b6 --- /dev/null +++ b/mini_irc/Makefile @@ -0,0 +1,2 @@ +make: + gcc mini_irc.c -o mini_irc
\ No newline at end of file diff --git a/mini_irc/mini_irc.c b/mini_irc/mini_irc.c new file mode 100644 index 0000000..326c9e8 --- /dev/null +++ b/mini_irc/mini_irc.c @@ -0,0 +1,373 @@ +#include <ctype.h> +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <netdb.h> +#include <sys/syscall.h> + +static char *nick = "cbot_git"; +static char *hostname = "irc.freenode.net"; +static char *port = "6667"; +static char *channel = "#mainlv"; + +static int conn; + +#define IO_STR str_cat_buf + +#define SYSC_WRITE(FD,X) write(FD,X,strlen(X)); +#define SYSC_WRITE_O(FD,STR) write(FD,(STR).str,(STR).sz);write(0,"<< ",4);write(0,(STR).str,(STR).sz); +#define SYSC_WRITE_I(FD,STR) write(FD,(STR).str,(STR).sz);write(0,">> ",4);write(0,(STR).str,(STR).sz); +#define SYSC_WRITE_IO0(FD) write(FD,(IO_STR).str,(IO_STR).sz);write(0,"<< ",4);write(0,(IO_STR).str,(IO_STR).sz); + +#define BUF_0(BUF) (BUF).sz=0; +#define BUF_ADD_STR(BUF,X) str_cat(BUF,X); +#define BUF_ADD_CHAR(BUF,C) {(BUF).str[(BUF).sz]=C;(BUF).sz+=1;} +#define BUF_CHAR(BUF,IDX) (BUF).str[IDX] +#define BUF_SZ(BUF) (BUF).sz +#define BUF_MAX(BUF) ((BUF).sz==BUF_MAX_SZ) +#define BUF_SET0(BUF) (BUF).str[(BUF).sz]=0; +#define BUF_STRCMP(BUF,STR) (!strncmp((BUF).str,STR,strlen(STR))) + +#define STR_0() (IO_STR).sz=0; +#define STR_ADD(X) str_cat((&IO_STR),X); + + + +#define BUF_MAX_SZ 1024 +typedef struct pos_str +{ + int sz; + char str[BUF_MAX_SZ+1]; +} pos_str; + +pos_str str_cat_buf; +pos_str str_buf; +pos_str serv_read; +pos_str serv_write; + +#define TOK_CMP(IDX,STR) ((strlen(STR)==strlen(tok[IDX].s)) && !(strncmp(tok[IDX].s,STR,strlen(STR)))) +#define TOK_NUM 20 +typedef struct token +{ + char *s, *e; +} token; +static int tok_cnt=0; +token tok[TOK_NUM]; + +char* skip(char *s, char c) +{ + while(*s != c && *s != '\0') + { + s++; + } + if(*s != '\0') + { + *s++ = '\0'; + } + return s; +} + +int str_cat(pos_str *buf, char *str) +{ + int i; + int pos=0; + int len = strlen(str); + + pos = buf->sz; + for (i=0;(i<len)&&(pos+i<BUF_MAX_SZ);i++) + { + buf->str[pos+i] = str[i]; + } + buf->sz = pos+i; + + return pos; +} + +int print_str(int fd, char *str) +{ + int ret = 0; + int len = strlen(str); + + write(fd, str, len); + + return ret; +} + +/* +return fd!=ifconnection there +*/ +int irc_connect( char *hostname, char *port ) +{ + int fd=0; + + struct addrinfo serv, *res; + + memset(&serv, 0, sizeof(serv)); + serv.ai_family = AF_INET; + serv.ai_socktype = SOCK_STREAM; + getaddrinfo(hostname, port, &serv, &res); + fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + connect(fd, res->ai_addr, res->ai_addrlen); + + return fd; +} + + + +int main() +{ + int i,j,m,len; + int ret; + char ch; + int wordcount; + char *user, *command, *where, *message, *iter, *start, *sep; + print_str(0,"Start programm\n"); + + //connect to server + conn = irc_connect( hostname, port ); + if (conn<1) + { + SYSC_WRITE(1,"Cannot connect\n"); + return -1; + } + + //send USER command + STR_0(); + STR_ADD("USER "); + STR_ADD(nick); + STR_ADD(" 0 0 :"); + STR_ADD(nick); + STR_ADD("\r\n"); + SYSC_WRITE_IO0(conn); + + //send NICK command + STR_0(); + STR_ADD("NICK "); + STR_ADD(nick); + STR_ADD("\r\n"); + SYSC_WRITE_IO0(conn); + + BUF_0(str_buf); + //server communication loop + while (ret=read(conn, serv_read.str, BUF_MAX_SZ)) + { + serv_read.sz = ret; + serv_read.str[ret]; + //SYSC_WRITE_I(0,serv_read); + + //parse to get commands + for (i=0;i<BUF_SZ(serv_read);i++) + { + BUF_ADD_CHAR(str_buf,BUF_CHAR(serv_read,i)); + ch = BUF_CHAR(serv_read,i); + if ((i>0 + && (BUF_CHAR(serv_read,i) == '\n') + && (BUF_CHAR(serv_read,i-1) == '\r')) + || + (BUF_MAX(str_buf))) + { + BUF_SET0(str_buf); + len = BUF_SZ(str_buf); + //printf("len = %d\n",len); + SYSC_WRITE_I(0,str_buf); + + //BUF_0(str_buf); + //check if ping then answer to ping + //if (BUF_STRCMP(str_buf,"PING")) + //{ + // STR_0(); + // STR_ADD("PONG\r\n") + // SYSC_WRITE_IO0(conn); + //} else + if (BUF_CHAR(str_buf,0) == ':') + { + #define START 1 + #define START_WORD 2 + #define CONTINUE 3 + #define MESSAGE 4 + #define END 5 + int state = START; + //printf("TOKENIZING\n"); + //tokenize string + tok_cnt = 0; + iter = str_buf.str; + + for (j=0;j<len;j++) + { + + + switch(state) + { + case START: + //printf("START %d %02x\n",j,iter[j]); + if (iter[j]==' ') + { + break; + } + if (iter[j]=='\0') + { + state = END; + break; + } + state = START_WORD; + break; + case START_WORD: + //printf("WORD\n"); + tok[tok_cnt].s = iter+j; + if (iter[j]==' ') + { + tok[tok_cnt].e = iter+j-1; + tok_cnt += 1; + state = START; + break; + } + if (iter[j]=='\0') + { + tok[tok_cnt].e = iter+j-1; + tok_cnt += 1; + state = END; + break; + } + if (iter[j]==':') + { + tok[tok_cnt].s = iter+j; + //tok_cnt += 1; + state = MESSAGE; + break; + } + state = CONTINUE; + break; + case CONTINUE: + //printf("CONTINUE\n"); + if ((iter[j]!=' ')&&(iter[j]!='\0')) + { + state = CONTINUE; + break; + } + if (iter[j]=='\0') + { + tok[tok_cnt].e = iter+j-1; + tok_cnt += 1; + state = END; + break; + } + if (iter[j]==' ') + { + tok[tok_cnt].e = iter+j-1; + tok_cnt += 1; + state = START_WORD; + break; + } + //printf("Unknown state\n"); + break; + case MESSAGE: + //printf("MESSAGE\n"); + if ((iter[j]=='\0')||(iter[j]=='\n')||(iter[j]=='\r')) + { + tok[tok_cnt].e = iter+j-1; + tok_cnt += 1; + state = END; + break; + } + state = MESSAGE; + break; + case END: + //printf("END\n"); + break; + default: + printf("ERR STATE %d\n",state); + return 0; + }; + + } + if ((state==CONTINUE)||(state==MESSAGE)) + { + tok[tok_cnt].e = iter+j-1; + tok_cnt += 1; + } + for (j=0;j<tok_cnt;j++) + { + write(0,tok[j].s,tok[j].e-tok[j].s+1); + *(tok[j].e+1)=0x0; + write(0,"]\n",2); + } + if (tok_cnt < 2 ) continue; + + //replay on commands + printf("CMD: %s\n",tok[1].s); + if (TOK_CMP(1,"NOTICE?")) + { + STR_0(); + STR_ADD(tok[1].s);//command + STR_ADD(" "); + STR_ADD(tok[2].s) + STR_ADD(" "); + STR_ADD(tok[3].s);//message + STR_ADD("\r\n"); + SYSC_WRITE_IO0(conn); + } else if (TOK_CMP(1,"PING")) + { + STR_0(); + STR_ADD("PONG :"); + STR_ADD(tok[0].s); + STR_ADD("\r\n"); + SYSC_WRITE_IO0(conn); + } else if (TOK_CMP(1,"PRIVMSG")) + { + //join command + if (TOK_CMP(3,":JOIN")) + { + STR_0(); + STR_ADD("JOIN "); + STR_ADD(channel) + STR_ADD("\r\n"); + SYSC_WRITE_IO0(conn); + //echo + } else + { + //if there is chan name then ech to chan + if (tok[2].s[0]=='#') + { + STR_0(); + STR_ADD(tok[1].s);//command + STR_ADD(" "); + STR_ADD(tok[2].s); + STR_ADD(" :"); + STR_ADD(tok[3].s+1); + STR_ADD("\r\n"); + SYSC_WRITE_IO0(conn); + } else + { + //get user name + sep = strchr(tok[0].s,'!'); + tok[0].s[sep-tok[0].s] = 0x0; + STR_0(); + STR_ADD(tok[1].s);//command + STR_ADD(" "); + STR_ADD(tok[0].s) + STR_ADD(" :"); + //STR_ADD(tok[2].s); + //STR_ADD("-"); + STR_ADD(tok[3].s+1);//message + STR_ADD("\r\n"); + SYSC_WRITE_IO0(conn); + } + } + } + + } + + BUF_0(str_buf); + } + } + } + + + print_str(0,"End program\n"); + + return 0; +}
\ No newline at end of file |