2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A#include <stdarg.h>
2N/A#include <errno.h>
2N/A#include <stdio.h>
2N/A#include <syslog.h>
2N/A#include <libintl.h>
2N/A#include <string.h>
2N/A#include <limits.h>
2N/A
2N/A#include "dhcpmsg.h"
2N/A
2N/Astatic boolean_t is_daemon = B_FALSE;
2N/Astatic boolean_t is_verbose = B_FALSE;
2N/Astatic char program[PATH_MAX] = "<unknown>";
2N/Astatic int debug_level;
2N/A
2N/Astatic const char *err_to_string(int);
2N/Astatic int err_to_syslog(int);
2N/A
2N/A/*
2N/A * dhcpmsg(): logs a message to the console or to syslog
2N/A *
2N/A * input: int: the level to log the message at
2N/A * const char *: a printf-like format string
2N/A * ...: arguments to the format string
2N/A * output: void
2N/A */
2N/A
2N/Avoid
2N/Adhcpmsg(int errlevel, const char *fmt, ...)
2N/A{
2N/A va_list ap;
2N/A char buf[512];
2N/A char *errmsg;
2N/A
2N/A if ((errlevel == MSG_DEBUG2 && (debug_level < 2)) ||
2N/A (errlevel == MSG_DEBUG && (debug_level < 1)) ||
2N/A (errlevel == MSG_VERBOSE && !is_verbose))
2N/A return;
2N/A
2N/A va_start(ap, fmt);
2N/A
2N/A /*
2N/A * either log to stderr, or log to syslog. print out unix
2N/A * error message if errlevel is MSG_ERR and errno is set
2N/A */
2N/A
2N/A if (is_daemon) {
2N/A (void) snprintf(buf, sizeof (buf), (errlevel == MSG_ERR &&
2N/A errno != 0) ? "%s: %%m\n" : "%s\n", gettext(fmt));
2N/A (void) vsyslog(err_to_syslog(errlevel), buf, ap);
2N/A } else {
2N/A errmsg = strerror(errno);
2N/A if (errmsg == NULL)
2N/A errmsg = dgettext(TEXT_DOMAIN, "<unknown error>");
2N/A
2N/A (void) snprintf(buf, sizeof (buf), (errlevel == MSG_ERR &&
2N/A errno != 0) ? "%s: %s: %s: %s\n" : "%s: %s: %s\n", program,
2N/A dgettext(TEXT_DOMAIN, err_to_string(errlevel)),
2N/A gettext(fmt), errmsg);
2N/A
2N/A (void) vfprintf(stderr, buf, ap);
2N/A }
2N/A
2N/A va_end(ap);
2N/A}
2N/A
2N/A/*
2N/A * dhcpmsg_init(): opens and initializes the DHCP messaging facility
2N/A *
2N/A * input: const char *: the name of the executable
2N/A * boolean_t: whether the executable is a daemon
2N/A * boolean_t: whether the executable is running "verbosely"
2N/A * int: the debugging level the executable is being run at
2N/A * output: void
2N/A */
2N/A
2N/Avoid
2N/Adhcpmsg_init(const char *program_name, boolean_t daemon, boolean_t verbose,
2N/A int level)
2N/A{
2N/A (void) strlcpy(program, program_name, sizeof (program));
2N/A
2N/A debug_level = level;
2N/A is_verbose = verbose;
2N/A
2N/A if (daemon) {
2N/A is_daemon = B_TRUE;
2N/A (void) openlog(program, LOG_PID, LOG_DAEMON);
2N/A if (is_verbose) {
2N/A syslog(err_to_syslog(MSG_VERBOSE), "%s",
2N/A dgettext(TEXT_DOMAIN, "Daemon started"));
2N/A }
2N/A }
2N/A}
2N/A
2N/A/*
2N/A * dhcpmsg_fini(): closes the DHCP messaging facility.
2N/A *
2N/A * input: void
2N/A * output: void
2N/A */
2N/A
2N/Avoid
2N/Adhcpmsg_fini(void)
2N/A{
2N/A if (is_daemon) {
2N/A if (is_verbose) {
2N/A syslog(err_to_syslog(MSG_VERBOSE), "%s",
2N/A dgettext(TEXT_DOMAIN, "Daemon terminated"));
2N/A }
2N/A closelog();
2N/A }
2N/A}
2N/A
2N/A/*
2N/A * err_to_syslog(): converts a dhcpmsg log level into a syslog log level
2N/A *
2N/A * input: int: the dhcpmsg log level
2N/A * output: int: the syslog log level
2N/A */
2N/A
2N/Astatic int
2N/Aerr_to_syslog(int errlevel)
2N/A{
2N/A switch (errlevel) {
2N/A
2N/A case MSG_DEBUG:
2N/A case MSG_DEBUG2:
2N/A return (LOG_DEBUG);
2N/A
2N/A case MSG_ERROR:
2N/A case MSG_ERR:
2N/A return (LOG_ERR);
2N/A
2N/A case MSG_WARNING:
2N/A return (LOG_WARNING);
2N/A
2N/A case MSG_NOTICE:
2N/A return (LOG_NOTICE);
2N/A
2N/A case MSG_CRIT:
2N/A return (LOG_CRIT);
2N/A
2N/A case MSG_VERBOSE:
2N/A case MSG_INFO:
2N/A return (LOG_INFO);
2N/A }
2N/A
2N/A return (LOG_INFO);
2N/A}
2N/A
2N/A/*
2N/A * err_to_string(): converts a log level into a string
2N/A *
2N/A * input: int: the log level
2N/A * output: const char *: the stringified log level
2N/A */
2N/A
2N/Astatic const char *
2N/Aerr_to_string(int errlevel)
2N/A{
2N/A switch (errlevel) {
2N/A
2N/A case MSG_DEBUG:
2N/A case MSG_DEBUG2:
2N/A return ("debug");
2N/A
2N/A case MSG_ERR:
2N/A case MSG_ERROR:
2N/A return ("error");
2N/A
2N/A case MSG_WARNING:
2N/A return ("warning");
2N/A
2N/A case MSG_NOTICE:
2N/A return ("notice");
2N/A
2N/A case MSG_CRIT:
2N/A return ("CRITICAL");
2N/A
2N/A case MSG_VERBOSE:
2N/A case MSG_INFO:
2N/A return ("info");
2N/A }
2N/A
2N/A return ("<unknown>");
2N/A}