+ if (type < 1 || type > 4)
+ return NULL;
+ return (SilcLog)&silclogs[(int)type - 1];
+}
+
+/* Check log file site and cycle log file if it is over max size. */
+
+static void silc_log_checksize(SilcLog log)
+{
+ char newname[256];
+ SilcUInt64 size;
+
+ if (!log || !log->fp || !log->maxsize)
+ return;
+
+ size = silc_file_size(log->filename);
+ if (!size) {
+ fclose(log->fp);
+ log->fp = NULL;
+ }
+
+ if (size < log->maxsize)
+ return;
+
+ /* Cycle log file */
+ fprintf(log->fp,
+ "[%s] [%s] Cycling log file, over max log size (%lu kilobytes)\n",
+ silc_time_string(0), log->typename,
+ (unsigned long)log->maxsize / 1024);
+ fflush(log->fp);
+ fclose(log->fp);
+
+ memset(newname, 0, sizeof(newname));
+ silc_snprintf(newname, sizeof(newname) - 1, "%s.old", log->filename);
+ unlink(newname);
+ rename(log->filename, newname);
+
+ 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 */
+}
+
+/* Internal timeout callback to flush log channels and check file sizes */
+
+SILC_TASK_CALLBACK(silc_log_fflush_callback)
+{
+#ifndef SILC_SYMBIAN
+ SilcLog log;
+
+ if (!silclog.quick) {
+ silc_log_flush_all();
+ 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);
+ }
+
+ silclog.starting = FALSE;
+
+ if (silclog.flushdelay < 2)
+ silclog.flushdelay = 2;
+ silc_schedule_task_add_timeout(context, silc_log_fflush_callback, context,
+ silclog.flushdelay, 0);
+#endif /* !SILC_SYMBIAN */
+}
+
+/* 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);