904 lines
28 KiB
C
904 lines
28 KiB
C
/*-
|
|
* Copyright (c) 2017-2019 Carsten Sonne Larsen <cs@innolan.net>
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#include "state.h"
|
|
#include "mem.h"
|
|
|
|
struct AppState *Globals;
|
|
struct AppSettingKeys *SettingKeys;
|
|
|
|
static const struct AppSettingKeys SettingKeyStruct = {
|
|
.DestinationAddress = KEYWORD_SERVER,
|
|
.DestinationPort = KEYWORD_PORT,
|
|
.Threshold = KEYWORD_THRESHOLD,
|
|
.Interval = KEYWORD_INTERVAL,
|
|
.Priority = KEYWORD_PRIORITY,
|
|
.PopKey = KEYWORD_POPKEY,
|
|
.Popup = KEYWORD_POPUP,
|
|
.Readonly = KEYWORD_READONLY,
|
|
.Expert = KEYWORD_EXPERT,
|
|
.Timeout = KEYWORD_TIMEOUT,
|
|
.Verbose = KEYWORD_VERBOSE,
|
|
.LogFile = KEYWORD_LOGFILE};
|
|
|
|
const struct AppSettings DefaultSettings = {
|
|
.Type = DefaultSettingType,
|
|
.DestinationAddress = (char *)SERVER_DEF,
|
|
.DestinationPort = (char *)PORT_DEF,
|
|
.Timeout = TIMEOUT_DEF,
|
|
.Interval = INTERVAL_DEF,
|
|
.PopKey = POPKEY_DEF,
|
|
.Popup = POPUP_DEF,
|
|
.Verbose = VERBOSE_DEF,
|
|
.Readonly = READONLY_DEF,
|
|
.Expert = EXPERT_DEF,
|
|
.Priority = PRIORITY_DEF,
|
|
.Threshold = THRESHOLD_DEF,
|
|
.LogFile = (char *)LOGFILE_DEF,
|
|
.Values = 0xFFFF};
|
|
|
|
static void SetPrioritySetting(struct AppSettings *, void *);
|
|
static void SetIntervalSetting(struct AppSettings *, void *);
|
|
static void SetVerboseSetting(struct AppSettings *, void *);
|
|
static void SetTimeoutSetting(struct AppSettings *, void *);
|
|
static void SetThresholdSetting(struct AppSettings *, void *);
|
|
static void SetDestinationAddressSetting(struct AppSettings *, void *);
|
|
static void SetDestinationPortSetting(struct AppSettings *, void *);
|
|
static void SetReadOnlySetting(struct AppSettings *, void *);
|
|
static void SetExpertSetting(struct AppSettings *, void *);
|
|
static void SetLogFileSetting(struct AppSettings *, void *);
|
|
static void SetPopupSetting(struct AppSettings *, void *);
|
|
static void SetPopKeySetting(struct AppSettings *, void *);
|
|
|
|
// Keyword order in settingFunctions needs to match order in keyword template
|
|
const struct SettingFunc settingFunctions[] = {
|
|
{KEYWORD_READONLY, SetReadOnlySetting},
|
|
{KEYWORD_EXPERT, SetExpertSetting},
|
|
{KEYWORD_SERVER, SetDestinationAddressSetting},
|
|
{KEYWORD_PORT, SetDestinationPortSetting},
|
|
{KEYWORD_TIMEOUT, SetTimeoutSetting},
|
|
{KEYWORD_THRESHOLD, SetThresholdSetting},
|
|
{KEYWORD_INTERVAL, SetIntervalSetting},
|
|
{KEYWORD_VERBOSE, SetVerboseSetting},
|
|
{KEYWORD_PRIORITY, SetPrioritySetting},
|
|
{KEYWORD_POPKEY, SetPopKeySetting},
|
|
{KEYWORD_POPUP, SetPopupSetting},
|
|
{KEYWORD_LOGFILE, SetLogFileSetting}};
|
|
|
|
static const char *prefsFile = "ENV:timekeeper.prefs";
|
|
static const char *persistentPrefsFile = "ENVARC:timekeeper.prefs";
|
|
static const char *prefsFileSearch = "Searching for preference in %s";
|
|
static const char *prefsFileFound = "Found preference file";
|
|
static const char *prefsFileNotFound = "Preference file not found";
|
|
static const char *prefsFileSave = "Saving preferences in %s";
|
|
static const char *fileOpenError = "Could not open preference file";
|
|
static const char *fileSaveError = "Could not save preference file";
|
|
static const char *fileReadError = "Error while reading file";
|
|
static const char *fileWriteError = "Error while writing file";
|
|
static const char *unknownSetting = "Found unknown setting in preference file: %s";
|
|
static const char *foundSetting = "Found %s in preference file";
|
|
static const char *foundWbSetting = "Found tooltype from icon: %s";
|
|
static const char *foundCliSetting = "Got %s from CLI";
|
|
static const char *integerError = "Value should be an integer: %s";
|
|
static const char *yesNoError = "Value should be YES or NO: %s";
|
|
static const char *applyDefaultSettings = "Applying default values";
|
|
static const char *applyFileSettings = "Applying values from preference file";
|
|
static const char *applyCliSettings = "Applying values from CLI";
|
|
static const char *applyWbSettings = "Applying values from tooltypes";
|
|
static const char *effectiveSettings = "Listing runtime values";
|
|
static const char *settingTooLow = "%s < %ld (too low)";
|
|
static const char *settingTooHigh = "%s > %ld (too high)";
|
|
static const char *settingGreaterThan = "%s > %s";
|
|
static const char *settingChangedLong = "%s changed: %ld -> %ld";
|
|
static const char *settingChangedString = "%s changed: %s -> %s";
|
|
static const char *settingSetLong = "%s already set to %ld";
|
|
static const char *settingSetString = "%s already set to %s";
|
|
static const char *settingValueLong = "%s=%ld";
|
|
static const char *settingValueString = "%s=%s";
|
|
static const char *saveValueLong = "%s=%ld\n";
|
|
static const char *saveValueString = "%s=%s\n";
|
|
|
|
static const char *noLogFile = "(none)";
|
|
static const char *noValueString = "NO";
|
|
static const char *yesValueString = "YES";
|
|
|
|
#define MAXSETTINGLINELEN 256
|
|
|
|
static struct AppSettings *fileSettings;
|
|
static struct AppSettings *cachedSettings;
|
|
|
|
void InitState(void)
|
|
{
|
|
Globals = (struct AppState *)AllocMemSafe(sizeof(struct AppState));
|
|
Globals->Broker = (struct AppBroker *)AllocMemSafe(sizeof(struct AppBroker));
|
|
Globals->Window = (struct AppSettingWindow *)AllocMemSafe(sizeof(struct AppSettingWindow));
|
|
Globals->Settings = CreateSettings(GlobalSettingType);
|
|
Globals->Locale = OpenLocale(NULL);
|
|
SettingKeys = (struct AppSettingKeys *)&SettingKeyStruct;
|
|
}
|
|
|
|
void DestroyState(void)
|
|
{
|
|
if (Globals->Syncer != NULL)
|
|
{
|
|
FreeMemSafe(Globals->Syncer);
|
|
Globals->Syncer = NULL;
|
|
}
|
|
|
|
FreeSettings(Globals->Settings);
|
|
CloseLocale(Globals->Locale);
|
|
FreeMemSafe((void *)Globals->Window);
|
|
FreeMemSafe((void *)Globals->Broker);
|
|
FreeMemSafe((void *)Globals);
|
|
}
|
|
|
|
static char *BooleanAsText(bool value)
|
|
{
|
|
return (char *)(value ? yesValueString : noValueString);
|
|
}
|
|
|
|
void ShowAppSettings(struct AppSettings *settings)
|
|
{
|
|
char low[MAXLONGLONGCHARSIZE];
|
|
|
|
LongLongToStr(settings->Threshold, low);
|
|
LogTrace(settingValueString, SettingKeys->Popup, BooleanAsText(settings->Popup));
|
|
LogTrace(settingValueString, SettingKeys->PopKey, settings->PopKey);
|
|
LogTrace(settingValueLong, SettingKeys->Priority, settings->Priority);
|
|
LogTrace(settingValueString, SettingKeys->Threshold, low);
|
|
LogTrace(settingValueString, SettingKeys->DestinationAddress, settings->DestinationAddress);
|
|
LogTrace(settingValueString, SettingKeys->DestinationPort, settings->DestinationPort);
|
|
LogTrace(settingValueLong, SettingKeys->Timeout, settings->Timeout);
|
|
LogTrace(settingValueLong, SettingKeys->Interval, settings->Interval);
|
|
LogTrace(settingValueLong, SettingKeys->Verbose, settings->Verbose);
|
|
LogTrace(settingValueString, SettingKeys->Readonly, BooleanAsText(settings->Readonly));
|
|
LogTrace(settingValueString, SettingKeys->Expert, BooleanAsText(settings->Expert));
|
|
LogTrace(settingValueString, SettingKeys->LogFile,
|
|
settings->LogFile ? settings->LogFile : noLogFile);
|
|
}
|
|
|
|
void ShowSettings(void)
|
|
{
|
|
LogTrace(effectiveSettings);
|
|
ShowAppSettings(Globals->Settings);
|
|
}
|
|
|
|
void LogFoundSetting(long type, const char *name)
|
|
{
|
|
switch (type)
|
|
{
|
|
case PrefsSettingType:
|
|
LogTrace(foundSetting, name);
|
|
break;
|
|
case CliSettingType:
|
|
LogTrace(foundCliSetting, name);
|
|
break;
|
|
case WbSettingType:
|
|
LogTrace(foundWbSetting, name);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void ParseLongSetting(
|
|
struct AppSettings *settings,
|
|
long flag,
|
|
const char *keyword,
|
|
long *valueField,
|
|
void *value)
|
|
{
|
|
LogFoundSetting(settings->Type, keyword);
|
|
if (settings->Type == CliSettingType)
|
|
{
|
|
*valueField = *(long *)value;
|
|
settings->Values |= flag;
|
|
return;
|
|
}
|
|
|
|
if (TryParseLong((char *)value, valueField))
|
|
{
|
|
settings->Values |= flag;
|
|
return;
|
|
}
|
|
|
|
LogWarning(integerError, value);
|
|
}
|
|
|
|
static void ParseBooleanSetting(
|
|
struct AppSettings *settings,
|
|
long flag,
|
|
const char *keyword,
|
|
long *valueField,
|
|
void *value,
|
|
bool yesNo)
|
|
{
|
|
LogFoundSetting(settings->Type, SettingKeys->Popup);
|
|
|
|
// CLI switch is always a long value
|
|
if (settings->Type == CliSettingType && !yesNo)
|
|
{
|
|
*valueField = (*valueField != 0 ? true : false);
|
|
settings->Values |= flag;
|
|
return;
|
|
}
|
|
|
|
if (value == NULL || *((const char *)value) == '\0')
|
|
{
|
|
LogWarning(yesNoError, '\0');
|
|
return;
|
|
}
|
|
|
|
if (Stricmp((STRPTR)noValueString, (STRPTR)value) == 0 || Stricmp("0", (STRPTR)value) == 0)
|
|
{
|
|
*valueField = false;
|
|
settings->Values |= flag;
|
|
return;
|
|
}
|
|
|
|
if (Stricmp((STRPTR)yesValueString, (STRPTR)value) == 0 || Stricmp("1", (STRPTR)value) == 0)
|
|
{
|
|
*valueField = true;
|
|
settings->Values |= flag;
|
|
return;
|
|
}
|
|
|
|
LogWarning(yesNoError, value);
|
|
}
|
|
|
|
static void SetPrioritySetting(struct AppSettings *settings, void *value)
|
|
{
|
|
ParseLongSetting(settings, PrioritySet, SettingKeys->Priority,
|
|
&settings->Priority, value);
|
|
}
|
|
|
|
static void SetVerboseSetting(struct AppSettings *settings, void *value)
|
|
{
|
|
ParseLongSetting(settings, VerboseSet, SettingKeys->Verbose,
|
|
&settings->Verbose, value);
|
|
}
|
|
|
|
static void SetIntervalSetting(struct AppSettings *settings, void *value)
|
|
{
|
|
ParseLongSetting(settings, IntervalSet, SettingKeys->Interval,
|
|
&settings->Interval, value);
|
|
}
|
|
|
|
static void SetTimeoutSetting(struct AppSettings *settings, void *value)
|
|
{
|
|
ParseLongSetting(settings, TimeoutSet, SettingKeys->Timeout,
|
|
&settings->Timeout, value);
|
|
}
|
|
|
|
static void SetThresholdSetting(struct AppSettings *settings, void *value)
|
|
{
|
|
LogFoundSetting(settings->Type, SettingKeys->Threshold);
|
|
if (TryParseLongLong((char *)value, &settings->Threshold))
|
|
{
|
|
settings->Values |= ThresholdSet;
|
|
return;
|
|
}
|
|
|
|
LogWarning(integerError, value);
|
|
}
|
|
|
|
static void SetDestinationAddressSetting(struct AppSettings *settings, void *value)
|
|
{
|
|
LogFoundSetting(settings->Type, SettingKeys->DestinationAddress);
|
|
settings->DestinationAddress = StrDupSafe((const char *)value);
|
|
settings->Values |= DestinationAddressSet;
|
|
}
|
|
|
|
static void SetPopKeySetting(struct AppSettings *settings, void *value)
|
|
{
|
|
LogFoundSetting(settings->Type, SettingKeys->PopKey);
|
|
settings->PopKey = StrDupSafe((const char *)value);
|
|
settings->Values |= PopKeySet;
|
|
}
|
|
|
|
static void SetDestinationPortSetting(struct AppSettings *settings, void *value)
|
|
{
|
|
LogFoundSetting(settings->Type, SettingKeys->DestinationPort);
|
|
settings->DestinationPort = StrDupSafe((const char *)value);
|
|
settings->Values |= DestinationPortSet;
|
|
}
|
|
|
|
static void SetReadOnlySetting(struct AppSettings *settings, void *value)
|
|
{
|
|
ParseBooleanSetting(settings, ReadonlySet, SettingKeys->Readonly,
|
|
&settings->Readonly, value, true);
|
|
}
|
|
|
|
static void SetExpertSetting(struct AppSettings *settings, void *value)
|
|
{
|
|
ParseBooleanSetting(settings, ExpertSet, SettingKeys->Expert,
|
|
&settings->Expert, value, true);
|
|
}
|
|
|
|
static void SetPopupSetting(struct AppSettings *settings, void *value)
|
|
{
|
|
ParseBooleanSetting(settings, PopUpSet, SettingKeys->Popup,
|
|
&settings->Popup, value, false);
|
|
}
|
|
|
|
static void SetLogFileSetting(struct AppSettings *settings, void *value)
|
|
{
|
|
LogFoundSetting(settings->Type, SettingKeys->LogFile);
|
|
|
|
if (value == NULL || *((const char *)value) == '\0' ||
|
|
Stricmp((STRPTR)noValueString, (STRPTR)value) == 0 ||
|
|
Stricmp((STRPTR)noLogFile, (STRPTR)value) == 0)
|
|
{
|
|
settings->LogFile = NULL;
|
|
}
|
|
else
|
|
{
|
|
settings->LogFile = StrDupSafe((const char *)value);
|
|
}
|
|
settings->Values |= LogFileSet;
|
|
}
|
|
|
|
static void ParseSetting(struct AppSettings *settings, char *line)
|
|
{
|
|
char *value;
|
|
char *end;
|
|
int i;
|
|
|
|
value = StrChr(line, '=', MAXSETTINGLINELEN);
|
|
if (value == NULL)
|
|
{
|
|
LogWarning(unknownSetting, "No assignment");
|
|
return;
|
|
}
|
|
|
|
end = StrChr(value, '\n', MAXSETTINGLINELEN);
|
|
if (end == NULL)
|
|
{
|
|
LogWarning(unknownSetting, "No end of line");
|
|
return;
|
|
}
|
|
|
|
*value++ = '\0';
|
|
*end = '\0';
|
|
|
|
for (i = 0; i < KEYWORD_COUNT; i++)
|
|
{
|
|
if (Stricmp((STRPTR)settingFunctions[i].Name, (STRPTR)line) == 0)
|
|
{
|
|
settingFunctions[i].Function(settings, (void *)value);
|
|
return;
|
|
}
|
|
}
|
|
|
|
LogWarning(unknownSetting, line);
|
|
}
|
|
|
|
void LoadSettings(void)
|
|
{
|
|
struct AppSettings *settings;
|
|
const int maxLines = 25;
|
|
char line[MAXSETTINGLINELEN];
|
|
char message[MAXDOSERRORLEN];
|
|
bool eof = false;
|
|
int count = 0;
|
|
long error;
|
|
BPTR file;
|
|
|
|
LogTrace(prefsFileSearch, prefsFile);
|
|
file = Open((STRPTR)prefsFile, MODE_OLDFILE);
|
|
|
|
if (!file)
|
|
{
|
|
error = IoErr();
|
|
if (error == ERROR_OBJECT_NOT_FOUND)
|
|
{
|
|
LogWarning(prefsFileNotFound);
|
|
}
|
|
else
|
|
{
|
|
Fault(error, (STRPTR)fileOpenError, (STRPTR)message, MAXDOSERRORLEN);
|
|
LogWarning(message);
|
|
}
|
|
return;
|
|
}
|
|
|
|
LogInfo(prefsFileFound);
|
|
|
|
settings = CreateSettings(PrefsSettingType);
|
|
|
|
do
|
|
{
|
|
char *c = (char *)FGets(file, (STRPTR)line, MAXSETTINGLINELEN);
|
|
eof = (c == NULL);
|
|
|
|
if (!eof)
|
|
{
|
|
ParseSetting(settings, line);
|
|
count++;
|
|
}
|
|
} while (!eof && count < maxLines);
|
|
|
|
// If NULL is returned for an EOF, IoErr() will return 0.
|
|
error = IoErr();
|
|
if (error != 0)
|
|
{
|
|
Fault(error, (STRPTR)fileReadError, (STRPTR)message, MAXDOSERRORLEN);
|
|
LogError(message);
|
|
}
|
|
|
|
Close(file);
|
|
fileSettings = settings;
|
|
}
|
|
|
|
static void WriteSetting(BPTR file, const char *format, ...)
|
|
{
|
|
long count;
|
|
va_list args;
|
|
va_start(args, format);
|
|
count = VFPrintf(file, (void *)format, (void *)args);
|
|
va_end(args);
|
|
|
|
if (count <= 0)
|
|
{
|
|
long error = IoErr();
|
|
if (error != 0)
|
|
{
|
|
char message[MAXDOSERRORLEN];
|
|
Fault(error, (STRPTR)fileWriteError, (STRPTR)message, MAXDOSERRORLEN);
|
|
LogError(message);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SaveSettings(bool persist)
|
|
{
|
|
char low[MAXLONGLONGCHARSIZE];
|
|
const char *fileName = persist ? persistentPrefsFile : prefsFile;
|
|
BPTR file = Open((STRPTR)fileName, MODE_NEWFILE);
|
|
if (!file)
|
|
{
|
|
char message[MAXDOSERRORLEN];
|
|
long error = IoErr();
|
|
Fault(error, (STRPTR)fileSaveError, (STRPTR)message, MAXDOSERRORLEN);
|
|
LogWarning(message);
|
|
return;
|
|
}
|
|
|
|
LogInfo(prefsFileSave, fileName);
|
|
|
|
LongLongToStr(Globals->Settings->Threshold, low);
|
|
WriteSetting(file, saveValueString, SettingKeys->Popup, BooleanAsText(Globals->Settings->Popup));
|
|
WriteSetting(file, saveValueString, SettingKeys->PopKey, Globals->Settings->PopKey);
|
|
WriteSetting(file, saveValueLong, SettingKeys->Priority, Globals->Settings->Priority);
|
|
WriteSetting(file, saveValueString, SettingKeys->Threshold, low);
|
|
WriteSetting(file, saveValueString, SettingKeys->DestinationAddress, Globals->Settings->DestinationAddress);
|
|
WriteSetting(file, saveValueString, SettingKeys->DestinationPort, Globals->Settings->DestinationPort);
|
|
WriteSetting(file, saveValueLong, SettingKeys->Timeout, Globals->Settings->Timeout);
|
|
WriteSetting(file, saveValueLong, SettingKeys->Interval, Globals->Settings->Interval);
|
|
WriteSetting(file, saveValueLong, SettingKeys->Verbose, Globals->Settings->Verbose);
|
|
WriteSetting(file, saveValueString, SettingKeys->Readonly, BooleanAsText(Globals->Settings->Readonly));
|
|
WriteSetting(file, saveValueString, SettingKeys->Expert, BooleanAsText(Globals->Settings->Expert));
|
|
WriteSetting(file, saveValueString, SettingKeys->LogFile, Globals->Settings->LogFile);
|
|
|
|
Close(file);
|
|
}
|
|
|
|
struct AppSettings *CreateSettings(long type)
|
|
{
|
|
struct AppSettings *settings;
|
|
settings = (struct AppSettings *)AllocMemSafe(sizeof(struct AppSettings));
|
|
settings->Type = type;
|
|
return settings;
|
|
}
|
|
|
|
struct AppSettings *CopySettings(const struct AppSettings *settings)
|
|
{
|
|
struct AppSettings *s = CreateSettings(settings->Type);
|
|
CopyMem((void *)settings, s, sizeof(struct AppSettings));
|
|
s->DestinationAddress = StrDupSafe(settings->DestinationAddress);
|
|
s->DestinationPort = StrDupSafe(settings->DestinationPort);
|
|
s->PopKey = StrDupSafe(settings->PopKey);
|
|
if (s->LogFile != NULL)
|
|
{
|
|
s->LogFile = StrDupSafe(settings->LogFile);
|
|
}
|
|
s->Values = 0xFFFF;
|
|
return s;
|
|
}
|
|
|
|
void FreeSettings(struct AppSettings *settings)
|
|
{
|
|
if (settings->DestinationAddress != NULL)
|
|
{
|
|
FreeMemSafe(settings->DestinationAddress);
|
|
}
|
|
|
|
if (settings->DestinationPort != NULL)
|
|
{
|
|
FreeMemSafe(settings->DestinationPort);
|
|
}
|
|
|
|
if (settings->PopKey != NULL)
|
|
{
|
|
FreeMemSafe(settings->PopKey);
|
|
}
|
|
|
|
if (settings->LogFile != NULL)
|
|
{
|
|
FreeMemSafe(settings->LogFile);
|
|
}
|
|
|
|
FreeMemSafe(settings);
|
|
}
|
|
|
|
static void ApplyLongSetting(
|
|
struct AppSettings *settings,
|
|
long flag,
|
|
const char *keyword,
|
|
long *curValue,
|
|
long *newValue,
|
|
bool quiet)
|
|
{
|
|
if ((settings->Values & flag) == flag)
|
|
{
|
|
if (settings->Type == DefaultSettingType)
|
|
{
|
|
LogTrace(settingValueLong, keyword, *newValue);
|
|
}
|
|
else if (*curValue != *newValue)
|
|
{
|
|
LogInfo(settingChangedLong, keyword, *curValue, *newValue);
|
|
}
|
|
else if (!quiet)
|
|
{
|
|
LogTrace(settingSetLong, keyword, *newValue);
|
|
}
|
|
*curValue = *newValue;
|
|
}
|
|
}
|
|
|
|
static void ApplyBooleanSetting(
|
|
struct AppSettings *settings,
|
|
long flag,
|
|
const char *keyword,
|
|
long *curValue,
|
|
long *newValue,
|
|
bool quiet)
|
|
{
|
|
if ((settings->Values & flag) == flag)
|
|
{
|
|
if (settings->Type == DefaultSettingType)
|
|
{
|
|
LogTrace(settingValueString, keyword, BooleanAsText(*newValue));
|
|
}
|
|
else if (*curValue != *newValue)
|
|
{
|
|
LogInfo(settingChangedString, keyword, BooleanAsText(*curValue), BooleanAsText(*newValue));
|
|
}
|
|
else if (!quiet)
|
|
{
|
|
LogTrace(settingValueString, keyword, BooleanAsText(*newValue));
|
|
}
|
|
*curValue = *newValue;
|
|
}
|
|
}
|
|
|
|
static void ApplyStringSetting(
|
|
struct AppSettings *settings,
|
|
long flag,
|
|
const char *keyword,
|
|
char **curValue,
|
|
char *newValue,
|
|
bool quiet)
|
|
{
|
|
if ((settings->Values & flag) == flag)
|
|
{
|
|
if (settings->Type == DefaultSettingType)
|
|
{
|
|
LogTrace(settingValueString, keyword, newValue);
|
|
}
|
|
else if (Stricmp((STRPTR)*curValue, (STRPTR)newValue) != 0)
|
|
{
|
|
LogInfo(settingChangedString, keyword, *curValue, newValue);
|
|
}
|
|
else if (!quiet)
|
|
{
|
|
LogTrace(settingSetString, keyword, newValue);
|
|
}
|
|
|
|
if (*curValue != NULL)
|
|
{
|
|
FreeMemSafe(*curValue);
|
|
}
|
|
*curValue = StrDupSafe(newValue);
|
|
}
|
|
}
|
|
|
|
void ApplyAppSettings(struct AppSettings *settings, bool quiet)
|
|
{
|
|
switch (settings->Type)
|
|
{
|
|
case DefaultSettingType:
|
|
LogInfo(applyDefaultSettings);
|
|
break;
|
|
case PrefsSettingType:
|
|
LogInfo(applyFileSettings);
|
|
break;
|
|
case CliSettingType:
|
|
LogInfo(applyCliSettings);
|
|
break;
|
|
case WbSettingType:
|
|
LogInfo(applyWbSettings);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
ApplyBooleanSetting(settings, PopUpSet, SettingKeys->Popup,
|
|
&Globals->Settings->Popup, &settings->Popup, quiet);
|
|
|
|
ApplyStringSetting(settings, PopKeySet, SettingKeys->PopKey,
|
|
&Globals->Settings->PopKey, settings->PopKey, quiet);
|
|
|
|
ApplyLongSetting(settings, PrioritySet, SettingKeys->Priority,
|
|
&Globals->Settings->Priority, &settings->Priority, quiet);
|
|
|
|
ApplyLongSetting(settings, VerboseSet, SettingKeys->Verbose,
|
|
&Globals->Settings->Verbose, &settings->Verbose, quiet);
|
|
|
|
ApplyLongSetting(settings, TimeoutSet, SettingKeys->Timeout,
|
|
&Globals->Settings->Timeout, &settings->Timeout, quiet);
|
|
|
|
ApplyLongSetting(settings, IntervalSet, SettingKeys->Interval,
|
|
&Globals->Settings->Interval, &settings->Interval, quiet);
|
|
|
|
ApplyBooleanSetting(settings, ReadonlySet, SettingKeys->Readonly,
|
|
&Globals->Settings->Readonly, &settings->Readonly, quiet);
|
|
|
|
ApplyBooleanSetting(settings, ExpertSet, SettingKeys->Expert,
|
|
&Globals->Settings->Expert, &settings->Expert, quiet);
|
|
|
|
ApplyStringSetting(settings, DestinationAddressSet, SettingKeys->DestinationAddress,
|
|
&Globals->Settings->DestinationAddress, settings->DestinationAddress, quiet);
|
|
|
|
ApplyStringSetting(settings, DestinationPortSet, SettingKeys->DestinationPort,
|
|
&Globals->Settings->DestinationPort, settings->DestinationPort, quiet);
|
|
|
|
if ((settings->Values & ThresholdSet) == ThresholdSet)
|
|
{
|
|
char before[MAXLONGLONGCHARSIZE];
|
|
char after[MAXLONGLONGCHARSIZE];
|
|
|
|
if (settings->Type == DefaultSettingType)
|
|
{
|
|
LongLongToStr(settings->Threshold, after);
|
|
LogTrace(settingValueString, SettingKeys->Threshold, after);
|
|
}
|
|
else if (Globals->Settings->Threshold != settings->Threshold)
|
|
{
|
|
LongLongToStr(Globals->Settings->Threshold, before);
|
|
LongLongToStr(settings->Threshold, after);
|
|
LogInfo(settingChangedString, SettingKeys->Threshold, before, after);
|
|
}
|
|
else if (!quiet)
|
|
{
|
|
LongLongToStr(Globals->Settings->Threshold, before);
|
|
LogTrace(settingSetString, SettingKeys->Threshold, before);
|
|
}
|
|
Globals->Settings->Threshold = settings->Threshold;
|
|
}
|
|
|
|
if ((settings->Values & LogFileSet) == LogFileSet)
|
|
{
|
|
if (settings->Type == DefaultSettingType)
|
|
{
|
|
LogTrace(settingValueString, SettingKeys->LogFile,
|
|
settings->LogFile != NULL ? settings->LogFile : noLogFile);
|
|
}
|
|
else if (!(Globals->Settings->LogFile == NULL && settings->LogFile == NULL) ||
|
|
StrnCmp(Globals->Locale,
|
|
(STRPTR)Globals->Settings->LogFile,
|
|
(STRPTR)settings->LogFile,
|
|
(LONG)MAXSETTINGLINELEN, SC_ASCII) != 0)
|
|
{
|
|
LogInfo(settingChangedString, SettingKeys->LogFile,
|
|
Globals->Settings->LogFile != NULL ? Globals->Settings->LogFile : noLogFile,
|
|
settings->LogFile != NULL ? settings->LogFile : noLogFile);
|
|
}
|
|
else if (!quiet)
|
|
{
|
|
LogTrace(settingSetString, SettingKeys->LogFile,
|
|
settings->LogFile != NULL ? settings->LogFile : noLogFile);
|
|
}
|
|
|
|
if (Globals->Settings->LogFile != NULL)
|
|
{
|
|
FreeMemSafe(Globals->Settings->LogFile);
|
|
}
|
|
Globals->Settings->LogFile = settings->LogFile != NULL
|
|
? StrDupSafe(settings->LogFile)
|
|
: NULL;
|
|
}
|
|
}
|
|
|
|
void CacheSettings(struct AppSettings *settings)
|
|
{
|
|
if (cachedSettings != NULL)
|
|
{
|
|
FreeSettings(cachedSettings);
|
|
}
|
|
cachedSettings = settings;
|
|
}
|
|
|
|
void ApplySettings()
|
|
{
|
|
ApplyAppSettings((struct AppSettings *)&DefaultSettings, false);
|
|
|
|
if (fileSettings != NULL)
|
|
{
|
|
ApplyAppSettings(fileSettings, false);
|
|
FreeSettings(fileSettings);
|
|
}
|
|
|
|
if (cachedSettings != NULL)
|
|
{
|
|
ApplyAppSettings(cachedSettings, false);
|
|
FreeSettings(cachedSettings);
|
|
}
|
|
}
|
|
|
|
static void ValidateInterval(void)
|
|
{
|
|
if (Globals->Settings->Interval < INTERVAL_MIN)
|
|
{
|
|
LogInfo(settingTooLow,
|
|
SettingKeys->Interval,
|
|
INTERVAL_MIN);
|
|
LogInfo(settingChangedLong,
|
|
SettingKeys->Interval,
|
|
Globals->Settings->Interval,
|
|
INTERVAL_MIN);
|
|
Globals->Settings->Interval = INTERVAL_MIN;
|
|
}
|
|
}
|
|
|
|
static void ValidateTimeout(void)
|
|
{
|
|
if (Globals->Settings->Timeout < TIMEOUT_MIN)
|
|
{
|
|
LogInfo(settingTooLow,
|
|
SettingKeys->Timeout,
|
|
TIMEOUT_MIN);
|
|
LogInfo(settingChangedLong,
|
|
SettingKeys->Timeout,
|
|
Globals->Settings->Timeout,
|
|
TIMEOUT_MIN);
|
|
Globals->Settings->Timeout = TIMEOUT_MIN;
|
|
}
|
|
|
|
if (Globals->Settings->Timeout > Globals->Settings->Interval)
|
|
{
|
|
LogInfo(settingGreaterThan,
|
|
SettingKeys->Timeout,
|
|
SettingKeys->Interval);
|
|
LogInfo(settingChangedLong,
|
|
SettingKeys->Timeout,
|
|
Globals->Settings->Timeout,
|
|
Globals->Settings->Interval);
|
|
Globals->Settings->Timeout = Globals->Settings->Interval;
|
|
}
|
|
|
|
if (Globals->Settings->Timeout > TIMEOUT_MAX)
|
|
{
|
|
LogInfo(settingTooHigh,
|
|
SettingKeys->Timeout,
|
|
TIMEOUT_MAX);
|
|
LogInfo(settingChangedLong,
|
|
SettingKeys->Timeout,
|
|
Globals->Settings->Timeout,
|
|
TIMEOUT_MAX);
|
|
Globals->Settings->Timeout = TIMEOUT_MAX;
|
|
}
|
|
}
|
|
|
|
static void ValidatePriority(void)
|
|
{
|
|
if (Globals->Settings->Priority < PRIORITY_MIN)
|
|
{
|
|
LogInfo(settingTooLow,
|
|
SettingKeys->Priority,
|
|
PRIORITY_MIN);
|
|
LogInfo(settingChangedLong,
|
|
SettingKeys->Priority,
|
|
Globals->Settings->Priority,
|
|
PRIORITY_MIN);
|
|
Globals->Settings->Priority = PRIORITY_MIN;
|
|
}
|
|
|
|
if (Globals->Settings->Priority > PRIORITY_MAX)
|
|
{
|
|
LogInfo(settingTooHigh,
|
|
SettingKeys->Priority,
|
|
PRIORITY_MAX);
|
|
LogInfo(settingChangedLong,
|
|
SettingKeys->Priority,
|
|
Globals->Settings->Priority,
|
|
PRIORITY_MAX);
|
|
Globals->Settings->Priority = PRIORITY_MAX;
|
|
}
|
|
}
|
|
|
|
static void ValidateThreshold(void)
|
|
{
|
|
if (Globals->Settings->Threshold < THRESHOLD_MIN)
|
|
{
|
|
LogInfo(settingTooLow,
|
|
SettingKeys->Threshold,
|
|
THRESHOLD_MIN);
|
|
LogInfo(settingChangedLong,
|
|
SettingKeys->Threshold,
|
|
Globals->Settings->Threshold,
|
|
THRESHOLD_MIN);
|
|
Globals->Settings->Threshold = THRESHOLD_MIN;
|
|
}
|
|
}
|
|
|
|
static void ValidateVerbose(void)
|
|
{
|
|
if (Globals->Settings->Verbose < VERBOSE_MIN)
|
|
{
|
|
LogInfo(settingTooLow,
|
|
SettingKeys->Verbose,
|
|
VERBOSE_MIN);
|
|
LogInfo(settingChangedLong,
|
|
SettingKeys->Verbose,
|
|
Globals->Settings->Verbose,
|
|
VERBOSE_MIN);
|
|
Globals->Settings->Verbose = VERBOSE_MIN;
|
|
}
|
|
|
|
if (Globals->Settings->Verbose > VERBOSE_MAX)
|
|
{
|
|
LogInfo(settingTooHigh,
|
|
SettingKeys->Verbose,
|
|
VERBOSE_MAX);
|
|
LogInfo(settingChangedLong,
|
|
SettingKeys->Verbose,
|
|
Globals->Settings->Verbose,
|
|
VERBOSE_MAX);
|
|
Globals->Settings->Verbose = VERBOSE_MAX;
|
|
}
|
|
}
|
|
|
|
void SanitizeSettings(void)
|
|
{
|
|
ValidateInterval();
|
|
ValidateTimeout();
|
|
ValidatePriority();
|
|
ValidateThreshold();
|
|
ValidateVerbose();
|
|
}
|