#define SPEED_G_STR "GB/s"
#define SPEED_T_STR "TB/s"
-#define LOGFILE_MODE_STR "a+"
-
static bool paused = false;
static bool seenHUP = false;
static const char *logfileName = NULL;
-static FILE *logfile = NULL;
+static tr_sys_file_t logfile = TR_BAD_SYS_FILE;
static tr_session * mySession = NULL;
static tr_quark key_pidfile = 0;
static struct event_base *ev_base = NULL;
exit (0);
}
+static bool
+reopen_log_file (const char *filename)
+{
+ tr_error * error = NULL;
+ const tr_sys_file_t old_log_file = logfile;
+ const tr_sys_file_t new_log_file = tr_sys_file_open (filename,
+ TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_APPEND,
+ 0666, &error);
+
+ if (new_log_file == TR_BAD_SYS_FILE)
+ {
+ fprintf (stderr, "Couldn't (re)open log file \"%s\": %s\n", filename, error->message);
+ tr_error_free (error);
+ return false;
+ }
+
+ logfile = new_log_file;
+
+ if (old_log_file != TR_BAD_SYS_FILE)
+ tr_sys_file_close (old_log_file, NULL);
+
+ return true;
+}
+
static void
gotsig (int sig)
{
const char * configDir;
/* reopen the logfile to allow for log rotation */
- if (logfileName) {
- logfile = freopen (logfileName, LOGFILE_MODE_STR, logfile);
- if (!logfile)
- fprintf (stderr, "Couldn't reopen \"%s\": %s\n", logfileName, tr_strerror (errno));
+ if (logfileName != NULL)
+ {
+ reopen_log_file (logfileName);
}
configDir = tr_sessionGetConfigDir (mySession);
}
static void
-printMessage (FILE * logfile, int level, const char * name, const char * message, const char * file, int line)
+printMessage (tr_sys_file_t logfile, int level, const char * name, const char * message, const char * file, int line)
{
- if (logfile != NULL)
+ if (logfile != TR_BAD_SYS_FILE)
{
char timestr[64];
tr_logGetTimeStr (timestr, sizeof (timestr));
if (name)
- fprintf (logfile, "[%s] %s %s (%s:%d)\n", timestr, name, message, file, line);
+ tr_sys_file_write_fmt (logfile, "[%s] %s %s (%s:%d)" TR_NATIVE_EOL_STR,
+ NULL, timestr, name, message, file, line);
else
- fprintf (logfile, "[%s] %s (%s:%d)\n", timestr, message, file, line);
+ tr_sys_file_write_fmt (logfile, "[%s] %s (%s:%d)" TR_NATIVE_EOL_STR,
+ NULL, timestr, message, file, line);
}
#ifdef HAVE_SYSLOG
else /* daemon... write to syslog */
}
static void
-pumpLogMessages (FILE * logfile)
+pumpLogMessages (tr_sys_file_t logfile)
{
const tr_log_message * l;
tr_log_message * list = tr_logGetQueue ();
for (l=list; l!=NULL; l=l->next)
printMessage (logfile, l->level, l->name, l->message, l->file, l->line);
- if (logfile != NULL)
- fflush (logfile);
+ if (logfile != TR_BAD_SYS_FILE)
+ tr_sys_file_flush (logfile, NULL);
tr_logFreeQueue (list);
}
break;
case 'd': dumpSettings = true;
break;
- case 'e': logfile = fopen (optarg, LOGFILE_MODE_STR);
- if (logfile)
+ case 'e': if (reopen_log_file (optarg))
logfileName = optarg;
- else
- fprintf (stderr, "Couldn't open \"%s\": %s\n", optarg, tr_strerror (errno));
break;
case 'f': foreground = true;
break;
}
}
- if (foreground && !logfile)
- logfile = stderr;
+ if (foreground && logfile == TR_BAD_SYS_FILE)
+ logfile = tr_sys_file_get_std (TR_STD_SYS_FILE_ERR, NULL);
if (!loaded)
{
tr_variantDictFindStr (&settings, key_pidfile, &pid_filename, NULL);
if (pid_filename && *pid_filename)
{
- FILE * fp = fopen (pid_filename, "w+");
- if (fp != NULL)
+ tr_error * error = NULL;
+ tr_sys_file_t fp = tr_sys_file_open (pid_filename,
+ TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE,
+ 0666, &error);
+ if (fp != TR_BAD_SYS_FILE)
{
- fprintf (fp, "%d", (int)getpid ());
- fclose (fp);
+ tr_sys_file_write_fmt (fp, "%d", NULL, (int)getpid ());
+ tr_sys_file_close (fp, NULL);
tr_logAddInfo ("Saved pidfile \"%s\"", pid_filename);
pidfile_created = true;
}
else
- tr_logAddError ("Unable to save pidfile \"%s\": %s", pid_filename, tr_strerror (errno));
+ {
+ tr_logAddError ("Unable to save pidfile \"%s\": %s", pid_filename, error->message);
+ tr_error_free (error);
+ }
}
if (tr_variantDictFindBool (&settings, TR_KEY_rpc_authentication_required, &boolVal) && boolVal)
#endif
#include <assert.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h> /* getuid(), close() */
+#include <unistd.h> /* getuid() */
+
+#ifdef __HAIKU__
+ #include <limits.h> /* PATH_MAX */
+#endif
#ifdef _WIN32
#include <w32api.h>
#include "log.h"
#include "platform.h"
#include "session.h"
+#include "utils.h"
/***
**** THREADS
#include <pwd.h>
#endif
+#ifdef _WIN32
+
+char *
+win32_get_special_folder (int folder_id)
+{
+ wchar_t path[MAX_PATH]; /* SHGetFolderPath () requires MAX_PATH */
+ *path = L'\0';
+ SHGetFolderPathW (NULL, folder_id, NULL, 0, path);
+ return tr_win32_native_to_utf8 (path, -1);
+}
+
+#endif
+
static const char *
getHomeDir (void)
{
if (!home)
{
#ifdef _WIN32
- char appdata[MAX_PATH]; /* SHGetFolderPath () requires MAX_PATH */
- *appdata = '\0';
- SHGetFolderPath (NULL, CSIDL_PERSONAL, NULL, 0, appdata);
- home = tr_strdup (appdata);
+ home = win32_get_special_folder (CSIDL_PERSONAL);
#else
struct passwd * pw = getpwuid (getuid ());
if (pw)
#ifdef __APPLE__
s = tr_buildPath (getHomeDir (), "Library", "Application Support", appname, NULL);
#elif defined (_WIN32)
- char appdata[TR_PATH_MAX]; /* SHGetFolderPath () requires MAX_PATH */
- SHGetFolderPath (NULL, CSIDL_APPDATA, NULL, 0, appdata);
+ char * appdata = win32_get_special_folder (CSIDL_APPDATA);
s = tr_buildPath (appdata, appname, NULL);
+ tr_free (appdata);
#elif defined (__HAIKU__)
- char buf[TR_PATH_MAX];
+ char buf[PATH_MAX];
find_directory (B_USER_SETTINGS_DIRECTORY, -1, true, buf, sizeof (buf));
s = tr_buildPath (buf, appname, NULL);
#else
****
***/
-static int
+static bool
isWebClientDir (const char * path)
{
char * tmp = tr_buildPath (path, "index.html", NULL);
#elif defined (_WIN32)
- /* SHGetFolderPath explicitly requires MAX_PATH length */
- char dir[MAX_PATH];
-
/* Generally, Web interface should be stored in a Web subdir of
* calling executable dir. */
if (s == NULL) /* check personal AppData/Transmission/Web */
{
- SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA, NULL, 0, dir);
+ char * dir = win32_get_special_folder (CSIDL_COMMON_APPDATA);
s = tr_buildPath (dir, "Transmission", "Web", NULL);
+ tr_free (dir);
if (!isWebClientDir (s))
{
tr_free (s);
if (s == NULL) /* check personal AppData */
{
- SHGetFolderPath (NULL, CSIDL_APPDATA, NULL, 0, dir);
+ char * dir = win32_get_special_folder (CSIDL_APPDATA);
s = tr_buildPath (dir, "Transmission", "Web", NULL);
+ tr_free (dir);
if (!isWebClientDir (s))
{
tr_free (s);
if (s == NULL) /* check calling module place */
{
- char * tmp;
- GetModuleFileName (GetModuleHandle (NULL), dir, sizeof (dir));
- tmp = tr_sys_path_dirname (dir, NULL);
- s = tr_buildPath (tmp, "Web", NULL);
- tr_free (tmp);
+ wchar_t wide_module_path[MAX_PATH];
+ char * module_path;
+ char * dir;
+ GetModuleFileNameW (NULL, wide_module_path,
+ sizeof (wide_module_path) / sizeof (*wide_module_path));
+ module_path = tr_win32_native_to_utf8 (wide_module_path, -1);
+ dir = tr_sys_path_dirname (module_path, NULL);
+ tr_free (module_path);
+ s = tr_buildPath (dir, "Web", NULL);
+ tr_free (dir);
if (!isWebClientDir (s))
{
tr_free (s);