/* vi: set sw=4 ts=4: */
/*
 * Mini syslogd implementation for busybox
 *
 * Copyright (C) 1999,2000 by Lineo, inc.
 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
 *
 * Copyright (C) 2000 by Karl M. Hegbloom <karlheg@debian.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

#include "internal.h"
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <paths.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/klog.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/param.h>
#include <time.h>
#include <unistd.h>

#define ksyslog klogctl
extern int ksyslog(int type, char *buf, int len);


/* SYSLOG_NAMES defined to pull some extra junk from syslog.h */
#define SYSLOG_NAMES
#include <sys/syslog.h>

/* Path for the file where all log messages are written */
#define __LOG_FILE "/var/log/messages"

/* Path to the unix socket */
char lfile[BUFSIZ] = "";

static char *logFilePath = __LOG_FILE;

/* interval between marks in seconds */
static int MarkInterval = 20 * 60;

/* localhost's name */
static char LocalHostName[32];

static const char syslogd_usage[] =
	"syslogd [OPTION]...\n"
#ifndef BB_FEATURE_TRIVIAL_HELP
	"\nLinux system and kernel (provides klogd) logging utility.\n"
	"Note that this version of syslogd/klogd ignores /etc/syslog.conf.\n\n"
	"Options:\n"
	"\t-m\tChange the mark timestamp interval. default=20min. 0=off\n"
	"\t-n\tDo not fork into the background (for when run by init)\n"
#ifdef BB_KLOGD
	"\t-K\tDo not start up the klogd process (by default syslogd spawns klogd).\n"
#endif
	"\t-O\tSpecify an alternate log file.  default=/var/log/messages\n"
#endif
	;

