aboutsummaryrefslogtreecommitdiff
path: root/bee.c
blob: 89ad3ff449e08d8d7c94878b61cb6fb99f52dd3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include "irc.h"
#include "chanlist.h"
#include "unix.h"
#include "conf.h"
#include "debug.h"

#include <stdio.h>
#include <poll.h>
#include <stdlib.h>

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;
	}
	return 0;
}

int
main()
{
	if (irc_connect()) { fputs("falure in irc_connect\n",stderr); return 1; }
	if (irc_handshake()) { fputs("failure in irc_handshake\n",stderr); return 1; }

	// 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;

	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;
		}

		int fd;
		if ((fd = unix_setup(fname)) == -1) {
			fputs("failure in unix_setup\n",stderr);
			return 1;
		}
		pfs[i+1].fd = fd;
		pfs[i+1].events = POLLIN;
	}

	for (;;) {
		if (poll(pfs, g_nchannels+1, -1) == -1) {
			perror("poll");
			return 1;
		}

		// 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) {
				// 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;
			}
		}

		// 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;
				}
			}
		}
	}

	return 0;
}