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 41289999Sglebiusextern char const * 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{ 148289999Sglebius static char const * prevcall_progname; 149289999Sglebius static char const * 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; 334293893Sglebius int 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 360289999Sglebiusvoid 361289999Sglebiusmvsyslog( 362289999Sglebius int level, 363289999Sglebius const char * fmt, 364289999Sglebius va_list ap 365289999Sglebius ) 366289999Sglebius{ 367289999Sglebius char buf[1024]; 368289999Sglebius mvsnprintf(buf, sizeof(buf), fmt, ap); 369289999Sglebius addto_syslog(level, buf); 370289999Sglebius} 371285612Sdelphij 372289999Sglebius 373285612Sdelphij/* 374285612Sdelphij * Initialize the logging 375285612Sdelphij * 376285612Sdelphij * Called once per process, including forked children. 377285612Sdelphij */ 378285612Sdelphijvoid 379285612Sdelphijinit_logging( 380285612Sdelphij const char * name, 381285612Sdelphij u_int32 def_syslogmask, 382285612Sdelphij int is_daemon 383285612Sdelphij ) 384285612Sdelphij{ 385285612Sdelphij static int was_daemon; 386289999Sglebius char * cp; 387285612Sdelphij const char * pname; 388285612Sdelphij 389285612Sdelphij /* 390285612Sdelphij * ntpd defaults to only logging sync-category events, when 391285612Sdelphij * NLOG() is used to conditionalize. Other libntp clients 392285612Sdelphij * leave it alone so that all NLOG() conditionals will fire. 393285612Sdelphij * This presumes all bits lit in ntp_syslogmask can't be 394285612Sdelphij * configured via logconfig and all lit is thereby a sentinel 395285612Sdelphij * that ntp_syslogmask is still at its default from libntp, 396285612Sdelphij * keeping in mind this function is called in forked children 397285612Sdelphij * where it has already been called in the parent earlier. 398285612Sdelphij * Forked children pass 0 for def_syslogmask. 399285612Sdelphij */ 400285612Sdelphij if (INIT_NTP_SYSLOGMASK == ntp_syslogmask && 401285612Sdelphij 0 != def_syslogmask) 402285612Sdelphij ntp_syslogmask = def_syslogmask; /* set more via logconfig */ 403285612Sdelphij 404285612Sdelphij /* 405285612Sdelphij * Logging. This may actually work on the gizmo board. Find a name 406285612Sdelphij * to log with by using the basename 407285612Sdelphij */ 408285612Sdelphij cp = strrchr(name, DIR_SEP); 409285612Sdelphij if (NULL == cp) 410285612Sdelphij pname = name; 411285612Sdelphij else 412285612Sdelphij pname = 1 + cp; /* skip DIR_SEP */ 413285612Sdelphij progname = estrdup(pname); 414285612Sdelphij#ifdef SYS_WINNT /* strip ".exe" */ 415285612Sdelphij cp = strrchr(progname, '.'); 416285612Sdelphij if (NULL != cp && !strcasecmp(cp, ".exe")) 417289999Sglebius *cp = '\0'; 418285612Sdelphij#endif 419285612Sdelphij 420285612Sdelphij#if !defined(VMS) 421285612Sdelphij 422285612Sdelphij if (is_daemon) 423285612Sdelphij was_daemon = TRUE; 424285612Sdelphij# ifndef LOG_DAEMON 425285612Sdelphij openlog(progname, LOG_PID); 426285612Sdelphij# else /* LOG_DAEMON */ 427285612Sdelphij 428285612Sdelphij# ifndef LOG_NTP 429285612Sdelphij# define LOG_NTP LOG_DAEMON 430285612Sdelphij# endif 431285612Sdelphij openlog(progname, LOG_PID | LOG_NDELAY, (was_daemon) 432285612Sdelphij ? LOG_NTP 433285612Sdelphij : 0); 434285612Sdelphij# ifdef DEBUG 435285612Sdelphij if (debug) 436285612Sdelphij setlogmask(LOG_UPTO(LOG_DEBUG)); 437285612Sdelphij else 438285612Sdelphij# endif /* DEBUG */ 439285612Sdelphij setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */ 440285612Sdelphij# endif /* LOG_DAEMON */ 441285612Sdelphij#endif /* !VMS */ 442285612Sdelphij} 443285612Sdelphij 444285612Sdelphij 445285612Sdelphij/* 446285612Sdelphij * change_logfile() 447285612Sdelphij * 448285612Sdelphij * Used to change from syslog to a logfile, or from one logfile to 449285612Sdelphij * another, and to reopen logfiles after forking. On systems where 450285612Sdelphij * ntpd forks, deals with converting relative logfile paths to 451285612Sdelphij * absolute (root-based) because we reopen logfiles after the current 452285612Sdelphij * directory has changed. 453285612Sdelphij */ 454285612Sdelphijint 455285612Sdelphijchange_logfile( 456285612Sdelphij const char * fname, 457285612Sdelphij int leave_crumbs 458285612Sdelphij ) 459285612Sdelphij{ 460285612Sdelphij FILE * new_file; 461285612Sdelphij const char * log_fname; 462285612Sdelphij char * abs_fname; 463285612Sdelphij#if !defined(SYS_WINNT) && !defined(SYS_VXWORKS) && !defined(VMS) 464285612Sdelphij char curdir[512]; 465285612Sdelphij size_t cd_octets; 466285612Sdelphij size_t octets; 467285612Sdelphij#endif /* POSIX */ 468285612Sdelphij 469289999Sglebius REQUIRE(fname != NULL); 470285612Sdelphij log_fname = fname; 471285612Sdelphij 472285612Sdelphij /* 473285612Sdelphij * In a forked child of a parent which is logging to a file 474285612Sdelphij * instead of syslog, syslog_file will be NULL and both 475285612Sdelphij * syslog_fname and syslog_abs_fname will be non-NULL. 476285612Sdelphij * If we are given the same filename previously opened 477285612Sdelphij * and it's still open, there's nothing to do here. 478285612Sdelphij */ 479285612Sdelphij if (syslog_file != NULL && syslog_fname != NULL && 480285612Sdelphij 0 == strcmp(syslog_fname, log_fname)) 481285612Sdelphij return 0; 482285612Sdelphij 483285612Sdelphij if (0 == strcmp(log_fname, "stderr")) { 484285612Sdelphij new_file = stderr; 485285612Sdelphij abs_fname = estrdup(log_fname); 486285612Sdelphij } else if (0 == strcmp(log_fname, "stdout")) { 487285612Sdelphij new_file = stdout; 488285612Sdelphij abs_fname = estrdup(log_fname); 489285612Sdelphij } else { 490285612Sdelphij if (syslog_fname != NULL && 491285612Sdelphij 0 == strcmp(log_fname, syslog_fname)) 492285612Sdelphij log_fname = syslog_abs_fname; 493285612Sdelphij#if !defined(SYS_WINNT) && !defined(SYS_VXWORKS) && !defined(VMS) 494285612Sdelphij if (log_fname != syslog_abs_fname && 495285612Sdelphij DIR_SEP != log_fname[0] && 496285612Sdelphij 0 != strcmp(log_fname, "stderr") && 497285612Sdelphij 0 != strcmp(log_fname, "stdout") && 498285612Sdelphij NULL != getcwd(curdir, sizeof(curdir))) { 499285612Sdelphij cd_octets = strlen(curdir); 500285612Sdelphij /* trim any trailing '/' */ 501285612Sdelphij if (cd_octets > 1 && 502285612Sdelphij DIR_SEP == curdir[cd_octets - 1]) 503285612Sdelphij cd_octets--; 504285612Sdelphij octets = cd_octets; 505285612Sdelphij octets += 1; /* separator '/' */ 506285612Sdelphij octets += strlen(log_fname); 507285612Sdelphij octets += 1; /* NUL terminator */ 508285612Sdelphij abs_fname = emalloc(octets); 509285612Sdelphij snprintf(abs_fname, octets, "%.*s%c%s", 510285612Sdelphij (int)cd_octets, curdir, DIR_SEP, 511285612Sdelphij log_fname); 512285612Sdelphij } else 513285612Sdelphij#endif 514285612Sdelphij abs_fname = estrdup(log_fname); 515285612Sdelphij TRACE(1, ("attempting to open log %s\n", abs_fname)); 516285612Sdelphij new_file = fopen(abs_fname, "a"); 517285612Sdelphij } 518285612Sdelphij 519285612Sdelphij if (NULL == new_file) { 520285612Sdelphij free(abs_fname); 521285612Sdelphij return -1; 522285612Sdelphij } 523285612Sdelphij 524285612Sdelphij /* leave a pointer in the old log */ 525285612Sdelphij if (leave_crumbs && (syslogit || log_fname != syslog_abs_fname)) 526285612Sdelphij msyslog(LOG_NOTICE, "switching logging to file %s", 527285612Sdelphij abs_fname); 528285612Sdelphij 529285612Sdelphij if (syslog_file != NULL && 530285612Sdelphij syslog_file != stderr && syslog_file != stdout && 531285612Sdelphij fileno(syslog_file) != fileno(new_file)) 532285612Sdelphij fclose(syslog_file); 533285612Sdelphij syslog_file = new_file; 534285612Sdelphij if (log_fname == syslog_abs_fname) { 535285612Sdelphij free(abs_fname); 536285612Sdelphij } else { 537285612Sdelphij if (syslog_abs_fname != NULL && 538285612Sdelphij syslog_abs_fname != syslog_fname) 539285612Sdelphij free(syslog_abs_fname); 540285612Sdelphij if (syslog_fname != NULL) 541285612Sdelphij free(syslog_fname); 542285612Sdelphij syslog_fname = estrdup(log_fname); 543285612Sdelphij syslog_abs_fname = abs_fname; 544285612Sdelphij } 545285612Sdelphij syslogit = FALSE; 546285612Sdelphij 547285612Sdelphij return 0; 548285612Sdelphij} 549285612Sdelphij 550285612Sdelphij 551285612Sdelphij/* 552285612Sdelphij * setup_logfile() 553285612Sdelphij * 554285612Sdelphij * Redirect logging to a file if requested with -l/--logfile or via 555285612Sdelphij * ntp.conf logfile directive. 556285612Sdelphij * 557285612Sdelphij * This routine is invoked three different times in the sequence of a 558285612Sdelphij * typical daemon ntpd with DNS lookups to do. First it is invoked in 559285612Sdelphij * the original ntpd process, then again in the daemon after closing 560285612Sdelphij * all descriptors. In both of those cases, ntp.conf has not been 561285612Sdelphij * processed, so only -l/--logfile will trigger logfile redirection in 562285612Sdelphij * those invocations. Finally, if DNS names are resolved, the worker 563285612Sdelphij * child invokes this routine after its fork and close of all 564285612Sdelphij * descriptors. In this case, ntp.conf has been processed and any 565285612Sdelphij * "logfile" directive needs to be honored in the child as well. 566285612Sdelphij */ 567285612Sdelphijvoid 568285612Sdelphijsetup_logfile( 569285612Sdelphij const char * name 570285612Sdelphij ) 571285612Sdelphij{ 572285612Sdelphij if (NULL == syslog_fname && NULL != name) { 573285612Sdelphij if (-1 == change_logfile(name, TRUE)) 574285612Sdelphij msyslog(LOG_ERR, "Cannot open log file %s, %m", 575285612Sdelphij name); 576285612Sdelphij return ; 577285612Sdelphij } 578285612Sdelphij if (NULL == syslog_fname) 579285612Sdelphij return; 580285612Sdelphij 581285612Sdelphij if (-1 == change_logfile(syslog_fname, FALSE)) 582285612Sdelphij msyslog(LOG_ERR, "Cannot reopen log file %s, %m", 583285612Sdelphij syslog_fname); 584285612Sdelphij} 585