diff options
Diffstat (limited to 'vncviewer/parameters.cxx')
-rw-r--r-- | vncviewer/parameters.cxx | 593 |
1 files changed, 341 insertions, 252 deletions
diff --git a/vncviewer/parameters.cxx b/vncviewer/parameters.cxx index a6229a34..d2000181 100644 --- a/vncviewer/parameters.cxx +++ b/vncviewer/parameters.cxx @@ -32,13 +32,12 @@ #include "parameters.h" -#include <os/os.h> +#include <core/Exception.h> +#include <core/LogWriter.h> +#include <core/string.h> +#include <core/xdgdirs.h> -#include <rdr/Exception.h> - -#include <rfb/LogWriter.h> #include <rfb/SecurityClient.h> -#include <rfb/util.h> #include <FL/fl_utf8.h> @@ -50,123 +49,199 @@ #include "i18n.h" -using namespace rfb; -using namespace std; - -static LogWriter vlog("Parameters"); - - -IntParameter pointerEventInterval("PointerEventInterval", - "Time in milliseconds to rate-limit" - " successive pointer events", 17); -BoolParameter emulateMiddleButton("EmulateMiddleButton", - "Emulate middle mouse button by pressing " - "left and right mouse buttons simultaneously", - false); -BoolParameter dotWhenNoCursor("DotWhenNoCursor", - "Show the dot cursor when the server sends an " - "invisible cursor", false); - -BoolParameter alertOnFatalError("AlertOnFatalError", - "Give a dialog on connection problems rather " - "than exiting immediately", true); - -BoolParameter reconnectOnError("ReconnectOnError", - "Give a dialog on connection problems rather " - "than exiting immediately and ask for a reconnect.", true); - -StringParameter passwordFile("PasswordFile", - "Password file for VNC authentication", ""); -AliasParameter passwd("passwd", "Alias for PasswordFile", &passwordFile); - -BoolParameter autoSelect("AutoSelect", - "Auto select pixel format and encoding. " - "Default if PreferredEncoding and FullColor are not specified.", - true); -BoolParameter fullColour("FullColor", - "Use full color", true); -AliasParameter fullColourAlias("FullColour", "Alias for FullColor", &fullColour); -IntParameter lowColourLevel("LowColorLevel", - "Color level to use on slow connections. " - "0 = Very Low, 1 = Low, 2 = Medium", 2); -AliasParameter lowColourLevelAlias("LowColourLevel", "Alias for LowColorLevel", &lowColourLevel); -StringParameter preferredEncoding("PreferredEncoding", - "Preferred encoding to use (Tight, ZRLE, Hextile or" - " Raw)", "Tight"); -BoolParameter customCompressLevel("CustomCompressLevel", - "Use custom compression level. " - "Default if CompressLevel is specified.", false); -IntParameter compressLevel("CompressLevel", - "Use specified compression level 0 = Low, 9 = High", - 2); -BoolParameter noJpeg("NoJPEG", - "Disable lossy JPEG compression in Tight encoding.", - false); -IntParameter qualityLevel("QualityLevel", - "JPEG quality level. 0 = Low, 9 = High", - 8); - -BoolParameter maximize("Maximize", "Maximize viewer window", false); -BoolParameter fullScreen("FullScreen", "Enable full screen", false); -StringParameter fullScreenMode("FullScreenMode", "Specify which monitors to use when in full screen. " - "Should be either Current, Selected or All", - "Current"); -BoolParameter fullScreenAllMonitors("FullScreenAllMonitors", - "[DEPRECATED] Enable full screen over all monitors", - false); -MonitorIndicesParameter fullScreenSelectedMonitors("FullScreenSelectedMonitors", - "Use the given list of monitors in full screen" - " when -FullScreenMode=Selected.", - "1"); -StringParameter desktopSize("DesktopSize", - "Reconfigure desktop size on the server on " - "connect (if possible)", ""); -StringParameter geometry("geometry", - "Specify size and position of viewer window", ""); - -BoolParameter listenMode("listen", "Listen for connections from VNC servers", false); - -BoolParameter remoteResize("RemoteResize", - "Dynamically resize the remote desktop size as " - "the size of the local client window changes. " - "(Does not work with all servers)", true); - -BoolParameter viewOnly("ViewOnly", - "Don't send any mouse or keyboard events to the server", - false); -BoolParameter shared("Shared", - "Don't disconnect other viewers upon connection - " - "share the desktop instead", - false); - -BoolParameter acceptClipboard("AcceptClipboard", - "Accept clipboard changes from the server", - true); -BoolParameter sendClipboard("SendClipboard", - "Send clipboard changes to the server", true); +static core::LogWriter vlog("Parameters"); + +core::IntParameter + pointerEventInterval("PointerEventInterval", + "Time in milliseconds to rate-limit successive " + "pointer events", + 17, 0, INT_MAX); +core::BoolParameter + emulateMiddleButton("EmulateMiddleButton", + "Emulate middle mouse button by pressing left " + "and right mouse buttons simultaneously", + false); +core::BoolParameter + dotWhenNoCursor("DotWhenNoCursor", + "[DEPRECATED] Show the dot cursor when the server " + "sends an invisible cursor", + false); +core::BoolParameter + alwaysCursor("AlwaysCursor", + "Show the local cursor when the server sends an " + "invisible cursor", + false); +core::EnumParameter + cursorType("CursorType", + "Specify which cursor type the local cursor should be. " + "Should be either Dot or System", + {"Dot", "System"}, "Dot"); + +core::BoolParameter + alertOnFatalError("AlertOnFatalError", + "Give a dialog on connection problems rather than " + "exiting immediately", + true); + +core::BoolParameter + reconnectOnError("ReconnectOnError", + "Give a dialog on connection problems rather than " + "exiting immediately and ask for a reconnect.", + true); + +core::StringParameter + passwordFile("PasswordFile", + "Password file for VNC authentication", + ""); +core::AliasParameter + passwd("passwd", "Alias for PasswordFile", &passwordFile); + +core::BoolParameter + autoSelect("AutoSelect", + "Auto select pixel format and encoding. Default if " + "PreferredEncoding and FullColor are not specified.", + true); +core::BoolParameter + fullColour("FullColor", "Use full color", true); +core::AliasParameter + fullColourAlias("FullColour", "Alias for FullColor", &fullColour); +core::IntParameter + lowColourLevel("LowColorLevel", + "Color level to use on slow connections. " + "0 = Very Low, 1 = Low, 2 = Medium", + 2, 0, 2); +core::AliasParameter + lowColourLevelAlias("LowColourLevel", + "Alias for LowColorLevel", &lowColourLevel); +core::EnumParameter + preferredEncoding("PreferredEncoding", + "Preferred encoding to use (Tight, ZRLE, Hextile, " +#ifdef HAVE_H264 + "H.264, " +#endif + "or Raw)", + {"Tight", "ZRLE", "Hextile", +#ifdef HAVE_H264 + "H.264", +#endif + "Raw"}, + "Tight"); +core::BoolParameter + customCompressLevel("CustomCompressLevel", + "Use custom compression level. Default if " + "CompressLevel is specified.", + false); +core::IntParameter + compressLevel("CompressLevel", + "Use specified compression level 0 = Low, 9 = High", + 2, 0, 9); +core::BoolParameter + noJpeg("NoJPEG", + "Disable lossy JPEG compression in Tight encoding.", + false); +core::IntParameter + qualityLevel("QualityLevel", + "JPEG quality level. 0 = Low, 9 = High", + 8, 0, 9); + +core::BoolParameter + maximize("Maximize", "Maximize viewer window", false); +core::BoolParameter + fullScreen("FullScreen", "Enable full screen", false); +core::EnumParameter + fullScreenMode("FullScreenMode", + "Specify which monitors to use when in full screen. " + "Should be either Current, Selected or All", + {"Current", "Selected", "All"}, "Current"); + +core::BoolParameter + fullScreenAllMonitors("FullScreenAllMonitors", + "[DEPRECATED] Enable full screen over all " + "monitors", + false); +MonitorIndicesParameter + fullScreenSelectedMonitors("FullScreenSelectedMonitors", + "Use the given list of monitors in full " + "screen when -FullScreenMode=Selected.", + {1}); +core::StringParameter + desktopSize("DesktopSize", + "Reconfigure desktop size on the server on connect (if " + "possible)", + ""); +core::StringParameter + geometry("geometry", + "Specify size and position of viewer window", + ""); + +core::BoolParameter + listenMode("listen", + "Listen for connections from VNC servers", + false); + +core::BoolParameter + remoteResize("RemoteResize", + "Dynamically resize the remote desktop size as the size " + "of the local client window changes. (Does not work " + "with all servers)", + true); + +core::BoolParameter + viewOnly("ViewOnly", + "Don't send any mouse or keyboard events to the server", + false); +core::BoolParameter + shared("Shared", + "Don't disconnect other viewers upon connection - " + "share the desktop instead", + false); + +core::BoolParameter + acceptClipboard("AcceptClipboard", + "Accept clipboard changes from the server", + true); +core::BoolParameter + sendClipboard("SendClipboard", + "Send clipboard changes to the server", + true); #if !defined(WIN32) && !defined(__APPLE__) -BoolParameter setPrimary("SetPrimary", - "Set the primary selection as well as the " - "clipboard selection", true); -BoolParameter sendPrimary("SendPrimary", - "Send the primary selection to the " - "server as well as the clipboard selection", - true); -StringParameter display("display", - "Specifies the X display on which the VNC viewer window should appear.", - ""); +core::BoolParameter + setPrimary("SetPrimary", + "Set the primary selection as well as the clipboard " + "selection", + true); +core::BoolParameter + sendPrimary("SendPrimary", + "Send the primary selection to the server as well as the " + "clipboard selection", + true); +core::StringParameter + display("display", + "Specifies the X display on which the TigerVNC window " + "should appear.", + ""); #endif -StringParameter menuKey("MenuKey", "The key which brings up the popup menu", - "F8"); - -BoolParameter fullscreenSystemKeys("FullscreenSystemKeys", - "Pass special keys (like Alt+Tab) directly " - "to the server when in full-screen mode.", - true); +// Keep list of valid values in sync with ShortcutHandler +core::EnumListParameter + shortcutModifiers("ShortcutModifiers", + "The combination of modifier keys that triggers " + "special actions in the viewer instead of being " + "sent to the remote session. Possible values are a " + "combination of Ctrl, Shift, Alt, and Super.", + {"Ctrl", "Shift", "Alt", "Super", + "Win", "Option", "Cmd"}, + {"Ctrl", "Alt"}); + +core::BoolParameter + fullscreenSystemKeys("FullscreenSystemKeys", + "Pass special keys (like Alt+Tab) directly to " + "the server when in full-screen mode.", + true); #ifndef WIN32 -StringParameter via("via", "Gateway to tunnel via", ""); +core::StringParameter + via("via", "Gateway to tunnel via", ""); #endif static const char* IDENTIFIER_STRING = "TigerVNC Configuration file Version 1.0"; @@ -175,13 +250,13 @@ static const char* IDENTIFIER_STRING = "TigerVNC Configuration file Version 1.0" * We only save the sub set of parameters that can be modified from * the graphical user interface */ -static VoidParameter* parameterArray[] = { +static core::VoidParameter* parameterArray[] = { /* Security */ #ifdef HAVE_GNUTLS - &CSecurityTLS::X509CA, - &CSecurityTLS::X509CRL, + &rfb::CSecurityTLS::X509CA, + &rfb::CSecurityTLS::X509CRL, #endif // HAVE_GNUTLS - &SecurityClient::secTypes, + &rfb::SecurityClient::secTypes, /* Misc. */ &reconnectOnError, &shared, @@ -201,19 +276,22 @@ static VoidParameter* parameterArray[] = { /* Input */ &viewOnly, &emulateMiddleButton, - &dotWhenNoCursor, + &alwaysCursor, + &cursorType, &acceptClipboard, &sendClipboard, #if !defined(WIN32) && !defined(__APPLE__) &sendPrimary, &setPrimary, #endif - &menuKey, - &fullscreenSystemKeys + &fullscreenSystemKeys, + /* Keyboard shortcuts */ + &shortcutModifiers, }; -static VoidParameter* readOnlyParameterArray[] = { - &fullScreenAllMonitors +static core::VoidParameter* readOnlyParameterArray[] = { + &fullScreenAllMonitors, + &dotWhenNoCursor }; // Encoding Table @@ -320,7 +398,7 @@ static void setKeyString(const char *_name, const char *_value, HKEY* hKey) { LONG res = RegSetValueExW(*hKey, name, 0, REG_SZ, (BYTE*)&value, (wcslen(value)+1)*2); if (res != ERROR_SUCCESS) - throw rdr::win32_error("RegSetValueExW", res); + throw core::win32_error("RegSetValueExW", res); } @@ -336,7 +414,7 @@ static void setKeyInt(const char *_name, const int _value, HKEY* hKey) { LONG res = RegSetValueExW(*hKey, name, 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD)); if (res != ERROR_SUCCESS) - throw rdr::win32_error("RegSetValueExW", res); + throw core::win32_error("RegSetValueExW", res); } @@ -357,7 +435,7 @@ static bool getKeyString(const char* _name, char* dest, size_t destSize, HKEY* h if (res != ERROR_SUCCESS){ delete [] value; if (res != ERROR_FILE_NOT_FOUND) - throw rdr::win32_error("RegQueryValueExW", res); + throw core::win32_error("RegQueryValueExW", res); // The value does not exist, defaults will be used. return false; } @@ -394,7 +472,7 @@ static bool getKeyInt(const char* _name, int* dest, HKEY* hKey) { LONG res = RegQueryValueExW(*hKey, name, nullptr, nullptr, (LPBYTE)&value, &dwordsize); if (res != ERROR_SUCCESS){ if (res != ERROR_FILE_NOT_FOUND) - throw rdr::win32_error("RegQueryValueExW", res); + throw core::win32_error("RegQueryValueExW", res); // The value does not exist, defaults will be used. return false; } @@ -414,13 +492,14 @@ static void removeValue(const char* _name, HKEY* hKey) { LONG res = RegDeleteValueW(*hKey, name); if (res != ERROR_SUCCESS) { if (res != ERROR_FILE_NOT_FOUND) - throw rdr::win32_error("RegDeleteValueW", res); + throw core::win32_error("RegDeleteValueW", res); // The value does not exist, no need to remove it. return; } } -void saveHistoryToRegKey(const list<string>& serverHistory) { +void saveHistoryToRegKey(const std::list<std::string>& serverHistory) +{ HKEY hKey; LONG res = RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\TigerVNC\\vncviewer\\history", 0, nullptr, @@ -428,14 +507,14 @@ void saveHistoryToRegKey(const list<string>& serverHistory) { &hKey, nullptr); if (res != ERROR_SUCCESS) - throw rdr::win32_error(_("Failed to create registry key"), res); + throw core::win32_error(_("Failed to create registry key"), res); unsigned index = 0; assert(SERVER_HISTORY_SIZE < 100); char indexString[3]; try { - for (const string& entry : serverHistory) { + for (const std::string& entry : serverHistory) { if (index > SERVER_HISTORY_SIZE) break; snprintf(indexString, 3, "%d", index); @@ -449,7 +528,7 @@ void saveHistoryToRegKey(const list<string>& serverHistory) { res = RegCloseKey(hKey); if (res != ERROR_SUCCESS) - throw rdr::win32_error(_("Failed to close registry key"), res); + throw core::win32_error(_("Failed to close registry key"), res); } static void saveToReg(const char* servername) { @@ -461,57 +540,74 @@ static void saveToReg(const char* servername) { REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, nullptr, &hKey, nullptr); if (res != ERROR_SUCCESS) - throw rdr::win32_error(_("Failed to create registry key"), res); + throw core::win32_error(_("Failed to create registry key"), res); try { setKeyString("ServerName", servername, &hKey); } catch (std::exception& e) { RegCloseKey(hKey); - throw std::runtime_error(format(_("Failed to save \"%s\": %s"), - "ServerName", e.what())); + throw std::runtime_error(core::format( + _("Failed to save \"%s\": %s"), "ServerName", e.what())); } - for (size_t i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) { + for (core::VoidParameter* param : parameterArray) { + core::IntParameter* iparam; + core::BoolParameter* bparam; + + if (param->isDefault()) { + try { + removeValue(param->getName(), &hKey); + } catch (std::exception& e) { + RegCloseKey(hKey); + throw std::runtime_error( + core::format(_("Failed to remove \"%s\": %s"), + param->getName(), e.what())); + } + continue; + } + + iparam = dynamic_cast<core::IntParameter*>(param); + bparam = dynamic_cast<core::BoolParameter*>(param); + try { - if (dynamic_cast<StringParameter*>(parameterArray[i]) != nullptr) { - setKeyString(parameterArray[i]->getName(), *(StringParameter*)parameterArray[i], &hKey); - } else if (dynamic_cast<IntParameter*>(parameterArray[i]) != nullptr) { - setKeyInt(parameterArray[i]->getName(), (int)*(IntParameter*)parameterArray[i], &hKey); - } else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != nullptr) { - setKeyInt(parameterArray[i]->getName(), (int)*(BoolParameter*)parameterArray[i], &hKey); + if (iparam != nullptr) { + setKeyInt(iparam->getName(), (int)*(iparam), &hKey); + } else if (bparam != nullptr) { + setKeyInt(bparam->getName(), (int)*(bparam), &hKey); } else { - throw std::logic_error(_("Unknown parameter type")); + setKeyString(param->getName(), param->getValueStr().c_str(), &hKey); } } catch (std::exception& e) { RegCloseKey(hKey); - throw std::runtime_error(format(_("Failed to save \"%s\": %s"), - parameterArray[i]->getName(), - e.what())); + throw std::runtime_error( + core::format(_("Failed to save \"%s\": %s"), + param->getName(), e.what())); } } // Remove read-only parameters to replicate the behaviour of Linux/macOS when they // store a config to disk. If the parameter hasn't been migrated at this point it // will be lost. - for (size_t i = 0; i < sizeof(readOnlyParameterArray)/sizeof(VoidParameter*); i++) { + for (core::VoidParameter* param : readOnlyParameterArray) { try { - removeValue(readOnlyParameterArray[i]->getName(), &hKey); + removeValue(param->getName(), &hKey); } catch (std::exception& e) { RegCloseKey(hKey); - throw std::runtime_error(format(_("Failed to remove \"%s\": %s"), - readOnlyParameterArray[i]->getName(), - e.what())); + throw std::runtime_error( + core::format(_("Failed to remove \"%s\": %s"), + param->getName(), e.what())); } } res = RegCloseKey(hKey); if (res != ERROR_SUCCESS) - throw rdr::win32_error(_("Failed to close registry key"), res); + throw core::win32_error(_("Failed to close registry key"), res); } -list<string> loadHistoryFromRegKey() { +std::list<std::string> loadHistoryFromRegKey() +{ HKEY hKey; - list<string> serverHistory; + std::list<std::string> serverHistory; LONG res = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\TigerVNC\\vncviewer\\history", 0, @@ -522,7 +618,7 @@ list<string> loadHistoryFromRegKey() { return serverHistory; } - throw rdr::win32_error(_("Failed to open registry key"), res); + throw core::win32_error(_("Failed to open registry key"), res); } unsigned index; @@ -549,31 +645,35 @@ list<string> loadHistoryFromRegKey() { res = RegCloseKey(hKey); if (res != ERROR_SUCCESS) - throw rdr::win32_error(_("Failed to close registry key"), res); + throw core::win32_error(_("Failed to close registry key"), res); return serverHistory; } -static void getParametersFromReg(VoidParameter* parameters[], +static void getParametersFromReg(core::VoidParameter* parameters[], size_t parameters_len, HKEY* hKey) { const size_t buffersize = 256; int intValue = 0; char stringValue[buffersize]; - for (size_t i = 0; i < parameters_len/sizeof(VoidParameter*); i++) { + for (size_t i = 0; i < parameters_len; i++) { + core::IntParameter* iparam; + core::BoolParameter* bparam; + + iparam = dynamic_cast<core::IntParameter*>(parameters[i]); + bparam = dynamic_cast<core::BoolParameter*>(parameters[i]); + try { - if (dynamic_cast<StringParameter*>(parameters[i]) != nullptr) { + if (iparam != nullptr) { + if (getKeyInt(iparam->getName(), &intValue, hKey)) + iparam->setParam(intValue); + } else if (bparam != nullptr) { + if (getKeyInt(bparam->getName(), &intValue, hKey)) + bparam->setParam(intValue); + } else { if (getKeyString(parameters[i]->getName(), stringValue, buffersize, hKey)) parameters[i]->setParam(stringValue); - } else if (dynamic_cast<IntParameter*>(parameters[i]) != nullptr) { - if (getKeyInt(parameters[i]->getName(), &intValue, hKey)) - ((IntParameter*)parameters[i])->setParam(intValue); - } else if (dynamic_cast<BoolParameter*>(parameters[i]) != nullptr) { - if (getKeyInt(parameters[i]->getName(), &intValue, hKey)) - ((BoolParameter*)parameters[i])->setParam(intValue); - } else { - throw std::logic_error(_("Unknown parameter type")); } } catch(std::exception& e) { // Just ignore this entry and continue with the rest @@ -596,7 +696,7 @@ static char* loadFromReg() { return nullptr; } - throw rdr::win32_error(_("Failed to open registry key"), res); + throw core::win32_error(_("Failed to open registry key"), res); } const size_t buffersize = 256; @@ -612,13 +712,18 @@ static char* loadFromReg() { strcpy(servername, ""); } - getParametersFromReg(parameterArray, sizeof(parameterArray), &hKey); + getParametersFromReg(parameterArray, + sizeof(parameterArray) / + sizeof(core::VoidParameter*), + &hKey); getParametersFromReg(readOnlyParameterArray, - sizeof(readOnlyParameterArray), &hKey); + sizeof(readOnlyParameterArray) / + sizeof(core::VoidParameter*), + &hKey); res = RegCloseKey(hKey); if (res != ERROR_SUCCESS) - throw rdr::win32_error(_("Failed to close registry key"), res); + throw core::win32_error(_("Failed to close registry key"), res); return servername; } @@ -639,7 +744,7 @@ void saveViewerParameters(const char *filename, const char *servername) { return; #endif - const char* configDir = os::getvncconfigdir(); + const char* configDir = core::getvncconfigdir(); if (configDir == nullptr) throw std::runtime_error(_("Could not determine VNC config directory path")); @@ -650,78 +755,50 @@ void saveViewerParameters(const char *filename, const char *servername) { /* Write parameters to file */ FILE* f = fopen(filepath, "w+"); - if (!f) { - std::string msg = format(_("Could not open \"%s\""), filepath); - throw rdr::posix_error(msg.c_str(), errno); - } + if (!f) + throw core::posix_error( + core::format(_("Could not open \"%s\""), filepath), errno); fprintf(f, "%s\n", IDENTIFIER_STRING); fprintf(f, "\n"); if (!encodeValue(servername, encodingBuffer, buffersize)) { fclose(f); - throw std::runtime_error(format(_("Failed to save \"%s\": %s"), - "ServerName", - _("Could not encode parameter"))); + throw std::runtime_error( + core::format(_("Failed to save \"%s\": %s"), "ServerName", + _("Could not encode parameter"))); } fprintf(f, "ServerName=%s\n", encodingBuffer); - for (VoidParameter* param : parameterArray) { - if (dynamic_cast<StringParameter*>(param) != nullptr) { - if (!encodeValue(*(StringParameter*)param, - encodingBuffer, buffersize)) { - fclose(f); - throw std::runtime_error(format(_("Failed to save \"%s\": %s"), - param->getName(), - _("Could not encode parameter"))); - } - fprintf(f, "%s=%s\n", ((StringParameter*)param)->getName(), encodingBuffer); - } else if (dynamic_cast<IntParameter*>(param) != nullptr) { - fprintf(f, "%s=%d\n", ((IntParameter*)param)->getName(), (int)*(IntParameter*)param); - } else if (dynamic_cast<BoolParameter*>(param) != nullptr) { - fprintf(f, "%s=%d\n", ((BoolParameter*)param)->getName(), (int)*(BoolParameter*)param); - } else { + for (core::VoidParameter* param : parameterArray) { + if (param->isDefault()) + continue; + if (!encodeValue(param->getValueStr().c_str(), + encodingBuffer, buffersize)) { fclose(f); - throw std::logic_error(format(_("Failed to save \"%s\": %s"), - param->getName(), - _("Unknown parameter type"))); + throw std::runtime_error( + core::format(_("Failed to save \"%s\": %s"), param->getName(), + _("Could not encode parameter"))); } + fprintf(f, "%s=%s\n", param->getName(), encodingBuffer); } fclose(f); } static bool findAndSetViewerParameterFromValue( - VoidParameter* parameters[], size_t parameters_len, + core::VoidParameter* parameters[], size_t parameters_len, char* value, char* line) { const size_t buffersize = 256; char decodingBuffer[buffersize]; // Find and set the correct parameter - for (size_t i = 0; i < parameters_len/sizeof(VoidParameter*); i++) { - - if (dynamic_cast<StringParameter*>(parameters[i]) != nullptr) { - if (strcasecmp(line, ((StringParameter*)parameters[i])->getName()) == 0) { - if(!decodeValue(value, decodingBuffer, sizeof(decodingBuffer))) - throw std::runtime_error(_("Invalid format or too large value")); - ((StringParameter*)parameters[i])->setParam(decodingBuffer); - return false; - } - - } else if (dynamic_cast<IntParameter*>(parameters[i]) != nullptr) { - if (strcasecmp(line, ((IntParameter*)parameters[i])->getName()) == 0) { - ((IntParameter*)parameters[i])->setParam(atoi(value)); - return false; - } - - } else if (dynamic_cast<BoolParameter*>(parameters[i]) != nullptr) { - if (strcasecmp(line, ((BoolParameter*)parameters[i])->getName()) == 0) { - ((BoolParameter*)parameters[i])->setParam(atoi(value)); - return false; - } - - } else { - throw std::logic_error(_("Unknown parameter type")); + for (size_t i = 0; i < parameters_len; i++) { + if (strcasecmp(line, parameters[i]->getName()) == 0) { + if(!decodeValue(value, decodingBuffer, sizeof(decodingBuffer))) + throw std::runtime_error(_("Invalid format or too large value")); + parameters[i]->setParam(decodingBuffer); + return false; } } @@ -745,7 +822,7 @@ char* loadViewerParameters(const char *filename) { return loadFromReg(); #endif - const char* configDir = os::getvncconfigdir(); + const char* configDir = core::getvncconfigdir(); if (configDir == nullptr) throw std::runtime_error(_("Could not determine VNC config directory path")); @@ -759,10 +836,10 @@ char* loadViewerParameters(const char *filename) { if (!f) { if (!filename) return nullptr; // Use defaults. - std::string msg = format(_("Could not open \"%s\""), filepath); - throw rdr::posix_error(msg.c_str(), errno); + throw core::posix_error( + core::format(_("Could not open \"%s\""), filepath), errno); } - + int lineNr = 0; while (!feof(f)) { @@ -773,18 +850,19 @@ char* loadViewerParameters(const char *filename) { break; fclose(f); - std::string msg = format(_("Failed to read line %d in " - "file \"%s\""), lineNr, filepath); - throw rdr::posix_error(msg.c_str(), errno); + throw core::posix_error( + core::format(_("Failed to read line %d in file \"%s\""), + lineNr, filepath), + errno); } if (strlen(line) == (sizeof(line) - 1)) { fclose(f); - throw std::runtime_error(format("%s: %s", - format(_("Failed to read line %d " - "in file \"%s\""), - lineNr, filepath).c_str(), - _("Line too long"))); + std::string msg = core::format(_("Failed to read line %d in " + "file \"%s\""), + lineNr, filepath); + throw std::runtime_error( + core::format("%s: %s", msg.c_str(), _("Line too long"))); } // Make sure that the first line of the file has the file identifier string @@ -793,11 +871,10 @@ char* loadViewerParameters(const char *filename) { continue; fclose(f); - throw std::runtime_error(format(_("Configuration file %s is in " - "an invalid format"), - filepath)); + throw std::runtime_error(core::format( + _("Configuration file %s is in an invalid format"), filepath)); } - + // Skip empty lines and comments if ((line[0] == '\n') || (line[0] == '#') || (line[0] == '\r')) continue; @@ -815,8 +892,10 @@ char* loadViewerParameters(const char *filename) { // Find the parameter value char *value = strchr(line, '='); if (value == nullptr) { - vlog.error(_("Failed to read line %d in file %s: %s"), - lineNr, filepath, _("Invalid format")); + std::string msg = core::format(_("Failed to read line %d in " + "file \"%s\""), + lineNr, filepath); + vlog.error("%s: %s", msg.c_str(), _("Invalid format")); continue; } *value = '\0'; // line only contains the parameter name below. @@ -834,24 +913,34 @@ char* loadViewerParameters(const char *filename) { invalidParameterName = false; } else { - invalidParameterName = findAndSetViewerParameterFromValue(parameterArray, sizeof(parameterArray), - value, line); + invalidParameterName = findAndSetViewerParameterFromValue( + parameterArray, + sizeof(parameterArray) / sizeof(core::VoidParameter *), + value, line); if (invalidParameterName) { - invalidParameterName = findAndSetViewerParameterFromValue(readOnlyParameterArray, sizeof(readOnlyParameterArray), - value, line); + invalidParameterName = findAndSetViewerParameterFromValue( + readOnlyParameterArray, + sizeof(readOnlyParameterArray) / + sizeof(core::VoidParameter *), + value, line); } } } catch(std::exception& e) { // Just ignore this entry and continue with the rest - vlog.error(_("Failed to read line %d in file %s: %s"), - lineNr, filepath, e.what()); + std::string msg = core::format(_("Failed to read line %d in " + "file \"%s\""), + lineNr, filepath); + vlog.error("%s: %s", msg.c_str(), e.what()); continue; } - if (invalidParameterName) - vlog.error(_("Failed to read line %d in file %s: %s"), - lineNr, filepath, _("Unknown parameter")); + if (invalidParameterName) { + std::string msg = core::format(_("Failed to read line %d in " + "file \"%s\""), + lineNr, filepath); + vlog.error("%s: %s", msg.c_str(), _("Unknown parameter")); + } } fclose(f); f = nullptr; |