msyslog.c revision 285612
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 12285612Sdelphij#include <sys/types.h> 1354359Sroberto#ifdef HAVE_UNISTD_H 1454359Sroberto# include <unistd.h> 1554359Sroberto#endif 1654359Sroberto#include <stdio.h> 1754359Sroberto 1854359Sroberto#include "ntp_string.h" 19285612Sdelphij#include "ntp.h" 20285612Sdelphij#include "ntp_debug.h" 2182498Sroberto#include "ntp_syslog.h" 2254359Sroberto 2354359Sroberto#ifdef SYS_WINNT 24132451Sroberto# include <stdarg.h> 2554359Sroberto# include "..\ports\winnt\libntp\messages.h" 2654359Sroberto#endif 2754359Sroberto 2854359Sroberto 29285612Sdelphijint syslogit = TRUE; 30285612Sdelphijint msyslog_term = FALSE; /* duplicate to stdout/err */ 31285612Sdelphijint msyslog_term_pid = TRUE; 32285612Sdelphijint msyslog_include_timestamp = TRUE; 33285612SdelphijFILE * syslog_file; 34285612Sdelphijchar * syslog_fname; 35285612Sdelphijchar * syslog_abs_fname; 3654359Sroberto 37285612Sdelphij/* libntp default ntp_syslogmask is all bits lit */ 38285612Sdelphij#define INIT_NTP_SYSLOGMASK ~(u_int32)0 39285612Sdelphiju_int32 ntp_syslogmask = INIT_NTP_SYSLOGMASK; 4054359Sroberto 41285612Sdelphijextern char * progname; 4254359Sroberto 43132451Sroberto/* Declare the local functions */ 44285612Sdelphijvoid addto_syslog (int, const char *); 45285612Sdelphij#ifndef VSNPRINTF_PERCENT_M 46285612Sdelphijvoid format_errmsg (char *, size_t, const char *, int); 47132451Sroberto 48285612Sdelphij/* format_errmsg() is under #ifndef VSNPRINTF_PERCENT_M above */ 49132451Srobertovoid 50285612Sdelphijformat_errmsg( 51285612Sdelphij char * nfmt, 52285612Sdelphij size_t lennfmt, 53285612Sdelphij const char * fmt, 54285612Sdelphij int errval 55285612Sdelphij ) 5654359Sroberto{ 57285612Sdelphij char errmsg[256]; 58285612Sdelphij char c; 59285612Sdelphij char *n; 60285612Sdelphij const char *f; 61285612Sdelphij size_t len; 62132451Sroberto 6354359Sroberto n = nfmt; 6454359Sroberto f = fmt; 65285612Sdelphij while ((c = *f++) != '\0' && n < (nfmt + lennfmt - 1)) { 6654359Sroberto if (c != '%') { 6754359Sroberto *n++ = c; 6854359Sroberto continue; 6954359Sroberto } 7054359Sroberto if ((c = *f++) != 'm') { 7154359Sroberto *n++ = '%'; 72285612Sdelphij if ('\0' == c) 73285612Sdelphij break; 7454359Sroberto *n++ = c; 7554359Sroberto continue; 7654359Sroberto } 77285612Sdelphij errno_to_str(errval, errmsg, sizeof(errmsg)); 78285612Sdelphij len = strlen(errmsg); 79285612Sdelphij 80132451Sroberto /* Make sure we have enough space for the error message */ 81285612Sdelphij if ((n + len) < (nfmt + lennfmt - 1)) { 82285612Sdelphij memcpy(n, errmsg, len); 83285612Sdelphij n += len; 8454359Sroberto } 8554359Sroberto } 8654359Sroberto *n = '\0'; 87132451Sroberto} 88285612Sdelphij#endif /* VSNPRINTF_PERCENT_M */ 8954359Sroberto 90285612Sdelphij 91132451Sroberto/* 92285612Sdelphij * errno_to_str() - a thread-safe strerror() replacement. 93285612Sdelphij * Hides the varied signatures of strerror_r(). 94285612Sdelphij * For Windows, we have: 95285612Sdelphij * #define errno_to_str isc_strerror 96132451Sroberto */ 97285612Sdelphij#ifndef errno_to_str 98285612Sdelphijvoid 99285612Sdelphijerrno_to_str( 100285612Sdelphij int err, 101285612Sdelphij char * buf, 102285612Sdelphij size_t bufsiz 103285612Sdelphij ) 104285612Sdelphij{ 105285612Sdelphij# if defined(STRERROR_R_CHAR_P) || !HAVE_DECL_STRERROR_R 106285612Sdelphij char * pstatic; 107132451Sroberto 108285612Sdelphij buf[0] = '\0'; 109285612Sdelphij# ifdef STRERROR_R_CHAR_P 110285612Sdelphij pstatic = strerror_r(err, buf, bufsiz); 111285612Sdelphij# else 112285612Sdelphij pstatic = strerror(err); 113285612Sdelphij# endif 114285612Sdelphij if (NULL == pstatic && '\0' == buf[0]) 115285612Sdelphij snprintf(buf, bufsiz, "%s(%d): errno %d", 116285612Sdelphij# ifdef STRERROR_R_CHAR_P 117285612Sdelphij "strerror_r", 118285612Sdelphij# else 119285612Sdelphij "strerror", 120285612Sdelphij# endif 121285612Sdelphij err, errno); 122285612Sdelphij /* protect against believing an int return is a pointer */ 123285612Sdelphij else if (pstatic != buf && pstatic > (char *)bufsiz) 124285612Sdelphij strlcpy(buf, pstatic, bufsiz); 125285612Sdelphij# else 126285612Sdelphij int rc; 127285612Sdelphij 128285612Sdelphij rc = strerror_r(err, buf, bufsiz); 129285612Sdelphij if (rc < 0) 130285612Sdelphij snprintf(buf, bufsiz, "strerror_r(%d): errno %d", 131285612Sdelphij err, errno); 132285612Sdelphij# endif 133285612Sdelphij} 134285612Sdelphij#endif /* errno_to_str */ 135285612Sdelphij 136285612Sdelphij 137285612Sdelphij/* 138285612Sdelphij * addto_syslog() 139285612Sdelphij * This routine adds the contents of a buffer to the syslog or an 140285612Sdelphij * application-specific logfile. 141285612Sdelphij */ 142285612Sdelphijvoid 143285612Sdelphijaddto_syslog( 144285612Sdelphij int level, 145285612Sdelphij const char * msg 146285612Sdelphij ) 147132451Sroberto{ 148285612Sdelphij static char * prevcall_progname; 149285612Sdelphij static char * prog; 150285612Sdelphij const char nl[] = "\n"; 151285612Sdelphij const char empty[] = ""; 152285612Sdelphij FILE * term_file; 153285612Sdelphij int log_to_term; 154285612Sdelphij int log_to_file; 155285612Sdelphij int pid; 156285612Sdelphij const char * nl_or_empty; 157285612Sdelphij const char * human_time; 158285612Sdelphij 159285612Sdelphij /* setup program basename static var prog if needed */ 160285612Sdelphij if (progname != prevcall_progname) { 161285612Sdelphij prevcall_progname = progname; 162285612Sdelphij prog = strrchr(progname, DIR_SEP); 163285612Sdelphij if (prog != NULL) 164285612Sdelphij prog++; 165285612Sdelphij else 166285612Sdelphij prog = progname; 167285612Sdelphij } 168285612Sdelphij 169285612Sdelphij log_to_term = msyslog_term; 170285612Sdelphij log_to_file = FALSE; 171285612Sdelphij#if !defined(VMS) && !defined(SYS_VXWORKS) 172285612Sdelphij if (syslogit) 173285612Sdelphij syslog(level, "%s", msg); 174285612Sdelphij else 175285612Sdelphij#endif 176285612Sdelphij if (syslog_file != NULL) 177285612Sdelphij log_to_file = TRUE; 178285612Sdelphij else 179285612Sdelphij log_to_term = TRUE; 180285612Sdelphij#if DEBUG 181285612Sdelphij if (debug > 0) 182285612Sdelphij log_to_term = TRUE; 183285612Sdelphij#endif 184285612Sdelphij if (!(log_to_file || log_to_term)) 185285612Sdelphij return; 186285612Sdelphij 187285612Sdelphij /* syslog() adds the timestamp, name, and pid */ 188285612Sdelphij if (msyslog_include_timestamp) 189285612Sdelphij human_time = humanlogtime(); 190285612Sdelphij else /* suppress gcc pot. uninit. warning */ 191285612Sdelphij human_time = NULL; 192285612Sdelphij if (msyslog_term_pid || log_to_file) 193285612Sdelphij pid = getpid(); 194285612Sdelphij else /* suppress gcc pot. uninit. warning */ 195285612Sdelphij pid = -1; 196285612Sdelphij 197285612Sdelphij /* syslog() adds trailing \n if not present */ 198285612Sdelphij if ('\n' != msg[strlen(msg) - 1]) 199285612Sdelphij nl_or_empty = nl; 200285612Sdelphij else 201285612Sdelphij nl_or_empty = empty; 202285612Sdelphij 203285612Sdelphij if (log_to_term) { 204285612Sdelphij term_file = (level <= LOG_ERR) 205285612Sdelphij ? stderr 206285612Sdelphij : stdout; 207285612Sdelphij if (msyslog_include_timestamp) 208285612Sdelphij fprintf(term_file, "%s ", human_time); 209285612Sdelphij if (msyslog_term_pid) 210285612Sdelphij fprintf(term_file, "%s[%d]: ", prog, pid); 211285612Sdelphij fprintf(term_file, "%s%s", msg, nl_or_empty); 212285612Sdelphij fflush(term_file); 213285612Sdelphij } 214285612Sdelphij 215285612Sdelphij if (log_to_file) { 216285612Sdelphij if (msyslog_include_timestamp) 217285612Sdelphij fprintf(syslog_file, "%s ", human_time); 218285612Sdelphij fprintf(syslog_file, "%s[%d]: %s%s", prog, pid, msg, 219285612Sdelphij nl_or_empty); 220285612Sdelphij fflush(syslog_file); 221285612Sdelphij } 222285612Sdelphij} 223285612Sdelphij 224285612Sdelphij 225285612Sdelphijint 226285612Sdelphijmvsnprintf( 227285612Sdelphij char * buf, 228285612Sdelphij size_t bufsiz, 229285612Sdelphij const char * fmt, 230285612Sdelphij va_list ap 231285612Sdelphij ) 232285612Sdelphij{ 233285612Sdelphij#ifndef VSNPRINTF_PERCENT_M 234285612Sdelphij char nfmt[256]; 235132451Sroberto#else 236285612Sdelphij const char * nfmt = fmt; 237132451Sroberto#endif 238285612Sdelphij int errval; 239132451Sroberto 240132451Sroberto /* 241132451Sroberto * Save the error value as soon as possible 242132451Sroberto */ 243132451Sroberto#ifdef SYS_WINNT 244285612Sdelphij errval = GetLastError(); 245285612Sdelphij if (NO_ERROR == errval) 246285612Sdelphij#endif /* SYS_WINNT */ 247285612Sdelphij errval = errno; 248285612Sdelphij 249285612Sdelphij#ifndef VSNPRINTF_PERCENT_M 250285612Sdelphij format_errmsg(nfmt, sizeof(nfmt), fmt, errval); 251132451Sroberto#else 252285612Sdelphij errno = errval; 253132451Sroberto#endif 254285612Sdelphij return vsnprintf(buf, bufsiz, nfmt, ap); 255285612Sdelphij} 256132451Sroberto 257132451Sroberto 258285612Sdelphijint 259285612Sdelphijmvfprintf( 260285612Sdelphij FILE * fp, 261285612Sdelphij const char * fmt, 262285612Sdelphij va_list ap 263285612Sdelphij ) 264132451Sroberto{ 265285612Sdelphij#ifndef VSNPRINTF_PERCENT_M 266285612Sdelphij char nfmt[256]; 26754359Sroberto#else 268285612Sdelphij const char * nfmt = fmt; 269132451Sroberto#endif 270285612Sdelphij int errval; 27154359Sroberto 272132451Sroberto /* 273132451Sroberto * Save the error value as soon as possible 274132451Sroberto */ 275132451Sroberto#ifdef SYS_WINNT 276285612Sdelphij errval = GetLastError(); 277285612Sdelphij if (NO_ERROR == errval) 278285612Sdelphij#endif /* SYS_WINNT */ 279285612Sdelphij errval = errno; 280285612Sdelphij 281285612Sdelphij#ifndef VSNPRINTF_PERCENT_M 282285612Sdelphij format_errmsg(nfmt, sizeof(nfmt), fmt, errval); 283132451Sroberto#else 284285612Sdelphij errno = errval; 285132451Sroberto#endif 286285612Sdelphij return vfprintf(fp, nfmt, ap); 287285612Sdelphij} 288132451Sroberto 289285612Sdelphij 290285612Sdelphijint 291285612Sdelphijmfprintf( 292285612Sdelphij FILE * fp, 293285612Sdelphij const char * fmt, 294285612Sdelphij ... 295285612Sdelphij ) 296285612Sdelphij{ 297285612Sdelphij va_list ap; 298285612Sdelphij int rc; 299285612Sdelphij 300132451Sroberto va_start(ap, fmt); 301285612Sdelphij rc = mvfprintf(fp, fmt, ap); 302285612Sdelphij va_end(ap); 303132451Sroberto 304285612Sdelphij return rc; 305285612Sdelphij} 306132451Sroberto 307285612Sdelphij 308285612Sdelphijint 309285612Sdelphijmprintf( 310285612Sdelphij const char * fmt, 311285612Sdelphij ... 312285612Sdelphij ) 313285612Sdelphij{ 314285612Sdelphij va_list ap; 315285612Sdelphij int rc; 316285612Sdelphij 317285612Sdelphij va_start(ap, fmt); 318285612Sdelphij rc = mvfprintf(stdout, fmt, ap); 31954359Sroberto va_end(ap); 320285612Sdelphij 321285612Sdelphij return rc; 32254359Sroberto} 323285612Sdelphij 324285612Sdelphij 325285612Sdelphijint 326285612Sdelphijmsnprintf( 327285612Sdelphij char * buf, 328285612Sdelphij size_t bufsiz, 329285612Sdelphij const char * fmt, 330285612Sdelphij ... 331285612Sdelphij ) 332285612Sdelphij{ 333285612Sdelphij va_list ap; 334285612Sdelphij size_t rc; 335285612Sdelphij 336285612Sdelphij va_start(ap, fmt); 337285612Sdelphij rc = mvsnprintf(buf, bufsiz, fmt, ap); 338285612Sdelphij va_end(ap); 339285612Sdelphij 340285612Sdelphij return rc; 341285612Sdelphij} 342285612Sdelphij 343285612Sdelphij 344285612Sdelphijvoid 345285612Sdelphijmsyslog( 346285612Sdelphij int level, 347285612Sdelphij const char * fmt, 348285612Sdelphij ... 349285612Sdelphij ) 350285612Sdelphij{ 351285612Sdelphij char buf[1024]; 352285612Sdelphij va_list ap; 353285612Sdelphij 354285612Sdelphij va_start(ap, fmt); 355285612Sdelphij mvsnprintf(buf, sizeof(buf), fmt, ap); 356285612Sdelphij va_end(ap); 357285612Sdelphij addto_syslog(level, buf); 358285612Sdelphij} 359285612Sdelphij 360285612Sdelphij 361285612Sdelphij/* 362285612Sdelphij * Initialize the logging 363285612Sdelphij * 364285612Sdelphij * Called once per process, including forked children. 365285612Sdelphij */ 366285612Sdelphijvoid 367285612Sdelphijinit_logging( 368285612Sdelphij const char * name, 369285612Sdelphij u_int32 def_syslogmask, 370285612Sdelphij int is_daemon 371285612Sdelphij ) 372285612Sdelphij{ 373285612Sdelphij static int was_daemon; 374285612Sdelphij const char * cp; 375285612Sdelphij const char * pname; 376285612Sdelphij 377285612Sdelphij /* 378285612Sdelphij * ntpd defaults to only logging sync-category events, when 379285612Sdelphij * NLOG() is used to conditionalize. Other libntp clients 380285612Sdelphij * leave it alone so that all NLOG() conditionals will fire. 381285612Sdelphij * This presumes all bits lit in ntp_syslogmask can't be 382285612Sdelphij * configured via logconfig and all lit is thereby a sentinel 383285612Sdelphij * that ntp_syslogmask is still at its default from libntp, 384285612Sdelphij * keeping in mind this function is called in forked children 385285612Sdelphij * where it has already been called in the parent earlier. 386285612Sdelphij * Forked children pass 0 for def_syslogmask. 387285612Sdelphij */ 388285612Sdelphij if (INIT_NTP_SYSLOGMASK == ntp_syslogmask && 389285612Sdelphij 0 != def_syslogmask) 390285612Sdelphij ntp_syslogmask = def_syslogmask; /* set more via logconfig */ 391285612Sdelphij 392285612Sdelphij /* 393285612Sdelphij * Logging. This may actually work on the gizmo board. Find a name 394285612Sdelphij * to log with by using the basename 395285612Sdelphij */ 396285612Sdelphij cp = strrchr(name, DIR_SEP); 397285612Sdelphij if (NULL == cp) 398285612Sdelphij pname = name; 399285612Sdelphij else 400285612Sdelphij pname = 1 + cp; /* skip DIR_SEP */ 401285612Sdelphij progname = estrdup(pname); 402285612Sdelphij#ifdef SYS_WINNT /* strip ".exe" */ 403285612Sdelphij cp = strrchr(progname, '.'); 404285612Sdelphij if (NULL != cp && !strcasecmp(cp, ".exe")) 405285612Sdelphij progname[cp - progname] = '\0'; 406285612Sdelphij#endif 407285612Sdelphij 408285612Sdelphij#if !defined(VMS) 409285612Sdelphij 410285612Sdelphij if (is_daemon) 411285612Sdelphij was_daemon = TRUE; 412285612Sdelphij# ifndef LOG_DAEMON 413285612Sdelphij openlog(progname, LOG_PID); 414285612Sdelphij# else /* LOG_DAEMON */ 415285612Sdelphij 416285612Sdelphij# ifndef LOG_NTP 417285612Sdelphij# define LOG_NTP LOG_DAEMON 418285612Sdelphij# endif 419285612Sdelphij openlog(progname, LOG_PID | LOG_NDELAY, (was_daemon) 420285612Sdelphij ? LOG_NTP 421285612Sdelphij : 0); 422285612Sdelphij# ifdef DEBUG 423285612Sdelphij if (debug) 424285612Sdelphij setlogmask(LOG_UPTO(LOG_DEBUG)); 425285612Sdelphij else 426285612Sdelphij# endif /* DEBUG */ 427285612Sdelphij setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */ 428285612Sdelphij# endif /* LOG_DAEMON */ 429285612Sdelphij#endif /* !VMS */ 430285612Sdelphij} 431285612Sdelphij 432285612Sdelphij 433285612Sdelphij/* 434285612Sdelphij * change_logfile() 435285612Sdelphij * 436285612Sdelphij * Used to change from syslog to a logfile, or from one logfile to 437285612Sdelphij * another, and to reopen logfiles after forking. On systems where 438285612Sdelphij * ntpd forks, deals with converting relative logfile paths to 439285612Sdelphij * absolute (root-based) because we reopen logfiles after the current 440285612Sdelphij * directory has changed. 441285612Sdelphij */ 442285612Sdelphijint 443285612Sdelphijchange_logfile( 444285612Sdelphij const char * fname, 445285612Sdelphij int leave_crumbs 446285612Sdelphij ) 447285612Sdelphij{ 448285612Sdelphij FILE * new_file; 449285612Sdelphij const char * log_fname; 450285612Sdelphij char * abs_fname; 451285612Sdelphij#if !defined(SYS_WINNT) && !defined(SYS_VXWORKS) && !defined(VMS) 452285612Sdelphij char curdir[512]; 453285612Sdelphij size_t cd_octets; 454285612Sdelphij size_t octets; 455285612Sdelphij#endif /* POSIX */ 456285612Sdelphij 457285612Sdelphij NTP_REQUIRE(fname != NULL); 458285612Sdelphij log_fname = fname; 459285612Sdelphij 460285612Sdelphij /* 461285612Sdelphij * In a forked child of a parent which is logging to a file 462285612Sdelphij * instead of syslog, syslog_file will be NULL and both 463285612Sdelphij * syslog_fname and syslog_abs_fname will be non-NULL. 464285612Sdelphij * If we are given the same filename previously opened 465285612Sdelphij * and it's still open, there's nothing to do here. 466285612Sdelphij */ 467285612Sdelphij if (syslog_file != NULL && syslog_fname != NULL && 468285612Sdelphij 0 == strcmp(syslog_fname, log_fname)) 469285612Sdelphij return 0; 470285612Sdelphij 471285612Sdelphij if (0 == strcmp(log_fname, "stderr")) { 472285612Sdelphij new_file = stderr; 473285612Sdelphij abs_fname = estrdup(log_fname); 474285612Sdelphij } else if (0 == strcmp(log_fname, "stdout")) { 475285612Sdelphij new_file = stdout; 476285612Sdelphij abs_fname = estrdup(log_fname); 477285612Sdelphij } else { 478285612Sdelphij if (syslog_fname != NULL && 479285612Sdelphij 0 == strcmp(log_fname, syslog_fname)) 480285612Sdelphij log_fname = syslog_abs_fname; 481285612Sdelphij#if !defined(SYS_WINNT) && !defined(SYS_VXWORKS) && !defined(VMS) 482285612Sdelphij if (log_fname != syslog_abs_fname && 483285612Sdelphij DIR_SEP != log_fname[0] && 484285612Sdelphij 0 != strcmp(log_fname, "stderr") && 485285612Sdelphij 0 != strcmp(log_fname, "stdout") && 486285612Sdelphij NULL != getcwd(curdir, sizeof(curdir))) { 487285612Sdelphij cd_octets = strlen(curdir); 488285612Sdelphij /* trim any trailing '/' */ 489285612Sdelphij if (cd_octets > 1 && 490285612Sdelphij DIR_SEP == curdir[cd_octets - 1]) 491285612Sdelphij cd_octets--; 492285612Sdelphij octets = cd_octets; 493285612Sdelphij octets += 1; /* separator '/' */ 494285612Sdelphij octets += strlen(log_fname); 495285612Sdelphij octets += 1; /* NUL terminator */ 496285612Sdelphij abs_fname = emalloc(octets); 497285612Sdelphij snprintf(abs_fname, octets, "%.*s%c%s", 498285612Sdelphij (int)cd_octets, curdir, DIR_SEP, 499285612Sdelphij log_fname); 500285612Sdelphij } else 501285612Sdelphij#endif 502285612Sdelphij abs_fname = estrdup(log_fname); 503285612Sdelphij TRACE(1, ("attempting to open log %s\n", abs_fname)); 504285612Sdelphij new_file = fopen(abs_fname, "a"); 505285612Sdelphij } 506285612Sdelphij 507285612Sdelphij if (NULL == new_file) { 508285612Sdelphij free(abs_fname); 509285612Sdelphij return -1; 510285612Sdelphij } 511285612Sdelphij 512285612Sdelphij /* leave a pointer in the old log */ 513285612Sdelphij if (leave_crumbs && (syslogit || log_fname != syslog_abs_fname)) 514285612Sdelphij msyslog(LOG_NOTICE, "switching logging to file %s", 515285612Sdelphij abs_fname); 516285612Sdelphij 517285612Sdelphij if (syslog_file != NULL && 518285612Sdelphij syslog_file != stderr && syslog_file != stdout && 519285612Sdelphij fileno(syslog_file) != fileno(new_file)) 520285612Sdelphij fclose(syslog_file); 521285612Sdelphij syslog_file = new_file; 522285612Sdelphij if (log_fname == syslog_abs_fname) { 523285612Sdelphij free(abs_fname); 524285612Sdelphij } else { 525285612Sdelphij if (syslog_abs_fname != NULL && 526285612Sdelphij syslog_abs_fname != syslog_fname) 527285612Sdelphij free(syslog_abs_fname); 528285612Sdelphij if (syslog_fname != NULL) 529285612Sdelphij free(syslog_fname); 530285612Sdelphij syslog_fname = estrdup(log_fname); 531285612Sdelphij syslog_abs_fname = abs_fname; 532285612Sdelphij } 533285612Sdelphij syslogit = FALSE; 534285612Sdelphij 535285612Sdelphij return 0; 536285612Sdelphij} 537285612Sdelphij 538285612Sdelphij 539285612Sdelphij/* 540285612Sdelphij * setup_logfile() 541285612Sdelphij * 542285612Sdelphij * Redirect logging to a file if requested with -l/--logfile or via 543285612Sdelphij * ntp.conf logfile directive. 544285612Sdelphij * 545285612Sdelphij * This routine is invoked three different times in the sequence of a 546285612Sdelphij * typical daemon ntpd with DNS lookups to do. First it is invoked in 547285612Sdelphij * the original ntpd process, then again in the daemon after closing 548285612Sdelphij * all descriptors. In both of those cases, ntp.conf has not been 549285612Sdelphij * processed, so only -l/--logfile will trigger logfile redirection in 550285612Sdelphij * those invocations. Finally, if DNS names are resolved, the worker 551285612Sdelphij * child invokes this routine after its fork and close of all 552285612Sdelphij * descriptors. In this case, ntp.conf has been processed and any 553285612Sdelphij * "logfile" directive needs to be honored in the child as well. 554285612Sdelphij */ 555285612Sdelphijvoid 556285612Sdelphijsetup_logfile( 557285612Sdelphij const char * name 558285612Sdelphij ) 559285612Sdelphij{ 560285612Sdelphij if (NULL == syslog_fname && NULL != name) { 561285612Sdelphij if (-1 == change_logfile(name, TRUE)) 562285612Sdelphij msyslog(LOG_ERR, "Cannot open log file %s, %m", 563285612Sdelphij name); 564285612Sdelphij return ; 565285612Sdelphij } 566285612Sdelphij if (NULL == syslog_fname) 567285612Sdelphij return; 568285612Sdelphij 569285612Sdelphij if (-1 == change_logfile(syslog_fname, FALSE)) 570285612Sdelphij msyslog(LOG_ERR, "Cannot reopen log file %s, %m", 571285612Sdelphij syslog_fname); 572285612Sdelphij} 573