/*
Copyright (c) 2001-2006, Gerrit Pape
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

   1. Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
   2. Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
   3. The name of the author may not be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/* Busyboxed by Denis Vlasenko <vda.linux@googlemail.com> */
/* TODO: depends on runit_lib.c - review and reduce/eliminate */

#include <sys/poll.h>
#include <sys/file.h>
#include "busybox.h"
#include "runit_lib.h"

static unsigned verbose;
static int linemax = 1000;
static int buflen = 1024;
static int linelen;

static char **fndir;
static int fdwdir;
static int wstat;
static struct taia trotate;

static char *line;
static unsigned exitasap;
static unsigned rotateasap;
static unsigned reopenasap;
static unsigned linecomplete = 1;
static unsigned tmaxflag;
static iopause_fd in;

static const char *replace = "";
static char repl;

static struct logdir {
	char *btmp;
	/* pattern list to match, in "aa\0bb\0\cc\0\0" form */
	char *inst;
	char *processor;
	char *name;
	unsigned size;
	unsigned sizemax;
	unsigned nmax;
	unsigned nmin;
	/* int (not long) because of taia_uint() usage: */
	unsigned tmax;
	int ppid;
	int fddir;
	int fdcur;
	int fdlock;
	struct taia trotate;
	char fnsave[FMT_PTIME];
	char match;
	char matcherr;
} *dir;
static unsigned dirn = 0;

#define FATAL "fatal: "
#define WARNING "warning: "
#define PAUSE "pausing: "
#define INFO "info: "

#define usage() bb_show_usage()
static void fatalx(char *m0)
{
	bb_error_msg_and_die(FATAL"%s", m0);
}
static void warn(char *m0) {
	bb_perror_msg(WARNING"%s", m0);
}
static void warn2(char *m0, char *m1)
{
	bb_perror_msg(WARNING"%s: %s", m0, m1);
}
static void warnx(char *m0, char *m1)
{
	bb_error_msg(WARNING"%s: %s", m0, m1);
}
static void pause_nomem(void)
{
	bb_error_msg(PAUSE"out of memory"); sleep(3);
}
static void pause1cannot(char *m0)
{
	bb_perror_msg(PAUSE"cannot %s", m0); sleep(3);
}
static void pause2cannot(char *m0, char *m1)
{
	bb_perror_msg(PAUSE"cannot %s %s", m0, m1);
	sleep(3);
}

static char* wstrdup(const char *str)
{
	char *s;
	while (!(s = strdup(str))) pause_nomem();
	return s;
}

static unsigned processorstart(struct logdir *ld)
{
	int pid;

	if (!ld->processor) return 0;
	if (ld->ppid) {
		warnx("processor already running", ld->name);
		return 0;
	}
	while ((pid = fork()) == -1)
		pause2cannot("fork for processor", ld->name);
	if (!pid) {
		char *prog[4];
		int fd;

		/* child */
		sig_uncatch(sig_term);
		sig_uncatch(sig_alarm);
		sig_uncatch(sig_hangup);
		sig_unblock(sig_term);
		sig_unblock(sig_alarm);
		sig_unblock(sig_hangup);
		
		if (verbose)
			bb_error_msg(INFO"processing: %s/%s", ld->name, ld->fnsave);
		fd = xopen(ld->fnsave, O_RDONLY|O_NDELAY);
		if (fd_move(0, fd) == -1)
			bb_perror_msg_and_die(FATAL"cannot %s processor %s", "move filedescriptor for", ld->name);
		ld->fnsave[26] = 't';
		fd = xopen(ld->fnsave, O_WRONLY|O_NDELAY|O_TRUNC|O_CREAT);
		if (fd_move(1, fd) == -1)
			bb_perror_msg_and_die(FATAL"cannot %s processor %s", "move filedescriptor for", ld->name);
		fd = open_read("state");
		if (fd == -1) {
			if (errno != ENOENT)
				bb_perror_msg_and_die(FATAL"cannot %s processor %s", "open state for", ld->name);
			close(xopen("state", O_WRONLY|O_NDELAY|O_TRUNC|O_CREAT));
			fd = xopen("state", O_RDONLY|O_NDELAY);
		}
		if (fd_move(4, fd) == -1)
			bb_perror_msg_and_die(FATAL"cannot %s processor %s", "move filedescriptor for", ld->name);
		fd = xopen("newstate", O_WRONLY|O_NDELAY|O_TRUNC|O_CREAT);
		if (fd_move(5, fd) == -1)
			bb_perror_msg_and_die(FATAL"cannot %s processor %s", "move filedescriptor for", ld->name);

		prog[0] = "sh";
		prog[1] = "-c";
		prog[2] = ld->processor;
		prog[3] = '\0';
		execve("/bin/sh", prog, environ);
		bb_perror_msg_and_die(FATAL"cannot %s processor %s", "run", ld->name);
	}
	ld->ppid = pid;
	return 1;
}

