diff -Nurd -Xfreeciv/diff_ignore freeciv-1.11.12/client/helpdata.c rulesetcrash/client/helpdata.c --- freeciv-1.11.12/client/helpdata.c Sat Sep 2 03:58:34 2000 +++ rulesetcrash/client/helpdata.c Fri Aug 10 13:47:54 2001 @@ -203,10 +203,6 @@ filename = datafilename("helpdata.txt"); if (filename == NULL) { - freelog(LOG_ERROR, "Could not find readable helpdata.txt in data path"); - freelog(LOG_ERROR, "The data path may be set via" - " the environment variable FREECIV_PATH"); - freelog(LOG_ERROR, "Current data path is: \"%s\"", datafilename(NULL)); freelog(LOG_ERROR, "Did not read help texts"); return; } diff -Nurd -Xfreeciv/diff_ignore freeciv-1.11.12/client/tilespec.c rulesetcrash/client/tilespec.c --- freeciv-1.11.12/client/tilespec.c Mon Aug 6 23:02:00 2001 +++ rulesetcrash/client/tilespec.c Fri Aug 10 14:03:08 2001 @@ -121,7 +121,6 @@ { char *tileset_default; char *fname, *dname; - int level; if (isometric_view_supported()) { tileset_default = "hires"; /* Do not i18n! --dwp */ @@ -142,19 +141,10 @@ } if (strcmp(tileset_name, tileset_default)==0) { - level = LOG_FATAL; - } else { - level = LOG_ERROR; - } - freelog(level, _("Could not find readable file \"%s\" in data path."), - fname); - freelog(level, _("The data path may be set via" - " the environment variable FREECIV_PATH.")); - freelog(level, _("Current data path is: \"%s\""), datafilename(NULL)); - if (level == LOG_FATAL) { + freelog(LOG_FATAL, _("No useable default tileset found, aborting!")); exit(1); } - freelog(level, _("Trying \"%s\" tileset."), tileset_default); + freelog(LOG_ERROR, _("Trying \"%s\" tileset."), tileset_default); free(fname); return tilespec_fullname(tileset_default); } diff -Nurd -Xfreeciv/diff_ignore freeciv-1.11.12/common/registry.c rulesetcrash/common/registry.c --- freeciv-1.11.12/common/registry.c Mon May 28 00:42:59 2001 +++ rulesetcrash/common/registry.c Fri Aug 10 13:52:47 2001 @@ -368,7 +368,6 @@ inf = inf_open(filename, datafilename); if (!inf) { - freelog(LOG_ERROR, "Could not open file \"%s\"", filename); return 0; } section_file_init(sf); diff -Nurd -Xfreeciv/diff_ignore freeciv-1.11.12/common/shared.c rulesetcrash/common/shared.c --- freeciv-1.11.12/common/shared.c Sun Feb 18 17:28:30 2001 +++ rulesetcrash/common/shared.c Fri Aug 10 14:02:28 2001 @@ -591,21 +591,25 @@ ***************************************************************************/ char *datafilename(const char *filename) { - static int init = 0; + static char *path = NULL; static int num_dirs = 0; static char **dirs = NULL; static struct astring realfile = ASTRING_INIT; int i; - if (!init) { + if (path == NULL) { char *tok; - char *path = getenv("FREECIV_PATH"); + char *path2; + + path = getenv("FREECIV_PATH"); if (!path) { path = DEFAULT_DATA_PATH; } - path = mystrdup(path); /* something we can strtok */ + assert(path != NULL); + + path2 = mystrdup(path); /* something we can strtok */ - tok = strtok(path, PATH_SEPARATOR); + tok = strtok(path2, PATH_SEPARATOR); do { int i; /* strlen(tok), or -1 as flag */ @@ -651,8 +655,7 @@ tok = strtok(NULL, PATH_SEPARATOR); } while(tok != NULL); - free(path); - init = 1; + free(path2); } if (filename == NULL) { @@ -684,6 +687,13 @@ return realfile.str; } } + + freelog(LOG_ERROR, _("Could not find readable file \"%s\" in data path."), + filename); + freelog(LOG_ERROR, _("The data path may be set via" + " the environment variable FREECIV_PATH.")); + freelog(LOG_ERROR, _("Current data path is: \"%s\""), datafilename(NULL)); + return NULL; } @@ -701,11 +711,8 @@ if (dname) { return dname; } else { - freelog(LOG_FATAL, _("Could not find readable file \"%s\" in data path."), - filename); - freelog(LOG_FATAL, _("The data path may be set via" - " the environment variable FREECIV_PATH.")); - freelog(LOG_FATAL, _("Current data path is: \"%s\""), datafilename(NULL)); + freelog(LOG_FATAL, + _("The \"%s\" file is required ... aborting!"), filename); exit(1); } } diff -Nurd -Xfreeciv/diff_ignore freeciv-1.11.12/server/ruleset.c rulesetcrash/server/ruleset.c --- freeciv-1.11.12/server/ruleset.c Sat Jul 21 20:31:57 2001 +++ rulesetcrash/server/ruleset.c Fri Aug 10 14:15:06 2001 @@ -94,6 +94,30 @@ static void send_ruleset_game(struct conn_list *dest); /************************************************************************** + datafilename() wrapper: tries to match in two ways. + Returns NULL on failure, the (statically allocated) filename on success. +**************************************************************************/ +char *valid_ruleset_filename(char *subdir, char *whichset) +{ + char filename1[512], filename2[512], *dfilename; + + my_snprintf(filename1, sizeof(filename1), "%s/%s.ruleset", subdir, whichset); + dfilename = datafilename(filename1); + if (dfilename) + return dfilename; + + freelog(LOG_ERROR, _("Trying alternative ruleset filename syntax.")); + + my_snprintf(filename2, sizeof(filename2), "%s_%s.ruleset", subdir, whichset); + dfilename = datafilename(filename2); + + if (dfilename) + return dfilename; + + return(NULL); +} + +/************************************************************************** Do initial section_file_load on a ruleset file. "subdir" = "default", "civ1", "custom", ... "whichset" = "techs", "units", "buildings", "terrain", ... @@ -101,29 +125,22 @@ This no longer returns the full filename opened; used secfile_filename() if you want it. **************************************************************************/ + static void openload_ruleset_file(struct section_file *file, char *subdir, char *whichset) { - char filename1[512], filename2[512], *dfilename; char sfilename[512]; + char *dfilename = valid_ruleset_filename(subdir, whichset); - my_snprintf(filename1, sizeof(filename1), "%s_%s.ruleset", subdir, whichset); - dfilename = datafilename(filename1); if (!dfilename) { - my_snprintf(filename2, sizeof(filename2), "%s/%s.ruleset", subdir, whichset); - dfilename = datafilename(filename2); - if (!dfilename) { - freelog(LOG_FATAL, - _("Could not find readable ruleset" - " file \"%s\" or \"%s\" in data path."), filename1, filename2); - freelog(LOG_FATAL, _("The data path may be set via" - " the environment variable FREECIV_PATH.")); - freelog(LOG_FATAL, _("Current data path is: \"%s\""), datafilename(NULL)); - exit(1); - } + freelog(LOG_FATAL, + _("Could not find a readable \"%s\" ruleset file."), whichset); + exit(1); } + /* Need to save a copy of the filename for following message, since section_file_load() may call datafilename() for includes. */ + sz_strlcpy(sfilename, dfilename); if (!section_file_load(file,sfilename)) { diff -Nurd -Xfreeciv/diff_ignore freeciv-1.11.12/server/ruleset.h rulesetcrash/server/ruleset.h --- freeciv-1.11.12/server/ruleset.h Wed Aug 2 16:14:08 2000 +++ rulesetcrash/server/ruleset.h Fri Aug 10 14:20:58 2001 @@ -18,4 +18,8 @@ void load_rulesets(void); void send_rulesets(struct conn_list *dest); +char *valid_ruleset_filename(char *subdir, char *whichset); + /* used as a partial pre-check on ruleset validity */ + /* doesn't try to fall back on a default */ + #endif /* FC__RULESET_H */ diff -Nurd -Xfreeciv/diff_ignore freeciv-1.11.12/server/stdinhand.c rulesetcrash/server/stdinhand.c --- freeciv-1.11.12/server/stdinhand.c Tue Aug 7 15:35:06 2001 +++ rulesetcrash/server/stdinhand.c Fri Aug 10 15:29:04 2001 @@ -47,6 +47,7 @@ #include "meta.h" #include "plrhand.h" #include "report.h" +#include "ruleset.h" #include "rulesout.h" #include "sernet.h" #include "srv_main.h" @@ -102,11 +103,11 @@ struct settings_s { char *name; int *value; - /* if the function is non-NULL the value should be modified through it. - The function returns whether the change was legal. The char * is - for returning an error message in the case of reject. */ + /* Validating function for integer settings. If the function is non-NULL, + it is called with the new value, and returns whether the change is + legal. The char * is an error message in the case of reject. */ int (*func_change)(int, char **); - /* The same, just for string settings. The first char* is the new + /* The same, for string settings. The first char* is the new value as an argument, the second is for returning the error message. */ int (*func_change_s)(char *, char **); @@ -134,8 +135,49 @@ size_t sz_svalue; /* max size we can write into svalue */ }; +/******************************************************************** +Triggers used in settings_s. valid_ruleset() is clumsy because of +the fixed number of arguments and the reject_message - change? - rp +*********************************************************************/ + static int autotoggle(int value, char **reject_message); +static int valid_ruleset(char *whichset, char *subdir, char **reject_message) +{ + static char buffer[MAX_LEN_CONSOLE_LINE]; + + assert(subdir != NULL); + + *reject_message = buffer; + + if (!valid_ruleset_filename(subdir,whichset)) { + my_snprintf(buffer, sizeof(buffer), + _("Invalid ruleset subdirectory, keeping old value.")); + return 0; + } + + buffer[0] = '\0'; + + return 1; +} + +static int valid_techs_ruleset(char *v, char **r_m) + { return valid_ruleset("techs",v,r_m); } +static int valid_governments_ruleset(char *v, char **r_m) + { return valid_ruleset("governments",v,r_m); } +static int valid_units_ruleset(char *v, char **r_m) + { return valid_ruleset("units",v,r_m); } +static int valid_buildings_ruleset(char *v, char **r_m) + { return valid_ruleset("buildings",v,r_m); } +static int valid_terrain_ruleset(char *v, char **r_m) + { return valid_ruleset("terrain",v,r_m); } +static int valid_nations_ruleset(char *v, char **r_m) + { return valid_ruleset("nations",v,r_m); } +static int valid_cities_ruleset(char *v, char **r_m) + { return valid_ruleset("cities",v,r_m); } +static int valid_game_ruleset(char *v, char **r_m) + { return valid_ruleset("game",v,r_m); } + #define SETTING_IS_INT(s) ((s)->value!=NULL) #define SETTING_IS_STRING(s) ((s)->value==NULL) @@ -298,7 +340,7 @@ N_("Number of initial advances per player"), "" }, /* Various rules: these cannot be changed once the game has started. */ - { "techs", NULL, NULL, NULL, + { "techs", NULL, NULL, valid_techs_ruleset, SSET_RULES, SSET_TO_CLIENT, 0, 0, 0, N_("Data subdir containing techs.ruleset"), @@ -310,7 +352,7 @@ game.ruleset.techs, GAME_DEFAULT_RULESET, sizeof(game.ruleset.techs) }, - { "governments", NULL, NULL, NULL, + { "governments", NULL, NULL, valid_governments_ruleset, SSET_RULES, SSET_TO_CLIENT, 0, 0, 0, N_("Data subdir containing governments.ruleset"), @@ -322,7 +364,7 @@ game.ruleset.governments, GAME_DEFAULT_RULESET, sizeof(game.ruleset.governments) }, - { "units", NULL, NULL, NULL, + { "units", NULL, NULL, valid_units_ruleset, SSET_RULES, SSET_TO_CLIENT, 0, 0, 0, N_("Data subdir containing units.ruleset"), @@ -334,7 +376,7 @@ game.ruleset.units, GAME_DEFAULT_RULESET, sizeof(game.ruleset.units) }, - { "buildings", NULL, NULL, NULL, + { "buildings", NULL, NULL, valid_buildings_ruleset, SSET_RULES, SSET_TO_CLIENT, 0, 0, 0, N_("Data subdir containing buildings.ruleset"), @@ -346,7 +388,7 @@ game.ruleset.buildings, GAME_DEFAULT_RULESET, sizeof(game.ruleset.buildings) }, - { "terrain", NULL, NULL, NULL, + { "terrain", NULL, NULL, valid_terrain_ruleset, SSET_RULES, SSET_TO_CLIENT, 0, 0, 0, N_("Data subdir containing terrain.ruleset"), @@ -358,7 +400,7 @@ game.ruleset.terrain, GAME_DEFAULT_RULESET, sizeof(game.ruleset.terrain) }, - { "nations", NULL, NULL, NULL, + { "nations", NULL, NULL, valid_nations_ruleset, SSET_RULES, SSET_TO_CLIENT, 0, 0, 0, N_("Data subdir containing nations.ruleset"), @@ -370,7 +412,7 @@ game.ruleset.nations, GAME_DEFAULT_RULESET, sizeof(game.ruleset.nations) }, - { "cities", NULL, NULL, NULL, + { "cities", NULL, NULL, valid_cities_ruleset, SSET_RULES, SSET_TO_CLIENT, 0, 0, 0, N_("Data subdir containing cities.ruleset"), @@ -381,7 +423,7 @@ game.ruleset.cities, GAME_DEFAULT_RULESET, sizeof(game.ruleset.cities) }, - { "game", NULL, NULL, NULL, + { "game", NULL, NULL, valid_game_ruleset, SSET_RULES, SSET_TO_CLIENT, 0, 0, 0, N_("Data subdir containing game.ruleset"),