/* vi: set sw=4 ts=4: */
/*
 * Mini tail implementation for busybox
 *
 * Copyright (C) 2001 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 */

/* BB_AUDIT SUSv3 compliant (need fancy for -c) */
/* BB_AUDIT GNU compatible -c, -q, and -v options in 'fancy' configuration. */
/* http://www.opengroup.org/onlinepubs/007904975/utilities/tail.html */

/* Mar 16, 2003      Manuel Novoa III   (mjn3@codepoet.org)
 *
 * Pretty much rewritten to fix numerous bugs and reduce realloc() calls.
 * Bugs fixed (although I may have forgotten one or two... it was pretty bad)
 * 1) mixing printf/write without fflush()ing stdout
 * 2) no check that any open files are present
 * 3) optstring had -q taking an arg
 * 4) no error checking on write in some cases, and a warning even then
 * 5) q and s interaction bug
 * 6) no check for lseek error
 * 7) lseek attempted when count==0 even if arg was +0 (from top)
 */

#include "libbb.h"

static const struct suffix_mult tail_suffixes[] = {
	{ "b", 512 },
	{ "k", 1024 },
	{ "m", 1024*1024 },
	{ }
};

struct globals {
	bool status;
};
#define G (*(struct globals*)&bb_common_bufsiz1)

static void tail_xprint_header(const char *fmt, const char *filename)
{
	if (fdprintf(STDOUT_FILENO, fmt, filename) < 0)
		bb_perror_nomsg_and_die();
}

static ssize_t tail_read(int fd, char *buf, size_t count)
{
	ssize_t r;
	off_t current;
	struct stat sbuf;

	/* (A good comment is missing here) */
	current = lseek(fd, 0, SEEK_CUR);
	/* /proc files report zero st_size, don't lseek them. */
	if (fstat(fd, &sbuf) == 0 && sbuf.st_size)
		if (sbuf.st_size < current)
			lseek(fd, 0, SEEK_SET);

	r = full_read(fd, buf, count);
	if (r < 0) {
		bb_perror_msg(bb_msg_read_error);
		G.status = EXIT_FAILURE;
	}

	return r;
}

static const char header_fmt[] ALIGN1 = "\n==> %s <==\n";

static unsigned eat_num(const char *p)
{
	if (*p == '-')
		p++;
	else if (*p == '+') {
		p++;
		G.status = 1; /* mark that we saw "+" */
	}
	return xatou_sfx(p, tail_suffixes);
}

