diff --git a/Bot/bot.c b/Bot/bot.c index 98fb4ad..dda09c3 100644 --- a/Bot/bot.c +++ b/Bot/bot.c @@ -27,12 +27,8 @@ #define OKUU_VERSION "1.00" -extern char* nntpserver; -extern char* nntpuser; -extern char* nntppass; extern char* nntppath; extern char* nntpcount; -extern int nntpport; extern char* ircserver; extern char* ircchan; @@ -87,6 +83,14 @@ void ok_bot(void){ ok_addr.sin_family = PF_INET; ok_addr.sin_addr.s_addr = inet_addr(ircserver); ok_addr.sin_port = htons(ircport); + + int yes = 1; + + if(setsockopt(ok_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)) < 0) { + fprintf(stderr, "setsockopt failure"); + ok_close(ok_sock); + return; + } if(connect(ok_sock, (struct sockaddr*)&ok_addr, sizeof(ok_addr)) < 0){ fprintf(stderr, "Connection failure\n"); @@ -234,6 +238,10 @@ void ok_bot(void){ } }else if(sentin[0] == '#'){ /* This was sent in channel */ + if(ok_news_write(nick, msg) != 0){ + sprintf(construct, "PRIVMSG %s :Could not send the message to the USENET", sentin); + ircfw_socket_send_cmd(ok_sock, NULL, construct); + } } free(nick); diff --git a/Bot/main.c b/Bot/main.c index 9ff8e1e..062c498 100644 --- a/Bot/main.c +++ b/Bot/main.c @@ -12,6 +12,8 @@ char* nntpserver; char* nntpuser; char* nntppass; char* nntppath; +char* nntpgroup; +char* nntpfrom; char* nntpcount; int nntpport = 119; @@ -30,7 +32,9 @@ int main(){ nntpuser = getenv("NNTPUSER"); nntppass = getenv("NNTPPASS"); nntppath = getenv("NNTPPATH"); + nntpgroup = getenv("NNTPGROUP"); nntpcount = getenv("NNTPCOUNT"); + nntpfrom = getenv("NNTPFROM"); ircserver = getenv("IRCSERVER"); ircchan = getenv("IRCCHAN"); ircuser = getenv("IRCUSER"); @@ -56,6 +60,14 @@ int main(){ fprintf(stderr, "Set NNTPCOUNT\n"); bad = true; } + if(nntpfrom == NULL){ + fprintf(stderr, "Set NNTPFROM\n"); + bad = true; + } + if(nntpgroup == NULL){ + fprintf(stderr, "Set NNTPGROUP\n"); + bad = true; + } if(ircserver == NULL){ fprintf(stderr, "Set IRCSERVER\n"); bad = true; diff --git a/Bot/news.c b/Bot/news.c index f5c018f..cdc3d26 100644 --- a/Bot/news.c +++ b/Bot/news.c @@ -12,15 +12,33 @@ #include #include +#include +#include +#include + +#ifdef __FreeBSD__ +#include +#endif + +extern char* nntpserver; +extern char* nntpuser; +extern char* nntppass; +extern char* nntppath; +extern char* nntpfrom; +extern char* nntpgroup; +extern char* nntpcount; +extern int nntpport; + struct news_entry news_entry; +void ok_close(int sock); + void ok_news_init(void){ news_entry.from = NULL; news_entry.content = NULL; } int ok_news_read(const char* path){ - if(news_entry.from != NULL){ free(news_entry.from); news_entry.from = NULL; @@ -203,3 +221,120 @@ int ok_news_read(const char* path){ return 1; } } + +int ok_news_parse(int sock){ + char c; + int sta = 0; + bool st = false; + while(1){ + if(recv(sock, &c, 1, 0) <= 0){ + return -1; + } + if(c == '\n') break; + if(!st){ + if('0' <= c && c <= '9'){ + sta *= 10; + sta += c - '0'; + }else if(c == ' '){ + st = true; + } + } + } + return sta == 0 ? -1 : sta; +} + +int ok_news_write(const char* nick, const char* message){ + int nt_sock; + struct sockaddr_in nt_addr; + if((nt_sock = socket(PF_INET, SOCK_STREAM, 0)) < 0){ + fprintf(stderr, "Socket creation failure\n"); + return 1; + } + + bzero((char*)&nt_addr, sizeof(nt_addr)); + nt_addr.sin_family = PF_INET; + nt_addr.sin_addr.s_addr = inet_addr(nntpserver); + nt_addr.sin_port = htons(nntpport); + + int yes = 1; + + if(setsockopt(nt_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)) < 0) { + fprintf(stderr, "setsockopt failure"); + ok_close(nt_sock); + return 1; + } + + if(connect(nt_sock, (struct sockaddr*)&nt_addr, sizeof(nt_addr)) < 0){ + fprintf(stderr, "Connection failure\n"); + ok_close(nt_sock); + return 1; + } + + int sta; + + sta = ok_news_parse(nt_sock); + if(sta == 200 || sta == 201){ + char construct[1024]; + if(nntpuser != NULL){ + sprintf(construct, "AUTHINFO USER %s\r\n", nntpuser); + send(nt_sock, construct, strlen(construct), 0); + sta = ok_news_parse(nt_sock); + if(sta != 381){ + goto cleanup; + } + } + if(nntppass != NULL){ + sprintf(construct, "AUTHINFO PASS %s\r\n", nntppass); + send(nt_sock, construct, strlen(construct), 0); + if(sta != 281){ + goto cleanup; + } + } + send(nt_sock, "MODE READER\r\n", 4 + 1 + 6 + 2, 0); + sta = ok_news_parse(nt_sock); + if(sta == 200 || sta == 201){ + send(nt_sock, "POST\r\n", 4 + 2, 0); + sta = ok_news_parse(nt_sock); + if(sta == 340){ + sprintf(construct, "From: %s\r\n", nntpfrom); + send(nt_sock, construct, strlen(construct), 0); + sprintf(construct, "Newsgroups: %s\r\n", nntpgroup); + send(nt_sock, construct, strlen(construct), 0); + sprintf(construct, "Subject: Message from %s\r\n", nick); + send(nt_sock, construct, strlen(construct), 0); + send(nt_sock, "\r\n", 2, 0); + char c; + int i; + bool first = true; + for(i = 0; message[i] != 0; i++){ + if(message[i] == '\n'){ + send(nt_sock, "\r\n", 2, 0); + first = true; + }else{ + if(first && message[i] == '.'){ + send(nt_sock, message + i, 1, 0); + } + send(nt_sock, message + i, 1, 0); + first = false; + } + } + if(!first) send(nt_sock, "\r\n", 2, 0); + send(nt_sock, ".\r\n", 3, 0); + sta = ok_news_parse(nt_sock); + if(sta != 240) goto cleanup; + }else{ + goto cleanup; + } + }else{ + goto cleanup; + } + }else{ + goto cleanup; + } + + ok_close(nt_sock); + return 0; +cleanup: + ok_close(nt_sock); + return 1; +} diff --git a/Bot/ok_news.h b/Bot/ok_news.h index a3ed195..a49dc9d 100644 --- a/Bot/ok_news.h +++ b/Bot/ok_news.h @@ -10,6 +10,7 @@ struct news_entry { void ok_news_init(void); int ok_news_read(const char* path); +int ok_news_write(const char* nick, const char* message); #ifndef OK_NEWS_SRC extern struct news_entry news_entry;