+/**
+ * Setup the log file.
+ *
+ * @param tm timestamp for which we should setup logging
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+static int
+setup_log_file (const struct tm *tm)
+{
+ static char last_fn[PATH_MAX + 1];
+ char fn[PATH_MAX + 1];
+ int dirwarn;
+ int altlog_fd;
+ int dup_return;
+ FILE *altlog;
+ char *leftsquare;
+
+ if (NULL == log_file_name)
+ return GNUNET_SYSERR;
+ if (0 == strftime (fn, sizeof (fn), log_file_name, tm))
+ return GNUNET_SYSERR;
+ leftsquare = strrchr (fn, '[');
+ if ( (NULL != leftsquare) && (']' == leftsquare[1]) )
+ {
+ char *logfile_copy = GNUNET_strdup (fn);
+ logfile_copy[leftsquare - fn] = '\0';
+ logfile_copy[leftsquare - fn + 1] = '\0';
+ snprintf (fn, PATH_MAX, "%s%d%s",
+ logfile_copy, getpid (), &logfile_copy[leftsquare - fn + 2]);
+ GNUNET_free (logfile_copy);
+ }
+ if (0 == strcmp (fn, last_fn))
+ return GNUNET_OK; /* no change */
+ log_rotate (last_fn);
+ strcpy (last_fn, fn);
+ dirwarn = (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn));
+#if WINDOWS
+ altlog_fd = OPEN (fn, O_APPEND |
+ O_BINARY |
+ O_WRONLY | O_CREAT,
+ _S_IREAD | _S_IWRITE);
+#else
+ altlog_fd = OPEN (fn, O_APPEND |
+ O_WRONLY | O_CREAT,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+#endif
+ if (-1 != altlog_fd)
+ {
+ if (NULL != GNUNET_stderr)
+ fclose (GNUNET_stderr);
+ dup_return = dup2 (altlog_fd, 2);
+ (void) close (altlog_fd);
+ if (-1 != dup_return)
+ {
+ altlog = fdopen (2, "ab");
+ if (NULL == altlog)
+ {
+ (void) close (2);
+ altlog_fd = -1;
+ }
+ }
+ else
+ {
+ altlog_fd = -1;
+ }
+ }
+ if (-1 == altlog_fd)
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", fn);
+ if (dirwarn)
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Failed to create or access directory for log file `%s'\n"),
+ fn);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_stderr = altlog;
+ return GNUNET_OK;
+}
+