aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2022-10-31 19:14:39 +0000
committerubq323 <ubq323@ubq323.website>2022-10-31 19:14:39 +0000
commit65fc26be19594c91b3af57c548c2e5c7307457f2 (patch)
treeed1857b7e5ac903896ecd8b6d1f43314748da584
parent1dc90feaf9d7db3c0e5d8233a5d60c46ee236c1c (diff)
multiple channels are now supported
-rw-r--r--Makefile12
-rw-r--r--bee.c107
-rw-r--r--conf.c11
-rw-r--r--conf.h7
-rw-r--r--irc.c18
-rw-r--r--irc.h7
-rw-r--r--unix.c51
-rw-r--r--unix.h5
-rw-r--r--util.c1
-rw-r--r--util.h1
10 files changed, 128 insertions, 92 deletions
diff --git a/Makefile b/Makefile
index 388884c..97d5d35 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ CC=cc
debug=-g -DDEBUG -DLOCAL
CFLAGS=$(MORE_CFLAGS) -Wall -Wpedantic
-OBJS=bee.o irc.o util.o unix.o conf.o
+OBJS=bee.o irc.o util.o unix.o
all: apiobot
apiobot: $(OBJS)
@@ -19,12 +19,12 @@ local:
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
-apiosend.o: apiosend.c
-bee.o: bee.c irc.h unix.h
-conf.o: conf.c conf.h
+bee.o: bee.c irc.h unix.h conf.h debug.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
+thing.o: thing.c conf.h
+unix.o: unix.c unix.h conf.h irc.h
+util.o: util.c util.h debug.h conf.h
+
run: all
./apiobot
diff --git a/bee.c b/bee.c
index 9f7fb5d..9a2e0a5 100644
--- a/bee.c
+++ b/bee.c
@@ -1,59 +1,21 @@
#include "irc.h"
#include "unix.h"
+#include "conf.h"
+#include "debug.h"
#include <stdio.h>
#include <poll.h>
+#include <stdlib.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);
+static int
+socket_fname(char chname[], char out[], size_t lim) {
+ if (strlen(chname) > 16) return -1;
+ if (snprintf(out, lim, SOCKETDIR"/%s.sock", chname) >= lim) {
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;
- }
+ return 0;
}
-
-
int
main()
{
@@ -65,31 +27,40 @@ main()
fputs("failure in unix_setup\n",stderr); return -1;
}
- struct pollfd pfs[2];
+ // pfs[0] is the irc socket
+ // pfs[k>=1] is the unix socket that should send to channel g_chanlist[k-1]
+ struct pollfd *pfs = malloc((1 + g_nchannels) * sizeof(struct pollfd));
pfs[0].fd = g_ircsock;
pfs[0].events = POLLIN;
- pfs[1].fd = unixfd;
- pfs[1].events = POLLIN;
- for (;;) {
- if (poll(pfs, 2, -1) == -1) {
- perror("poll");
+ char fname[100];
+ for (int i = 0; i<g_nchannels; i++) {
+ // construct filename for listening socket
+ if (socket_fname(g_chanlist[i], fname, sizeof fname) == -1) {
+ fprintf(stderr,"failed to generate socket filename for channel %s\n",g_chanlist[i]);
return 1;
}
- if (pfs[0].revents & POLLERR) {
- fputs("irc socket error\n",stderr);
- return 1;
+ int fd;
+ if ((fd = unix_setup(fname)) == -1) {
+ fputs("failure in unix_setup\n",stderr);
+ return -1;
}
- if (pfs[0].revents & POLLHUP) {
- fputs("irc hup\n",stderr);
+ pfs[i+1].fd = fd;
+ pfs[i+1].events = POLLIN;
+ }
+
+ for (;;) {
+ if (poll(pfs, g_nchannels+1, -1) == -1) {
+ perror("poll");
return 1;
}
- if (pfs[1].revents & POLLERR) {
- fputs("unix sock err\n",stderr);
+
+ // irc
+ if (pfs[0].revents & (POLLERR|POLLHUP)) {
+ fputs("irc socket error\n",stderr);
return 1;
}
-
if (pfs[0].revents & POLLIN) {
int r = irc_recv();
if (r == -2) {
@@ -102,12 +73,20 @@ main()
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);
+
+ // unixes
+ for (int i = 0; i < g_nchannels; i++) {
+ struct pollfd *p = &pfs[i+1];
+ if (p->revents & (POLLERR|POLLHUP)) {
+ fputs("unix socket error\n",stderr);
return 1;
}
+ if (p->revents & POLLIN) {
+ if (unix_handle(p->fd,g_chanlist[i]) == -1) {
+ fputs("unix_handle failure\n",stderr);
+ return 1;
+ }
+ }
}
}
diff --git a/conf.c b/conf.c
deleted file mode 100644
index 3c38adc..0000000
--- a/conf.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "conf.h"
-
-#include <stddef.h>
-
-char *CHANNELS[] = {
- "a",
- "b",
- "jonathan",
- "secret-channel",
- NULL,
-};
diff --git a/conf.h b/conf.h
index 5f84b0e..084fce4 100644
--- a/conf.h
+++ b/conf.h
@@ -4,12 +4,12 @@
#ifdef LOCAL
#define HOST "0.0.0.0"
#define PORT "6971"
- #define SOCKETNAME "bees.sock"
+ #define SOCKETDIR "socks"
#define SOCKETGROUP "cdrom"
#else
#define HOST "ubq323.website"
#define PORT "6667"
- #define SOCKETNAME "/srv/apiobot/bees.sock"
+ #define SOCKETDIR "socks"
#define SOCKETGROUP "apionet"
#endif
@@ -18,8 +18,5 @@
#define USERNAME "apiobot"
#define REALNAME "apiobot"
-// defined in conf.c
-extern char *CHANNELS[];
-
#endif // conf_h_INCLUDED
diff --git a/irc.c b/irc.c
index 065cee0..b30af48 100644
--- a/irc.c
+++ b/irc.c
@@ -6,6 +6,16 @@
int g_ircsock = -1;
+char *g_chanlist[] = {
+ "a",
+ "b",
+ "g",
+ "cg",
+ "secret-channel",
+};
+const int g_nchannels = sizeof(g_chanlist)/sizeof(g_chanlist[0]);
+
+
int
irc_connect()
{
@@ -53,13 +63,13 @@ irc_handshake()
#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]);
+ for (int i = 0; i<g_nchannels; i++) {
+ if (strlen(g_chanlist[i]) > 16) {
+ fprintf(stderr,"channel name too long (%s)\n",g_chanlist[i]);
return -1;
}
E(irc_sendall("JOIN #",6));
- E(irc_sendall(CHANNELS[i],strlen(CHANNELS[i])));
+ E(irc_sendall(g_chanlist[i],strlen(g_chanlist[i])));
E(irc_sendall("\r\n",2));
}
#undef E
diff --git a/irc.h b/irc.h
index a56379d..870508f 100644
--- a/irc.h
+++ b/irc.h
@@ -10,8 +10,15 @@
#define IRC_RECVBUF_SIZE 1024
+// fd of the irc connection socket
extern int g_ircsock;
+// list of channels to join
+extern char *g_chanlist[];
+// length of the above
+extern const int g_nchannels;
+
+
// connects to the irc server, as defined in config.h
// returns -1 on failure.
int irc_connect();
diff --git a/unix.c b/unix.c
index ac1d1fd..1fbb496 100644
--- a/unix.c
+++ b/unix.c
@@ -1,6 +1,7 @@
#include "unix.h"
#include "conf.h"
+#include "irc.h"
static int
sock_perms(char fname[])
@@ -60,5 +61,53 @@ unix_setup(char filename[])
return sock;
}
-
+// reads a message from the fd in question, and sends it to irc
+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;
+ }
+}
+
diff --git a/unix.h b/unix.h
index 57d1cfc..50511b1 100644
--- a/unix.h
+++ b/unix.h
@@ -10,9 +10,14 @@
#include <stdio.h>
+
// takes filename, returns socket fd
// or -1 on failure.
int unix_setup(char sockname[]);
+// reads a message from unix socket on fd,
+// and sends it to irc on the channel chname.
+int unix_handle(int fd, char chname[]);
+
#endif // unix_h_INCLUDED
diff --git a/util.c b/util.c
index ceb2767..69271b5 100644
--- a/util.c
+++ b/util.c
@@ -1,5 +1,6 @@
#include "util.h"
#include "debug.h"
+#include "conf.h"
ssize_t sendall(int sockfd, char *buf, size_t len) {
ssize_t total_sent = 0;
diff --git a/util.h b/util.h
index f447872..e25b171 100644
--- a/util.h
+++ b/util.h
@@ -4,7 +4,6 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <stddef.h>
-#include "conf.h"
// repeatedly call send until all the data has been sent down
// the socket.