Browse Source

Consistently use exceptions for parameter errors

Clean up the structure around storing and loading parameters and server
history so that failures will always be reported by using exceptions.
tags/v1.11.90
Pierre Ossman 2 years ago
parent
commit
76d4a33b15
2 changed files with 227 additions and 184 deletions
  1. 35
    7
      vncviewer/ServerDialog.cxx
  2. 192
    177
      vncviewer/parameters.cxx

+ 35
- 7
vncviewer/ServerDialog.cxx View File



#include <os/os.h> #include <os/os.h>
#include <rfb/Exception.h> #include <rfb/Exception.h>
#include <rfb/LogWriter.h>


#include "ServerDialog.h" #include "ServerDialog.h"
#include "OptionsDialog.h" #include "OptionsDialog.h"
using namespace std; using namespace std;
using namespace rfb; using namespace rfb;


static LogWriter vlog("ServerDialog");

const char* SERVER_HISTORY="tigervnc.history"; const char* SERVER_HISTORY="tigervnc.history";


ServerDialog::ServerDialog() ServerDialog::ServerDialog()
y = margin; y = margin;
serverName = new Fl_Input_Choice(x, y, w() - margin*2 - server_label_width, INPUT_HEIGHT, _("VNC server:")); serverName = new Fl_Input_Choice(x, y, w() - margin*2 - server_label_width, INPUT_HEIGHT, _("VNC server:"));
loadServerHistory();
for(size_t i=0;i<serverHistory.size();++i) {
serverName->add(serverHistory[i].c_str());
}


int adjust = (w() - 20) / 4; int adjust = (w() - 20) / 4;
int button_width = adjust - margin/2; int button_width = adjust - margin/2;
dialog.serverName->value(servername); dialog.serverName->value(servername);


dialog.show(); dialog.show();

try {
size_t i;

dialog.loadServerHistory();

dialog.serverName->clear();
for(i = 0; i < dialog.serverHistory.size(); ++i)
dialog.serverName->add(dialog.serverHistory[i].c_str());
} catch (Exception& e) {
vlog.error("%s", e.str());
fl_alert(_("Unable to load the server history:\n\n%s"),
e.str());
}

while (dialog.shown()) Fl::wait(); while (dialog.shown()) Fl::wait();


if (dialog.serverName->value() == NULL) { if (dialog.serverName->value() == NULL) {
try { try {
dialog->serverName->value(loadViewerParameters(filename)); dialog->serverName->value(loadViewerParameters(filename));
} catch (Exception& e) { } catch (Exception& e) {
fl_alert("%s", e.str());
vlog.error("%s", e.str());
fl_alert(_("Unable to load the specified configuration file:\n\n%s"),
e.str());
} }


delete(file_chooser); delete(file_chooser);
try { try {
saveViewerParameters(filename, servername); saveViewerParameters(filename, servername);
} catch (Exception& e) { } catch (Exception& e) {
fl_alert("%s", e.str());
vlog.error("%s", e.str());
fl_alert(_("Unable to save the specified configuration "
"file:\n\n%s"), e.str());
} }
delete(file_chooser); delete(file_chooser);


try { try {
saveViewerParameters(NULL, servername); saveViewerParameters(NULL, servername);
} catch (Exception& e) {
vlog.error("%s", e.str());
fl_alert(_("Unable to save the default configuration:\n\n%s"),
e.str());
}


try {
vector<string>::iterator elem = std::find(dialog->serverHistory.begin(), dialog->serverHistory.end(), servername); vector<string>::iterator elem = std::find(dialog->serverHistory.begin(), dialog->serverHistory.end(), servername);
// avoid duplicates in the history // avoid duplicates in the history
if(dialog->serverHistory.end() == elem) { if(dialog->serverHistory.end() == elem) {
dialog->saveServerHistory(); dialog->saveServerHistory();
} }
} catch (Exception& e) { } catch (Exception& e) {
fl_alert("%s", e.str());
vlog.error("%s", e.str());
fl_alert(_("Unable to save the server history:\n\n%s"),
e.str());
} }
} }




