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