/* vi: set sw=4 ts=4: */
/*
 * Generic non-forking server infrastructure.
 * Intended to make writing telnetd-type servers easier.
 *
 * Copyright (C) 2007 Denis Vlasenko
 *
 * Licensed under GPL version 2, see file LICENSE in this tarball for details.
 */

#include "busybox.h"
#include "isrv.h"

#define DEBUG 0

#if DEBUG
#define DPRINTF(args...) bb_error_msg(args)
#else
#define DPRINTF(args...) ((void)0)
#endif

/* Helpers */

/* Even if _POSIX_MONOTONIC_CLOCK is defined, this
 * may require librt */
#if 0 /*def _POSIX_MONOTONIC_CLOCK*/
static time_t monotonic_time(void)
{
	struct timespec ts;
	if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
		time(&ts.tv_sec);
	return ts.tv_sec;
}
#else
#define monotonic_time() (time(NULL))
#endif

/* Opaque structure */

struct isrv_state_t {
	short  *fd2peer; /* one per registered fd */
	void  **param_tbl; /* one per registered peer */
	/* one per registered peer; doesn't exist if !timeout */
	time_t *timeo_tbl;
	int   (*new_peer)(isrv_state_t *state, int fd);
	time_t  curtime;
	int     timeout;
	int     fd_count;
	int     peer_count;
	int     wr_count;
	fd_set  rd;
	fd_set  wr;
};
#define FD2PEER    (state->fd2peer)
#define PARAM_TBL  (state->param_tbl)
#define TIMEO_TBL  (state->timeo_tbl)
#define CURTIME    (state->curtime)
#define TIMEOUT    (state->timeout)
#define FD_COUNT   (state->fd_count)
#define PEER_COUNT (state->peer_count)
#define WR_COUNT   (state->wr_count)

/* callback */
void isrv_want_rd(isrv_state_t *state, int fd)
{
	FD_SET(fd, &state->rd);
}

/* callback */
void isrv_want_wr(isrv_state_t *state, int fd)
{
	if (!FD_ISSET(fd, &state->wr)) {
		WR_COUNT++;
		FD_SET(fd, &state->wr);
	}
}

/* callback */
void isrv_dont_want_rd(isrv_state_t *state, int fd)
{
	FD_CLR(fd, &state->rd);
}

/* callback */
void isrv_dont_want_wr(isrv_state_t *state, int fd)
{
	if (FD_ISSET(fd, &state->wr)) {
		WR_COUNT--;
		FD_CLR(fd, &state->wr);
	}
}

/* callback */
int isrv_register_fd(isrv_state_t *state, int peer, int fd)
{
	int n;

	DPRINTF("register_fd(peer:%d,fd:%d)", peer, fd);

	if (FD_COUNT >= FD_SETSIZE) return -1;
	if (FD_COUNT <= fd) {
		n = FD_COUNT;
		FD_COUNT = fd + 1;

		DPRINTF("register_fd: FD_COUNT %d", FD_COUNT);

		FD2PEER = xrealloc(FD2PEER, FD_COUNT * sizeof(FD2PEER[0]));
		while (n < fd) FD2PEER[n++] = -1;
	}

	DPRINTF("register_fd: FD2PEER[%d] = %d", fd, peer);

	FD2PEER[fd] = peer;
	return 0;
}

/* callback */
void isrv_close_fd(isrv_state_t *state, int fd)
{
	DPRINTF("close_fd(%d)", fd);

	close(fd);
	isrv_dont_want_rd(state, fd);
	if (WR_COUNT) isrv_dont_want_wr(state, fd);

	FD2PEER[fd] = -1;
	if (fd == FD_COUNT-1) {
		do fd--; while (fd >= 0 && FD2PEER[fd] == -1);
		FD_COUNT = fd + 1;

		DPRINTF("close_fd: FD_COUNT %d", FD_COUNT);

		FD2PEER = xrealloc(FD2PEER, FD_COUNT * sizeof(FD2PEER[0]));
	}
}

/* callback */
int isrv_register_peer(isrv_state_t *state, void *param)
{
	int n;

	if (PEER_COUNT >= FD_SETSIZE) return -1;
	n = PEER_COUNT++;

	DPRINTF("register_peer: PEER_COUNT %d", PEER_COUNT);

	PARAM_TBL = xrealloc(PARAM_TBL, PEER_COUNT * sizeof(PARAM_TBL[0]));
	PARAM_TBL[n] = param;
	if (TIMEOUT) {
		TIMEO_TBL = xrealloc(TIMEO_TBL, PEER_COUNT * sizeof(TIMEO_TBL[0]));
		TIMEO_TBL[n] = CURTIME;
	}
	return n;
}

static void remove_peer(isrv_state_t *state, int peer)
{
	int movesize;
	int fd;

	DPRINTF("remove_peer(%d)", peer);

	fd = FD_COUNT - 1;
	while (fd >= 0) {
		if (FD2PEER[fd] == peer) {
			isrv_close_fd(state, fd);
			fd--;
			continue;
		}
		if (FD2PEER[fd] > peer)
			FD2PEER[fd]--;
		fd--;
	}

	PEER_COUNT--;
	DPRINTF("remove_peer: PEER_COUNT %d", PEER_COUNT);

	movesize = (PEER_COUNT - peer) * sizeof(void*);
	if (movesize > 0) {
		memcpy(&PARAM_TBL[peer], &PARAM_TBL[peer+1], movesize);
		if (TIMEOUT)
			memcpy(&TIMEO_TBL[peer], &TIMEO_TBL[peer+1], movesize);
	}
	PARAM_TBL = xrealloc(PARAM_TBL, PEER_COUNT * sizeof(PARAM_TBL[0]));
	if (TIMEOUT)
		TIMEO_TBL = xrealloc(TIMEO_TBL, PEER_COUNT * sizeof(TIMEO_TBL[0]));
}

