From 2753c53d395949feb96461acad5df22db8ab04c4 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Tue, 10 May 2005 13:22:51 +0000 Subject: [PATCH] Rewritten SILC Log API. --- CHANGES | 4 + apps/irssi/src/silc/core/silc-core.c | 53 ++- apps/silcd/server.c | 6 +- apps/silcd/serverconfig.c | 10 +- apps/silcd/silcd.c | 19 +- apps/silcstress/silcstress.c | 6 +- lib/doc/silcclient_using.html | 70 ++-- lib/silcutil/Makefile.ad | 1 + lib/silcutil/silclog.c | 543 ++++++++++++++------------- lib/silcutil/silclog.h | 387 +++++++------------ lib/silcutil/silclog_i.h | 40 ++ win32/libsilc/libsilc.def | 8 +- 12 files changed, 558 insertions(+), 589 deletions(-) create mode 100644 lib/silcutil/silclog_i.h diff --git a/CHANGES b/CHANGES index 3bc0fa28..9b437dcf 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +Tue May 10 15:11:53 EEST 2005 Pekka Riikonen + + * Rewritten SILC Log API. Affected files lib/silcutil/silclog.[ch]. + Mon May 9 12:00:08 EEST 2005 Pekka Riikonen * Fixed channel public key list saving on JOIN command reply diff --git a/apps/irssi/src/silc/core/silc-core.c b/apps/irssi/src/silc/core/silc-core.c index e61e1c1d..47c927b4 100644 --- a/apps/irssi/src/silc/core/silc-core.c +++ b/apps/irssi/src/silc/core/silc-core.c @@ -4,13 +4,13 @@ Author: Pekka Riikonen - 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); diff --git a/apps/silcd/server.c b/apps/silcd/server.c index cf5ddde8..f5a2ffe7 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -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 */ diff --git a/apps/silcd/serverconfig.c b/apps/silcd/serverconfig.c index 133b576a..2582f6a8 100644 --- a/apps/silcd/serverconfig.c +++ b/apps/silcd/serverconfig.c @@ -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, diff --git a/apps/silcd/silcd.c b/apps/silcd/silcd.c index a19a4c72..9c02f13a 100644 --- a/apps/silcd/silcd.c +++ b/apps/silcd/silcd.c @@ -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. */ diff --git a/apps/silcstress/silcstress.c b/apps/silcstress/silcstress.c index 9cb18e1c..874c5b1b 100644 --- a/apps/silcstress/silcstress.c +++ b/apps/silcstress/silcstress.c @@ -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" diff --git a/lib/doc/silcclient_using.html b/lib/doc/silcclient_using.html index 780c7f31..ba658317 100644 --- a/lib/doc/silcclient_using.html +++ b/lib/doc/silcclient_using.html @@ -29,7 +29,7 @@ and other utility functions. Including Library Headers
 
-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:
 
@@ -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.
 
@@ -179,30 +179,30 @@ should initialize the user interface. Running the Client in GUI application
 
-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.
 
-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.
 
-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. Running Client in GTK--
 
-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:
 
@@ -238,8 +238,8 @@ Gnome::Main::timeout.connect(slot(this, &YourClass::silc_scheduler), 50);

 
-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:
 
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.
 
-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:
 
-  silc_debug = TRUE;
+  silc_log_debug(TRUE);
  silc_log_set_debug_string("*");
@@ -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); diff --git a/lib/silcutil/Makefile.ad b/lib/silcutil/Makefile.ad index c9ba5f61..027525a6 100644 --- a/lib/silcutil/Makefile.ad +++ b/lib/silcutil/Makefile.ad @@ -71,6 +71,7 @@ include_HEADERS = \ silcconfig.h \ silchashtable.h \ silclog.h \ + silclog_i.h \ silcmemory.h \ silcmutex.h \ silcnet.h \ diff --git a/lib/silcutil/silclog.c b/lib/silcutil/silclog.c index 0bd5f738..a836d858 100644 --- a/lib/silcutil/silclog.c +++ b/lib/silcutil/silclog.c @@ -2,7 +2,7 @@ silclog.c - Author: Giovanni Giacobbi + Author: Pekka Riikonen Copyright (C) 1997 - 2005 Pekka Riikonen @@ -20,264 +20,221 @@ #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); -} diff --git a/lib/silcutil/silclog.h b/lib/silcutil/silclog.h index 0cdc6544..af835850 100644 --- a/lib/silcutil/silclog.h +++ b/lib/silcutil/silclog.h @@ -2,7 +2,7 @@ silclog.h - Author: Giovanni Giacobbi + Author: Pekka Riikonen Copyright (C) 1997 - 2005 Pekka Riikonen @@ -37,33 +37,20 @@ * * 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 index 00000000..26156356 --- /dev/null +++ b/lib/silcutil/silclog_i.h @@ -0,0 +1,40 @@ +/* + + silclog_i.h + + Author: Pekka Riikonen + + 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 */ diff --git a/win32/libsilc/libsilc.def b/win32/libsilc/libsilc.def index e47325b0..611cd6bc 100644 --- a/win32/libsilc/libsilc.def +++ b/win32/libsilc/libsilc.def @@ -98,7 +98,7 @@ EXPORTS silc_command_set_command @ 323 ; silc_command_set_ident @ 324 ; silc_config_open @ 327 ; - silc_debug @ 328 DATA ; + silc_log_debug @ 328; silc_pem_decode @ 329 ; silc_default_ciphers @ 330 DATA ; silc_default_hash @ 331 DATA ; @@ -522,10 +522,10 @@ EXPORTS silc_log_reset_all @ 844 ; silc_log_flush_all @ 845 ; silc_log_get_file @ 846 ; - silc_log_quick @ 847 DATA ; - silc_log_flushdelay @ 848 DATA ; + silc_log_quick @ 847; + silc_log_flushdelay @ 848; silc_hash_table_list_reset @ 849 ; - silc_debug_hexdump @ 850 DATA ; + silc_log_debug_hexdump @ 850; silc_memdup @ 851 ; silc_command_get_status @ 852 ; silc_utf8_encode @ 853 ; -- 2.24.0