+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
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
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);
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') {
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') {
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') {
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
}
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;
silc_cipher_register(&(silc_default_ciphers[i]));
break;
}
-
+
if (!silc_cipher_is_supported(cipher)) {
SILC_LOG_ERROR(("Unknown cipher `%s'", cipher));
exit(1);
silc_hash_register(&(silc_default_hash[i]));
break;
}
-
+
if (!silc_hash_is_supported(hash)) {
SILC_LOG_ERROR(("Unknown hash function `%s'", hash));
exit(1);
silc_hmac_register(&(silc_default_hmacs[i]));
break;
}
-
+
if (!silc_hmac_is_supported(hmac)) {
SILC_LOG_ERROR(("Unknown HMAC `%s'", hmac));
exit(1);
/* 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);
}
}
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);
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);
{
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);
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);
#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 */
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) */
#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 */
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,
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"
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"
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"
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. */
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"
<b>Including Library Headers</b>
<br /> <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 /> <br />
`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 /> <br />
<b>Running the Client in GUI application</b>
<br /> <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 /> <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 /> <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.
<b>Running Client in GTK--</b>
<br /> <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 /> <br />
</tt>
<br /> <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.
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).
<br /> <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.
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 /> <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 /> <br />
<tt>
- silc_debug = TRUE;<br />
+ silc_log_debug(TRUE);<br />
silc_log_set_debug_string("*");<br />
</tt>
/* 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);
silcconfig.h \
silchashtable.h \
silclog.h \
+ silclog_i.h \
silcmemory.h \
silcmutex.h \
silcnet.h \
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;
}
#endif /* HAVE_CHMOD */
}
- /* clean the logging channel */
+ /* Close previous log file if it exists */
if (strlen(log->filename)) {
if (log->fp)
fclose(log->fp);
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;
}
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;
}
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);
-}
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
* 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.
* 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.
* 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
* 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.
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
* 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)
/* 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
*
***/
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
* 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
*
* silc_log_quick
*
***/
-void silc_log_flush_all();
+void silc_log_flush_all(void);
/****f* silcutil/SilcLogAPI/silc_log_reset_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
*
* 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,
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
***/
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 */
--- /dev/null
+/*
+
+ 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 */
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
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