From d8414257c2a60e775002e7550feeaa63c17e6f62 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 14 Jan 2002 22:23:19 +0000 Subject: [PATCH] updates. --- CHANGES | 16 +++++++++++ apps/silcd/server.c | 1 + apps/silcd/serverconfig.c | 50 +++++++++++++++++++++++---------- apps/silcd/serverconfig.h | 2 ++ apps/silcd/silcd.c | 58 +++++++++++++++++++++++++++++---------- doc/example_silcd.conf.in | 8 +++++- lib/silcutil/silclog.c | 49 +++++++++++++++++++++------------ lib/silcutil/silclog.h | 17 ++++++++++++ 8 files changed, 153 insertions(+), 48 deletions(-) diff --git a/CHANGES b/CHANGES index dec28652..1ff4a821 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,19 @@ +Mon Jan 7 23:38:19 CET 2002 Johnny Mnemonic + + * Simple handling of TERM and HUP signals. Also added some log + flushing call around. Affected file is + silcd/silcd.c. + + * Fixed small bugs in silclog.c. Now buffering output will take + effect after 10 seconds since startup: This will ensure that + no important startup messages are lost. Also output redirection + will preserve original format ([Date] [Type] message). + Affected file is lib/silcutil/silclog.c. + + * Added two options to the config file, in the logging section: + quicklogs:: and flushdelay::. Affected files + lib/silcutil/silclog.[ch], silcd/serverconfig.[ch]. + Sun Jan 6 12:49:40 EET 2002 Pekka Riikonen * Do not print the warning about log files not being initialized diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 24f71ef5..e65b4eaf 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -504,6 +504,7 @@ void silc_server_stop(SilcServer server) if (server->schedule) { silc_schedule_stop(server->schedule); silc_schedule_uninit(server->schedule); + server->schedule = NULL; } silc_server_protocols_unregister(); diff --git a/apps/silcd/serverconfig.c b/apps/silcd/serverconfig.c index 4e575c2e..5a8f731d 100644 --- a/apps/silcd/serverconfig.c +++ b/apps/silcd/serverconfig.c @@ -23,25 +23,25 @@ #include "server_internal.h" SilcServerConfigSection silc_server_config_sections[] = { - { "[Cipher]", + { "[Cipher]", SILC_CONFIG_SERVER_SECTION_TYPE_CIPHER, 4 }, - { "[PKCS]", + { "[PKCS]", SILC_CONFIG_SERVER_SECTION_TYPE_PKCS, 1 }, - { "[Hash]", + { "[Hash]", SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION, 4 }, - { "[hmac]", + { "[hmac]", SILC_CONFIG_SERVER_SECTION_TYPE_HMAC, 3 }, - { "[ServerKeys]", + { "[ServerKeys]", SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_KEYS, 2 }, - { "[ServerInfo]", + { "[ServerInfo]", SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO, 4 }, - { "[AdminInfo]", + { "[AdminInfo]", SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO, 4 }, - { "[ListenPort]", + { "[ListenPort]", SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT, 3 }, - { "[Identity]", + { "[Identity]", SILC_CONFIG_SERVER_SECTION_TYPE_IDENTITY, 2 }, - { "[Logging]", + { "[Logging]", SILC_CONFIG_SERVER_SECTION_TYPE_LOGGING, 3 }, { "[ConnectionClass]", SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS, 4 }, @@ -147,7 +147,7 @@ int silc_server_config_parse(SilcServerConfig config, SilcBuffer buffer, begin = 0; linenum = 0; - while((begin = silc_gets(line, sizeof(line), + while((begin = silc_gets(line, sizeof(line), buffer->data, buffer->len, begin)) != EOF) { cp = line; linenum++; @@ -653,14 +653,16 @@ int silc_server_config_parse_lines(SilcServerConfig config, if (ret < 0) break; if (ret == 0) { - fprintf(stderr, "%s:%d: Log file section not defined\n", + fprintf(stderr, "%s:%d: Log file section not defined\n", config->filename, pc->linenum); break; } if (strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_INFO) && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_WARNING) && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_ERROR) - && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_FATAL)) { + && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_FATAL) + && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LO_QUICK) + && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LO_FDELAY)) { fprintf(stderr, "%s:%d: Unknown log file section '%s'\n", config->filename, pc->linenum, config->logging->logtype); break; @@ -1208,9 +1210,9 @@ int silc_server_config_check_sections(uint32 checkmask) return FALSE; } - if (!(checkmask + if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION))) { - + return FALSE; } @@ -1221,11 +1223,13 @@ int silc_server_config_check_sections(uint32 checkmask) void silc_server_config_setlogfiles(SilcServerConfig config, SilcSchedule sked) { + long tmp; SilcServerConfigSectionLogging *log; SILC_LOG_DEBUG(("Setting configured log file names")); log = config->logging; while (log) { + /* Logging Files */ if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO)) silc_log_set_file(SILC_LOG_INFO, log->filename, log->maxsize, sked); if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING)) @@ -1234,6 +1238,22 @@ void silc_server_config_setlogfiles(SilcServerConfig config, SilcSchedule sked) silc_log_set_file(SILC_LOG_ERROR, log->filename, log->maxsize, sked); if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL)) silc_log_set_file(SILC_LOG_FATAL, log->filename, log->maxsize, sked); + /* Logging Options */ + if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LO_QUICK)) { + if (!strcasecmp(log->filename, "yes") || + !strcasecmp(log->filename, "on")) + silc_log_quick = TRUE; + } + if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LO_FDELAY)) { + tmp = atol(log->filename); + if (tmp > 0) + silc_log_flushdelay = tmp; + else { + fprintf(stderr, "config: invalid flushdelay value, use quicklogs if " + "you want real-time logging.\n"); + exit(1); + } + } log = log->next; } diff --git a/apps/silcd/serverconfig.h b/apps/silcd/serverconfig.h index a11fc782..4bf80bd0 100644 --- a/apps/silcd/serverconfig.h +++ b/apps/silcd/serverconfig.h @@ -83,6 +83,8 @@ typedef struct SilcServerConfigSectionLoggingStruct { #define SILC_CONFIG_SERVER_LF_WARNING "warninglogfile" #define SILC_CONFIG_SERVER_LF_ERROR "errorlogfile" #define SILC_CONFIG_SERVER_LF_FATAL "fatallogfile" +#define SILC_CONFIG_SERVER_LO_QUICK "quicklogs" +#define SILC_CONFIG_SERVER_LO_FDELAY "flushdelay" } SilcServerConfigSectionLogging; /* Holds all configured connection classes */ diff --git a/apps/silcd/silcd.c b/apps/silcd/silcd.c index e740fd1b..8de6d80b 100644 --- a/apps/silcd/silcd.c +++ b/apps/silcd/silcd.c @@ -1,23 +1,23 @@ /* silcd.c - + Author: Pekka Riikonen - Copyright (C) 1997 - 2001 Pekka Riikonen + Copyright (C) 1997 - 2002 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -/* +/* * Created: Wed Mar 19 00:17:12 1997 * * This is the main program for the SILC daemon. This parses command @@ -29,16 +29,19 @@ #include "server_internal.h" #include "version.h" +/* For now, we'll have this one server context global for this module. */ +static SilcServer silcd; + static void silc_usage(); static char *silc_server_create_identifier(); -static int +static int silc_server_create_key_pair(char *pkcs_name, int bits, char *path, - char *identifier, + char *identifier, SilcPublicKey *ret_pub_key, SilcPrivateKey *ret_prv_key); /* Long command line options */ -static struct option long_opts[] = +static struct option long_opts[] = { { "config-file", 1, NULL, 'f' }, { "debug", 1, NULL, 'd' }, @@ -124,19 +127,39 @@ static void silc_checkpid(SilcServer silcd) } } +static void got_hup(int z) +{ + /* First, reset all log files (they might have been deleted) */ + silc_log_reset_all(); + silc_log_flush_all(); +} + +static void stop_server(int z) +{ + SILC_LOG_DEBUG(("Start")); + + /* Flush log files */ + silc_log_flush_all(); + + /* Gracefully stop the server */ + /* silc_server_stop(silcd); */ + /* XXX do this for now since doing graceful exit now can remove + the scheduler underneath the server too early and crash it. */ + exit(0); +} + int main(int argc, char **argv) { int ret, opt, option_index; char *config_file = NULL; bool foreground = FALSE; - SilcServer silcd; struct sigaction sa; /* Parse command line arguments */ if (argc > 1) { while ((opt = getopt_long(argc, argv, "cf:d:hFVC:", long_opts, &option_index)) != EOF) { - switch(opt) + switch(opt) { case 'h': silc_usage(); @@ -157,7 +180,7 @@ int main(int argc, char **argv) foreground = TRUE; silc_log_quick = TRUE; #else - fprintf(stdout, + fprintf(stdout, "Run-time debugging is not enabled. To enable it recompile\n" "the server with --enable-debug configuration option.\n"); #endif @@ -235,6 +258,12 @@ int main(int argc, char **argv) sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaction(SIGPIPE, &sa, NULL); + sa.sa_handler = got_hup; + sigaction(SIGHUP, &sa, NULL); + sa.sa_handler = stop_server; + sigaction(SIGTERM, &sa, NULL); + sa.sa_handler = stop_server; + sigaction(SIGINT, &sa, NULL); /* Before running the server, fork to background. */ if (!foreground) @@ -255,11 +284,12 @@ int main(int argc, char **argv) and we will exit. */ silc_server_run(silcd); - /* Stop the server. This probably has been done already but it - doesn't hurt to do it here again. */ - silc_server_stop(silcd); + /* The server was stopped, free it now */ silc_server_free(silcd); - + + /* Flush the logging system */ + silc_log_flush_all(); + exit(0); fail: exit(1); diff --git a/doc/example_silcd.conf.in b/doc/example_silcd.conf.in index 479fdb5e..d12a141b 100644 --- a/doc/example_silcd.conf.in +++ b/doc/example_silcd.conf.in @@ -111,13 +111,19 @@ lassi.kuo.fi.ssh.com:10.2.1.6:Kuopio, Finland:706 # this is NOT recommended). # If maximum size is given, the logfile will be rotated to a logfile with # the ".old" extension added. Older logfiles are flushed. +# There are also two options, quicklogs and flushdelay. Their values +# must be enclosed in colons (:), see the format below. # -# Format: infologfile:: +# Format: quicklogs:: +# flushdelay:: +# infologfile:: # warninglogile:: # errorlogile:: # fatallogile:: # [Logging] +quicklogs:no: +flushdelay:300: infologfile:@LOGSDIR@/silcd.log:50000 warninglogfile:@LOGSDIR@/silcd_warnings.log:50000 #errorlogfile:@LOGSDIR@/silcd_errors.log:50000 diff --git a/lib/silcutil/silclog.c b/lib/silcutil/silclog.c index e48bfeed..cf89958b 100644 --- a/lib/silcutil/silclog.c +++ b/lib/silcutil/silclog.c @@ -21,8 +21,8 @@ #include "silcincludes.h" -/* default flush time (5 minutes) */ -#define SILC_LOG_TIMEOUT 300 +/* Minimum time delay for log flushing calls (in seconds) */ +#define SILC_LOG_FLUSH_MIN_DELAY 2 /* nice macro for looping through all logs -- makes the code more readable */ #define SILC_FOREACH_LOG(__x__) for (__x__ = 0; __x__ < SILC_LOG_MAX; __x__++) @@ -55,6 +55,9 @@ bool silc_log_quick = FALSE; bool silc_debug = FALSE; bool silc_debug_hexdump = FALSE; +/* Flush delay */ +long silc_log_flushdelay = 300; + /* Regular pattern matching expression for the debug output */ static char *silc_log_debug_string = NULL; @@ -68,6 +71,9 @@ static void *silc_log_hexdump_context = NULL; static bool silc_log_scheduled = FALSE; static bool silc_log_no_init = FALSE; +/* This is only needed during starting up -- don't lose any logging */ +static bool silc_log_starting = TRUE; + /* The type wrapper utility. Translates a SilcLogType id to the corresponding * logfile, or NULL if not found. */ static SilcLog silc_log_find_by_type(SilcLogType type) @@ -135,6 +141,7 @@ static bool silc_log_reset(SilcLog log) fflush(log->fp); fclose(log->fp); } + if (!log->filename) return FALSE; if (!(log->fp = fopen(log->filename, "a+"))) { SILC_LOG_WARNING(("Couldn't reset logfile %s for type \"%s\": %s", log->filename, log->typename, strerror(errno))); @@ -153,8 +160,11 @@ SILC_TASK_CALLBACK(silc_log_fflush_callback) SILC_FOREACH_LOG(u) silc_log_checksize(&silclogs[u]); } + silc_log_starting = FALSE; + if (silc_log_flushdelay < SILC_LOG_FLUSH_MIN_DELAY) + silc_log_flushdelay = SILC_LOG_FLUSH_MIN_DELAY; silc_schedule_task_add((SilcSchedule) context, 0, silc_log_fflush_callback, - context, SILC_LOG_TIMEOUT, 0, SILC_TASK_TIMEOUT, + context, silc_log_flushdelay, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); } @@ -166,6 +176,7 @@ SILC_TASK_CALLBACK(silc_log_fflush_callback) void silc_log_output(SilcLogType type, char *string) { char *typename; + FILE *fp; SilcLog log; if ((type > SILC_LOG_MAX) || !(log = silc_log_find_by_type(type))) @@ -177,25 +188,26 @@ void silc_log_output(SilcLogType type, char *string) goto end; } + /* save the original typename, because if we redirect the channel we + * keep however the original destination channel name */ + typename = log->typename; + if (!silc_log_scheduled) { if (silc_log_no_init == FALSE) { - fprintf(stderr, + fprintf(stderr, "Warning, trying to output without log files initialization, " "log output is going to stderr\n"); silc_log_no_init = TRUE; } - - fprintf(stderr, "%s\n", string); - goto end; + /* redirect output */ + fp = stderr; + log = NULL; + goto found; } - /* save the original typename, because if we redirect the channel we - * keep however the original destination channel name */ - typename = log->typename; - /* ok, now we have to find an open stream */ while (TRUE) { - if (log && log->fp) goto found; + if (log && (fp = log->fp)) goto found; if (type == 0) break; log = silc_log_find_by_type(--type); } @@ -205,10 +217,11 @@ void silc_log_output(SilcLogType type, char *string) goto end; found: - fprintf(log->fp, "[%s] [%s] %s\n", silc_get_time(), typename, string); - if (silc_log_quick) { - fflush(log->fp); - silc_log_checksize(log); + fprintf(fp, "[%s] [%s] %s\n", silc_get_time(), typename, string); + if (silc_log_quick || silc_log_starting) { + fflush(fp); + if (log) + silc_log_checksize(log); } end: @@ -270,9 +283,9 @@ bool silc_log_set_file(SilcLogType type, char *filename, uint32 maxsize, if (silc_log_scheduled) return TRUE; - /* make sure we write to the disk sometimes */ + /* add schedule hook with a short delay to make sure we'll use right delay */ silc_schedule_task_add(scheduler, 0, silc_log_fflush_callback, - (void *) scheduler, SILC_LOG_TIMEOUT, 0, + (void *) scheduler, 10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); silc_log_scheduled = TRUE; diff --git a/lib/silcutil/silclog.h b/lib/silcutil/silclog.h index 222575be..6a476e6e 100644 --- a/lib/silcutil/silclog.h +++ b/lib/silcutil/silclog.h @@ -162,6 +162,23 @@ typedef bool (*SilcLogHexdumpCb)(char *file, char *function, int line, ***/ extern bool silc_log_quick; +/****v* silcutil/SilcLogAPI/silc_log_flushdelay + * + * NAME + * + * long silc_log_flushdelay -- flushing time delay + * + * DESCRIPTION + * + * Sets the logfiles flushing delay in seconds. As for now, changing this + * value AFTER logfiles initialization won't take effect until previous + * delay time will expire; for example if you change from 300 seconds to + * 60 seconds you will have to wait up to 300 seconds for this change to + * take effect. + * + ***/ +extern long silc_log_flushdelay; + /****v* silcutil/SilcLogAPI/silc_debug * * NAME -- 2.24.0