1/*
2 * msyslog - either send a message to the terminal or print it on
3 *	     the standard output.
4 *
5 * Converted to use varargs, much better ... jks
6 */
7
8#ifdef HAVE_CONFIG_H
9# include <config.h>
10#endif
11
12#include <sys/types.h>
13#ifdef HAVE_UNISTD_H
14# include <unistd.h>
15#endif
16
17#include <stdio.h>
18
19#include "ntp_types.h"
20#include "ntp_string.h"
21#include "ntp_syslog.h"
22#include "ntp_stdlib.h"
23
24#ifdef SYS_WINNT
25# include <stdarg.h>
26# include "..\ports\winnt\libntp\messages.h"
27#endif
28
29int syslogit = 1;
30
31FILE *syslog_file = NULL;
32
33u_long ntp_syslogmask =  ~ (u_long) 0;
34
35#ifdef SYS_WINNT
36static char separator = '\\';
37#else
38static char separator = '/';
39#endif /* SYS_WINNT */
40extern	char *progname;
41
42/* Declare the local functions */
43void	addto_syslog	(int, char *);
44void	format_errmsg   (char *, int, const char *, int);
45
46
47/*
48 * This routine adds the contents of a buffer to the log
49 */
50void
51addto_syslog(int level, char * buf)
52{
53	char *prog;
54	FILE *out_file = syslog_file;
55
56#if !defined(VMS) && !defined (SYS_VXWORKS)
57	if (syslogit)
58	    syslog(level, "%s", buf);
59	else
60#endif /* VMS  && SYS_VXWORKS*/
61	{
62		out_file = syslog_file ? syslog_file: level <= LOG_ERR ? stderr : stdout;
63		/* syslog() provides the timestamp, so if we're not using
64		   syslog, we must provide it. */
65		prog = strrchr(progname, separator);
66		if (prog == NULL)
67		    prog = progname;
68		else
69		    prog++;
70		(void) fprintf(out_file, "%s ", humanlogtime ());
71		(void) fprintf(out_file, "%s[%d]: %s", prog, (int)getpid(), buf);
72		fflush (out_file);
73	}
74#if DEBUG
75	if (debug && out_file != stdout && out_file != stderr)
76		printf("addto_syslog: %s\n", buf);
77#endif
78}
79void
80format_errmsg(char *nfmt, int lennfmt, const char *fmt, int errval)
81{
82	register char c;
83	register char *n;
84	register const char *f;
85	size_t len;
86	char *err;
87
88	n = nfmt;
89	f = fmt;
90	while ((c = *f++) != '\0' && n < (nfmt + lennfmt - 2)) {
91		if (c != '%') {
92			*n++ = c;
93			continue;
94		}
95		if ((c = *f++) != 'm') {
96			*n++ = '%';
97			*n++ = c;
98			continue;
99		}
100		err = strerror(errval);
101		len = strlen(err);
102
103		/* Make sure we have enough space for the error message */
104		if ((n + len) < (nfmt + lennfmt - 2)) {
105			memcpy(n, err, len);
106			n += len;
107		}
108	}
109#if !defined(VMS)
110	if (!syslogit)
111#endif /* VMS */
112	    *n++ = '\n';
113	*n = '\0';
114}
115
116#if defined(__STDC__) || defined(HAVE_STDARG_H)
117void msyslog(int level, const char *fmt, ...)
118#else /* defined(__STDC__) || defined(HAVE_STDARG_H) */
119     /*VARARGS*/
120     void msyslog(va_alist)
121     va_dcl
122#endif /* defined(__STDC__) || defined(HAVE_STDARG_H) */
123{
124#if defined(__STDC__) || defined(HAVE_STDARG_H)
125#else
126	int level;
127	const char *fmt;
128#endif
129	va_list ap;
130	char buf[1025], nfmt[256];
131	int errval;
132
133	/*
134	 * Save the error value as soon as possible
135	 */
136	errval = errno;
137
138#ifdef SYS_WINNT
139	errval = GetLastError();
140	if (NO_ERROR == errval)
141		errval = errno;
142#endif /* SYS_WINNT */
143
144#if defined(__STDC__) || defined(HAVE_STDARG_H)
145	va_start(ap, fmt);
146#else
147	va_start(ap);
148
149	level = va_arg(ap, int);
150	fmt = va_arg(ap, char *);
151#endif
152	format_errmsg(nfmt, sizeof(nfmt), fmt, errval);
153
154	vsnprintf(buf, sizeof(buf), nfmt, ap);
155	addto_syslog(level, buf);
156	va_end(ap);
157}
158