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