blob: 4c5a3dd6a520100ad17e87f80af1ffd978e23a83 [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)", "");
Pierre Ossmanff473402012-07-04 11:27:47 +0000103BoolParameter remoteResize("RemoteResize",
104 "Dynamically resize the remote desktop size as "
105 "the size of the local client window changes. "
106 "(Does not work with all servers)", true);
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000107
108BoolParameter viewOnly("ViewOnly",
109 "Don't send any mouse or keyboard events to the server",
110 false);
111BoolParameter shared("Shared",
112 "Don't disconnect other viewers upon connection - "
113 "share the desktop instead",
114 false);
115
116BoolParameter acceptClipboard("AcceptClipboard",
117 "Accept clipboard changes from the server",
118 true);
119BoolParameter sendClipboard("SendClipboard",
120 "Send clipboard changes to the server", true);
121BoolParameter sendPrimary("SendPrimary",
122 "Send the primary selection and cut buffer to the "
123 "server as well as the clipboard selection",
124 true);
125
126StringParameter menuKey("MenuKey", "The key which brings up the popup menu",
127 "F8");
128
Pierre Ossman407a5c32011-05-26 14:48:29 +0000129BoolParameter fullscreenSystemKeys("FullscreenSystemKeys",
130 "Pass special keys (like Alt+Tab) directly "
131 "to the server when in full screen mode.",
132 true);
133
Peter Åstrand8a2b0812012-08-08 11:49:01 +0000134const char* IDENTIFIER_STRING = "TigerVNC Configuration file Version 1.0";
135
136VoidParameter* parameterArray[] = {
137#ifdef HAVE_GNUTLS
138 &CSecurityTLS::x509ca,
139 &CSecurityTLS::x509crl,
140#endif // HAVE_GNUTLS
141 &SecurityClient::secTypes,
142 &dotWhenNoCursor,
143 &autoSelect,
144 &fullColour,
145 &lowColourLevel,
146 &preferredEncoding,
147 &customCompressLevel,
148 &compressLevel,
149 &noJpeg,
150 &qualityLevel,
151#ifdef HAVE_FLTK_FULLSCREEN
152 &fullScreen,
153#ifdef HAVE_FLTK_FULLSCREEN_SCREENS
154 &fullScreenAllMonitors,
155#endif // HAVE_FLTK_FULLSCREEN_SCREENS
156#endif // HAVE_FLTK_FULLSCREEN
157 &desktopSize,
158 &remoteResize,
159 &viewOnly,
160 &shared,
161 &acceptClipboard,
162 &sendClipboard,
163 &sendPrimary,
164 &menuKey,
165 &fullscreenSystemKeys
166};
167
168// Encoding Table
169static struct {
170 const char first;
171 const char second;
172} replaceMap[] = {'\n', 'n',
173 '\r', 'r'};
174
175bool encodeValue(const char* val, char* dest, size_t destSize) {
176
177 bool normalCharacter = true;
178 size_t pos = 0;
179
180 for (int i = 0; (val[i] != '\0') && (i < (destSize - 1)); i++) {
181
182 // Check for sequences which will need encoding
183 if (val[i] == '\\') {
184
185 strncpy(dest+pos, "\\\\", 2);
186 pos++;
187 if (pos >= destSize) {
188 vlog.error("Encoding backslash: The size of the buffer dest is to small, "
189 "it needs to be more than %d bytes bigger.", (destSize - 1 - i));
190 return false;
191 }
192
193 } else {
194
195 for (int j = 0; j < sizeof(replaceMap)/sizeof(replaceMap[0]); j++)
196
197 if (val[i] == replaceMap[j].first) {
198 dest[pos] = '\\';
199 pos++;
200 if (pos >= destSize) {
201 vlog.error("Encoding escape sequence: The size of the buffer dest is to small, "
202 "it needs to be more than %d bytes bigger.", (destSize - 1 - i));
203 return false;
204 }
205
206 dest[pos] = replaceMap[j].second;
207 normalCharacter = false;
208 break;
209 }
210
211 if (normalCharacter) {
212 dest[pos] = val[i];
213 }
214 }
215 normalCharacter = true; // Reset for next loop
216
217 pos++;
218 if (pos >= destSize) {
219 vlog.error("Encoding normal character: The size of the buffer dest is to small, "
220 "it needs to be more than %d bytes bigger.", (destSize - 1 - i));
221 return false;
222 }
223
224 }
225
226 dest[pos] = '\0';
227 return true;
228}
229
230
231bool decodeValue(const char* val, char* dest, size_t destSize) {
232
233 size_t pos = 0;
234 bool escapedCharacter = false;
235
236 for (int i = 0; (val[i] != '\0') && (i < (destSize - 1)); i++) {
237
238 // Check for escape sequences
239 if (val[i] == '\\') {
240
241 for (int j = 0; j < sizeof(replaceMap)/sizeof(replaceMap[0]); j++) {
242 if (val[i+1] == replaceMap[j].second) {
243 dest[pos] = replaceMap[j].first;
244 escapedCharacter = true;
245 pos--;
246 break;
247 }
248 }
249
250 if (!escapedCharacter) {
251 if (val[i+1] == '\\') {
252 dest[pos] = val[i];
253 i++;
254 } else {
255 vlog.error("Unknown escape sequence at character %d", i);
256 return false;
257 }
258 }
259
260 } else {
261 dest[pos] = val[i];
262 }
263
264 escapedCharacter = false; // Reset for next loop
265 pos++;
266 if (pos >= destSize) {
267 vlog.error("Decoding: The size of the buffer dest is to small, "
268 "it needs to be 1 byte bigger.");
269 return false;
270 }
271 }
272
273 dest[pos] = '\0';
274 return true;
275}
276
277
278#ifdef _WIN32
279void setKeyString(const char *_name, const char *_value, HKEY* hKey) {
280
281 const DWORD buffersize = 256;
282
283 wchar_t name[buffersize];
284 unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
285 if (size >= buffersize) {
286 vlog.error("Could not convert the parameter-name %s to wchar_t* when "
287 "writing to the Registry, the buffersize is to small.", _name);
288 return;
289 }
290
291 char encodingBuffer[buffersize];
292 if (!encodeValue(_value, encodingBuffer, buffersize)) {
293 vlog.error("Could not encode the parameter-value %s when "
294 "writing to the Registry.", _value);
295 return;
296 }
297
298 wchar_t value[buffersize];
299 size = fl_utf8towc(encodingBuffer, strlen(encodingBuffer)+1, value, buffersize);
300 if (size >= buffersize) {
301 vlog.error("Could not convert the parameter-value %s to wchar_t* when "
302 "writing to the Registry, the buffersize is to small.", _value);
303 return;
304 }
305
306 LONG res = RegSetValueExW(*hKey, name, 0, REG_SZ, (BYTE*)&value, (wcslen(value)+1)*2);
307 if (res != ERROR_SUCCESS) {
308 vlog.error("Error(%d) writing %s(REG_SZ) to Registry.", res, _value);
309 return;
310 }
311}
312
313
314void setKeyInt(const char *_name, const int _value, HKEY* hKey) {
315
316 const DWORD buffersize = 256;
317 wchar_t name[buffersize];
318 DWORD value = _value;
319
320 unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
321 if (size >= buffersize) {
322 vlog.error("Could not convert the parameter-name %s to wchar_t* when "
323 "writing to the Registry, the buffersize is to small.", _name);
324 return;
325 }
326
327 LONG res = RegSetValueExW(*hKey, name, 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
328 if (res != ERROR_SUCCESS) {
329 vlog.error("Error(%d) writing %d(REG_DWORD) to Registry.", res, _value);
330 return;
331 }
332}
333
334
335bool getKeyString(const char* _name, char* dest, size_t destSize, HKEY* hKey) {
336
337 DWORD buffersize = 256;
338 WCHAR value[destSize];
339 wchar_t name[buffersize];
340
341 unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
342 if (size >= buffersize) {
343 vlog.error("Could not convert the parameter-name %s to wchar_t* when "
344 "reading from the Registry, the buffersize is to small.", _name);
345 return false;
346 }
347
348 LONG res = RegQueryValueExW(*hKey, name, 0, NULL, (LPBYTE)value, &buffersize);
349 if (res != ERROR_SUCCESS){
350 if (res == ERROR_FILE_NOT_FOUND) {
351 // The value does not exist, defaults will be used.
352 } else {
353 vlog.error("Error(%d) reading %s from Registry.", res, _name);
354 }
355 return false;
356 }
357
358 char utf8val[destSize];
359 size = fl_utf8fromwc(utf8val, sizeof(utf8val), value, wcslen(value)+1);
360 if (size >= sizeof(utf8val)) {
361 vlog.error("Could not convert the parameter-value for %s to utf8 char* "
362 "when reading from the Registry, the buffer dest is to small.",
363 _name);
364 return false;
365 }
366 const char *ret = utf8val;
367
368 if(decodeValue(ret, dest, destSize))
369 return true;
370 else
371 return false;
372}
373
374
375bool getKeyInt(const char* _name, int* dest, HKEY* hKey) {
376
377 const DWORD buffersize = 256;
378 DWORD dwordsize = sizeof(DWORD);
379 DWORD value = 0;
380 wchar_t name[buffersize];
381
382 unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
383 if (size >= buffersize) {
384 vlog.error("Could not convert the parameter-name %s to wchar_t* when "
385 "reading from the Registry, the buffersize is to small.", _name);
386 return false;
387 }
388
389 LONG res = RegQueryValueExW(*hKey, name, 0, NULL, (LPBYTE)&value, &dwordsize);
390 if (res != ERROR_SUCCESS){
391 if (res == ERROR_FILE_NOT_FOUND) {
392 // The value does not exist, defaults will be used.
393 } else {
394 vlog.error("Error(%d) reading %s from Registry.", res, _name);
395 }
396 return false;
397 }
398
399 *dest = (int)value;
400 return true;
401}
402
403
404void saveToReg(const char* servername) {
405
406 HKEY hKey;
407
408 LONG res = RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\TigerVNC\\vncviewer", 0, NULL,
409 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
410 if (res != ERROR_SUCCESS) {
411 vlog.error("Error(%d) creating key: Software\\TigerVNC\\vncviewer", res);
412 return;
413 }
414
415 setKeyString("ServerName", servername, &hKey);
416
417 for (int i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) {
418 if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) {
419 setKeyString(parameterArray[i]->getName(), *(StringParameter*)parameterArray[i], &hKey);
420 } else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) {
421 setKeyInt(parameterArray[i]->getName(), (int)*(IntParameter*)parameterArray[i], &hKey);
422 } else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) {
423 setKeyInt(parameterArray[i]->getName(), (int)*(BoolParameter*)parameterArray[i], &hKey);
424 } else {
425 vlog.info("The parameterArray contains a object of a invalid type at line %d.", i);
426 }
427 }
428
429 res = RegCloseKey(hKey);
430 if (res != ERROR_SUCCESS) {
431 vlog.error("Error(%d) closing key: Software\\TigerVNC\\vncviewer", res);
432 }
433}
434
435
436char* loadFromReg() {
437
438 HKEY hKey;
439
440 LONG res = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\TigerVNC\\vncviewer"
441 , 0, KEY_READ, &hKey);
442 if (res != ERROR_SUCCESS) {
443 if (res == ERROR_FILE_NOT_FOUND) {
444 // The key does not exist, defaults will be used.
445 } else {
446 vlog.error("Error(%d) opening key: Software\\TigerVNC\\vncviewer", res);
447 }
448 return NULL;
449 }
450
451 const size_t buffersize = 256;
452 static char servername[buffersize];
453
454 char servernameBuffer[buffersize];
455 if (getKeyString("ServerName", servernameBuffer, buffersize, &hKey))
456 snprintf(servername, buffersize, "%s", servernameBuffer);
457
458 int intValue = 0;
459 char stringValue[buffersize];
460
461 for (int i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) {
462 if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) {
463 if (getKeyString(parameterArray[i]->getName(), stringValue, buffersize, &hKey))
464 parameterArray[i]->setParam(stringValue);
465 } else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) {
466 if (getKeyInt(parameterArray[i]->getName(), &intValue, &hKey))
467 ((IntParameter*)parameterArray[i])->setParam(intValue);
468 } else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) {
469 if (getKeyInt(parameterArray[i]->getName(), &intValue, &hKey))
470 ((BoolParameter*)parameterArray[i])->setParam(intValue);
471 } else {
472 vlog.info("The parameterArray contains a object of a invalid type at line %d.", i);
473 }
474 }
475
476 res = RegCloseKey(hKey);
477 if (res != ERROR_SUCCESS){
478 vlog.error("Error(%d) closing key: Software\\TigerVNC\\vncviewer", res);
479 }
480
481 return servername;
482}
483#endif // _WIN32
484
485
486void saveViewerParameters(const char *filename, const char *servername) {
487
488 const size_t buffersize = 256;
489 char filepath[PATH_MAX];
490 char write_error[buffersize*2];
491 char encodingBuffer[buffersize];
492
493 // Write to the registry or a predefined file if no filename was specified.
494 if(filename == NULL) {
495
496#ifdef _WIN32
497 saveToReg(servername);
498 return;
499#endif
500
501 char* homeDir = NULL;
502 if (getvnchomedir(&homeDir) == -1) {
503 vlog.error("Failed to write configuration file, "
504 "can't obtain home directory path.");
505 return;
506 }
507
508 snprintf(filepath, sizeof(filepath), "%sdefault.tigervnc", homeDir);
509 } else {
510 snprintf(filepath, sizeof(filepath), "%s", filename);
511 }
512
513 /* Write parameters to file */
514 FILE* f = fopen(filepath, "w+");
515 if (!f) {
516 snprintf(write_error, sizeof(filepath), "Failed to write configuration file, "
517 "can't open %s", filepath);
518 throw Exception(write_error);
519 }
520
521 fprintf(f, "%s\r\n", IDENTIFIER_STRING);
522 fprintf(f, "\r\n");
523
524 if (encodeValue(servername, encodingBuffer, buffersize))
525 fprintf(f, "ServerName=%s\n", encodingBuffer);
526
527 for (int i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) {
528 if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) {
529 if (encodeValue(*(StringParameter*)parameterArray[i], encodingBuffer, buffersize))
530 fprintf(f, "%s=%s\n", ((StringParameter*)parameterArray[i])->getName(), encodingBuffer);
531 } else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) {
532 fprintf(f, "%s=%d\n", ((IntParameter*)parameterArray[i])->getName(), (int)*(IntParameter*)parameterArray[i]);
533 } else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) {
534 fprintf(f, "%s=%d\n", ((BoolParameter*)parameterArray[i])->getName(), (int)*(BoolParameter*)parameterArray[i]);
535 } else {
536 vlog.info("The parameterArray contains a object of a invalid type at line %d.", i);
537 }
538 }
539 fclose(f);
540}
541
542
543char* loadViewerParameters(const char *filename) {
544
545 const size_t buffersize = 256;
546 char filepath[PATH_MAX];
547 char readError[buffersize*2];
548 char line[buffersize];
549 char decodingBuffer[buffersize];
550 char decodedValue[buffersize];
551 static char servername[sizeof(line)];
552
553 // Load from the registry or a predefined file if no filename was specified.
554 if(filename == NULL) {
555
556#ifdef _WIN32
557 return loadFromReg();
558#endif
559
560 char* homeDir = NULL;
561 if (getvnchomedir(&homeDir) == -1)
562 throw Exception("Failed to read configuration file, "
563 "can't obtain home directory path.");
564
565 snprintf(filepath, sizeof(filepath), "%sdefault.tigervnc", homeDir);
566 } else {
567 snprintf(filepath, sizeof(filepath), "%s", filename);
568 }
569
570 /* Read parameters from file */
571 FILE* f = fopen(filepath, "r");
572 if (!f) {
573 if (!filename)
574 return NULL; // Use defaults.
575 snprintf(readError, sizeof(readError), "Failed to read configuration file, "
576 "can't open %s", filepath);
577 throw Exception(readError);
578 }
579
580 int lineNr = 0;
581 while (!feof(f)) {
582
583 // Read the next line
584 lineNr++;
585 if (!fgets(line, sizeof(line), f)) {
586 if (line[sizeof(line) -1] != '\0') {
587 vlog.error("Could not read the line(%d) in the configuration file,"
588 "the buffersize is to small.", lineNr);
589 return NULL;
590 }
591 if (feof(f))
592 break;
593
594 snprintf(readError, sizeof(readError), "Failed to read line %d in file %s",
595 lineNr, filepath);
596 throw Exception(readError);
597 }
598
599 // Make sure that the first line of the file has the file identifier string
600 if(lineNr == 1) {
601 if(strncmp(line, IDENTIFIER_STRING, strlen(IDENTIFIER_STRING)) == 0) {
602 continue;
603 } else {
604 snprintf(readError, sizeof(readError), "Line 1 in file %s\n"
605 "must contain the TigerVNC configurationfile identifier string:\n"
606 "\"%s\"", filepath, IDENTIFIER_STRING);
607 throw Exception(readError);
608 }
609 }
610
611 // Skip empty lines and comments
612 if ((line[0] == '\n') || (line[0] == '#') || (line[0] == '\r'))
613 continue;
614
615 int len = strlen(line);
616 if (line[len-1] == '\n') {
617 line[len-1] = '\0';
618 len--;
619 }
620
621 // Find the parameter value
622 char *value = strchr(line, '=');
623 if (value == NULL) {
624 vlog.info("Bad Name/Value pair on line: %d in file: %s",
625 lineNr, filepath);
626 continue;
627 }
628 *value = '\0'; // line only contains the parameter name below.
629 value++;
630
631 bool invalidParameterName = true; // Will be set to false below if
632 // the line contains a valid name.
633
634 if (strcasecmp(line, "ServerName") == 0) {
635
636 if(!decodeValue(value, decodingBuffer, sizeof(decodingBuffer))) {
637 vlog.info("The value of the parameter %s on line %d in file %s is invalid.",
638 line, lineNr, filepath);
639 continue;
640 }
641 snprintf(servername, sizeof(decodingBuffer), "%s", decodingBuffer);
642 invalidParameterName = false;
643
644 } else {
645
646 // Find and set the correct parameter
647 for (int i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) {
648
649 if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) {
650 if (strcasecmp(line, ((StringParameter*)parameterArray[i])->getName()) == 0) {
651
652 if(!decodeValue(value, decodingBuffer, sizeof(decodingBuffer))) {
653 vlog.info("The value of the parameter %s on line %d in file %s is invalid.",
654 line, lineNr, filepath);
655 continue;
656 }
657 ((StringParameter*)parameterArray[i])->setParam(decodingBuffer);
658 invalidParameterName = false;
659 }
660
661 } else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) {
662 if (strcasecmp(line, ((IntParameter*)parameterArray[i])->getName()) == 0) {
663 ((IntParameter*)parameterArray[i])->setParam(atoi(value));
664 invalidParameterName = false;
665 }
666
667 } else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) {
668 if (strcasecmp(line, ((BoolParameter*)parameterArray[i])->getName()) == 0) {
669 ((BoolParameter*)parameterArray[i])->setParam(atoi(value));
670 invalidParameterName = false;
671 }
672
673 } else {
674 vlog.info("The parameterArray contains a object of a invalid type at line %d.", lineNr);
675 }
676 }
677 }
678
679 if (invalidParameterName)
680 vlog.info("Invalid parameter name on line: %d in file: %s",
681 lineNr, filepath);
682 }
683 fclose(f); f=0;
684
685 return servername;
686}