/* Note: There is also a function called "message()" in init.c */
/* Print a message to the log file. */
static void message (char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
static void message (char *fmt, ...)
{
	int fd;
	struct flock fl;
	va_list arguments;

	fl.l_whence = SEEK_SET;
	fl.l_start  = 0;
	fl.l_len    = 1;

	if ((fd = device_open (logFilePath,
						   O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND |
						   O_NONBLOCK)) >= 0) {
		fl.l_type = F_WRLCK;
		fcntl (fd, F_SETLKW, &fl);
		va_start (arguments, fmt);
		vdprintf (fd, fmt, arguments);
		va_end (arguments);
		fl.l_type = F_UNLCK;
		fcntl (fd, F_SETLKW, &fl);
		close (fd);
	} else {
		/* Always send console messages to /dev/console so people will see them. */
		if ((fd = device_open (_PATH_CONSOLE,
							   O_WRONLY | O_NOCTTY | O_NONBLOCK)) >= 0) {
			va_start (arguments, fmt);
			vdprintf (fd, fmt, arguments);
			va_end (arguments);
			close (fd);
		} else {
			fprintf (stderr, "Bummer, can't print: ");
			va_start (arguments, fmt);
			vfprintf (stderr, fmt, arguments);
			fflush (stderr);
			va_end (arguments);
		}
	}
}

static void logMessage (int pri, char *msg)
{
	time_t now;
	char *timestamp;
	static char res[20] = "";
	CODE *c_pri, *c_fac;

	if (pri != 0) {
		for (c_fac = facilitynames;
			 c_fac->c_name && !(c_fac->c_val == LOG_FAC(pri) << 3); c_fac++);
		for (c_pri = prioritynames;
			 c_pri->c_name && !(c_pri->c_val == LOG_PRI(pri)); c_pri++);
		if (*c_fac->c_name == '\0' || *c_pri->c_name == '\0')
			snprintf(res, sizeof(res), "<%d>", pri);
		else
			snprintf(res, sizeof(res), "%s.%s", c_fac->c_name, c_pri->c_name);
	}

	if (strlen(msg) < 16 || msg[3] != ' ' || msg[6] != ' ' ||
		msg[9] != ':' || msg[12] != ':' || msg[15] != ' ') {
		time(&now);
		timestamp = ctime(&now) + 4;
		timestamp[15] = '\0';
	} else {
		timestamp = msg;
		timestamp[15] = '\0';
		msg += 16;
	}

	/* todo: supress duplicates */

	/* now spew out the message to wherever it is supposed to go */
	message("%s %s %s %s\n", timestamp, LocalHostName, res, msg);
}

static void quit_signal(int sig)
{
	logMessage(0, "System log daemon exiting.");
	unlink(lfile);
	exit(TRUE);
}

static void domark(int sig)
{
	if (MarkInterval > 0) {
		logMessage(LOG_SYSLOG | LOG_INFO, "-- MARK --");
		alarm(MarkInterval);
	}
}

static void doSyslogd (void) __attribute__ ((noreturn));
static void doSyslogd (void)
{
	struct sockaddr_un sunx;
	socklen_t addrLength;


	int sock_fd;
	fd_set fds;

	char lfile[BUFSIZ];

	/* Set up signal handlers. */
	signal (SIGINT,  quit_signal);
	signal (SIGTERM, quit_signal);
	signal (SIGQUIT, quit_signal);
	signal (SIGHUP,  SIG_IGN);
	signal (SIGCLD,  SIG_IGN);
	signal (SIGALRM, domark);
	alarm (MarkInterval);

	/* Create the syslog file so realpath() can work. */
	close (open (_PATH_LOG, O_RDWR | O_CREAT, 0644));
	if (realpath (_PATH_LOG, lfile) == NULL)
		fatalError ("Could not resolv path to " _PATH_LOG ": %s", strerror (errno));

	unlink (lfile);

	memset (&sunx, 0, sizeof (sunx));
	sunx.sun_family = AF_UNIX;
	strncpy (sunx.sun_path, lfile, sizeof (sunx.sun_path));
	if ((sock_fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
		fatalError ("Couldn't obtain descriptor for socket " _PATH_LOG ": %s", strerror (errno));

	addrLength = sizeof (sunx.sun_family) + strlen (sunx.sun_path);
	if ((bind (sock_fd, (struct sockaddr *) &sunx, addrLength)) || (listen (sock_fd, 5)))
		fatalError ("Could not connect to socket " _PATH_LOG ": %s", strerror (errno));

	if (chmod (lfile, 0666) < 0)
		fatalError ("Could not set permission on " _PATH_LOG ": %s", strerror (errno));

	FD_ZERO (&fds);
	FD_SET (sock_fd, &fds);

	logMessage (0, "syslogd started: BusyBox v" BB_VER " (" BB_BT ")");

	for (;;) {

		fd_set readfds;
		int    n_ready;
		int    fd;

		memcpy (&readfds, &fds, sizeof (fds));

		if ((n_ready = select (FD_SETSIZE, &readfds, NULL, NULL, NULL)) < 0) {
			if (errno == EINTR) continue; /* alarm may have happened. */
			fatalError ("select error: %s\n", strerror (errno));
		}

		for (fd = 0; (n_ready > 0) && (fd < FD_SETSIZE); fd++) {
			if (FD_ISSET (fd, &readfds)) {

				--n_ready;

				if (fd == sock_fd) {

					int   conn;
					pid_t pid;

					if ((conn = accept (sock_fd, (struct sockaddr *) &sunx, &addrLength)) < 0) {
						fatalError ("accept error: %s\n", strerror (errno));
					}

					pid = fork();

					if (pid < 0) {
						perror ("syslogd: fork");
						close (conn);
						continue;
					}

					if (pid > 0) {

#						define BUFSIZE 1023
						char   buf[ BUFSIZE + 1 ];
						int    n_read;

						while ((n_read = read (conn, buf, BUFSIZE )) > 0) {

							int           pri = (LOG_USER | LOG_NOTICE);
							char          line[ BUFSIZE + 1 ];
							unsigned char c;

							char *p = buf, *q = line;

							buf[ n_read - 1 ] = '\0';

							while (p && (c = *p) && q < &line[ sizeof (line) - 1 ]) {
								if (c == '<') {
								/* Parse the magic priority number. */
									pri = 0;
									while (isdigit (*(++p))) {
										pri = 10 * pri + (*p - '0');
									}
									if (pri & ~(LOG_FACMASK | LOG_PRIMASK))
										pri = (LOG_USER | LOG_NOTICE);
								} else if (c == '\n') {
									*q++ = ' ';
								} else if (iscntrl (c) && (c < 0177)) {
									*q++ = '^';
									*q++ = c ^ 0100;
								} else {
									*q++ = c;
								}
								p++;
							}
							*q = '\0';
							/* Now log it */
							logMessage (pri, line);
						}
						exit (0);
					}
					close (conn);
				}
			}
		}
	}
}

#ifdef BB_KLOGD

static void klogd_signal(int sig)
{
	ksyslog(7, NULL, 0);
	ksyslog(0, 0, 0);
	logMessage(0, "Kernel log daemon exiting.");
	exit(TRUE);
}

static void doKlogd (void) __attribute__ ((noreturn));
static void doKlogd (void)
{
	int priority = LOG_INFO;
	char log_buffer[4096];
	char *logp;

	/* Set up sig handlers */
	signal(SIGINT, klogd_signal);
	signal(SIGKILL, klogd_signal);
	signal(SIGTERM, klogd_signal);
	signal(SIGHUP, SIG_IGN);
	logMessage(0, "klogd started: "
			   "BusyBox v" BB_VER " (" BB_BT ")");

	ksyslog(1, NULL, 0);

	while (1) {
		/* Use kernel syscalls */
		memset(log_buffer, '\0', sizeof(log_buffer));
		if (ksyslog(2, log_buffer, sizeof(log_buffer)) < 0) {
			char message[80];

			if (errno == EINTR)
				continue;
			snprintf(message, 79, "klogd: Error return from sys_sycall: " \
					 "%d - %s.\n", errno, strerror(errno));
			logMessage(LOG_SYSLOG | LOG_ERR, message);
			exit(1);
		}
		logp = log_buffer;
		if (*log_buffer == '<') {
			switch (*(log_buffer + 1)) {
			case '0':
				priority = LOG_EMERG;
				break;
			case '1':
				priority = LOG_ALERT;
				break;
			case '2':
				priority = LOG_CRIT;
				break;
			case '3':
				priority = LOG_ERR;
				break;
			case '4':
				priority = LOG_WARNING;
				break;
			case '5':
				priority = LOG_NOTICE;
				break;
			case '6':
				priority = LOG_INFO;
				break;
			case '7':
			default:
				priority = LOG_DEBUG;
			}
			logp += 3;
		}
		logMessage(LOG_KERN | priority, logp);
	}

}

#endif

static void daemon_init (char **argv, char *dz, void fn (void))
{
	setsid();
	chdir ("/");
	strncpy(argv[0], dz, strlen(argv[0]));
	fn();
	exit(0);
}

extern int syslogd_main(int argc, char **argv)
{
	int pid, klogd_pid;
	int doFork = TRUE;

#ifdef BB_KLOGD
	int startKlogd = TRUE;
#endif
	int stopDoingThat = FALSE;
	char *p;
	char **argv1 = argv;

	while (--argc > 0 && **(++argv1) == '-') {
		stopDoingThat = FALSE;
		while (stopDoingThat == FALSE && *(++(*argv1))) {
			switch (**argv1) {
			case 'm':
				if (--argc == 0) {
					usage(syslogd_usage);
				}
				MarkInterval = atoi(*(++argv1)) * 60;
				break;
			case 'n':
				doFork = FALSE;
				break;
#ifdef BB_KLOGD
			case 'K':
				startKlogd = FALSE;
				break;
#endif
			case 'O':
				if (--argc == 0) {
					usage(syslogd_usage);
				}
				logFilePath = *(++argv1);
				stopDoingThat = TRUE;
				break;
			default:
				usage(syslogd_usage);
			}
		}
	}

	/* Store away localhost's name before the fork */
	gethostname(LocalHostName, sizeof(LocalHostName));
	if ((p = strchr(LocalHostName, '.'))) {
		*p++ = '\0';
	}

	umask(0);

#ifdef BB_KLOGD
	/* Start up the klogd process */
	if (startKlogd == TRUE) {
		klogd_pid = fork();
		if (klogd_pid == 0) {
			daemon_init (argv, "klogd", doKlogd);
		}
	}
#endif

	if (doFork == TRUE) {
		pid = fork();
		if (pid < 0)
			exit(pid);
		else if (pid == 0) {
			daemon_init (argv, "syslogd", doSyslogd);
		}
	} else {
		doSyslogd();
	}

	exit(TRUE);
}

/*
Local Variables
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/
