typedef struct srsd_t {
unsigned listener : 1;
unsigned decoder : 1;
- unsigned watchwr : 1;
int fd;
buffer_t ibuf;
buffer_t obuf;
int process_srs(srs_t *srs, const char *domain, srsd_t *srsd)
{
+ int res = buffer_read(&srsd->ibuf, srsd->fd, -1);
+
+ if ((res < 0 && errno != EINTR && errno != EAGAIN) || res == 0)
+ return -1;
+
while (srsd->ibuf.len > 4) {
char buf[BUFSIZ], *p, *q, *nl;
int err;
.sin_family = AF_INET,
.sin_addr = { htonl(INADDR_LOOPBACK) },
};
- struct epoll_event evt = { .events = EPOLLIN };
srsd_t *tmp;
int sock;
return -1;
}
- evt.data.ptr = tmp = srsd_new();
+ tmp = srsd_new();
tmp->fd = sock;
tmp->decoder = decoder;
tmp->listener = true;
- if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &evt) < 0) {
- UNIXERR("epoll_ctl");
- return -1;
- }
+ epoll_register(sock, EPOLLIN, tmp);
return 0;
}
+void start_client(srsd_t *srsd)
+{
+ srsd_t *tmp;
+ int sock;
+
+ sock = accept_nonblock(srsd->fd);
+ if (sock < 0) {
+ UNIXERR("accept");
+ return;
+ }
+
+ tmp = srsd_new();
+ tmp->decoder = srsd->decoder;
+ tmp->fd = sock;
+ epoll_register(sock, EPOLLIN, tmp);
+}
+
/* }}} */
/* administrivia {{{ */
" (default: "STR(DEFAULT_DECODER_PORT)")\n"
" -p <pidfile> file to write our pid to\n"
" -u unsafe mode: don't drop privilegies\n"
+ " -f stay in foreground\n"
, stderr);
}
struct epoll_event evts[1024];
int n;
- n = epoll_wait(epollfd, evts, countof(evts), -1);
+ n = epoll_select(evts, countof(evts), -1);
if (n < 0) {
if (errno != EAGAIN && errno != EINTR) {
UNIXERR("epoll_wait");
srsd_t *srsd = evts[n].data.ptr;
if (srsd->listener) {
- struct epoll_event evt = { .events = EPOLLIN };
- srsd_t *tmp;
- int sock;
-
- sock = accept_nonblock(srsd->fd);
- if (sock < 0) {
- UNIXERR("accept");
- continue;
- }
-
- evt.data.ptr = tmp = srsd_new();
- tmp->decoder = srsd->decoder;
- tmp->fd = sock;
- if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &evt) < 0) {
- UNIXERR("epoll_ctl");
- srsd_delete(&tmp);
- close(sock);
- }
+ start_client(srsd);
continue;
}
if (evts[n].events & EPOLLIN) {
- int res = buffer_read(&srsd->ibuf, srsd->fd, -1);
-
- if ((res < 0 && errno != EINTR && errno != EAGAIN)
- || res == 0)
- {
- srsd_delete(&srsd);
- continue;
- }
-
if (process_srs(srs, domain, srsd) < 0) {
srsd_delete(&srsd);
continue;
}
+ if (srsd->obuf.len) {
+ epoll_register(srsd->fd, EPOLLIN | EPOLLOUT, srsd);
+ }
}
if ((evts[n].events & EPOLLOUT) && srsd->obuf.len) {
- int res = write(srsd->fd, srsd->obuf.data, srsd->obuf.len);
-
- if (res < 0 && errno != EINTR && errno != EAGAIN) {
+ if (buffer_write(&srsd->obuf, srsd->fd) < 0) {
srsd_delete(&srsd);
continue;
}
-
- if (res > 0) {
- buffer_consume(&srsd->obuf, res);
- }
- }
-
- if (srsd->watchwr == !srsd->obuf.len) {
- struct epoll_event evt = {
- .events = EPOLLIN | (srsd->obuf.len ? EPOLLOUT : 0),
- .data.ptr = srsd,
- };
- if (epoll_ctl(epollfd, EPOLL_CTL_MOD, srsd->fd, &evt) < 0) {
- UNIXERR("epoll_ctl");
- srsd_delete(&srsd);
- continue;
+ if (!srsd->obuf.len) {
+ epoll_modify(srsd->fd, EPOLLIN, srsd);
}
- srsd->watchwr = srsd->obuf.len != 0;
}
}
}
int main(int argc, char *argv[])
{
bool unsafe = false;
+ bool daemonize = true;
int port_enc = DEFAULT_ENCODER_PORT;
int port_dec = DEFAULT_DECODER_PORT;
const char *pidfile = NULL;
int res;
srs_t *srs;
- for (int c = 0; (c = getopt(argc, argv, "hu" "e:d:p:")) >= 0; ) {
+ for (int c = 0; (c = getopt(argc, argv, "hfu" "e:d:p:")) >= 0; ) {
switch (c) {
case 'e':
port_enc = atoi(optarg);
break;
+ case 'f':
+ daemonize = false;
+ break;
case 'd':
port_dec = atoi(optarg);
break;
return EXIT_FAILURE;
}
- if (daemon_detach() < 0) {
+ if (daemonize && daemon_detach() < 0) {
syslog(LOG_CRIT, "unable to fork");
return EXIT_FAILURE;
}