/*
 * logsave.c --- A program which saves the output of a program until
 *	/var/log is mounted.
 *
 * Copyright (C) 2003 Theodore Ts'o.
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the GNU Public
 * License.
 * %End-Header%
 */

#define _XOPEN_SOURCE 600 /* for inclusion of sa_handler in Solaris */

#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
extern char *optarg;
extern int optind;
#endif

static int	outfd = -1;
static int	outbufsize = 0;
static void	*outbuf = 0;
static int	verbose = 0;
static int	do_skip = 0;
static int	skip_mode = 0;
static pid_t	child_pid = -1;

static void usage(char *progname)
{
	printf("Usage: %s [-asv] logfile program\n", progname);
	exit(1);
}

#define SEND_LOG	0x01
#define SEND_CONSOLE	0x02
#define SEND_BOTH	0x03

/*
 * Helper function that does the right thing if write returns a
 * partial write, or an EGAIN/EINTR error.
 */
static int write_all(int fd, const char *buf, size_t count)
{
	ssize_t ret;
	int c = 0;

	while (count > 0) {
		ret = write(fd, buf, count);
		if (ret < 0) {
			if ((errno == EAGAIN) || (errno == EINTR))
				continue;
			return -1;
		}
		count -= ret;
		buf += ret;
		c += ret;
	}
	return c;
}

static void send_output(const char *buffer, int c, int flag)
{
	const char	*cp;
	char		*n;
	int		cnt, d, del;

	if (c == 0)
		c = strlen(buffer);

	if (flag & SEND_CONSOLE) {
		cnt = c;
		cp = buffer;
		while (cnt) {
			del = 0;
			for (d=0; d < cnt; d++) {
				if (skip_mode &&
				    (cp[d] == '\001' || cp[d] == '\002')) {
					del = 1;
					break;
				}
			}
			write_all(1, cp, d);
			if (del)
				d++;
			cnt -= d;
			cp += d;
		}
	}
	if (!(flag & SEND_LOG))
		return;
	if (outfd > 0)
		write_all(outfd, buffer, c);
	else {
		n = realloc(outbuf, outbufsize + c);
		if (n) {
			outbuf = n;
			memcpy(((char *)outbuf)+outbufsize, buffer, c);
			outbufsize += c;
		}
	}
}

static int do_read(int fd)
{
	int	c;
	char	buffer[4096], *cp, *sep;

	c = read(fd, buffer, sizeof(buffer)-1);
	if (c <= 0)
		return c;
	if (do_skip) {
		send_output(buffer, c, SEND_CONSOLE);
		buffer[c] = 0;
		cp = buffer;
		while (*cp) {
			if (skip_mode) {
				cp = strchr(cp, '\002');
				if (!cp)
					return 0;
				cp++;
				skip_mode = 0;
				continue;
			}
			sep = strchr(cp, '\001');
			if (sep)
				*sep = 0;
			send_output(cp, 0, SEND_LOG);
			if (sep) {
				cp = sep + 1;
				skip_mode = 1;
			} else
				break;
		}
	} else
		send_output(buffer, c, SEND_BOTH);
	return c;
}

static void signal_term(int sig)
{
	if (child_pid > 0)
		kill(child_pid, sig);
}

