aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile14
-rw-r--r--bee.c109
-rw-r--r--conf.c11
-rw-r--r--conf.h5
-rw-r--r--irc.c21
-rw-r--r--util.c2
-rw-r--r--util.h2
7 files changed, 135 insertions, 29 deletions
diff --git a/Makefile b/Makefile
index 9d57e9e..388884c 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/bee.c b/bee.c
index 0cd3b13..9f7fb5d 100644
--- a/bee.c
+++ b/bee.c
@@ -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;
}
diff --git a/conf.c b/conf.c
new file mode 100644
index 0000000..3c38adc
--- /dev/null
+++ b/conf.c
@@ -0,0 +1,11 @@
+#include "conf.h"
+
+#include <stddef.h>
+
+char *CHANNELS[] = {
+ "a",
+ "b",
+ "jonathan",
+ "secret-channel",
+ NULL,
+};
diff --git a/conf.h b/conf.h
index c405d11..5f84b0e 100644
--- a/conf.h
+++ b/conf.h
@@ -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
diff --git a/irc.c b/irc.c
index 5af46ae..065cee0 100644
--- a/irc.c
+++ b/irc.c
@@ -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);
diff --git a/util.c b/util.c
index 97d705a..ceb2767 100644
--- a/util.c
+++ b/util.c
@@ -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 {
diff --git a/util.h b/util.h
index f273e2f..f447872 100644
--- a/util.h
+++ b/util.h
@@ -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);