<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40504 >
Building Freeciv in Ubuntu Intrepid causes a lot of "format not a string literal and no format arguments" -warnings. Attached patch fixes them from S2_2 server and gtk-client TODO: - Clients other than gtk - Replace some sprintf(dest, "%s", src) type constructs with strcpy(dest, src) type constructs - Other branches - ML
diff -Nurd -X.diff_ignore freeciv/ai/ailog.c freeciv/ai/ailog.c --- freeciv/ai/ailog.c 2008-05-26 10:15:42.000000000 +0300 +++ freeciv/ai/ailog.c 2008-09-22 03:19:16.000000000 +0300 @@ -69,11 +69,11 @@ my_vsnprintf(buffer2, sizeof(buffer2), msg, ap); va_end(ap); - cat_snprintf(buffer, sizeof(buffer), buffer2); + cat_snprintf(buffer, sizeof(buffer), "%s", buffer2); if (BV_ISSET(pplayer->debug, PLAYER_DEBUG_TECH)) { notify_conn(NULL, NULL, E_AI_DEBUG, "%s", buffer); } - freelog(minlevel, buffer); + freelog(minlevel, "%s", buffer); } /************************************************************************** @@ -112,11 +112,11 @@ my_vsnprintf(buffer2, sizeof(buffer2), msg, ap); va_end(ap); - cat_snprintf(buffer, sizeof(buffer), buffer2); + cat_snprintf(buffer, sizeof(buffer), "%s", buffer2); if (BV_ISSET(pplayer->debug, PLAYER_DEBUG_DIPLOMACY)) { notify_conn(NULL, NULL, E_AI_DEBUG, "%s", buffer); } - freelog(minlevel, buffer); + freelog(minlevel, "%s", buffer); } /************************************************************************** @@ -147,11 +147,11 @@ my_vsnprintf(buffer2, sizeof(buffer2), msg, ap); va_end(ap); - cat_snprintf(buffer, sizeof(buffer), buffer2); + cat_snprintf(buffer, sizeof(buffer), "%s", buffer2); if (pcity->debug) { notify_conn(NULL, NULL, E_AI_DEBUG, "%s", buffer); } - freelog(minlevel, buffer); + freelog(minlevel, "%s", buffer); } /************************************************************************** @@ -207,11 +207,11 @@ my_vsnprintf(buffer2, sizeof(buffer2), msg, ap); va_end(ap); - cat_snprintf(buffer, sizeof(buffer), buffer2); + cat_snprintf(buffer, sizeof(buffer), "%s", buffer2); if (punit->debug || messwin) { notify_conn(NULL, NULL, E_AI_DEBUG, "%s", buffer); } - freelog(minlevel, buffer); + freelog(minlevel, "%s", buffer); } /************************************************************************** @@ -262,11 +262,11 @@ type, TILE_XY(punit->tile), s, id, charge_x, charge_y); - cat_snprintf(buffer, sizeof(buffer), msg); + cat_snprintf(buffer, sizeof(buffer), "%s", msg); if (punit->debug) { notify_conn(NULL, NULL, E_AI_DEBUG, "%s", buffer); } - freelog(minlevel, buffer); + freelog(minlevel, "%s", buffer); } /************************************************************************** @@ -316,7 +316,7 @@ my_snprintf(buf, sizeof(buf), " %s: %g sec turn, %g sec game", text, \ read_timer_seconds(aitimer[which][0]), \ read_timer_seconds(aitimer[which][1])); \ - freelog(LOG_TEST, buf); \ + freelog(LOG_TEST, "%s", buf); \ notify_conn(NULL, NULL, E_AI_DEBUG, "%s", buf); freelog(LOG_TEST, " --- AI timing results ---"); diff -Nurd -X.diff_ignore freeciv/client/agents/cma_fec.c freeciv/client/agents/cma_fec.c --- freeciv/client/agents/cma_fec.c 2008-05-26 10:24:09.000000000 +0300 +++ freeciv/client/agents/cma_fec.c 2008-09-22 03:46:25.000000000 +0300 @@ -286,7 +286,7 @@ } if (city_production_has_flag(pcity, IF_GOLD)) { - my_snprintf(buffer, sizeof(buffer), + my_snprintf(buffer, sizeof(buffer), "%s", improvement_name_translation(pcity->production.value.building)); return buffer; } diff -Nurd -X.diff_ignore freeciv/client/citydlg_common.c freeciv/client/citydlg_common.c --- freeciv/client/citydlg_common.c 2008-05-26 10:25:18.000000000 +0300 +++ freeciv/client/citydlg_common.c 2008-09-22 03:53:56.000000000 +0300 @@ -213,7 +213,8 @@ * be extended to return the longer of the two; in the meantime * translators can fudge it by changing this "filler" string. */ - my_snprintf(buffer, buffer_len, Q_("?filler:XXX/XXX XXX turns")); + /* TRANS: Use longer of "XXX turns" and "never" */ + my_snprintf(buffer, buffer_len, "%s", Q_("?filler:XXX/XXX XXX turns")); return; } @@ -265,7 +266,7 @@ switch (target.kind) { case VUT_IMPROVEMENT: - my_snprintf(buffer, buffer_len, + my_snprintf(buffer, buffer_len, "%s", city_improvement_name_translation(pcity, target.value.building)); if (improvement_has_flag(target.value.building, IF_GOLD)) { @@ -306,7 +307,7 @@ { struct unit_type *ptype = target.value.utype; - my_snprintf(buf[1], column_size, utype_values_string(ptype)); + my_snprintf(buf[1], column_size, "%s", utype_values_string(ptype)); my_snprintf(buf[2], column_size, "(%d)", utype_build_shield_cost(ptype)); break; } @@ -343,7 +344,7 @@ state = _("Small Wonder"); } } - my_snprintf(buf[1], column_size, state); + my_snprintf(buf[1], column_size, "%s", state); } my_snprintf(buf[2], column_size, "%d", diff -Nurd -X.diff_ignore freeciv/client/gui-gtk-2.0/dialogs.c freeciv/client/gui-gtk-2.0/dialogs.c --- freeciv/client/gui-gtk-2.0/dialogs.c 2008-09-22 00:34:34.000000000 +0300 +++ freeciv/client/gui-gtk-2.0/dialogs.c 2008-09-22 03:41:00.000000000 +0300 @@ -1329,7 +1329,8 @@ if (!get_units_upgrade_info(buf, sizeof(buf), punits)) { shell = gtk_message_dialog_new(NULL, 0, - GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, buf); + GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, + "%s", buf); gtk_window_set_title(GTK_WINDOW(shell), _("Upgrade Unit!")); setup_dialog(shell, toplevel); g_signal_connect(shell, "response", G_CALLBACK(gtk_widget_destroy), @@ -1338,7 +1339,7 @@ } else { shell = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, - buf); + "%s", buf); gtk_window_set_title(GTK_WINDOW(shell), _("Upgrade Obsolete Units")); setup_dialog(shell, toplevel); gtk_dialog_set_default_response(GTK_DIALOG(shell), GTK_RESPONSE_YES); diff -Nurd -X.diff_ignore freeciv/client/gui-gtk-2.0/pages.c freeciv/client/gui-gtk-2.0/pages.c --- freeciv/client/gui-gtk-2.0/pages.c 2008-07-01 02:24:00.000000000 +0300 +++ freeciv/client/gui-gtk-2.0/pages.c 2008-09-22 03:44:03.000000000 +0300 @@ -1139,7 +1139,8 @@ /* Show popup. */ popup = gtk_message_dialog_new(NULL, 0, - GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, buf); + GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, + "%s", buf); gtk_window_set_title(GTK_WINDOW(popup), _("Player/conn info")); setup_dialog(popup, toplevel); g_signal_connect(popup, "response", G_CALLBACK(gtk_widget_destroy), NULL); diff -Nurd -X.diff_ignore freeciv/client/gui-gtk-2.0/repodlgs.c freeciv/client/gui-gtk-2.0/repodlgs.c --- freeciv/client/gui-gtk-2.0/repodlgs.c 2008-08-12 03:52:15.000000000 +0300 +++ freeciv/client/gui-gtk-2.0/repodlgs.c 2008-09-22 03:45:04.000000000 +0300 @@ -840,7 +840,7 @@ NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, - buf); + "%s", buf); setup_dialog(shell, gui_dialog_get_toplevel(dlg)); g_signal_connect(shell, "response", G_CALLBACK(gtk_widget_destroy), NULL); diff -Nurd -X.diff_ignore freeciv/client/helpdata.c freeciv/client/helpdata.c --- freeciv/client/helpdata.c 2008-08-12 03:52:23.000000000 +0300 +++ freeciv/client/helpdata.c 2008-09-22 04:09:22.000000000 +0300 @@ -1340,8 +1340,8 @@ output_type = preq->source.value.outputtype; oname = get_output_name(output_type); - astr_add(&outputs_or, oname); - astr_add(&outputs_and, oname); + astr_add(&outputs_or, "%s", oname); + astr_add(&outputs_and, "%s", oname); } break; case VUT_UCLASS: @@ -1395,32 +1395,32 @@ if (!harvested_only || pot->harvested) { if (prev2 != NULL) { - astr_add(&outputs_or, prev2); - astr_add(&outputs_or, Q_("?or:, ")); - astr_add(&outputs_and, prev2); - astr_add(&outputs_and, Q_("?and:, ")); + astr_add(&outputs_or, "%s", prev2); + astr_add(&outputs_or, "%s", Q_("?or:, ")); + astr_add(&outputs_and, "%s", prev2); + astr_add(&outputs_and, "%s", Q_("?and:, ")); } prev2 = prev; prev = _(pot->name); } } output_type_iterate_end; if (prev2 != NULL) { - astr_add(&outputs_or, prev2); + astr_add(&outputs_or, "%s", prev2); /* TRANS: List of possible output types has this between * last two elements */ - astr_add(&outputs_or, Q_(" or ")); - astr_add(&outputs_and, prev2); + astr_add(&outputs_or, "%s", Q_(" or ")); + astr_add(&outputs_and, "%s", prev2); /* TRANS: List of possible output types has this between * last two elements */ - astr_add(&outputs_and, Q_(" and ")); + astr_add(&outputs_and, "%s", Q_(" and ")); } if (prev != NULL) { - astr_add(&outputs_or, prev); - astr_add(&outputs_and, prev); + astr_add(&outputs_or, "%s", prev); + astr_add(&outputs_and, "%s", prev); } else { /* TRANS: Empty output type list, should never happen. */ - astr_add(&outputs_or, Q_("?outputlist: Nothing ")); - astr_add(&outputs_and, Q_("?outputlist: Nothing ")); + astr_add(&outputs_or, "%s", Q_("?outputlist: Nothing ")); + astr_add(&outputs_and, "%s", Q_("?outputlist: Nothing ")); } } diff -Nurd -X.diff_ignore freeciv/client/mapview_common.c freeciv/client/mapview_common.c --- freeciv/client/mapview_common.c 2008-09-22 00:34:40.000000000 +0300 +++ freeciv/client/mapview_common.c 2008-09-22 04:10:19.000000000 +0300 @@ -2311,7 +2311,7 @@ size_t growth_buffer_len, enum color_std *growth_color) { - my_snprintf(name_buffer, name_buffer_len, city_name(pcity)); + my_snprintf(name_buffer, name_buffer_len, "%s", city_name(pcity)); if (NULL == client.conn.playing || city_owner(pcity) == client.conn.playing) { diff -Nurd -X.diff_ignore freeciv/client/text.c freeciv/client/text.c --- freeciv/client/text.c 2008-09-22 00:34:40.000000000 +0300 +++ freeciv/client/text.c 2008-09-22 04:13:30.000000000 +0300 @@ -204,7 +204,7 @@ astr_add(&str, Q_("?clistlast: and %s"), improvement_name_translation(prev_impr)); } - astr_add(&str, Q_("?clistend:.")); + astr_add(&str, "%s", Q_("?clistend:.")); } unit_list_iterate(get_units_in_focus(), pfocus_unit) { @@ -746,7 +746,7 @@ if (!goto_get_turns(&min, &max)) { /* TRANS: Impossible to reach goto target tile */ - astr_add_line(&str, Q_("?goto:Unreachable")); + astr_add_line(&str, "%s", Q_("?goto:Unreachable")); } else if (min == max) { astr_add_line(&str, _("Turns to target: %d"), max); } else { @@ -1000,7 +1000,8 @@ astr_add_line(&str, _("Shows your current government:")); if (NULL != client.conn.playing) { - astr_add_line(&str, government_name_for_player(client.conn.playing)); + astr_add_line(&str, "%s", + government_name_for_player(client.conn.playing)); } return str.str; } @@ -1215,7 +1216,7 @@ if (faces == 0) { astr_add(&str, _("None. ")); } else { - astr_add(&str, Q_("?clistend:.")); + astr_add(&str, "%s", Q_("?clistend:.")); } return str.str; @@ -1254,7 +1255,7 @@ if (faces == 0) { astr_add(&str, _("None. ")); } else { - astr_add(&str, Q_("?clistend:.")); + astr_add(&str, "%s", Q_("?clistend:.")); } return str.str; diff -Nurd -X.diff_ignore freeciv/server/cityhand.c freeciv/server/cityhand.c --- freeciv/server/cityhand.c 2008-05-26 10:16:20.000000000 +0300 +++ freeciv/server/cityhand.c 2008-09-22 03:23:45.000000000 +0300 @@ -450,7 +450,7 @@ } if (!is_allowed_city_name(pplayer, name, message, sizeof(message))) { - notify_player(pplayer, pcity->tile, E_BAD_COMMAND, + notify_player(pplayer, pcity->tile, E_BAD_COMMAND, "%s", message); return; } diff -Nurd -X.diff_ignore freeciv/server/console.c freeciv/server/console.c --- freeciv/server/console.c 2008-05-26 10:16:20.000000000 +0300 +++ freeciv/server/console.c 2008-09-22 03:25:10.000000000 +0300 @@ -50,7 +50,7 @@ static void con_handle_log(int level, const char *message, bool file_too) { if (LOG_ERROR == level) { - notify_conn(NULL, NULL, E_LOG_ERROR, message); + notify_conn(NULL, NULL, E_LOG_ERROR, "%s", message); } else if (LOG_FATAL >= level) { /* Make sure that message is not left to buffers when server dies */ conn_list_iterate(game.est_connections, pconn) { @@ -58,7 +58,7 @@ pconn->compression.frozen_level = 0; } conn_list_iterate_end; - notify_conn(NULL, NULL, E_LOG_FATAL, message); + notify_conn(NULL, NULL, E_LOG_FATAL, "%s", message); notify_conn(NULL, NULL, E_LOG_FATAL, _("Please report this message at %s"), BUG_URL); diff -Nurd -X.diff_ignore freeciv/server/savegame.c freeciv/server/savegame.c --- freeciv/server/savegame.c 2008-09-22 00:34:30.000000000 +0300 +++ freeciv/server/savegame.c 2008-09-22 03:29:51.000000000 +0300 @@ -2386,7 +2386,7 @@ /* lookup name out of order */ my_snprintf(named, sizeof(named), "player%d.c%d.name", plrno, i); /* instead of dying, use name string for damaged name */ - name = secfile_lookup_str_default(file, named, named); + name = secfile_lookup_str_default(file, named, "%s", named); /* copied into city->name */ pcity = create_city_virtual(plr, pcenter, name); @@ -4491,10 +4491,8 @@ rstate.j = secfile_lookup_int(file,"random.index_J"); rstate.k = secfile_lookup_int(file,"random.index_K"); rstate.x = secfile_lookup_int(file,"random.index_X"); - for(i=0;i<8;i++) { - char name[20]; - my_snprintf(name, sizeof(name), "random.table%d",i); - string=secfile_lookup_str(file,name); + for(i = 0; i < 8; i++) { + string = secfile_lookup_str(file, "random.table%d",i); sscanf(string,"%8x %8x %8x %8x %8x %8x %8x", &rstate.v[7*i], &rstate.v[7*i+1], &rstate.v[7*i+2], &rstate.v[7*i+3], &rstate.v[7*i+4], &rstate.v[7*i+5], &rstate.v[7*i+6]); @@ -4974,15 +4972,14 @@ secfile_insert_int(file, rstate.x, "random.index_X"); for (i = 0; i < 8; i++) { - char name[20], vec[100]; + char vec[100]; - my_snprintf(name, sizeof(name), "random.table%d", i); my_snprintf(vec, sizeof(vec), "%8x %8x %8x %8x %8x %8x %8x", rstate.v[7 * i], rstate.v[7 * i + 1], rstate.v[7 * i + 2], rstate.v[7 * i + 3], rstate.v[7 * i + 4], rstate.v[7 * i + 5], rstate.v[7 * i + 6]); - secfile_insert_str(file, vec, name); + secfile_insert_str(file, vec, "random.table%d", i); } } else { secfile_insert_int(file, 0, "game.save_random"); diff -Nurd -X.diff_ignore freeciv/server/scripting/script.c freeciv/server/scripting/script.c --- freeciv/server/scripting/script.c 2008-07-01 02:23:51.000000000 +0300 +++ freeciv/server/scripting/script.c 2008-09-22 03:22:35.000000000 +0300 @@ -104,7 +104,7 @@ } } - freelog(LOG_ERROR, str.str); + freelog(LOG_ERROR, "%s", str.str); astr_free(&str); @@ -293,7 +293,7 @@ const char *vars; const char *section = "script.vars"; - vars = secfile_lookup_str_default(file, "", section); + vars = secfile_lookup_str_default(file, "", "%s", section); script_dostring(state, vars, section); } } @@ -349,7 +349,7 @@ const char *code; const char *section = "script.code"; - code = secfile_lookup_str_default(file, "", section); + code = secfile_lookup_str_default(file, "", "%s", section); script_code = mystrdup(code); script_dostring(state, script_code, section); } diff -Nurd -X.diff_ignore freeciv/server/sernet.c freeciv/server/sernet.c --- freeciv/server/sernet.c 2008-09-22 00:34:30.000000000 +0300 +++ freeciv/server/sernet.c 2008-09-22 03:30:54.000000000 +0300 @@ -491,7 +491,7 @@ if (time(NULL) > last_noplayers + srvarg.quitidle) { save_game_auto("Lost all connections"); set_meta_message_string(N_("restarting for lack of players")); - freelog(LOG_NORMAL, Q_(get_meta_message_string())); + freelog(LOG_NORMAL, "%s", Q_(get_meta_message_string())); (void) send_server_info_to_metaserver(META_INFO); set_server_state(S_S_OVER); diff -Nurd -X.diff_ignore freeciv/server/stdinhand.c freeciv/server/stdinhand.c --- freeciv/server/stdinhand.c 2008-09-22 00:34:30.000000000 +0300 +++ freeciv/server/stdinhand.c 2008-09-22 03:38:51.000000000 +0300 @@ -1609,13 +1609,14 @@ if (may_view_option(caller, i)) { cat_snprintf(buf, sizeof(buf), "%-19s", settings[i].name); if ((++j % 4) == 0) { - cmd_reply(help_cmd, caller, C_COMMENT, buf); + cmd_reply(help_cmd, caller, C_COMMENT, "%s", buf); buf[0] = '\0'; } } } - if (buf[0] != '\0') - cmd_reply(help_cmd, caller, C_COMMENT, buf); + if (buf[0] != '\0') { + cmd_reply(help_cmd, caller, C_COMMENT, "%s", buf); + } } cmd_reply(help_cmd, caller, C_COMMENT, horiz_line); } @@ -1951,7 +1952,7 @@ cmd = -1; /* to indicate that no comannd was specified */ } -#define cmd_reply_show(string) cmd_reply(CMD_SHOW, caller, C_COMMENT, string) +#define cmd_reply_show(string) cmd_reply(CMD_SHOW, caller, C_COMMENT, "%s", string) #define OPTION_NAME_SPACE 13 /* under 16, so it fits into 80 cols more easily - rp */ @@ -1981,8 +1982,9 @@ cmd_reply_show(horiz_line); len1 = my_snprintf(buf, sizeof(buf), _("%-*s value (min,max) "), OPTION_NAME_SPACE, _("Option")); - if (len1 == -1) + if (len1 == -1) { len1 = sizeof(buf) -1; + } sz_strlcat(buf, _("description")); cmd_reply_show(buf); cmd_reply_show(horiz_line); @@ -2556,7 +2558,7 @@ if (settings[cmd].bool_validate && !settings[cmd].bool_validate(b_val, &reject_message)) { - cmd_reply(CMD_SET, caller, C_SYNTAX, reject_message); + cmd_reply(CMD_SET, caller, C_SYNTAX, "%s", reject_message); return FALSE; } else if (!check) { *(op->bool_value) = b_val; @@ -2596,7 +2598,7 @@ if (settings[cmd].int_validate && !settings[cmd].int_validate(val, &reject_message)) { - cmd_reply(CMD_SET, caller, C_SYNTAX, reject_message); + cmd_reply(CMD_SET, caller, C_SYNTAX, "%s", reject_message); return FALSE; } else if (!check) { *(op->int_value) = val; @@ -2619,7 +2621,7 @@ if (settings[cmd].string_validate && !settings[cmd].string_validate(arg, &reject_message)) { - cmd_reply(CMD_SET, caller, C_SYNTAX, reject_message); + cmd_reply(CMD_SET, caller, C_SYNTAX, "%s", reject_message); return FALSE; } else if (!check) { strcpy(op->string_value, arg); @@ -2828,7 +2830,7 @@ /* check allowtake for permission */ if (!is_allowed_to_take(pplayer, TRUE, msg)) { - cmd_reply(CMD_OBSERVE, caller, C_FAIL, msg); + cmd_reply(CMD_OBSERVE, caller, C_FAIL, "%s", msg); goto end; } @@ -2998,7 +3000,7 @@ /* check allowtake for permission */ if (!is_allowed_to_take(pplayer, FALSE, msg)) { - cmd_reply(CMD_TAKE, caller, C_FAIL, msg); + cmd_reply(CMD_TAKE, caller, C_FAIL, "%s", msg); goto end; } @@ -3838,10 +3840,10 @@ **************************************************************************/ static void start_cmd_reply(struct connection *caller, bool notify, char *msg) { - cmd_reply(CMD_START_GAME, caller, C_FAIL, msg); - if (notify) { - notify_conn(NULL, NULL, E_SETTING, msg); - } + cmd_reply(CMD_START_GAME, caller, C_FAIL, "%s", msg); + if (notify) { + notify_conn(NULL, NULL, E_SETTING, "%s", msg); + } } /************************************************************************** @@ -4001,7 +4003,7 @@ " save - to save the current game\n" " quit - to exit"); - cmd_reply(help_cmd, caller, C_COMMENT, help); + cmd_reply(help_cmd, caller, C_COMMENT, "%s", help); } /************************************************************************** @@ -4073,13 +4075,13 @@ if (may_use(caller, i)) { cat_snprintf(buf, sizeof(buf), "%-19s", command_name_by_number(i)); if((++j % 4) == 0) { - cmd_reply(help_cmd, caller, C_COMMENT, buf); + cmd_reply(help_cmd, caller, C_COMMENT, "%s", buf); buf[0] = '\0'; } } } if (buf[0] != '\0') - cmd_reply(help_cmd, caller, C_COMMENT, buf); + cmd_reply(help_cmd, caller, C_COMMENT, "%s", buf); } cmd_reply(help_cmd, caller, C_COMMENT, horiz_line); } diff -Nurd -X.diff_ignore freeciv/utility/registry.c freeciv/utility/registry.c --- freeciv/utility/registry.c 2008-05-26 10:15:54.000000000 +0300 +++ freeciv/utility/registry.c 2008-09-22 03:07:23.000000000 +0300 @@ -1557,7 +1557,7 @@ my_vsnprintf(buf, sizeof(buf), path, ap); va_end(ap); - *dimen = secfile_lookup_vec_dimen(my_section_file, buf); + *dimen = secfile_lookup_vec_dimen(my_section_file, "%s", buf); if (*dimen == 0) { return NULL; } @@ -1589,7 +1589,7 @@ my_vsnprintf(buf, sizeof(buf), path, ap); va_end(ap); - *dimen = secfile_lookup_vec_dimen(my_section_file, buf); + *dimen = secfile_lookup_vec_dimen(my_section_file, "%s", buf); if (*dimen == 0) { return NULL; }
_______________________________________________ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev