1 /*
2  * synergy -- mouse and keyboard sharing utility
3  * Copyright (C) 2012-2016 Symless Ltd.
4  * Copyright (C) 2002 Chris Schoeneman
5  *
6  * This package is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * found in the file LICENSE that should have accompanied this file.
9  *
10  * This package is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #pragma once
20 
21 #include "ipc/IpcClient.h"
22 #include "synergy/IApp.h"
23 #include "base/String.h"
24 #include "base/Log.h"
25 #include "base/EventQueue.h"
26 #include "common/common.h"
27 
28 #if SYSAPI_WIN32
29 #include "synergy/win32/AppUtilWindows.h"
30 #elif SYSAPI_UNIX
31 #include "synergy/unix/AppUtilUnix.h"
32 #endif
33 
34 class IArchTaskBarReceiver;
35 class BufferedLogOutputter;
36 class ILogOutputter;
37 class FileLogOutputter;
38 namespace synergy { class Screen; }
39 class IEventQueue;
40 class SocketMultiplexer;
41 
42 typedef IArchTaskBarReceiver* (*CreateTaskBarReceiverFunc)(const BufferedLogOutputter*, IEventQueue* events);
43 
44 class App : public IApp {
45 public:
46     App(IEventQueue* events, CreateTaskBarReceiverFunc createTaskBarReceiver, lib::synergy::ArgsBase* args);
47     App(App const &) =delete;
48     App(App &&) =delete;
49     virtual ~App();
50 
51     App& operator=(App const &) =delete;
52     App& operator=(App &&) =delete;
53 
54     // Returns args that are common between server and client.
argsBase()55     lib::synergy::ArgsBase& argsBase() const { return *m_args; }
56 
57     // Prints the current compiled version.
58     virtual void version();
59 
60     // Prints help specific to client or server.
61     virtual void help() = 0;
62 
63     // Parse command line arguments.
64     virtual void parseArgs(int argc, const char* const* argv) = 0;
65 
66     int run(int argc, char** argv);
67 
68     int daemonMainLoop(int, const char**);
69 
70     virtual void loadConfig() = 0;
71     virtual bool loadConfig(const String& pathname) = 0;
72 
73     // A description of the daemon (used only on Windows).
74     virtual const char* daemonInfo() const = 0;
75 
76     // Function pointer for function to exit immediately.
77     // TODO: this is old C code - use inheritance to normalize
78     void (*m_bye)(int);
79 
instance()80     static App& instance() { assert(s_instance != nullptr); return *s_instance; }
81 
82     // If --log was specified in args, then add a file logger.
83     void setupFileLogging();
84 
85     // If messages will be hidden (to improve performance), warn user.
86     void loggingFilterWarning();
87 
88     // Parses args, sets up file logging, and loads the config.
89     void initApp(int argc, const char** argv);
90 
91     // HACK: accept non-const, but make it const anyway
initApp(int argc,char ** argv)92     void initApp(int argc, char** argv) { initApp(argc, (const char**)argv); }
93 
appUtil()94     ARCH_APP_UTIL& appUtil() { return m_appUtil; }
95 
taskBarReceiver()96     virtual IArchTaskBarReceiver* taskBarReceiver() const  { return m_taskBarReceiver; }
97 
setByeFunc(void (* bye)(int))98     virtual void setByeFunc(void(*bye)(int)) { m_bye = bye; }
bye(int error)99     virtual void bye(int error) { m_bye(error); }
100 
getEvents()101     virtual IEventQueue* getEvents() const { return m_events; }
102 
setSocketMultiplexer(SocketMultiplexer * sm)103     void                setSocketMultiplexer(SocketMultiplexer* sm) { m_socketMultiplexer = sm; }
getSocketMultiplexer()104     SocketMultiplexer*    getSocketMultiplexer() const { return m_socketMultiplexer; }
105 
setEvents(EventQueue & events)106     void                setEvents(EventQueue& events) { m_events = &events; }
107 
108 private:
109     void                handleIpcMessage(const Event&, void*);
110 
111 protected:
112     void                initIpcClient();
113     void                cleanupIpcClient();
114     void                runEventsLoop(void*);
115 
116     IArchTaskBarReceiver* m_taskBarReceiver;
117     bool m_suspended;
118     IEventQueue*        m_events;
119 
120 private:
121     lib::synergy::ArgsBase* m_args;
122     static App* s_instance;
123     FileLogOutputter* m_fileLog;
124     CreateTaskBarReceiverFunc m_createTaskBarReceiver;
125     ARCH_APP_UTIL m_appUtil;
126     IpcClient*            m_ipcClient;
127     SocketMultiplexer*    m_socketMultiplexer;
128 };
129 
130 class MinimalApp : public App {
131 public:
132     MinimalApp();
133     virtual ~MinimalApp();
134 
135     // IApp overrides
136     virtual int            standardStartup(int argc, char** argv);
137     virtual int            runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup);
138     virtual void        startNode();
139     virtual int            mainLoop();
140     virtual int            foregroundStartup(int argc, char** argv);
141     virtual synergy::Screen*
142                         createScreen();
143     virtual void        loadConfig();
144     virtual bool        loadConfig(const String& pathname);
145     virtual const char*    daemonInfo() const;
146     virtual const char* daemonName() const;
147     virtual void        parseArgs(int argc, const char* const* argv);
148 
149 private:
150     Arch                m_arch;
151     Log                    m_log;
152     EventQueue            m_events;
153 };
154 
155 #if WINAPI_MSWINDOWS
156 #define DAEMON_RUNNING(running_) ArchMiscWindows::daemonRunning(running_)
157 #else
158 #define DAEMON_RUNNING(running_)
159 #endif
160 
161 #define HELP_COMMON_INFO_1 \
162     "  -d, --debug <level>      filter out log messages with priority below level.\n" \
163     "                             level may be: FATAL, ERROR, WARNING, NOTE, INFO,\n" \
164     "                             DEBUG, DEBUG1, DEBUG2.\n" \
165     "  -n, --name <screen-name> use screen-name instead the hostname to identify\n" \
166     "                             this screen in the configuration.\n" \
167     "  -1, --no-restart         do not try to restart on failure.\n" \
168     "*     --restart            restart the server automatically if it fails.\n" \
169     "  -l  --log <file>         write log messages to file.\n" \
170     "      --no-tray            disable the system tray icon.\n" \
171     "      --enable-drag-drop   enable file drag & drop.\n" \
172     "      --enable-crypto      enable the crypto (ssl) plugin.\n" \
173     "      --tls-cert           specify the path to the tls certificate file.\n"
174 
175 #define HELP_COMMON_INFO_2 \
176     "  -h, --help               display this help and exit.\n" \
177     "      --version            display version information and exit.\n"
178 
179 #define HELP_COMMON_ARGS \
180     " [--name <screen-name>]" \
181     " [--restart|--no-restart]" \
182     " [--debug <level>]"
183 
184 // system args (windows/unix)
185 #if SYSAPI_UNIX
186 
187 // unix daemon mode args
188 #  define HELP_SYS_ARGS \
189     " [--daemon|--no-daemon]"
190 #  define HELP_SYS_INFO \
191     "  -f, --no-daemon          run in the foreground.\n"    \
192     "*     --daemon             run as a daemon.\n"
193 
194 #elif SYSAPI_WIN32
195 
196 // windows args
197 #  define HELP_SYS_ARGS \
198     " [--service <action>] [--relaunch] [--exit-pause]"
199 #  define HELP_SYS_INFO \
200     "      --service <action>   manage the windows service, valid options are:\n" \
201     "                             install/uninstall/start/stop\n" \
202     "      --relaunch           persistently relaunches process in current user \n" \
203     "                             session (useful for vista and upward).\n" \
204     "      --exit-pause         wait for key press on exit, can be useful for\n" \
205     "                             reading error messages that occur on exit.\n"
206 #endif
207