From 4945e55956878279f04562fe55f48d8071bb5e46 Mon Sep 17 00:00:00 2001
From: FreeArtMan <dos21h@gmail.com>
Date: Sun, 21 Aug 2016 10:14:02 +0100
Subject: Mini irc 'bot' supports 3 commands. Also can do echo replay on PM or
 chat message

---
 mini_irc/Makefile   |   2 +
 mini_irc/mini_irc.c | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 375 insertions(+)
 create mode 100644 mini_irc/Makefile
 create mode 100644 mini_irc/mini_irc.c

(limited to 'mini_irc')

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
-- 
cgit v1.2.3