blob: 9a3bcd25f6ba43994e2bdcd851bd8004fca1e7ab [file] [log] [blame]
Pierre Ossman5156d5e2011-03-09 09:42:34 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
2 * Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
Peter Åstrand8a2b0812012-08-08 11:49:01 +00003 * Copyright 2012 Samuel Mannehed <samuel@cendio.se> for Cendio AB
Pierre Ossman5156d5e2011-03-09 09:42:34 +00004 *
5 * This is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This software 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 software; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18 * USA.
19 */
20
Peter Åstrandc359f362011-08-23 12:04:46 +000021#ifdef HAVE_CONFIG_H
22#include <config.h>
23#endif
24
Peter Åstrand8a2b0812012-08-08 11:49:01 +000025#ifdef HAVE_GNUTLS
26#include <rfb/CSecurityTLS.h>
27#endif
28
29#ifdef _WIN32
30#include <windows.h>
31#include <tchar.h>
32#endif
33
Pierre Ossman5156d5e2011-03-09 09:42:34 +000034#include "parameters.h"
35
Peter Åstrand8a2b0812012-08-08 11:49:01 +000036#include <os/os.h>
37#include <rfb/Exception.h>
38#include <rfb/LogWriter.h>
39#include <rfb/SecurityClient.h>
40
41#include <FL/fl_utf8.h>
42
43#include <stdio.h>
44#include <string.h>
45#include <limits.h>
46
Pierre Ossman5156d5e2011-03-09 09:42:34 +000047using namespace rfb;
48
Peter Åstrand8a2b0812012-08-08 11:49:01 +000049static LogWriter vlog("Parameters");
50
51
Pierre Ossman4c8e3112011-06-08 17:21:48 +000052IntParameter pointerEventInterval("PointerEventInterval",
53 "Time in milliseconds to rate-limit"
54 " successive pointer events", 0);
Pierre Ossman5156d5e2011-03-09 09:42:34 +000055BoolParameter dotWhenNoCursor("DotWhenNoCursor",
56 "Show the dot cursor when the server sends an "
Pierre Ossman93f37742011-06-09 08:35:34 +000057 "invisible cursor", false);
Pierre Ossman5156d5e2011-03-09 09:42:34 +000058
59StringParameter passwordFile("PasswordFile",
60 "Password file for VNC authentication", "");
61AliasParameter passwd("passwd", "Alias for PasswordFile", &passwordFile);
62
63BoolParameter autoSelect("AutoSelect",
64 "Auto select pixel format and encoding. "
65 "Default if PreferredEncoding and FullColor are not specified.",
66 true);
67BoolParameter fullColour("FullColor",
68 "Use full color", true);
69AliasParameter fullColourAlias("FullColour", "Alias for FullColor", &fullColour);
70IntParameter lowColourLevel("LowColorLevel",
71 "Color level to use on slow connections. "
72 "0 = Very Low (8 colors), 1 = Low (64 colors), "
73 "2 = Medium (256 colors)", 2);
74AliasParameter lowColourLevelAlias("LowColourLevel", "Alias for LowColorLevel", &lowColourLevel);
75StringParameter preferredEncoding("PreferredEncoding",
76 "Preferred encoding to use (Tight, ZRLE, Hextile or"
77 " Raw)", "Tight");
78BoolParameter customCompressLevel("CustomCompressLevel",
79 "Use custom compression level. "
80 "Default if CompressLevel is specified.", false);
81IntParameter compressLevel("CompressLevel",
DRCba7bc512011-08-17 02:30:34 +000082 "Use specified compression level 0 = Low, 6 = High",
Pierre Ossman701ad682011-11-20 15:39:17 +000083 2);
Pierre Ossman5156d5e2011-03-09 09:42:34 +000084BoolParameter noJpeg("NoJPEG",
85 "Disable lossy JPEG compression in Tight encoding.",
86 false);
87IntParameter qualityLevel("QualityLevel",
88 "JPEG quality level. 0 = Low, 9 = High",
89 8);
90
Peter Åstrand49b11572012-08-01 08:09:09 +000091BoolParameter maximize("Maximize", "Maximize viewer window", false);
Pierre Ossman2441e822012-07-10 11:11:23 +000092#ifdef HAVE_FLTK_FULLSCREEN
Pierre Ossman5156d5e2011-03-09 09:42:34 +000093BoolParameter fullScreen("FullScreen", "Full screen mode", false);
Pierre Ossmanaae38912012-07-13 11:22:55 +000094#ifdef HAVE_FLTK_FULLSCREEN_SCREENS
95BoolParameter fullScreenAllMonitors("FullScreenAllMonitors",
96 "Enable full screen over all monitors",
97 true);
98#endif // HAVE_FLTK_FULLSCREEN_SCREENS
Pierre Ossman2441e822012-07-10 11:11:23 +000099#endif // HAVE_FLTK_FULLSCREEN
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000100StringParameter desktopSize("DesktopSize",
101 "Reconfigure desktop size on the server on "
102 "connect (if possible)", "");
Peter Åstrandb182a9e2012-08-27 07:28:08 +0000103StringParameter geometry("geometry",
104 "Specify size and position of viewer window", "");
Pierre Ossmanff473402012-07-04 11:27:47 +0000105BoolParameter remoteResize("RemoteResize",
106 "Dynamically resize the remote desktop size as "
107 "the size of the local client window changes. "
108 "(Does not work with all servers)", true);
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000109
110BoolParameter viewOnly("ViewOnly",
111 "Don't send any mouse or keyboard events to the server",
112 false);
113BoolParameter shared("Shared",
114 "Don't disconnect other viewers upon connection - "
115 "share the desktop instead",
116 false);
117
118BoolParameter acceptClipboard("AcceptClipboard",
119 "Accept clipboard changes from the server",
120 true);
121BoolParameter sendClipboard("SendClipboard",
122 "Send clipboard changes to the server", true);
123BoolParameter sendPrimary("SendPrimary",
124 "Send the primary selection and cut buffer to the "
125 "server as well as the clipboard selection",
126 true);
127
128StringParameter menuKey("MenuKey", "The key which brings up the popup menu",
129 "F8");
130
Pierre Ossman407a5c32011-05-26 14:48:29 +0000131BoolParameter fullscreenSystemKeys("FullscreenSystemKeys",
132 "Pass special keys (like Alt+Tab) directly "
133 "to the server when in full screen mode.",
134 true);
135
Peter Åstrand8a2b0812012-08-08 11:49:01 +0000136const char* IDENTIFIER_STRING = "TigerVNC Configuration file Version 1.0";
137
138VoidParameter* parameterArray[] = {
139#ifdef HAVE_GNUTLS
140 &CSecurityTLS::x509ca,
141 &CSecurityTLS::x509crl,
142#endif // HAVE_GNUTLS
143 &SecurityClient::secTypes,
144 &dotWhenNoCursor,
145 &autoSelect,
146 &fullColour,
147 &lowColourLevel,
148 &preferredEncoding,
149 &customCompressLevel,
150 &compressLevel,
151 &noJpeg,
152 &qualityLevel,
153#ifdef HAVE_FLTK_FULLSCREEN
154 &fullScreen,
155#ifdef HAVE_FLTK_FULLSCREEN_SCREENS
156 &fullScreenAllMonitors,
157#endif // HAVE_FLTK_FULLSCREEN_SCREENS
158#endif // HAVE_FLTK_FULLSCREEN
159 &desktopSize,
Peter Åstrandb182a9e2012-08-27 07:28:08 +0000160 &geometry,
Peter Åstrand8a2b0812012-08-08 11:49:01 +0000161 &remoteResize,
162 &viewOnly,
163 &shared,
164 &acceptClipboard,
165 &sendClipboard,
166 &sendPrimary,
167 &menuKey,
168 &fullscreenSystemKeys
169};
170
171// Encoding Table
172static struct {
173 const char first;
174 const char second;
175} replaceMap[] = {'\n', 'n',
176 '\r', 'r'};
177
178bool encodeValue(const char* val, char* dest, size_t destSize) {
179
180 bool normalCharacter = true;
181 size_t pos = 0;
182
183 for (int i = 0; (val[i] != '\0') && (i < (destSize - 1)); i++) {
184
185 // Check for sequences which will need encoding
186 if (val[i] == '\\') {
187
188 strncpy(dest+pos, "\\\\", 2);
189 pos++;
190 if (pos >= destSize) {
191 vlog.error("Encoding backslash: The size of the buffer dest is to small, "
192 "it needs to be more than %d bytes bigger.", (destSize - 1 - i));
193 return false;
194 }
195
196 } else {
197
198 for (int j = 0; j < sizeof(replaceMap)/sizeof(replaceMap[0]); j++)
199
200 if (val[i] == replaceMap[j].first) {
201 dest[pos] = '\\';
202 pos++;
203 if (pos >= destSize) {
204 vlog.error("Encoding escape sequence: The size of the buffer dest is to small, "
205 "it needs to be more than %d bytes bigger.", (destSize - 1 - i));
206 return false;
207 }
208
209 dest[pos] = replaceMap[j].second;
210 normalCharacter = false;
211 break;
212 }
213
214 if (normalCharacter) {
215 dest[pos] = val[i];
216 }
217 }
218 normalCharacter = true; // Reset for next loop
219
220 pos++;
221 if (pos >= destSize) {
222 vlog.error("Encoding normal character: The size of the buffer dest is to small, "
223 "it needs to be more than %d bytes bigger.", (destSize - 1 - i));
224 return false;
225 }
226
227 }
228
229 dest[pos] = '\0';
230 return true;
231}
232
233
234bool decodeValue(const char* val, char* dest, size_t destSize) {
235
236 size_t pos = 0;
237 bool escapedCharacter = false;
238
239 for (int i = 0; (val[i] != '\0') && (i < (destSize - 1)); i++) {
240
241 // Check for escape sequences
242 if (val[i] == '\\') {
243
244 for (int j = 0; j < sizeof(replaceMap)/sizeof(replaceMap[0]); j++) {
245 if (val[i+1] == replaceMap[j].second) {
246 dest[pos] = replaceMap[j].first;
247 escapedCharacter = true;
248 pos--;
249 break;
250 }
251 }
252
253 if (!escapedCharacter) {
254 if (val[i+1] == '\\') {
255 dest[pos] = val[i];
256 i++;
257 } else {
258 vlog.error("Unknown escape sequence at character %d", i);
259 return false;
260 }
261 }
262
263 } else {
264 dest[pos] = val[i];
265 }
266
267 escapedCharacter = false; // Reset for next loop
268 pos++;
269 if (pos >= destSize) {
270 vlog.error("Decoding: The size of the buffer dest is to small, "
271 "it needs to be 1 byte bigger.");
272 return false;
273 }
274 }
275
276 dest[pos] = '\0';
277 return true;
278}
279
280
281#ifdef _WIN32
282void setKeyString(const char *_name, const char *_value, HKEY* hKey) {
283
284 const DWORD buffersize = 256;
285
286 wchar_t name[buffersize];
287 unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
288 if (size >= buffersize) {
289 vlog.error("Could not convert the parameter-name %s to wchar_t* when "
290 "writing to the Registry, the buffersize is to small.", _name);
291 return;
292 }
293
294 char encodingBuffer[buffersize];
295 if (!encodeValue(_value, encodingBuffer, buffersize)) {
296 vlog.error("Could not encode the parameter-value %s when "
297 "writing to the Registry.", _value);
298 return;
299 }
300
301 wchar_t value[buffersize];
302 size = fl_utf8towc(encodingBuffer, strlen(encodingBuffer)+1, value, buffersize);
303 if (size >= buffersize) {
304 vlog.error("Could not convert the parameter-value %s to wchar_t* when "
305 "writing to the Registry, the buffersize is to small.", _value);
306 return;
307 }
308
309 LONG res = RegSetValueExW(*hKey, name, 0, REG_SZ, (BYTE*)&value, (wcslen(value)+1)*2);
310 if (res != ERROR_SUCCESS) {
311 vlog.error("Error(%d) writing %s(REG_SZ) to Registry.", res, _value);
312 return;
313 }
314}
315
316
317void setKeyInt(const char *_name, const int _value, HKEY* hKey) {
318
319 const DWORD buffersize = 256;
320 wchar_t name[buffersize];
321 DWORD value = _value;
322
323 unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
324 if (size >= buffersize) {
325 vlog.error("Could not convert the parameter-name %s to wchar_t* when "
326 "writing to the Registry, the buffersize is to small.", _name);
327 return;
328 }
329
330 LONG res = RegSetValueExW(*hKey, name, 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
331 if (res != ERROR_SUCCESS) {
332 vlog.error("Error(%d) writing %d(REG_DWORD) to Registry.", res, _value);
333 return;
334 }
335}
336
337
338bool getKeyString(const char* _name, char* dest, size_t destSize, HKEY* hKey) {
339
340 DWORD buffersize = 256;
341 WCHAR value[destSize];
342 wchar_t name[buffersize];
343
344 unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
345 if (size >= buffersize) {
346 vlog.error("Could not convert the parameter-name %s to wchar_t* when "
347 "reading from the Registry, the buffersize is to small.", _name);
348 return false;
349 }
350
351 LONG res = RegQueryValueExW(*hKey, name, 0, NULL, (LPBYTE)value, &buffersize);
352 if (res != ERROR_SUCCESS){
353 if (res == ERROR_FILE_NOT_FOUND) {
354 // The value does not exist, defaults will be used.
355 } else {
356 vlog.error("Error(%d) reading %s from Registry.", res, _name);
357 }
358 return false;
359 }
360
361 char utf8val[destSize];
362 size = fl_utf8fromwc(utf8val, sizeof(utf8val), value, wcslen(value)+1);
363 if (size >= sizeof(utf8val)) {
364 vlog.error("Could not convert the parameter-value for %s to utf8 char* "
365 "when reading from the Registry, the buffer dest is to small.",
366 _name);
367 return false;
368 }
369 const char *ret = utf8val;
370
371 if(decodeValue(ret, dest, destSize))
372 return true;
373 else
374 return false;
375}
376
377
378bool getKeyInt(const char* _name, int* dest, HKEY* hKey) {
379
380 const DWORD buffersize = 256;
381 DWORD dwordsize = sizeof(DWORD);
382 DWORD value = 0;
383 wchar_t name[buffersize];
384
385 unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
386 if (size >= buffersize) {
387 vlog.error("Could not convert the parameter-name %s to wchar_t* when "
388 "reading from the Registry, the buffersize is to small.", _name);
389 return false;
390 }
391
392 LONG res = RegQueryValueExW(*hKey, name, 0, NULL, (LPBYTE)&value, &dwordsize);
393 if (res != ERROR_SUCCESS){
394 if (res == ERROR_FILE_NOT_FOUND) {
395 // The value does not exist, defaults will be used.
396 } else {
397 vlog.error("Error(%d) reading %s from Registry.", res, _name);
398 }
399 return false;
400 }
401
402 *dest = (int)value;
403 return true;
404}
405
406
407void saveToReg(const char* servername) {
408
409 HKEY hKey;
410
411 LONG res = RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\TigerVNC\\vncviewer", 0, NULL,
412 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
413 if (res != ERROR_SUCCESS) {
414 vlog.error("Error(%d) creating key: Software\\TigerVNC\\vncviewer", res);
415 return;
416 }
417
418 setKeyString("ServerName", servername, &hKey);
419
420 for (int i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) {
421 if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) {
422 setKeyString(parameterArray[i]->getName(), *(StringParameter*)parameterArray[i], &hKey);
423 } else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) {
424 setKeyInt(parameterArray[i]->getName(), (int)*(IntParameter*)parameterArray[i], &hKey);
425 } else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) {
426 setKeyInt(parameterArray[i]->getName(), (int)*(BoolParameter*)parameterArray[i], &hKey);
427 } else {
428 vlog.info("The parameterArray contains a object of a invalid type at line %d.", i);
429 }
430 }
431
432 res = RegCloseKey(hKey);
433 if (res != ERROR_SUCCESS) {
434 vlog.error("Error(%d) closing key: Software\\TigerVNC\\vncviewer", res);
435 }
436}
437
438
439char* loadFromReg() {
440
441 HKEY hKey;
442
443 LONG res = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\TigerVNC\\vncviewer"
444 , 0, KEY_READ, &hKey);
445 if (res != ERROR_SUCCESS) {
446 if (res == ERROR_FILE_NOT_FOUND) {
447 // The key does not exist, defaults will be used.
448 } else {
449 vlog.error("Error(%d) opening key: Software\\TigerVNC\\vncviewer", res);
450 }
451 return NULL;
452 }
453
454 const size_t buffersize = 256;
455 static char servername[buffersize];
456
457 char servernameBuffer[buffersize];
458 if (getKeyString("ServerName", servernameBuffer, buffersize, &hKey))
459 snprintf(servername, buffersize, "%s", servernameBuffer);
460
461 int intValue = 0;
462 char stringValue[buffersize];
463
464 for (int i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) {
465 if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) {
466 if (getKeyString(parameterArray[i]->getName(), stringValue, buffersize, &hKey))
467 parameterArray[i]->setParam(stringValue);
468 } else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) {
469 if (getKeyInt(parameterArray[i]->getName(), &intValue, &hKey))
470 ((IntParameter*)parameterArray[i])->setParam(intValue);
471 } else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) {
472 if (getKeyInt(parameterArray[i]->getName(), &intValue, &hKey))
473 ((BoolParameter*)parameterArray[i])->setParam(intValue);
474 } else {
475 vlog.info("The parameterArray contains a object of a invalid type at line %d.", i);
476 }
477 }
478
479 res = RegCloseKey(hKey);
480 if (res != ERROR_SUCCESS){
481 vlog.error("Error(%d) closing key: Software\\TigerVNC\\vncviewer", res);
482 }
483
484 return servername;
485}
486#endif // _WIN32
487
488
489void saveViewerParameters(const char *filename, const char *servername) {
490
491 const size_t buffersize = 256;
492 char filepath[PATH_MAX];
493 char write_error[buffersize*2];
494 char encodingBuffer[buffersize];
495
496 // Write to the registry or a predefined file if no filename was specified.
497 if(filename == NULL) {
498
499#ifdef _WIN32
500 saveToReg(servername);
501 return;
502#endif
503
504 char* homeDir = NULL;
505 if (getvnchomedir(&homeDir) == -1) {
506 vlog.error("Failed to write configuration file, "
507 "can't obtain home directory path.");
508 return;
509 }
510
511 snprintf(filepath, sizeof(filepath), "%sdefault.tigervnc", homeDir);
512 } else {
513 snprintf(filepath, sizeof(filepath), "%s", filename);
514 }
515
516 /* Write parameters to file */
517 FILE* f = fopen(filepath, "w+");
518 if (!f) {
519 snprintf(write_error, sizeof(filepath), "Failed to write configuration file, "
520 "can't open %s", filepath);
521 throw Exception(write_error);
522 }
523
524 fprintf(f, "%s\r\n", IDENTIFIER_STRING);
525 fprintf(f, "\r\n");
526
527 if (encodeValue(servername, encodingBuffer, buffersize))
528 fprintf(f, "ServerName=%s\n", encodingBuffer);
529
530 for (int i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) {
531 if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) {
532 if (encodeValue(*(StringParameter*)parameterArray[i], encodingBuffer, buffersize))
533 fprintf(f, "%s=%s\n", ((StringParameter*)parameterArray[i])->getName(), encodingBuffer);
534 } else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) {
535 fprintf(f, "%s=%d\n", ((IntParameter*)parameterArray[i])->getName(), (int)*(IntParameter*)parameterArray[i]);
536 } else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) {
537 fprintf(f, "%s=%d\n", ((BoolParameter*)parameterArray[i])->getName(), (int)*(BoolParameter*)parameterArray[i]);
538 } else {
539 vlog.info("The parameterArray contains a object of a invalid type at line %d.", i);
540 }
541 }
542 fclose(f);
543}
544
545
546char* loadViewerParameters(const char *filename) {
547
548 const size_t buffersize = 256;
549 char filepath[PATH_MAX];
550 char readError[buffersize*2];
551 char line[buffersize];
552 char decodingBuffer[buffersize];
553 char decodedValue[buffersize];
554 static char servername[sizeof(line)];
555
556 // Load from the registry or a predefined file if no filename was specified.
557 if(filename == NULL) {
558
559#ifdef _WIN32
560 return loadFromReg();
561#endif
562
563 char* homeDir = NULL;
564 if (getvnchomedir(&homeDir) == -1)
565 throw Exception("Failed to read configuration file, "
566 "can't obtain home directory path.");
567
568 snprintf(filepath, sizeof(filepath), "%sdefault.tigervnc", homeDir);
569 } else {
570 snprintf(filepath, sizeof(filepath), "%s", filename);
571 }
572
573 /* Read parameters from file */
574 FILE* f = fopen(filepath, "r");
575 if (!f) {
576 if (!filename)
577 return NULL; // Use defaults.
578 snprintf(readError, sizeof(readError), "Failed to read configuration file, "
579 "can't open %s", filepath);
580 throw Exception(readError);
581 }
582
583 int lineNr = 0;
584 while (!feof(f)) {
585
586 // Read the next line
587 lineNr++;
588 if (!fgets(line, sizeof(line), f)) {
589 if (line[sizeof(line) -1] != '\0') {
590 vlog.error("Could not read the line(%d) in the configuration file,"
591 "the buffersize is to small.", lineNr);
592 return NULL;
593 }
594 if (feof(f))
595 break;
596
597 snprintf(readError, sizeof(readError), "Failed to read line %d in file %s",
598 lineNr, filepath);
599 throw Exception(readError);
600 }
601
602 // Make sure that the first line of the file has the file identifier string
603 if(lineNr == 1) {
604 if(strncmp(line, IDENTIFIER_STRING, strlen(IDENTIFIER_STRING)) == 0) {
605 continue;
606 } else {
607 snprintf(readError, sizeof(readError), "Line 1 in file %s\n"
608 "must contain the TigerVNC configurationfile identifier string:\n"
609 "\"%s\"", filepath, IDENTIFIER_STRING);
610 throw Exception(readError);
611 }
612 }
613
614 // Skip empty lines and comments
615 if ((line[0] == '\n') || (line[0] == '#') || (line[0] == '\r'))
616 continue;
617
618 int len = strlen(line);
619 if (line[len-1] == '\n') {
620 line[len-1] = '\0';
621 len--;
622 }
623
624 // Find the parameter value
625 char *value = strchr(line, '=');
626 if (value == NULL) {
627 vlog.info("Bad Name/Value pair on line: %d in file: %s",
628 lineNr, filepath);
629 continue;
630 }
631 *value = '\0'; // line only contains the parameter name below.
632 value++;
633
634 bool invalidParameterName = true; // Will be set to false below if
635 // the line contains a valid name.
636
637 if (strcasecmp(line, "ServerName") == 0) {
638
639 if(!decodeValue(value, decodingBuffer, sizeof(decodingBuffer))) {
640 vlog.info("The value of the parameter %s on line %d in file %s is invalid.",
641 line, lineNr, filepath);
642 continue;
643 }
644 snprintf(servername, sizeof(decodingBuffer), "%s", decodingBuffer);
645 invalidParameterName = false;
646
647 } else {
648
649 // Find and set the correct parameter
650 for (int i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) {
651
652 if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) {
653 if (strcasecmp(line, ((StringParameter*)parameterArray[i])->getName()) == 0) {
654
655 if(!decodeValue(value, decodingBuffer, sizeof(decodingBuffer))) {
656 vlog.info("The value of the parameter %s on line %d in file %s is invalid.",
657 line, lineNr, filepath);
658 continue;
659 }
660 ((StringParameter*)parameterArray[i])->setParam(decodingBuffer);
661 invalidParameterName = false;
662 }
663
664 } else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) {
665 if (strcasecmp(line, ((IntParameter*)parameterArray[i])->getName()) == 0) {
666 ((IntParameter*)parameterArray[i])->setParam(atoi(value));
667 invalidParameterName = false;
668 }
669
670 } else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) {
671 if (strcasecmp(line, ((BoolParameter*)parameterArray[i])->getName()) == 0) {
672 ((BoolParameter*)parameterArray[i])->setParam(atoi(value));
673 invalidParameterName = false;
674 }
675
676 } else {
677 vlog.info("The parameterArray contains a object of a invalid type at line %d.", lineNr);
678 }
679 }
680 }
681
682 if (invalidParameterName)
683 vlog.info("Invalid parameter name on line: %d in file: %s",
684 lineNr, filepath);
685 }
686 fclose(f); f=0;
687
688 return servername;
689}