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/17 18:53:43
@@ -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/17 18:53:45
@@ -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: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.89
diff -u -r1.89 game.c
--- game.c	2000/08/31 13:32:45	1.89
+++ game.c	2000/09/17 18:53:47
@@ -972,54 +972,60 @@
 ***************************************************************/
 void translate_data_names(void)
 {
-  int i, j;
+  int i;
+  static const char too_long_msg[]
+    = N_("Translated name is too long, truncating: %s");
+
+#define name_strlcpy(dst, src) sz_loud_strlcpy(dst, src, _(too_long_msg))
   
   for (i=0; i<game.num_tech_types; i++) {
     struct advance *tthis = &advances[i];
     sz_strlcpy(tthis->name_orig, tthis->name);
-    sz_strlcpy(tthis->name, Q_(tthis->name_orig));
+    name_strlcpy(tthis->name, Q_(tthis->name_orig));
   }
   for (i=0; i<game.num_unit_types; i++) {
     struct unit_type *tthis = &unit_types[i];
     sz_strlcpy(tthis->name_orig, tthis->name);
-    sz_strlcpy(tthis->name, Q_(tthis->name_orig));
+    name_strlcpy(tthis->name, Q_(tthis->name_orig));
   }
   for (i=0; i<game.num_impr_types; i++) {
     struct impr_type *tthis = &improvement_types[i];
     sz_strlcpy(tthis->name_orig, tthis->name);
-    sz_strlcpy(tthis->name, Q_(tthis->name_orig));
+    name_strlcpy(tthis->name, Q_(tthis->name_orig));
   }
   for (i=T_FIRST; i<T_COUNT; i++) {
     struct tile_type *tthis = &tile_types[i];
     sz_strlcpy(tthis->terrain_name_orig, tthis->terrain_name);
-    sz_strlcpy(tthis->terrain_name, Q_(tthis->terrain_name_orig));
+    name_strlcpy(tthis->terrain_name, Q_(tthis->terrain_name_orig));
     sz_strlcpy(tthis->special_1_name_orig, tthis->special_1_name);
-    sz_strlcpy(tthis->special_1_name, Q_(tthis->special_1_name_orig));
+    name_strlcpy(tthis->special_1_name, Q_(tthis->special_1_name_orig));
     sz_strlcpy(tthis->special_2_name_orig, tthis->special_2_name);
-    sz_strlcpy(tthis->special_2_name, Q_(tthis->special_2_name_orig));
+    name_strlcpy(tthis->special_2_name, Q_(tthis->special_2_name_orig));
   }
   for (i=0; i<game.government_count; i++) {
+    int j;
     struct government *tthis = &governments[i];
     sz_strlcpy(tthis->name_orig, tthis->name);
-    sz_strlcpy(tthis->name, Q_(tthis->name_orig));
+    name_strlcpy(tthis->name, Q_(tthis->name_orig));
     for(j=0; j<tthis->num_ruler_titles; j++) {
       struct ruler_title *that = &tthis->ruler_titles[j];
       sz_strlcpy(that->male_title_orig, that->male_title);
-      sz_strlcpy(that->male_title, Q_(that->male_title_orig));
+      name_strlcpy(that->male_title, Q_(that->male_title_orig));
       sz_strlcpy(that->female_title_orig, that->female_title);
-      sz_strlcpy(that->female_title, Q_(that->female_title_orig));
+      name_strlcpy(that->female_title, Q_(that->female_title_orig));
     }
   }
   for (i=0; i<game.nation_count; i++) {
     struct nation_type *tthis = get_nation_by_idx(i);
     sz_strlcpy(tthis->name_orig, tthis->name);
-    sz_strlcpy(tthis->name, Q_(tthis->name_orig));
+    name_strlcpy(tthis->name, Q_(tthis->name_orig));
     sz_strlcpy(tthis->name_plural_orig, tthis->name_plural);
-    sz_strlcpy(tthis->name_plural, Q_(tthis->name_plural_orig));
+    name_strlcpy(tthis->name_plural, Q_(tthis->name_plural_orig));
   }
   for (i=0; i<game.styles_count; i++) {
     struct citystyle *tthis = &city_styles[i];
     sz_strlcpy(tthis->name_orig, tthis->name);
-    sz_strlcpy(tthis->name, Q_(tthis->name_orig));
+    name_strlcpy(tthis->name, Q_(tthis->name_orig));
   }
 }
