diff options
Diffstat (limited to 'bee.c')
-rw-r--r-- | bee.c | 107 |
1 files changed, 43 insertions, 64 deletions
@@ -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; + } + } } } |