static unsigned processorstop(struct logdir *ld)
{
	char f[28];

	if (ld->ppid) {
		sig_unblock(sig_hangup);
		while (wait_pid(&wstat, ld->ppid) == -1)
			pause2cannot("wait for processor", ld->name);
		sig_block(sig_hangup);
		ld->ppid = 0;
	}
	if (ld->fddir == -1) return 1;
	while (fchdir(ld->fddir) == -1)
		pause2cannot("change directory, want processor", ld->name);
	if (wait_exitcode(wstat) != 0) {
		warnx("processor failed, restart", ld->name);
		ld->fnsave[26] = 't';
		unlink(ld->fnsave);
		ld->fnsave[26] = 'u';
		processorstart(ld);
		while (fchdir(fdwdir) == -1)
			pause1cannot("change to initial working directory");
		return ld->processor ? 0 : 1;
	}
	ld->fnsave[26] = 't';
	memcpy(f, ld->fnsave, 26);
	f[26] = 's';
	f[27] = '\0';
	while (rename(ld->fnsave, f) == -1)
		pause2cannot("rename processed", ld->name);
	while (chmod(f, 0744) == -1)
		pause2cannot("set mode of processed", ld->name);
	ld->fnsave[26] = 'u';
	if (unlink(ld->fnsave) == -1)
		bb_error_msg(WARNING"cannot unlink: %s/%s", ld->name, ld->fnsave);
	while (rename("newstate", "state") == -1)
		pause2cannot("rename state", ld->name);
	if (verbose) bb_error_msg(INFO"processed: %s/%s", ld->name, f);
	while (fchdir(fdwdir) == -1)
		pause1cannot("change to initial working directory");
	return 1;
}

static void rmoldest(struct logdir *ld)
{
	DIR *d;
	struct dirent *f;
	char oldest[FMT_PTIME];
	int n = 0;

	oldest[0] = 'A'; oldest[1] = oldest[27] = 0;
	while (!(d = opendir(".")))
		pause2cannot("open directory, want rotate", ld->name);
	errno = 0;
	while ((f = readdir(d))) {
		if ((f->d_name[0] == '@') && (strlen(f->d_name) == 27)) {
			if (f->d_name[26] == 't') {
				if (unlink(f->d_name) == -1)
					warn2("cannot unlink processor leftover", f->d_name);
			} else {
				++n;
				if (strcmp(f->d_name, oldest) < 0)
					memcpy(oldest, f->d_name, 27);
			}
			errno = 0;
		}
	}
	if (errno) warn2("cannot read directory", ld->name);
	closedir(d);

	if (ld->nmax && (n > ld->nmax)) {
		if (verbose) bb_error_msg(INFO"delete: %s/%s", ld->name, oldest);
		if ((*oldest == '@') && (unlink(oldest) == -1))
			warn2("cannot unlink oldest logfile", ld->name);
	}
}

static unsigned rotate(struct logdir *ld)
{
	struct stat st;
	struct taia now;

	if (ld->fddir == -1) {
		ld->tmax = 0;
		return 0;
	}
	if (ld->ppid)
		while (!processorstop(ld))
			/* wait */;

	while (fchdir(ld->fddir) == -1)
		pause2cannot("change directory, want rotate", ld->name);

	/* create new filename */
	ld->fnsave[25] = '.';
	ld->fnsave[26] = 's';
	if (ld->processor)
		ld->fnsave[26] = 'u';
	ld->fnsave[27] = '\0';
	do {
		taia_now(&now);
		fmt_taia(ld->fnsave, &now);
		errno = 0;
	} while ((stat(ld->fnsave, &st) != -1) || (errno != ENOENT));

	if (ld->tmax && taia_less(&ld->trotate, &now)) {
		taia_uint(&ld->trotate, ld->tmax);
		taia_add(&ld->trotate, &now, &ld->trotate);
		if (taia_less(&ld->trotate, &trotate))
			trotate = ld->trotate;
	}

	if (ld->size > 0) {
		while (fsync(ld->fdcur) == -1)
			pause2cannot("fsync current logfile", ld->name);
		while (fchmod(ld->fdcur, 0744) == -1)
			pause2cannot("set mode of current", ld->name);
		close(ld->fdcur);
		if (verbose) {
			bb_error_msg(INFO"rename: %s/current %s %u", ld->name,
					ld->fnsave, ld->size);
		}
		while (rename("current", ld->fnsave) == -1)
			pause2cannot("rename current", ld->name);
		while ((ld->fdcur = open("current", O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600)) == -1)
			pause2cannot("create new current", ld->name);
		coe(ld->fdcur);
		ld->size = 0;
		while (fchmod(ld->fdcur, 0644) == -1)
			pause2cannot("set mode of current", ld->name);
		rmoldest(ld);
		processorstart(ld);
	}

	while (fchdir(fdwdir) == -1)
		pause1cannot("change to initial working directory");
	return 1;
}

