From dd295bb54ad2fec1a17c9730f8364e640cc9ebdd Mon Sep 17 00:00:00 2001 From: ac-stef Date: Mon, 21 Mar 2016 17:53:47 +0100 Subject: [PATCH] initialise server parameters from commandline overwrite defaults with commandline parameters before first use (log level settings used as an example) --- config/serverparameters.cfg | 15 +++++++ source/src/log.cpp | 2 +- source/src/server.cpp | 34 +++++++++++++--- source/src/serverfiles.h | 81 ++++++++++++++++++++++++++++--------- 4 files changed, 107 insertions(+), 25 deletions(-) diff --git a/config/serverparameters.cfg b/config/serverparameters.cfg index 456fdd4c..402e5f6b 100644 --- a/config/serverparameters.cfg +++ b/config/serverparameters.cfg @@ -54,4 +54,19 @@ dumpparameters:0 dumpsuggestions:1 +// **** Commandline switch overrides **** + +// logthreshold_console Console log level +// integer [0..5], default 2, 0:debug, 1:verbose, 2:info, 3:warning, 4:error, 5:disabled +//logthreshold_console:2 + +// logthreshold_file Logfile log level +// integer [0..5], default 2, 0:debug, 1:verbose, 2:info, 3:warning, 4:error, 5:disabled +//logthreshold_file:2 + +// logthreshold_syslog Syslog log level +// integer [0..5], default 5, 0:debug, 1:verbose, 2:info, 3:warning, 4:error, 5:disabled +//logthreshold_syslog:5 + + diff --git a/source/src/log.cpp b/source/src/log.cpp index 5337466e..9fb5bb73 100644 --- a/source/src/log.cpp +++ b/source/src/log.cpp @@ -71,7 +71,7 @@ void exitlogging() { if(fp) { fclose(fp); fp = NULL; } #ifdef AC_USE_SYSLOG - if(syslogthreshold < ACLOG_NUM) closelog(); + if(enabled && syslogthreshold < ACLOG_NUM) closelog(); #endif syslogthreshold = ACLOG_NUM; enabled = false; diff --git a/source/src/server.cpp b/source/src/server.cpp index e120c929..6c47d33b 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -4593,6 +4593,24 @@ void quitproc(int param) exit(param == 2 ? EXIT_SUCCESS : EXIT_FAILURE); // 3 is the only reply on Win32 apparently, SIGINT == 2 == Ctrl-C } +const char *loglevelnames[] = { "debug", "verbose", "info", "warning", "error", "disabled", "" }; + +SERVPARLISTF(logthreshold_console, 0, ACLOG_INFO, 0, loglevelnames, restartlogging, "CConsole log level"); +SERVPARLISTF(logthreshold_syslog, 0, ACLOG_NUM, 0, loglevelnames, restartlogging, "CSyslog log level"); +SERVPARLISTF(logthreshold_file, 0, ACLOG_INFO, 0, loglevelnames, restartlogging, "CLogfile log level"); + +void restartlogging() +{ + if(isdedicated) + { + exitlogging(); + string identity; + if(scl.logident[0]) filtertext(identity, scl.logident, FTXT__LOGIDENT); + else formatstring(identity)("%s#%d", scl.ip[0] ? scl.ip : "local", scl.serverport); + initlogging(identity, scl.syslogfacility, logthreshold_console, logthreshold_file, logthreshold_syslog, scl.logtimestamp, scl.logfilepath); + } +} + void initserver(bool dedicated) { copystring(servpubkey, ""); @@ -4602,16 +4620,20 @@ void initserver(bool dedicated) sg->smapname[0] = '\0'; // start logging - string identity; - if(scl.logident[0]) filtertext(identity, scl.logident, FTXT__LOGIDENT); - else formatstring(identity)("%s#%d", scl.ip[0] ? scl.ip : "local", scl.serverport); - int conthres = scl.verbose > 1 ? ACLOG_DEBUG : (scl.verbose ? ACLOG_VERBOSE : ACLOG_INFO); - if(dedicated && !initlogging(identity, scl.syslogfacility, conthres, scl.filethres, scl.syslogthres, scl.logtimestamp, scl.logfilepath)) printf("WARNING: logging not started!\n"); + initserverparameter("logthreshold_console", scl.verbose > 1 ? ACLOG_DEBUG : (scl.verbose ? ACLOG_VERBOSE : ACLOG_INFO)); + initserverparameter("logthreshold_syslog", scl.syslogthres); + initserverparameter("logthreshold_file", scl.filethres); + if((isdedicated = dedicated)) + { + restartlogging(); + if(!logcheck(ACLOG_ERROR)) printf("WARNING: logging not started!\n"); + } logline(ACLOG_INFO, "logging local AssaultCube server (version %d, protocol %d/%d) now..", AC_VERSION, SERVER_PROTOCOL_VERSION, EXT_VERSION); + copystring(sg->servdesc_current, scl.servdesc_full); servermsinit(dedicated); - if((isdedicated = dedicated)) + if(isdedicated) { serverparameters.init(scl.parfilepath); if(serverparameters.load()) serverparameters.read(); // do this early, so the parameters are properly set during initialisation diff --git a/source/src/serverfiles.h b/source/src/serverfiles.h index 578681f9..71b7f4af 100644 --- a/source/src/serverfiles.h +++ b/source/src/serverfiles.h @@ -1,16 +1,22 @@ // serverfiles.h // abuse globals to register server parameters +extern int addservparint(const char *name, int minval, int cur, int maxval, const char *list[], int *storage, int *shadowstorage, void (*fun)(), bool logchanges, bool fromfile, const char *desc); +extern bool addservparstr(const char *name, int minlen, int maxlen, int filt, const char *cur, char *storage, char *shadowstorage, void (*fun)(), bool logchanges, bool fromfile, const char *desc); #ifdef _DEBUG #define SERVPAR(name, min, cur, max, desc) int last_##name, name = addservparint(#name, min, cur, max, NULL, &name, &last_##name, NULL, false, true, desc) #define SERVPARLIST(name, min, cur, max, list, desc) int last_##name, name = addservparint(#name, min, cur, max, list, &name, &last_##name, NULL, false, true, desc) -#define SERVPARF(name, min, cur, max, body, desc) extern int last_##name, name; void var_##name() { body; } int last_##name, name = addservparint(#name, min, cur, max, NULL,&name, &last_##name, var_##name, false, true, desc) +#define SERVPARF(name, min, cur, max, fun, desc) extern void fun(); int last_##name, name = addservparint(#name, min, cur, max, NULL,&name, &last_##name, fun, false, true, desc) +#define SERVPARLISTF(name, min, cur, max, list, fun, desc) extern void fun(); int last_##name, name = addservparint(#name, min, cur, max, list, &name, &last_##name, fun, false, true, desc) #define SERVSTR(name, cur, min, max, filt, desc) char last_##name[max+1], name[max+1]; bool __sdummy_##name = addservparstr(#name, min, max, filt, cur, name, last_##name, NULL, false, true, desc) +#define SERVSTRF(name, cur, min, max, filt, fun, desc) char last_##name[max+1], name[max+1]; extern void fun(); bool __sdummy_##name = addservparstr(#name, min, max, filt, cur, name, last_##name, fun, false, true, desc) #else #define SERVPAR(name, min, cur, max, desc) int last_##name, name = addservparint(#name, min, cur, max, NULL, &name, &last_##name, NULL, false, true, NULL) #define SERVPARLIST(name, min, cur, max, list, desc) int last_##name, name = addservparint(#name, min, cur, max, list, &name, &last_##name, NULL, false, true, NULL) -#define SERVPARF(name, min, cur, max, body, desc) extern int last_##name, name; void var_##name() { body; } int last_##name, name = addservparint(#name, min, cur, max, NULL, &name, &last_##name, var_##name, false, true, NULL) +#define SERVPARF(name, min, cur, max, fun, desc) extern void fun(); int last_##name, name = addservparint(#name, min, cur, max, NULL,&name, &last_##name, fun, false, true, NULL) +#define SERVPARLISTF(name, min, cur, max, list, fun, desc) extern void fun(); int last_##name, name = addservparint(#name, min, cur, max, list, &name, &last_##name, fun, false, true, NULL) #define SERVSTR(name, cur, min, max, filt, desc) char last_##name[max+1], name[max+1]; bool __sdummy_##name = addservparstr(#name, min, max, filt, cur, name, last_##name, NULL, false, true, NULL) +#define SERVSTRF(name, cur, min, max, filt, fun, desc) char last_##name[max+1], name[max+1]; extern void fun(); bool __sdummy_##name = addservparstr(#name, min, max, filt, cur, name, last_##name, fun, false, true, NULL) #endif #define CONFIG_MAXPAR 11 @@ -1584,40 +1590,40 @@ struct servpar const char *desc; int chapter; #endif - bool log; // log value changes (careful!) + bool logchanges; // log value changes (careful!) bool fromfile; // true: value can be set by config file, false: value is set by server servpar() {} // SID_INT - servpar(int type, const char *name, int minval, int maxval, const char *list[], int *i, int *shadow_i, int defval, void (*fun)(), bool log, bool fromfile, const char *_desc) - : type(type), name(name), minval(minval), maxval(maxval), i(i), shadow_i(shadow_i), fun(fun), list(list), defaultint(defval), log(log), fromfile(fromfile) + servpar(int type, const char *name, int minval, int maxval, const char *list[], int *i, int *shadow_i, int defval, void (*fun)(), bool logchanges, bool fromfile, const char *_desc) + : type(type), name(name), minval(minval), maxval(maxval), i(i), shadow_i(shadow_i), fun(fun), list(list), defaultint(defval), logchanges(logchanges), fromfile(fromfile) { DEBUGCODE(desc = _desc); } // SID_STR - servpar(int type, const char *name, int minlen, int maxlen, int filter, char *s, char *shadow_s, const char *defaultstr, void (*fun)(), bool log, int fromfile, const char *_desc) - : type(type), name(name), minlen(minlen), maxlen(maxlen), s(s), shadow_s(shadow_s), fun(fun), defaultstr(defaultstr), filter(filter), log(log), fromfile(fromfile) + servpar(int type, const char *name, int minlen, int maxlen, int filter, char *s, char *shadow_s, const char *defaultstr, void (*fun)(), bool logchanges, int fromfile, const char *_desc) + : type(type), name(name), minlen(minlen), maxlen(maxlen), s(s), shadow_s(shadow_s), fun(fun), defaultstr(defaultstr), filter(filter), logchanges(logchanges), fromfile(fromfile) { DEBUGCODE(desc = _desc;) } }; hashtable *servpars = NULL; -int addservparint(const char *name, int minval, int cur, int maxval, const char *list[], int *storage, int *shadowstorage, void (*fun)(), bool log, bool fromfile, const char *desc) +int addservparint(const char *name, int minval, int cur, int maxval, const char *list[], int *storage, int *shadowstorage, void (*fun)(), bool logchanges, bool fromfile, const char *desc) { if(!servpars) servpars = new hashtable; if(list && minval == maxval) while(list[maxval - minval + 1][0]) maxval++; // get list length ASSERT(cur >= minval && cur <= maxval); - servpar v(SID_INT, name, minval, maxval, list, storage, shadowstorage, cur, fun, log, fromfile, desc); + servpar v(SID_INT, name, minval, maxval, list, storage, shadowstorage, cur, fun, logchanges, fromfile, desc); servpars->access(name, v); *shadowstorage = cur; return cur; } -bool addservparstr(const char *name, int minlen, int maxlen, int filt, const char *cur, char *storage, char *shadowstorage, void (*fun)(), bool log, bool fromfile, const char *desc) +bool addservparstr(const char *name, int minlen, int maxlen, int filt, const char *cur, char *storage, char *shadowstorage, void (*fun)(), bool logchanges, bool fromfile, const char *desc) { if(!servpars) servpars = new hashtable; ASSERT(maxlen > minlen && minlen >= 0 && int(strlen(cur)) >= minlen && int(strlen(cur)) <= maxlen); - servpar v(SID_STR, name, minlen, maxlen, filt, storage, shadowstorage, cur, fun, log, fromfile, desc); + servpar v(SID_STR, name, minlen, maxlen, filt, storage, shadowstorage, cur, fun, logchanges, fromfile, desc); servpars->access(name, v); strncpy(storage, cur, maxlen + 1); strncpy(shadowstorage, cur, maxlen + 1); @@ -1671,8 +1677,11 @@ struct serverparameter : serverconfigfile { if(*id.i != *id.shadow_i) { - if(id.fun) ((void (__cdecl *)())id.fun)(); + int tmp = *id.i; *id.i = *id.shadow_i; + *id.shadow_i = tmp; // for the duration of fun(), last_parname _is_ actually the old value (at any other time, it's the next value) + if(id.fun) ((void (__cdecl *)())id.fun)(); + *id.shadow_i = *id.i; } break; } @@ -1680,8 +1689,16 @@ struct serverparameter : serverconfigfile { if(strcmp(id.s, id.shadow_s)) { - if(id.fun) ((void (__cdecl *)())id.fun)(); - strncpy(id.s, id.shadow_s, id.maxlen + 1); + if(id.fun) + { + char tmp[id.maxlen + 1]; + strncpy(tmp, id.s, id.maxlen + 1); + strncpy(id.s, id.shadow_s, id.maxlen + 1); + strncpy(id.shadow_s, tmp, id.maxlen + 1); // for the duration of fun(), last_parname _is_ actually the old value (at any other time, it's the next value) + ((void (__cdecl *)())id.fun)(); + strncpy(id.shadow_s, id.s, id.maxlen + 1); + } + else strncpy(id.s, id.shadow_s, id.maxlen + 1); } break; } @@ -1701,11 +1718,38 @@ struct serverparameter : serverconfigfile } }; +// optionally overwrite builtin default values with commandline parameters - before updating from file starts + +void initserverparameter(const char *name, int value) +{ + ASSERT(servpars); + servpar *id = servpars->access(name); + ASSERT(id && id->type == SID_INT); + if(value >= id->minval && value <= id->maxval) *id->i = *id->shadow_i = value; +} + +void initserverparameter(const char *name, const char *value) +{ + ASSERT(servpars); + servpar *id = servpars->access(name); + ASSERT(id && id->type == SID_STR); + string tmp; + filtertext(tmp, value, id->filter); + int len = (int)strlen(tmp); + if(len >= id->minlen && len <= id->maxlen) + { + strncpy(id->s, value, id->maxlen + 1); + strncpy(id->shadow_s, value, id->maxlen + 1); + } +} + +// write a nice template for serverparameters.cfg + #ifdef _DEBUG int siddocsort(servpar **a, servpar **b) { return (*a)->chapter == (*b)->chapter ? strcmp((*a)->name, (*b)->name) : (*a)->chapter - (*b)->chapter; } -const char *siddocchapters[] = { "dDebug switches", "mMisc settings", "vVote settings", "gMaprot settings", "sServer setup settings", "" }; -const char *siddocchaptersorting = "sgvmd"; +const char *siddocchapters[] = { "dDebug switches", "mMisc settings", "vVote settings", "gMaprot settings", "sServer setup settings", "CCommandline switch overrides", "" }; +const char *siddocchaptersorting = "sgvmdC", *siddocchaptercommentedout = "C"; void serverparameters_dumpdocu(char *fname) { @@ -1735,6 +1779,7 @@ void serverparameters_dumpdocu(char *fname) if(ch < 0) f->printf("\n// **** untitled chapter %c ****\n\n", lastchap); else f->printf("\n// **** %s ****\n\n", siddocchapters[ch] + 1); } + const char *commentout = strchr(siddocchaptercommentedout, id.desc[0]) != NULL ? "//" : ""; switch(id.type) { case SID_INT: @@ -1744,12 +1789,12 @@ void serverparameters_dumpdocu(char *fname) { for(int k = 0; id.list[k] && id.list[k][0]; k++) f->printf(", %d:%s", id.minval + k, id.list[k]); } - f->printf("\n%s:%d\n\n", id.name, id.defaultint); + f->printf("\n%s%s:%d\n\n", commentout, id.name, id.defaultint); break; } case SID_STR: { - f->printf("// %s %s\n// string [%d..%d chars], default \"%s\"\n%s:%s\n\n", id.name, id.desc + 1, id.minlen, id.maxlen, id.defaultstr, id.name, id.defaultstr); + f->printf("// %s %s\n// string [%d..%d chars], default \"%s\"\n%s%s:%s\n\n", id.name, id.desc + 1, id.minlen, id.maxlen, id.defaultstr, commentout, id.name, id.defaultstr); break; } }