|
Packit |
96c956 |
/*
|
|
Packit |
96c956 |
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
**********************************************************************
|
|
Packit |
96c956 |
* Copyright (C) Richard P. Curnow 1997-2003
|
|
Packit |
96c956 |
* Copyright (C) Miroslav Lichvar 2011-2014, 2018
|
|
Packit |
96c956 |
*
|
|
Packit |
96c956 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
96c956 |
* it under the terms of version 2 of the GNU General Public License as
|
|
Packit |
96c956 |
* published by the Free Software Foundation.
|
|
Packit |
96c956 |
*
|
|
Packit |
96c956 |
* This program is distributed in the hope that it will be useful, but
|
|
Packit |
96c956 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
96c956 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
96c956 |
* General Public License for more details.
|
|
Packit |
96c956 |
*
|
|
Packit |
96c956 |
* You should have received a copy of the GNU General Public License along
|
|
Packit |
96c956 |
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
Packit |
96c956 |
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit |
96c956 |
*
|
|
Packit |
96c956 |
**********************************************************************
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
=======================================================================
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
Module to handle logging of diagnostic information
|
|
Packit |
96c956 |
*/
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
#include "config.h"
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
#include "sysincl.h"
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
#include "conf.h"
|
|
Packit |
96c956 |
#include "logging.h"
|
|
Packit |
96c956 |
#include "util.h"
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* This is used by DEBUG_LOG macro */
|
|
Packit |
96c956 |
int log_debug_enabled = 0;
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* ================================================== */
|
|
Packit |
96c956 |
/* Flag indicating we have initialised */
|
|
Packit |
96c956 |
static int initialised = 0;
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
static FILE *file_log;
|
|
Packit |
96c956 |
static int system_log = 0;
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
static int parent_fd = 0;
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
#define DEBUG_LEVEL_PRINT_FUNCTION 2
|
|
Packit |
96c956 |
#define DEBUG_LEVEL_PRINT_DEBUG 2
|
|
Packit |
96c956 |
static int debug_level = 0;
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
struct LogFile {
|
|
Packit |
96c956 |
const char *name;
|
|
Packit |
96c956 |
const char *banner;
|
|
Packit |
96c956 |
FILE *file;
|
|
Packit |
96c956 |
unsigned long writes;
|
|
Packit |
96c956 |
};
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
static int n_filelogs = 0;
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* Increase this when adding a new logfile */
|
|
Packit |
96c956 |
#define MAX_FILELOGS 6
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
static struct LogFile logfiles[MAX_FILELOGS];
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* ================================================== */
|
|
Packit |
96c956 |
/* Init function */
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
void
|
|
Packit |
96c956 |
LOG_Initialise(void)
|
|
Packit |
96c956 |
{
|
|
Packit |
96c956 |
initialised = 1;
|
|
Packit |
96c956 |
file_log = stderr;
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* ================================================== */
|
|
Packit |
96c956 |
/* Fini function */
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
void
|
|
Packit |
96c956 |
LOG_Finalise(void)
|
|
Packit |
96c956 |
{
|
|
Packit |
96c956 |
if (system_log)
|
|
Packit |
96c956 |
closelog();
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
if (file_log)
|
|
Packit |
96c956 |
fclose(file_log);
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
LOG_CycleLogFiles();
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
initialised = 0;
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* ================================================== */
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
static void log_message(int fatal, LOG_Severity severity, const char *message)
|
|
Packit |
96c956 |
{
|
|
Packit |
96c956 |
if (system_log) {
|
|
Packit |
96c956 |
int priority;
|
|
Packit |
96c956 |
switch (severity) {
|
|
Packit |
96c956 |
case LOGS_DEBUG:
|
|
Packit |
96c956 |
priority = LOG_DEBUG;
|
|
Packit |
96c956 |
break;
|
|
Packit |
96c956 |
case LOGS_INFO:
|
|
Packit |
96c956 |
priority = LOG_INFO;
|
|
Packit |
96c956 |
break;
|
|
Packit |
96c956 |
case LOGS_WARN:
|
|
Packit |
96c956 |
priority = LOG_WARNING;
|
|
Packit |
96c956 |
break;
|
|
Packit |
96c956 |
case LOGS_ERR:
|
|
Packit |
96c956 |
priority = LOG_ERR;
|
|
Packit |
96c956 |
break;
|
|
Packit |
96c956 |
case LOGS_FATAL:
|
|
Packit |
96c956 |
priority = LOG_CRIT;
|
|
Packit |
96c956 |
break;
|
|
Packit |
96c956 |
default:
|
|
Packit |
96c956 |
assert(0);
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
syslog(priority, fatal ? "Fatal error : %s" : "%s", message);
|
|
Packit |
96c956 |
} else if (file_log) {
|
|
Packit |
96c956 |
fprintf(file_log, fatal ? "Fatal error : %s\n" : "%s\n", message);
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* ================================================== */
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
void LOG_Message(LOG_Severity severity,
|
|
Packit |
96c956 |
#if DEBUG > 0
|
|
Packit |
96c956 |
int line_number, const char *filename, const char *function_name,
|
|
Packit |
96c956 |
#endif
|
|
Packit |
96c956 |
const char *format, ...)
|
|
Packit |
96c956 |
{
|
|
Packit |
96c956 |
char buf[2048];
|
|
Packit |
96c956 |
va_list other_args;
|
|
Packit |
96c956 |
time_t t;
|
|
Packit |
96c956 |
struct tm *tm;
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
if (!system_log && file_log) {
|
|
Packit |
96c956 |
/* Don't clutter up syslog with timestamps and internal debugging info */
|
|
Packit |
96c956 |
time(&t);
|
|
Packit |
96c956 |
tm = gmtime(&t);
|
|
Packit |
96c956 |
if (tm) {
|
|
Packit |
96c956 |
strftime(buf, sizeof (buf), "%Y-%m-%dT%H:%M:%SZ", tm);
|
|
Packit |
96c956 |
fprintf(file_log, "%s ", buf);
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
#if DEBUG > 0
|
|
Packit |
96c956 |
if (debug_level >= DEBUG_LEVEL_PRINT_FUNCTION)
|
|
Packit |
96c956 |
fprintf(file_log, "%s:%d:(%s) ", filename, line_number, function_name);
|
|
Packit |
96c956 |
#endif
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
va_start(other_args, format);
|
|
Packit |
96c956 |
vsnprintf(buf, sizeof(buf), format, other_args);
|
|
Packit |
96c956 |
va_end(other_args);
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
switch (severity) {
|
|
Packit |
96c956 |
case LOGS_DEBUG:
|
|
Packit |
96c956 |
case LOGS_INFO:
|
|
Packit |
96c956 |
case LOGS_WARN:
|
|
Packit |
96c956 |
case LOGS_ERR:
|
|
Packit |
96c956 |
log_message(0, severity, buf);
|
|
Packit |
96c956 |
break;
|
|
Packit |
96c956 |
case LOGS_FATAL:
|
|
Packit |
96c956 |
log_message(1, severity, buf);
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* Send the message also to the foreground process if it is
|
|
Packit |
96c956 |
still running, or stderr if it is still open */
|
|
Packit |
96c956 |
if (parent_fd > 0) {
|
|
Packit |
96c956 |
if (write(parent_fd, buf, strlen(buf) + 1) < 0)
|
|
Packit |
96c956 |
; /* Not much we can do here */
|
|
Packit |
96c956 |
} else if (system_log && parent_fd == 0) {
|
|
Packit |
96c956 |
system_log = 0;
|
|
Packit |
96c956 |
log_message(1, severity, buf);
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
break;
|
|
Packit |
96c956 |
default:
|
|
Packit |
96c956 |
assert(0);
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* ================================================== */
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
void
|
|
Packit |
96c956 |
LOG_OpenFileLog(const char *log_file)
|
|
Packit |
96c956 |
{
|
|
Packit |
96c956 |
FILE *f;
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
if (log_file) {
|
|
Packit |
96c956 |
f = fopen(log_file, "a");
|
|
Packit |
96c956 |
if (!f)
|
|
Packit |
96c956 |
LOG_FATAL("Could not open log file %s", log_file);
|
|
Packit |
96c956 |
} else {
|
|
Packit |
96c956 |
f = stderr;
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* Enable line buffering */
|
|
Packit |
96c956 |
setvbuf(f, NULL, _IOLBF, BUFSIZ);
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
if (file_log && file_log != stderr)
|
|
Packit |
96c956 |
fclose(file_log);
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
file_log = f;
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* ================================================== */
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
void
|
|
Packit |
96c956 |
LOG_OpenSystemLog(void)
|
|
Packit |
96c956 |
{
|
|
Packit |
96c956 |
system_log = 1;
|
|
Packit |
96c956 |
openlog("chronyd", LOG_PID, LOG_DAEMON);
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* ================================================== */
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
void LOG_SetDebugLevel(int level)
|
|
Packit |
96c956 |
{
|
|
Packit |
96c956 |
debug_level = level;
|
|
Packit |
96c956 |
if (level >= DEBUG_LEVEL_PRINT_DEBUG) {
|
|
Packit |
96c956 |
log_debug_enabled = 1;
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* ================================================== */
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
void
|
|
Packit |
96c956 |
LOG_SetParentFd(int fd)
|
|
Packit |
96c956 |
{
|
|
Packit |
96c956 |
parent_fd = fd;
|
|
Packit |
96c956 |
if (file_log == stderr)
|
|
Packit |
96c956 |
file_log = NULL;
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* ================================================== */
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
void
|
|
Packit |
96c956 |
LOG_CloseParentFd()
|
|
Packit |
96c956 |
{
|
|
Packit |
96c956 |
if (parent_fd > 0)
|
|
Packit |
96c956 |
close(parent_fd);
|
|
Packit |
96c956 |
parent_fd = -1;
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* ================================================== */
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
LOG_FileID
|
|
Packit |
96c956 |
LOG_FileOpen(const char *name, const char *banner)
|
|
Packit |
96c956 |
{
|
|
Packit |
96c956 |
assert(n_filelogs < MAX_FILELOGS);
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
logfiles[n_filelogs].name = name;
|
|
Packit |
96c956 |
logfiles[n_filelogs].banner = banner;
|
|
Packit |
96c956 |
logfiles[n_filelogs].file = NULL;
|
|
Packit |
96c956 |
logfiles[n_filelogs].writes = 0;
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
return n_filelogs++;
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* ================================================== */
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
void
|
|
Packit |
96c956 |
LOG_FileWrite(LOG_FileID id, const char *format, ...)
|
|
Packit |
96c956 |
{
|
|
Packit |
96c956 |
va_list other_args;
|
|
Packit |
96c956 |
int banner;
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
if (id < 0 || id >= n_filelogs || !logfiles[id].name)
|
|
Packit |
96c956 |
return;
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
if (!logfiles[id].file) {
|
|
Packit |
96c956 |
char filename[512], *logdir = CNF_GetLogDir();
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
if (logdir[0] == '\0') {
|
|
Packit |
96c956 |
LOG(LOGS_WARN, "logdir not specified");
|
|
Packit |
96c956 |
logfiles[id].name = NULL;
|
|
Packit |
96c956 |
return;
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
if (snprintf(filename, sizeof(filename), "%s/%s.log",
|
|
Packit |
96c956 |
logdir, logfiles[id].name) >= sizeof (filename) ||
|
|
Packit |
96c956 |
!(logfiles[id].file = fopen(filename, "a"))) {
|
|
Packit |
96c956 |
LOG(LOGS_WARN, "Could not open log file %s", filename);
|
|
Packit |
96c956 |
logfiles[id].name = NULL;
|
|
Packit |
96c956 |
return;
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* Close on exec */
|
|
Packit |
96c956 |
UTI_FdSetCloexec(fileno(logfiles[id].file));
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
banner = CNF_GetLogBanner();
|
|
Packit |
96c956 |
if (banner && logfiles[id].writes++ % banner == 0) {
|
|
Packit |
96c956 |
char bannerline[256];
|
|
Packit |
96c956 |
int i, bannerlen;
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
bannerlen = strlen(logfiles[id].banner);
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
for (i = 0; i < bannerlen; i++)
|
|
Packit |
96c956 |
bannerline[i] = '=';
|
|
Packit |
96c956 |
bannerline[i] = '\0';
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
fprintf(logfiles[id].file, "%s\n", bannerline);
|
|
Packit |
96c956 |
fprintf(logfiles[id].file, "%s\n", logfiles[id].banner);
|
|
Packit |
96c956 |
fprintf(logfiles[id].file, "%s\n", bannerline);
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
va_start(other_args, format);
|
|
Packit |
96c956 |
vfprintf(logfiles[id].file, format, other_args);
|
|
Packit |
96c956 |
va_end(other_args);
|
|
Packit |
96c956 |
fprintf(logfiles[id].file, "\n");
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
fflush(logfiles[id].file);
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* ================================================== */
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
void
|
|
Packit |
96c956 |
LOG_CycleLogFiles(void)
|
|
Packit |
96c956 |
{
|
|
Packit |
96c956 |
LOG_FileID i;
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
for (i = 0; i < n_filelogs; i++) {
|
|
Packit |
96c956 |
if (logfiles[i].file)
|
|
Packit |
96c956 |
fclose(logfiles[i].file);
|
|
Packit |
96c956 |
logfiles[i].file = NULL;
|
|
Packit |
96c956 |
logfiles[i].writes = 0;
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
}
|
|
Packit |
96c956 |
|
|
Packit |
96c956 |
/* ================================================== */
|