int tail_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int tail_main(int argc, char **argv)
{
	unsigned count = 10;
	unsigned sleep_period = 1;
	bool from_top;
	int header_threshhold = 1;
	const char *str_c, *str_n;

	char *tailbuf;
	size_t tailbufsize;
	int taillen = 0;
	int newlines_seen = 0;
	int nfiles, nread, nwrite, seen, i, opt;

	int *fds;
	char *s, *buf;
	const char *fmt;

#if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_TAIL
	/* Allow legacy syntax of an initial numeric option without -n. */
	if (argv[1] && (argv[1][0] == '+' || argv[1][0] == '-')
	 && isdigit(argv[1][1])
	) {
		count = eat_num(&argv[1][1]);
		argv++;
		argc--;
	}
#endif

	USE_FEATURE_FANCY_TAIL(opt_complementary = "s+";) /* -s N */
	opt = getopt32(argv, "fc:n:" USE_FEATURE_FANCY_TAIL("qs:v"),
			&str_c, &str_n USE_FEATURE_FANCY_TAIL(,&sleep_period));
#define FOLLOW (opt & 0x1)
#define COUNT_BYTES (opt & 0x2)
	//if (opt & 0x1) // -f
	if (opt & 0x2) count = eat_num(str_c); // -c
	if (opt & 0x4) count = eat_num(str_n); // -n
#if ENABLE_FEATURE_FANCY_TAIL
	if (opt & 0x8) header_threshhold = INT_MAX; // -q
	if (opt & 0x20) header_threshhold = 0; // -v
#endif
	argc -= optind;
	argv += optind;
	from_top = G.status; /* 1 if there was "-c +N" or "-n +N" */
	G.status = EXIT_SUCCESS;

	/* open all the files */
	fds = xmalloc(sizeof(int) * (argc + 1));
	if (!argv[0]) {
		struct stat statbuf;

		if (!fstat(STDIN_FILENO, &statbuf) && S_ISFIFO(statbuf.st_mode)) {
			opt &= ~1; /* clear FOLLOW */
		}
		*argv = (char *) bb_msg_standard_input;
	}
	nfiles = i = 0;
	do {
		int fd = open_or_warn_stdin(argv[i]);
		if (fd < 0) {
			G.status = EXIT_FAILURE;
			continue;
		}
		fds[nfiles] = fd;
		argv[nfiles++] = argv[i];
	} while (++i < argc);

	if (!nfiles)
		bb_error_msg_and_die("no files");

	/* prepare the buffer */
	tailbufsize = BUFSIZ;
	if (!from_top && COUNT_BYTES) {
		if (tailbufsize < count + BUFSIZ) {
			tailbufsize = count + BUFSIZ;
		}
	}
	tailbuf = xmalloc(tailbufsize);

	/* tail the files */
	fmt = header_fmt + 1;	/* Skip header leading newline on first output. */
	i = 0;
	do {
		off_t current;

		if (nfiles > header_threshhold) {
			tail_xprint_header(fmt, argv[i]);
			fmt = header_fmt;
		}

		/* Optimizing count-bytes case if the file is seekable.
		 * Beware of backing up too far.
		 * Also we exclude files with size 0 (because of /proc/xxx) */
		current = lseek(fds[i], 0, SEEK_END);
		if (current > 0) {
			if (!from_top) {
				if (count == 0)
					continue; /* showing zero lines is easy :) */
				if (COUNT_BYTES) {
					current -= count;
					if (current < 0)
						current = 0;
					xlseek(fds[i], current, SEEK_SET);
					bb_copyfd_size(fds[i], STDOUT_FILENO, count);
					continue;
				}
			}
		}

		buf = tailbuf;
		taillen = 0;
		seen = 1;
		newlines_seen = 0;
		while ((nread = tail_read(fds[i], buf, tailbufsize-taillen)) > 0) {
			if (from_top) {
				nwrite = nread;
				if (seen < count) {
					if (COUNT_BYTES) {
						nwrite -= (count - seen);
						seen = count;
					} else {
						s = buf;
						do {
							--nwrite;
							if (*s++ == '\n' && ++seen == count) {
								break;
							}
						} while (nwrite);
					}
				}
				xwrite(STDOUT_FILENO, buf + nread - nwrite, nwrite);
			} else if (count) {
				if (COUNT_BYTES) {
					taillen += nread;
					if (taillen > count) {
						memmove(tailbuf, tailbuf + taillen - count, count);
						taillen = count;
					}
				} else {
					int k = nread;
					int newlines_in_buf = 0;

					do { /* count '\n' in last read */
						k--;
						if (buf[k] == '\n') {
							newlines_in_buf++;
						}
					} while (k);

					if (newlines_seen + newlines_in_buf < count) {
						newlines_seen += newlines_in_buf;
						taillen += nread;
					} else {
						int extra = (buf[nread-1] != '\n');

						k = newlines_seen + newlines_in_buf + extra - count;
						s = tailbuf;
						while (k) {
							if (*s == '\n') {
								k--;
							}
							s++;
						}
						taillen += nread - (s - tailbuf);
						memmove(tailbuf, s, taillen);
						newlines_seen = count - extra;
					}
					if (tailbufsize < taillen + BUFSIZ) {
						tailbufsize = taillen + BUFSIZ;
						tailbuf = xrealloc(tailbuf, tailbufsize);
					}
				}
				buf = tailbuf + taillen;
			}
		} /* while (tail_read() > 0) */
		if (!from_top) {
			xwrite(STDOUT_FILENO, tailbuf, taillen);
		}
	} while (++i < nfiles);

	buf = xrealloc(tailbuf, BUFSIZ);

	fmt = NULL;

	if (FOLLOW) while (1) {
		sleep(sleep_period);
		i = 0;
		do {
			if (nfiles > header_threshhold) {
				fmt = header_fmt;
			}
			while ((nread = tail_read(fds[i], buf, BUFSIZ)) > 0) {
				if (fmt) {
					tail_xprint_header(fmt, argv[i]);
					fmt = NULL;
				}
				xwrite(STDOUT_FILENO, buf, nread);
			}
		} while (++i < nfiles);
	}
	if (ENABLE_FEATURE_CLEAN_UP) {
		free(fds);
	}
	return G.status;
}
