+ FILE *fp = NULL;
+ SilcLog log;
+
+ log = silc_log_find_by_type(type);
+ if (!log)
+ return FALSE;
+
+ 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 */
+ if (filename) {
+ if (!(fp = fopen(filename, "a+"))) {
+ fprintf(stderr, "warning: couldn't open log file %s: %s\n",
+ filename, strerror(errno));
+ return FALSE;
+ }
+#ifdef HAVE_CHMOD
+ chmod(filename, 0600);
+#endif /* HAVE_CHMOD */
+ }
+
+ /* clean the logging channel */
+ if (strlen(log->filename)) {
+ if (log->fp)
+ fclose(log->fp);
+ memset(log->filename, 0, sizeof(log->filename));
+ log->fp = NULL;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ return TRUE;
+}
+
+/* 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;
+
+ if (!(log = silc_log_find_by_type(type)))