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 #include <stdarg.h> 27 #include <errno.h> 28 #include <stdio.h> 29 #include <syslog.h> 30 #include <libintl.h> 31 #include <string.h> 32 #include <limits.h> 33 34 #include "dhcpmsg.h" 35 36 static boolean_t is_daemon = B_FALSE; 37 static boolean_t is_verbose = B_FALSE; 38 static char program[PATH_MAX] = "<unknown>"; 39 static int debug_level; 40 41 static const char *err_to_string(int); 42 static int err_to_syslog(int); 43 44 /* 45 * dhcpmsg(): logs a message to the console or to syslog 46 * 47 * input: int: the level to log the message at 48 * const char *: a printf-like format string 49 * ...: arguments to the format string 50 * output: void 51 */ 52 53 void 54 dhcpmsg(int errlevel, const char *fmt, ...) 55 { 56 va_list ap; 57 char buf[512]; 58 char *errmsg; 59 60 if ((errlevel == MSG_DEBUG2 && (debug_level < 2)) || 61 (errlevel == MSG_DEBUG && (debug_level < 1)) || 62 (errlevel == MSG_VERBOSE && !is_verbose)) 63 return; 64 65 va_start(ap, fmt); 66 67 /* 68 * either log to stderr, or log to syslog. print out unix 69 * error message if errlevel is MSG_ERR and errno is set 70 */ 71 72 if (is_daemon) { 73 (void) snprintf(buf, sizeof (buf), (errlevel == MSG_ERR && 74 errno != 0) ? "%s: %%m\n" : "%s\n", gettext(fmt)); 75 (void) vsyslog(err_to_syslog(errlevel), buf, ap); 76 } else { 77 errmsg = strerror(errno); 78 if (errmsg == NULL) 79 errmsg = dgettext(TEXT_DOMAIN, "<unknown error>"); 80 81 (void) snprintf(buf, sizeof (buf), (errlevel == MSG_ERR && 82 errno != 0) ? "%s: %s: %s: %s\n" : "%s: %s: %s\n", program, 83 dgettext(TEXT_DOMAIN, err_to_string(errlevel)), 84 gettext(fmt), errmsg); 85 86 (void) vfprintf(stderr, buf, ap); 87 } 88 89 va_end(ap); 90 } 91 92 /* 93 * dhcpmsg_init(): opens and initializes the DHCP messaging facility 94 * 95 * input: const char *: the name of the executable 96 * boolean_t: whether the executable is a daemon 97 * boolean_t: whether the executable is running "verbosely" 98 * int: the debugging level the executable is being run at 99 * output: void 100 */ 101 102 void 103 dhcpmsg_init(const char *program_name, boolean_t daemon, boolean_t verbose, 104 int level) 105 { 106 (void) strlcpy(program, program_name, sizeof (program)); 107 108 debug_level = level; 109 is_verbose = verbose; 110 111 if (daemon) { 112 is_daemon = B_TRUE; 113 (void) openlog(program, LOG_PID, LOG_DAEMON); 114 if (is_verbose) { 115 syslog(err_to_syslog(MSG_VERBOSE), "%s", 116 dgettext(TEXT_DOMAIN, "Daemon started")); 117 } 118 } 119 } 120 121 /* 122 * dhcpmsg_fini(): closes the DHCP messaging facility. 123 * 124 * input: void 125 * output: void 126 */ 127 128 void 129 dhcpmsg_fini(void) 130 { 131 if (is_daemon) { 132 if (is_verbose) { 133 syslog(err_to_syslog(MSG_VERBOSE), "%s", 134 dgettext(TEXT_DOMAIN, "Daemon terminated")); 135 } 136 closelog(); 137 } 138 } 139 140 /* 141 * err_to_syslog(): converts a dhcpmsg log level into a syslog log level 142 * 143 * input: int: the dhcpmsg log level 144 * output: int: the syslog log level 145 */ 146 147 static int 148 err_to_syslog(int errlevel) 149 { 150 switch (errlevel) { 151 152 case MSG_DEBUG: 153 case MSG_DEBUG2: 154 return (LOG_DEBUG); 155 156 case MSG_ERROR: 157 case MSG_ERR: 158 return (LOG_ERR); 159 160 case MSG_WARNING: 161 return (LOG_WARNING); 162 163 case MSG_NOTICE: 164 return (LOG_NOTICE); 165 166 case MSG_CRIT: 167 return (LOG_CRIT); 168 169 case MSG_VERBOSE: 170 case MSG_INFO: 171 return (LOG_INFO); 172 } 173 174 return (LOG_INFO); 175 } 176 177 /* 178 * err_to_string(): converts a log level into a string 179 * 180 * input: int: the log level 181 * output: const char *: the stringified log level 182 */ 183 184 static const char * 185 err_to_string(int errlevel) 186 { 187 switch (errlevel) { 188 189 case MSG_DEBUG: 190 case MSG_DEBUG2: 191 return ("debug"); 192 193 case MSG_ERR: 194 case MSG_ERROR: 195 return ("error"); 196 197 case MSG_WARNING: 198 return ("warning"); 199 200 case MSG_NOTICE: 201 return ("notice"); 202 203 case MSG_CRIT: 204 return ("CRITICAL"); 205 206 case MSG_VERBOSE: 207 case MSG_INFO: 208 return ("info"); 209 } 210 211 return ("<unknown>"); 212 } 213