xref: /titanic_52/usr/src/cmd/rcap/common/utils.c (revision 18c2aff776a775d34a4c9893a4c72e0434d68e36)
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