1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 #include <stdarg.h>
29 #include <errno.h>
30 #include <stdio.h>
31 #include <syslog.h>
32 #include <libintl.h>
33 #include <string.h>
34 #include <limits.h>
35
36 #include "dhcpmsg.h"
37
38 static boolean_t is_daemon = B_FALSE;
39 static boolean_t is_verbose = B_FALSE;
40 static char program[PATH_MAX] = "<unknown>";
41 static int debug_level;
42
43 static const char *err_to_string(int);
44 static int err_to_syslog(int);
45
46 /*
47 * dhcpmsg(): logs a message to the console or to syslog
48 *
49 * input: int: the level to log the message at
50 * const char *: a printf-like format string
51 * ...: arguments to the format string
52 * output: void
53 */
54
55 void
dhcpmsg(int errlevel,const char * fmt,...)56 dhcpmsg(int errlevel, const char *fmt, ...)
57 {
58 va_list ap;
59 char buf[512];
60 char *errmsg;
61
62 if ((errlevel == MSG_DEBUG2 && (debug_level < 2)) ||
63 (errlevel == MSG_DEBUG && (debug_level < 1)) ||
64 (errlevel == MSG_VERBOSE && !is_verbose))
65 return;
66
67 va_start(ap, fmt);
68
69 /*
70 * either log to stderr, or log to syslog. print out unix
71 * error message if errlevel is MSG_ERR and errno is set
72 */
73
74 if (is_daemon) {
75 (void) snprintf(buf, sizeof (buf), (errlevel == MSG_ERR &&
76 errno != 0) ? "%s: %%m\n" : "%s\n", gettext(fmt));
77 (void) vsyslog(err_to_syslog(errlevel), buf, ap);
78 } else {
79 errmsg = strerror(errno);
80 if (errmsg == NULL)
81 errmsg = dgettext(TEXT_DOMAIN, "<unknown error>");
82
83 (void) snprintf(buf, sizeof (buf), (errlevel == MSG_ERR &&
84 errno != 0) ? "%s: %s: %s: %s\n" : "%s: %s: %s\n", program,
85 dgettext(TEXT_DOMAIN, err_to_string(errlevel)),
86 gettext(fmt), errmsg);
87
88 (void) vfprintf(stderr, buf, ap);
89 }
90
91 va_end(ap);
92 }
93
94 /*
95 * dhcpmsg_init(): opens and initializes the DHCP messaging facility
96 *
97 * input: const char *: the name of the executable
98 * boolean_t: whether the executable is a daemon
99 * boolean_t: whether the executable is running "verbosely"
100 * int: the debugging level the executable is being run at
101 * output: void
102 */
103
104 void
dhcpmsg_init(const char * program_name,boolean_t daemon,boolean_t verbose,int level)105 dhcpmsg_init(const char *program_name, boolean_t daemon, boolean_t verbose,
106 int level)
107 {
108 (void) strlcpy(program, program_name, sizeof (program));
109
110 debug_level = level;
111 is_verbose = verbose;
112
113 if (daemon) {
114 is_daemon = B_TRUE;
115 (void) openlog(program, LOG_PID, LOG_DAEMON);
116 if (is_verbose) {
117 syslog(err_to_syslog(MSG_VERBOSE), "%s",
118 dgettext(TEXT_DOMAIN, "Daemon started"));
119 }
120 }
121 }
122
123 /*
124 * dhcpmsg_fini(): closes the DHCP messaging facility.
125 *
126 * input: void
127 * output: void
128 */
129
130 void
dhcpmsg_fini(void)131 dhcpmsg_fini(void)
132 {
133 if (is_daemon) {
134 if (is_verbose) {
135 syslog(err_to_syslog(MSG_VERBOSE), "%s",
136 dgettext(TEXT_DOMAIN, "Daemon terminated"));
137 }
138 closelog();
139 }
140 }
141
142 /*
143 * err_to_syslog(): converts a dhcpmsg log level into a syslog log level
144 *
145 * input: int: the dhcpmsg log level
146 * output: int: the syslog log level
147 */
148
149 static int
err_to_syslog(int errlevel)150 err_to_syslog(int errlevel)
151 {
152 switch (errlevel) {
153
154 case MSG_DEBUG:
155 case MSG_DEBUG2:
156 return (LOG_DEBUG);
157
158 case MSG_ERROR:
159 case MSG_ERR:
160 return (LOG_ERR);
161
162 case MSG_WARNING:
163 return (LOG_WARNING);
164
165 case MSG_NOTICE:
166 return (LOG_NOTICE);
167
168 case MSG_CRIT:
169 return (LOG_CRIT);
170
171 case MSG_VERBOSE:
172 case MSG_INFO:
173 return (LOG_INFO);
174 }
175
176 return (LOG_INFO);
177 }
178
179 /*
180 * err_to_string(): converts a log level into a string
181 *
182 * input: int: the log level
183 * output: const char *: the stringified log level
184 */
185
186 static const char *
err_to_string(int errlevel)187 err_to_string(int errlevel)
188 {
189 switch (errlevel) {
190
191 case MSG_DEBUG:
192 case MSG_DEBUG2:
193 return ("debug");
194
195 case MSG_ERR:
196 case MSG_ERROR:
197 return ("error");
198
199 case MSG_WARNING:
200 return ("warning");
201
202 case MSG_NOTICE:
203 return ("notice");
204
205 case MSG_CRIT:
206 return ("CRITICAL");
207
208 case MSG_VERBOSE:
209 case MSG_INFO:
210 return ("info");
211 }
212
213 return ("<unknown>");
214 }
215