updates.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 14 Jan 2002 22:23:19 +0000 (22:23 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 14 Jan 2002 22:23:19 +0000 (22:23 +0000)
CHANGES
apps/silcd/server.c
apps/silcd/serverconfig.c
apps/silcd/serverconfig.h
apps/silcd/silcd.c
doc/example_silcd.conf.in
lib/silcutil/silclog.c
lib/silcutil/silclog.h

diff --git a/CHANGES b/CHANGES
index dec28652bb2b6a1d02fd4aa49f6fca9b25049188..1ff4a821897481ec65cbaa662f2384b9b7ec9a99 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,19 @@
+Mon Jan  7 23:38:19 CET 2002  Johnny Mnemonic <johnny@themnemonic.org>
+
+       * 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:<yes/no>: and flushdelay:<seconds>:.  Affected files
+         lib/silcutil/silclog.[ch], silcd/serverconfig.[ch].
+
 Sun Jan  6 12:49:40 EET 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Do not print the warning about log files not being initialized
index 24f71ef5b8190a323a9af2dcceebd16f98485de5..e65b4eaf94d77280d26ea3c8ffdd9b9f927ab466 100644 (file)
@@ -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();
index 4e575c2eb1c6d69109b8f83f4b22529b6dc75bc3..5a8f731d0b0414570a6701e05e2026a239dd21ba 100644 (file)
 #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;
   }
index a11fc782fd8af62c5bf2e4a10f4504aa7d60f579..4bf80bd018110b8cecece8866c9116c887be309b 100644 (file)
@@ -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 */
index e740fd1bf27ddeb50dd9c6bcaadf5a611fd96110..8de6d80b88abc94eb74fe0d53b561d3c9634973e 100644 (file)
@@ -1,23 +1,23 @@
 /*
 
   silcd.c
-  
+
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  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
 #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);
index 479fdb5ee52f42aa810993f291e66728044ab9d8..d12a141b9d2574f34e2b0cb3188328a549106c41 100644 (file)
@@ -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:<path>:<max byte size>
+# Format: quicklogs:<yes/no>:
+#         flushdelay:<seconds>:
+#         infologfile:<path>:<max byte size>
 #         warninglogile:<path>:<max byte size>
 #         errorlogile:<path>:<max byte size>
 #         fatallogile:<path>:<max byte size>
 #
 [Logging]
+quicklogs:no:
+flushdelay:300:
 infologfile:@LOGSDIR@/silcd.log:50000
 warninglogfile:@LOGSDIR@/silcd_warnings.log:50000
 #errorlogfile:@LOGSDIR@/silcd_errors.log:50000
index e48bfeed58adef486d6c40e8695a437b0e066473..cf89958b1bfc783718d0185ad3a4f51f67bc6b96 100644 (file)
@@ -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;
index 222575beaa2da02e0d04328cfbb1914bb664efcc..6a476e6ecc621670e9a4ff054eef0458cd506b13 100644 (file)
@@ -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