+#undef name_strlcpy
Index: common/log.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/log.c,v
retrieving revision 1.21
diff -u -r1.21 log.c
--- log.c	2000/08/08 12:23:37	1.21
+++ log.c	2000/09/17 18:53:48
@@ -217,7 +217,7 @@
 Calls log_callback if non-null, else prints to stderr.
 **************************************************************************/
 #define MAX_LEN_LOG_LINE 512
-void vreal_freelog(int level, char *message, va_list ap)
+void vreal_freelog(int level, const char *message, va_list ap)
 {
   static char bufbuf[2][MAX_LEN_LOG_LINE];
   char buf[MAX_LEN_LOG_LINE];
@@ -283,7 +283,7 @@
       fclose(fs);
   }
 }
-void real_freelog(int level, char *message, ...)
+void real_freelog(int level, const char *message, ...)
 {
   va_list ap;
   va_start(ap, message);
Index: common/log.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/log.h,v
retrieving revision 1.9
diff -u -r1.9 log.h
--- log.h	2000/08/08 12:23:38	1.9
+++ log.h	2000/09/17 18:53:48
@@ -54,9 +54,9 @@
 void log_init(char *filename, int initial_level, log_callback_fn callback);
 void log_set_level(int level);
 
-void real_freelog(int level, char *message, ...)
+void real_freelog(int level, const char *message, ...)
                   fc__attribute((format (printf, 2, 3)));
-void vreal_freelog(int level, char *message, va_list ap);
+void vreal_freelog(int level, const char *message, va_list ap);
 
 
 /* A static (per-file) function to use/update the above per-file vars.
Index: common/shared.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/shared.c,v
retrieving revision 1.60
diff -u -r1.60 shared.c
--- shared.c	2000/09/08 01:53:30	1.60
+++ shared.c	2000/09/17 18:53:51
@@ -450,6 +450,30 @@
 }
 
 /********************************************************************** 
+  Check the length of the given string.  If the string is too long,
+  log errmsg, which should be a string in printf-format taking up to
+  two arguments: the string and the length.
+**********************************************************************/ 
+int check_strlen(const char *str, size_t len, const char *errmsg)
+{
+  if (strlen(str) >= len) {
+    freelog(LOG_ERROR, errmsg, str, len);
+    return 1;
+  }
+  return 0;
+}
+
+/********************************************************************** 
+  Call check_strlen() on str and then strlcpy() it into buffer.
+**********************************************************************/
+size_t loud_strlcpy(char *buffer, const char *str, size_t len,
+		   const char *errmsg)
+{
+  check_strlen(str, len, errmsg);
+  return mystrlcpy(buffer, str, len);
+}
+
+/********************************************************************** 
  cat_snprintf is like a combination of my_snprintf and mystrlcat;
  it does snprintf to the end of an existing string.
  
Index: common/shared.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/shared.h,v
retrieving revision 1.84
diff -u -r1.84 shared.h
--- shared.h	2000/09/02 01:58:35	1.84
+++ shared.h	2000/09/17 18:53:51
@@ -74,6 +74,13 @@
 void remove_trailing_char(char *s, char trailing);
 int wordwrap_string(char *s, int len);
 
+int check_strlen(const char *str, size_t len, const char *errmsg);
+size_t loud_strlcpy(char *buffer, const char *str, size_t len,
+		   const char *errmsg);
+/* Convenience macro. */
+#define sz_loud_strlcpy(buffer, str, errmsg) \
+    loud_strlcpy(buffer, str, sizeof(buffer), errmsg)
+
 char *end_of_strn(char *str, int *nleft);
 int cat_snprintf(char *str, size_t n, const char *format, ...)
      fc__attribute((format (printf, 3, 4)));
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/17 18:53:55
@@ -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,7 +107,6 @@
 {
   char **nptr;
   int i, j;
-  static int n_misc = -1;
   static char tempname[MAX_LEN_NAME];
 
   static const int num_tiles = MAP_MAX_WIDTH * MAP_MAX_HEIGHT; 
@@ -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; i++) {
-      if (j >= 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/17 18:54:01
@@ -14,10 +14,11 @@
 #include <config.h>
 #endif
 
+#include <ctype.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 
 #include "capability.h"
 #include "city.h"
@@ -36,6 +37,13 @@
 
 #include "ruleset.h"
 
+static const char name_too_long[] = N_("Name \"%s\" too long; truncating.");
+#define check_name(name) check_strlen(name, MAX_LEN_NAME, _(name_too_long))
+#define name_strlcpy(dst, src) sz_loud_strlcpy(dst, src, _(name_too_long))
+
+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,
@@ -90,16 +98,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 +115,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,7 +377,7 @@
 }
 
 /**************************************************************************
- 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)
 {
@@ -426,10 +434,11 @@
   sz_strlcpy(advances[A_NONE].name, "None");
 
   game.num_tech_types = num_techs + 1; /* includes A_NONE */
-  a = &advances[A_FIRST];
 
-  for( i=0; i<num_techs; i++ ) {
-    sz_strlcpy(a->name, 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]);
+    name_strlcpy(a->name, name);
     a++;
   }
 }