void ServerDialog::loadServerHistory() void ServerDialog::loadServerHistory()
{ {
serverHistory.clear();

#ifdef _WIN32 #ifdef _WIN32
loadHistoryFromRegKey(serverHistory); loadHistoryFromRegKey(serverHistory);
return; return;

+ 192
- 177
vncviewer/parameters.cxx View File



wchar_t name[buffersize]; wchar_t name[buffersize];
unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize); unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
if (size >= buffersize) {
vlog.error(_("The name of the parameter %s was too large to write to the registry"), _name);
return;
}
if (size >= buffersize)
throw Exception(_("The name of the parameter is too large"));


char encodingBuffer[buffersize]; char encodingBuffer[buffersize];
if (!encodeValue(_value, encodingBuffer, buffersize)) {
vlog.error(_("The parameter %s was too large to write to the registry"), _name);
return;
}
if (!encodeValue(_value, encodingBuffer, buffersize))
throw Exception(_("The parameter is too large"));


wchar_t value[buffersize]; wchar_t value[buffersize];
size = fl_utf8towc(encodingBuffer, strlen(encodingBuffer)+1, value, buffersize); size = fl_utf8towc(encodingBuffer, strlen(encodingBuffer)+1, value, buffersize);
if (size >= buffersize) {
vlog.error(_("The parameter %s was too large to write to the registry"), _name);
return;
}
if (size >= buffersize)
throw Exception(_("The parameter is too large"));


LONG res = RegSetValueExW(*hKey, name, 0, REG_SZ, (BYTE*)&value, (wcslen(value)+1)*2); LONG res = RegSetValueExW(*hKey, name, 0, REG_SZ, (BYTE*)&value, (wcslen(value)+1)*2);
if (res != ERROR_SUCCESS) {
vlog.error(_("Failed to write parameter %s of type %s to the registry: %ld"),
_name, "REG_SZ", res);
return;
}
if (res != ERROR_SUCCESS)
throw rdr::SystemException("RegSetValueExW", res);
} }




DWORD value = _value; DWORD value = _value;


unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize); unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
if (size >= buffersize) {
vlog.error(_("The name of the parameter %s was too large to write to the registry"), _name);
return;
}
if (size >= buffersize)
throw Exception(_("The name of the parameter is too large"));

LONG res = RegSetValueExW(*hKey, name, 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD)); LONG res = RegSetValueExW(*hKey, name, 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
if (res != ERROR_SUCCESS) {
vlog.error(_("Failed to write parameter %s of type %s to the registry: %ld"),
_name, "REG_DWORD", res);
return;
}
if (res != ERROR_SUCCESS)
throw rdr::SystemException("RegSetValueExW", res);
} }




DWORD valuesize; DWORD valuesize;


unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize); unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
if (size >= buffersize) {
vlog.error(_("The name of the parameter %s was too large to read from the registry"), _name);
return false;
}
if (size >= buffersize)
throw Exception(_("The name of the parameter is too large"));


value = new WCHAR[destSize]; value = new WCHAR[destSize];
valuesize = destSize; valuesize = destSize;
LONG res = RegQueryValueExW(*hKey, name, 0, NULL, (LPBYTE)value, &valuesize); LONG res = RegQueryValueExW(*hKey, name, 0, NULL, (LPBYTE)value, &valuesize);
if (res != ERROR_SUCCESS){ if (res != ERROR_SUCCESS){
delete [] value; delete [] value;
if (res == ERROR_FILE_NOT_FOUND) {
// The value does not exist, defaults will be used.
} else {
vlog.error(_("Failed to read parameter %s from the registry: %ld"),
_name, res);
}
if (res != ERROR_FILE_NOT_FOUND)
throw rdr::SystemException("RegQueryValueExW", res);
// The value does not exist, defaults will be used.
return false; return false;
} }

