/* common.c
 *
 * Functions to assist in the writing and removing of pidfiles.
 *
 * Russ Dill <Russ.Dill@asu.edu> Soptember 2001
 * Rewrited by Vladimir Oleynik <dzo@simtreas.ru> (C) 2003
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/socket.h>

#include "common.h"


static int daemonized;

#ifdef CONFIG_FEATURE_UDHCP_SYSLOG

void udhcp_logging(int level, const char *fmt, ...)
{
	int e = errno;
	va_list p;
	va_list p2;

	va_start(p, fmt);
	__va_copy(p2, p);
	if(!daemonized) {
		vprintf(fmt, p);
		putchar('\n');
		errno = e;
	}
	vsyslog(level, fmt, p2);
	va_end(p);
}

void start_log(const char *client_server)
{
	openlog(bb_applet_name, LOG_PID | LOG_CONS, LOG_LOCAL0);
	udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
}

#else

static char *syslog_level_msg[] = {
	[LOG_EMERG]   = "EMERGENCY!",
	[LOG_ALERT]   = "ALERT!",
	[LOG_CRIT]    = "critical!",
	[LOG_WARNING] = "warning",
	[LOG_ERR]     = "error",
	[LOG_INFO]    = "info",
	[LOG_DEBUG]   = "debug"
};

void udhcp_logging(int level, const char *fmt, ...)
{
	int e = errno;
	va_list p;

	va_start(p, fmt);
	if(!daemonized) {
		printf("%s, ", syslog_level_msg[level]);
		errno = e;
		vprintf(fmt, p);
		putchar('\n');
	}
	va_end(p);
}

void start_log(const char *client_server)
{
	udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
}
#endif

static const char *saved_pidfile;

static void exit_fun(void)
{
	if (saved_pidfile) unlink(saved_pidfile);
}

void background(const char *pidfile)
{
	int pid_fd = -1;

	if (pidfile) {
		pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644);
		if (pid_fd < 0) {
			LOG(LOG_ERR, "Unable to open pidfile %s: %m", pidfile);
		} else {
			lockf(pid_fd, F_LOCK, 0);
			if(!saved_pidfile)
				atexit(exit_fun);       /* set atexit one only */
			saved_pidfile = pidfile;        /* but may be rewrite */
		}
	}
	while (pid_fd >= 0 && pid_fd < 3) pid_fd = dup(pid_fd); /* don't let daemon close it */
	if (daemon(0, 0) == -1) {
		perror("fork");
		exit(1);
	}
	daemonized++;
	if (pid_fd >= 0) {
		FILE *out;

		if ((out = fdopen(pid_fd, "w")) != NULL) {
			fprintf(out, "%d\n", getpid());
			fclose(out);
		}
		lockf(pid_fd, F_UNLCK, 0);
		close(pid_fd);
	}
}

/* Signal handler */
int udhcp_signal_pipe[2];
static void signal_handler(int sig)
{
	if (send(udhcp_signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0) {
		LOG(LOG_ERR, "Could not send signal: %m");
	}
}

void udhcp_set_signal_pipe(int sig_add)
{
	socketpair(AF_UNIX, SOCK_STREAM, 0, udhcp_signal_pipe);
	signal(SIGUSR1, signal_handler);
	signal(SIGTERM, signal_handler);
	if(sig_add)
		signal(sig_add, signal_handler);
}
