Rewritten SILC Log API.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 10 May 2005 13:22:51 +0000 (13:22 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 10 May 2005 13:22:51 +0000 (13:22 +0000)
12 files changed:
CHANGES
apps/irssi/src/silc/core/silc-core.c
apps/silcd/server.c
apps/silcd/serverconfig.c
apps/silcd/silcd.c
apps/silcstress/silcstress.c
lib/doc/silcclient_using.html
lib/silcutil/Makefile.ad
lib/silcutil/silclog.c
lib/silcutil/silclog.h
lib/silcutil/silclog_i.h [new file with mode: 0644]
win32/libsilc/libsilc.def

diff --git a/CHANGES b/CHANGES
index 3bc0fa283473fcfc01a6895d696928b037382031..9b437dcf48958bb73b7c8f4d567e25670e44586f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+Tue May 10 15:11:53 EEST 2005  Pekka Riikonen <priikone@silcnet.org>
+
+       * Rewritten SILC Log API.  Affected files lib/silcutil/silclog.[ch].
+
 Mon May  9 12:00:08 EEST 2005  Pekka Riikonen <priikone@silcnet.org>
 
        * Fixed channel public key list saving on JOIN command reply
index e61e1c1d023ae4ce8826bb35c19565a511685d52..47c927b4baffa668ba048daced079a36ab00742e 100644 (file)
@@ -4,13 +4,13 @@
 
   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
 
-  Copyright (C) 2001 Pekka Riikonen
+  Copyright (C) 2001, 2005 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
@@ -48,8 +48,6 @@ static int idletag = -1;
 
 SilcClient silc_client = NULL;
 extern SilcClientOperations ops;
-extern bool silc_debug;
-extern bool silc_debug_hexdump;
 
 void silc_expandos_init(void);
 void silc_expandos_deinit(void);
@@ -94,8 +92,8 @@ static void destroy_server_connect(SERVER_CONNECT_REC *conn)
 static void silc_init_userinfo(void)
 {
   const char *set, *nick, *user_name;
-  char *str;   
-        
+  char *str;
+
   /* check if nick/username/realname wasn't read from setup.. */
   set = settings_get_str("real_name");
   if (set == NULL || *set == '\0') {
@@ -105,7 +103,7 @@ static void silc_init_userinfo(void)
     settings_set_str("real_name",
                     str != NULL ? str : silc_get_real_name());
   }
+
   /* username */
   user_name = settings_get_str("user_name");
   if (user_name == NULL || *user_name == '\0') {
@@ -125,10 +123,10 @@ static void silc_init_userinfo(void)
     if (!str)
       str = g_getenv("IRCNICK");
     settings_set_str("nick", str != NULL ? str : user_name);
-    
+
     nick = settings_get_str("nick");
   }
-                
+
   /* alternate nick */
   set = settings_get_str("alternate_nick");
   if (set == NULL || *set == '\0') {
@@ -165,14 +163,15 @@ static void sig_setup_changed(void)
   bool debug = settings_get_bool("debug");
   if (debug) {
     const char *debug_string = settings_get_str("debug_string");
-    i_debug = silc_debug = TRUE;
+    i_debug = TRUE;
+    silc_log_debug(TRUE);
     if (strlen(debug_string))
       silc_log_set_debug_string(debug_string);
     silc_log_set_debug_callbacks(silc_irssi_debug_print, NULL, NULL, NULL);
     return;
   }
   if (i_debug)
-    silc_debug = FALSE;
+    silc_log_debug(FALSE);
 #endif
 }
 
@@ -180,7 +179,7 @@ static void sig_setup_changed(void)
 
 static bool silc_log_misc(SilcLogType type, char *message, void *context)
 {
-  printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%s: %s", 
+  printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%s: %s",
            (type == SILC_LOG_INFO ? "[Info]" :
             type == SILC_LOG_WARNING ? "[Warning]" : "[Error]"), message);
   return TRUE;
@@ -202,7 +201,7 @@ static void silc_register_cipher(SilcClient client, const char *cipher)
        silc_cipher_register(&(silc_default_ciphers[i]));
        break;
       }
-    
+
     if (!silc_cipher_is_supported(cipher)) {
       SILC_LOG_ERROR(("Unknown cipher `%s'", cipher));
       exit(1);
@@ -223,7 +222,7 @@ static void silc_register_hash(SilcClient client, const char *hash)
        silc_hash_register(&(silc_default_hash[i]));
        break;
       }
-    
+
     if (!silc_hash_is_supported(hash)) {
       SILC_LOG_ERROR(("Unknown hash function `%s'", hash));
       exit(1);
@@ -244,7 +243,7 @@ static void silc_register_hmac(SilcClient client, const char *hmac)
        silc_hmac_register(&(silc_default_hmacs[i]));
        break;
       }
-    
+
     if (!silc_hmac_is_supported(hmac)) {
       SILC_LOG_ERROR(("Unknown HMAC `%s'", hmac));
       exit(1);
@@ -257,18 +256,18 @@ static void silc_register_hmac(SilcClient client, const char *hmac)
 
 /* Finalize init. Init finish signal calls this. */
 
-void silc_opt_callback(poptContext con, 
+void silc_opt_callback(poptContext con,
                       enum poptCallbackReason reason,
                       const struct poptOption *opt,
                       const char *arg, void *data)
 {
   if (strcmp(opt->longName, "nick") == 0) {
-    g_free(silc_client->nickname);  
+    g_free(silc_client->nickname);
     silc_client->nickname = g_strdup(arg);
   }
 
   if (strcmp(opt->longName, "hostname") == 0) {
-    silc_free(silc_client->hostname);  
+    silc_free(silc_client->hostname);
     silc_client->hostname = g_strdup(arg);
   }
 
@@ -297,11 +296,11 @@ void silc_opt_callback(poptContext con,
   }
 
   if (strcmp(opt->longName, "debug") == 0) {
-    silc_debug = TRUE;
-    silc_debug_hexdump = TRUE;
+    silc_log_debug(TRUE);
+    silc_log_debug_hexdump(TRUE);
     silc_log_set_debug_string(arg);
 #ifndef SILC_DEBUG
-    fprintf(stdout, 
+    fprintf(stdout,
            "Run-time debugging is not enabled. To enable it recompile\n"
            "the client with --enable-debug configuration option.\n");
     sleep(1);
@@ -476,14 +475,14 @@ void silc_core_init(void)
   rec->create_channel_setup = create_channel_setup;
   rec->create_server_connect = create_server_connect;
   rec->destroy_server_connect = destroy_server_connect;
-  rec->server_init_connect = silc_server_init_connect; 
+  rec->server_init_connect = silc_server_init_connect;
   rec->server_connect = silc_server_connect;
-  rec->channel_create = (CHANNEL_REC *(*) (SERVER_REC *, const char *, 
+  rec->channel_create = (CHANNEL_REC *(*) (SERVER_REC *, const char *,
                                           const char *, int))
     silc_channel_create;
   rec->query_create = (QUERY_REC *(*) (const char *, const char *, int))
     silc_query_create;
-  
+
   chat_protocol_register(rec);
   g_free(rec);
 
@@ -504,7 +503,7 @@ void silc_core_deinit(void)
 {
   if (idletag != -1)
     g_source_remove(idletag);
-  
+
   signal_emit("chat protocol deinit", 1,
        chat_protocol_find("SILC"));
   signal_remove("setup changed", (SIGNAL_FUNC) sig_setup_changed);
@@ -517,9 +516,9 @@ void silc_core_deinit(void)
   silc_expandos_deinit();
   silc_lag_deinit();
   silc_chatnets_deinit();
-  
+
   chat_protocol_unregister("SILC");
-  
+
   g_free(silc_client->username);
   g_free(silc_client->realname);
   silc_free(silc_client->hostname);
index cf5ddde8a3c2f1cb4a774b270240e9a459597f45..f5a2ffe71fd2d1fcb9d9ac48ca36d3541245f459 100644 (file)
@@ -295,7 +295,7 @@ bool silc_server_init(SilcServer server)
 #ifdef SILC_DEBUG
   /* Set debugging on if configured */
   if (server->config->debug_string) {
-    silc_debug = TRUE;
+    silc_log_debug(TRUE);
     silc_log_set_debug_string(server->config->debug_string);
   }
 #endif /* SILC_DEBUG */
@@ -572,7 +572,7 @@ bool silc_server_rehash(SilcServer server)
   SILC_LOG_INFO(("Rehashing server"));
 
   /* Reset the logging system */
-  silc_log_quick = TRUE;
+  silc_log_quick(TRUE);
   silc_log_flush_all();
 
   /* Start the main rehash phase (read again the config file) */
@@ -764,7 +764,7 @@ bool silc_server_rehash(SilcServer server)
 #ifdef SILC_DEBUG
   /* Set debugging on if configured */
   if (server->config->debug_string) {
-    silc_debug = TRUE;
+    silc_log_debug(TRUE);
     silc_log_set_debug_string(server->config->debug_string);
   }
 #endif /* SILC_DEBUG */
index 133b576ae6e6e3acf97e97c6e68938dc938ff4f0..2582f6a8d4fdaa56931b10155fb0f87b669549b6 100644 (file)
@@ -1919,11 +1919,11 @@ void silc_server_config_setlogfiles(SilcServer server)
 
   SILC_LOG_DEBUG(("Setting configured log file names and options"));
 
-  silc_log_timestamp = config->logging_timestamp;
-  silc_log_quick = config->logging_quick;
-  silc_log_flushdelay = (config->logging_flushdelay ?
-                        config->logging_flushdelay :
-                        SILC_SERVER_LOG_FLUSH_DELAY);
+  silc_log_timestamp(config->logging_timestamp);
+  silc_log_quick(config->logging_quick);
+  silc_log_flushdelay(config->logging_flushdelay ?
+                     config->logging_flushdelay :
+                     SILC_SERVER_LOG_FLUSH_DELAY);
 
   if ((this = config->logging_fatals))
     silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
index a19a4c723fea93af8f5a06369b8bffcb54daf835..9c02f13af4b36ca99172b19304e4ac5ae4fff795 100644 (file)
@@ -612,11 +612,11 @@ int main(int argc, char **argv)
          break;
        case 'd':
 #ifdef SILC_DEBUG
-         silc_debug = TRUE;
+         silc_log_debug(TRUE);
+         silc_log_quick(TRUE);
          if (optarg)
            silc_log_set_debug_string(optarg);
          foreground = TRUE;        /* implied */
-         silc_log_quick = TRUE;    /* implied */
 #else
          fprintf(stderr,
                  "Run-time debugging is not enabled. To enable it recompile\n"
@@ -625,11 +625,11 @@ int main(int argc, char **argv)
          break;
        case 'D':
 #ifdef SILC_DEBUG
-         silc_debug = TRUE;
+         silc_log_debug(TRUE);
+         silc_log_quick(TRUE);
          if (optarg)
            silc_get_debug_level(atoi(optarg));
          foreground = TRUE;        /* implied */
-         silc_log_quick = TRUE;    /* implied */
 #else
          fprintf(stderr,
                  "Run-time debugging is not enabled. To enable it recompile\n"
@@ -638,10 +638,10 @@ int main(int argc, char **argv)
          break;
        case 'x':
 #ifdef SILC_DEBUG
-         silc_debug_hexdump = TRUE;
-         silc_debug = TRUE; /* implied */
+         silc_log_debug(TRUE);
+         silc_log_debug_hexdump(TRUE);
+         silc_log_quick(TRUE);
          foreground = TRUE; /* implied */
-         silc_log_quick = TRUE; /* implied */
 #else
          fprintf(stderr,
                  "Run-time debugging is not enabled. To enable it recompile\n"
@@ -772,12 +772,9 @@ int main(int argc, char **argv)
       snprintf(buf, sizeof(buf) - 1, "%d\n", getpid());
       silc_file_writefile(pidfile, buf, strlen(buf));
     }
-  }
 
-  /* Drop root if we are not in debug mode, so you don't need to bother about
-     file writing permissions and so on */
-  if (!silc_debug)
     silc_server_drop_privs(silcd);
+  }
 
   /* Run the server. When this returns the server has been stopped
      and we will exit. */
index 9cb18e1ceeaec4f373859e74b93413951bbb5396..874c5b1b3f17f07a0d0b4247651654e3e9556bb4 100644 (file)
@@ -133,11 +133,11 @@ int main(int argc, char **argv)
          break;
        case 'd':
 #ifdef SILC_DEBUG
-         silc_debug = TRUE;
-         silc_debug_hexdump = TRUE;
+         silc_log_debug(TRUE);
+         silc_log_debug_hexdump(TRUE);
+         silc_log_quick(TRUE);
          if (optarg)
            silc_log_set_debug_string(optarg);
-         silc_log_quick = TRUE;
 #else
          fprintf(stderr,
                  "Run-time debugging is not enabled. To enable it recompile\n"
index 780c7f312245d9893499502be4a8d4fd51a692fb..ba6583172e1a2aec31e50ad4577241258aefd30c 100644 (file)
@@ -29,7 +29,7 @@ and other utility functions.
 <b>Including Library Headers</b>
 
 <br />&nbsp;<br />
-Your application must include the following includes in your sources to 
+Your application must include the following includes in your sources to
 get access all SILC Client Library routines:
 
 <br />&nbsp;<br />
@@ -83,7 +83,7 @@ manner:
 `context' can be some application specific context that will be saved into
 the SilcClient object.  It is up to the caller to free this context.
 SilcClient is always passed to the application thus the application
-specific context can be retrieved from the SilcClient object.  See 
+specific context can be retrieved from the SilcClient object.  See
 `client.h' file for detailed definition of SilcClient object.
 
 <br />&nbsp;<br />
@@ -179,30 +179,30 @@ should initialize the user interface.
 <b>Running the Client in GUI application</b>
 
 <br />&nbsp;<br />
-Many GUI applications has their own main loop or event loop, which they 
-would like to use or are forced to use by the underlaying system.  If you 
-are developing for example GUI application on Unix system, and you are 
-using GTK+ or QT as GUI library you would probably like to use their own 
-main loop.  SILC Client can be run under external main loop as well.  The 
-interface provides a function silc_client_run_one which will run the 
-client library once, and returns immediately.  During that running it can 
-process incoming data and send outgoing data, but it is guaranteed that it 
+Many GUI applications has their own main loop or event loop, which they
+would like to use or are forced to use by the underlaying system.  If you
+are developing for example GUI application on Unix system, and you are
+using GTK+ or QT as GUI library you would probably like to use their own
+main loop.  SILC Client can be run under external main loop as well.  The
+interface provides a function silc_client_run_one which will run the
+client library once, and returns immediately.  During that running it can
+process incoming data and send outgoing data, but it is guaranteed that it
 will not block the calling process.
 
 <br />&nbsp;<br />
-It is suggested that you would call this function as many times in a 
-second as possible to provide smooth action for the client library.  You 
-can use an timeout task, or an idle task provided by your GUI library to 
-accomplish this.  After you have initialized the client library with 
-silc_client_init, you should register the timeout task or idle task that 
-will call the silc_client_run_one periodically.  In the Toolkit package 
-there is GTK-- GUI example in silcer/ directory.  That example calls the 
-silc_client_run_one every 50 milliseconds, and it should be sufficient for 
+It is suggested that you would call this function as many times in a
+second as possible to provide smooth action for the client library.  You
+can use an timeout task, or an idle task provided by your GUI library to
+accomplish this.  After you have initialized the client library with
+silc_client_init, you should register the timeout task or idle task that
+will call the silc_client_run_one periodically.  In the Toolkit package
+there is GTK-- GUI example in silcer/ directory.  That example calls the
+silc_client_run_one every 50 milliseconds, and it should be sufficient for
 smooth working.
 
 <br />&nbsp;<br />
-For Win32 the silc_client_run can be used instead of using the Windows's 
-own event loop.  However, if you would like to use the silc_client_run_one 
+For Win32 the silc_client_run can be used instead of using the Windows's
+own event loop.  However, if you would like to use the silc_client_run_one
 also on Win32 systems it is possible.
 
 
@@ -210,7 +210,7 @@ also on Win32 systems it is possible.
 <b>Running Client in GTK--</b>
 
 <br />&nbsp;<br />
-Here is a short example how to run the SILC Client libary under the 
+Here is a short example how to run the SILC Client libary under the
 Gnome/GTK--'s main loop:
 
 <br />&nbsp;<br />
@@ -238,8 +238,8 @@ Gnome::Main::timeout.connect(slot(this, &YourClass::silc_scheduler), 50);<br />
 </tt>
 
 <br />&nbsp;<br />
-This will call the function silc_scheduler every 50 millisecconds, which 
-on the otherhand will call silc_client_run_one, which will make the SILC 
+This will call the function silc_scheduler every 50 millisecconds, which
+on the otherhand will call silc_client_run_one, which will make the SILC
 Client library work on the background of the GUI application.
 
 
@@ -263,9 +263,9 @@ screen.  IRC is usually implemented this way, however it is not the
 necessary way to associate the client's connections.  SilcClientConnection
 object is provided by the library (and is always passed to the application)
 that can be used in the application to associate the connection from the
-library.  Application specific context can be saved to the 
+library.  Application specific context can be saved to the
 SilcClientConnection object which then can be retrieved in the application,
-thus perhaps associate the connection with what ever object in 
+thus perhaps associate the connection with what ever object in
 application (window or something else).
 
 
@@ -299,7 +299,7 @@ After connection has been created application must call:
 
 <br />&nbsp;<br />
 NOTE: These calls are performed only and only if application did not call
-silc_client_connect_to_server function, but performed the connecting 
+silc_client_connect_to_server function, but performed the connecting
 process manually.
 
 
@@ -317,21 +317,21 @@ debugging is enabled.
 Then, to say in your application you would like to use the debugging use
 the SILC_ENABLE_DEBUG macro.  Put this macro to your main header file, or
 some other file that needs the debugging enabled.  After using this macro
-you are able to use the debugging routines provided by the SILC Toolkit.  
+you are able to use the debugging routines provided by the SILC Toolkit.
 Note that, the Toolkit library must be compiled with --enable-debug for
 this macro to have any effect.
 
 <br />&nbsp;<br />
-To turn on the run-time debugging set the global variable "silc_debug" to
-TRUE.  To see packet hexdumps you can set also "silc_debug_hexdump" to TRUE.
-Hexdumps can create more debug log so not setting it to TRUE by default is
-probably best.  To get debug messages out of specific modules you can set
-a debug string with silc_log_set_debug_string function.  The function takes
-regex string as argument, for example:
+To turn on the run-time debugging call function silc_log_debug with TRUE
+value.  To see packet hexdumps you can call also silc_log_debug_hexdump
+with TRUE value.  Hexdumps can create more debug log so not setting it
+to TRUE by default is probably best.  To get debug messages out of specific
+modules you can set a debug string with silc_log_set_debug_string function.
+The function takes regex string as argument, for example:
 
 <br />&nbsp;<br />
 <tt>
-&nbsp;&nbsp;silc_debug = TRUE;<br />
+&nbsp;&nbsp;silc_log_debug(TRUE);<br />
 &nbsp;&nbsp;silc_log_set_debug_string("*");<br />
 </tt>
 
@@ -457,7 +457,7 @@ int main()
        /* Start the client. This will start the scheduler. At this phase
           the user might have the user interface in front of him already.
           He will use the user interface to create the connection to the
-          server for example. When this function returns the program is 
+          server for example. When this function returns the program is
          ended. */
        silc_client_run(client);
 
index c9ba5f61ffb1a1a2abb83ba1fda97779d27bf487..027525a6d4822cbba8d0a9d0a60999f27e1b3210 100644 (file)
@@ -71,6 +71,7 @@ include_HEADERS =     \
        silcconfig.h    \
        silchashtable.h \
        silclog.h       \
+       silclog_i.h     \
        silcmemory.h    \
        silcmutex.h     \
        silcnet.h       \
index 0bd5f7389881ec1dcefa58463dd42c56ad713abf..a836d858e26f877d1a429112f195d6c01570a77c 100644 (file)
@@ -2,7 +2,7 @@
 
   silclog.c
 
-  Author: Giovanni Giacobbi <giovanni@giacobbi.net>
+  Author: Pekka Riikonen <priikone@silcnet.org>
 
   Copyright (C) 1997 - 2005 Pekka Riikonen
 
 
 #include "silcincludes.h"
 
-/* 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__++)
-
-/* Our working struct -- at the moment we keep it private, but this could
- * change in the future */
-struct SilcLogStruct {
+/* SilcLogSettings context */
+typedef struct {
+  SilcUInt32 flushdelay;
+
+  char debug_string[128];
+  SilcLogDebugCb debug_cb;
+  void *debug_context;
+  SilcLogHexdumpCb hexdump_cb;
+  void *hexdump_context;
+
+  unsigned int timestamp       : 1;
+  unsigned int quick           : 1;
+  unsigned int debug           : 1;
+  unsigned int debug_hexdump   : 1;
+  unsigned int scheduled       : 1;
+  unsigned int no_init         : 1;
+  unsigned int starting        : 1;
+} *SilcLogSettings, SilcLogSettingsStruct;
+
+/* SilcLog context */
+typedef struct {
   char filename[256];
   FILE *fp;
-  SilcUInt32 maxsize;
+  SilcUInt64 maxsize;
   const char *typename;
   SilcLogType type;
   SilcLogCb cb;
   void *context;
+} *SilcLog, SilcLogStruct;
+
+/* Default settings */
+static SilcLogSettingsStruct silclog =
+{
+  300,
+  { 0 },
+  NULL, NULL,
+  NULL, NULL,
+  TRUE,
+  FALSE,
+  FALSE,
+  FALSE,
+  FALSE,
+  FALSE,
+  TRUE,
 };
-typedef struct SilcLogStruct *SilcLog;
 
-/* These are the known logging channels.  We initialize this struct with most
- * of the fields set to NULL, because we'll fill in those values at runtime. */
-static struct SilcLogStruct silclogs[SILC_LOG_MAX] = {
+/* Default log contexts */
+static SilcLogStruct silclogs[4] =
+{
   {"", NULL, 0, "Info", SILC_LOG_INFO, NULL, NULL},
   {"", NULL, 0, "Warning", SILC_LOG_WARNING, NULL, NULL},
   {"", NULL, 0, "Error", SILC_LOG_ERROR, NULL, NULL},
   {"", NULL, 0, "Fatal", SILC_LOG_FATAL, NULL, NULL},
 };
 
-/* Causes logging output to contain timestamps */
-bool silc_log_timestamp = TRUE;
-
-/* If TRUE, log files will be flushed for each log input */
-bool silc_log_quick = FALSE;
-
-/* Set TRUE/FALSE to enable/disable debugging */
-bool silc_debug = FALSE;
-bool silc_debug_hexdump = FALSE;
-
-/* Flush delay (in seconds) */
-long silc_log_flushdelay = 300;
-
-/* Regular pattern matching expression for the debug output */
-char silc_log_debug_string[128];
-
-/* Debug callbacks. If set, these are triggered for each specific output. */
-static SilcLogDebugCb silc_log_debug_cb = NULL;
-static void *silc_log_debug_context = NULL;
-static SilcLogHexdumpCb silc_log_hexdump_cb = NULL;
-static void *silc_log_hexdump_context = NULL;
-
-/* Did we register already our functions to the scheduler? */
-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 message */
-static bool silc_log_starting = TRUE;
+/* Return log context by type */
 
-/* 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)
+static SilcLog silc_log_get_context(SilcLogType type)
 {
-  /* this is not really needed, but i think it's more secure */
-  switch (type) {
-    case SILC_LOG_INFO:
-      return &silclogs[SILC_LOG_INFO];
-    case SILC_LOG_WARNING:
-      return &silclogs[SILC_LOG_WARNING];
-    case SILC_LOG_ERROR:
-      return &silclogs[SILC_LOG_ERROR];
-    case SILC_LOG_FATAL:
-      return &silclogs[SILC_LOG_FATAL];
-    default:
-      return NULL;
-  }
-  return NULL;
+  if (type < 1 || type > 4)
+    return NULL;
+  return &silclogs[(int)type - 1];
 }
 
-/* Given an open log file, checks the size and rotates it if there is a
- * max size set lower then the current size */
+/* Check log file site and cycle log file if it is over max size. */
+
 static void silc_log_checksize(SilcLog log)
 {
-  char newname[127];
-  long size;
+  char newname[256];
+  SilcUInt64 size;
 
   if (!log || !log->fp || !log->maxsize)
-    return; /* we are not interested */
-
-  if ((size = ftell(log->fp)) < 0) {
-    /* OMG, EBADF is here.. we'll try our best.. */
-    FILE *oldfp = log->fp;
-    fclose(oldfp); /* we can discard the error */
-    log->fp = NULL; /* make sure we don't get here recursively */
-    SILC_LOG_ERROR(("Error while checking size of the log file %s, fp=%p",
-                   log->filename, oldfp));
     return;
+
+  size = silc_file_size(log->filename);
+  if (!size) {
+    fclose(log->fp);
+    log->fp = NULL;
   }
+
   if (size < log->maxsize)
     return;
 
-  /* It's too big */
-  fprintf(log->fp, "[%s] [%s] Cycling log file, over max "
-         "logsize (%lu kilobytes)\n",
+  /* Cycle log file */
+  fprintf(log->fp,
+         "[%s] [%s] Cycling log file, over max log size (%lu kilobytes)\n",
          silc_get_time(0), log->typename, (unsigned long)log->maxsize / 1024);
   fflush(log->fp);
   fclose(log->fp);
+
   memset(newname, 0, sizeof(newname));
   snprintf(newname, sizeof(newname) - 1, "%s.old", log->filename);
   unlink(newname);
-
-  /* I heard the following syscall may cause portability issues, but I don't
-   * have any other solution since SILC library doesn't provide any other
-   * function like this. -Johnny */
   rename(log->filename, newname);
-  if (!(log->fp = fopen(log->filename, "w")))
-    SILC_LOG_WARNING(("Couldn't reopen logfile %s for type \"%s\": %s",
+
+  log->fp = fopen(log->filename, "w");
+  if (!log->fp)
+    SILC_LOG_WARNING(("Couldn't reopen log file '%s' for type '%s': %s",
                      log->filename, log->typename, strerror(errno)));
 #ifdef HAVE_CHMOD
   chmod(log->filename, 0600);
 #endif /* HAVE_CHMOD */
 }
 
-/* Reset a logging channel (close and reopen) */
-
-static bool silc_log_reset(SilcLog log)
-{
-  if (!log) return FALSE;
-  if (log->fp) {
-    fflush(log->fp);
-    fclose(log->fp);
-  }
-  if (!log->filename[0]) 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)));
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
 /* Internal timeout callback to flush log channels and check file sizes */
 
 SILC_TASK_CALLBACK(silc_log_fflush_callback)
 {
-  unsigned int u;
-  if (!silc_log_quick) {
+  SilcLog log;
+
+  if (!silclog.quick) {
     silc_log_flush_all();
-    SILC_FOREACH_LOG(u)
-      silc_log_checksize(&silclogs[u]);
+    log = silc_log_get_context(SILC_LOG_INFO);
+    silc_log_checksize(log);
+    log = silc_log_get_context(SILC_LOG_WARNING);
+    silc_log_checksize(log);
+    log = silc_log_get_context(SILC_LOG_ERROR);
+    silc_log_checksize(log);
+    log = silc_log_get_context(SILC_LOG_FATAL);
+    silc_log_checksize(log);
   }
-  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_flushdelay, 0, SILC_TASK_TIMEOUT,
+
+  silclog.starting = FALSE;
+
+  if (silclog.flushdelay < 2)
+    silclog.flushdelay = 2;
+  silc_schedule_task_add(context, 0, silc_log_fflush_callback, context,
+                        silclog.flushdelay, 0, SILC_TASK_TIMEOUT,
                         SILC_TASK_PRI_NORMAL);
 }
 
-/* Outputs the log message to the first available channel. Channels are
- * ordered by importance (see SilcLogType documentation).
- * More important channels can be printed on less important ones, but not
- * vice-versa. */
+/* Output log message to log file */
 
 void silc_log_output(SilcLogType type, char *string)
 {
   const char *typename = NULL;
+  SilcLog log = silc_log_get_context(type);
   FILE *fp;
-  SilcLog log;
 
-  if ((type > SILC_LOG_MAX) || !(log = silc_log_find_by_type(type)))
+  if (!log)
     goto end;
 
-  /* Save the original typename, because even if we redirect the message
-   * to another channel we'll keep however the original channel name */
-  typename = log->typename;
-
-  /* If there is a custom callback set, use it and return. */
-  if (log->cb) {
+  /* Forward to callback if set */
+  if (log->cb)
     if ((*log->cb)(type, string, log->context))
       goto end;
-  }
 
-  if (!silc_log_scheduled) {
-    if (silc_log_no_init == FALSE) {
+  typename = log->typename;
+
+  if (!silclog.scheduled) {
+    if (silclog.no_init == FALSE) {
       fprintf(stderr,
              "Warning, trying to output without log files initialization, "
              "log output is going to stderr\n");
-      silc_log_no_init = TRUE;
+      silclog.no_init = TRUE;
     }
-    /* redirect output */
+
     fp = stderr;
     log = NULL;
     goto found;
   }
 
-  /* ok, now we have to find an open stream */
-  while (TRUE) {
-    if (log && (fp = log->fp)) goto found;
-    if (type == 0) break;
-    log = silc_log_find_by_type(--type);
-  }
+  /* Find open log file */
+  while (log) {
+    if (log->fp) {
+      fp = log->fp;
+      break;
+    }
 
-  /* Couldn't find any open stream.. sorry :( */
-  SILC_LOG_DEBUG(("Warning! couldn't find any available log channel!"));
-  goto end;
+    log = silc_log_get_context(--type);
+  }
+  if (!log)
+    goto end;
 
  found:
-  /* writes the logging string to the selected channel */
-  if (silc_log_timestamp)
+  if (silclog.timestamp)
     fprintf(fp, "[%s] [%s] %s\n", silc_get_time(0), typename, string);
   else
     fprintf(fp, "[%s] %s\n", typename, string);
 
-  if (silc_log_quick || silc_log_starting) {
+  if (silclog.quick || silclog.starting) {
     fflush(fp);
-    if (log) /* we may have been redirected to stderr */
+    if (log)
       silc_log_checksize(log);
   }
 
  end:
-  /* If debugging, also output the logging message to the console */
-  if (typename && silc_debug) {
+  /* Output log to stderr if debugging */
+  if (typename && silclog.debug) {
     fprintf(stderr, "[Logging] [%s] %s\n", typename, string);
     fflush(stderr);
   }
   silc_free(string);
 }
 
-/* returns an internally allocated pointer to a logging channel file */
-char *silc_log_get_file(SilcLogType type)
-{
-  SilcLog log;
-
-  if (!(log = silc_log_find_by_type(type)))
-    return NULL;
-  if (log->fp)
-    return log->filename;
-  return NULL;
-}
+/* Set and initialize the specified log file. */
 
-/* Set and initialize the specified logging channel. See the API reference */
 bool silc_log_set_file(SilcLogType type, char *filename, SilcUInt32 maxsize,
                       SilcSchedule scheduler)
 {
   FILE *fp = NULL;
   SilcLog log;
 
-  log = silc_log_find_by_type(type);
+  log = silc_log_get_context(type);
   if (!log)
     return FALSE;
 
-  SILC_LOG_DEBUG(("Setting \"%s\" file to %s (max size=%d)",
+  SILC_LOG_DEBUG(("Setting '%s' file to %s (max size=%d)",
                  log->typename, filename, maxsize));
 
-  /* before assuming the new file, make sure we can open it */
+  /* Open log file */
   if (filename) {
-    if (!(fp = fopen(filename, "a+"))) {
-      fprintf(stderr, "warning: couldn't open log file %s: %s\n",
+    fp = fopen(filename, "a+");
+    if (!fp) {
+      fprintf(stderr, "warning: couldn't open log file '%s': %s\n",
              filename, strerror(errno));
       return FALSE;
     }
@@ -286,7 +243,7 @@ bool silc_log_set_file(SilcLogType type, char *filename, SilcUInt32 maxsize,
 #endif /* HAVE_CHMOD */
   }
 
-  /* clean the logging channel */
+  /* Close previous log file if it exists */
   if (strlen(log->filename)) {
     if (log->fp)
       fclose(log->fp);
@@ -294,92 +251,210 @@ bool silc_log_set_file(SilcLogType type, char *filename, SilcUInt32 maxsize,
     log->fp = NULL;
   }
 
+  /* Set new log file */
   if (fp) {
-    memset(log->filename, 0, sizeof(log->filename));
-    strncpy(log->filename, filename,
-           strlen(filename) < sizeof(log->filename) ? strlen(filename) :
-           sizeof(log->filename) - 1);
     log->fp = fp;
     log->maxsize = maxsize;
+
+    memset(log->filename, 0, sizeof(log->filename));
+    silc_strncat(log->filename, sizeof(log->filename), filename,
+                strlen(filename));
   }
 
+  /* Add flush timeout */
   if (scheduler) {
-    if (silc_log_scheduled)
-      return TRUE;
-
-    /* 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, 10, 0,
-                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
-    silc_log_scheduled = TRUE;
+    silc_schedule_task_del_by_callback(scheduler, silc_log_fflush_callback);
+    silc_schedule_task_add(scheduler, 0, silc_log_fflush_callback, scheduler,
+                          10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+    silclog.scheduled = TRUE;
   }
 
   return TRUE;
 }
 
+/* Return log filename */
+
+char *silc_log_get_file(SilcLogType type)
+{
+  SilcLog log = silc_log_get_context(type);
+  return log && log->fp ? log->filename : NULL;
+}
+
 /* Sets a log callback, set callback to NULL to return to default behaviour */
 
 void silc_log_set_callback(SilcLogType type, SilcLogCb cb, void *context)
 {
-  SilcLog log;
+  SilcLog log = silc_log_get_context(type);
+  if (log) {
+    log->cb = cb;
+    log->context = context;
+  }
+}
 
-  if (!(log = silc_log_find_by_type(type)))
-    return;
+/* Reset log callbacks */
 
-  log->cb = cb;
-  log->context = context;
+void silc_log_reset_callbacks(void)
+{
+  SilcLog log;
+  log = silc_log_get_context(SILC_LOG_INFO);
+  log->cb = log->context = NULL;
+  log = silc_log_get_context(SILC_LOG_WARNING);
+  log->cb = log->context = NULL;
+  log = silc_log_get_context(SILC_LOG_ERROR);
+  log->cb = log->context = NULL;
+  log = silc_log_get_context(SILC_LOG_FATAL);
+  log->cb = log->context = NULL;
 }
 
-/* Resets log callbacks */
+/* Flush all log files */
 
-void silc_log_reset_callbacks()
+void silc_log_flush_all(void)
 {
-  unsigned int u;
-  SILC_FOREACH_LOG(u) {
-    silclogs[u].cb = NULL;
-    silclogs[u].context = NULL;
-  }
+  SilcLog log;
+  log = silc_log_get_context(SILC_LOG_INFO);
+  if (log->fp)
+    fflush(log->fp);
+  log = silc_log_get_context(SILC_LOG_WARNING);
+  if (log->fp)
+    fflush(log->fp);
+  log = silc_log_get_context(SILC_LOG_ERROR);
+  if (log->fp)
+    fflush(log->fp);
+  log = silc_log_get_context(SILC_LOG_FATAL);
+  if (log->fp)
+    fflush(log->fp);
 }
 
-/* Flushes all opened logging channels */
+/* Reset a log file */
 
-void silc_log_flush_all() {
-  unsigned int u;
-  SILC_LOG_DEBUG(("Flushing all logs"));
-  SILC_FOREACH_LOG(u) {
-    if (silclogs[u].fp)
-      fflush(silclogs[u].fp);
+static void silc_log_reset(SilcLog log)
+{
+  if (log->fp) {
+    fflush(log->fp);
+    fclose(log->fp);
   }
+
+  if (!strlen(log->filename))
+    return;
+
+  log->fp = fopen(log->filename, "a+");
+  if (!log->fp)
+    SILC_LOG_WARNING(("Couldn't reset log file '%s' for type '%s': %s",
+                     log->filename, log->typename, strerror(errno)));
 }
 
-/* Resets all known logging channels */
+/* Reset all log files */
 
-void silc_log_reset_all() {
-  unsigned int u;
-  SILC_LOG_DEBUG(("Resetting all logs"));
-  SILC_FOREACH_LOG(u)
-    silc_log_reset(&silclogs[u]);
-  /* Immediately flush any possible warning message */
+void silc_log_reset_all(void)
+{
+  SilcLog log;
+  log = silc_log_get_context(SILC_LOG_INFO);
+  if (log->fp)
+    silc_log_reset(log);
+  log = silc_log_get_context(SILC_LOG_WARNING);
+  if (log->fp)
+    silc_log_reset(log);
+  log = silc_log_get_context(SILC_LOG_ERROR);
+  if (log->fp)
+    silc_log_reset(log);
+  log = silc_log_get_context(SILC_LOG_FATAL);
+  if (log->fp)
+    silc_log_reset(log);
   silc_log_flush_all();
 }
 
+/* Sets debug callbacks */
+
+void silc_log_set_debug_callbacks(SilcLogDebugCb debug_cb,
+                                 void *debug_context,
+                                 SilcLogHexdumpCb hexdump_cb,
+                                 void *hexdump_context)
+{
+  silclog.debug_cb = debug_cb;
+  silclog.debug_context = debug_context;
+  silclog.hexdump_cb = hexdump_cb;
+  silclog.hexdump_context = hexdump_context;
+}
+
+/* Resets debug callbacks */
+
+void silc_log_reset_debug_callbacks()
+{
+  silclog.debug_cb = NULL;
+  silclog.debug_context = NULL;
+  silclog.hexdump_cb = NULL;
+  silclog.hexdump_context = NULL;
+}
+
+/* Set current debug string */
+
+void silc_log_set_debug_string(const char *debug_string)
+{
+  char *string;
+  int len;
+  if ((strchr(debug_string, '(') && strchr(debug_string, ')')) ||
+      strchr(debug_string, '$'))
+    string = strdup(debug_string);
+  else
+    string = silc_string_regexify(debug_string);
+  len = strlen(string);
+  if (len >= sizeof(silclog.debug_string))
+    len = sizeof(silclog.debug_string) - 1;
+  memset(silclog.debug_string, 0, sizeof(silclog.debug_string));
+  strncpy(silclog.debug_string, string, len);
+  silc_free(string);
+}
+
+/* Set timestamp */
+
+void silc_log_timestamp(bool enable)
+{
+  silclog.timestamp = enable;
+}
+
+/* Set flushdelay */
+
+void silc_log_flushdelay(SilcUInt32 flushdelay)
+{
+  silclog.flushdelay = flushdelay;
+}
+
+/* Set quick logging */
+
+void silc_log_quick(bool enable)
+{
+  silclog.quick = enable;
+}
+
+/* Set debugging */
+
+void silc_log_debug(bool enable)
+{
+  silclog.debug = enable;
+}
+
+/* Set debug hexdump */
+
+void silc_log_debug_hexdump(bool enable)
+{
+  silclog.debug_hexdump = enable;
+}
+
 /* Outputs the debug message to stderr. */
 
 void silc_log_output_debug(char *file, const char *function,
                           int line, char *string)
 {
-  if (!silc_debug)
+  if (!silclog.debug)
     goto end;
 
-  if (silc_log_debug_string &&
-      !silc_string_regex_match(silc_log_debug_string, file) &&
-      !silc_string_regex_match(silc_log_debug_string, function))
+  if (!silc_string_regex_match(silclog.debug_string, file) &&
+      !silc_string_regex_match(silclog.debug_string, function))
     goto end;
 
-  if (silc_log_debug_cb) {
-    if ((*silc_log_debug_cb)(file, (char *)function, line, string,
-                            silc_log_debug_context))
+  if (silclog.debug_cb) {
+    if ((*silclog.debug_cb)(file, (char *)function, line, string,
+                           silclog.debug_context))
       goto end;
   }
 
@@ -400,18 +475,16 @@ void silc_log_output_hexdump(char *file, const char *function,
   int off, pos, count;
   unsigned char *data = (unsigned char *)data_in;
 
-  if (!silc_debug_hexdump)
+  if (!silclog.debug_hexdump)
     goto end;
 
-  if (silc_log_debug_string &&
-      !silc_string_regex_match(silc_log_debug_string, file) &&
-      !silc_string_regex_match(silc_log_debug_string, function))
+  if (!silc_string_regex_match(silclog.debug_string, file) &&
+      !silc_string_regex_match(silclog.debug_string, function))
     goto end;
 
-  if (silc_log_hexdump_cb) {
-    if ((*silc_log_hexdump_cb)(file, (char *)function, line,
-                              data_in, len, string,
-                              silc_log_hexdump_context))
+  if (silclog.hexdump_cb) {
+    if ((*silclog.hexdump_cb)(file, (char *)function, line,
+                             data_in, len, string, silclog.hexdump_context))
       goto end;
   }
 
@@ -475,45 +548,3 @@ void silc_log_output_hexdump(char *file, const char *function,
  end:
   silc_free(string);
 }
-
-/* Sets debug callbacks */
-
-void silc_log_set_debug_callbacks(SilcLogDebugCb debug_cb,
-                                 void *debug_context,
-                                 SilcLogHexdumpCb hexdump_cb,
-                                 void *hexdump_context)
-{
-  silc_log_debug_cb = debug_cb;
-  silc_log_debug_context = debug_context;
-  silc_log_hexdump_cb = hexdump_cb;
-  silc_log_hexdump_context = hexdump_context;
-}
-
-/* Resets debug callbacks */
-
-void silc_log_reset_debug_callbacks()
-{
-  silc_log_debug_cb = NULL;
-  silc_log_debug_context = NULL;
-  silc_log_hexdump_cb = NULL;
-  silc_log_hexdump_context = NULL;
-}
-
-/* Set current debug string */
-
-void silc_log_set_debug_string(const char *debug_string)
-{
-  char *string;
-  int len;
-  if ((strchr(debug_string, '(') && strchr(debug_string, ')')) ||
-      strchr(debug_string, '$'))
-    string = strdup(debug_string);
-  else
-    string = silc_string_regexify(debug_string);
-  len = strlen(string);
-  if (len >= sizeof(silc_log_debug_string))
-    len = sizeof(silc_log_debug_string) - 1;
-  memset(silc_log_debug_string, 0, sizeof(silc_log_debug_string));
-  strncpy(silc_log_debug_string, string, len);
-  silc_free(string);
-}
index 0cdc654454fb99bde563899b8c522f9b416c623d..af8358501e4d3bc849d6900ef031f02492b85546 100644 (file)
@@ -2,7 +2,7 @@
 
   silclog.h
 
-  Author: Giovanni Giacobbi <giovanni@giacobbi.net>
+  Author: Pekka Riikonen <priikone@silcnet.org>
 
   Copyright (C) 1997 - 2005 Pekka Riikonen
 
  *
  * DESCRIPTION
  *
- *    This is the main logging channel id. There are currently four known
- *    logging channels (plus the debugging output channel), and they are
- *    ordered by importance.
- *
- *    See the source code for SILC coding conventions about how to choose
- *    the right output channel.
+ *    The log type.  This can be given to various silc_log_* routines.
  *
  * SOURCE
  */
 typedef enum {
-  /* Generic info channel file */
-  SILC_LOG_INFO,
-
-  /* This should be used for warnings and non critical failures */
-  SILC_LOG_WARNING,
-
-  /* Generic error and critical failure messages */
-  SILC_LOG_ERROR,
-
-  /* Fatal messages (usually situations that will lead to a program crash */
-  SILC_LOG_FATAL,
-
-  /* Total number logging channels */
-  SILC_LOG_MAX
+  SILC_LOG_INFO       = 1,     /* Generic info */
+  SILC_LOG_WARNING    = 2,      /* Warnings and non-critical failures */
+  SILC_LOG_ERROR      = 3,      /* Generic error and critical failure */
+  SILC_LOG_FATAL      = 4,     /* Fatal error */
 } SilcLogType;
 /***/
 
+#include "silclog_i.h"
+
 /****f* silcutil/SilcLogAPI/SilcLogCb
  *
  * SYNOPSIS
@@ -76,6 +63,7 @@ typedef enum {
  *    The logging custom callback function.  The `type' is the channel ID
  *    that triggered the event, which allows you to use the same callback
  *    function for multiple logging channels.
+ *
  *    The `message' parameter points to a null-terminated buffer containing
  *    the received message, while `context' is the caller-specified context.
  *    The message must not be modified or freed by the callback function.
@@ -100,6 +88,7 @@ typedef bool (*SilcLogCb)(SilcLogType type, char *message, void *context);
  *    corresponding offsets in the source files.  `message' points to a
  *    null-terminated buffer containing the debugging message, and `context'
  *    is the caller-specified context.
+ *
  *    The message must not be modified or freed by the callback function.
  *    If the function returns TRUE, SilcLog will assume the message as handled
  *    and won't run its default handler.
@@ -116,7 +105,8 @@ typedef bool (*SilcLogDebugCb)(char *file, char *function, int line,
  * SYNOPSIS
  *
  *    typedef bool (*SilcDebugHexdumpCb)(char *file, char *function, int line,
- *                                       unsigned char *data, SilcUInt32 data_len,
+ *                                       unsigned char *data,
+ *                                       SilcUInt32 data_len,
  *                                       char *message, void *context;
  *
  * DESCRIPTION
@@ -126,6 +116,7 @@ typedef bool (*SilcLogDebugCb)(char *file, char *function, int line,
  *    like it to be.  `file', `function', and `line' are the corresponding
  *    offsets in the source files.  `data' is the begin of the buffer that
  *    should be hexdumped, which is `data_len' bytes long.
+ *
  *    The `message' parameter points to a null-terminated buffer containing
  *    the received message, while `context' is the caller-specified context.
  *    The message must not be modified or freed by the callback function.
@@ -140,135 +131,8 @@ typedef bool (*SilcLogHexdumpCb)(char *file, char *function, int line,
                                 unsigned char *data, SilcUInt32 data_len,
                                 char *message, void *context);
 
-/* Global Variables */
-
-/****v* silcutil/SilcLogAPI/silc_log_timestamp
- *
- * NAME
- *
- *    bool silc_log_timestamp -- enable/disable fast logging timestamp
- *
- * DESCRIPTION
- *
- *    Causes SilcLog to add a timestamp as returned by silc_get_time().
- *    This may be useful for example if you run your application under a
- *    daemon helper like watchdog that adds its own timestamp.  Defaults to
- *    true.
- *
- ***/
-extern DLLAPI bool silc_log_timestamp;
-
-/****v* silcutil/SilcLogAPI/silc_log_quick
- *
- * NAME
- *
- *    bool silc_log_quick -- enable/disable fast logging output
- *
- * DESCRIPTION
- *
- *    SilcLog makes use of libc stream buffering output, which means that it
- *    saves HD activity by buffering the logging messages and writing them
- *    all together every some minutes (default is 5 minutes).
- *    Setting this variable to TRUE will force SilcLog to write messages to the
- *    filesystem as soon as they are received. This increases the CPU activity
- *    notably on bigger servers, but reduces memory usage.
- *    If you want to change the logging style on-the-fly, make sure to call
- *    silc_log_flush_all() after setting this variable to TRUE.
- *
- ***/
-extern DLLAPI 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.
- *    This value must be greater than 2 seconds.
- *
- ***/
-extern DLLAPI long silc_log_flushdelay;
-
-/****v* silcutil/SilcLogAPI/silc_debug
- *
- * NAME
- *
- *    bool silc_debug -- enable/disable debugging output
- *
- * DESCRIPTION
- *
- *    If silc_debug is set to FALSE, debugging functions won't procude any
- *    output.  This is useful when for example you compile in the debugging
- *    support but at a certain point you want to send the program in the
- *    background.
- *
- * SEE ALSO
- *    SILC_LOG_DEBUG
- *
- ***/
-extern DLLAPI bool silc_debug;
-
-/****v* silcutil/SilcLogAPI/silc_debug_hexdump
- *
- * NAME
- *
- *    bool silc_debug_hexdump -- enable/disable debugging output
- *
- * DESCRIPTION
- *
- *    If silc_debug_hexdump is set to FALSE, debugging functions won't produce
- *    any output.  This is useful when for example you compile in the debugging
- *    support but at a certain point you want to send the program in the
- *    background.
- *
- * SEE ALSO
- *    SILC_LOG_HEXDUMP
- *
- ***/
-extern DLLAPI bool silc_debug_hexdump;
-
 /* Macros */
 
-#if defined(WIN32)
-#ifndef __FUNCTION__
-#define __FUNCTION__ ""
-#endif
-#endif
-
-/****d* silcutil/SilcLogAPI/SILC_ENABLE_DEBUG
- *
- * NAME
- *
- *    #define SILC_ENABLE_DEBUG
- *
- * DESCRIPTION
- *
- *    Use this macro to enable the debugging in your application.  If
- *    SILC was compiled with debugging enabled, this macro enables it.
- *    Use this macro in your application's main header, or in place where
- *    you need to enable the debugging.
- *
- * NOTES
- *
- *    You still can control the debugging with silc_debug variable, on
- *    whether to actually print the debugging or not.  This macro is
- *    used to enable debugging, not to say it is printed or not.
- *
- * SOURCE
- */
-#define SILC_ENABLE_DEBUG      \
-  #ifndef SILC_DEBUG           \
-  #define SILC_DEBUG 1         \
-  #endif
-/***/
-
 /****d* silcutil/SilcLogAPI/SILC_LOG_INFO
  *
  * NAME
@@ -363,19 +227,19 @@ extern DLLAPI bool silc_debug_hexdump;
  *    This is a special wrapper to the debugging output (usually stderr).
  *    The standard behaviour is the same as SILC_LOG_INFO, with the difference
  *    that this macro also depends on the global define SILC_DEBUG.
+ *
  *    Undefining SILC_DEBUG causes these functions to be defined to an empty
  *    value, thus removing all debug logging calls from the compiled
  *    application.
- *    This macro is also affected by the global variable silc_debug.
  *
  * SOURCE
  */
 #if defined(SILC_DEBUG)
-#define SILC_LOG_DEBUG(fmt) silc_log_output_debug(__FILE__, \
-                               __FUNCTION__, \
-                               __LINE__, \
+#define SILC_LOG_DEBUG(fmt) silc_log_output_debug(__FILE__,    \
+                               __FUNCTION__,                   \
+                               __LINE__,                       \
                                silc_format fmt)
-#define SILC_NOT_IMPLEMENTED(string) \
+#define SILC_NOT_IMPLEMENTED(string)                                   \
   SILC_LOG_INFO(("*********** %s: NOT IMPLEMENTED YET", string));
 #else
 #define SILC_LOG_DEBUG(fmt) do { } while(0)
@@ -423,30 +287,29 @@ extern DLLAPI bool silc_debug_hexdump;
 
 /* Prototypes */
 
-/****f* silcutil/SilcLogAPI/silc_log_output
+/****f* silcutil/SilcLogAPI/silc_log_set_file
  *
  * SYNOPSIS
  *
- *    void silc_log_output(SilcLogType type, char *string);
+ *    bool silc_log_set_file(SilcLogType type, char *filename,
+ *                           SilcUInt32 maxsize,
+ *                           SilcSchedule scheduler);
  *
  * DESCRIPTION
  *
- *    This is the main function for logging output. Please note that you
- *    should rather use one of the logging wrapper macros.
- *
- *    If you really want to use this function, its usage is quite simple.
- *    The `type' parameter identifies the channel to use, while the `string'
- *    parameter must be a dynamic allocated (null-terminated) buffer, because
- *    it will be freed at the end of this function, for internal reasons.
- *    If there are registered callbacks for the specified type, this function
- *    will first trigger those callbacks.  The callback functions must NOT
- *    free or modify the original buffer.
+ *    Sets `filename', which can be maximum `maxsize' bytes long, as the new
+ *    logging file for the channel `type'.  If you specify an illegal filename
+ *    a warning message is printed and FALSE is returned.  In this case
+ *    logging settings are not changed.
  *
- * SEE ALSO
- *    SILC_LOG_INFO, SILC_LOG_WARNING, SILC_LOG_ERROR, SILC_LOG_FATAL
+ *    You can disable logging for a channel by specifying NULL filename, the
+ *    maxsize in this case is not important.  The `scheduler' parameter is
+ *    needed by the internal logging to allow buffered output and thus to
+ *    save HD activity.
  *
  ***/
-void silc_log_output(SilcLogType type, char *string);
+bool silc_log_set_file(SilcLogType type, char *filename, SilcUInt32 maxsize,
+                      SilcSchedule scheduler);
 
 /****f* silcutil/SilcLogAPI/silc_log_get_file
  *
@@ -467,30 +330,6 @@ void silc_log_output(SilcLogType type, char *string);
  ***/
 char *silc_log_get_file(SilcLogType type);
 
-/****f* silcutil/SilcLogAPI/silc_log_set_file
- *
- * SYNOPSIS
- *
- *    bool silc_log_set_file(SilcLogType type, char *filename,
- *                           SilcUInt32 maxsize,
- *                           SilcSchedule scheduler);
- *
- * DESCRIPTION
- *
- *    Sets `filename', which can be maximum `maxsize' bytes long, as the new
- *    logging file for the channel `type'.  If you specify an illegal filename
- *    a warning message is printed and FALSE is returned.  In this case
- *    logging settings are not changed.
- *
- *    You can disable logging for a channel by specifying NULL filename, the
- *    maxsize in this case is not important.  The `scheduler' parameter is
- *    needed by the internal logging to allow buffered output and thus to
- *    save HD activity.
- *
- ***/
-bool silc_log_set_file(SilcLogType type, char *filename, SilcUInt32 maxsize,
-                      SilcSchedule scheduler);
-
 /****f* silcutil/SilcLogAPI/silc_log_set_callback
  *
  * SYNOPSIS
@@ -529,7 +368,7 @@ void silc_log_set_callback(SilcLogType type, SilcLogCb cb, void *context);
  *    rather need to call silc_log_set_debug_callbacks() with NULL callbacks.
  *
  ***/
-void silc_log_reset_callbacks();
+void silc_log_reset_callbacks(void);
 
 /****f* silcutil/SilcLogAPI/silc_log_flush_all
  *
@@ -546,7 +385,7 @@ void silc_log_reset_callbacks();
  *    silc_log_quick
  *
  ***/
-void silc_log_flush_all();
+void silc_log_flush_all(void);
 
 /****f* silcutil/SilcLogAPI/silc_log_reset_all
  *
@@ -558,52 +397,12 @@ void silc_log_flush_all();
  *
  *    Forces all logging channels to close and reopen their streams.  Useful
  *    for example after a SIGHUP signal.
+ *
  *    Please note that this function could generate some warning messages if
  *    one or more logging channels point to an illegal filename.
  *
  ***/
-void silc_log_reset_all();
-
-/****f* silcutil/SilcLogAPI/silc_log_output_debug
- *
- * SYNOPSIS
- *
- *    void silc_log_output_debug(char *file, const char *function,
- *                               int line, char *string);
- *
- * DESCRIPTION
- *
- *    This is the main function for debug output.  Please note that you should
- *    rather use the wrapper macro SILC_LOG_DEBUG.
- *    If you want to use it anyway, the `file', `function', and `line' are the
- *    corresponding offsets in the source files, while `string' must be a
- *    dynamic allocated (null-terminated) buffer.
- *
- ***/
-void silc_log_output_debug(char *file, const char *function,
-                          int line, char *string);
-
-/****f* silcutil/SilcLogAPI/silc_log_output_hexdump
- *
- * SYNOPSIS
- *
- *    void silc_log_output_hexdump(char *file, char *function,
- *                                 int line, void *data_in,
- *                                 SilcUInt32 len, char *string);
- *
- * DESCRIPTION
- *
- *    This is the main function for hexdump output.  Please note that you
- *    should rather use the wrapper macro SILC_LOG_HEXDUMP.
- *    If you want to use it anyway, the `file', `function', and `line' are the
- *    corresponding offsets in the source files, `data_in' is the beginning
- *    of the buffer you wish to hexdump, which is `len' bytes long.
- *    `string' must be a dynamic allocated (null-terminated) buffer.
- *
- ***/
-void silc_log_output_hexdump(char *file, const char *function,
-                            int line, void *data_in,
-                            SilcUInt32 len, char *string);
+void silc_log_reset_all(void);
 
 /****f* silcutil/SilcLogAPI/silc_log_set_debug_callbacks
  *
@@ -620,15 +419,13 @@ void silc_log_output_hexdump(char *file, const char *function,
  *    output, that will be called with the `debug_context' parameter.
  *    When SilcLog receives a debug message, it will trigger the callback
  *    function.  If the callback function returns TRUE SilcLog will assume
- *    the input as handled and won't run its default handler.
- *    `hexdump_cb' and `hexdump_context' works the same way, except that they
- *    are referred to SILC_LOG_HEXDUMP requests.
- *    You can disable/remove a callback by setting it to NULL.
- *    If set, each callback function must be either in the form described by
- *    SilcLogDebugCb or SilcLogHexdumpCb.
+ *    the input as handled and won't run its default handler.  The `hexdump_cb'
+ *    and `hexdump_context' works the same way, except that they are referred
+ *    to SILC_LOG_HEXDUMP requests.
  *
- * SEE ALSO
- *    SilcLogDebugCb,  SilcLogHexdumpCb
+ *    You can disable/remove a callback by setting it to NULL.  If set, each
+ *    callback function must be either in the form described by SilcLogDebugCb
+ *    or SilcLogHexdumpCb.
  *
  ***/
 void silc_log_set_debug_callbacks(SilcLogDebugCb debug_cb,
@@ -636,6 +433,19 @@ void silc_log_set_debug_callbacks(SilcLogDebugCb debug_cb,
                                  SilcLogHexdumpCb hexdump_cb,
                                  void *hexdump_context);
 
+/****f* silcutil/SilcLogAPI/silc_log_reset_debug_callbacks
+ *
+ * SYNOPSIS
+ *
+ *    void silc_log_reset_debug_callbacks();
+ *
+ * DESCRIPTION
+ *
+ *    Resets debug callbacks set with silc_log_set_debug_callbacks.
+ *
+ ***/
+void silc_log_reset_debug_callbacks(void);
+
 /****f* silcutil/SilcLogAPI/silc_log_set_debug_string
  *
  * SYNOPSIS
@@ -651,4 +461,91 @@ void silc_log_set_debug_callbacks(SilcLogDebugCb debug_cb,
  ***/
 void silc_log_set_debug_string(const char *debug_string);
 
+/****f* silcutil/SilcLogAPI/silc_log_timestamp
+ *
+ * NAME
+ *
+ *    void silc_log_timestamp(bool enable);
+ *
+ * DESCRIPTION
+ *
+ *    Use timestamp in log messages.  Set `enable' to TRUE to enable
+ *    timestamp and to FALSE to disable it.  Default is TRUE.
+ *
+ ***/
+void silc_log_timestamp(bool enable);
+
+/****f* silcutil/SilcLogAPI/silc_log_flushdelay
+ *
+ * NAME
+ *
+ *    void silc_log_flushdelay(SilcUInt32 flushdelay);
+ *
+ * DESCRIPTION
+ *
+ *    Sets the logfiles flushing delay in seconds.  Default is 300 seconds.
+ *
+ ***/
+void silc_log_flushdelay(SilcUInt32 flushdelay);
+
+/****f* silcutil/SilcLogAPI/silc_log_quick
+ *
+ * NAME
+ *
+ *    void silc_log_quick(bool enable);
+ *
+ * DESCRIPTION
+ *
+ *    SilcLog makes use of libc stream buffering output, which means that it
+ *    saves HD activity by buffering the logging messages and writing them
+ *    all together every some minutes (default is 5 minutes).
+ *
+ *    Setting `enable' to TRUE will force SilcLog to write messages to the
+ *    filesystem as soon as they are received. This increases the CPU activity
+ *    notably on bigger servers, but reduces memory usage.
+ *
+ *    If you want to change the logging style on-the-fly, make sure to call
+ *    silc_log_flush_all() after setting `enable'  to TRUE.
+ *
+ *    Default is FALSE.
+ *
+ ***/
+void silc_log_quick(bool enable);
+
+/****v* silcutil/SilcLogAPI/silc_log_debug
+ *
+ * NAME
+ *
+ *    void silc_log_debug(bool enable);
+ *
+ * DESCRIPTION
+ *
+ *    If `enable' is set to FALSE, debugging functions won't procude any
+ *    output and if set to TRUE prints debug messages to stderr.  Default
+ *    is FALSE.
+ *
+ * SEE ALSO
+ *    SILC_LOG_DEBUG
+ *
+ ***/
+void silc_log_debug(bool enable);
+
+/****v* silcutil/SilcLogAPI/silc_log_debug_hexdump
+ *
+ * NAME
+ *
+ *    void silc_log_debug_hexdump(bool enable);
+ *
+ * DESCRIPTION
+ *
+ *    If `enable' is set to FALSE, debugging functions won't produce
+ *    any output anf if set to TRUE prints hexdump debug message to
+ *    stderr.  Default is FALSE.
+ *
+ * SEE ALSO
+ *    SILC_LOG_HEXDUMP
+ *
+ ***/
+void silc_log_debug_hexdump(bool enable);
+
 #endif /* !SILCLOG_H */
diff --git a/lib/silcutil/silclog_i.h b/lib/silcutil/silclog_i.h
new file mode 100644 (file)
index 0000000..2615635
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+
+  silclog_i.h
+
+  Author: Pekka Riikonen <priikone@silcnet.org>
+
+  Copyright (C) 2005 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; version 2 of the License.
+
+  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.
+
+*/
+
+#ifndef SILCLOG_I_H
+#define SILCLOG_I_H
+
+#ifndef SILCLOG_H
+#error "Do not include this header directly"
+#endif
+
+#if defined(WIN32)
+#ifndef __FUNCTION__
+#define __FUNCTION__ ""
+#endif
+#endif
+
+void silc_log_output(SilcLogType type, char *string);
+void silc_log_output_debug(char *file, const char *function,
+                          int line, char *string);
+void silc_log_output_hexdump(char *file, const char *function,
+                            int line, void *data_in,
+                            SilcUInt32 len, char *string);
+
+#endif /* SILCLOG_I_H */
index e47325b028e83a12802335aecd0316736d053e11..611cd6bc595798e5860e5dc0dc5ed20615038f2e 100644 (file)
@@ -98,7 +98,7 @@ EXPORTS
        silc_command_set_command @ 323 ;\r
        silc_command_set_ident @ 324 ;\r
        silc_config_open @ 327 ;\r
-       silc_debug @ 328 DATA ;\r
+       silc_log_debug @ 328;\r
        silc_pem_decode @ 329 ;\r
        silc_default_ciphers @ 330 DATA ;\r
        silc_default_hash @ 331 DATA ;\r
@@ -522,10 +522,10 @@ EXPORTS
        silc_log_reset_all @ 844 ;\r
        silc_log_flush_all @ 845 ;\r
        silc_log_get_file @ 846 ;\r
-       silc_log_quick @ 847 DATA ;\r
-       silc_log_flushdelay @ 848 DATA ;\r
+       silc_log_quick @ 847;\r
+       silc_log_flushdelay @ 848;\r
        silc_hash_table_list_reset @ 849 ;\r
-       silc_debug_hexdump @ 850 DATA ;\r
+       silc_log_debug_hexdump @ 850;\r
        silc_memdup @ 851 ;\r
        silc_command_get_status @ 852 ;\r
        silc_utf8_encode @ 853 ;\r