From 2373391b2e5fab03b93a50f89c93646267fae095 Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Sat, 26 Mar 2016 22:41:14 +1000 Subject: [PATCH] New experimental chat system based on IRC --- Makefile | 2 +- bbs.c | 10 +- bbs.h | 6 + chat_system.c | 292 +++++++++++++++++++++++++++++++++++++++++ config_default/bbs.ini | 3 + doors.c | 2 +- mail_menu.c | 2 +- main_menu.c | 7 +- 8 files changed, 319 insertions(+), 5 deletions(-) create mode 100644 chat_system.c diff --git a/Makefile b/Makefile index 7b59a9f..5a982ee 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ CFLAGS=-I/usr/local/include DEPS = bbs.h JAMLIB = jamlib/jamlib.a -OBJ = inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o doors.o bbs_list.o +OBJ = inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o doors.o bbs_list.o chat_system.o %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) diff --git a/bbs.c b/bbs.c index bd53269..8eed978 100644 --- a/bbs.c +++ b/bbs.c @@ -287,7 +287,13 @@ static int handler(void* user, const char* section, const char* name, conf->nodes = atoi(value); } else if (strcasecmp(name, "new user level") == 0) { conf->newuserlvl = atoi(value); - } + } else if (strcasecmp(name, "irc server") == 0) { + conf->irc_server = strdup(value); + } else if (strcasecmp(name, "irc port") == 0) { + conf->irc_port = atoi(value); + } else if (strcasecmp(name, "irc channel") == 0) { + conf->irc_channel = strdup(value); + } } else if (strcasecmp(section, "paths") == 0){ if (strcasecmp(name, "ansi path") == 0) { conf->ansi_path = strdup(value); @@ -569,6 +575,8 @@ void runbbs(int socket, char *config_path) { conf.mail_conference_count = 0; conf.door_count = 0; conf.file_directory_count = 0; + conf.irc_server = NULL; + conf.irc_port = 6667; // Load BBS data if (ini_parse(config_path, handler, &conf) <0) { diff --git a/bbs.h b/bbs.h index e0b5945..cbe3b95 100644 --- a/bbs.h +++ b/bbs.h @@ -76,6 +76,10 @@ struct bbs_config { char *bbs_path; char *email_path; + char *irc_server; + int irc_port; + char *irc_channel; + int nodes; int newuserlvl; int mail_conference_count; @@ -137,4 +141,6 @@ extern int mail_menu(int socket, struct user_record *user); extern int door_menu(int socket, struct user_record *user); extern void bbs_list(int socket, struct user_record *user); + +extern void chat_system(int sock, struct user_record *user); #endif diff --git a/chat_system.c b/chat_system.c new file mode 100644 index 0000000..23bc154 --- /dev/null +++ b/chat_system.c @@ -0,0 +1,292 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bbs.h" + +extern struct bbs_config conf; +extern int mynode; + +static char **screenbuffer; +static int chat_socket; +static int line_at; +static int row_at; +static char sbuf[512]; +extern struct user_record gUser; + +void scroll_up() { + int y; + + for (y=1;y<23;y++) { + strcpy(screenbuffer[y-1], screenbuffer[y]); + + } + memset(screenbuffer[22], 0, 81); + row_at = 0; +} + +void raw(char *fmt, ...) { + + va_list ap; + va_start(ap, fmt); + vsnprintf(sbuf, 512, fmt, ap); + va_end(ap); + write(chat_socket, sbuf, strlen(sbuf)); +} + +int hostname_to_ip(char * hostname , char* ip) { + struct hostent *he; + struct in_addr **addr_list; + int i; + + if ( (he = gethostbyname( hostname ) ) == NULL) + { + // get the host info + return 1; + } + + addr_list = (struct in_addr **) he->h_addr_list; + + for(i = 0; addr_list[i] != NULL; i++) { + strcpy(ip , inet_ntoa(*addr_list[i]) ); + return 0; + } + + return 1; +} +void append_screenbuffer(char *buffer) { + int z; + + for (z=0;zloginname, user->loginname); + raw("NICK %s\r\n", user->loginname); + raw("JOIN %s\r\n", conf.irc_channel); + + memset(buffer, 0, 513); + + screenbuffer = (char **)malloc(sizeof(char *) * 23); + for (i=0;i<23;i++) { + screenbuffer[i] = (char *)malloc(81); + memset(screenbuffer[i], 0, 81); + } + + while (1) { + FD_ZERO(&fds); + FD_SET(sock, &fds); + FD_SET(chat_socket, &fds); + + if (chat_socket > sock) { + t = chat_socket + 1; + } else { + t = sock + 1; + } + + ret = select(t, &fds, NULL, NULL, NULL); + + if (ret > 0) { + if (FD_ISSET(sock, &fds)) { + len = read(sock, &c, 1); + if (len == 0) { + raw("QUIT\r\n"); + disconnect(sock); + } + + if (c == '\r') { + if (inputbuffer[0] == '/') { + if (strcasecmp(&inputbuffer[1], "quit") == 0) { + raw("QUIT\r\n"); + for (i=0;i<22;i++) { + free(screenbuffer[i]); + } + free(screenbuffer); + return; + } + } else { + raw("PRIVMSG %s :%s\r\n", conf.irc_channel, inputbuffer); + sprintf(buffer2, "%s: %s", user->loginname, inputbuffer); + append_screenbuffer(buffer2); + do_update = 1; + } + memset(inputbuffer, 0, 80); + inputbuffer_at = 0; + } else if (c != '\n') { + if (c == '\b' || c == 127) { + if (inputbuffer_at > 0) { + inputbuffer_at--; + inputbuffer[inputbuffer_at] = '\0'; + do_update = 2; + } + } else if (inputbuffer_at < 79) { + inputbuffer[inputbuffer_at++] = c; + do_update = 2; + } + } + } + if (FD_ISSET(chat_socket, &fds)) { + len = read(chat_socket, &c, 1); + if (len == 0) { + s_putstring(sock, "\r\n\r\n\r\nLost connection to chat server!\r\n"); + for (i=0;i<22;i++) { + free(screenbuffer[i]); + } + free(screenbuffer); + return; + } + + if (c == '\r' || buffer_at == 512) { + if (!strncmp(buffer, "PING", 4)) { + buffer[1] = 'O'; + raw(buffer); + } else if (buffer[0] == ':') { + usr = cmd = where = message = NULL; + for (j=1;j 0) { + s_putstring(sock, inputbuffer); + } + do_update = 0; + } else if (do_update == 2) { + sprintf(buffer2, "\e[24;1f%s\e[K", inputbuffer); + s_putstring(sock, buffer2); + } + } +} diff --git a/config_default/bbs.ini b/config_default/bbs.ini index 59b293b..ab95753 100644 --- a/config_default/bbs.ini +++ b/config_default/bbs.ini @@ -3,6 +3,9 @@ BBS Name = Magicka BBS Sysop Name = sysop nodes = 4 New User Level = 10 +IRC Server = localhost +IRC Port = 6667 +IRC Channel = #bbs [paths] ANSI Path = /home/andrew/MagickaBBS/ansis diff --git a/doors.c b/doors.c index 03c4609..81c87c4 100644 --- a/doors.c +++ b/doors.c @@ -205,7 +205,7 @@ int door_menu(int socket, struct user_record *user) { while (!dodoors) { s_displayansi(socket, "doors"); - sprintf(prompt, "\r\nTL: %dm :> ", user->timeleft); + sprintf(prompt, "\e[0m\r\nTL: %dm :> ", user->timeleft); s_putstring(socket, prompt); c = s_getc(socket); diff --git a/mail_menu.c b/mail_menu.c index 65e1fe5..1d7cab2 100644 --- a/mail_menu.c +++ b/mail_menu.c @@ -582,7 +582,7 @@ int mail_menu(int socket, struct user_record *user) { s_displayansi(socket, "mailmenu"); - sprintf(prompt, "\r\nConf: (%d) %s\r\nArea: (%d) %s\r\nTL: %dm :> ", user->cur_mail_conf, conf.mail_conferences[user->cur_mail_conf]->name, user->cur_mail_area, conf.mail_conferences[user->cur_mail_conf]->mail_areas[user->cur_mail_area]->name, user->timeleft); + sprintf(prompt, "\e[0m\r\nConf: (%d) %s\r\nArea: (%d) %s\r\nTL: %dm :> ", user->cur_mail_conf, conf.mail_conferences[user->cur_mail_conf]->name, user->cur_mail_area, conf.mail_conferences[user->cur_mail_conf]->mail_areas[user->cur_mail_area]->name, user->timeleft); s_putstring(socket, prompt); c = s_getc(socket); diff --git a/main_menu.c b/main_menu.c index b2ae6be..11cbc79 100644 --- a/main_menu.c +++ b/main_menu.c @@ -17,12 +17,17 @@ void main_menu(int socket, struct user_record *user) { s_displayansi(socket, "mainmenu"); - sprintf(prompt, "\r\nTL: %dm :> ", user->timeleft); + sprintf(prompt, "\r\n\e[0mTL: %dm :> ", user->timeleft); s_putstring(socket, prompt); c = s_getc(socket); switch(tolower(c)) { + case 'c': + { + chat_system(socket, user); + } + break; case 'l': { bbs_list(socket, user);