119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * logsave.c --- A program which saves the output of a program until
319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *	/var/log is mounted.
419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 2003 Theodore Ts'o.
619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %Begin-Header%
819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This file may be redistributed under the terms of the GNU Public
919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * License.
1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %End-Header%
1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h>
1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdlib.h>
1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h>
1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h>
1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/types.h>
1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/wait.h>
1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <fcntl.h>
2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <time.h>
2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h>
2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_GETOPT_H
2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <getopt.h>
2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else
2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern char *optarg;
2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern int optind;
2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint	outfd = -1;
3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint	outbufsize = 0;
3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectvoid	*outbuf = 0;
3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint	verbose = 0;
3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint	do_skip = 0;
3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint	skip_mode = 0;
3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void usage(char *progname)
3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf("Usage: %s [-v] [-d dir] logfile program\n", progname);
3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	exit(1);
4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define SEND_LOG	0x01
4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define SEND_CONSOLE	0x02
4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define SEND_BOTH	0x03
4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void send_output(const char *buffer, int c, int flag)
4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char	*n;
4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (c == 0)
5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		c = strlen(buffer);
5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (flag & SEND_CONSOLE)
5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		write(1, buffer, c);
5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!(flag & SEND_LOG))
5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (outfd > 0)
5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		write(outfd, buffer, c);
5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else {
6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		n = realloc(outbuf, outbufsize + c);
6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (n) {
6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			outbuf = n;
6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			memcpy(((char *)outbuf)+outbufsize, buffer, c);
6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			outbufsize += c;
6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int do_read(int fd)
7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	c;
7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char	buffer[4096], *cp, *sep;
7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	c = read(fd, buffer, sizeof(buffer)-1);
7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (c <= 0)
7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return c;
7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (do_skip) {
7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		send_output(buffer, c, SEND_CONSOLE);
7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		buffer[c] = 0;
8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cp = buffer;
8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		while (*cp) {
8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (skip_mode) {
8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				cp = strchr(cp, '\002');
8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				if (!cp)
8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					return 0;
8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				cp++;
8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				skip_mode = 0;
8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				continue;
8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			sep = strchr(cp, '\001');
9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (sep)
9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				*sep = 0;
9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			send_output(cp, 0, SEND_LOG);
9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (sep) {
9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				cp = sep + 1;
9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				skip_mode = 1;
9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			} else
9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				break;
9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	} else
10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		send_output(buffer, c, SEND_BOTH);
10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return c;
10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int run_program(char **argv)
10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	fds[2];
10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	status, rc, pid;
10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char	buffer[80];
11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (pipe(fds) < 0) {
11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		perror("pipe");
11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit(1);
11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	pid = fork();
11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (pid < 0) {
11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		perror("vfork");
11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit(1);
12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (pid == 0) {
12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		dup2(fds[1],1);		/* fds[1] replaces stdout */
12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		dup2(fds[1],2);  	/* fds[1] replaces stderr */
12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		close(fds[0]);	/* don't need this here */
12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		execvp(argv[0], argv);
12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		perror(argv[0]);
12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit(1);
12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	close(fds[1]);
13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (!(waitpid(pid, &status, WNOHANG ))) {
13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		do_read(fds[0]);
13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	do_read(fds[0]);
13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	close(fds[0]);
13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ( WIFEXITED(status) ) {
13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		rc = WEXITSTATUS(status);
14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (rc) {
14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			send_output(argv[0], 0, SEND_BOTH);
14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			sprintf(buffer, " died with exit status %d\n", rc);
14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			send_output(buffer, 0, SEND_BOTH);
14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	} else {
14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (WIFSIGNALED(status)) {
14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			send_output(argv[0], 0, SEND_BOTH);
14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			sprintf(buffer, "died with signal %d\n",
14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				WTERMSIG(status));
15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			send_output(buffer, 0, SEND_BOTH);
15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			rc = 1;
15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		rc = 0;
15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return rc;
15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int copy_from_stdin(void)
15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	c, bad_read = 0;
16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (1) {
16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		c = do_read(0);
16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((c == 0 ) ||
16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    ((c < 0) && ((errno == EAGAIN) || (errno == EINTR)))) {
16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (bad_read++ > 3)
16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				break;
16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			continue;
16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (c < 0) {
17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			perror("read");
17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			exit(1);
17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		bad_read = 0;
17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
17919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint main(int argc, char **argv)
18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
18319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	c, pid, rc;
18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char	*outfn, **cpp;
18519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	openflags = O_CREAT|O_WRONLY|O_TRUNC;
18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	send_flag = SEND_LOG;
18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	do_stdin;
18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	time_t	t;
18919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
19019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while ((c = getopt(argc, argv, "+asv")) != EOF) {
19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		switch (c) {
19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'a':
19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			openflags &= ~O_TRUNC;
19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			openflags |= O_APPEND;
19519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 's':
19719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			do_skip = 1;
19819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
19919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'v':
20019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			verbose++;
20119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			send_flag |= SEND_CONSOLE;
20219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
20319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
20419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
20519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (optind == argc || optind+1 == argc)
20619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		usage(argv[0]);
20719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	outfn = argv[optind];
20819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	optind++;
20919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	argv += optind;
21019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	argc -= optind;
21119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
21219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	outfd = open(outfn, openflags, 0644);
21319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	do_stdin = !strcmp(argv[0], "-");
21419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
21519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	send_output("Log of ", 0, send_flag);
21619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (do_stdin)
21719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		send_output("stdin", 0, send_flag);
21819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else {
21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		for (cpp = argv; *cpp; cpp++) {
22019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			send_output(*cpp, 0, send_flag);
22119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			send_output(" ", 0, send_flag);
22219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
22319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	send_output("\n", 0, send_flag);
22519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	t = time(0);
22619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	send_output(ctime(&t), 0, send_flag);
22719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	send_output("\n", 0, send_flag);
22819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
22919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (do_stdin)
23019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		rc = copy_from_stdin();
23119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else
23219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		rc = run_program(argv);
23319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
23419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	send_output("\n", 0, send_flag);
23519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	t = time(0);
23619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	send_output(ctime(&t), 0, send_flag);
23719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	send_output("----------------\n", 0, send_flag);
23819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (outbuf) {
24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		pid = fork();
24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (pid < 0) {
24219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			perror("fork");
24319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			exit(1);
24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
24519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (pid) {
24619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (verbose)
24719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				printf("Backgrounding to save %s later\n",
24819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				       outfn);
24919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			exit(rc);
25019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		setsid();	/* To avoid getting killed by init */
25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		while (outfd < 0) {
25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			outfd = open(outfn, openflags, 0644);
25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			sleep(1);
25519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
25619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		write(outfd, outbuf, outbufsize);
25719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		free(outbuf);
25819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
25919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	close(outfd);
26019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
26119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	exit(rc);
26219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
263