mirror of
https://github.com/debauchee/barrier.git
synced 2026-11-03 22:14:26 +08:00
Refactored some platform dependent code into a new library,
lib/arch. This should make porting easier. Will probably continue to refactor a little more, moving platform dependent event handling stuff into lib/platform.
This commit is contained in:
@@ -12,8 +12,11 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "CPlatform.h"
|
||||
#include "CLog.h"
|
||||
#include "ILogOutputter.h"
|
||||
#include "CArch.h"
|
||||
#include "CStringUtil.h"
|
||||
#include "XArch.h"
|
||||
#include "CAutoStart.h"
|
||||
#include "LaunchUtil.h"
|
||||
#include "resource.h"
|
||||
@@ -23,6 +26,37 @@
|
||||
#define CLIENT_DAEMON_INFO "Shares this system's mouse and keyboard with others."
|
||||
#define SERVER_DAEMON_INFO "Shares this system's mouse and keyboard with others."
|
||||
|
||||
//
|
||||
// CAutoStartOutputter
|
||||
//
|
||||
// This class detects a message above a certain level and saves it
|
||||
//
|
||||
|
||||
class CAutoStartOutputter : public ILogOutputter {
|
||||
public:
|
||||
CAutoStartOutputter(CString* msg) : m_msg(msg) { }
|
||||
virtual ~CAutoStartOutputter() { }
|
||||
|
||||
// ILogOutputter overrides
|
||||
virtual void open(const char*) { }
|
||||
virtual void close() { }
|
||||
virtual bool write(ELevel level, const char* message);
|
||||
virtual const char* getNewline() const { return ""; }
|
||||
|
||||
private:
|
||||
CString* m_msg;
|
||||
};
|
||||
|
||||
bool
|
||||
CAutoStartOutputter::write(ELevel level, const char* message)
|
||||
{
|
||||
if (level <= CLog::kERROR) {
|
||||
*m_msg = message;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// CAutoStart
|
||||
//
|
||||
@@ -51,8 +85,7 @@ void
|
||||
CAutoStart::doModal()
|
||||
{
|
||||
// install our log outputter
|
||||
CLog::Outputter oldOutputter = CLog::getOutputter();
|
||||
CLog::setOutputter(&CAutoStart::onLog);
|
||||
CLOG->insert(new CAutoStartOutputter(&m_errorMessage));
|
||||
|
||||
// reset saved flag
|
||||
m_userConfigSaved = false;
|
||||
@@ -61,8 +94,8 @@ CAutoStart::doModal()
|
||||
DialogBoxParam(s_instance, MAKEINTRESOURCE(IDD_AUTOSTART),
|
||||
m_parent, dlgProc, (LPARAM)this);
|
||||
|
||||
// restore log outputter
|
||||
CLog::setOutputter(oldOutputter);
|
||||
// remove log outputter
|
||||
CLOG->pop_front();
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -74,19 +107,16 @@ CAutoStart::wasUserConfigSaved() const
|
||||
void
|
||||
CAutoStart::update()
|
||||
{
|
||||
// need a platform object
|
||||
CPlatform platform;
|
||||
|
||||
// get installation state
|
||||
const bool installedSystem = platform.isDaemonInstalled(
|
||||
const bool installedSystem = ARCH->isDaemonInstalled(
|
||||
m_name.c_str(), true);
|
||||
const bool installedUser = platform.isDaemonInstalled(
|
||||
const bool installedUser = ARCH->isDaemonInstalled(
|
||||
m_name.c_str(), false);
|
||||
|
||||
// get user's permissions
|
||||
const bool canInstallSystem = platform.canInstallDaemon(
|
||||
const bool canInstallSystem = ARCH->canInstallDaemon(
|
||||
m_name.c_str(), true);
|
||||
const bool canInstallUser = platform.canInstallDaemon(
|
||||
const bool canInstallUser = ARCH->canInstallDaemon(
|
||||
m_name.c_str(), false);
|
||||
|
||||
// update messages
|
||||
@@ -165,22 +195,25 @@ CAutoStart::onInstall(bool allUsers)
|
||||
m_errorMessage = "";
|
||||
|
||||
// install
|
||||
CPlatform platform;
|
||||
if (!platform.installDaemon(m_name.c_str(),
|
||||
try {
|
||||
ARCH->installDaemon(m_name.c_str(),
|
||||
m_isServer ? SERVER_DAEMON_INFO : CLIENT_DAEMON_INFO,
|
||||
appPath.c_str(), m_cmdLine.c_str(), allUsers)) {
|
||||
appPath.c_str(), m_cmdLine.c_str(), allUsers);
|
||||
askOkay(m_hwnd, getString(IDS_INSTALL_TITLE),
|
||||
getString(allUsers ?
|
||||
IDS_INSTALLED_SYSTEM :
|
||||
IDS_INSTALLED_USER));
|
||||
return true;
|
||||
}
|
||||
catch (XArchDaemon& e) {
|
||||
if (m_errorMessage.empty()) {
|
||||
m_errorMessage = getString(IDS_INSTALL_GENERIC_ERROR);
|
||||
m_errorMessage = CStringUtil::format(
|
||||
getString(IDS_INSTALL_GENERIC_ERROR).c_str(),
|
||||
e.what().c_str());
|
||||
}
|
||||
showError(m_hwnd, m_errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
askOkay(m_hwnd, getString(IDS_INSTALL_TITLE),
|
||||
getString(allUsers ?
|
||||
IDS_INSTALLED_SYSTEM :
|
||||
IDS_INSTALLED_USER));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -190,30 +223,23 @@ CAutoStart::onUninstall(bool allUsers)
|
||||
m_errorMessage = "";
|
||||
|
||||
// uninstall
|
||||
CPlatform platform;
|
||||
if (platform.uninstallDaemon(m_name.c_str(), allUsers) !=
|
||||
IPlatform::kSuccess) {
|
||||
try {
|
||||
ARCH->uninstallDaemon(m_name.c_str(), allUsers);
|
||||
askOkay(m_hwnd, getString(IDS_UNINSTALL_TITLE),
|
||||
getString(allUsers ?
|
||||
IDS_UNINSTALLED_SYSTEM :
|
||||
IDS_UNINSTALLED_USER));
|
||||
return true;
|
||||
}
|
||||
catch (XArchDaemon& e) {
|
||||
if (m_errorMessage.empty()) {
|
||||
m_errorMessage = getString(IDS_UNINSTALL_GENERIC_ERROR);
|
||||
m_errorMessage = CStringUtil::format(
|
||||
getString(IDS_UNINSTALL_GENERIC_ERROR).c_str(),
|
||||
e.what().c_str());
|
||||
}
|
||||
showError(m_hwnd, m_errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
askOkay(m_hwnd, getString(IDS_UNINSTALL_TITLE),
|
||||
getString(allUsers ?
|
||||
IDS_UNINSTALLED_SYSTEM :
|
||||
IDS_UNINSTALLED_USER));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CAutoStart::onLog(int priority, const char* message)
|
||||
{
|
||||
if (priority <= CLog::kERROR) {
|
||||
s_singleton->m_errorMessage = message;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
||||
@@ -57,9 +57,6 @@ private:
|
||||
bool onInstall(bool allUsers);
|
||||
bool onUninstall(bool allUsers);
|
||||
|
||||
// log handling
|
||||
static bool onLog(int priority, const char* message);
|
||||
|
||||
// message handling
|
||||
BOOL doDlgProc(HWND, UINT, WPARAM, LPARAM);
|
||||
static BOOL CALLBACK dlgProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
*/
|
||||
|
||||
#include "CConfig.h"
|
||||
#include "CPlatform.h"
|
||||
#include "LaunchUtil.h"
|
||||
#include "CArch.h"
|
||||
#include "resource.h"
|
||||
#include "stdfstream.h"
|
||||
|
||||
@@ -107,10 +107,9 @@ CString
|
||||
getAppPath(const CString& appName)
|
||||
{
|
||||
// prepare path to app
|
||||
CPlatform platform;
|
||||
char myPathname[MAX_PATH];
|
||||
GetModuleFileName(s_instance, myPathname, MAX_PATH);
|
||||
const char* myBasename = platform.getBasename(myPathname);
|
||||
const char* myBasename = ARCH->getBasename(myPathname);
|
||||
CString appPath = CString(myPathname, myBasename - myPathname);
|
||||
appPath += appName;
|
||||
return appPath;
|
||||
@@ -136,24 +135,20 @@ loadConfig(const CString& pathname, CConfig& config)
|
||||
bool
|
||||
loadConfig(CConfig& config)
|
||||
{
|
||||
CPlatform platform;
|
||||
|
||||
// load configuration
|
||||
bool configLoaded = false;
|
||||
CString path = platform.getUserDirectory();
|
||||
CString path = ARCH->getUserDirectory();
|
||||
if (!path.empty()) {
|
||||
CPlatform platform;
|
||||
|
||||
// try loading the user's configuration
|
||||
path = platform.addPathComponent(path, CONFIG_NAME);
|
||||
path = ARCH->concatPath(path, CONFIG_NAME);
|
||||
if (loadConfig(path, config)) {
|
||||
configLoaded = true;
|
||||
}
|
||||
else {
|
||||
// try the system-wide config file
|
||||
path = platform.getSystemDirectory();
|
||||
path = ARCH->getSystemDirectory();
|
||||
if (!path.empty()) {
|
||||
path = platform.addPathComponent(path, CONFIG_NAME);
|
||||
path = ARCH->concatPath(path, CONFIG_NAME);
|
||||
if (loadConfig(path, config)) {
|
||||
configLoaded = true;
|
||||
}
|
||||
@@ -183,13 +178,11 @@ saveConfig(const CString& pathname, const CConfig& config)
|
||||
bool
|
||||
saveConfig(const CConfig& config, bool sysOnly)
|
||||
{
|
||||
CPlatform platform;
|
||||
|
||||
// try saving the user's configuration
|
||||
if (!sysOnly) {
|
||||
CString path = platform.getUserDirectory();
|
||||
CString path = ARCH->getUserDirectory();
|
||||
if (!path.empty()) {
|
||||
path = platform.addPathComponent(path, CONFIG_NAME);
|
||||
path = ARCH->concatPath(path, CONFIG_NAME);
|
||||
if (saveConfig(path, config)) {
|
||||
return true;
|
||||
}
|
||||
@@ -198,9 +191,9 @@ saveConfig(const CConfig& config, bool sysOnly)
|
||||
|
||||
// try the system-wide config file
|
||||
else {
|
||||
CString path = platform.getSystemDirectory();
|
||||
CString path = ARCH->getSystemDirectory();
|
||||
if (!path.empty()) {
|
||||
path = platform.addPathComponent(path, CONFIG_NAME);
|
||||
path = ARCH->concatPath(path, CONFIG_NAME);
|
||||
if (saveConfig(path, config)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
|
||||
#include "CConfig.h"
|
||||
#include "ProtocolTypes.h"
|
||||
#include "CPlatform.h"
|
||||
#include "CNetwork.h"
|
||||
#include "CLog.h"
|
||||
#include "CStringUtil.h"
|
||||
#include "CArch.h"
|
||||
#include "Version.h"
|
||||
#include "stdvector.h"
|
||||
#include "resource.h"
|
||||
@@ -62,10 +62,26 @@ static const char* s_debugName[][2] = {
|
||||
};
|
||||
static const int s_defaultDebug = 3; // INFO
|
||||
|
||||
static HWND s_mainWindow;
|
||||
static CConfig s_config;
|
||||
static CConfig s_oldConfig;
|
||||
static CStringList s_screens;
|
||||
//
|
||||
// program arguments
|
||||
//
|
||||
|
||||
#define ARG CArgs::s_instance
|
||||
|
||||
class CArgs {
|
||||
public:
|
||||
CArgs() { s_instance = this; }
|
||||
~CArgs() { s_instance = NULL; }
|
||||
|
||||
public:
|
||||
static CArgs* s_instance;
|
||||
CConfig m_config;
|
||||
CConfig m_oldConfig;
|
||||
CStringList m_screens;
|
||||
};
|
||||
|
||||
CArgs* CArgs::s_instance = NULL;
|
||||
|
||||
|
||||
static
|
||||
BOOL CALLBACK
|
||||
@@ -117,7 +133,7 @@ static
|
||||
void
|
||||
enableSaveControls(HWND hwnd)
|
||||
{
|
||||
enableItem(hwnd, IDC_MAIN_SAVE, s_config != s_oldConfig);
|
||||
enableItem(hwnd, IDC_MAIN_SAVE, ARG->m_config != ARG->m_oldConfig);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -171,8 +187,8 @@ updateNeighbor(HWND hwnd, const CString& screen, EDirection direction)
|
||||
|
||||
// add all screens to combo box
|
||||
if (!screen.empty()) {
|
||||
for (CConfig::const_iterator index = s_config.begin();
|
||||
index != s_config.end(); ++index) {
|
||||
for (CConfig::const_iterator index = ARG->m_config.begin();
|
||||
index != ARG->m_config.end(); ++index) {
|
||||
SendMessage(hwnd, CB_INSERTSTRING,
|
||||
(WPARAM)-1, (LPARAM)index->c_str());
|
||||
}
|
||||
@@ -184,7 +200,7 @@ updateNeighbor(HWND hwnd, const CString& screen, EDirection direction)
|
||||
// select neighbor in combo box
|
||||
LRESULT index = 0;
|
||||
if (!screen.empty()) {
|
||||
const CString& neighbor = s_config.getNeighbor(screen, direction);
|
||||
const CString& neighbor = ARG->m_config.getNeighbor(screen, direction);
|
||||
if (!neighbor.empty()) {
|
||||
index = SendMessage(hwnd, CB_FINDSTRINGEXACT,
|
||||
0, (LPARAM)neighbor.c_str());
|
||||
@@ -205,7 +221,7 @@ updateNeighbors(HWND hwnd)
|
||||
HWND child = getItem(hwnd, IDC_MAIN_SERVER_SCREENS_LIST);
|
||||
LRESULT index = SendMessage(child, LB_GETCURSEL, 0, 0);
|
||||
if (index != LB_ERR) {
|
||||
screen = s_screens[index];
|
||||
screen = ARG->m_screens[index];
|
||||
}
|
||||
|
||||
// set neighbor combo boxes
|
||||
@@ -230,7 +246,7 @@ addScreen(HWND hwnd)
|
||||
if (DialogBoxParam(s_instance, MAKEINTRESOURCE(IDD_ADD),
|
||||
hwnd, addDlgProc, (LPARAM)&info) != 0) {
|
||||
// get current number of screens
|
||||
UInt32 i = s_screens.size();
|
||||
UInt32 i = ARG->m_screens.size();
|
||||
|
||||
// add screen to list control
|
||||
HWND child = getItem(hwnd, IDC_MAIN_SERVER_SCREENS_LIST);
|
||||
@@ -239,15 +255,15 @@ addScreen(HWND hwnd)
|
||||
SendMessage(child, LB_ADDSTRING, 0, (LPARAM)item.c_str());
|
||||
|
||||
// add screen to screen list
|
||||
s_screens.push_back(info.m_screen);
|
||||
ARG->m_screens.push_back(info.m_screen);
|
||||
|
||||
// add screen to config
|
||||
s_config.addScreen(info.m_screen);
|
||||
ARG->m_config.addScreen(info.m_screen);
|
||||
|
||||
// add aliases to config
|
||||
for (CStringList::const_iterator index = info.m_aliases.begin();
|
||||
index != info.m_aliases.end(); ++index) {
|
||||
s_config.addAlias(info.m_screen, *index);
|
||||
ARG->m_config.addAlias(info.m_screen, *index);
|
||||
}
|
||||
|
||||
// update neighbors
|
||||
@@ -271,9 +287,9 @@ editScreen(HWND hwnd)
|
||||
|
||||
// fill in screen info
|
||||
CScreenInfo info;
|
||||
info.m_screen = s_screens[index];
|
||||
for (CConfig::all_const_iterator index = s_config.beginAll();
|
||||
index != s_config.endAll(); ++index) {
|
||||
info.m_screen = ARG->m_screens[index];
|
||||
for (CConfig::all_const_iterator index = ARG->m_config.beginAll();
|
||||
index != ARG->m_config.endAll(); ++index) {
|
||||
if (CStringUtil::CaselessCmp::equal(index->second, info.m_screen) &&
|
||||
!CStringUtil::CaselessCmp::equal(index->second, index->first)) {
|
||||
info.m_aliases.push_back(index->first);
|
||||
@@ -287,21 +303,21 @@ editScreen(HWND hwnd)
|
||||
if (DialogBoxParam(s_instance, MAKEINTRESOURCE(IDD_ADD),
|
||||
hwnd, addDlgProc, (LPARAM)&info) != 0) {
|
||||
// replace screen
|
||||
s_screens[index] = info.m_screen;
|
||||
ARG->m_screens[index] = info.m_screen;
|
||||
|
||||
// remove old aliases
|
||||
for (CStringList::const_iterator index = oldInfo.m_aliases.begin();
|
||||
index != oldInfo.m_aliases.end(); ++index) {
|
||||
s_config.removeAlias(*index);
|
||||
ARG->m_config.removeAlias(*index);
|
||||
}
|
||||
|
||||
// replace name
|
||||
s_config.renameScreen(oldInfo.m_screen, info.m_screen);
|
||||
ARG->m_config.renameScreen(oldInfo.m_screen, info.m_screen);
|
||||
|
||||
// add new aliases
|
||||
for (CStringList::const_iterator index = info.m_aliases.begin();
|
||||
index != info.m_aliases.end(); ++index) {
|
||||
s_config.addAlias(info.m_screen, *index);
|
||||
ARG->m_config.addAlias(info.m_screen, *index);
|
||||
}
|
||||
|
||||
// update list
|
||||
@@ -331,16 +347,16 @@ removeScreen(HWND hwnd)
|
||||
}
|
||||
|
||||
// get screen name
|
||||
CString name = s_screens[index];
|
||||
CString name = ARG->m_screens[index];
|
||||
|
||||
// remove screen from list control
|
||||
SendMessage(child, LB_DELETESTRING, index, 0);
|
||||
|
||||
// remove screen from screen list
|
||||
s_screens.erase(&s_screens[index]);
|
||||
ARG->m_screens.erase(&ARG->m_screens[index]);
|
||||
|
||||
// remove screen from config (this also removes aliases)
|
||||
s_config.removeScreen(name);
|
||||
ARG->m_config.removeScreen(name);
|
||||
|
||||
// update neighbors
|
||||
updateNeighbors(hwnd);
|
||||
@@ -361,20 +377,20 @@ changeNeighbor(HWND hwnd, HWND combo, EDirection direction)
|
||||
}
|
||||
|
||||
// get screen name
|
||||
CString screen = s_screens[index];
|
||||
CString screen = ARG->m_screens[index];
|
||||
|
||||
// get selected neighbor
|
||||
index = SendMessage(combo, CB_GETCURSEL, 0, 0);
|
||||
|
||||
// remove old connection
|
||||
s_config.disconnect(screen, direction);
|
||||
ARG->m_config.disconnect(screen, direction);
|
||||
|
||||
// add new connection
|
||||
if (index != LB_ERR && index != 0) {
|
||||
LRESULT size = SendMessage(combo, CB_GETLBTEXTLEN, index, 0);
|
||||
char* neighbor = new char[size + 1];
|
||||
SendMessage(combo, CB_GETLBTEXT, index, (LPARAM)neighbor);
|
||||
s_config.connect(screen, direction, CString(neighbor));
|
||||
ARG->m_config.connect(screen, direction, CString(neighbor));
|
||||
delete[] neighbor;
|
||||
}
|
||||
|
||||
@@ -444,14 +460,14 @@ getCommandLine(HWND hwnd, bool testing)
|
||||
// get and verify screen name
|
||||
HWND child = getItem(hwnd, IDC_MAIN_ADVANCED_NAME_EDIT);
|
||||
CString name = getWindowText(child);
|
||||
if (!s_config.isValidScreenName(name)) {
|
||||
if (!ARG->m_config.isValidScreenName(name)) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_INVALID_SCREEN_NAME).c_str(),
|
||||
name.c_str()));
|
||||
SetFocus(child);
|
||||
return CString();
|
||||
}
|
||||
if (!isClient && !s_config.isScreen(name)) {
|
||||
if (!isClient && !ARG->m_config.isScreen(name)) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_UNKNOWN_SCREEN_NAME).c_str(),
|
||||
name.c_str()));
|
||||
@@ -490,7 +506,7 @@ getCommandLine(HWND hwnd, bool testing)
|
||||
// check server name
|
||||
child = getItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_EDIT);
|
||||
CString server = getWindowText(child);
|
||||
if (!s_config.isValidScreenName(server)) {
|
||||
if (!ARG->m_config.isValidScreenName(server)) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_INVALID_SERVER_NAME).c_str(),
|
||||
server.c_str()));
|
||||
@@ -649,15 +665,13 @@ static
|
||||
void
|
||||
initMainWindow(HWND hwnd)
|
||||
{
|
||||
CPlatform platform;
|
||||
|
||||
// append version number to title
|
||||
CString titleFormat = getString(IDS_TITLE);
|
||||
setWindowText(hwnd, CStringUtil::format(titleFormat.c_str(), VERSION));
|
||||
|
||||
// load configuration
|
||||
bool configLoaded = loadConfig(s_config);
|
||||
s_oldConfig = s_config;
|
||||
bool configLoaded = loadConfig(ARG->m_config);
|
||||
ARG->m_oldConfig = ARG->m_config;
|
||||
enableSaveControls(hwnd);
|
||||
|
||||
// choose client/server radio buttons
|
||||
@@ -673,9 +687,9 @@ initMainWindow(HWND hwnd)
|
||||
if (configLoaded) {
|
||||
int i = 1;
|
||||
child = getItem(hwnd, IDC_MAIN_SERVER_SCREENS_LIST);
|
||||
for (CConfig::const_iterator index = s_config.begin();
|
||||
index != s_config.end(); ++i, ++index) {
|
||||
s_screens.push_back(*index);
|
||||
for (CConfig::const_iterator index = ARG->m_config.begin();
|
||||
index != ARG->m_config.end(); ++i, ++index) {
|
||||
ARG->m_screens.push_back(*index);
|
||||
CString item = CStringUtil::print("%d. %s", i, index->c_str());
|
||||
SendMessage(child, LB_ADDSTRING, 0, (LPARAM)item.c_str());
|
||||
}
|
||||
@@ -687,9 +701,9 @@ initMainWindow(HWND hwnd)
|
||||
child = getItem(hwnd, IDC_MAIN_ADVANCED_PORT_EDIT);
|
||||
SendMessage(child, WM_SETTEXT, 0, (LPARAM)buffer);
|
||||
|
||||
CNetwork::gethostname(buffer, sizeof(buffer));
|
||||
CString hostname = ARCH->getHostName();
|
||||
child = getItem(hwnd, IDC_MAIN_ADVANCED_NAME_EDIT);
|
||||
SendMessage(child, WM_SETTEXT, 0, (LPARAM)buffer);
|
||||
SendMessage(child, WM_SETTEXT, 0, (LPARAM)hostname.c_str());
|
||||
|
||||
child = getItem(hwnd, IDC_MAIN_DEBUG);
|
||||
for (unsigned int i = 0; i < sizeof(s_debugName) /
|
||||
@@ -746,7 +760,7 @@ addDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
tokenize(newAliases, getWindowText(child));
|
||||
|
||||
// name must be valid
|
||||
if (!s_config.isValidScreenName(newName)) {
|
||||
if (!ARG->m_config.isValidScreenName(newName)) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_INVALID_SCREEN_NAME).c_str(),
|
||||
newName.c_str()));
|
||||
@@ -756,7 +770,7 @@ addDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
// aliases must be valid
|
||||
for (CStringList::const_iterator index = newAliases.begin();
|
||||
index != newAliases.end(); ++index) {
|
||||
if (!s_config.isValidScreenName(*index)) {
|
||||
if (!ARG->m_config.isValidScreenName(*index)) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_INVALID_SCREEN_NAME).c_str(),
|
||||
index->c_str()));
|
||||
@@ -775,7 +789,7 @@ addDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
// name must not exist in config but allow same name. also
|
||||
// allow name if it exists in the old alias list but not the
|
||||
// new one.
|
||||
if (s_config.isScreen(newName) &&
|
||||
if (ARG->m_config.isScreen(newName) &&
|
||||
!CStringUtil::CaselessCmp::equal(newName, info->m_screen) &&
|
||||
!isNameInList(info->m_aliases, newName)) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
@@ -788,7 +802,7 @@ addDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
// allow an alias to be the old name.
|
||||
for (CStringList::const_iterator index = newAliases.begin();
|
||||
index != newAliases.end(); ++index) {
|
||||
if (s_config.isScreen(*index) &&
|
||||
if (ARG->m_config.isScreen(*index) &&
|
||||
!CStringUtil::CaselessCmp::equal(*index, info->m_screen) &&
|
||||
!isNameInList(info->m_aliases, *index)) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
@@ -830,7 +844,7 @@ mainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDCANCEL:
|
||||
// test for unsaved data
|
||||
if (s_config != s_oldConfig) {
|
||||
if (ARG->m_config != ARG->m_oldConfig) {
|
||||
if (!askVerify(hwnd, getString(IDS_UNSAVED_DATA_REALLY_QUIT))) {
|
||||
return 0;
|
||||
}
|
||||
@@ -846,14 +860,14 @@ mainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
const bool testing = (LOWORD(wParam) == IDC_MAIN_TEST);
|
||||
|
||||
// save data
|
||||
if (s_config != s_oldConfig) {
|
||||
if (!saveConfig(s_config, false)) {
|
||||
if (ARG->m_config != ARG->m_oldConfig) {
|
||||
if (!saveConfig(ARG->m_config, false)) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_SAVE_FAILED).c_str(),
|
||||
getErrorString(GetLastError()).c_str()));
|
||||
return 0;
|
||||
}
|
||||
s_oldConfig = s_config;
|
||||
ARG->m_oldConfig = ARG->m_config;
|
||||
enableSaveControls(hwnd);
|
||||
}
|
||||
|
||||
@@ -892,11 +906,11 @@ mainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
if (!cmdLine.empty()) {
|
||||
// run dialog
|
||||
CAutoStart autoStart(hwnd,
|
||||
isClientChecked(hwnd) ? NULL : &s_config,
|
||||
isClientChecked(hwnd) ? NULL : &ARG->m_config,
|
||||
cmdLine);
|
||||
autoStart.doModal();
|
||||
if (autoStart.wasUserConfigSaved()) {
|
||||
s_oldConfig = s_config;
|
||||
ARG->m_oldConfig = ARG->m_config;
|
||||
enableSaveControls(hwnd);
|
||||
}
|
||||
}
|
||||
@@ -904,13 +918,13 @@ mainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
}
|
||||
|
||||
case IDC_MAIN_SAVE:
|
||||
if (!saveConfig(s_config, false)) {
|
||||
if (!saveConfig(ARG->m_config, false)) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_SAVE_FAILED).c_str(),
|
||||
getErrorString(GetLastError()).c_str()));
|
||||
}
|
||||
else {
|
||||
s_oldConfig = s_config;
|
||||
ARG->m_oldConfig = ARG->m_config;
|
||||
enableSaveControls(hwnd);
|
||||
}
|
||||
return 0;
|
||||
@@ -981,10 +995,11 @@ mainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
int WINAPI
|
||||
WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int nCmdShow)
|
||||
{
|
||||
s_instance = instance;
|
||||
CArch arch;
|
||||
CLOG;
|
||||
CArgs args;
|
||||
|
||||
// initialize network library
|
||||
CNetwork::init();
|
||||
s_instance = instance;
|
||||
|
||||
// register main window (dialog) class
|
||||
WNDCLASSEX classInfo;
|
||||
@@ -1009,13 +1024,14 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int nCmdShow)
|
||||
RegisterClassEx(&classInfo);
|
||||
|
||||
// create main window
|
||||
s_mainWindow = CreateDialog(s_instance, MAKEINTRESOURCE(IDD_MAIN), 0, NULL);
|
||||
HWND m_mainWindow = CreateDialog(s_instance,
|
||||
MAKEINTRESOURCE(IDD_MAIN), 0, NULL);
|
||||
|
||||
// prep window
|
||||
initMainWindow(s_mainWindow);
|
||||
initMainWindow(m_mainWindow);
|
||||
|
||||
// show window
|
||||
ShowWindow(s_mainWindow, nCmdShow);
|
||||
ShowWindow(m_mainWindow, nCmdShow);
|
||||
|
||||
// main loop
|
||||
MSG msg;
|
||||
@@ -1032,7 +1048,7 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int nCmdShow)
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!IsDialogMessage(s_mainWindow, &msg)) {
|
||||
if (!IsDialogMessage(m_mainWindow, &msg)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\http" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
|
||||
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\http" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
@@ -71,7 +71,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\http" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\http" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
|
||||
@@ -241,8 +241,8 @@ BEGIN
|
||||
"Synergy is not configured to start automatically."
|
||||
IDS_INSTALL_LABEL "Install"
|
||||
IDS_UNINSTALL_LABEL "Uninstall"
|
||||
IDS_INSTALL_GENERIC_ERROR "Install failed for an unknown reason."
|
||||
IDS_UNINSTALL_GENERIC_ERROR "Uninstall failed for an unknown reason."
|
||||
IDS_INSTALL_GENERIC_ERROR "Install failed: %{1}."
|
||||
IDS_UNINSTALL_GENERIC_ERROR "Uninstall failed: %{1}."
|
||||
IDS_INSTALL_TITLE "Installed Auto-Start"
|
||||
IDS_INSTALLED_SYSTEM "Installed auto-start. Synergy will now automatically start each time you start your computer."
|
||||
IDS_INSTALLED_USER "Installed auto-start. Synergy will now automatically start each time you log in."
|
||||
|
||||
@@ -38,6 +38,7 @@ synergyc_LDADD = \
|
||||
$(DEPTH)/lib/io/libio.a \
|
||||
$(DEPTH)/lib/mt/libmt.a \
|
||||
$(DEPTH)/lib/base/libbase.a \
|
||||
$(DEPTH)/lib/arch/libarch.a \
|
||||
$(X_LIBS) \
|
||||
$(X_PRE_LIBS) \
|
||||
-lXtst \
|
||||
@@ -46,6 +47,8 @@ synergyc_LDADD = \
|
||||
$(X_EXTRA_LIBS) \
|
||||
$(NULL)
|
||||
INCLUDES = \
|
||||
-I$(VDEPTH)/lib/common \
|
||||
-I$(VDEPTH)/lib/arch \
|
||||
-I$(VDEPTH)/lib/base \
|
||||
-I$(VDEPTH)/lib/mt \
|
||||
-I$(VDEPTH)/lib/io \
|
||||
|
||||
@@ -14,11 +14,9 @@
|
||||
|
||||
#include "CClient.h"
|
||||
#include "ISecondaryScreenFactory.h"
|
||||
#include "CPlatform.h"
|
||||
#include "ProtocolTypes.h"
|
||||
#include "Version.h"
|
||||
#include "XScreen.h"
|
||||
#include "CNetwork.h"
|
||||
#include "CNetworkAddress.h"
|
||||
#include "CTCPSocketFactory.h"
|
||||
#include "XSocket.h"
|
||||
@@ -28,12 +26,18 @@
|
||||
#include "CThread.h"
|
||||
#include "XThread.h"
|
||||
#include "CLog.h"
|
||||
#include "LogOutputters.h"
|
||||
#include "CString.h"
|
||||
#include "CArch.h"
|
||||
#include "CArchMiscWindows.h"
|
||||
#include <cstring>
|
||||
|
||||
#define DAEMON_RUNNING(running_)
|
||||
#if WINDOWS_LIKE
|
||||
#include "CMSWindowsSecondaryScreen.h"
|
||||
#include "resource.h"
|
||||
#undef DAEMON_RUNNING
|
||||
#define DAEMON_RUNNING(running_) CArchMiscWindows::daemonRunning(running_)
|
||||
#elif UNIX_LIKE
|
||||
#include "CXWindowsSecondaryScreen.h"
|
||||
#endif
|
||||
@@ -49,35 +53,33 @@
|
||||
// program arguments
|
||||
//
|
||||
|
||||
static const char* pname = NULL;
|
||||
static bool s_backend = false;
|
||||
static bool s_restartable = true;
|
||||
static bool s_daemon = true;
|
||||
static bool s_camp = true;
|
||||
static const char* s_logFilter = NULL;
|
||||
static CString s_name;
|
||||
static CNetworkAddress s_serverAddress;
|
||||
#define ARG CArgs::s_instance
|
||||
|
||||
class CArgs {
|
||||
public:
|
||||
CArgs() :
|
||||
m_pname(NULL),
|
||||
m_backend(false),
|
||||
m_restartable(true),
|
||||
m_daemon(true),
|
||||
m_camp(true),
|
||||
m_logFilter(NULL)
|
||||
{ s_instance = this; }
|
||||
~CArgs() { s_instance = NULL; }
|
||||
|
||||
//
|
||||
// logging thread safety
|
||||
//
|
||||
public:
|
||||
static CArgs* s_instance;
|
||||
const char* m_pname;
|
||||
bool m_backend;
|
||||
bool m_restartable;
|
||||
bool m_daemon;
|
||||
bool m_camp;
|
||||
const char* m_logFilter;
|
||||
CString m_name;
|
||||
CNetworkAddress m_serverAddress;
|
||||
};
|
||||
|
||||
static CMutex* s_logMutex = NULL;
|
||||
|
||||
static
|
||||
void
|
||||
logLock(bool lock)
|
||||
{
|
||||
assert(s_logMutex != NULL);
|
||||
|
||||
if (lock) {
|
||||
s_logMutex->lock();
|
||||
}
|
||||
else {
|
||||
s_logMutex->unlock();
|
||||
}
|
||||
}
|
||||
CArgs* CArgs::s_instance = NULL;
|
||||
|
||||
|
||||
//
|
||||
@@ -113,27 +115,17 @@ static CClient* s_client = NULL;
|
||||
|
||||
static
|
||||
int
|
||||
realMain(CMutex* mutex)
|
||||
realMain(void)
|
||||
{
|
||||
// caller should have mutex locked on entry
|
||||
|
||||
// initialize threading library
|
||||
CThread::init();
|
||||
|
||||
// make logging thread safe
|
||||
CMutex logMutex;
|
||||
s_logMutex = &logMutex;
|
||||
CLog::setLock(&logLock);
|
||||
|
||||
int result = kExitSuccess;
|
||||
do {
|
||||
bool opened = false;
|
||||
bool locked = true;
|
||||
try {
|
||||
// create client
|
||||
s_client = new CClient(s_name);
|
||||
s_client->camp(s_camp);
|
||||
s_client->setAddress(s_serverAddress);
|
||||
s_client = new CClient(ARG->m_name);
|
||||
s_client->camp(ARG->m_camp);
|
||||
s_client->setAddress(ARG->m_serverAddress);
|
||||
s_client->setScreenFactory(new CSecondaryScreenFactory);
|
||||
s_client->setSocketFactory(new CTCPSocketFactory);
|
||||
s_client->setStreamFilterFactory(NULL);
|
||||
@@ -144,9 +136,7 @@ realMain(CMutex* mutex)
|
||||
opened = true;
|
||||
|
||||
// run client
|
||||
if (mutex != NULL) {
|
||||
mutex->unlock();
|
||||
}
|
||||
DAEMON_RUNNING(true);
|
||||
locked = false;
|
||||
s_client->mainLoop();
|
||||
locked = true;
|
||||
@@ -160,8 +150,8 @@ realMain(CMutex* mutex)
|
||||
|
||||
// clean up
|
||||
#define FINALLY do { \
|
||||
if (!locked && mutex != NULL) { \
|
||||
mutex->lock(); \
|
||||
if (!locked) { \
|
||||
DAEMON_RUNNING(false); \
|
||||
} \
|
||||
if (s_client != NULL) { \
|
||||
if (opened) { \
|
||||
@@ -175,8 +165,8 @@ realMain(CMutex* mutex)
|
||||
}
|
||||
catch (XScreenUnavailable& e) {
|
||||
// wait before retrying if we're going to retry
|
||||
if (s_restartable) {
|
||||
CThread::sleep(e.getRetryTime());
|
||||
if (ARG->m_restartable) {
|
||||
ARCH->sleep(e.getRetryTime());
|
||||
}
|
||||
else {
|
||||
result = kExitFailed;
|
||||
@@ -189,8 +179,8 @@ realMain(CMutex* mutex)
|
||||
}
|
||||
catch (...) {
|
||||
// don't try to restart and fail
|
||||
s_restartable = false;
|
||||
result = kExitFailed;
|
||||
ARG->m_restartable = false;
|
||||
result = kExitFailed;
|
||||
FINALLY;
|
||||
}
|
||||
#undef FINALLY
|
||||
@@ -200,19 +190,10 @@ realMain(CMutex* mutex)
|
||||
}
|
||||
catch (XThread&) {
|
||||
// terminated
|
||||
s_restartable = false;
|
||||
result = kExitTerminated;
|
||||
ARG->m_restartable = false;
|
||||
result = kExitTerminated;
|
||||
}
|
||||
catch (...) {
|
||||
CLog::setLock(NULL);
|
||||
s_logMutex = NULL;
|
||||
throw;
|
||||
}
|
||||
} while (s_restartable);
|
||||
|
||||
// clean up
|
||||
CLog::setLock(NULL);
|
||||
s_logMutex = NULL;
|
||||
} while (ARG->m_restartable);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -233,7 +214,7 @@ version()
|
||||
LOG((CLOG_PRINT
|
||||
"%s %s, protocol version %d.%d\n"
|
||||
"%s",
|
||||
pname,
|
||||
ARG->m_pname,
|
||||
kVersion,
|
||||
kProtocolMajorVersion,
|
||||
kProtocolMinorVersion,
|
||||
@@ -279,7 +260,7 @@ help()
|
||||
"\n"
|
||||
"Where log messages go depends on the platform and whether or not the\n"
|
||||
"client is running as a daemon.",
|
||||
pname, kDefaultPort));
|
||||
ARG->m_pname, kDefaultPort));
|
||||
|
||||
}
|
||||
|
||||
@@ -294,7 +275,7 @@ isArg(int argi, int argc, const char** argv,
|
||||
// match. check args left.
|
||||
if (argi + minRequiredParameters >= argc) {
|
||||
LOG((CLOG_PRINT "%s: missing arguments for `%s'" BYE,
|
||||
pname, argv[argi], pname));
|
||||
ARG->m_pname, argv[argi], ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
return true;
|
||||
@@ -308,61 +289,58 @@ static
|
||||
void
|
||||
parse(int argc, const char** argv)
|
||||
{
|
||||
assert(pname != NULL);
|
||||
assert(argv != NULL);
|
||||
assert(argc >= 1);
|
||||
assert(ARG->m_pname != NULL);
|
||||
assert(argv != NULL);
|
||||
assert(argc >= 1);
|
||||
|
||||
// set defaults
|
||||
char hostname[256];
|
||||
if (CNetwork::gethostname(hostname, sizeof(hostname)) != CNetwork::Error) {
|
||||
s_name = hostname;
|
||||
}
|
||||
ARG->m_name = ARCH->getHostName();
|
||||
|
||||
// parse options
|
||||
int i;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (isArg(i, argc, argv, "-d", "--debug", 1)) {
|
||||
// change logging level
|
||||
s_logFilter = argv[++i];
|
||||
ARG->m_logFilter = argv[++i];
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-n", "--name", 1)) {
|
||||
// save screen name
|
||||
s_name = argv[++i];
|
||||
ARG->m_name = argv[++i];
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, NULL, "--camp")) {
|
||||
// enable camping
|
||||
s_camp = true;
|
||||
ARG->m_camp = true;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, NULL, "--no-camp")) {
|
||||
// disable camping
|
||||
s_camp = false;
|
||||
ARG->m_camp = false;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-f", "--no-daemon")) {
|
||||
// not a daemon
|
||||
s_daemon = false;
|
||||
ARG->m_daemon = false;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, NULL, "--daemon")) {
|
||||
// daemonize
|
||||
s_daemon = true;
|
||||
ARG->m_daemon = true;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-1", "--no-restart")) {
|
||||
// don't try to restart
|
||||
s_restartable = false;
|
||||
ARG->m_restartable = false;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, NULL, "--restart")) {
|
||||
// try to restart
|
||||
s_restartable = true;
|
||||
ARG->m_restartable = true;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-z", NULL)) {
|
||||
s_backend = true;
|
||||
ARG->m_backend = true;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-h", "--help")) {
|
||||
@@ -383,7 +361,7 @@ parse(int argc, const char** argv)
|
||||
|
||||
else if (argv[i][0] == '-') {
|
||||
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
||||
pname, argv[i], pname));
|
||||
ARG->m_pname, argv[i], ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
|
||||
@@ -396,49 +374,60 @@ parse(int argc, const char** argv)
|
||||
// exactly one non-option argument (server-address)
|
||||
if (i == argc) {
|
||||
LOG((CLOG_PRINT "%s: a server address or name is required" BYE,
|
||||
pname, pname));
|
||||
ARG->m_pname, ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
if (i + 1 != argc) {
|
||||
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
||||
pname, argv[i], pname));
|
||||
ARG->m_pname, argv[i], ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
|
||||
// save server address
|
||||
try {
|
||||
s_serverAddress = CNetworkAddress(argv[i], kDefaultPort);
|
||||
ARG->m_serverAddress = CNetworkAddress(argv[i], kDefaultPort);
|
||||
}
|
||||
catch (XSocketAddress& e) {
|
||||
LOG((CLOG_PRINT "%s: %s" BYE,
|
||||
pname, e.what(), pname));
|
||||
ARG->m_pname, e.what(), ARG->m_pname));
|
||||
bye(kExitFailed);
|
||||
}
|
||||
|
||||
// increase default filter level for daemon. the user must
|
||||
// explicitly request another level for a daemon.
|
||||
if (s_daemon && s_logFilter == NULL) {
|
||||
if (ARG->m_daemon && ARG->m_logFilter == NULL) {
|
||||
#if WINDOWS_LIKE
|
||||
if (CPlatform::isWindows95Family()) {
|
||||
if (CArchMiscWindows::isWindows95Family()) {
|
||||
// windows 95 has no place for logging so avoid showing
|
||||
// the log console window.
|
||||
s_logFilter = "FATAL";
|
||||
ARG->m_logFilter = "FATAL";
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
s_logFilter = "NOTE";
|
||||
ARG->m_logFilter = "NOTE";
|
||||
}
|
||||
}
|
||||
|
||||
// set log filter
|
||||
if (!CLog::setFilter(s_logFilter)) {
|
||||
if (!CLOG->setFilter(ARG->m_logFilter)) {
|
||||
LOG((CLOG_PRINT "%s: unrecognized log level `%s'" BYE,
|
||||
pname, s_logFilter, pname));
|
||||
ARG->m_pname, ARG->m_logFilter, ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
useSystemLog()
|
||||
{
|
||||
// redirect log messages
|
||||
ILogOutputter* logger = new CSystemLogOutputter;
|
||||
logger->open(DAEMON_NAME);
|
||||
CLOG->insert(new CStopLogOutputter);
|
||||
CLOG->insert(logger);
|
||||
}
|
||||
|
||||
//
|
||||
// platform dependent entry points
|
||||
//
|
||||
@@ -449,24 +438,41 @@ parse(int argc, const char** argv)
|
||||
|
||||
static bool s_hasImportantLogMessages = false;
|
||||
|
||||
static
|
||||
//
|
||||
// CMessageBoxOutputter
|
||||
//
|
||||
// This class writes severe log messages to a message box
|
||||
//
|
||||
|
||||
class CMessageBoxOutputter : public ILogOutputter {
|
||||
public:
|
||||
CMessageBoxOutputter() { }
|
||||
virtual ~CMessageBoxOutputter() { }
|
||||
|
||||
// ILogOutputter overrides
|
||||
virtual void open(const char*) { }
|
||||
virtual void close() { }
|
||||
virtual bool write(ELevel level, const char* message);
|
||||
virtual const char* getNewline() const { return ""; }
|
||||
};
|
||||
|
||||
bool
|
||||
logMessageBox(int priority, const char* msg)
|
||||
CMessageBoxOutputter::write(ELevel level, const char* message)
|
||||
{
|
||||
// note any important messages the user may need to know about
|
||||
if (priority <= CLog::kWARNING) {
|
||||
if (level <= CLog::kWARNING) {
|
||||
s_hasImportantLogMessages = true;
|
||||
}
|
||||
|
||||
// FATAL and PRINT messages get a dialog box if not running as
|
||||
// backend. if we're running as a backend the user will have
|
||||
// a chance to see the messages when we exit.
|
||||
if (!s_backend && priority <= CLog::kFATAL) {
|
||||
MessageBox(NULL, msg, pname, MB_OK | MB_ICONWARNING);
|
||||
return true;
|
||||
if (!ARG->m_backend && level <= CLog::kFATAL) {
|
||||
MessageBox(NULL, message, ARG->m_pname, MB_OK | MB_ICONWARNING);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,7 +480,7 @@ static
|
||||
void
|
||||
byeThrow(int x)
|
||||
{
|
||||
throw CWin32Platform::CDaemonFailed(x);
|
||||
CArchMiscWindows::daemonFailed(x);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -486,10 +492,9 @@ daemonStop(void)
|
||||
|
||||
static
|
||||
int
|
||||
daemonStartup(IPlatform* iplatform, int argc, const char** argv)
|
||||
daemonStartup(int argc, const char** argv)
|
||||
{
|
||||
// get platform pointer
|
||||
CWin32Platform* platform = static_cast<CWin32Platform*>(iplatform);
|
||||
useSystemLog();
|
||||
|
||||
// catch errors that would normally exit
|
||||
bye = &byeThrow;
|
||||
@@ -498,35 +503,35 @@ daemonStartup(IPlatform* iplatform, int argc, const char** argv)
|
||||
parse(argc, argv);
|
||||
|
||||
// cannot run as backend if running as a service
|
||||
s_backend = false;
|
||||
ARG->m_backend = false;
|
||||
|
||||
// run as a service
|
||||
return platform->runDaemon(realMain, daemonStop);
|
||||
return CArchMiscWindows::runDaemon(realMain, daemonStop);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
daemonStartup95(IPlatform*, int, const char**)
|
||||
daemonStartup95(int, const char**)
|
||||
{
|
||||
return realMain(NULL);
|
||||
useSystemLog();
|
||||
return realMain();
|
||||
}
|
||||
|
||||
int WINAPI
|
||||
WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||
{
|
||||
CPlatform platform;
|
||||
CArch arch;
|
||||
CLOG;
|
||||
CArgs args;
|
||||
|
||||
// save instance
|
||||
CMSWindowsScreen::init(instance);
|
||||
|
||||
// get program name
|
||||
pname = platform.getBasename(__argv[0]);
|
||||
|
||||
// initialize network library
|
||||
CNetwork::init();
|
||||
ARG->m_pname = ARCH->getBasename(__argv[0]);
|
||||
|
||||
// send PRINT and FATAL output to a message box
|
||||
CLog::setOutputter(&logMessageBox);
|
||||
CLOG->insert(new CMessageBoxOutputter);
|
||||
|
||||
// windows NT family starts services using no command line options.
|
||||
// since i'm not sure how to tell the difference between that and
|
||||
@@ -534,10 +539,10 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||
// arguments and we're on NT then we're being invoked as a service.
|
||||
// users on NT can use `--daemon' or `--no-daemon' to force us out
|
||||
// of the service code path.
|
||||
if (__argc <= 1 && !CWin32Platform::isWindows95Family()) {
|
||||
int result = platform.daemonize(DAEMON_NAME, &daemonStartup);
|
||||
if (__argc <= 1 && !CArchMiscWindows::isWindows95Family()) {
|
||||
int result = ARCH->daemonize(DAEMON_NAME, &daemonStartup);
|
||||
if (result == -1) {
|
||||
LOG((CLOG_CRIT "failed to start as a service" BYE, pname));
|
||||
LOG((CLOG_CRIT "failed to start as a service" BYE, ARG->m_pname));
|
||||
return kExitFailed;
|
||||
}
|
||||
return result;
|
||||
@@ -548,38 +553,36 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||
|
||||
// daemonize if requested
|
||||
int result;
|
||||
if (s_daemon) {
|
||||
// redirect log messages
|
||||
platform.installDaemonLogger(DAEMON_NAME);
|
||||
|
||||
if (ARG->m_daemon) {
|
||||
// start as a daemon
|
||||
if (CWin32Platform::isWindows95Family()) {
|
||||
result = platform.daemonize(DAEMON_NAME, &daemonStartup95);
|
||||
if (result == -1) {
|
||||
LOG((CLOG_CRIT "failed to start as a service" BYE, pname));
|
||||
if (CArchMiscWindows::isWindows95Family()) {
|
||||
try {
|
||||
result = ARCH->daemonize(DAEMON_NAME, &daemonStartup95);
|
||||
}
|
||||
catch (XArchDaemon&) {
|
||||
LOG((CLOG_CRIT "failed to start as a service" BYE, ARG->m_pname));
|
||||
result = kExitFailed;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// cannot start a service from the command line so just
|
||||
// run normally (except with log messages redirected).
|
||||
result = realMain(NULL);
|
||||
useSystemLog();
|
||||
result = realMain();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// run
|
||||
result = realMain(NULL);
|
||||
result = realMain();
|
||||
}
|
||||
|
||||
CNetwork::cleanup();
|
||||
|
||||
// let user examine any messages if we're running as a backend
|
||||
// by putting up a dialog box before exiting.
|
||||
if (s_backend && s_hasImportantLogMessages) {
|
||||
if (ARG->m_backend && s_hasImportantLogMessages) {
|
||||
char msg[1024];
|
||||
msg[0] = '\0';
|
||||
LoadString(instance, IDS_FAILED, msg, sizeof(msg) / sizeof(msg[0]));
|
||||
MessageBox(NULL, msg, pname, MB_OK | MB_ICONWARNING);
|
||||
MessageBox(NULL, msg, ARG->m_pname, MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -589,40 +592,40 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||
|
||||
static
|
||||
int
|
||||
daemonStartup(IPlatform*, int, const char**)
|
||||
daemonStartup(int, const char**)
|
||||
{
|
||||
return realMain(NULL);
|
||||
useSystemLog();
|
||||
return realMain();
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
CPlatform platform;
|
||||
CArch arch;
|
||||
CLOG;
|
||||
CArgs args;
|
||||
|
||||
// get program name
|
||||
pname = platform.getBasename(argv[0]);
|
||||
|
||||
// initialize network library
|
||||
CNetwork::init();
|
||||
ARG->m_pname = ARCH->getBasename(argv[0]);
|
||||
|
||||
// parse command line
|
||||
parse(argc, const_cast<const char**>(argv));
|
||||
|
||||
// daemonize if requested
|
||||
int result;
|
||||
if (s_daemon) {
|
||||
result = platform.daemonize(DAEMON_NAME, &daemonStartup);
|
||||
if (result == -1) {
|
||||
if (ARG->m_daemon) {
|
||||
try {
|
||||
result = ARCH->daemonize(DAEMON_NAME, &daemonStartup);
|
||||
}
|
||||
catch (XArchDaemon&) {
|
||||
LOG((CLOG_CRIT "failed to daemonize"));
|
||||
return kExitFailed;
|
||||
result = kExitFailed;
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = realMain(NULL);
|
||||
result = realMain();
|
||||
}
|
||||
|
||||
CNetwork::cleanup();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\..\lib\base" /I "..\..\lib\io" /I "..\..\lib\mt" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\client" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
|
||||
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\io" /I "..\..\lib\mt" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\client" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
@@ -54,7 +54,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"../../Release/synergyc.exe"
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "synergyc - Win32 Debug"
|
||||
|
||||
@@ -70,7 +70,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\lib\base" /I "..\..\lib\io" /I "..\..\lib\mt" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\client" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\io" /I "..\..\lib\mt" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\client" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
@@ -81,7 +81,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"../../Debug/synergyc.exe" /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ synergys_LDADD = \
|
||||
$(DEPTH)/lib/io/libio.a \
|
||||
$(DEPTH)/lib/mt/libmt.a \
|
||||
$(DEPTH)/lib/base/libbase.a \
|
||||
$(DEPTH)/lib/arch/libarch.a \
|
||||
$(X_LIBS) \
|
||||
$(X_PRE_LIBS) \
|
||||
-lXtst \
|
||||
@@ -47,6 +48,8 @@ synergys_LDADD = \
|
||||
$(X_EXTRA_LIBS) \
|
||||
$(NULL)
|
||||
INCLUDES = \
|
||||
-I$(VDEPTH)/lib/common \
|
||||
-I$(VDEPTH)/lib/arch \
|
||||
-I$(VDEPTH)/lib/base \
|
||||
-I$(VDEPTH)/lib/mt \
|
||||
-I$(VDEPTH)/lib/io \
|
||||
|
||||
@@ -15,11 +15,9 @@
|
||||
#include "CServer.h"
|
||||
#include "CConfig.h"
|
||||
#include "IPrimaryScreenFactory.h"
|
||||
#include "CPlatform.h"
|
||||
#include "ProtocolTypes.h"
|
||||
#include "Version.h"
|
||||
#include "XScreen.h"
|
||||
#include "CNetwork.h"
|
||||
#include "CTCPSocketFactory.h"
|
||||
#include "XSocket.h"
|
||||
#include "CLock.h"
|
||||
@@ -27,12 +25,18 @@
|
||||
#include "CThread.h"
|
||||
#include "XThread.h"
|
||||
#include "CLog.h"
|
||||
#include "LogOutputters.h"
|
||||
#include "CArch.h"
|
||||
#include "CArchMiscWindows.h"
|
||||
#include "stdfstream.h"
|
||||
#include <cstring>
|
||||
|
||||
#define DAEMON_RUNNING(running_)
|
||||
#if WINDOWS_LIKE
|
||||
#include "CMSWindowsPrimaryScreen.h"
|
||||
#include "resource.h"
|
||||
#undef DAEMON_RUNNING
|
||||
#define DAEMON_RUNNING(running_) CArchMiscWindows::daemonRunning(running_)
|
||||
#elif UNIX_LIKE
|
||||
#include "CXWindowsPrimaryScreen.h"
|
||||
#endif
|
||||
@@ -57,37 +61,35 @@
|
||||
// program arguments
|
||||
//
|
||||
|
||||
static const char* pname = NULL;
|
||||
static bool s_backend = false;
|
||||
static bool s_restartable = true;
|
||||
static bool s_daemon = true;
|
||||
static const char* s_configFile = NULL;
|
||||
static const char* s_logFilter = NULL;
|
||||
static CString s_name;
|
||||
static CNetworkAddress s_synergyAddress;
|
||||
static CNetworkAddress s_httpAddress;
|
||||
static CConfig s_config;
|
||||
#define ARG CArgs::s_instance
|
||||
|
||||
class CArgs {
|
||||
public:
|
||||
CArgs() :
|
||||
m_pname(NULL),
|
||||
m_backend(false),
|
||||
m_restartable(true),
|
||||
m_daemon(true),
|
||||
m_configFile(NULL),
|
||||
m_logFilter(NULL)
|
||||
{ s_instance = this; }
|
||||
~CArgs() { s_instance = NULL; }
|
||||
|
||||
//
|
||||
// logging thread safety
|
||||
//
|
||||
public:
|
||||
static CArgs* s_instance;
|
||||
const char* m_pname;
|
||||
bool m_backend;
|
||||
bool m_restartable;
|
||||
bool m_daemon;
|
||||
const char* m_configFile;
|
||||
const char* m_logFilter;
|
||||
CString m_name;
|
||||
CNetworkAddress m_synergyAddress;
|
||||
CNetworkAddress m_httpAddress;
|
||||
CConfig m_config;
|
||||
};
|
||||
|
||||
static CMutex* s_logMutex = NULL;
|
||||
|
||||
static
|
||||
void
|
||||
logLock(bool lock)
|
||||
{
|
||||
assert(s_logMutex != NULL);
|
||||
|
||||
if (lock) {
|
||||
s_logMutex->lock();
|
||||
}
|
||||
else {
|
||||
s_logMutex->unlock();
|
||||
}
|
||||
}
|
||||
CArgs* CArgs::s_instance = NULL;
|
||||
|
||||
|
||||
//
|
||||
@@ -124,18 +126,8 @@ static CServer* s_server = NULL;
|
||||
|
||||
static
|
||||
int
|
||||
realMain(CMutex* mutex)
|
||||
realMain(void)
|
||||
{
|
||||
// caller should have mutex locked on entry
|
||||
|
||||
// initialize threading library
|
||||
CThread::init();
|
||||
|
||||
// make logging thread safe
|
||||
CMutex logMutex;
|
||||
s_logMutex = &logMutex;
|
||||
CLog::setLock(&logLock);
|
||||
|
||||
int result = kExitSuccess;
|
||||
do {
|
||||
bool opened = false;
|
||||
@@ -143,28 +135,28 @@ realMain(CMutex* mutex)
|
||||
try {
|
||||
// if configuration has no screens then add this system
|
||||
// as the default
|
||||
if (s_config.begin() == s_config.end()) {
|
||||
s_config.addScreen(s_name);
|
||||
if (ARG->m_config.begin() == ARG->m_config.end()) {
|
||||
ARG->m_config.addScreen(ARG->m_name);
|
||||
}
|
||||
|
||||
// set the contact address, if provided, in the config.
|
||||
// otherwise, if the config doesn't have an address, use
|
||||
// the default.
|
||||
if (s_synergyAddress.isValid()) {
|
||||
s_config.setSynergyAddress(s_synergyAddress);
|
||||
if (ARG->m_synergyAddress.isValid()) {
|
||||
ARG->m_config.setSynergyAddress(ARG->m_synergyAddress);
|
||||
}
|
||||
else if (!s_config.getSynergyAddress().isValid()) {
|
||||
s_config.setSynergyAddress(CNetworkAddress(kDefaultPort));
|
||||
else if (!ARG->m_config.getSynergyAddress().isValid()) {
|
||||
ARG->m_config.setSynergyAddress(CNetworkAddress(kDefaultPort));
|
||||
}
|
||||
|
||||
// set HTTP address if provided
|
||||
if (s_httpAddress.isValid()) {
|
||||
s_config.setHTTPAddress(s_httpAddress);
|
||||
if (ARG->m_httpAddress.isValid()) {
|
||||
ARG->m_config.setHTTPAddress(ARG->m_httpAddress);
|
||||
}
|
||||
|
||||
// create server
|
||||
s_server = new CServer(s_name);
|
||||
s_server->setConfig(s_config);
|
||||
s_server = new CServer(ARG->m_name);
|
||||
s_server->setConfig(ARG->m_config);
|
||||
s_server->setScreenFactory(new CPrimaryScreenFactory);
|
||||
s_server->setSocketFactory(new CTCPSocketFactory);
|
||||
s_server->setStreamFilterFactory(NULL);
|
||||
@@ -174,18 +166,16 @@ realMain(CMutex* mutex)
|
||||
s_server->open();
|
||||
opened = true;
|
||||
|
||||
// run server (unlocked)
|
||||
if (mutex != NULL) {
|
||||
mutex->unlock();
|
||||
}
|
||||
// run server
|
||||
DAEMON_RUNNING(true);
|
||||
locked = false;
|
||||
s_server->mainLoop();
|
||||
locked = true;
|
||||
|
||||
// clean up
|
||||
#define FINALLY do { \
|
||||
if (!locked && mutex != NULL) { \
|
||||
mutex->lock(); \
|
||||
if (!locked) { \
|
||||
DAEMON_RUNNING(false); \
|
||||
} \
|
||||
if (s_server != NULL) { \
|
||||
if (opened) { \
|
||||
@@ -199,8 +189,8 @@ realMain(CMutex* mutex)
|
||||
}
|
||||
catch (XScreenUnavailable& e) {
|
||||
// wait before retrying if we're going to retry
|
||||
if (s_restartable) {
|
||||
CThread::sleep(e.getRetryTime());
|
||||
if (ARG->m_restartable) {
|
||||
ARCH->sleep(e.getRetryTime());
|
||||
}
|
||||
else {
|
||||
result = kExitFailed;
|
||||
@@ -213,8 +203,8 @@ realMain(CMutex* mutex)
|
||||
}
|
||||
catch (...) {
|
||||
// don't try to restart and fail
|
||||
s_restartable = false;
|
||||
result = kExitFailed;
|
||||
ARG->m_restartable = false;
|
||||
result = kExitFailed;
|
||||
FINALLY;
|
||||
}
|
||||
#undef FINALLY
|
||||
@@ -224,19 +214,10 @@ realMain(CMutex* mutex)
|
||||
}
|
||||
catch (XThread&) {
|
||||
// terminated
|
||||
s_restartable = false;
|
||||
result = kExitTerminated;
|
||||
ARG->m_restartable = false;
|
||||
result = kExitTerminated;
|
||||
}
|
||||
catch (...) {
|
||||
CLog::setLock(NULL);
|
||||
s_logMutex = NULL;
|
||||
throw;
|
||||
}
|
||||
} while (s_restartable);
|
||||
|
||||
// clean up
|
||||
CLog::setLock(NULL);
|
||||
s_logMutex = NULL;
|
||||
} while (ARG->m_restartable);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -257,7 +238,7 @@ version()
|
||||
LOG((CLOG_PRINT
|
||||
"%s %s, protocol version %d.%d\n"
|
||||
"%s",
|
||||
pname,
|
||||
ARG->m_pname,
|
||||
kVersion,
|
||||
kProtocolMajorVersion,
|
||||
kProtocolMinorVersion,
|
||||
@@ -287,8 +268,6 @@ help()
|
||||
|
||||
#endif
|
||||
|
||||
CPlatform platform;
|
||||
|
||||
LOG((CLOG_PRINT
|
||||
"Usage: %s"
|
||||
" [--address <address>]"
|
||||
@@ -333,13 +312,13 @@ PLATFORM_EXTRA
|
||||
"\n"
|
||||
"Where log messages go depends on the platform and whether or not the\n"
|
||||
"server is running as a daemon.",
|
||||
pname,
|
||||
ARG->m_pname,
|
||||
kDefaultPort,
|
||||
platform.addPathComponent(
|
||||
platform.getUserDirectory(),
|
||||
ARCH->concatPath(
|
||||
ARCH->getUserDirectory(),
|
||||
USR_CONFIG_NAME).c_str(),
|
||||
platform.addPathComponent(
|
||||
platform.getSystemDirectory(),
|
||||
ARCH->concatPath(
|
||||
ARCH->getSystemDirectory(),
|
||||
SYS_CONFIG_NAME).c_str()));
|
||||
}
|
||||
|
||||
@@ -354,7 +333,7 @@ isArg(int argi, int argc, const char** argv,
|
||||
// match. check args left.
|
||||
if (argi + minRequiredParameters >= argc) {
|
||||
LOG((CLOG_PRINT "%s: missing arguments for `%s'" BYE,
|
||||
pname, argv[argi], pname));
|
||||
ARG->m_pname, argv[argi], ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
return true;
|
||||
@@ -368,32 +347,30 @@ static
|
||||
void
|
||||
parse(int argc, const char** argv)
|
||||
{
|
||||
assert(pname != NULL);
|
||||
assert(argv != NULL);
|
||||
assert(argc >= 1);
|
||||
assert(ARG->m_pname != NULL);
|
||||
assert(argv != NULL);
|
||||
assert(argc >= 1);
|
||||
|
||||
// set defaults
|
||||
char hostname[256];
|
||||
if (CNetwork::gethostname(hostname, sizeof(hostname)) != CNetwork::Error) {
|
||||
s_name = hostname;
|
||||
}
|
||||
ARG->m_name = ARCH->getHostName();
|
||||
|
||||
// parse options
|
||||
int i;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (isArg(i, argc, argv, "-d", "--debug", 1)) {
|
||||
// change logging level
|
||||
s_logFilter = argv[++i];
|
||||
ARG->m_logFilter = argv[++i];
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-a", "--address", 1)) {
|
||||
// save listen address
|
||||
try {
|
||||
s_synergyAddress = CNetworkAddress(argv[i + 1], kDefaultPort);
|
||||
ARG->m_synergyAddress = CNetworkAddress(argv[i + 1],
|
||||
kDefaultPort);
|
||||
}
|
||||
catch (XSocketAddress& e) {
|
||||
LOG((CLOG_PRINT "%s: %s" BYE,
|
||||
pname, e.what(), pname));
|
||||
ARG->m_pname, e.what(), ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
++i;
|
||||
@@ -402,11 +379,12 @@ parse(int argc, const char** argv)
|
||||
else if (isArg(i, argc, argv, NULL, "--http", 1)) {
|
||||
// save listen address
|
||||
try {
|
||||
s_httpAddress = CNetworkAddress(argv[i + 1], kDefaultPort + 1);
|
||||
ARG->m_httpAddress = CNetworkAddress(argv[i + 1],
|
||||
kDefaultPort + 1);
|
||||
}
|
||||
catch (XSocketAddress& e) {
|
||||
LOG((CLOG_PRINT "%s: %s" BYE,
|
||||
pname, e.what(), pname));
|
||||
ARG->m_pname, e.what(), ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
++i;
|
||||
@@ -414,36 +392,36 @@ parse(int argc, const char** argv)
|
||||
|
||||
else if (isArg(i, argc, argv, "-n", "--name", 1)) {
|
||||
// save screen name
|
||||
s_name = argv[++i];
|
||||
ARG->m_name = argv[++i];
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-c", "--config", 1)) {
|
||||
// save configuration file path
|
||||
s_configFile = argv[++i];
|
||||
ARG->m_configFile = argv[++i];
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-f", "--no-daemon")) {
|
||||
// not a daemon
|
||||
s_daemon = false;
|
||||
ARG->m_daemon = false;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, NULL, "--daemon")) {
|
||||
// daemonize
|
||||
s_daemon = true;
|
||||
ARG->m_daemon = true;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-1", "--no-restart")) {
|
||||
// don't try to restart
|
||||
s_restartable = false;
|
||||
ARG->m_restartable = false;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, NULL, "--restart")) {
|
||||
// try to restart
|
||||
s_restartable = true;
|
||||
ARG->m_restartable = true;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-z", NULL)) {
|
||||
s_backend = true;
|
||||
ARG->m_backend = true;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-h", "--help")) {
|
||||
@@ -464,7 +442,7 @@ parse(int argc, const char** argv)
|
||||
|
||||
else if (argv[i][0] == '-') {
|
||||
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
||||
pname, argv[i], pname));
|
||||
ARG->m_pname, argv[i], ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
|
||||
@@ -477,30 +455,30 @@ parse(int argc, const char** argv)
|
||||
// no non-option arguments are allowed
|
||||
if (i != argc) {
|
||||
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
||||
pname, argv[i], pname));
|
||||
ARG->m_pname, argv[i], ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
|
||||
// increase default filter level for daemon. the user must
|
||||
// explicitly request another level for a daemon.
|
||||
if (s_daemon && s_logFilter == NULL) {
|
||||
if (ARG->m_daemon && ARG->m_logFilter == NULL) {
|
||||
#if WINDOWS_LIKE
|
||||
if (CPlatform::isWindows95Family()) {
|
||||
if (CArchMiscWindows::isWindows95Family()) {
|
||||
// windows 95 has no place for logging so avoid showing
|
||||
// the log console window.
|
||||
s_logFilter = "FATAL";
|
||||
ARG->m_logFilter = "FATAL";
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
s_logFilter = "NOTE";
|
||||
ARG->m_logFilter = "NOTE";
|
||||
}
|
||||
}
|
||||
|
||||
// set log filter
|
||||
if (!CLog::setFilter(s_logFilter)) {
|
||||
if (!CLOG->setFilter(ARG->m_logFilter)) {
|
||||
LOG((CLOG_PRINT "%s: unrecognized log level `%s'" BYE,
|
||||
pname, s_logFilter, pname));
|
||||
ARG->m_pname, ARG->m_logFilter, ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
}
|
||||
@@ -518,14 +496,14 @@ loadConfig(const char* pathname, bool require)
|
||||
if (!configStream) {
|
||||
throw XConfigRead("cannot open file");
|
||||
}
|
||||
configStream >> s_config;
|
||||
configStream >> ARG->m_config;
|
||||
LOG((CLOG_DEBUG "configuration read successfully"));
|
||||
return true;
|
||||
}
|
||||
catch (XConfigRead& e) {
|
||||
if (require) {
|
||||
LOG((CLOG_PRINT "%s: cannot read configuration '%s': %s",
|
||||
pname, pathname, e.what()));
|
||||
ARG->m_pname, pathname, e.what()));
|
||||
bye(kExitConfig);
|
||||
}
|
||||
else {
|
||||
@@ -541,36 +519,46 @@ void
|
||||
loadConfig()
|
||||
{
|
||||
// load the config file, if specified
|
||||
if (s_configFile != NULL) {
|
||||
if (ARG->m_configFile != NULL) {
|
||||
// require the user specified file to load correctly
|
||||
loadConfig(s_configFile, true);
|
||||
loadConfig(ARG->m_configFile, true);
|
||||
}
|
||||
|
||||
// load the default configuration if no explicit file given
|
||||
else {
|
||||
// get the user's home directory. use the effective user id
|
||||
// so a user can't get a setuid root program to load his file.
|
||||
CPlatform platform;
|
||||
bool loaded = false;
|
||||
CString path = platform.getUserDirectory();
|
||||
CString path = ARCH->getUserDirectory();
|
||||
if (!path.empty()) {
|
||||
// complete path
|
||||
path = platform.addPathComponent(path, USR_CONFIG_NAME);
|
||||
path = ARCH->concatPath(path, USR_CONFIG_NAME);
|
||||
|
||||
// now try loading the user's configuration
|
||||
loaded = loadConfig(path.c_str(), false);
|
||||
}
|
||||
if (!loaded) {
|
||||
// try the system-wide config file
|
||||
path = platform.getSystemDirectory();
|
||||
path = ARCH->getSystemDirectory();
|
||||
if (!path.empty()) {
|
||||
path = platform.addPathComponent(path, SYS_CONFIG_NAME);
|
||||
path = ARCH->concatPath(path, SYS_CONFIG_NAME);
|
||||
loadConfig(path.c_str(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
useSystemLog()
|
||||
{
|
||||
// redirect log messages
|
||||
ILogOutputter* logger = new CSystemLogOutputter;
|
||||
logger->open(DAEMON_NAME);
|
||||
CLOG->insert(new CStopLogOutputter);
|
||||
CLOG->insert(logger);
|
||||
}
|
||||
|
||||
//
|
||||
// platform dependent entry points
|
||||
//
|
||||
@@ -581,24 +569,41 @@ loadConfig()
|
||||
|
||||
static bool s_hasImportantLogMessages = false;
|
||||
|
||||
static
|
||||
//
|
||||
// CMessageBoxOutputter
|
||||
//
|
||||
// This class writes severe log messages to a message box
|
||||
//
|
||||
|
||||
class CMessageBoxOutputter : public ILogOutputter {
|
||||
public:
|
||||
CMessageBoxOutputter() { }
|
||||
virtual ~CMessageBoxOutputter() { }
|
||||
|
||||
// ILogOutputter overrides
|
||||
virtual void open(const char*) { }
|
||||
virtual void close() { }
|
||||
virtual bool write(ELevel level, const char* message);
|
||||
virtual const char* getNewline() const { return ""; }
|
||||
};
|
||||
|
||||
bool
|
||||
logMessageBox(int priority, const char* msg)
|
||||
CMessageBoxOutputter::write(ELevel level, const char* message)
|
||||
{
|
||||
// note any important messages the user may need to know about
|
||||
if (priority <= CLog::kWARNING) {
|
||||
if (level <= CLog::kWARNING) {
|
||||
s_hasImportantLogMessages = true;
|
||||
}
|
||||
|
||||
// FATAL and PRINT messages get a dialog box if not running as
|
||||
// backend. if we're running as a backend the user will have
|
||||
// a chance to see the messages when we exit.
|
||||
if (!s_backend && priority <= CLog::kFATAL) {
|
||||
MessageBox(NULL, msg, pname, MB_OK | MB_ICONWARNING);
|
||||
return true;
|
||||
if (!ARG->m_backend && level <= CLog::kFATAL) {
|
||||
MessageBox(NULL, message, ARG->m_pname, MB_OK | MB_ICONWARNING);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -606,7 +611,7 @@ static
|
||||
void
|
||||
byeThrow(int x)
|
||||
{
|
||||
throw CWin32Platform::CDaemonFailed(x);
|
||||
CArchMiscWindows::daemonFailed(x);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -618,10 +623,9 @@ daemonStop(void)
|
||||
|
||||
static
|
||||
int
|
||||
daemonStartup(IPlatform* iplatform, int argc, const char** argv)
|
||||
daemonStartup(int argc, const char** argv)
|
||||
{
|
||||
// get platform pointer
|
||||
CWin32Platform* platform = static_cast<CWin32Platform*>(iplatform);
|
||||
useSystemLog();
|
||||
|
||||
// catch errors that would normally exit
|
||||
bye = &byeThrow;
|
||||
@@ -630,38 +634,38 @@ daemonStartup(IPlatform* iplatform, int argc, const char** argv)
|
||||
parse(argc, argv);
|
||||
|
||||
// cannot run as backend if running as a service
|
||||
s_backend = false;
|
||||
ARG->m_backend = false;
|
||||
|
||||
// load configuration
|
||||
loadConfig();
|
||||
|
||||
// run as a service
|
||||
return platform->runDaemon(realMain, daemonStop);
|
||||
return CArchMiscWindows::runDaemon(realMain, daemonStop);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
daemonStartup95(IPlatform*, int, const char**)
|
||||
daemonStartup95(int, const char**)
|
||||
{
|
||||
return realMain(NULL);
|
||||
useSystemLog();
|
||||
return realMain();
|
||||
}
|
||||
|
||||
int WINAPI
|
||||
WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||
{
|
||||
CPlatform platform;
|
||||
CArch arch;
|
||||
CLOG;
|
||||
CArgs args;
|
||||
|
||||
// save instance
|
||||
CMSWindowsScreen::init(instance);
|
||||
|
||||
// get program name
|
||||
pname = platform.getBasename(__argv[0]);
|
||||
|
||||
// initialize network library
|
||||
CNetwork::init();
|
||||
ARG->m_pname = ARCH->getBasename(__argv[0]);
|
||||
|
||||
// send PRINT and FATAL output to a message box
|
||||
CLog::setOutputter(&logMessageBox);
|
||||
CLOG->insert(new CMessageBoxOutputter);
|
||||
|
||||
// windows NT family starts services using no command line options.
|
||||
// since i'm not sure how to tell the difference between that and
|
||||
@@ -669,13 +673,14 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||
// arguments and we're on NT then we're being invoked as a service.
|
||||
// users on NT can use `--daemon' or `--no-daemon' to force us out
|
||||
// of the service code path.
|
||||
if (__argc <= 1 && !CWin32Platform::isWindows95Family()) {
|
||||
int result = platform.daemonize(DAEMON_NAME, &daemonStartup);
|
||||
if (result == -1) {
|
||||
LOG((CLOG_CRIT "failed to start as a service" BYE, pname));
|
||||
if (__argc <= 1 && !CArchMiscWindows::isWindows95Family()) {
|
||||
try {
|
||||
return ARCH->daemonize(DAEMON_NAME, &daemonStartup);
|
||||
}
|
||||
catch (XArchDaemon&) {
|
||||
LOG((CLOG_CRIT "failed to start as a service" BYE, ARG->m_pname));
|
||||
return kExitFailed;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// parse command line
|
||||
@@ -686,38 +691,36 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||
|
||||
// daemonize if requested
|
||||
int result;
|
||||
if (s_daemon) {
|
||||
// redirect log messages
|
||||
platform.installDaemonLogger(DAEMON_NAME);
|
||||
|
||||
if (ARG->m_daemon) {
|
||||
// start as a daemon
|
||||
if (CWin32Platform::isWindows95Family()) {
|
||||
result = platform.daemonize(DAEMON_NAME, &daemonStartup95);
|
||||
if (result == -1) {
|
||||
LOG((CLOG_CRIT "failed to start as a service" BYE, pname));
|
||||
if (CArchMiscWindows::isWindows95Family()) {
|
||||
try {
|
||||
result = ARCH->daemonize(DAEMON_NAME, &daemonStartup95);
|
||||
}
|
||||
catch (XArchDaemon&) {
|
||||
LOG((CLOG_CRIT "failed to start as a service" BYE, ARG->m_pname));
|
||||
result = kExitFailed;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// cannot start a service from the command line so just
|
||||
// run normally (except with log messages redirected).
|
||||
result = realMain(NULL);
|
||||
useSystemLog();
|
||||
result = realMain();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// run
|
||||
result = realMain(NULL);
|
||||
result = realMain();
|
||||
}
|
||||
|
||||
CNetwork::cleanup();
|
||||
|
||||
// let user examine any messages if we're running as a backend
|
||||
// by putting up a dialog box before exiting.
|
||||
if (s_backend && s_hasImportantLogMessages) {
|
||||
if (ARG->m_backend && s_hasImportantLogMessages) {
|
||||
char msg[1024];
|
||||
msg[0] = '\0';
|
||||
LoadString(instance, IDS_FAILED, msg, sizeof(msg) / sizeof(msg[0]));
|
||||
MessageBox(NULL, msg, pname, MB_OK | MB_ICONWARNING);
|
||||
MessageBox(NULL, msg, ARG->m_pname, MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -727,21 +730,21 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||
|
||||
static
|
||||
int
|
||||
daemonStartup(IPlatform*, int, const char**)
|
||||
daemonStartup(int, const char**)
|
||||
{
|
||||
return realMain(NULL);
|
||||
useSystemLog();
|
||||
return realMain();
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
CPlatform platform;
|
||||
CArch arch;
|
||||
CLOG;
|
||||
CArgs args;
|
||||
|
||||
// get program name
|
||||
pname = platform.getBasename(argv[0]);
|
||||
|
||||
// initialize network library
|
||||
CNetwork::init();
|
||||
ARG->m_pname = ARCH->getBasename(argv[0]);
|
||||
|
||||
// parse command line
|
||||
parse(argc, const_cast<const char**>(argv));
|
||||
@@ -751,19 +754,19 @@ main(int argc, char** argv)
|
||||
|
||||
// daemonize if requested
|
||||
int result;
|
||||
if (s_daemon) {
|
||||
result = platform.daemonize(DAEMON_NAME, &daemonStartup);
|
||||
if (result == -1) {
|
||||
if (ARG->m_daemon) {
|
||||
try {
|
||||
result = ARCH->daemonize(DAEMON_NAME, &daemonStartup);
|
||||
}
|
||||
catch (XArchDaemon&) {
|
||||
LOG((CLOG_CRIT "failed to daemonize"));
|
||||
return kExitFailed;
|
||||
result = kExitFailed;
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = realMain(NULL);
|
||||
result = realMain();
|
||||
}
|
||||
|
||||
CNetwork::cleanup();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\http" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
|
||||
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\http" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
@@ -70,7 +70,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\http" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\http" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
|
||||
Reference in New Issue
Block a user