/*
 * dsyslog - a dumb syslog (e.g. syslog for people who have a clue)
 * Copyright (c) 2008 William Pitcock <nenolod@sacredspiral.co.uk>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
 */

#include "dsyslog.h"

#include <signal.h>

static void
dsyslog_daemonize(void)
{
	pid_t pid;

	_ENTER;

	if ((pid = fork()) != 0) {
		_INFO("Launching into background as process %d", pid);
		exit(0);
	}

	_DEBUG("child process, calling setsid to reparent");
	setsid();

#ifdef NDEBUG
	_DEBUG("closing stdin/stdout/stderr to avoid leaking messages to console");
	fclose(stdin);
	fclose(stdout);
	fclose(stderr);
#endif

	_LEAVE;
}

dsyslog_options_t options;

static GOptionEntry cmd_entries[] = {
	{"nofork", 'n', 0, G_OPTION_ARG_NONE, &options.nofork, "Do not fork into background."},
	{"version", 'v', 0, G_OPTION_ARG_NONE, &options.version, "Display program version and quit."},
	{"configtest", 'C', 0, G_OPTION_ARG_NONE, &options.configtest, "Test configuration."},
	{"config", 'c', 0, G_OPTION_ARG_STRING, &options.cfg, "Specify alternate config file."},
	{NULL}
};

static void
dsyslog_version(void)
{
	printf("dsyslog " PACKAGE_VERSION "\n");
	printf("Copyright © 2007-2009 William Pitcock, ISC license.\n");
	printf("A copy of the ISC license is included with the dsyslog source.\n");
	exit(EXIT_SUCCESS);
}

static void
dsyslog_rehash(int sig)
{
	_ENTER;

	dsyslog_log("Got signal %d; rehashing.", sig);
	dsyslog_config_rehash(options.cfg);

	_LEAVE;
}

int
main(gint argc, gchar *argv[])
{
	GMainLoop *loop;
	GOptionContext *context;
	GError *error = NULL;

	_ENTER;

	g_thread_init(NULL);

	memset(&options, '\0', sizeof(options));
	options.cfg = SYSCONFDIR "/dsyslog.conf";

	context = g_option_context_new("- a system logging daemon");
	g_option_context_add_main_entries(context, cmd_entries, PACKAGE_NAME);
	g_option_context_parse(context, &argc, &argv, &error);

	if (error)
	{
		printf("%s: %s\n"
		       "%s: Try `%s --help' for more information.\n",
		       argv[0], error->message, argv[0], argv[0]);
		_LEAVE -1;
	}

	if (options.version)
		dsyslog_version();	/* no return */

	dsyslog_config_init(options.cfg);
	if (options.configtest)
	{
		_LEAVE 0;
	}

	dsyslog_event_init();

	if (!options.nofork)
		dsyslog_daemonize();

	signal(SIGHUP, dsyslog_rehash);

	loop = g_main_loop_new(NULL, FALSE);
	g_main_loop_run(loop);
	g_main_loop_unref(loop);

	_LEAVE 0;
}