@@ -533,7 +542,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 +559,9 @@
     exit(1);
   }
   game.num_unit_types = nval;
-  for( i=0; i<game.num_unit_types; i++ ) {
-    u = &unit_types[i];
-    sz_strlcpy(u->name, 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]);
+    name_strlcpy(unit_types[i].name, name);
   }
 }
 
@@ -839,7 +847,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 +871,10 @@
   /* REMOVE TO HERE when gen-impr implemented. */
   game.num_impr_types = nval;
 
-  for (i=0; i<game.num_impr_types; i++) {
-    b = &improvement_types[i];
-    sz_strlcpy(b->name, 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]);
+    name_strlcpy(improvement_types[i].name, name);
+    improvement_types[i].name_orig[0] = 0;
   }
 }
 
@@ -1187,7 +1194,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);
@@ -1203,15 +1209,14 @@
       freelog(LOG_FATAL, "Bad number of terrains %d (%s)", nval, filename);
       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]);
+    name_strlcpy(tile_types[i].terrain_name, name);
+    if (!strcmp(tile_types[i].terrain_name, "unused")) {
+      tile_types[i].terrain_name[0] = 0;
     }
+  }
 }
 
 /**************************************************************************
@@ -1291,6 +1296,8 @@
 
   for (i = T_FIRST; i < T_COUNT; i++)
     {
+      char *s1_name;
+      char *s2_name;
       t = &(tile_types[i]);
 
       sz_strlcpy(t->graphic_str,
@@ -1305,15 +1312,15 @@
       t->shield = secfile_lookup_int(file, "%s.shield", sec[i]);
       t->trade = secfile_lookup_int(file, "%s.trade", sec[i]);
 
-      sz_strlcpy(t->special_1_name,
-		 secfile_lookup_str(file, "%s.special_1_name", sec[i]));
+      s1_name = secfile_lookup_str(file, "%s.special_1_name", sec[i]);
+      name_strlcpy(t->special_1_name, s1_name);
       if (0 == strcmp(t->special_1_name, "none")) *(t->special_1_name) = '\0';
       t->food_special_1 = secfile_lookup_int(file, "%s.food_special_1", sec[i]);
       t->shield_special_1 = secfile_lookup_int(file, "%s.shield_special_1", sec[i]);
       t->trade_special_1 = secfile_lookup_int(file, "%s.trade_special_1", sec[i]);
 
-      sz_strlcpy(t->special_2_name,
-		 secfile_lookup_str(file, "%s.special_2_name", sec[i]));
+      s2_name = secfile_lookup_str(file, "%s.special_2_name", sec[i]);
+      name_strlcpy(t->special_2_name, s2_name);
       if (0 == strcmp(t->special_2_name, "none")) *(t->special_2_name) = '\0';
       t->food_special_2 = secfile_lookup_int(file, "%s.food_special_2", sec[i]);
       t->shield_special_2 = secfile_lookup_int(file, "%s.shield_special_2", sec[i]);
@@ -1361,7 +1368,6 @@
 **************************************************************************/
 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 +1391,9 @@
 
   /* 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]);
+    name_strlcpy(governments[i].name, name);
+    governments[i].index = i;
   }
 }
 
@@ -1704,7 +1710,6 @@
 {
   char **sec;
   int i, j;
-  struct nation_type *pl;
 
   section_file_lookup(file,"datafile.description"); /* unused */
 
@@ -1712,27 +1717,35 @@
   game.playable_nation_count = game.nation_count - 1;
   freelog(LOG_VERBOSE, "There are %d nations defined", game.playable_nation_count);
 
