diff options
-rw-r--r-- | Makefile | 14 | ||||
-rw-r--r-- | bee.c | 109 | ||||
-rw-r--r-- | conf.c | 11 | ||||
-rw-r--r-- | conf.h | 5 | ||||
-rw-r--r-- | irc.c | 21 | ||||
-rw-r--r-- | util.c | 2 | ||||
-rw-r--r-- | util.h | 2 |
7 files changed, 135 insertions, 29 deletions
@@ -3,9 +3,9 @@ CC=cc debug=-g -DDEBUG -DLOCAL -CFLAGS=$(MORE_CFLAGS) -Wall +CFLAGS=$(MORE_CFLAGS) -Wall -Wpedantic -OBJS=bee.o irc.o util.o unix.o +OBJS=bee.o irc.o util.o unix.o conf.o all: apiobot apiobot: $(OBJS) @@ -13,11 +13,19 @@ apiobot: $(OBJS) debug: make apiobot MORE_CFLAGS="-DDEBUG -DLOCAL -g" +local: + make apiobot MORE_CFLAGS="-DLOCAL" - .c.o: $(CC) $(CFLAGS) -c $< -o $@ +apiosend.o: apiosend.c +bee.o: bee.c irc.h unix.h +conf.o: conf.c conf.h +irc.o: irc.c irc.h debug.h conf.h util.h +unix.o: unix.c unix.h conf.h +util.o: util.c util.h conf.h debug.h + run: all ./apiobot @@ -2,41 +2,114 @@ #include "unix.h" #include <stdio.h> +#include <poll.h> + +int +unix_handle(int fd, char chname[]) +{ + // PRIVMSG #{chname} :{message}<CR><LF> + // 123456789 12 3 4 + // 512 >= 13 + strlen(chname) + length of message + // chname can be max 16 bytes, so worst case + // 512 >= 13 + 16 + length of message + // 483 >= length of message + // 480 is slightly pessimistic but it's a rounder number. + // (one more byte for null terminator needed by snprintf) + unsigned char buf[481]; + + if (strlen(chname) > 16) { + fprintf(stderr,"channel name %s is longer than 16 bytes, ignoring\n",chname); + return -1; + } + + ssize_t amt; + if ((amt = recv(fd, buf, sizeof buf-1,0)) == -1) { + perror("recv"); + return -1; + } else if (amt == 0) { + fputs("unix eof\n",stderr); + return -1; + } else { + int i; + for (i=0;i<amt;i++) { + if (buf[i] < ' ') { + buf[i] = ' '; + } + } + buf[amt] = '\0'; + char msg[512]; + int s; + if ((s=snprintf(msg,512,"PRIVMSG #%s :%s\r\n",chname,buf)) > 512) { + fprintf(stderr,"irc message was somehow too long (this should never happen) (%d)/512\n",s); + return -1; + } + if (irc_sendall(msg, s) == -1) { + perror("sendall"); + return -1; + }; + + return 0; + } +} int main() { - /* if (irc_connect()) { fputs("falure in irc_connect\n",stderr); return 1; } + if (irc_connect()) { fputs("falure in irc_connect\n",stderr); return 1; } if (irc_handshake()) { fputs("failure in irc_handshake\n",stderr); return 1; } - */ int unixfd; if ((unixfd = unix_setup("bees2.sock")) == -1) { fputs("failure in unix_setup\n",stderr); return -1; } - char buf[128]; - ssize_t amt; + struct pollfd pfs[2]; + pfs[0].fd = g_ircsock; + pfs[0].events = POLLIN; + pfs[1].fd = unixfd; + pfs[1].events = POLLIN; + for (;;) { - if ((amt = recv(unixfd,buf,sizeof buf - 1,0)) == -1) { - perror("recv"); + if (poll(pfs, 2, -1) == -1) { + perror("poll"); + return 1; + } + + if (pfs[0].revents & POLLERR) { + fputs("irc socket error\n",stderr); + return 1; + } + if (pfs[0].revents & POLLHUP) { + fputs("irc hup\n",stderr); + return 1; + } + if (pfs[1].revents & POLLERR) { + fputs("unix sock err\n",stderr); return 1; - } else if (amt == 0) { - puts("unix eof"); - return 0; - } else { - buf[amt] = 0; - printf("got: %s\n",buf); } - } - - int x; - do { - x = irc_recv(); - } while (!x); + if (pfs[0].revents & POLLIN) { + int r = irc_recv(); + if (r == -2) { + // don't currently try to reconnect + // maybe that could happen in the future. + fputs("disconnected from irc, exiting\n",stderr); + return 2; + } else if (r == -1) { + fputs("exiting due to irc error\n",stderr); + return 1; + } + } + if (pfs[1].revents & POLLIN) { + int r = unix_handle(unixfd,"a"); + if (r==-1) { + fputs("exiting due to unix sock error\n",stderr); + return 1; + } + } + } return 0; } @@ -0,0 +1,11 @@ +#include "conf.h" + +#include <stddef.h> + +char *CHANNELS[] = { + "a", + "b", + "jonathan", + "secret-channel", + NULL, +}; @@ -14,11 +14,12 @@ #endif -#define NICK "Bee" +#define NICK "Bee2" #define USERNAME "apiobot" #define REALNAME "apiobot" -#define CHANNEL "#a" +// defined in conf.c +extern char *CHANNELS[]; #endif // conf_h_INCLUDED @@ -49,9 +49,21 @@ irc_sendall(char msg[], size_t len) int irc_handshake() -{ - char msg[] = "NICK "NICK"\r\nUSER "USERNAME" 0 * :"REALNAME"\r\nJOIN "CHANNEL"\r\n"; - return irc_sendall(msg, sizeof msg-1); +{ + #define E(x) do { if (x==-1) { perror("irc_sendall"); return -1; } } while(0) + char msg1[] = "NICK "NICK"\r\nUSER "USERNAME" 0 * :"REALNAME"\r\n"; + E(irc_sendall(msg1, sizeof msg1-1)); + for (int i = 0; CHANNELS[i] != NULL; i++) { + if (strlen(CHANNELS[i]) > 16) { + fprintf(stderr,"channel name too long (%s)\n",CHANNELS[i]); + return -1; + } + E(irc_sendall("JOIN #",6)); + E(irc_sendall(CHANNELS[i],strlen(CHANNELS[i]))); + E(irc_sendall("\r\n",2)); + } + #undef E + return 0; } @@ -99,6 +111,7 @@ char *recv_end = &recv_buf[RECVBUF_SIZE]; // then cur points to one past the most recently recieved byte. // after processing a message, if there's more stuff in the buffer, memmove it back. +// returns -2 on eof, -1 on other error, 0 on success int irc_recv() { @@ -110,7 +123,7 @@ irc_recv() } else if (amt == 0) { // eof fprintf(stderr,"irc eof\n"); - return -1; + return -2; } DPf("recieved %ld ",amt); @@ -1,7 +1,7 @@ #include "util.h" #include "debug.h" -ssize_t sendall(int sockfd, void *buf, size_t len) { +ssize_t sendall(int sockfd, char *buf, size_t len) { ssize_t total_sent = 0; ssize_t sent; do { @@ -8,7 +8,7 @@ // repeatedly call send until all the data has been sent down // the socket. -ssize_t sendall(int sockfd, void *buf, size_t len); +ssize_t sendall(int sockfd, char *buf, size_t len); |