char* utf8val = new char[destSize]; char* utf8val = new char[destSize];
size = fl_utf8fromwc(utf8val, destSize, value, wcslen(value)+1); size = fl_utf8fromwc(utf8val, destSize, value, wcslen(value)+1);
delete [] value; delete [] value;
if (size >= destSize) { if (size >= destSize) {
delete [] utf8val; delete [] utf8val;
vlog.error(_("The parameter %s was too large to read from the registry"), _name);
return false;
throw Exception(_("The parameter is too large"));
} }
bool ret = decodeValue(utf8val, dest, destSize); bool ret = decodeValue(utf8val, dest, destSize);
delete [] utf8val; delete [] utf8val;


return ret;
if (!ret)
throw Exception(_("Invalid format or too large value"));

return true;
} }




wchar_t name[buffersize]; wchar_t name[buffersize];


unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize); unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
if (size >= buffersize) {
vlog.error(_("The name of the parameter %s was too large to read from the registry"), _name);
return false;
}
if (size >= buffersize)
throw Exception(_("The name of the parameter is too large"));


LONG res = RegQueryValueExW(*hKey, name, 0, NULL, (LPBYTE)&value, &dwordsize); LONG res = RegQueryValueExW(*hKey, name, 0, NULL, (LPBYTE)&value, &dwordsize);
if (res != ERROR_SUCCESS){ if (res != ERROR_SUCCESS){
if (res == ERROR_FILE_NOT_FOUND) {
// The value does not exist, defaults will be used.
} else {
vlog.error(_("Failed to read parameter %s from the registry: %ld"),
_name, res);
}
if (res != ERROR_FILE_NOT_FOUND)
throw rdr::SystemException("RegQueryValueExW", res);
// The value does not exist, defaults will be used.
return false; return false;
} }


return true; return true;
} }


static bool removeValue(const char* _name, HKEY* hKey) {
static void removeValue(const char* _name, HKEY* hKey) {
const DWORD buffersize = 256; const DWORD buffersize = 256;
wchar_t name[buffersize]; wchar_t name[buffersize];


unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize); unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
if (size >= buffersize) {
vlog.error(_("The name of the parameter %s was too large to remove from the registry"), _name);
return false;
}
if (size >= buffersize)
throw Exception(_("The name of the parameter is too large"));


LONG res = RegDeleteValueW(*hKey, name); LONG res = RegDeleteValueW(*hKey, name);
if (res != ERROR_SUCCESS) { if (res != ERROR_SUCCESS) {
if (res == ERROR_FILE_NOT_FOUND) {
// The value does not exist, no need to remove it.
return true;
} else {
vlog.error(_("Failed to remove parameter %s from the registry: %ld"),
_name, res);
return false;
}
if (res != ERROR_FILE_NOT_FOUND)
throw rdr::SystemException("RegDeleteValueW", res);
// The value does not exist, no need to remove it.
return;
} }

return true;
} }


void saveHistoryToRegKey(const vector<string>& serverHistory) { void saveHistoryToRegKey(const vector<string>& serverHistory) {
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&hKey, NULL); &hKey, NULL);


if (res != ERROR_SUCCESS) {
vlog.error(_("Failed to create registry key: %ld"), res);
return;
}
if (res != ERROR_SUCCESS)
throw rdr::SystemException(_("Failed to create registry key"), res);


size_t index = 0; size_t index = 0;
assert(SERVER_HISTORY_SIZE < 100); assert(SERVER_HISTORY_SIZE < 100);
char indexString[3]; char indexString[3];


while(index < serverHistory.size() && index <= SERVER_HISTORY_SIZE) {
snprintf(indexString, 3, "%d", index);
setKeyString(indexString, serverHistory[index].c_str(), &hKey);
index++;
try {
while(index < serverHistory.size() && index <= SERVER_HISTORY_SIZE) {
snprintf(indexString, 3, "%d", index);
setKeyString(indexString, serverHistory[index].c_str(), &hKey);
index++;
}
} catch (Exception& e) {
RegCloseKey(hKey);
throw;
} }


res = RegCloseKey(hKey); res = RegCloseKey(hKey);
if (res != ERROR_SUCCESS) {
vlog.error(_("Failed to close registry key: %ld"), res);
}
if (res != ERROR_SUCCESS)
throw rdr::SystemException(_("Failed to close registry key"), res);
} }


