154359Sroberto/*
254359Sroberto * msyslog - either send a message to the terminal or print it on
354359Sroberto *	     the standard output.
454359Sroberto *
554359Sroberto * Converted to use varargs, much better ... jks
654359Sroberto */
754359Sroberto
854359Sroberto#ifdef HAVE_CONFIG_H
954359Sroberto# include <config.h>
1054359Sroberto#endif
1154359Sroberto
1254359Sroberto#ifdef HAVE_SYS_TYPES_H
1354359Sroberto# include <sys/types.h>
1454359Sroberto#endif
1554359Sroberto#ifdef HAVE_UNISTD_H
1654359Sroberto# include <unistd.h>
1754359Sroberto#endif
1854359Sroberto
1954359Sroberto#include <stdio.h>
2054359Sroberto
2154359Sroberto#include "ntp_types.h"
2254359Sroberto#include "ntp_string.h"
2382498Sroberto#include "ntp_syslog.h"
2454359Sroberto#include "ntp_stdlib.h"
2554359Sroberto
2654359Sroberto#ifdef SYS_WINNT
27132451Sroberto# include <stdarg.h>
2854359Sroberto# include "..\ports\winnt\libntp\messages.h"
2954359Sroberto#endif
3054359Sroberto
3154359Srobertoint syslogit = 1;
3254359Sroberto
3354359SrobertoFILE *syslog_file = NULL;
3454359Sroberto
3554359Srobertou_long ntp_syslogmask =  ~ (u_long) 0;
3654359Sroberto
3754359Sroberto#ifdef SYS_WINNT
38132451Srobertostatic char separator = '\\';
39132451Sroberto#else
40132451Srobertostatic char separator = '/';
4154359Sroberto#endif /* SYS_WINNT */
4254359Srobertoextern	char *progname;
4354359Sroberto
44132451Sroberto/* Declare the local functions */
45132451Srobertovoid	addto_syslog	P((int, char *));
46132451Srobertovoid	format_errmsg   P((char *, int, const char *, int));
47132451Sroberto
48132451Sroberto
49132451Sroberto/*
50132451Sroberto * This routine adds the contents of a buffer to the log
51132451Sroberto */
52132451Srobertovoid
53132451Srobertoaddto_syslog(int level, char * buf)
5454359Sroberto{
55132451Sroberto	char *prog;
56132451Sroberto	FILE *out_file = syslog_file;
57132451Sroberto
58132451Sroberto#if !defined(VMS) && !defined (SYS_VXWORKS)
59132451Sroberto	if (syslogit)
60132451Sroberto	    syslog(level, "%s", buf);
61132451Sroberto	else
62132451Sroberto#endif /* VMS  && SYS_VXWORKS*/
63132451Sroberto	{
64132451Sroberto		out_file = syslog_file ? syslog_file: level <= LOG_ERR ? stderr : stdout;
65132451Sroberto		/* syslog() provides the timestamp, so if we're not using
66132451Sroberto		   syslog, we must provide it. */
67132451Sroberto		prog = strrchr(progname, separator);
68132451Sroberto		if (prog == NULL)
69132451Sroberto		    prog = progname;
70132451Sroberto		else
71132451Sroberto		    prog++;
72132451Sroberto		(void) fprintf(out_file, "%s ", humanlogtime ());
73132451Sroberto		(void) fprintf(out_file, "%s[%d]: %s", prog, (int)getpid(), buf);
74132451Sroberto		fflush (out_file);
75132451Sroberto	}
76132451Sroberto#if DEBUG
77132451Sroberto	if (debug && out_file != stdout && out_file != stderr)
78132451Sroberto		printf("addto_syslog: %s\n", buf);
7954359Sroberto#endif
80132451Sroberto}
81132451Srobertovoid
82132451Srobertoformat_errmsg(char *nfmt, int lennfmt, const char *fmt, int errval)
83132451Sroberto{
84132451Sroberto	register char c;
85132451Sroberto	register char *n;
8654359Sroberto	register const char *f;
87132451Sroberto
8854359Sroberto	char *err;
8954359Sroberto
9054359Sroberto	n = nfmt;
9154359Sroberto	f = fmt;
92132451Sroberto	while ((c = *f++) != '\0' && n < (nfmt+lennfmt - 2)) {
9354359Sroberto		if (c != '%') {
9454359Sroberto			*n++ = c;
9554359Sroberto			continue;
9654359Sroberto		}
9754359Sroberto		if ((c = *f++) != 'm') {
9854359Sroberto			*n++ = '%';
9954359Sroberto			*n++ = c;
10054359Sroberto			continue;
10154359Sroberto		}
10254359Sroberto		err = 0;
103132451Sroberto		err = strerror(errval);
104132451Sroberto		/* Make sure we have enough space for the error message */
105132451Sroberto		if ((n + strlen(err)) < (nfmt + lennfmt -2)) {
10654359Sroberto			strcpy(n, err);
10754359Sroberto			n += strlen(err);
10854359Sroberto		}
10954359Sroberto	}
11054359Sroberto#if !defined(VMS)
11154359Sroberto	if (!syslogit)
11254359Sroberto#endif /* VMS */
11354359Sroberto	    *n++ = '\n';
11454359Sroberto	*n = '\0';
115132451Sroberto}
11654359Sroberto
117132451Sroberto/*
118132451Sroberto * The externally called functions are defined here
119132451Sroberto * but share the internal function above to fetch
120132451Sroberto * any error message strings, This is done so that we can
121132451Sroberto * have two different functions to perform the logging
122132451Sroberto * since Windows gets it's error information from different
123132451Sroberto * places depending on whether or not it's network I/O.
124132451Sroberto * msyslog() is for general use while netsyslog() is for
125132451Sroberto * network I/O functions. They are virtually identical
126132451Sroberto * in implementation.
127132451Sroberto */
128132451Sroberto
129132451Sroberto#if defined(__STDC__) || defined(HAVE_STDARG_H)
130132451Srobertovoid msyslog(int level, const char *fmt, ...)
131132451Sroberto#else /* defined(__STDC__) || defined(HAVE_STDARG_H) */
132132451Sroberto     /*VARARGS*/
133132451Sroberto     void msyslog(va_alist)
134132451Sroberto     va_dcl
135132451Sroberto#endif /* defined(__STDC__) || defined(HAVE_STDARG_H) */
136132451Sroberto{
137132451Sroberto#if defined(__STDC__) || defined(HAVE_STDARG_H)
138132451Sroberto#else
139132451Sroberto	int level;
140132451Sroberto	const char *fmt;
141132451Sroberto#endif
142132451Sroberto	va_list ap;
143132451Sroberto	char buf[1025], nfmt[256];
144132451Sroberto
145132451Sroberto	/*
146132451Sroberto	 * Save the error value as soon as possible
147132451Sroberto	 */
148132451Sroberto#ifdef SYS_WINNT
149132451Sroberto	int errval = GetLastError();
150132451Sroberto#else
151132451Sroberto	int errval = errno;
152132451Sroberto#endif
153132451Sroberto
154132451Sroberto#if defined(__STDC__) || defined(HAVE_STDARG_H)
155132451Sroberto	va_start(ap, fmt);
156132451Sroberto#else
157132451Sroberto	va_start(ap);
158132451Sroberto
159132451Sroberto	level = va_arg(ap, int);
160132451Sroberto	fmt = va_arg(ap, char *);
161132451Sroberto#endif
162132451Sroberto	format_errmsg(nfmt, sizeof(nfmt), fmt, errval);
163132451Sroberto
164106424Sroberto	vsnprintf(buf, sizeof(buf), nfmt, ap);
165132451Sroberto	addto_syslog(level, buf);
166132451Sroberto	va_end(ap);
167132451Sroberto}
168132451Sroberto#if defined(__STDC__) || defined(HAVE_STDARG_H)
169132451Srobertovoid netsyslog(int level, const char *fmt, ...)
170132451Sroberto#else /* defined(__STDC__) || defined(HAVE_STDARG_H) */
171132451Sroberto     /*VARARGS*/
172132451Sroberto     void netsyslog(va_alist)
173132451Sroberto     va_dcl
174132451Sroberto#endif /* defined(__STDC__) || defined(HAVE_STDARG_H) */
175132451Sroberto{
176132451Sroberto#if defined(__STDC__) || defined(HAVE_STDARG_H)
17754359Sroberto#else
178132451Sroberto	int level;
179132451Sroberto	const char *fmt;
180132451Sroberto#endif
181132451Sroberto	va_list ap;
182132451Sroberto	char buf[1025], nfmt[256];
18354359Sroberto
184132451Sroberto	/*
185132451Sroberto	 * Save the error value as soon as possible
186132451Sroberto	 */
187132451Sroberto#ifdef SYS_WINNT
188132451Sroberto	int errval = WSAGetLastError();
189132451Sroberto#else
190132451Sroberto	int errval = errno;
191132451Sroberto#endif
192132451Sroberto
193132451Sroberto#if defined(__STDC__) || defined(HAVE_STDARG_H)
194132451Sroberto	va_start(ap, fmt);
195132451Sroberto#else
196132451Sroberto	va_start(ap);
197132451Sroberto
198132451Sroberto	level = va_arg(ap, int);
199132451Sroberto	fmt = va_arg(ap, char *);
200132451Sroberto#endif
201132451Sroberto	format_errmsg(nfmt, sizeof(nfmt), fmt, errval);
202132451Sroberto
203132451Sroberto	vsnprintf(buf, sizeof(buf), nfmt, ap);
204132451Sroberto	addto_syslog(level, buf);
20554359Sroberto	va_end(ap);
20654359Sroberto}
207