static int buffer_pwrite(int n, char *s, unsigned len)
{
	int i;
	struct logdir *ld = &dir[n];

	if (ld->sizemax) {
		if (ld->size >= ld->sizemax)
			rotate(ld);
		if (len > (ld->sizemax - ld->size))
			len = ld->sizemax - ld->size;
	}
	while ((i = write(ld->fdcur, s, len)) == -1) {
		if ((errno == ENOSPC) && (ld->nmin < ld->nmax)) {
			DIR *d;
			struct dirent *f;
			char oldest[FMT_PTIME];
			int j = 0;

			while (fchdir(ld->fddir) == -1)
				pause2cannot("change directory, want remove old logfile",
							 ld->name);
			oldest[0] = 'A';
			oldest[1] = oldest[27] = '\0';
			while (!(d = opendir(".")))
				pause2cannot("open directory, want remove old logfile",
							 ld->name);
			errno = 0;
			while ((f = readdir(d)))
				if ((f->d_name[0] == '@') && (strlen(f->d_name) == 27)) {
					++j;
					if (strcmp(f->d_name, oldest) < 0)
						memcpy(oldest, f->d_name, 27);
				}
			if (errno) warn2("cannot read directory, want remove old logfile",
					ld->name);
			closedir(d);
			errno = ENOSPC;
			if (j > ld->nmin) {
				if (*oldest == '@') {
					bb_error_msg(WARNING"out of disk space, delete: %s/%s",
							ld->name, oldest);
					errno = 0;
					if (unlink(oldest) == -1) {
						warn2("cannot unlink oldest logfile", ld->name);
						errno = ENOSPC;
					}
					while (fchdir(fdwdir) == -1)
						pause1cannot("change to initial working directory");
				}
			}
		}
		if (errno) pause2cannot("write to current", ld->name);
	}

	ld->size += i;
	if (ld->sizemax)
		if (s[i-1] == '\n')
			if (ld->size >= (ld->sizemax - linemax))
				rotate(ld);
	return i;
}

static void logdir_close(struct logdir *ld)
{
	if (ld->fddir == -1)
		return;
	if (verbose)
		bb_error_msg(INFO"close: %s", ld->name);
	close(ld->fddir);
	ld->fddir = -1;
	if (ld->fdcur == -1)
		return; /* impossible */
	while (fsync(ld->fdcur) == -1)
		pause2cannot("fsync current logfile", ld->name);
	while (fchmod(ld->fdcur, 0744) == -1)
		pause2cannot("set mode of current", ld->name);
	close(ld->fdcur);
	ld->fdcur = -1;
	if (ld->fdlock == -1)
		return; /* impossible */
	close(ld->fdlock);
	ld->fdlock = -1;
	free(ld->processor);
	ld->processor = NULL;
}

