From 926276659270c80de3df1bdcf8059d6a6d4b1054 Mon Sep 17 00:00:00 2001 From: fatbob313 Date: Sun, 13 Feb 2011 16:44:45 +0000 Subject: [PATCH] Add logging to file --- src/conf.c | 11 ++++++++ src/conf.h | 1 + src/log.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++----- src/log.h | 1 + src/main.c | 27 +++++++++--------- 5 files changed, 101 insertions(+), 20 deletions(-) diff --git a/src/conf.c b/src/conf.c index 3592647..9e50063 100644 --- a/src/conf.c +++ b/src/conf.c @@ -158,6 +158,17 @@ const char *getStrConf(param_t param) return ""; } break; + case LOGFILE: + setting = config_lookup(&configuration, "logfile"); + if (!setting) + return NULL; + else { + if ((strsetting = config_setting_get_string(setting)) != NULL) + return strsetting; + else + return NULL; + } + break; default: doAssert(false); break; diff --git a/src/conf.h b/src/conf.h index 6e0a666..6d7bacf 100644 --- a/src/conf.h +++ b/src/conf.h @@ -45,6 +45,7 @@ typedef enum param { DEFAULT_CHANNEL, USERNAME, GROUPNAME, + LOGFILE, } param_t; typedef struct { diff --git a/src/log.c b/src/log.c index 5d2af2b..39b9cf9 100644 --- a/src/log.c +++ b/src/log.c @@ -34,26 +34,73 @@ #include #include #include +#include +#include #include "log.h" +#include "conf.h" #define STRSIZE 254 -static bool_t termprint; +static bool_t termprint, init; +static FILE *logfile; + +static void openlogfile(const char *logfilename) +{ + int fd, flags; + logfile = fopen(logfilename, "a"); + if (logfile == NULL) { + Log_fatal("Failed to open log file '%s' for writing: %s\n", logfilename, strerror(errno)); + } + + /* XXX - Is it neccessary/appropriate that logging to file is non-blocking? + * If not, there's a risk that execution blocks, meaning that voice blocks + * as well since uMurmur is single threaded by design. OTOH, what could + * cause a block? If the disk causes blocking, it is probably br0ken. but + * the log could be on a nfs or smb share, so let's set it up as + * non-blocking and we'll see what happens. + */ + fd = fileno(logfile); + flags = fcntl(fd, F_GETFL, 0); + fcntl(fd, F_SETFL, flags | O_NONBLOCK); +} void Log_init(bool_t terminal) { - termprint = terminal; - if (!termprint) - openlog("uMurmurd", LOG_PID, LOG_DAEMON); + const char *logfilename; + + termprint = terminal; + if (termprint) + return; + + logfilename = getStrConf(LOGFILE); + if (logfilename != NULL) { + openlogfile(logfilename); + } + else openlog("uMurmurd", LOG_PID, LOG_DAEMON); + init = true; } void Log_free() { - if (!termprint) + if (termprint) + return; + else if (logfile) + fclose(logfile); + else closelog(); } +void Log_reset() +{ + const char *logfilename; + + if (logfile) { + logfilename = getStrConf(LOGFILE); + fclose(logfile); + openlogfile(logfilename); + } +} void logthis(const char *logstring, ...) { @@ -65,6 +112,8 @@ void logthis(const char *logstring, ...) va_end(argp); if (termprint) fprintf(stderr, "%s\n", buf); + else if (logfile) + fprintf(logfile, "%s\n", buf); else syslog(LOG_INFO, "%s", buf); } @@ -81,6 +130,8 @@ void Log_warn(const char *logstring, ...) va_end(argp); if (termprint) fprintf(stderr, "%s\n", buf); + else if (logfile) + fprintf(logfile, "%s\n", buf); else syslog(LOG_WARNING, "%s", buf); } @@ -97,9 +148,14 @@ void Log_info(const char *logstring, ...) va_end(argp); if (termprint) fprintf(stderr, "%s\n", buf); + else if (logfile) { + fprintf(logfile, "%s\n", buf); + fflush(logfile); + } else syslog(LOG_INFO, "%s", buf); } + void Log_info_client(client_t *client, const char *logstring, ...) { va_list argp; @@ -117,9 +173,10 @@ void Log_info_client(client_t *client, const char *logstring, ...) ntohs(client->remote_tcp.sin_port)); if (termprint) fprintf(stderr, "%s\n", buf); + else if (logfile) + fprintf(logfile, "%s\n", buf); else syslog(LOG_INFO, "%s", buf); - } #ifdef DEBUG @@ -135,6 +192,8 @@ void Log_debug(const char *logstring, ...) va_end(argp); if (termprint) fprintf(stderr, "%s\n", buf); + else if (logfile) + fprintf(logfile, "%s\n", buf); else syslog(LOG_DEBUG, "%s", buf); } @@ -151,7 +210,15 @@ void Log_fatal(const char *logstring, ...) va_end(argp); if (termprint) fprintf(stderr, "%s\n", buf); - else + else if (logfile) + fprintf(logfile, "%s\n", buf); + else { /* If logging subsystem is not initialized, fall back to syslog logging + * for fatal errors. Only config file reading that needs this currently. + */ + if (!init) + openlog("uMurmurd", LOG_PID, LOG_DAEMON); syslog(LOG_CRIT, "%s", buf); + } + exit(1); } diff --git a/src/log.h b/src/log.h index 3d74722..8bfc5b6 100644 --- a/src/log.h +++ b/src/log.h @@ -56,6 +56,7 @@ void Log_info_client(client_t *client, const char *logstring, ...); void Log_fatal(const char *logstring, ...); void Log_init(bool_t terminal); +void Log_reset(); void Log_free(); #endif diff --git a/src/main.c b/src/main.c index cef4f60..aaf1e0d 100644 --- a/src/main.c +++ b/src/main.c @@ -163,8 +163,8 @@ void signal_handler(int sig) { switch(sig) { case SIGHUP: - /* XXX - do stuff? */ - Log_info("HUP signal"); + Log_info("HUP signal received."); + Log_reset(); break; case SIGTERM: Log_info("TERM signal. Shutting down."); @@ -277,28 +277,29 @@ int main(int argc, char **argv) break; } } - - /* Logging to terminal if not daemonizing, otherwise to syslog. - * Need to initialize logging before calling Conf_init() - */ - if (!nodaemon) - Log_init(false); - else - Log_init(true); /* Initialize the config subsystem early; - * switch_user() will need to read some config variables. + * switch_user() will need to read some config variables as well as logging. */ Conf_init(conffile); - + + /* Logging to terminal if not daemonizing, otherwise to syslog or log file. + */ if (!nodaemon) { daemonize(); + Log_init(false); if (pidfile != NULL) lockfile(pidfile); switch_user(); - } + /* Reopen log file. If user switch results in access denied, we catch + * it early. + */ + Log_reset(); + } + else Log_init(true); + signal(SIGCHLD, SIG_IGN); /* ignore child */ signal(SIGTSTP, SIG_IGN); /* ignore tty signals */ signal(SIGTTOU, SIG_IGN); -- 2.30.2