Index: common/city.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/city.c,v retrieving revision 1.93 diff -u -r1.93 city.c --- city.c 2000/08/31 13:32:44 1.93 +++ city.c 2000/09/05 21:58:38 @@ -49,10 +49,7 @@ { 3, 4 }, { 1, 4 } }; -char **misc_city_names; - struct citystyle *city_styles = NULL; - /************************************************************************** Set the worker on the citymap. Also sets the worked field in the map. Index: common/city.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/city.h,v retrieving revision 1.67 diff -u -r1.67 city.h --- city.h 2000/08/25 13:54:27 1.67 +++ city.h 2000/09/05 21:58:39 @@ -239,9 +239,6 @@ TYPED_LIST_ITERATE(struct city, citylist, pcity) #define city_list_iterate_end LIST_ITERATE_END - -extern char **misc_city_names; - /* properties */ struct player *city_owner(struct city *pcity); Index: server/cityhand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/cityhand.c,v retrieving revision 1.88 diff -u -r1.88 cityhand.c --- cityhand.c 2000/08/31 13:32:47 1.88 +++ cityhand.c 2000/09/05 21:58:44 @@ -54,6 +54,9 @@ struct packet_short_city *packet); static void remove_trade_route(int c1, int c2); +char **misc_city_names; +int num_misc_city_names; + /************************************************************************** Establish a trade route, notice that there has to be space for them, So use can_establish_Trade_route first. @@ -104,9 +107,8 @@ { char **nptr; int i, j; - static int n_misc = -1; - static char tempname[MAX_LEN_NAME]; + static char tempname[MAX_LEN_NAME]; static const int num_tiles = MAP_MAX_WIDTH * MAP_MAX_HEIGHT; freelog(LOG_VERBOSE, "Suggesting city name for %s", pplayer->name); @@ -115,16 +117,14 @@ if(!game_find_city_by_name(*nptr)) return *nptr; } - - if (n_misc == -1) - for (n_misc = 0; misc_city_names[n_misc]; n_misc++) - ; - if (n_misc > 0) { - j = myrand(n_misc); + if (num_misc_city_names > 0) { + j = myrand(num_misc_city_names); - for (i=0; i= n_misc) j = 0; + for (i = 0; i < num_misc_city_names; i++) { + if (j >= num_misc_city_names) { + j = 0; + } if (!game_find_city_by_name(misc_city_names[j])) return misc_city_names[j]; j++; Index: server/ruleset.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v retrieving revision 1.65 diff -u -r1.65 ruleset.c --- ruleset.c 2000/08/31 13:32:49 1.65 +++ ruleset.c 2000/09/05 21:58:50 @@ -14,10 +14,11 @@ #include #endif +#include +#include #include #include #include -#include #include "capability.h" #include "city.h" @@ -36,6 +37,9 @@ #include "ruleset.h" +extern char **misc_city_names; +extern int num_misc_city_names; + static void openload_ruleset_file(struct section_file *file, char *subdir, char *whichset); static char *check_ruleset_capabilities(struct section_file *file, @@ -60,6 +64,8 @@ static enum tile_terrain_type lookup_terrain(char *name, int tthis); +static void check_name(const char *name); + static void load_tech_names(struct section_file *file); static void load_unit_names(struct section_file *file); static void load_building_names(struct section_file *file); @@ -90,16 +96,16 @@ /************************************************************************** Do initial section_file_load on a ruleset file. "subdir" = "default", "civ1", "custom", ... - "whichset" = "techs", "units", "buildings", "terrain" (...) + "whichset" = "techs", "units", "buildings", "terrain", ... Calls exit(1) on failure. 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 *subdir, char *whichset) { - char filename1[512], filename2[512], *dfilename; - char sfilename[512]; + char filename1[PATH_MAX + 1], filename2[PATH_MAX + 1], *dfilename; + char sfilename[PATH_MAX + 1]; my_snprintf(filename1, sizeof(filename1), "%s_%s.ruleset", subdir, whichset); dfilename = datafilename(filename1); @@ -107,9 +113,9 @@ 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\""), - filename1); - freelog(LOG_FATAL, _("or \"%s\" in data path."), filename2); + 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)); @@ -369,33 +375,40 @@ } /************************************************************************** - Lookup a terrain name in the tile_types array; return its index. + Look up a terrain name in the tile_types array and return its index. **************************************************************************/ static enum tile_terrain_type lookup_terrain(char *name, int tthis) { int i; - if ((!(*name)) || (0 == strcmp(name, "none")) || (0 == strcmp(name, "no"))) - { - return (T_LAST); - } - else if (0 == strcmp(name, "yes")) - { - return (tthis); - } + if (!(*name) || !strcmp(name, "none") || !strcmp(name, "no")) { + return T_LAST; + } else if (!strcmp(name, "yes")) { + return tthis; + } - for (i = T_FIRST; i < T_COUNT; i++) - { - if (0 == strcmp(name, tile_types[i].terrain_name)) - { - return (i); - } + for (i = T_FIRST; i < T_COUNT; i++) { + if (!strcmp(name, tile_types[i].terrain_name)) { + return i; } + } - return (T_UNKNOWN); + return T_UNKNOWN; } /************************************************************************** + Check that a name is not too long, and possibly warn about + truncation (but does not perform the actual truncation. +**************************************************************************/ + +static void check_name(const char *name) +{ + if (strlen(name) + 1 > MAX_LEN_NAME) { + freelog(LOG_ERROR, "Name too long; truncating: %s", name); + } +} + +/************************************************************************** ... **************************************************************************/ static void load_tech_names(struct section_file *file) @@ -426,10 +439,12 @@ sz_strlcpy(advances[A_NONE].name, "None"); game.num_tech_types = num_techs + 1; /* includes A_NONE */ - a = &advances[A_FIRST]; - for( i=0; iname, secfile_lookup_str(file, "%s.name", sec[i])); + a = &advances[A_FIRST]; + for (i = 0; i < num_techs; i++ ) { + char *name = secfile_lookup_str(file, "%s.name", sec[i]); + check_name(name); + sz_strlcpy(a->name, name); a++; } } @@ -533,7 +548,6 @@ { char **sec; int nval, i; - struct unit_type *u; const char *filename = secfile_filename(file); section_file_lookup(file,"datafile.description"); /* unused */ @@ -551,9 +565,10 @@ exit(1); } game.num_unit_types = nval; - for( i=0; iname, secfile_lookup_str(file, "%s.name", sec[i])); + for (i = 0; i < game.num_unit_types; i++ ) { + char *name = secfile_lookup_str(file, "%s.name", sec[i]); + check_name(name); + sz_strlcpy(unit_types[i].name, name); } } @@ -839,7 +854,6 @@ { char **sec; int nval, i; - struct impr_type *b; const char *filename = secfile_filename(file); section_file_lookup(file,"datafile.description"); /* unused */ @@ -864,10 +878,11 @@ /* REMOVE TO HERE when gen-impr implemented. */ game.num_impr_types = nval; - for (i=0; iname, secfile_lookup_str(file, "%s.name", sec[i])); - b->name_orig[0] = '\0'; + for (i = 0; i < game.num_impr_types; i++) { + char *name = secfile_lookup_str(file, "%s.name", sec[i]); + check_name(name); + sz_strlcpy(improvement_types[i].name, name); + improvement_types[i].name_orig[0] = 0; } } @@ -1187,7 +1202,6 @@ **************************************************************************/ static void load_terrain_names(struct section_file *file) { - struct tile_type *t; int nval, i; char **sec; const char *filename = secfile_filename(file); @@ -1204,14 +1218,14 @@ exit(1); } - for (i = T_FIRST; i < T_COUNT; i++) - { - t = &(tile_types[i]); - - sz_strlcpy(t->terrain_name, - secfile_lookup_str(file, "%s.terrain_name", sec[i])); - if (0 == strcmp(t->terrain_name, "unused")) *(t->terrain_name) = '\0'; + for (i = T_FIRST; i < T_COUNT; i++) { + char *name = secfile_lookup_str(file, "%s.terrain_name", sec[i]); + check_name(name); + sz_strlcpy(tile_types[i].terrain_name, name); + if (!strcmp(tile_types[i].terrain_name, "unused")) { + tile_types[i].terrain_name[0] = 0; } + } } /************************************************************************** @@ -1357,11 +1371,10 @@ } /************************************************************************** - ... + ... **************************************************************************/ static void load_government_names(struct section_file *file) { - struct government *g = NULL; int nval, i; char **sec; const char *filename = secfile_filename(file); @@ -1385,9 +1398,10 @@ /* first fill in government names so find_government_by_name will work -SKi */ for(i = 0; i < game.government_count; i++) { - g = &governments[i]; - sz_strlcpy(g->name, secfile_lookup_str(file, "%s.name", sec[i])); - g->index = i; + char *name = secfile_lookup_str(file, "%s.name", sec[i]); + check_name(name); + sz_strlcpy(governments[i].name, name); + governments[i].index = i; } } @@ -1762,36 +1776,44 @@ /* nation leaders */ leaders = secfile_lookup_str_vec(file, &dim, "%s.leader", sec[i]); - if( dim<1 || dim > MAX_NUM_LEADERS ) { - freelog(LOG_FATAL, "Nation %s: number of leaders must be 1-%d", pl->name, - MAX_NUM_LEADERS); + if (dim < 1 || dim > MAX_NUM_LEADERS) { + freelog(LOG_FATAL, + "Nation %s: number of leaders must be in the range 1 to %d", + pl->name, MAX_NUM_LEADERS); exit(1); } pl->leader_count = dim; - for( j=0; jleader_name[j] = mystrdup(leaders[j]); + check_name(leaders[j]); + if (strlen(leaders[j]) + 1 > MAX_LEN_NAME) { + pl->leader_name[j][MAX_LEN_NAME - 1] = 0; + } } free(leaders); /* check if leader name is not already defined */ if( (bad_leader=check_leader_names(i)) ) { - freelog(LOG_FATAL, "Nation %s leader %s already defined", pl->name, bad_leader); + freelog(LOG_FATAL, + "Nation %s leader %s already defined", pl->name, bad_leader); exit(1); } /* read leaders'sexes */ leaders = secfile_lookup_str_vec(file, &dim, "%s.leader_sex", sec[i]); - if( dim != pl->leader_count ) { - freelog(LOG_FATAL, "Nation %s: leader sex count not equal to number of leaders", + if (dim != pl->leader_count) { + freelog(LOG_FATAL, + "Nation %s: leader sex count not equal to number of leaders", pl->name); exit(1); } - for(j=0; jleader_is_male[j] = 1; - else if( strcmp(leaders[j], "Female")==0 ) + else if ( strcmp(leaders[j], "Female")==0 ) pl->leader_is_male[j] = 0; else { - freelog( LOG_FATAL, "Nation %s leader sex must be Male or Female", pl->name); + freelog(LOG_FATAL, + "Nation %s leader sex must be Male or Female", pl->name); exit(1); } } @@ -1807,14 +1829,16 @@ /* Ruler titles */ j = -1; - while((g = secfile_lookup_str_default(file, NULL, "%s.ruler_titles%d.government", - sec[i], ++j))) { + while ((g = secfile_lookup_str_default(file, NULL, + "%s.ruler_titles%d.government", + sec[i], ++j))) { sz_strlcpy(male, secfile_lookup_str(file, "%s.ruler_titles%d.male_title", sec[i], j)); sz_strlcpy(female, secfile_lookup_str(file, "%s.ruler_titles%d.female_title", sec[i], j)); if( (gov = find_government_by_name(g)) != NULL ) { + /* FIXME: Use check_name() here? */ set_ruler_title(gov, i, male, female); } else { @@ -1827,15 +1851,18 @@ sz_strlcpy(temp_name, secfile_lookup_str_default(file, "-", "%s.city_style", sec[i])); pl->city_style = get_style_by_name(temp_name); - if( pl->city_style == -1 ) { - freelog( LOG_NORMAL, "Nation %d city style %s not known, using default", - i, temp_name); + if (pl->city_style == -1) { + freelog(LOG_NORMAL, "Nation %s city style %s not known, using default.", + pl->name_plural, temp_name); pl->city_style = 0; } - if( city_styles[pl->city_style].techreq != A_NONE ) { - freelog( LOG_FATAL, "Nation %d city style %s is not available from beginning", - i, temp_name); - exit(1); + + if (city_styles[pl->city_style].techreq != A_NONE) { + freelog(LOG_ERROR, + "Nation %s city style %s is not available from beginning," + " using default.", + pl->name_plural, temp_name); + pl->city_style = 0; } /* AI stuff */ @@ -1845,14 +1872,14 @@ pl->civilized = secfile_lookup_int_default(file, 2, "%s.civilized", sec[i]); res = secfile_lookup_int_vec(file, &dim, "%s.advisors", sec[i]); - if( dim != ADV_LAST ) { - freelog( LOG_FATAL, "Nation %d number of advisors must be %d but is %d", - i, ADV_LAST, dim); - exit(1); + if (dim != ADV_LAST) { + freelog(LOG_FATAL, "Nation %s number of advisors must be %d but is %d", + pl->name_plural, ADV_LAST, dim); + exit(1); } for ( j=0; jadvisors[j] = res[j]; - if(res) free(res); + free(res); /* AI techs */ @@ -1866,11 +1893,11 @@ for( j=0; jname); - } else if(!tech_exists(val)) { - freelog(LOG_VERBOSE, "Goal tech %d \"%s\" for %s doesn't exist", - j, techs[j], pl->name); + freelog(LOG_VERBOSE, "Could not match tech goal \"%s\" for the %s", + techs[j], pl->name_plural); + } else if (!tech_exists(val)) { + freelog(LOG_VERBOSE, "Goal tech \"%s\" for the %s doesn't exist", + techs[j], pl->name_plural); val = A_LAST; } if(val != A_LAST && val != A_NONE) { @@ -1880,7 +1907,7 @@ } freelog(LOG_DEBUG, "%s %d tech goals", pl->name, j); if(j==0) { - freelog(LOG_VERBOSE, "No valid goal techs for %s", pl->name); + freelog(LOG_VERBOSE, "No valid goal techs for %s.", pl->name); } while( j < MAX_NUM_TECH_GOALS ) pl->goals.tech[j++] = A_NONE; @@ -1921,6 +1948,8 @@ pl->default_city_names[dim] = NULL; for ( j=0; jdefault_city_names[j] = mystrdup(cities[j]); + check_name(cities[j]); + pl->default_city_names[j][MAX_LEN_NAME - 1] = 0; } if(cities) free(cities); } @@ -1929,12 +1958,16 @@ /* read miscellaneous city names */ cities = secfile_lookup_str_vec(file, &dim, "misc.cities"); - misc_city_names = fc_calloc(dim+1, sizeof(char*)); - for ( j=0; j