Merged silc_1_0_branch to trunk.
[silc.git] / lib / silcutil / silclog.c
index a28e9f4f8c15e073b7bfeb07ed8adee5c8be7c68..976005266bb108c190096d9bd6134b79c103d838 100644 (file)
@@ -2,9 +2,9 @@
 
   silclog.c
 
-  Author: Johnny Mnemonic <johnny@themnemonic.org>
+  Author: Giovanni Giacobbi <giovanni@giacobbi.net>
 
-  Copyright (C) 1997 - 2002 Pekka Riikonen
+  Copyright (C) 1997 - 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
 /* Our working struct -- at the moment we keep it private, but this could
  * change in the future */
 struct SilcLogStruct {
-  char *filename;
+  char filename[256];
   FILE *fp;
   SilcUInt32 maxsize;
-  char *typename;
+  const char *typename;
   SilcLogType type;
   SilcLogCb cb;
   void *context;
@@ -43,12 +43,15 @@ 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] = {
-  {NULL, NULL, 0, "Info", SILC_LOG_INFO, NULL, NULL},
-  {NULL, NULL, 0, "Warning", SILC_LOG_WARNING, NULL, NULL},
-  {NULL, NULL, 0, "Error", SILC_LOG_ERROR, NULL, NULL},
-  {NULL, NULL, 0, "Fatal", SILC_LOG_FATAL, NULL, NULL},
+  {"", 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;
 
@@ -114,15 +117,17 @@ static void silc_log_checksize(SilcLog log)
                    log->filename, oldfp));
     return;
   }
-  if (size < log->maxsize) return;
+  if (size < log->maxsize)
+    return;
 
   /* It's too big */
   fprintf(log->fp, "[%s] [%s] Cycling log file, over max "
          "logsize (%lu kilobytes)\n",
-         silc_get_time(), log->typename, log->maxsize / 1024);
+         silc_get_time(0), log->typename, (unsigned long)log->maxsize / 1024);
   fflush(log->fp);
   fclose(log->fp);
-  snprintf(newname, sizeof(newname), "%s.old", log->filename);
+  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
@@ -132,6 +137,9 @@ static void silc_log_checksize(SilcLog log)
   if (!(log->fp = fopen(log->filename, "w")))
     SILC_LOG_WARNING(("Couldn't reopen logfile %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) */
@@ -143,7 +151,7 @@ static bool silc_log_reset(SilcLog log)
     fflush(log->fp);
     fclose(log->fp);
   }
-  if (!log->filename) return FALSE;
+  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)));
@@ -178,7 +186,7 @@ SILC_TASK_CALLBACK(silc_log_fflush_callback)
 
 void silc_log_output(SilcLogType type, char *string)
 {
-  char *typename = NULL;
+  const char *typename = NULL;
   FILE *fp;
   SilcLog log;
 
@@ -220,7 +228,12 @@ void silc_log_output(SilcLogType type, char *string)
   goto end;
 
  found:
-  fprintf(fp, "[%s] [%s] %s\n", silc_get_time(), typename, string);
+  /* writes the logging string to the selected channel */
+  if (silc_log_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) {
     fflush(fp);
     if (log) /* we may have been redirected to stderr */
@@ -269,19 +282,24 @@ bool silc_log_set_file(SilcLogType type, char *filename, SilcUInt32 maxsize,
              filename, strerror(errno));
       return FALSE;
     }
+#ifdef HAVE_CHMOD
+    chmod(filename, 0600);
+#endif /* HAVE_CHMOD */
   }
 
   /* clean the logging channel */
-  if (log->filename) {
+  if (strlen(log->filename)) {
     if (log->fp)
       fclose(log->fp);
-    silc_free(log->filename);
-    log->filename = NULL;
+    memset(log->filename, 0, sizeof(log->filename));
     log->fp = NULL;
   }
 
   if (fp) {
-    log->filename = strdup(filename);
+    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;
   }
@@ -290,7 +308,7 @@ bool silc_log_set_file(SilcLogType type, char *filename, SilcUInt32 maxsize,
     if (silc_log_scheduled)
       return TRUE;
 
-    /* Add schedule hook with a short delay to make sure we'll use 
+    /* 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,
@@ -349,7 +367,7 @@ void silc_log_reset_all() {
 
 /* Outputs the debug message to stderr. */
 
-void silc_log_output_debug(char *file, char *function,
+void silc_log_output_debug(char *file, const char *function,
                           int line, char *string)
 {
   if (!silc_debug)
@@ -361,7 +379,7 @@ void silc_log_output_debug(char *file, char *function,
     goto end;
 
   if (silc_log_debug_cb) {
-    if ((*silc_log_debug_cb)(file, function, line, string,
+    if ((*silc_log_debug_cb)(file, (char *)function, line, string,
                             silc_log_debug_context))
       goto end;
   }
@@ -375,7 +393,7 @@ void silc_log_output_debug(char *file, char *function,
 
 /* Hexdumps a message */
 
-void silc_log_output_hexdump(char *file, char *function,
+void silc_log_output_hexdump(char *file, const char *function,
                             int line, void *data_in,
                             SilcUInt32 len, char *string)
 {
@@ -392,7 +410,8 @@ void silc_log_output_hexdump(char *file, char *function,
     goto end;
 
   if (silc_log_hexdump_cb) {
-    if ((*silc_log_hexdump_cb)(file, function, line, data_in, len, string,
+    if ((*silc_log_hexdump_cb)(file, (char *)function, line,
+                              data_in, len, string,
                               silc_log_hexdump_context))
       goto end;
   }
@@ -486,11 +505,16 @@ void silc_log_reset_debug_callbacks()
 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);
-  strncpy(silc_log_debug_string, string, strlen(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);
 }