static unsigned logdir_open(struct logdir *ld, const char *fn)
{
	char buf[128];
	struct taia now;
	char *new, *s, *np;
	int i;
	struct stat st;

	ld->fddir = open(fn, O_RDONLY|O_NDELAY);
	if (ld->fddir == -1) {
		warn2("cannot open log directory", (char*)fn);
		return 0;
	}
	coe(ld->fddir);
	if (fchdir(ld->fddir) == -1) {
		logdir_close(ld);
		warn2("cannot change directory", (char*)fn);
		return 0;
	}
	ld->fdlock = open("lock", O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600);
	if ((ld->fdlock == -1)
	 || (lock_exnb(ld->fdlock) == -1)
	) {
		logdir_close(ld);
		warn2("cannot lock directory", (char*)fn);
		while (fchdir(fdwdir) == -1)
			pause1cannot("change to initial working directory");
		return 0;
	}
	coe(ld->fdlock);

	ld->size = 0;
	ld->sizemax = 1000000;
	ld->nmax = ld->nmin = 10;
	ld->tmax = 0;
	ld->name = (char*)fn;
	ld->ppid = 0;
	ld->match = '+';
	free(ld->inst); ld->inst = NULL;
	free(ld->processor); ld->processor = NULL;

	/* read config */
	i = open_read_close("config", buf, sizeof(buf));
	if (i < 0)
		warn2("cannot read config", ld->name);
	if (i > 0) {
		if (verbose) bb_error_msg(INFO"read: %s/config", ld->name);
		s = buf;
		while (s) {
			np = strchr(s, '\n');
			if (np) *np++ = '\0';
			switch (s[0]) {
			case '+':
			case '-':
			case 'e':
			case 'E':
				while (1) {
					int l = asprintf(&new, "%s%s\n", ld->inst?:"", s);
					if (l >= 0 && new) break;
					pause_nomem();
				}
				free(ld->inst);
				ld->inst = new;
				break;
			case 's': {
				static const struct suffix_mult km_suffixes[] = {
						{ "k", 1024 },
						{ "m", 1024*1024 },
						{ NULL, 0 }
				};
				ld->sizemax = xatou_sfx(&s[1], km_suffixes);
				break;
			}
			case 'n':
				ld->nmax = xatoi_u(&s[1]);
				break;
			case 'N':
				ld->nmin = xatoi_u(&s[1]);
				break;
			case 't': {
				static const struct suffix_mult mh_suffixes[] = {
						{ "m", 60 },
						{ "h", 60*60 },
						/*{ "d", 24*60*60 },*/
						{ NULL, 0 }
				};
				ld->tmax = xatou_sfx(&s[1], mh_suffixes);
				if (ld->tmax) {
					taia_uint(&ld->trotate, ld->tmax);
					taia_add(&ld->trotate, &now, &ld->trotate);
					if (!tmaxflag || taia_less(&ld->trotate, &trotate))
						trotate = ld->trotate;
					tmaxflag = 1;
				}
				break;
			}
			case '!':
				if (s[1]) {
					free(ld->processor);
					ld->processor = wstrdup(s);
				}
				break;
			}
			s = np;
		}
		/* Convert "aa\nbb\ncc\n\0" to "aa\0bb\0cc\0\0" */
		s = ld->inst;
		while (s) {
			np = strchr(s, '\n');
			if (np) *np++ = '\0';
			s = np;
		}
	}

	/* open current */
	i = stat("current", &st);
	if (i != -1) {
		if (st.st_size && ! (st.st_mode & S_IXUSR)) {
			ld->fnsave[25] = '.';
			ld->fnsave[26] = 'u';
			ld->fnsave[27] = '\0';
			do {
				taia_now(&now);
				fmt_taia(ld->fnsave, &now);
				errno = 0;
			} while ((stat(ld->fnsave, &st) != -1) || (errno != ENOENT));
			while (rename("current", ld->fnsave) == -1)
				pause2cannot("rename current", ld->name);
			rmoldest(ld);
			i = -1;
		} else {
			/* Be paranoid: st.st_size can be not just bigger, but WIDER! */
			/* (bug in original svlogd. remove this comment when fixed there) */
			ld->size = (st.st_size > ld->sizemax) ? ld->sizemax : st.st_size;
		}
	} else {
		if (errno != ENOENT) {
			logdir_close(ld);
			warn2("cannot stat current", ld->name);
			while (fchdir(fdwdir) == -1)
				pause1cannot("change to initial working directory");
			return 0;
		}
	}
	while ((ld->fdcur = open("current", O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600)) == -1)
		pause2cannot("open current", ld->name);
	coe(ld->fdcur);
	while (fchmod(ld->fdcur, 0644) == -1)
		pause2cannot("set mode of current", ld->name);
	
	if (verbose) {
		if (i == 0) bb_error_msg(INFO"append: %s/current", ld->name);
		else bb_error_msg(INFO"new: %s/current", ld->name);
	}
	
	while (fchdir(fdwdir) == -1)
		pause1cannot("change to initial working directory");
	return 1;
}

static void logdirs_reopen(void)
{
	struct taia now;
	int l;
	int ok = 0;

	tmaxflag = 0;
	taia_now(&now);
	for (l = 0; l < dirn; ++l) {
		logdir_close(&dir[l]);    
		if (logdir_open(&dir[l], fndir[l])) ok = 1;
	}
	if (!ok) fatalx("no functional log directories");
}

