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 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 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 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 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 * 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