static void saveToReg(const char* servername) { static void saveToReg(const char* servername) {
L"Software\\TigerVNC\\vncviewer", 0, NULL, L"Software\\TigerVNC\\vncviewer", 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&hKey, NULL); &hKey, NULL);
if (res != ERROR_SUCCESS) {
vlog.error(_("Failed to create registry key: %ld"), res);
return;
}
if (res != ERROR_SUCCESS)
throw rdr::SystemException(_("Failed to create registry key"), res);


setKeyString("ServerName", servername, &hKey);
try {
setKeyString("ServerName", servername, &hKey);
} catch (Exception& e) {
RegCloseKey(hKey);
throw Exception(_("Failed to save \"%s\": %s"),
"ServerName", e.str());
}


for (size_t i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) { for (size_t i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) {
if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) {
setKeyString(parameterArray[i]->getName(), *(StringParameter*)parameterArray[i], &hKey);
} else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) {
setKeyInt(parameterArray[i]->getName(), (int)*(IntParameter*)parameterArray[i], &hKey);
} else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) {
setKeyInt(parameterArray[i]->getName(), (int)*(BoolParameter*)parameterArray[i], &hKey);
} else {
vlog.error(_("Unknown parameter type for parameter %s"),
parameterArray[i]->getName());
try {
if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) {
setKeyString(parameterArray[i]->getName(), *(StringParameter*)parameterArray[i], &hKey);
} else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) {
setKeyInt(parameterArray[i]->getName(), (int)*(IntParameter*)parameterArray[i], &hKey);
} else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) {
setKeyInt(parameterArray[i]->getName(), (int)*(BoolParameter*)parameterArray[i], &hKey);
} else {
throw Exception(_("Unknown parameter type"));
}
} catch (Exception& e) {
RegCloseKey(hKey);
throw Exception(_("Failed to save \"%s\": %s"),
parameterArray[i]->getName(), e.str());
} }
} }


// Remove read-only parameters to replicate the behaviour of Linux/macOS when they // 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 // store a config to disk. If the parameter hasn't been migrated at this point it
// will be lost. // will be lost.
for (size_t i = 0; i < sizeof(readOnlyParameterArray)/sizeof(VoidParameter*); i++)
removeValue(readOnlyParameterArray[i]->getName(), &hKey);
for (size_t i = 0; i < sizeof(readOnlyParameterArray)/sizeof(VoidParameter*); i++) {
try {
removeValue(readOnlyParameterArray[i]->getName(), &hKey);
} catch (Exception& e) {
RegCloseKey(hKey);
throw Exception(_("Failed to remove \"%s\": %s"),
readOnlyParameterArray[i]->getName(), e.str());
}
}


res = RegCloseKey(hKey); res = RegCloseKey(hKey);
if (res != ERROR_SUCCESS) {
vlog.error(_("Failed to close registry key: %ld"), res);
}
if (res != ERROR_SUCCESS)
throw rdr::SystemException(_("Failed to close registry key"), res);
} }


void loadHistoryFromRegKey(vector<string>& serverHistory) { void loadHistoryFromRegKey(vector<string>& serverHistory) {
if (res != ERROR_SUCCESS) { if (res != ERROR_SUCCESS) {
if (res == ERROR_FILE_NOT_FOUND) { if (res == ERROR_FILE_NOT_FOUND) {
// The key does not exist, defaults will be used. // The key does not exist, defaults will be used.
} else {
vlog.error(_("Failed to open registry key: %ld"), res);
return;
} }
return;

throw rdr::SystemException(_("Failed to open registry key"), res);
} }


bool stop = false;
size_t index = 0;
size_t index;
const DWORD buffersize = 256; const DWORD buffersize = 256;
char indexString[3]; char indexString[3];


while(!stop) {
for (index = 0;;index++) {
snprintf(indexString, 3, "%d", index); snprintf(indexString, 3, "%d", index);
char servernameBuffer[buffersize]; char servernameBuffer[buffersize];
if (getKeyString(indexString, servernameBuffer, buffersize, &hKey)) {
serverHistory.push_back(servernameBuffer);
index++;
}
else {
stop = true;

try {
if (!getKeyString(indexString, servernameBuffer,
buffersize, &hKey))
break;
} catch (Exception& e) {
// Just ignore this entry and try the next one
vlog.error(_("Failed to read server history entry %d: %s"),
(int)index, e.str());
continue;
} }

serverHistory.push_back(servernameBuffer);
} }


res = RegCloseKey(hKey); res = RegCloseKey(hKey);
if (res != ERROR_SUCCESS){
vlog.error(_("Failed to close registry key: %ld"), res);
}
if (res != ERROR_SUCCESS)
throw rdr::SystemException(_("Failed to close registry key"), res);
} }