/* Used for reading stdin */
static int buffer_pread(int fd, char *s, unsigned len)
{
	struct taia now;
	int i;

	if (rotateasap) {
		for (i = 0; i < dirn; ++i)
			rotate(dir+i);
		rotateasap = 0;
	}
	if (exitasap) {
		if (linecomplete)
			return 0;
		len = 1;
	}
	if (reopenasap) {
		logdirs_reopen();
		reopenasap = 0;
	}
	taia_now(&now);
	taia_uint(&trotate, 2744);
	taia_add(&trotate, &now, &trotate);
	for (i = 0; i < dirn; ++i)
		if (dir[i].tmax) {
			if (taia_less(&dir[i].trotate, &now))
				rotate(dir+i);
			if (taia_less(&dir[i].trotate, &trotate))
				trotate = dir[i].trotate;
		}

	while (1) {
		/* Comment? */
		sig_unblock(sig_term);
		sig_unblock(sig_child);
		sig_unblock(sig_alarm);
		sig_unblock(sig_hangup);
		iopause(&in, 1, &trotate, &now);
		sig_block(sig_term);
		sig_block(sig_child);
		sig_block(sig_alarm);
		sig_block(sig_hangup);
		i = safe_read(fd, s, len);
		if (i >= 0) break;
		if (errno != EAGAIN) {
			warn("cannot read standard input");
			break;
		}
		/* else: EAGAIN - normal, repeat silently */
	}

	if (i > 0) {
		int cnt;
		linecomplete = (s[i-1] == '\n');
		if (!repl) return i;

		cnt = i;
		while (--cnt >= 0) {
			char ch = *s;
			if (ch != '\n') {
				if (ch < 32 || ch > 126)
					*s = repl;
				else {
					int j;
					for (j = 0; replace[j]; ++j) {
						if (ch == replace[j]) {
							*s = repl;
							break;
						}
					}
				}
			}
			s++;
		}
	}
	return i;
}


static void sig_term_handler(int sig_no)
{
	if (verbose)
		bb_error_msg(INFO"sig%s received", "term");
	exitasap = 1;
}

static void sig_child_handler(int sig_no)
{
	int pid, l;

	if (verbose)
		bb_error_msg(INFO"sig%s received", "child");
	while ((pid = wait_nohang(&wstat)) > 0)
		for (l = 0; l < dirn; ++l)
			if (dir[l].ppid == pid) {
				dir[l].ppid = 0;
				processorstop(&dir[l]);
				break;
			}
}

static void sig_alarm_handler(int sig_no)
{
	if (verbose)
		bb_error_msg(INFO"sig%s received", "alarm");
	rotateasap = 1;
}

static void sig_hangup_handler(int sig_no)
{
	if (verbose)
		bb_error_msg(INFO"sig%s received", "hangup");
	reopenasap = 1;
}

static void logmatch(struct logdir *ld)
{
	char *s;

	ld->match = '+';
	ld->matcherr = 'E';
	s = ld->inst;
	while (s && s[0]) {
		switch (s[0]) {
		case '+':
		case '-':
			if (pmatch(s+1, line, linelen))
				ld->match = s[0];
			break;
		case 'e':
		case 'E':
			if (pmatch(s+1, line, linelen))
				ld->matcherr = s[0];
			break;
		}
		s += strlen(s) + 1;
	}
}

