xref: /netbsd-src/external/bsd/ntp/dist/libntp/msyslog.c (revision b757af438b42b93f8c6571f026d8b8ef3eaf5fc9)
1 /*	$NetBSD: msyslog.c,v 1.1.1.2 2012/01/31 21:24:16 kardel Exp $	*/
2 
3 /*
4  * msyslog - either send a message to the terminal or print it on
5  *	     the standard output.
6  *
7  * Converted to use varargs, much better ... jks
8  */
9 
10 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13 
14 #include <sys/types.h>
15 #ifdef HAVE_UNISTD_H
16 # include <unistd.h>
17 #endif
18 #include <stdio.h>
19 
20 #include "ntp.h"
21 #include "ntp_string.h"
22 #include "ntp_syslog.h"
23 
24 #ifdef SYS_WINNT
25 # include <stdarg.h>
26 # include "..\ports\winnt\libntp\messages.h"
27 #endif
28 
29 
30 int	syslogit = 1;
31 int	msyslog_term = FALSE;	/* duplicate to stdout/err */
32 FILE *	syslog_file;
33 
34 u_int32 ntp_syslogmask =  ~(u_int32)0;	/* libntp default is all lit */
35 
36 extern	char *	progname;
37 
38 /* Declare the local functions */
39 void	addto_syslog	(int, const char *);
40 void	format_errmsg	(char *, size_t, const char *, int);
41 
42 
43 /*
44  * This routine adds the contents of a buffer to the syslog or an
45  * application-specific logfile.
46  */
47 void
48 addto_syslog(
49 	int		level,
50 	const char *	msg
51 	)
52 {
53 	static char *	prevcall_progname;
54 	static char *	prog;
55 	const char	nl[] = "\n";
56 	const char	empty[] = "";
57 	FILE *		term_file;
58 	int		log_to_term;
59 	int		log_to_file;
60 	const char *	nl_or_empty;
61 	const char *	human_time;
62 
63 	/* setup program basename static var prog if needed */
64 	if (progname != prevcall_progname) {
65 		prevcall_progname = progname;
66 		prog = strrchr(progname, DIR_SEP);
67 		if (prog != NULL)
68 			prog++;
69 		else
70 			prog = progname;
71 	}
72 
73 	log_to_term = msyslog_term;
74 	log_to_file = FALSE;
75 #if !defined(VMS) && !defined(SYS_VXWORKS)
76 	if (syslogit)
77 		syslog(level, "%s", msg);
78 	else
79 #endif
80 		if (syslog_file != NULL)
81 			log_to_file = TRUE;
82 		else
83 			log_to_term = TRUE;
84 #if DEBUG
85 	if (debug > 0)
86 		log_to_term = TRUE;
87 #endif
88 	if (!(log_to_file || log_to_term))
89 		return;
90 
91 	/* syslog() adds the timestamp, name, and pid */
92 	human_time = humanlogtime();
93 
94 	/* syslog() adds trailing \n if not present */
95 	if ('\n' != msg[strlen(msg) - 1])
96 		nl_or_empty = nl;
97 	else
98 		nl_or_empty = empty;
99 
100 	if (log_to_term) {
101 		term_file = (level <= LOG_ERR)
102 				? stderr
103 				: stdout;
104 		fprintf(term_file, "%s %s[%d]: %s%s", human_time, prog,
105 			(int)getpid(), msg, nl_or_empty);
106 		fflush(term_file);
107 	}
108 
109 	if (log_to_file) {
110 		fprintf(syslog_file, "%s %s[%d]: %s%s", human_time,
111 			prog, (int)getpid(), msg, nl_or_empty);
112 		fflush(syslog_file);
113 	}
114 }
115 
116 
117 void
118 format_errmsg(
119 	char *		nfmt,
120 	size_t		lennfmt,
121 	const char *	fmt,
122 	int		errval
123 	)
124 {
125 	char c;
126 	char *n;
127 	const char *f;
128 	size_t len;
129 	char *err;
130 
131 	n = nfmt;
132 	f = fmt;
133 	while ((c = *f++) != '\0' && n < (nfmt + lennfmt - 1)) {
134 		if (c != '%') {
135 			*n++ = c;
136 			continue;
137 		}
138 		if ((c = *f++) != 'm') {
139 			*n++ = '%';
140 			if ('\0' == c)
141 				break;
142 			*n++ = c;
143 			continue;
144 		}
145 		err = strerror(errval);
146 		len = strlen(err);
147 
148 		/* Make sure we have enough space for the error message */
149 		if ((n + len) < (nfmt + lennfmt - 1)) {
150 			memcpy(n, err, len);
151 			n += len;
152 		}
153 	}
154 	*n = '\0';
155 }
156 
157 
158 int
159 mvsnprintf(
160 	char *		buf,
161 	size_t		bufsiz,
162 	const char *	fmt,
163 	va_list		ap
164 	)
165 {
166 #ifndef VSNPRINTF_PERCENT_M
167 	char		nfmt[256];
168 #else
169 	const char *	nfmt = fmt;
170 #endif
171 	int		errval;
172 
173 	/*
174 	 * Save the error value as soon as possible
175 	 */
176 #ifdef SYS_WINNT
177 	errval = GetLastError();
178 	if (NO_ERROR == errval)
179 #endif /* SYS_WINNT */
180 		errval = errno;
181 
182 #ifndef VSNPRINTF_PERCENT_M
183 	format_errmsg(nfmt, sizeof(nfmt), fmt, errval);
184 #else
185 	errno = errval;
186 #endif
187 	return vsnprintf(buf, bufsiz, nfmt, ap);
188 }
189 
190 
191 int
192 mvfprintf(
193 	FILE *		fp,
194 	const char *	fmt,
195 	va_list		ap
196 	)
197 {
198 #ifndef VSNPRINTF_PERCENT_M
199 	char		nfmt[256];
200 #else
201 	const char *	nfmt = fmt;
202 #endif
203 	int		errval;
204 
205 	/*
206 	 * Save the error value as soon as possible
207 	 */
208 #ifdef SYS_WINNT
209 	errval = GetLastError();
210 	if (NO_ERROR == errval)
211 #endif /* SYS_WINNT */
212 		errval = errno;
213 
214 #ifndef VSNPRINTF_PERCENT_M
215 	format_errmsg(nfmt, sizeof(nfmt), fmt, errval);
216 #else
217 	errno = errval;
218 #endif
219 	return vfprintf(fp, nfmt, ap);
220 }
221 
222 
223 int
224 mfprintf(
225 	FILE *		fp,
226 	const char *	fmt,
227 	...
228 	)
229 {
230 	va_list		ap;
231 	int		rc;
232 
233 	va_start(ap, fmt);
234 	rc = mvfprintf(fp, fmt, ap);
235 	va_end(ap);
236 
237 	return rc;
238 }
239 
240 
241 int
242 mprintf(
243 	const char *	fmt,
244 	...
245 	)
246 {
247 	va_list		ap;
248 	int		rc;
249 
250 	va_start(ap, fmt);
251 	rc = mvfprintf(stdout, fmt, ap);
252 	va_end(ap);
253 
254 	return rc;
255 }
256 
257 
258 int
259 msnprintf(
260 	char *		buf,
261 	size_t		bufsiz,
262 	const char *	fmt,
263 	...
264 	)
265 {
266 	va_list	ap;
267 	size_t	rc;
268 
269 	va_start(ap, fmt);
270 	rc = mvsnprintf(buf, bufsiz, fmt, ap);
271 	va_end(ap);
272 
273 	return rc;
274 }
275 
276 
277 void
278 msyslog(
279 	int		level,
280 	const char *	fmt,
281 	...
282 	)
283 {
284 	char	buf[1024];
285 	va_list	ap;
286 
287 	va_start(ap, fmt);
288 	mvsnprintf(buf, sizeof(buf), fmt, ap);
289 	va_end(ap);
290 	addto_syslog(level, buf);
291 }
292