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 2003 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 <sys/param.h> 30 #include <libintl.h> 31 #include <stdarg.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <strings.h> 35 #include <syslog.h> 36 #include <unistd.h> 37 #include <errno.h> 38 39 #include "utils.h" 40 41 static char ERRNO_FMT[] = ": %s"; 42 43 static char *pname = NULL; 44 static rcm_level_t message_priority = RCM_WARN; 45 static rcm_dst_t message_dst = RCD_STD; 46 47 static void dmesg(int level, char *msg); 48 49 /*PRINTFLIKE2*/ 50 void 51 dprintfe(int level, char *format, ...) 52 { 53 va_list alist; 54 55 va_start(alist, format); 56 vdprintfe(level, format, alist); 57 va_end(alist); 58 } 59 60 /*PRINTFLIKE2*/ 61 void 62 vdprintfe(int level, char *format, va_list alist) 63 { 64 char buf[LINELEN]; 65 char *c; 66 int err = errno; 67 68 *buf = 0; 69 70 if ((strlen(buf) + 1) < LINELEN) 71 (void) vsnprintf(buf + strlen(buf), LINELEN - 1 - strlen(buf), 72 format, alist); 73 if ((c = strchr(buf, '\n')) == NULL) { 74 if ((strlen(buf) + 1) < LINELEN) 75 (void) snprintf(buf + strlen(buf), LINELEN - 1 - 76 strlen(buf), gettext(ERRNO_FMT), strerror(err)); 77 } else 78 *c = 0; 79 80 dmesg(level, buf); 81 } 82 83 #ifdef DEBUG_MSG 84 /*PRINTFLIKE1*/ 85 void 86 debug(char *format, ...) 87 { 88 va_list alist; 89 90 if (get_message_priority() < RCM_DEBUG) 91 return; 92 93 va_start(alist, format); 94 vdprintfe(RCM_DEBUG, format, alist); 95 va_end(alist); 96 } 97 98 /*PRINTFLIKE1*/ 99 void 100 debug_high(char *format, ...) 101 { 102 va_list alist; 103 104 if (get_message_priority() < RCM_DEBUG_HIGH) 105 return; 106 107 va_start(alist, format); 108 vdprintfe(RCM_DEBUG_HIGH, format, alist); 109 va_end(alist); 110 } 111 #endif /* DEBUG_MSG */ 112 113 /*PRINTFLIKE1*/ 114 void 115 warn(char *format, ...) 116 { 117 va_list alist; 118 119 if (get_message_priority() < RCM_WARN) 120 return; 121 122 va_start(alist, format); 123 vdprintfe(RCM_WARN, format, alist); 124 va_end(alist); 125 } 126 127 /*PRINTFLIKE1*/ 128 void 129 die(char *format, ...) 130 { 131 va_list alist; 132 133 if (get_message_priority() < RCM_ERR) 134 return; 135 136 va_start(alist, format); 137 vdprintfe(RCM_ERR, format, alist); 138 va_end(alist); 139 140 exit(E_ERROR); 141 } 142 143 /*PRINTFLIKE1*/ 144 void 145 info(char *format, ...) 146 { 147 va_list alist; 148 149 if (get_message_priority() < RCM_INFO) 150 return; 151 152 va_start(alist, format); 153 vdprintfe(RCM_INFO, format, alist); 154 va_end(alist); 155 } 156 157 char * 158 setprogname(char *arg0) 159 { 160 char *p = strrchr(arg0, '/'); 161 162 if (p == NULL) 163 p = arg0; 164 else 165 p++; 166 pname = p; 167 return (pname); 168 } 169 170 /* 171 * Output a message to the controlling tty or log, depending on which is 172 * configured. The message should contain no newlines. 173 */ 174 static void 175 dmesg(int level, char *msg) 176 { 177 if (message_priority >= level) { 178 FILE *fp; 179 int syslog_severity = -1; 180 181 switch (message_dst) { 182 case RCD_STD: 183 fp = level >= RCM_DEBUG ? stderr : stdout; 184 185 if (pname != NULL) { 186 (void) fputs(pname, fp); 187 (void) fputs(": ", fp); 188 } 189 (void) fputs(msg, fp); 190 (void) fputc('\n', fp); 191 (void) fflush(fp); 192 break; 193 case RCD_SYSLOG: 194 switch (level) { 195 case RCM_ERR: 196 syslog_severity = LOG_ERR; 197 break; 198 case RCM_WARN: 199 syslog_severity = LOG_WARNING; 200 break; 201 case RCM_INFO: 202 syslog_severity = LOG_INFO; 203 break; 204 case RCM_DEBUG: 205 syslog_severity = LOG_DEBUG; 206 break; 207 } 208 if (syslog_severity >= 0) 209 (void) syslog(syslog_severity, "%s", msg); 210 break; 211 } 212 } 213 } 214 215 rcm_level_t 216 get_message_priority(void) 217 { 218 return (message_priority); 219 } 220 221 rcm_level_t 222 set_message_priority(rcm_level_t new_priority) 223 { 224 rcm_level_t old_priority = message_priority; 225 226 message_priority = new_priority; 227 return (old_priority); 228 } 229 230 rcm_dst_t 231 set_message_destination(rcm_dst_t new_dst) 232 { 233 rcm_dst_t old_dst = message_dst; 234 235 if ((message_dst = new_dst) == RCD_SYSLOG) 236 openlog(pname, LOG_ODELAY | LOG_PID, LOG_DAEMON); 237 238 return (old_dst); 239 } 240 241 void 242 hrt2ts(hrtime_t hrt, timestruc_t *tsp) 243 { 244 tsp->tv_sec = hrt / NANOSEC; 245 tsp->tv_nsec = hrt % NANOSEC; 246 } 247 248 int 249 xatoi(char *p) 250 { 251 int i; 252 char *q; 253 254 errno = 0; 255 i = (int)strtol(p, &q, 10); 256 if (errno != 0 || q == p || i < 0 || *q != '\0') { 257 warn(gettext("illegal argument -- %s\n"), p); 258 return (-1); 259 } else { 260 return (i); 261 } 262 } 263