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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#include "irc.h"
#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_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;
}
struct pollfd pfs[2];
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");
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;
}
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;
}
|