static int run_program(char **argv)
{
	int	fds[2];
	int	status, rc, pid;
	char	buffer[80];
#ifdef HAVE_SIGNAL_H
	struct sigaction	sa;
#endif

	if (pipe(fds) < 0) {
		perror("pipe");
		exit(1);
	}

#ifdef HAVE_SIGNAL_H
	memset(&sa, 0, sizeof(struct sigaction));
	sa.sa_handler = signal_term;
	sigaction(SIGINT, &sa, 0);
	sigaction(SIGTERM, &sa, 0);
#ifdef SA_RESTART
	sa.sa_flags = SA_RESTART;
#endif
#endif

	pid = fork();
	if (pid < 0) {
		perror("vfork");
		exit(1);
	}
	if (pid == 0) {
		dup2(fds[1],1);		/* fds[1] replaces stdout */
		dup2(fds[1],2);  	/* fds[1] replaces stderr */
		close(fds[0]);	/* don't need this here */
		close(fds[1]);

		execvp(argv[0], argv);
		perror(argv[0]);
		exit(1);
	}
	child_pid = pid;
	close(fds[1]);

	while (!(waitpid(pid, &status, WNOHANG ))) {
		do_read(fds[0]);
	}
	child_pid = -1;
	do_read(fds[0]);
	close(fds[0]);

	if ( WIFEXITED(status) ) {
		rc = WEXITSTATUS(status);
		if (rc) {
			send_output(argv[0], 0, SEND_BOTH);
			sprintf(buffer, " exited with status code %d\n", rc);
			send_output(buffer, 0, SEND_BOTH);
		}
	} else {
		if (WIFSIGNALED(status)) {
			send_output(argv[0], 0, SEND_BOTH);
			sprintf(buffer, "died with signal %d\n",
				WTERMSIG(status));
			send_output(buffer, 0, SEND_BOTH);
			return 1;
		}
		rc = 0;
	}
	return rc;
}

static int copy_from_stdin(void)
{
	int	c, bad_read = 0;

	while (1) {
		c = do_read(0);
		if ((c == 0 ) ||
		    ((c < 0) && ((errno == EAGAIN) || (errno == EINTR)))) {
			if (bad_read++ > 3)
				break;
			continue;
		}
		if (c < 0) {
			perror("read");
			exit(1);
		}
		bad_read = 0;
	}
	return 0;
}



int main(int argc, char **argv)
{
	int	c, pid, rc;
	char	*outfn, **cpp;
	int	openflags = O_CREAT|O_WRONLY|O_TRUNC;
	int	send_flag = SEND_LOG;
	int	do_stdin;
	time_t	t;

	while ((c = getopt(argc, argv, "+asv")) != EOF) {
		switch (c) {
		case 'a':
			openflags &= ~O_TRUNC;
			openflags |= O_APPEND;
			break;
		case 's':
			do_skip = 1;
			break;
		case 'v':
			verbose++;
			send_flag |= SEND_CONSOLE;
			break;
		}
	}
	if (optind == argc || optind+1 == argc)
		usage(argv[0]);
	outfn = argv[optind];
	optind++;
	argv += optind;
	argc -= optind;

	outfd = open(outfn, openflags, 0644);
	do_stdin = !strcmp(argv[0], "-");

	send_output("Log of ", 0, send_flag);
	if (do_stdin)
		send_output("stdin", 0, send_flag);
	else {
		for (cpp = argv; *cpp; cpp++) {
			send_output(*cpp, 0, send_flag);
			send_output(" ", 0, send_flag);
		}
	}
	send_output("\n", 0, send_flag);
	t = time(0);
	send_output(ctime(&t), 0, send_flag);
	send_output("\n", 0, send_flag);

	if (do_stdin)
		rc = copy_from_stdin();
	else
		rc = run_program(argv);

	send_output("\n", 0, send_flag);
	t = time(0);
	send_output(ctime(&t), 0, send_flag);
	send_output("----------------\n", 0, send_flag);

	if (outbuf) {
		pid = fork();
		if (pid < 0) {
			perror("fork");
			exit(1);
		}
		if (pid) {
			if (verbose)
				printf("Backgrounding to save %s later\n",
				       outfn);
			exit(rc);
		}
		setsid();	/* To avoid getting killed by init */
		while (outfd < 0) {
			outfd = open(outfn, openflags, 0644);
			sleep(1);
		}
		write_all(outfd, outbuf, outbufsize);
		free(outbuf);
	}
	if (outfd >= 0)
		close(outfd);

	exit(rc);
}