static void findAndSetViewerParametersFromReg(VoidParameter* parameters[], size_t parameters_len, HKEY* hKey) {

static void getParametersFromReg(VoidParameter* parameters[],
size_t parameters_len, HKEY* hKey)
{
const size_t buffersize = 256; const size_t buffersize = 256;
int intValue = 0; int intValue = 0;
char stringValue[buffersize]; char stringValue[buffersize];


for (size_t i = 0; i < parameters_len/sizeof(VoidParameter*); i++) { for (size_t i = 0; i < parameters_len/sizeof(VoidParameter*); i++) {
if (dynamic_cast<StringParameter*>(parameters[i]) != NULL) {
if (getKeyString(parameters[i]->getName(), stringValue, buffersize, hKey))
parameters[i]->setParam(stringValue);
} else if (dynamic_cast<IntParameter*>(parameters[i]) != NULL) {
if (getKeyInt(parameters[i]->getName(), &intValue, hKey))
((IntParameter*)parameters[i])->setParam(intValue);
} else if (dynamic_cast<BoolParameter*>(parameters[i]) != NULL) {
if (getKeyInt(parameters[i]->getName(), &intValue, hKey))
((BoolParameter*)parameters[i])->setParam(intValue);
} else {
vlog.error(_("Unknown parameter type for parameter %s"),
parameters[i]->getName());
try {
if (dynamic_cast<StringParameter*>(parameters[i]) != NULL) {
if (getKeyString(parameters[i]->getName(), stringValue, buffersize, hKey))
parameters[i]->setParam(stringValue);
} else if (dynamic_cast<IntParameter*>(parameters[i]) != NULL) {
if (getKeyInt(parameters[i]->getName(), &intValue, hKey))
((IntParameter*)parameters[i])->setParam(intValue);
} else if (dynamic_cast<BoolParameter*>(parameters[i]) != NULL) {
if (getKeyInt(parameters[i]->getName(), &intValue, hKey))
((BoolParameter*)parameters[i])->setParam(intValue);
} else {
throw Exception(_("Unknown parameter type"));
}
} catch(Exception& e) {
// Just ignore this entry and continue with the rest
vlog.error(_("Failed to read parameter \"%s\": %s"),
parameters[i]->getName(), e.str());
} }
} }
} }
if (res != ERROR_SUCCESS) { if (res != ERROR_SUCCESS) {
if (res == ERROR_FILE_NOT_FOUND) { if (res == ERROR_FILE_NOT_FOUND) {
// The key does not exist, defaults will be used. // The key does not exist, defaults will be used.
} else {
vlog.error(_("Failed to open registry key: %ld"), res);
return NULL;
} }
return NULL;

throw rdr::SystemException(_("Failed to open registry key"), res);
} }


const size_t buffersize = 256; const size_t buffersize = 256;
static char servername[buffersize]; static char servername[buffersize];


char servernameBuffer[buffersize]; char servernameBuffer[buffersize];
if (getKeyString("ServerName", servernameBuffer, buffersize, &hKey))
snprintf(servername, buffersize, "%s", servernameBuffer);
findAndSetViewerParametersFromReg(parameterArray, sizeof(parameterArray), &hKey);
findAndSetViewerParametersFromReg(readOnlyParameterArray, sizeof(readOnlyParameterArray), &hKey);
try {
if (getKeyString("ServerName", servernameBuffer, buffersize, &hKey))
snprintf(servername, buffersize, "%s", servernameBuffer);
} catch(Exception& e) {
vlog.error(_("Failed to read parameter \"%s\": %s"),
"ServerName", e.str());
strcpy(servername, "");
}

