66#include < string.h>
77
88#include < iostream>
9+ #include < sstream>
910
1011#include < errno.h>
1112#include < sys/time.h>
1415#include < assert.h>
1516#include < getopt.h>
1617
18+ #include < libconfig.h++>
19+
1720#include " Exception.hh"
1821#include " UFile.hh"
1922#include " DMXResource.hh"
2326
2427extern bool terminate;
2528
29+ struct ConfigData
30+ {
31+ uint32_t screen = 0 ;
32+ bool relative = false ;
33+ std::string password;
34+ int port = 0 ;
35+ bool unsafe = false ;
36+ bool fullscreen = false ;
37+ bool multiThreaded = false ;
38+ int frameRate = 15 ;
39+ std::string configFile;
40+ };
41+
42+ void GetConfigData (int argc, char *argv[], ConfigData& configData);
43+ void GetCommandLineConfigData (int argc, char *argv[], ConfigData& configData);
44+ bool ReadConfigFile (const char *programName, const std::string& configFile, ConfigData& configData);
45+ bool TryReadConfigFile (libconfig::Config& config, const std::string& file);
2646void usage (const char *programName);
2747
2848void sig_handler (int signo)
@@ -36,90 +56,31 @@ int main(int argc, char *argv[])
3656
3757 try
3858 {
39- uint32_t screen = 0 ;
40- bool relativeMode = 0 ;
41- std::string password;
42- int port = 0 ;
43- bool safeMode = true ;
44- bool bandwidthMode = true ;
45- bool multiThreaded = false ;
46- int frameRate = 15 ;
47-
48- static struct option long_options[] = {
49- { " relative" , no_argument, nullptr , ' r' },
50- { " absolute" , no_argument, nullptr , ' a' },
51- { " unsafe" , no_argument, nullptr , ' u' },
52- { " fullscreen" , no_argument, nullptr , ' f' },
53- { " multi-threaded" , no_argument, nullptr , ' m' },
54- { " password" , required_argument, nullptr , ' P' },
55- { " port" , required_argument, nullptr , ' p' },
56- { " screen" , required_argument, nullptr , ' s' },
57- { " frame-rate" , required_argument, nullptr , ' t' },
58- { " help" , no_argument, nullptr , CHAR_MIN - 2 },
59- { nullptr , 0 , nullptr , 0 }
60- };
61-
62- int c;
63- while (-1 != (c = getopt_long (argc, argv, " abfmP:p:rs:t:u" , long_options, nullptr ))) {
64- switch (c) {
65- case ' a' :
66- relativeMode = false ;
67- break ;
68-
69- case ' r' :
70- relativeMode = true ;
71- break ;
72-
73- case ' u' :
74- safeMode = false ;
75- break ;
76-
77- case ' f' :
78- bandwidthMode = false ;
79- break ;
80-
81- case ' m' :
82- multiThreaded = true ;
83- break ;
84-
85- case ' P' :
86- password = optarg;
87- break ;
88-
89- case ' p' :
90- port = atoi (optarg);
91- break ;
92-
93- case ' s' :
94- screen = atoi (optarg);
95- break ;
96-
97- case ' t' :
98- frameRate = atoi (optarg);
99- break ;
100-
101- case CHAR_MIN - 2 :
102- throw HelpException ();
103-
104- default :
105- throw ParamException ();
106- }
107- }
108-
109- if (optind < argc) {
110- std::cerr << " Unknown parameter: " << argv[optind] << ' \n ' ;
111- throw ParamException ();
112- }
113-
11459 if (signal (SIGINT, sig_handler) == SIG_ERR) {
11560 throw Exception ( " error setting sighandler" );
11661 }
11762 if (signal (SIGTERM, sig_handler) == SIG_ERR) {
11863 throw Exception (" error setting sighandler" );
11964 }
12065
121- DMXVNCServer vncServer (BPP, frameRate);
122- vncServer.Run ( argc, argv, port, password, screen, relativeMode, safeMode, bandwidthMode, multiThreaded);
66+ ConfigData configData;
67+ GetConfigData (argc, argv, configData);
68+
69+ std::cerr <<
70+ " Running vnc server with the following settings\n "
71+ " frame-rate = " << configData.frameRate << " \n "
72+ " fullscreen = " << (configData.fullscreen ? " true" : " false" ) << " \n "
73+ " multi-threaded = " << (configData.multiThreaded ? " true" : " false" ) << " \n "
74+ " password = " << (configData.password .length () ? " ***" : " " ) << " \n "
75+ " port = " << configData.port << " \n "
76+ " relative = " << (configData.relative ? " true" : " false" ) << " \n "
77+ " screen = " << configData.screen << " \n "
78+ " unsafe = " << (configData.unsafe ? " true" : " false" ) << " \n " ;
79+
80+ DMXVNCServer vncServer (BPP, configData.frameRate );
81+ vncServer.Run (argc, argv, configData.port , configData.password , configData.screen ,
82+ configData.relative , !configData.unsafe , !configData.fullscreen ,
83+ configData.multiThreaded );
12384 }
12485 catch (HelpException) {
12586 usage (argv[0 ]);
@@ -129,19 +90,165 @@ int main(int argc, char *argv[])
12990 ret = EXIT_FAILURE;
13091 }
13192 catch (Exception& e) {
132- std::cerr << " Exception caught : " << e.what () << " \n " ;
93+ std::cerr << " Exception: " << e.what () << " \n " ;
13394 ret = EXIT_FAILURE;
13495 }
13596
13697 return ret;
13798}
13899
100+ void GetConfigData (int argc, char *argv[], ConfigData& configData)
101+ {
102+ ConfigData configDataTemp;
103+ GetCommandLineConfigData (argc, argv, configDataTemp);
104+ if (ReadConfigFile (argv[0 ], configDataTemp.configFile , configData))
105+ GetCommandLineConfigData (argc, argv, configData);
106+ else
107+ configData = configDataTemp;
108+ }
109+
110+ void GetCommandLineConfigData (int argc, char *argv[], ConfigData& configData)
111+ {
112+ static struct option long_options[] = {
113+ { " relative" , no_argument, nullptr , ' r' },
114+ { " absolute" , no_argument, nullptr , ' a' },
115+ { " config-file" , required_argument, nullptr , ' c' },
116+ { " unsafe" , no_argument, nullptr , ' u' },
117+ { " fullscreen" , no_argument, nullptr , ' f' },
118+ { " multi-threaded" , no_argument, nullptr , ' m' },
119+ { " password" , required_argument, nullptr , ' P' },
120+ { " port" , required_argument, nullptr , ' p' },
121+ { " screen" , required_argument, nullptr , ' s' },
122+ { " frame-rate" , required_argument, nullptr , ' t' },
123+ { " help" , no_argument, nullptr , CHAR_MIN - 2 },
124+ { nullptr , 0 , nullptr , 0 }
125+ };
126+
127+ int c;
128+ while (-1 != (c = getopt_long (argc, argv, " abc:fmP:p:rs:t:u" , long_options, nullptr ))) {
129+ switch (c) {
130+ case ' a' :
131+ configData.relative = false ;
132+ break ;
133+
134+ case ' r' :
135+ configData.relative = true ;
136+ break ;
137+
138+ case ' c' :
139+ configData.configFile = optarg;
140+ break ;
141+
142+ case ' u' :
143+ configData.unsafe = true ;
144+ break ;
145+
146+ case ' f' :
147+ configData.fullscreen = true ;
148+ break ;
149+
150+ case ' m' :
151+ configData.multiThreaded = true ;
152+ break ;
153+
154+ case ' P' :
155+ configData.password = optarg;
156+ break ;
157+
158+ case ' p' :
159+ configData.port = atoi (optarg);
160+ break ;
161+
162+ case ' s' :
163+ configData.screen = atoi (optarg);
164+ break ;
165+
166+ case ' t' :
167+ configData.frameRate = atoi (optarg);
168+ break ;
169+
170+ case CHAR_MIN - 2 :
171+ throw HelpException ();
172+
173+ default :
174+ throw ParamException ();
175+ }
176+ }
177+
178+ if (optind < argc) {
179+ std::cerr << " Unknown parameter: " << argv[optind] << ' \n ' ;
180+ throw ParamException ();
181+ }
182+ }
183+
184+ bool ReadConfigFile (const char *programName, const std::string& configFile, ConfigData& configData)
185+ {
186+ std::string configFileTemp;
187+ libconfig::Config config;
188+ bool readConfig = false ;
189+
190+ if (configFile.length ()) {
191+ configFileTemp = configFile;
192+ readConfig = TryReadConfigFile (config, configFileTemp);
193+ if (!readConfig)
194+ throw Exception (" Unable to read the specified configuration file" );
195+ }
196+ else {
197+ configFileTemp = programName;
198+ configFileTemp += " .conf" ;
199+ readConfig = TryReadConfigFile (config, configFileTemp);
200+ if (!readConfig) {
201+ const char *baseName = basename (programName);
202+ configFileTemp = " /etc/" ;
203+ configFileTemp += baseName;
204+ configFileTemp += " .conf" ;
205+ std::cerr << " trying: " << configFileTemp << ' \n ' ;
206+ // configFileTemp = "/etc/dispmanx_vncserver.conf";
207+ readConfig = TryReadConfigFile (config, configFileTemp);
208+ }
209+ }
210+
211+ if (readConfig) {
212+ std::cerr << " Read config file: " << configFileTemp << ' \n ' ;
213+
214+ config.lookupValue (" relative" , configData.relative );
215+ config.lookupValue (" unsafe" , configData.unsafe );
216+ config.lookupValue (" fullscreen" , configData.fullscreen );
217+ config.lookupValue (" multi-threaded" , configData.multiThreaded );
218+ config.lookupValue (" password" , configData.password );
219+ config.lookupValue (" port" , configData.port );
220+ config.lookupValue (" screen" , configData.screen );
221+ config.lookupValue (" frame-rate" , configData.frameRate );
222+ }
223+ else
224+ std::cerr << " No config file found\n " ;
225+
226+ return readConfig;
227+ }
228+
229+ bool TryReadConfigFile (libconfig::Config& config, const std::string& file)
230+ {
231+ try {
232+ config.readFile (file.c_str ());
233+ return true ;
234+ }
235+ catch (libconfig::FileIOException) {
236+ return false ;;
237+ }
238+ catch (libconfig::ParseException &e) {
239+ std::stringstream ss;
240+ ss << " Error: " << e.getError () << " on line " << e.getLine () << " while reading configuration file: " << file;
241+ throw Exception (ss.str ());
242+ }
243+ }
244+
139245void usage (const char *programName)
140246{
141247 std::cout <<
142248 " Usage: " << programName << " [OPTION]...\n "
143249 " \n "
144250 " -a, --absolute absolute mouse movements\n "
251+ " -c, --config-file=FILE use the specified configuration file\n "
145252 " -f, --fullscreen always runs fullscreen mode\n "
146253 " -m, --multi-threaded runs vnc in a separate thread\n "
147254 " -p, --port=PORT makes vnc available on the speficied port\n "
0 commit comments