-  if ( game.playable_nation_count >= MAX_NUM_NATIONS
-       || game.playable_nation_count == 0) {
-    freelog(LOG_FATAL, "There must be between 1 and %d nations", MAX_NUM_NATIONS);
-    exit(1);
+  if (game.playable_nation_count < 0) {
+    freelog(LOG_FATAL,
+	    "There must be at least one nation defined; number is %d",
+	    game.playable_nation_count);
+    exit(1);
+  } else if (game.playable_nation_count >= MAX_NUM_NATIONS) {
+    freelog(LOG_ERROR,
+	    "There are too many nations; only using %d of %d available.",
+	    MAX_NUM_NATIONS - 1, game.playable_nation_count);
+    game.playable_nation_count = MAX_NUM_NATIONS - 1;
   }
   alloc_nations(game.nation_count);
 
   for( i=0; i<game.nation_count; i++) {
-    pl = get_nation_by_idx(i);
-    sz_strlcpy(pl->name, secfile_lookup_str(file, "%s.name", sec[i]));
-    sz_strlcpy(pl->name_plural, secfile_lookup_str(file, "%s.plural", sec[i]));
-
-    /* check if nation name is not already defined */
-    for( j=0; j<i; j++) {
-      if( !strcmp(get_nation_name(j), pl->name) ) {
-        freelog(LOG_FATAL, "Nation %s already defined in section nation%d", pl->name, j);
-        exit(1);
-      }
-      if( !strcmp(get_nation_name_plural(j), pl->name_plural) ) {
-        freelog(LOG_FATAL, "Nation %s already defined in section nation%d", 
-                pl->name_plural, j);
+    char *name        = secfile_lookup_str(file, "%s.name", sec[i]);
+    char *name_plural = secfile_lookup_str(file, "%s.plural", sec[i]);
+    struct nation_type *pl = get_nation_by_idx(i);
+
+    name_strlcpy(pl->name, name);
+    name_strlcpy(pl->name_plural, name_plural);
+
+    /* Check if nation name is already defined. */
+    for(j = 0; j < i; j++) {
+      if (!strcmp(get_nation_name(j), pl->name)
+	  || !strcmp(get_nation_name_plural(j), pl->name_plural)) {
+        freelog(LOG_FATAL,
+		"Nation %s (the %s) defined twice; "
+		"in section nation%d and section nation%d",
+		pl->name, pl->name, j, i);
         exit(1);
       }
     }
@@ -1748,7 +1761,7 @@
   struct nation_type *pl;
   struct government *gov;
   int *res, dim, val, i, j, nval;
-  char temp_name[MAX_LEN_NAME], male[MAX_LEN_NAME], female[MAX_LEN_NAME];
+  char temp_name[MAX_LEN_NAME];
   char **cities, **techs, **leaders, **sec;
   const char *filename = secfile_filename(file);
 
@@ -1762,37 +1775,51 @@
     /* 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 > MAX_NUM_LEADERS) {
+      freelog(LOG_ERROR, "Nation %s: too many leaders; only using %d of %d",
+	      pl->name, MAX_NUM_LEADERS, dim);
+      dim = MAX_NUM_LEADERS;
+    } else if (dim < 1) {
+      freelog(LOG_FATAL,
+	      "Nation %s: number of leaders is %d; at least one is required.",
+	      pl->name, dim);
       exit(1);
     }
     pl->leader_count = dim;
-    for( j=0; j<dim; j++) {
+    for(j = 0; j < dim; j++) {
       pl->leader_name[j] = mystrdup(leaders[j]);
+      if (check_name(leaders[j])) {
+	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 defined more than once",
+		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",
-              pl->name);
+    if (dim != pl->leader_count) {
+      freelog(LOG_FATAL,
+	      "Nation %s: the leader sex count (%d) "
+	      "is not equal to the number of leaders (%d)",
+              pl->name, dim, pl->leader_count);
       exit(1);
     }
-    for(j=0; j<dim; j++) {
-      if( strcmp(leaders[j], "Male")==0 )
+    for (j = 0; j < dim; j++) {
+      if (0 == mystrcasecmp(leaders[j], "Male")) {
         pl->leader_is_male[j] = 1;
-      else if( strcmp(leaders[j], "Female")==0 )
+      } else if (0 == mystrcasecmp(leaders[j], "Female")) {
         pl->leader_is_male[j] = 0;
-      else {
-        freelog( LOG_FATAL, "Nation %s leader sex must be Male or Female", pl->name);
-        exit(1);
+      } else {
+        freelog(LOG_ERROR,
+		"Nation %s, leader %s: sex must be either Male or Female; "
+		"assuming Male",
+		pl->name, pl->leader_name[j]);
+	pl->leader_is_male[j] = 1;
       }
     }
     free(leaders);
@@ -1807,18 +1834,26 @@
     /* Ruler titles */
 
     j = -1;
-    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 ) {
-        set_ruler_title(gov, i, male, female);
-      }
-      else {
-        freelog(LOG_VERBOSE,"Nation %s, government %s not found", pl->name, g);
+    while ((g = secfile_lookup_str_default(file, NULL,
+					   "%s.ruler_titles%d.government",
+					   sec[i], ++j))) {
+      char *male_name;
+      char *female_name;
+      
+      male_name = secfile_lookup_str(file, "%s.ruler_titles%d.male_title",
+				     sec[i], j);
+      female_name = secfile_lookup_str(file, "%s.ruler_titles%d.female_title",
+				       sec[i], j);
+
+      gov = find_government_by_name(g);
+      if (gov != NULL) {
+	check_name(male_name);
+	check_name(female_name);
+	/* Truncation is handled by set_ruler_title(). */
+	set_ruler_title(gov, i, male_name, female_name);
+      } else {
+        freelog(LOG_VERBOSE,
+		"Nation %s: government %s not found", pl->name, g);
       }
     }
 
@@ -1827,15 +1862,25 @@
     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 is unknown, 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);
+
+    while (city_styles[pl->city_style].techreq != A_NONE) {
+      if (pl->city_style == 0) {
+	freelog(LOG_FATAL,
+	       "Nation %s: the default city style is not available "
+	       "from the beginning", pl->name);
+	/* Note that we can't use temp_name here. */
+	exit(1);
+      }
+      freelog(LOG_ERROR,
+	      "Nation %s: city style %s is not available from beginning; "
+	      "using default.", pl->name, temp_name);
+      pl->city_style = 0;
     }
 
     /* AI stuff */
@@ -1845,14 +1890,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; j<ADV_LAST; j++) 
       pl->advisors[j] = res[j];
-    if(res) free(res);
+    if(res) free(res);
 
     /* AI techs */
 
@@ -1866,11 +1911,11 @@
     for( j=0; j<dim; j++) {
       val = find_tech_by_name(techs[j]);
       if(val == A_LAST) {
-	freelog(LOG_VERBOSE, "Didn't match goal tech %d \"%s\" for %s",
-		j, techs[j], pl->name);
-      } 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) {
@@ -1919,8 +1964,11 @@
     cities = secfile_lookup_str_vec(file, &dim, "%s.cities", sec[i]);
     pl->default_city_names = fc_calloc(dim+1, sizeof(char*));
     pl->default_city_names[dim] = NULL;
-    for ( j=0; j<dim; j++) {
+    for (j = 0; j < dim; j++) {
       pl->default_city_names[j] = mystrdup(cities[j]);
+      if (check_name(cities[j])) {
+	pl->default_city_names[j][MAX_LEN_NAME - 1] = 0;
+      }
     }
     if(cities) free(cities);
   }
@@ -1929,12 +1977,17 @@
   /* 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<dim; j++) {
+  misc_city_names = fc_calloc(dim, sizeof(char*));
+
+  for (j = 0; j < dim; j++) {
     misc_city_names[j] = mystrdup(cities[j]);
+    if (check_name(cities[j])) {
+      misc_city_names[j][MAX_LEN_NAME - 1] = 0;
+    }
   }
-  misc_city_names[dim] = NULL;
-  if(cities) free(cities);
+  num_misc_city_names = dim;
+
+  if (cities) free(cities);
 
   section_file_check_unused(file, filename);
   section_file_free(file);
@@ -1956,9 +2009,9 @@
   city_styles = fc_calloc( game.styles_count, sizeof(struct citystyle) );
 
   /* Get names, so can lookup for replacements: */
-  for( i=0; i<game.styles_count; i++) {
-    sz_strlcpy(city_styles[i].name, 
-               secfile_lookup_str(file, "%s.name", styles[i]));
+  for (i = 0; i < game.styles_count; i++) {
+    char *style_name = secfile_lookup_str(file, "%s.name", styles[i]);
+    name_strlcpy(city_styles[i].name, style_name);
   }
 }