getParametersFromReg(parameterArray, sizeof(parameterArray), &hKey);
getParametersFromReg(readOnlyParameterArray,
sizeof(readOnlyParameterArray), &hKey);


res = RegCloseKey(hKey); res = RegCloseKey(hKey);
if (res != ERROR_SUCCESS){
vlog.error(_("Failed to close registry key: %ld"), res);
}
if (res != ERROR_SUCCESS)
throw rdr::SystemException(_("Failed to close registry key"), res);

return servername; return servername;
} }
#endif // _WIN32 #endif // _WIN32
#endif #endif
char* homeDir = NULL; char* homeDir = NULL;
if (getvnchomedir(&homeDir) == -1) {
vlog.error(_("Failed to write configuration file, can't obtain home "
"directory path."));
return;
}
if (getvnchomedir(&homeDir) == -1)
throw Exception(_("Could not obtain the home directory path"));


snprintf(filepath, sizeof(filepath), "%sdefault.tigervnc", homeDir); snprintf(filepath, sizeof(filepath), "%sdefault.tigervnc", homeDir);
delete[] homeDir; delete[] homeDir;
fprintf(f, "%s\n", IDENTIFIER_STRING); fprintf(f, "%s\n", IDENTIFIER_STRING);
fprintf(f, "\n"); fprintf(f, "\n");


if (encodeValue(servername, encodingBuffer, buffersize))
fprintf(f, "ServerName=%s\n", encodingBuffer);
if (!encodeValue(servername, encodingBuffer, buffersize)) {
fclose(f);
throw Exception(_("Failed to save \"%s\": %s"),
"ServerName", _("Could not encode parameter"));
}
fprintf(f, "ServerName=%s\n", encodingBuffer);


for (size_t i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) { for (size_t i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) {
if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) { if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) {
if (encodeValue(*(StringParameter*)parameterArray[i], encodingBuffer, buffersize))
fprintf(f, "%s=%s\n", ((StringParameter*)parameterArray[i])->getName(), encodingBuffer);
if (!encodeValue(*(StringParameter*)parameterArray[i],
encodingBuffer, buffersize)) {
fclose(f);
throw Exception(_("Failed to save \"%s\": %s"),
parameterArray[i]->getName(),
_("Could not encode parameter"));
}
fprintf(f, "%s=%s\n", ((StringParameter*)parameterArray[i])->getName(), encodingBuffer);
} else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) { } else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) {
fprintf(f, "%s=%d\n", ((IntParameter*)parameterArray[i])->getName(), (int)*(IntParameter*)parameterArray[i]); fprintf(f, "%s=%d\n", ((IntParameter*)parameterArray[i])->getName(), (int)*(IntParameter*)parameterArray[i]);
} else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) { } else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) {
fprintf(f, "%s=%d\n", ((BoolParameter*)parameterArray[i])->getName(), (int)*(BoolParameter*)parameterArray[i]); fprintf(f, "%s=%d\n", ((BoolParameter*)parameterArray[i])->getName(), (int)*(BoolParameter*)parameterArray[i]);
} else { } else {
vlog.error(_("Unknown parameter type for parameter %s"),
parameterArray[i]->getName());
fclose(f);
throw Exception(_("Failed to save \"%s\": %s"),
parameterArray[i]->getName(),
_("Unknown parameter type"));
} }
} }
fclose(f); fclose(f);