static void handle_accept(isrv_state_t *state, int fd)
{
	int n, newfd;

	fcntl(fd, F_SETFL, (int)(PARAM_TBL[0]) | O_NONBLOCK);
	newfd = accept(fd, NULL, 0);
	fcntl(fd, F_SETFL, (int)(PARAM_TBL[0]));
	if (newfd < 0) {
		if (errno == EAGAIN) return;
		/* Most probably someone gave us wrong fd type
		 * (for example, non-socket). Don't want
		 * to loop forever. */
		bb_perror_msg_and_die("accept");
	}

	DPRINTF("new_peer(%d)", newfd);
	n = state->new_peer(state, newfd);
	if (n)
		remove_peer(state, n); /* unsuccesful peer start */
}

void BUG_sizeof_fd_set_is_strange(void);
static void handle_fd_set(isrv_state_t *state, fd_set *fds, int (*h)(int, void **))
{
	enum { LONG_CNT = sizeof(fd_set) / sizeof(long) };
	int fds_pos;
	int fd, peer;
	/* need to know value at _the beginning_ of this routine */
	int fd_cnt = FD_COUNT;

	if (LONG_CNT * sizeof(long) != sizeof(fd_set))
		BUG_sizeof_fd_set_is_strange();

	fds_pos = 0;
	while (1) {
		/* Find next nonzero bit */
		while (fds_pos < LONG_CNT) {
			if (((long*)fds)[fds_pos] == 0) {
				fds_pos++;
				continue;
			}
			/* Found non-zero word */
			fd = fds_pos * sizeof(long)*8; /* word# -> bit# */
			while (1) {
				if (FD_ISSET(fd, fds)) {
					FD_CLR(fd, fds);
					goto found_fd;
				}
				fd++;
			}
		}
		break; /* all words are zero */
 found_fd:
		if (fd >= fd_cnt) { /* paranoia */
			DPRINTF("handle_fd_set: fd > fd_cnt?? (%d > %d)",
					fd, fd_cnt);
			break;
		}
		DPRINTF("handle_fd_set: fd %d is active", fd);
		peer = FD2PEER[fd];
		if (peer < 0)
			continue; /* peer is already gone */
		if (peer == 0) {
			handle_accept(state, fd);
			continue;
		}
		DPRINTF("h(fd:%d)", fd);
		if (h(fd, &PARAM_TBL[peer])) {
			/* this peer is gone */
			remove_peer(state, peer);
		} else if (TIMEOUT) {
			TIMEO_TBL[peer] = monotonic_time();
		}
	}
}

static void handle_timeout(isrv_state_t *state, int (*do_timeout)(void **))
{
	int n, peer;
	peer = PEER_COUNT-1;
	/* peer 0 is not checked */
	while (peer > 0) {
		DPRINTF("peer %d: time diff %d", peer,
				(int)(CURTIME - TIMEO_TBL[peer]));
		if ((CURTIME - TIMEO_TBL[peer]) >= TIMEOUT) {
			DPRINTF("peer %d: do_timeout()", peer);
			n = do_timeout(&PARAM_TBL[peer]);
			if (n)
				remove_peer(state, peer);
		}
		peer--;
	}
}

/* Driver */
void isrv_run(
	int listen_fd,
	int (*new_peer)(isrv_state_t *state, int fd),
	int (*do_rd)(int fd, void **),
	int (*do_wr)(int fd, void **),
	int (*do_timeout)(void **),
	int timeout,
	int linger_timeout)
{
	isrv_state_t *state = xzalloc(sizeof(*state));
	state->new_peer = new_peer;
	state->timeout  = timeout;

	/* register "peer" #0 - it will accept new connections */
	isrv_register_peer(state, NULL);
	isrv_register_fd(state, /*peer:*/ 0, listen_fd);
	isrv_want_rd(state, listen_fd);
	/* remember flags to make blocking<->nonblocking switch faster */
	PARAM_TBL[0] = (void*) (fcntl(listen_fd, F_GETFL, 0));

	while (1) {
		struct timeval tv;
		fd_set rd;
		fd_set wr;
		fd_set *wrp = NULL;
		int n;

		tv.tv_sec = timeout;
		if (PEER_COUNT <= 1)
			tv.tv_sec = linger_timeout;
		tv.tv_usec = 0;
		rd = state->rd;
		if (WR_COUNT) {
			wr = state->wr;
			wrp = &wr;
		}

		DPRINTF("run: select(FD_COUNT:%d,timeout:%d)...",
				FD_COUNT, (int)tv.tv_sec);
		n = select(FD_COUNT, &rd, wrp, NULL, tv.tv_sec ? &tv : NULL);
		DPRINTF("run: ...select:%d", n);

		if (n < 0) {
			if (errno != EINTR)
				bb_perror_msg("select");
			continue;
		}

		if (n == 0 && linger_timeout && PEER_COUNT <= 1)
			break;

		if (timeout) {
			time_t t = monotonic_time();
			if (t != CURTIME) {
				CURTIME = t;
				handle_timeout(state, do_timeout);
			}
		}
		if (n > 0) {
			handle_fd_set(state, &rd, do_rd);
			if (wrp)
				handle_fd_set(state, wrp, do_wr);
		}
	}
	DPRINTF("run: bailout");
	/* NB: accept socket is not closed. Caller is to decide what to do */
}
