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