static bool findAndSetViewerParameterFromValue( static bool findAndSetViewerParameterFromValue(
VoidParameter* parameters[], size_t parameters_len, VoidParameter* parameters[], size_t parameters_len,
char* value, char* line, int lineNr, char* filepath)
char* value, char* line, char* filepath)
{ {
const size_t buffersize = 256; const size_t buffersize = 256;
char decodingBuffer[buffersize]; char decodingBuffer[buffersize];


if (dynamic_cast<StringParameter*>(parameters[i]) != NULL) { if (dynamic_cast<StringParameter*>(parameters[i]) != NULL) {
if (strcasecmp(line, ((StringParameter*)parameters[i])->getName()) == 0) { if (strcasecmp(line, ((StringParameter*)parameters[i])->getName()) == 0) {

if(!decodeValue(value, decodingBuffer, sizeof(decodingBuffer))) {
vlog.error(_("Failed to read line %d in file %s: %s"),
lineNr, filepath, _("Invalid format or too large value"));
continue;
}
if(!decodeValue(value, decodingBuffer, sizeof(decodingBuffer)))
throw Exception(_("Invalid format or too large value"));
((StringParameter*)parameters[i])->setParam(decodingBuffer); ((StringParameter*)parameters[i])->setParam(decodingBuffer);
return false; return false;
} }
} }


} else { } else {
vlog.error(_("Unknown parameter type for parameter %s"),
parameters[i]->getName());
throw Exception(_("Unknown parameter type"));
} }
} }


if (feof(f)) if (feof(f))
break; break;


fclose(f);
throw Exception(_("Failed to read line %d in file %s: %s"), throw Exception(_("Failed to read line %d in file %s: %s"),
lineNr, filepath, strerror(errno)); lineNr, filepath, strerror(errno));
} }


if (strlen(line) == (sizeof(line) - 1))
if (strlen(line) == (sizeof(line) - 1)) {
fclose(f);
throw Exception(_("Failed to read line %d in file %s: %s"), throw Exception(_("Failed to read line %d in file %s: %s"),
lineNr, filepath, _("Line too long")); lineNr, filepath, _("Line too long"));
}

// Make sure that the first line of the file has the file identifier string // Make sure that the first line of the file has the file identifier string
if(lineNr == 1) { if(lineNr == 1) {
if(strncmp(line, IDENTIFIER_STRING, strlen(IDENTIFIER_STRING)) == 0) if(strncmp(line, IDENTIFIER_STRING, strlen(IDENTIFIER_STRING)) == 0)
continue; continue;
else
throw Exception(_("Configuration file %s is in an invalid format"),
filepath);

fclose(f);
throw Exception(_("Configuration file %s is in an invalid format"),
filepath);
} }
// Skip empty lines and comments // Skip empty lines and comments
bool invalidParameterName = true; // Will be set to false below if bool invalidParameterName = true; // Will be set to false below if
// the line contains a valid name. // the line contains a valid name.


if (strcasecmp(line, "ServerName") == 0) {
try {
if (strcasecmp(line, "ServerName") == 0) {


if(!decodeValue(value, decodingBuffer, sizeof(decodingBuffer))) {
vlog.error(_("Failed to read line %d in file %s: %s"),
lineNr, filepath, _("Invalid format or too large value"));
continue;
}
snprintf(servername, sizeof(decodingBuffer), "%s", decodingBuffer);
invalidParameterName = false;
if(!decodeValue(value, decodingBuffer, sizeof(decodingBuffer)))
throw Exception(_("Invalid format or too large value"));
snprintf(servername, sizeof(decodingBuffer), "%s", decodingBuffer);
invalidParameterName = false;


} else {
invalidParameterName = findAndSetViewerParameterFromValue(parameterArray, sizeof(parameterArray),
value, line, lineNr, filepath);
} else {
invalidParameterName = findAndSetViewerParameterFromValue(parameterArray, sizeof(parameterArray),
value, line, filepath);


if (invalidParameterName) {
invalidParameterName = findAndSetViewerParameterFromValue(readOnlyParameterArray, sizeof(readOnlyParameterArray),
value, line, lineNr, filepath);
if (invalidParameterName) {
invalidParameterName = findAndSetViewerParameterFromValue(readOnlyParameterArray, sizeof(readOnlyParameterArray),
value, line, filepath);
}
} }
} catch(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.str());
continue;
} }


if (invalidParameterName) if (invalidParameterName)

Loading…
Cancel
Save