diff --git a/README b/README index 985e34cd..2993e486 100644 --- a/README +++ b/README @@ -169,9 +169,9 @@ recommended that you run it in the foreground until you've sorted out your configuration. on the Windows NT family you cannot run a service directly. -instead you install the service then control it via the Services -control panel. on the Windows 95 family, you can use the -`--daemon' command line option to start synergy in the background +instead you install the service then run or stop it via the +Services control panel. on the Windows 95 family, you can use +the `--daemon' command line option to start synergy as a service or you can install the service and restart your computer. in the text below, except where noted, synergy refers to the @@ -201,7 +201,7 @@ windows: directory (e.g. C:\WINNT) and call it "synergy.sgc". the server will automatically find this file. however, you can also use the --config command line option and specify an - absolute path to the file. remember that this file must be + *absolute* path to the file. remember that this file must be accessible when the system starts up, before network shares are mapped. diff --git a/client/client.cpp b/client/client.cpp index ea23b151..3b1418b8 100644 --- a/client/client.cpp +++ b/client/client.cpp @@ -485,24 +485,10 @@ daemonStartup(IPlatform* iplatform, int argc, const char** argv) } static -bool -logDiscard(int, const char*) +int +daemonStartup95(IPlatform*, int, const char**) { - return true; -} - -static bool s_die = false; - -static -void -checkParse(int e) -{ - // anything over 1 means invalid args. 1 means missing args. - // 0 means graceful exit. we plan to exit for anything but - // 1 (missing args); the service control manager may supply - // the missing arguments so we don't exit in that case. - s_die = (e != 1); - throw s_die; + return restartableMain(); } int WINAPI @@ -519,42 +505,26 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int) // initialize network library CNetwork::init(); - // parse command line without reporting errors but recording if - // the app would've exited. this is too avoid showing a dialog - // box if we're being started as a service because we shouldn't - // take too long to startup in that case. this mostly works but - // will choke if the service control manager passes --install - // or --uninstall (but that's unlikely). - CLog::setOutputter(&logDiscard); - bye = &checkParse; - try { - parse(__argc, const_cast(__argv)); - } - catch (...) { - // ignore - } - // send PRINT and FATAL output to a message box CLog::setOutputter(&logMessageBox); - // if we're not starting as an NT service then reparse the command - // line normally. - if (s_die || __argc > 1 || s_install || s_uninstall || - CWin32Platform::isWindows95Family()) { - - // exit on bye - bye = &exit; - - // reparse - parse(__argc, const_cast(__argv)); + // windows NT family starts services using no command line options. + // since i'm not sure how to tell the difference between that and + // a user providing no options we'll assume that if there are no + // 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)); + return 16; + } + return result; } - // if no arguments were provided then we're hopefully starting as - // a service. we'll parse the command line passed in when the - // service control manager calls us back. - else { - // do nothing - } + // parse command line + parse(__argc, const_cast(__argv)); // install/uninstall if (s_install) { @@ -609,24 +579,25 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int) // daemonize if requested int result; - if (__argc <= 1) { + if (s_daemon) { + // redirect log messages + platform.installDaemonLogger(DAEMON_NAME); + + // start as a daemon if (CWin32Platform::isWindows95Family()) { - result = -1; + result = platform.daemonize(DAEMON_NAME, &daemonStartup95); + if (result == -1) { + log((CLOG_CRIT "failed to start as a service" BYE, pname)); + return 16; + } } else { - result = platform.daemonize(DAEMON_NAME, &daemonStartup); - } - if (result == -1) { - log((CLOG_CRIT "failed to start as a service" BYE, pname)); - return 16; + // cannot start a service from the command line so just + // run normally (except with log messages redirected). + result = restartableMain(); } } else { - // if a daemon then redirect log - if (s_daemon) { - platform.installDaemonLogger(__argv[0]); - } - // run result = restartableMain(); } diff --git a/server/server.cpp b/server/server.cpp index 690637f1..dbbf7e0f 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -599,24 +599,10 @@ daemonStartup(IPlatform* iplatform, int argc, const char** argv) } static -bool -logDiscard(int, const char*) +int +daemonStartup95(IPlatform*, int, const char**) { - return true; -} - -static bool s_die = false; - -static -void -checkParse(int e) -{ - // anything over 1 means invalid args. 1 means missing args. - // 0 means graceful exit. we plan to exit for anything but - // 1 (missing args); the service control manager may supply - // the missing arguments so we don't exit in that case. - s_die = (e != 1); - throw s_die; + return restartableMain(); } int WINAPI @@ -633,42 +619,26 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int) // initialize network library CNetwork::init(); - // parse command line without reporting errors but recording if - // the app would've exited. this is too avoid showing a dialog - // box if we're being started as a service because we shouldn't - // take to long to startup as a service. this mostly works but - // will choke if the service control manager passes --install - // or --uninstall (but that's unlikely). - CLog::setOutputter(&logDiscard); - bye = &checkParse; - try { - parse(__argc, const_cast(__argv)); - } - catch (...) { - // ignore - } - // send PRINT and FATAL output to a message box CLog::setOutputter(&logMessageBox); - // if we're not starting as an NT service then reparse the command - // line normally. - if (s_die || __argc > 1 || s_install || s_uninstall || - CWin32Platform::isWindows95Family()) { - - // exit on bye - bye = &exit; - - // reparse - parse(__argc, const_cast(__argv)); + // windows NT family starts services using no command line options. + // since i'm not sure how to tell the difference between that and + // a user providing no options we'll assume that if there are no + // 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)); + return 16; + } + return result; } - // if no arguments were provided then we're hopefully starting as - // a service. we'll parse the command line passed in when the - // service control manager calls us back. - else { - // do nothing - } + // parse command line + parse(__argc, const_cast(__argv)); // install/uninstall if (s_install) { @@ -731,23 +701,24 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int) // daemonize if requested int result; if (s_daemon) { + // redirect log messages + platform.installDaemonLogger(DAEMON_NAME); + + // start as a daemon if (CWin32Platform::isWindows95Family()) { - result = -1; + result = platform.daemonize(DAEMON_NAME, &daemonStartup95); + if (result == -1) { + log((CLOG_CRIT "failed to start as a service" BYE, pname)); + return 16; + } } else { - result = platform.daemonize(DAEMON_NAME, &daemonStartup); - } - if (result == -1) { - log((CLOG_CRIT "failed to start as a service" BYE, pname)); - return 16; + // cannot start a service from the command line so just + // run normally (except with log messages redirected). + result = restartableMain(); } } else { - // if a daemon then redirect log - if (s_daemon) { - platform.installDaemonLogger(__argv[0]); - } - // run result = restartableMain(); }