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