int svlogd_main(int argc, char **argv)
{
	struct taia now;
	char *r,*l,*b;
	ssize_t stdin_cnt = 0;
	int i;
	unsigned opt;
	unsigned timestamp = 0;

	opt_complementary = "tt:vv";
	opt = getopt32(argc, argv, "r:R:l:b:tv",
			&r, &replace, &l, &b, &timestamp, &verbose);
	if (opt & 1) { // -r
		repl = r[0];
		if (!repl || r[1]) usage();
	}
	if (opt & 2) if (!repl) repl = '_'; // -R
	if (opt & 4) { // -l
		linemax = xatou_range(l, 0, 1000);
		if (linemax == 0) linemax = 1000;
		if (linemax < 256) linemax = 256;
	}
	if (opt & 8) { // -b
		buflen = xatoi_u(b);
		if (buflen == 0) buflen = 1024;
	}
	//if (opt & 0x10) timestamp++; // -t
	//if (opt & 0x20) verbose++; // -v
	if (timestamp > 2) timestamp = 2;
	argv += optind;
	argc -= optind;

	dirn = argc;
	if (dirn <= 0) usage();
	if (buflen <= linemax) usage();
	fdwdir = xopen(".", O_RDONLY|O_NDELAY);
	coe(fdwdir);
	dir = xmalloc(dirn * sizeof(struct logdir));
	for (i = 0; i < dirn; ++i) {
		dir[i].fddir = -1;
		dir[i].fdcur = -1;
		dir[i].btmp = xmalloc(buflen);
		dir[i].ppid = 0;
	}
	line = xmalloc(linemax + (timestamp ? 26 : 0));
	fndir = argv;
	in.fd = 0;
	in.events = IOPAUSE_READ;
	ndelay_on(in.fd);

	sig_block(sig_term);
	sig_block(sig_child);
	sig_block(sig_alarm);
	sig_block(sig_hangup);
	sig_catch(sig_term, sig_term_handler);
	sig_catch(sig_child, sig_child_handler);
	sig_catch(sig_alarm, sig_alarm_handler);
	sig_catch(sig_hangup, sig_hangup_handler);

	logdirs_reopen();

	/* Each iteration processes one line */
	while (1) {
		int printlen;
		char *lineptr = line;
		char *np;
		char ch;

		/* Prepare timestamp if needed */
		if (timestamp) {
			char stamp[FMT_PTIME];
			taia_now(&now);
			switch (timestamp) {
			case 1:
				fmt_taia(stamp, &now);
				break;
			default: /* case 2: */
				fmt_ptime(stamp, &now);
				break;
			}
			memcpy(line, stamp, 25);
			line[25] = ' ';
			lineptr += 26;
		}

		/* lineptr[0..linemax-1] - buffer for stdin */
		/* (possibly has some unprocessed data from prev loop) */

		/* Refill the buffer if needed */
		np = memchr(lineptr, '\n', stdin_cnt);
		i = linemax - stdin_cnt; /* avail. bytes at tail */
		if (i >= 128 && !exitasap && !np) {
			int sz = buffer_pread(0, lineptr + stdin_cnt, i);
			if (sz <= 0) /* EOF or error on stdin */
				exitasap = 1;
			else {
				stdin_cnt += sz;
				np = memchr(lineptr, '\n', stdin_cnt);
			}
		}
		if (stdin_cnt <= 0 && exitasap)
			break;

		/* Search for '\n' (in fact, np already holds the result) */
		linelen = stdin_cnt;
		if (np) linelen = np - lineptr + 1;
		/* linelen == no of chars incl. '\n' (or == stdin_cnt) */
		ch = lineptr[linelen-1];

		printlen = linelen + (timestamp ? 26 : 0);
		/* write out line[0..printlen-1] to each log destination */
		for (i = 0; i < dirn; ++i) {
			struct logdir *ld = &dir[i];
			if (ld->fddir == -1) continue;
			if (ld->inst)
				logmatch(ld);
			if (ld->matcherr == 'e')
				full_write(2, line, printlen);
			if (ld->match != '+') continue;
			buffer_pwrite(i, line, printlen);
		}

		/* If we didn't see '\n' (long input line), */
		/* read/write repeatedly until we see it */
		while (ch != '\n') {
			/* lineptr is emptied now, safe to use as buffer */
			stdin_cnt = exitasap ? -1 : buffer_pread(0, lineptr, linemax);
			if (stdin_cnt <= 0) { /* EOF or error on stdin */
				lineptr[0] = ch = '\n';
				linelen = 1;
				exitasap = 1;
				stdin_cnt = 1;
			} else {
				linelen = stdin_cnt;
				np = memchr(lineptr, '\n', stdin_cnt);
				if (np) linelen = np - lineptr + 1;
				ch = lineptr[linelen-1];
			}
			/* linelen == no of chars incl. '\n' (or == stdin_cnt) */
			for (i = 0; i < dirn; ++i) {
				if (dir[i].fddir == -1) continue;
				if (dir[i].matcherr == 'e')
					full_write(2, lineptr, linelen);
				if (dir[i].match != '+') continue;
				buffer_pwrite(i, lineptr, linelen);
			}
		}

		/* Move unprocessed data to the front of line */
		stdin_cnt -= linelen;
		if (stdin_cnt > 0) /* TODO: slow if buffer is big */
			memmove(lineptr, &lineptr[linelen], stdin_cnt);
	}

	for (i = 0; i < dirn; ++i) {
		if (dir[i].ppid)
			while (!processorstop(&dir[i]))
				/* repeat */;
		logdir_close(&dir[i]);
	}
	_exit(0);
}
