diff --git a/src/lib/arch/IArchFile.h b/src/lib/arch/IArchFile.h index dc2d9c12..940f1f3f 100644 --- a/src/lib/arch/IArchFile.h +++ b/src/lib/arch/IArchFile.h @@ -50,6 +50,18 @@ public: */ virtual std::string getSystemDirectory() = 0; + //! Get installed directory + /*! + Returns the directory in which Synergy is installed. + */ + virtual std::string getInstalledDirectory() = 0; + + //! Get log directory + /*! + Returns the log file directory. + */ + virtual std::string getLogDirectory() = 0; + //! Concatenate path components /*! Concatenate pathname components with a directory separator diff --git a/src/lib/arch/unix/ArchFileUnix.cpp b/src/lib/arch/unix/ArchFileUnix.cpp index dd9de7d2..7b2117c2 100644 --- a/src/lib/arch/unix/ArchFileUnix.cpp +++ b/src/lib/arch/unix/ArchFileUnix.cpp @@ -88,6 +88,22 @@ CArchFileUnix::getSystemDirectory() return "/etc"; } +std::string +CArchFileUnix::getInstalledDirectory() +{ +#if WINAPI_XWINDOWS + return "/bin"; +#else + return ""; +#endif +} + +std::string +CArchFileUnix::getLogDirectory() +{ + return "/var/log"; +} + std::string CArchFileUnix::concatPath(const std::string& prefix, const std::string& suffix) diff --git a/src/lib/arch/unix/ArchFileUnix.h b/src/lib/arch/unix/ArchFileUnix.h index 0eaaca61..92d08f31 100644 --- a/src/lib/arch/unix/ArchFileUnix.h +++ b/src/lib/arch/unix/ArchFileUnix.h @@ -32,6 +32,8 @@ public: virtual const char* getBasename(const char* pathname); virtual std::string getUserDirectory(); virtual std::string getSystemDirectory(); + virtual std::string getInstalledDirectory(); + virtual std::string getLogDirectory(); virtual std::string concatPath(const std::string& prefix, const std::string& suffix); }; diff --git a/src/lib/arch/win32/ArchFileWindows.cpp b/src/lib/arch/win32/ArchFileWindows.cpp index d710ad82..3428e220 100644 --- a/src/lib/arch/win32/ArchFileWindows.cpp +++ b/src/lib/arch/win32/ArchFileWindows.cpp @@ -121,6 +121,24 @@ CArchFileWindows::getSystemDirectory() } } +std::string +CArchFileWindows::getInstalledDirectory() +{ + char fileNameBuffer[MAX_PATH]; + GetModuleFileName(NULL, fileNameBuffer, MAX_PATH); + std::string fileName(fileNameBuffer); + size_t lastSlash = fileName.find_last_of("\\"); + fileName = fileName.substr(0, lastSlash); + + return fileName; +} + +std::string +CArchFileWindows::getLogDirectory() +{ + return getInstalledDirectory(); +} + std::string CArchFileWindows::concatPath(const std::string& prefix, const std::string& suffix) diff --git a/src/lib/arch/win32/ArchFileWindows.h b/src/lib/arch/win32/ArchFileWindows.h index e4f7b326..6ba44ec0 100644 --- a/src/lib/arch/win32/ArchFileWindows.h +++ b/src/lib/arch/win32/ArchFileWindows.h @@ -32,6 +32,8 @@ public: virtual const char* getBasename(const char* pathname); virtual std::string getUserDirectory(); virtual std::string getSystemDirectory(); + virtual std::string getInstalledDirectory(); + virtual std::string getLogDirectory(); virtual std::string concatPath(const std::string& prefix, const std::string& suffix); }; diff --git a/src/lib/base/log_outputters.cpp b/src/lib/base/log_outputters.cpp index ee46ab74..ab4a5f5e 100644 --- a/src/lib/base/log_outputters.cpp +++ b/src/lib/base/log_outputters.cpp @@ -235,14 +235,20 @@ CBufferedLogOutputter::write(ELevel, const char* message) CFileLogOutputter::CFileLogOutputter(const char* logFile) { - assert(logFile != NULL); - m_fileName = logFile; + setLogFilename(logFile); } CFileLogOutputter::~CFileLogOutputter() { } +void +CFileLogOutputter::setLogFilename(const char* logFile) +{ + assert(logFile != NULL); + m_fileName = logFile; +} + bool CFileLogOutputter::write(ELevel level, const char *message) { diff --git a/src/lib/base/log_outputters.h b/src/lib/base/log_outputters.h index 57b927b1..234fd9c1 100644 --- a/src/lib/base/log_outputters.h +++ b/src/lib/base/log_outputters.h @@ -79,8 +79,11 @@ public: virtual void close(); virtual void show(bool showIfEmpty); virtual bool write(ELevel level, const char* message); + + void setLogFilename(const char* title); + private: - std::string m_fileName; + std::string m_fileName; }; //! Write log to system log diff --git a/src/lib/ipc/IpcClientProxy.cpp b/src/lib/ipc/IpcClientProxy.cpp index fdc9bd4b..72c867ac 100644 --- a/src/lib/ipc/IpcClientProxy.cpp +++ b/src/lib/ipc/IpcClientProxy.cpp @@ -141,7 +141,7 @@ CIpcClientProxy::send(const CIpcMessage& message) // also, don't allow the dtor to destroy the stream while we're using it. CArchMutexLock lock(m_writeMutex); - LOG((CLOG_DEBUG "ipc write: %d", message.type())); + LOG((CLOG_DEBUG4 "ipc write: %d", message.type())); switch (message.type()) { case kIpcLogLine: { diff --git a/src/lib/ipc/IpcServerProxy.cpp b/src/lib/ipc/IpcServerProxy.cpp index 582759d8..f84352cf 100644 --- a/src/lib/ipc/IpcServerProxy.cpp +++ b/src/lib/ipc/IpcServerProxy.cpp @@ -83,7 +83,7 @@ CIpcServerProxy::handleData(const CEvent&, void*) void CIpcServerProxy::send(const CIpcMessage& message) { - LOG((CLOG_DEBUG "ipc write: %d", message.type())); + LOG((CLOG_DEBUG4 "ipc write: %d", message.type())); switch (message.type()) { case kIpcHello: { diff --git a/src/lib/platform/MSWindowsWatchdog.cpp b/src/lib/platform/MSWindowsWatchdog.cpp index 3e854392..0dc020f2 100644 --- a/src/lib/platform/MSWindowsWatchdog.cpp +++ b/src/lib/platform/MSWindowsWatchdog.cpp @@ -28,6 +28,7 @@ #include "arch/win32/ArchDaemonWindows.h" #include "arch/win32/XArchWindows.h" #include "arch/Arch.h" +#include "base/log_outputters.h" #include "base/TMethodJob.h" #include "base/Log.h" #include "common/Version.h" @@ -56,7 +57,8 @@ CMSWindowsWatchdog::CMSWindowsWatchdog( m_ipcLogOutputter(ipcLogOutputter), m_elevateProcess(false), m_processFailures(0), - m_processRunning(false) + m_processRunning(false), + m_fileLogOutputter(NULL) { } @@ -245,6 +247,12 @@ CMSWindowsWatchdog::isProcessActive() return exitCode == STILL_ACTIVE; } +void +CMSWindowsWatchdog::setFileLogOutputter(CFileLogOutputter* outputter) +{ + m_fileLogOutputter = outputter; +} + void CMSWindowsWatchdog::startProcess() { @@ -383,8 +391,11 @@ CMSWindowsWatchdog::outputLoop(void*) // send process output over IPC to GUI, and force it to be sent // which bypasses the ipc logging anti-recursion mechanism. m_ipcLogOutputter.write(kINFO, buffer, true); - } - + + if (m_fileLogOutputter != NULL) { + m_fileLogOutputter->write(kINFO, buffer); + } + } } } diff --git a/src/lib/platform/MSWindowsWatchdog.h b/src/lib/platform/MSWindowsWatchdog.h index 67936011..9dd60285 100644 --- a/src/lib/platform/MSWindowsWatchdog.h +++ b/src/lib/platform/MSWindowsWatchdog.h @@ -29,6 +29,7 @@ class CThread; class CIpcLogOutputter; class CIpcServer; +class CFileLogOutputter; class CMSWindowsWatchdog { public: @@ -43,6 +44,7 @@ public: void setCommand(const std::string& command, bool elevate); void stop(); bool isProcessActive(); + void setFileLogOutputter(CFileLogOutputter* outputter); private: void mainLoop(void*); @@ -70,6 +72,7 @@ private: PROCESS_INFORMATION m_processInfo; int m_processFailures; bool m_processRunning; + CFileLogOutputter* m_fileLogOutputter; }; //! Relauncher error diff --git a/src/lib/synergy/DaemonApp.cpp b/src/lib/synergy/DaemonApp.cpp index 43bab0cb..dbaae1d4 100644 --- a/src/lib/synergy/DaemonApp.cpp +++ b/src/lib/synergy/DaemonApp.cpp @@ -87,7 +87,8 @@ CDaemonApp::CDaemonApp() : #if SYSAPI_WIN32 m_watchdog(nullptr), #endif - m_events(nullptr) + m_events(nullptr), + m_fileLogOutputter(nullptr) { s_instance = this; } @@ -197,8 +198,10 @@ CDaemonApp::mainLoop(bool logToFile) { DAEMON_RUNNING(true); - if (logToFile) - CLOG->insert(new CFileLogOutputter(logPath().c_str())); + if (logToFile) { + m_fileLogOutputter = new CFileLogOutputter(logFilename().c_str()); + CLOG->insert(m_fileLogOutputter); + } // create socket multiplexer. this must happen after daemonization // on unix because threads evaporate across a fork(). @@ -213,6 +216,7 @@ CDaemonApp::mainLoop(bool logToFile) #if SYSAPI_WIN32 m_watchdog = new CMSWindowsWatchdog(false, *m_ipcServer, *m_ipcLogOutputter); + m_watchdog->setFileLogOutputter(m_fileLogOutputter); #endif m_events->adoptHandler( @@ -270,21 +274,17 @@ CDaemonApp::foregroundError(const char* message) } std::string -CDaemonApp::logPath() +CDaemonApp::logFilename() { -#ifdef SYSAPI_WIN32 - // TODO: move to CArchMiscWindows - // on windows, log to the same dir as the binary. - char fileNameBuffer[MAX_PATH]; - GetModuleFileName(NULL, fileNameBuffer, MAX_PATH); - string fileName(fileNameBuffer); - size_t lastSlash = fileName.find_last_of("\\"); - string path(fileName.substr(0, lastSlash)); - path.append("\\").append(LOG_FILENAME); - return path; -#elif SYSAPI_UNIX - return "/var/log/" LOG_FILENAME; -#endif + string logFilename; + logFilename = ARCH->setting("LogFilename"); + if (logFilename.empty()) { + logFilename = ARCH->getLogDirectory(); + logFilename.append("/"); + logFilename.append(LOG_FILENAME); + } + + return logFilename; } void @@ -337,6 +337,23 @@ CDaemonApp::handleIpcMessage(const CEvent& e, void*) LOG((CLOG_ERR "failed to save LogLevel setting, %s", e.what())); } } + +#if SYSAPI_WIN32 + CString logFilename; + if (argBase->m_logFile != NULL) { + logFilename = CString(argBase->m_logFile); + ARCH->setting("LogFilename", logFilename); + m_watchdog->setFileLogOutputter(m_fileLogOutputter); + command = CArgParser::assembleCommand(argsArray, "--log", 1); + LOG((CLOG_DEBUG "removed log file argument and filename %s from command ", logFilename.c_str())); + LOG((CLOG_DEBUG "new command, elevate=%d command=%s", cm->elevate(), command.c_str())); + } + else { + m_watchdog->setFileLogOutputter(NULL); + } + + m_fileLogOutputter->setLogFilename(logFilename.c_str()); +#endif } else { LOG((CLOG_DEBUG "empty command, elevate=%d", cm->elevate())); diff --git a/src/lib/synergy/DaemonApp.h b/src/lib/synergy/DaemonApp.h index 47277c82..7de4a931 100644 --- a/src/lib/synergy/DaemonApp.h +++ b/src/lib/synergy/DaemonApp.h @@ -25,6 +25,7 @@ class CEvent; class CIpcLogOutputter; +class CFileLogOutputter; #if SYSAPI_WIN32 class CMSWindowsWatchdog; @@ -41,7 +42,7 @@ public: private: void daemonize(); void foregroundError(const char* message); - std::string logPath(); + std::string logFilename(); void handleIpcMessage(const CEvent&, void*); public: @@ -55,6 +56,7 @@ private: CIpcServer* m_ipcServer; CIpcLogOutputter* m_ipcLogOutputter; IEventQueue* m_events; + CFileLogOutputter* m_fileLogOutputter; }; #define LOG_FILENAME "synergyd.log"