On Fri, Nov 13, 2009 at 09:24:04PM +0100, Roland Clobus wrote:
> Hello,

Hi,

Sorry for the delay, I've been busy with other things.

> I see a few comments about modifying the patch already sent. What will
> the actual patch be for me to test?

I have it attached.  I wanted to make it clean by doing make reindent
first, but somehow it turned it into a 900+ lines diff.  Sorry about
that.  The patch is identical to my earlier patch plus the suggested
addition for IPV6_V6ONLY in common/network.c.

> (In the meantime I've released 0.12.3, but a 0.12.4 could follow soon,
> if required)

The patch does add a new string (which shouldn't be seen, but should be
translated), so that will need a string-freeze waiting period.

Thanks,
Bas
Index: debian/po/templates.pot
===================================================================
--- debian/po/templates.pot	(revision 1493)
+++ debian/po/templates.pot	(working copy)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: pione...@packages.debian.org\n"
-"POT-Creation-Date: 2009-06-25 20:30+0200\n"
+"POT-Creation-Date: 2010-01-06 21:31+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <em...@address>\n"
 "Language-Team: LANGUAGE <l...@li.org>\n"
Index: editor/gtk/editor.c
===================================================================
--- editor/gtk/editor.c	(revision 1493)
+++ editor/gtk/editor.c	(working copy)
@@ -397,8 +397,8 @@ static void change_height(G_GNUC_UNUSED 
 	if (GPOINTER_TO_INT(user_data) < 0) {
 		gint x;
 		for (x = 0; x < gmap->map->x_size; x++)
-			clear_hex(gmap->map->
-				  grid[gmap->map->y_size - 1][x]);
+			clear_hex(gmap->
+				  map->grid[gmap->map->y_size - 1][x]);
 	}
 	post_change(&gmap->map->y_size, vresize_buttons,
 		    GPOINTER_TO_INT(user_data));
@@ -529,9 +529,8 @@ static GtkWidget *build_terrain_menu(voi
 		}
 
 		pixbuf =
-		    gdk_pixbuf_scale_simple(theme->
-					    scaledata[i].native_image,
-					    width, height,
+		    gdk_pixbuf_scale_simple(theme->scaledata[i].
+					    native_image, width, height,
 					    GDK_INTERP_BILINEAR);
 
 		image = gtk_image_new_from_pixbuf(pixbuf);
Index: common/network.h
===================================================================
--- common/network.h	(revision 1493)
+++ common/network.h	(working copy)
@@ -82,9 +82,11 @@ gboolean net_connected(Session * ses);
  *  @param port The port
  *  @retval error_message If opening fails, a description of the error
  *          You should g_free the error_message
- *  @return A file descriptor if succesfull, or -1 if it fails
+ *  @retval num_fds The number of valid fds in the returned array
+ *  @return An array of file descriptors if succesfull, or NULL if it fails
  */
-int net_open_listening_socket(const gchar * port, gchar ** error_message);
+int *net_open_listening_socket(const gchar * port, gchar ** error_message,
+			       int *num_fds);
 
 /** Close a socket
  */
Index: common/gtk/game-rules.c
===================================================================
--- common/gtk/game-rules.c	(revision 1493)
+++ common/gtk/game-rules.c	(working copy)
@@ -244,6 +244,5 @@ gboolean game_rules_get_victory_at_end_o
 {
 	return
 	    gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
-					 (gr->
-					  check_victory_at_end_of_turn));
+					 (gr->check_victory_at_end_of_turn));
 }
Index: common/gtk/theme.c
===================================================================
--- common/gtk/theme.c	(revision 1493)
+++ common/gtk/theme.c	(working copy)
@@ -394,9 +394,9 @@ void theme_rescale(int new_width)
 		/* rescale the pixbuf */
 		gdk_pixbuf_unref(current_theme->scaledata[i].image);
 		current_theme->scaledata[i].image =
-		    gdk_pixbuf_scale_simple(current_theme->scaledata[i].
-					    native_image, new_width,
-					    new_height,
+		    gdk_pixbuf_scale_simple(current_theme->
+					    scaledata[i].native_image,
+					    new_width, new_height,
 					    GDK_INTERP_BILINEAR);
 
 		/* render a new pixmap */
@@ -404,9 +404,8 @@ void theme_rescale(int new_width)
 		gdk_pixbuf_render_pixmap_and_mask(current_theme->scaledata
 						  [i].image,
 						  &
-						  (current_theme->
-						   terrain_tiles[i]), NULL,
-						  1);
+						  (current_theme->terrain_tiles
+						   [i]), NULL, 1);
 	}
 }
 
Index: common/gtk/guimap.c
===================================================================
--- common/gtk/guimap.c	(revision 1493)
+++ common/gtk/guimap.c	(working copy)
@@ -113,8 +113,7 @@ void guimap_delete(GuiMap * gmap)
 
 		if (gmap->initial_font_size != -1) {
 			pango_font_description_set_size(pfd,
-							gmap->
-							initial_font_size);
+							gmap->initial_font_size);
 		}
 
 		g_object_unref(gmap->layout);
@@ -722,8 +721,8 @@ static gboolean display_hex(const Hex * 
 		} else if (!theme->colors[TC_PORT_BG].transparent) {
 			gdk_gc_set_fill(gmap->gc, GDK_SOLID);
 			gdk_gc_set_foreground(gmap->gc,
-					      &theme->colors[TC_PORT_BG].
-					      color);
+					      &theme->
+					      colors[TC_PORT_BG].color);
 			typeind = FALSE;
 			drawit = TRUE;
 		} else {
@@ -745,8 +744,8 @@ static gboolean display_hex(const Hex * 
 						   GDK_CAP_BUTT,
 						   GDK_JOIN_MITER);
 			gdk_gc_set_foreground(gmap->gc,
-					      &theme->colors[TC_PORT_BD].
-					      color);
+					      &theme->
+					      colors[TC_PORT_BD].color);
 			gdk_draw_arc(gmap->pixmap, gmap->gc, FALSE,
 				     x_offset - gmap->chit_radius,
 				     y_offset - gmap->chit_radius,
@@ -794,8 +793,8 @@ static gboolean display_hex(const Hex * 
 			pango_layout_get_pixel_size(gmap->layout, &width,
 						    &height);
 			gdk_gc_set_foreground(gmap->gc,
-					      &theme->colors[TC_PORT_FG].
-					      color);
+					      &theme->
+					      colors[TC_PORT_FG].color);
 			gdk_draw_layout(gmap->pixmap, gmap->gc,
 					x_offset - width / 2,
 					y_offset - height / 2,
@@ -879,14 +878,14 @@ static gboolean display_hex(const Hex * 
 					   GDK_CAP_BUTT, GDK_JOIN_MITER);
 		if (!theme->colors[TC_ROBBER_FG].transparent) {
 			gdk_gc_set_foreground(gmap->gc,
-					      &theme->colors[TC_ROBBER_FG].
-					      color);
+					      &theme->
+					      colors[TC_ROBBER_FG].color);
 			poly_draw(gmap->pixmap, gmap->gc, TRUE, &poly);
 		}
 		if (!theme->colors[TC_ROBBER_BD].transparent) {
 			gdk_gc_set_foreground(gmap->gc,
-					      &theme->colors[TC_ROBBER_BD].
-					      color);
+					      &theme->
+					      colors[TC_ROBBER_BD].color);
 			poly_draw(gmap->pixmap, gmap->gc, FALSE, &poly);
 		}
 	}
@@ -899,14 +898,14 @@ static gboolean display_hex(const Hex * 
 					   GDK_CAP_BUTT, GDK_JOIN_MITER);
 		if (!theme->colors[TC_ROBBER_FG].transparent) {
 			gdk_gc_set_foreground(gmap->gc,
-					      &theme->colors[TC_ROBBER_FG].
-					      color);
+					      &theme->
+					      colors[TC_ROBBER_FG].color);
 			poly_draw(gmap->pixmap, gmap->gc, TRUE, &poly);
 		}
 		if (!theme->colors[TC_ROBBER_BD].transparent) {
 			gdk_gc_set_foreground(gmap->gc,
-					      &theme->colors[TC_ROBBER_BD].
-					      color);
+					      &theme->
+					      colors[TC_ROBBER_BD].color);
 			poly_draw(gmap->pixmap, gmap->gc, FALSE, &poly);
 		}
 	}
@@ -1805,8 +1804,7 @@ void guimap_cursor_move(GuiMap * gmap, g
 		if (element->pointer) {
 			can_build_settlement = (settlementM
 						&& settlementF(*element,
-							       gmap->
-							       player_num,
+							       gmap->player_num,
 							       dummyElement));
 			can_build_city = (cityM
 					  && cityF(*element,
@@ -1814,8 +1812,7 @@ void guimap_cursor_move(GuiMap * gmap, g
 						   dummyElement));
 			can_build_city_wall = (cityWallM
 					       && cityWallF(*element,
-							    gmap->
-							    player_num,
+							    gmap->player_num,
 							    dummyElement));
 			can_build_node = can_build_settlement
 			    || can_build_city || can_build_city_wall;
Index: common/game.c
===================================================================
--- common/game.c	(revision 1493)
+++ common/game.c	(working copy)
@@ -245,8 +245,7 @@ void params_write_lines(GameParams * par
 			buff = g_strdup_printf("%s %d", param->name,
 					       G_STRUCT_MEMBER(gint,
 							       params,
-							       param->
-							       offset));
+							       param->offset));
 			func(user_data, buff);
 			g_free(buff);
 			break;
@@ -261,8 +260,7 @@ void params_write_lines(GameParams * par
 			    format_int_list(param->name,
 					    G_STRUCT_MEMBER(GArray *,
 							    params,
-							    param->
-							    offset));
+							    param->offset));
 			/* Don't send empty intlists */
 			if (buff != NULL) {
 				func(user_data, buff);
@@ -498,8 +496,7 @@ GameParams *params_copy(const GameParams
 			    format_int_list("",
 					    G_STRUCT_MEMBER(GArray *,
 							    &nonconst,
-							    param->
-							    offset));
+							    param->offset));
 			if (buff != NULL) {
 				G_STRUCT_MEMBER(GArray *, copy,
 						param->offset) =
@@ -619,9 +616,8 @@ WinnableState params_check_winnable_stat
 			    g_array_index(params->island_discovery_bonus,
 					  gint,
 					  MIN
-					  (params->
-					   island_discovery_bonus->len - 1,
-					   i));
+					  (params->island_discovery_bonus->
+					   len - 1, i));
 			/* The island score can be negative */
 			if (max_island < total_island)
 				max_island = total_island;
Index: common/network.c
===================================================================
--- common/network.c	(revision 1493)
+++ common/network.c	(working copy)
@@ -743,13 +743,17 @@ const gchar *get_pioneers_dir(void)
 	return pioneers_dir;
 }
 
-int net_open_listening_socket(const gchar * port, gchar ** error_message)
+int *net_open_listening_socket(const gchar * port, gchar ** error_message,
+			       int *num_fds)
 {
 #ifdef HAVE_GETADDRINFO_ET_AL
 	int err;
 	struct addrinfo hints, *ai, *aip;
 	int yes;
-	gint fd = -1;
+	int *fds;
+	int max_num_fds;
+
+	*num_fds = 0;
 
 	memset(&hints, 0, sizeof(hints));
 
@@ -763,65 +767,89 @@ int net_open_listening_socket(const gcha
 		    g_strdup_printf(_(""
 				      "Error creating struct addrinfo: %s"),
 				    gai_strerror(err));
-		return -1;
+		return NULL;
+	}
+
+	max_num_fds = 0;
+	for (aip = ai; aip; aip = aip->ai_next) {
+		++max_num_fds;
 	}
 
+	fds = g_malloc(max_num_fds * sizeof(*fds));
 	for (aip = ai; aip; aip = aip->ai_next) {
-		fd = socket(aip->ai_family, SOCK_STREAM, 0);
-		if (fd < 0) {
+		fds[*num_fds] = socket(aip->ai_family, SOCK_STREAM, 0);
+		if (fds[*num_fds] < 0) {
 			continue;
 		}
-		yes = 1;
 
 		/* setsockopt() before bind(); otherwise it has no effect! -- egnor */
+		yes = 1;
+		if ((aip->ai_family == AF_INET6)
+		    &&
+		    (setsockopt
+		     (fds[*num_fds], IPPROTO_IPV6, IPV6_V6ONLY, &yes,
+		      sizeof(yes)) < 0)) {
+			g_warning(_
+				  (""
+				   "Not using socket because setting IPV6_V6ONLY failed: %s\n"),
+				  net_errormsg());
+			net_closesocket(fds[*num_fds]);
+			continue;
+		}
 		if (setsockopt
-		    (fd, SOL_SOCKET, SO_REUSEADDR, &yes,
+		    (fds[*num_fds], SOL_SOCKET, SO_REUSEADDR, &yes,
 		     sizeof(yes)) < 0) {
-			net_closesocket(fd);
+			g_warning(_(""
+				    "Not using socket because setting REUSEADDR failed: %s\n"),
+				  net_errormsg());
+			net_closesocket(fds[*num_fds]);
 			continue;
 		}
-		if (bind(fd, aip->ai_addr, aip->ai_addrlen) < 0) {
-			net_closesocket(fd);
+		if (bind(fds[*num_fds], aip->ai_addr, aip->ai_addrlen) < 0) {
+			g_warning(_(""
+				    "Not using socket because bind failed: %s\n"),
+				  net_errormsg());
+			net_closesocket(fds[*num_fds]);
 			continue;
 		}
 
-		break;
-	}
+		if (net_set_socket_non_blocking(fds[*num_fds])) {
+			g_warning(_(""
+				    "Not using socket because it cannot be set to non-blocking: %s\n"),
+				  net_errormsg());
+			net_closesocket(fds[*num_fds]);
+			continue;
+		}
 
-	if (!aip) {
-		*error_message =
-		    g_strdup_printf(_(""
-				      "Error creating listening socket: %s\n"),
-				    net_errormsg());
-		freeaddrinfo(ai);
-		return -1;
+		if (listen(fds[*num_fds], 5) < 0) {
+			g_warning(_(""
+				    "Not using socket because listening failed: %s\n"),
+				  net_errormsg());
+			net_closesocket(fds[*num_fds]);
+			continue;
+		}
+
+		/* Listening succeeded.  Keep the fd and continue.  */
+		++*num_fds;
 	}
 
 	freeaddrinfo(ai);
 
-	if (net_set_socket_non_blocking(fd)) {
+	if (*num_fds == 0) {
+		g_free(fds);
 		*error_message =
 		    g_strdup_printf(_(""
-				      "Error setting socket non-blocking: %s\n"),
+				      "Error creating listening socket: %s\n"),
 				    net_errormsg());
-		net_closesocket(fd);
-		return -1;
+		return NULL;
 	}
 
-	if (listen(fd, 5) < 0) {
-		*error_message =
-		    g_strdup_printf(_(""
-				      "Error during listen on socket: %s\n"),
-				    net_errormsg());
-		net_closesocket(fd);
-		return -1;
-	}
 	*error_message = NULL;
-	return fd;
+	return fds;
 #else				/* HAVE_GETADDRINFO_ET_AL */
 	*error_message =
 	    g_strdup(_("Listening not yet supported on this platform."));
-	return -1;
+	return NULL;
 #endif				/* HAVE_GETADDRINFO_ET_AL */
 }
 
Index: meta-server/main.c
===================================================================
--- meta-server/main.c	(revision 1493)
+++ meta-server/main.c	(working copy)
@@ -92,7 +92,8 @@ static GList *client_list;
 
 static fd_set read_fds;
 static fd_set write_fds;
-static int accept_fd;
+static int *accept_fds;
+static int num_accept_fds;
 static gint max_fd;
 
 /* Command line data */
@@ -189,8 +190,14 @@ static void meta_debug(const gchar * fmt
 static void find_new_max_fd(void)
 {
 	GList *list;
+	int i;
 
-	max_fd = accept_fd;
+	max_fd = -1;
+	for (i = 0; i < num_accept_fds; ++i) {
+		if (accept_fds[i] > max_fd) {
+			max_fd = accept_fds[i];
+		}
+	}
 	for (list = client_list; list != NULL; list = g_list_next(list)) {
 		Client *client = list->data;
 
@@ -836,7 +843,7 @@ static void client_do_read(Client * clie
 	set_client_event_at(client);
 }
 
-static void accept_new_client(void)
+static void accept_new_client(int accept_fd)
 {
 	int fd;
 	gchar *error_message;
@@ -928,6 +935,7 @@ static void select_loop(void)
 		fd_set read_res;
 		fd_set write_res;
 		int num;
+		int i;
 		struct timeval *timeout;
 		GList *list;
 
@@ -952,9 +960,11 @@ static void select_loop(void)
 			}
 		}
 
-		if (FD_ISSET(accept_fd, &read_res)) {
-			accept_new_client();
-			num--;
+		for (i = 0; i < num_accept_fds; ++i) {
+			if (FD_ISSET(accept_fds[i], &read_res)) {
+				accept_new_client(accept_fds[i]);
+				num--;
+			}
 		}
 
 		list = client_list;
@@ -985,17 +995,22 @@ static void select_loop(void)
 
 static gboolean setup_accept_sock(const gchar * port)
 {
-	int fd;
+	int *fds;
+	int i;
 	gchar *error_message;
 
-	fd = net_open_listening_socket(port, &error_message);
-	if (fd == -1) {
+	fds =
+	    net_open_listening_socket(port, &error_message,
+				      &num_accept_fds);
+	if (!fds) {
 		my_syslog(LOG_ERR, "%s", error_message);
 		g_free(error_message);
 		return FALSE;
 	}
-	accept_fd = max_fd = fd;
-	FD_SET(accept_fd, &read_fds);
+	accept_fds = fds;
+	find_new_max_fd();
+	for (i = 0; i < num_accept_fds; ++i)
+		FD_SET(accept_fds[i], &read_fds);
 	return TRUE;
 }
 
@@ -1089,6 +1104,7 @@ int main(int argc, char *argv[])
 	GOptionContext *context;
 	GError *error = NULL;
 	GList *game_list;
+	int i;
 
 	setlocale(LC_ALL, "");
 	bindtextdomain(PACKAGE, LOCALEDIR);
@@ -1161,6 +1177,11 @@ int main(int argc, char *argv[])
 	my_syslog(LOG_INFO, "Pioneers meta server started.");
 	select_loop();
 
+	for (i = 0; i < num_accept_fds; ++i) {
+		net_closesocket(accept_fds[i]);
+		accept_fds[i] = -1;
+	}
 	net_finish();
+	g_free(accept_fds);
 	return 0;
 }
Index: server/gtk/main.c
===================================================================
--- server/gtk/main.c	(revision 1493)
+++ server/gtk/main.c	(working copy)
@@ -175,8 +175,7 @@ static void update_game_settings(const G
 	game_settings_set_victory_points(GAMESETTINGS(game_settings),
 					 params->victory_points);
 	game_rules_set_victory_at_end_of_turn(GAMERULES(game_rules),
-					      params->
-					      check_victory_at_end_of_turn);
+					      params->check_victory_at_end_of_turn);
 	game_rules_set_random_terrain(GAMERULES(game_rules),
 				      params->random_terrain);
 	game_rules_set_sevens_rule(GAMERULES(game_rules),
@@ -298,8 +297,7 @@ static void start_clicked_cb(G_GNUC_UNUS
 			config_set_int("game/victory-points",
 				       params->victory_points);
 			config_set_int("game/check-victory-at-end-of-turn",
-				       params->
-				       check_victory_at_end_of_turn);
+				       params->check_victory_at_end_of_turn);
 			config_set_int("game/sevens-rule",
 				       params->sevens_rule);
 			config_set_int("game/use-pirate",
Index: server/meta.c
===================================================================
--- server/meta.c	(revision 1493)
+++ server/meta.c	(working copy)
@@ -94,15 +94,15 @@ void meta_send_details(Game * game)
 			   game->params->sevens_rule == 0 ? "normal" :
 			   game->params->sevens_rule ==
 			   1 ? "reroll first 2" : "reroll all",
-			   game->params->
-			   random_terrain ? "random" : "default",
+			   game->
+			   params->random_terrain ? "random" : "default",
 			   game->params->title);
 	} else {
 		net_printf(ses,
 			   "map=%s\n"
 			   "comment=%s\n",
-			   game->params->
-			   random_terrain ? "random" : "default",
+			   game->
+			   params->random_terrain ? "random" : "default",
 			   game->params->title);
 	}
 }
Index: server/turn.c
===================================================================
--- server/turn.c	(revision 1493)
+++ server/turn.c	(working copy)
@@ -238,11 +238,12 @@ static void build_add(Player * player, B
 			 * or the current island
 			 */
 			points =
-			    g_array_index(game->params->
-					  island_discovery_bonus, gint,
-					  MIN(game->params->
-					      island_discovery_bonus->len -
-					      1,
+			    g_array_index(game->
+					  params->island_discovery_bonus,
+					  gint,
+					  MIN(game->
+					      params->island_discovery_bonus->
+					      len - 1,
 					      player->islands_discovered));
 
 			if (points != 0)
Index: server/server.c
===================================================================
--- server/server.c	(revision 1493)
+++ server/server.c	(working copy)
@@ -74,8 +74,9 @@ Game *game_new(const GameParams * params
 
 	game = g_malloc0(sizeof(*game));
 
-	game->accept_tag = 0;
-	game->accept_fd = -1;
+	game->accept_tag = NULL;
+	game->accept_fd = NULL;
+	game->num_fds = 0;
 	game->is_running = FALSE;
 	game->is_game_over = FALSE;
 	game->params = params_copy(params);
@@ -101,6 +102,10 @@ void game_free(Game * game)
 	if (game->server_port != NULL)
 		g_free(game->server_port);
 	params_free(game->params);
+	if (game->accept_fd)
+		g_free(game->accept_fd);
+	if (game->accept_tag)
+		g_free(game->accept_tag);
 	g_free(game);
 }
 
@@ -161,14 +166,16 @@ gint add_computer_player(Game * game, gb
 }
 
 
-static void player_connect(Game * game)
+static void player_connect(Connect_info * info)
 {
 	gchar *location;
-	gint fd = accept_connection(game->accept_fd, &location);
+	gint fd =
+	    accept_connection(info->game->accept_fd[info->num], &location);
 
 	if (fd > 0) {
-		if (player_new_connection(game, fd, location) != NULL)
-			stop_timeout(game);
+		if (player_new_connection(info->game, fd, location) !=
+		    NULL)
+			stop_timeout(info->game);
 	}
 	g_free(location);
 }
@@ -177,21 +184,32 @@ static gboolean game_server_start(Game *
 				  const gchar * meta_server_name)
 {
 	gchar *error_message;
+	int i;
 
 	game->accept_fd =
-	    net_open_listening_socket(game->server_port, &error_message);
-	if (game->accept_fd == -1) {
+	    net_open_listening_socket(game->server_port, &error_message,
+				      &game->num_fds);
+	if (game->accept_fd == NULL) {
 		log_message(MSG_ERROR, "%s\n", error_message);
 		g_free(error_message);
 		return FALSE;
 	}
+	game->accept_tag =
+	    g_malloc0(game->num_fds * sizeof(*game->accept_tag));
 	game->is_running = TRUE;
 
 	start_timeout(game);
 
-	game->accept_tag = driver->input_add_read(game->accept_fd,
-						  (InputFunc)
-						  player_connect, game);
+	game->connect_info =
+	    g_malloc0(game->num_fds * sizeof(Connect_info));
+	for (i = 0; i < game->num_fds; ++i) {
+		game->connect_info[i].game = game;
+		game->connect_info[i].num = i;
+		game->accept_tag[i] =
+		    driver->input_add_read(game->accept_fd[i], (InputFunc)
+					   player_connect,
+					   &game->connect_info[i]);
+	}
 
 	if (register_server) {
 		g_assert(meta_server_name != NULL);
@@ -254,6 +272,7 @@ Game *server_start(const GameParams * pa
 gboolean server_stop(Game * game)
 {
 	GList *current;
+	int i;
 
 	if (!server_is_running(game))
 		return FALSE;
@@ -262,13 +281,18 @@ gboolean server_stop(Game * game)
 
 	game->is_running = FALSE;
 	if (game->accept_tag) {
-		driver->input_remove(game->accept_tag);
-		game->accept_tag = 0;
-	}
-	if (game->accept_fd >= 0) {
-		close(game->accept_fd);
-		game->accept_fd = -1;
+		for (i = 0; i < game->num_fds; ++i)
+			driver->input_remove(game->accept_tag[i]);
+		g_free(game->accept_tag);
+		game->accept_tag = NULL;
+	}
+	if (game->accept_fd) {
+		for (i = 0; i < game->num_fds; ++i)
+			close(game->accept_fd[i]);
+		g_free(game->accept_fd);
+		game->accept_fd = NULL;
 	}
+	game->num_fds = 0;
 
 	playerlist_inc_use_count(game);
 	current = game->player_list;
Index: server/server.h
===================================================================
--- server/server.h	(revision 1493)
+++ server/server.h	(working copy)
@@ -47,6 +47,12 @@ typedef enum {
 #define TERRAIN_RANDOM	1
 
 typedef struct Game Game;
+
+typedef struct {
+	Game *game;		/* The game */
+	int num;		/* The index into game->accept_fd */
+} Connect_info;
+
 typedef struct {
 	StateMachine *sm;	/* state machine for this player */
 	Game *game;		/* game that player belongs to */
@@ -89,8 +95,10 @@ struct Game {
 	GameParams *params;	/* game parameters */
 	gchar *hostname;	/* reported hostname */
 
-	int accept_fd;		/* socket for accepting new clients */
-	int accept_tag;		/* Gdk event tag for accept socket */
+	int num_fds;		/* number of elements in accept_fd and accept_tag */
+	int *accept_fd;		/* sockets for accepting new clients */
+	int *accept_tag;	/* Gdk event tags for accept socket */
+	Connect_info *connect_info;	/* Structure for finding the listening fd in the accept callback */
 
 	GList *player_list;	/* all players in the game */
 	GList *dead_players;	/* all players that should be removed when player_list_use_count == 0 */
Index: server/pregame.c
===================================================================
--- server/pregame.c	(revision 1493)
+++ server/pregame.c	(working copy)
@@ -681,8 +681,8 @@ gboolean mode_pre_game(Player * player, 
 				player_send_uncached(player, FIRST_VERSION,
 						     LATEST_VERSION,
 						     "playerinfo: numdevcards: %d\n",
-						     player->devel->
-						     num_cards);
+						     player->
+						     devel->num_cards);
 				for (i = 0; i < player->devel->num_cards;
 				     i++) {
 					player_send_uncached(player,
@@ -690,13 +690,10 @@ gboolean mode_pre_game(Player * player, 
 							     LATEST_VERSION,
 							     "playerinfo: devcard: %d %d\n",
 							     (gint)
-							     player->
-							     devel->
-							     cards[i].type,
-							     player->
-							     devel->
-							     cards[i].
-							     turn_bought);
+							     player->devel->cards
+							     [i].type,
+							     player->devel->cards
+							     [i].turn_bought);
 				}
 				player_send_uncached(player, FIRST_VERSION,
 						     LATEST_VERSION,
@@ -704,8 +701,7 @@ gboolean mode_pre_game(Player * player, 
 						     player->num_roads,
 						     player->num_bridges,
 						     player->num_ships,
-						     player->
-						     num_settlements,
+						     player->num_settlements,
 						     player->num_cities,
 						     player->num_soldiers,
 						     player->road_len,
@@ -729,8 +725,7 @@ gboolean mode_pre_game(Player * player, 
 							     "get-point %d %d %d %s\n",
 							     player->num,
 							     points->id,
-							     points->
-							     points,
+							     points->points,
 							     points->name);
 					list = g_list_next(list);
 				}
@@ -772,8 +767,7 @@ gboolean mode_pre_game(Player * player, 
 							     "get-point %d %d %d %s\n",
 							     p->num,
 							     points->id,
-							     points->
-							     points,
+							     points->points,
 							     points->name);
 					list = g_list_next(list);
 				}
@@ -805,8 +799,8 @@ gboolean mode_pre_game(Player * player, 
 			    && (Player *) game->setup_player->data !=
 			    player) {
 				gint num =
-				    ((Player *) (game->setup_player->
-						 data))->num;
+				    ((Player *) (game->
+						 setup_player->data))->num;
 				if (game->double_setup)
 					player_send_uncached(player,
 							     FIRST_VERSION,
@@ -819,8 +813,7 @@ gboolean mode_pre_game(Player * player, 
 							     LATEST_VERSION,
 							     "player %d setup %d\n",
 							     num,
-							     game->
-							     reverse_setup);
+							     game->reverse_setup);
 			}
 
 			if (recover_from_plenty) {
@@ -841,8 +834,7 @@ gboolean mode_pre_game(Player * player, 
 							     LATEST_VERSION,
 							     "player %d must-discard %d\n",
 							     p->num,
-							     p->
-							     discard_num);
+							     p->discard_num);
 				}
 				if (p->gold > 0) {
 					player_send_uncached(player,
@@ -889,10 +881,10 @@ gboolean mode_pre_game(Player * player, 
 						    (player, FIRST_VERSION,
 						     LATEST_VERSION,
 						     "player %d domestic-quote quote %d supply %R receive %R\n",
-						     quote->var.d.
-						     player_num,
-						     quote->var.d.
-						     quote_num,
+						     quote->var.
+						     d.player_num,
+						     quote->var.
+						     d.quote_num,
 						     quote->var.d.supply,
 						     quote->var.d.receive);
 					}
Index: server/admin.c
===================================================================
--- server/admin.c	(revision 1493)
+++ server/admin.c	(working copy)
@@ -35,7 +35,8 @@
 #include "server.h"
 
 /* network administration functions */
-comm_info *_accept_info = NULL;
+static comm_info *_accept_info = NULL;
+static int num_accept_fds = 0;
 
 gint admin_dice_roll = 0;
 
@@ -234,14 +235,12 @@ void admin_run_command(Session * admin_s
 					net_printf(admin_session,
 						   "INFO %s argument\n",
 						   admin_commands
-						   [command_number].
-						   command);
+						   [command_number].command);
 				} else {
 					net_printf(admin_session,
 						   "INFO %s\n",
 						   admin_commands
-						   [command_number].
-						   command);
+						   [command_number].command);
 				}
 			}
 			break;
@@ -373,25 +372,35 @@ void admin_connect(comm_info * admin_inf
 void admin_listen(const gchar * port)
 {
 	gchar *error_message;
-
-	if (!_accept_info) {
-		_accept_info = g_malloc0(sizeof(comm_info));
-	}
-
-	/* open up a socket on which to listen for connections */
-	_accept_info->fd = net_open_listening_socket(port, &error_message);
-	if (_accept_info->fd == -1) {
+	int num_fds;
+	int *fds;
+	int i;
+
+	/* open up sockets on which to listen for connections */
+	fds = net_open_listening_socket(port, &error_message, &num_fds);
+	if (!fds) {
 		log_message(MSG_ERROR, "%s\n", error_message);
 		g_free(error_message);
 		return;
 	}
+
+	if (!_accept_info) {
+		_accept_info = g_malloc0(sizeof(comm_info) * num_fds);
+	} else if (num_accept_fds != num_fds) {
+		g_free(_accept_info);
+		_accept_info = g_malloc0(sizeof(comm_info) * num_fds);
+	}
+	num_accept_fds = num_fds;
+
+	for (i = 0; i < num_fds; ++i) {
 #ifdef PRINT_INFO
-	g_print("admin_listen: fd = %d\n", _accept_info->fd);
+		g_print("admin_listen: fd[%d] = %d\n", i, fds[i]);
 #endif
-
-	/* set up the callback to handle connections */
-	_accept_info->read_tag =
-	    driver->input_add_read(_accept_info->fd,
-				   (InputFunc) admin_connect,
-				   _accept_info);
+		_accept_info[i].fd = fds[i];
+		/* set up the callback to handle connections */
+		_accept_info[i].read_tag =
+		    driver->input_add_read(fds[i],
+					   (InputFunc) admin_connect,
+					   &_accept_info[i]);
+	}
 }
Index: server/admin.h
===================================================================
--- server/admin.h	(revision 1493)
+++ server/admin.h	(working copy)
@@ -25,7 +25,7 @@
 #include "network.h"
 
 typedef struct _comm_info {
-	gint fd;
+	int fd;
 	guint read_tag;
 	guint write_tag;
 } comm_info;
Index: client/gtk/player.c
===================================================================
--- client/gtk/player.c	(revision 1493)
+++ client/gtk/player.c	(working copy)
@@ -289,8 +289,7 @@ void frontend_new_statistics(gint player
 			if (statistics[type].plural != NULL)
 				desc = g_strdup_printf("%d %s", value,
 						       gettext(statistics
-							       [type].
-							       singular));
+							       [type].singular));
 			else
 				desc = g_strdup(gettext
 						(statistics
Index: client/gtk/quote-view.c
===================================================================
--- client/gtk/quote-view.c	(revision 1493)
+++ client/gtk/quote-view.c	(working copy)
@@ -575,10 +575,10 @@ void quote_view_add_quote(QuoteView * qv
 	pixbuf = player_create_icon(GTK_WIDGET(qv), player_num, TRUE);
 	gtk_list_store_set(qv->store, &iter, TRADE_COLUMN_PLAYER, pixbuf,
 			   TRADE_COLUMN_POSSIBLE,
-			   qv->check_quote_func(quote) ? qv->
-			   true_pixbuf : qv->false_pixbuf,
-			   TRADE_COLUMN_DESCRIPTION, quote_desc,
-			   TRADE_COLUMN_QUOTE, quote,
+			   qv->
+			   check_quote_func(quote) ? qv->true_pixbuf : qv->
+			   false_pixbuf, TRADE_COLUMN_DESCRIPTION,
+			   quote_desc, TRADE_COLUMN_QUOTE, quote,
 			   TRADE_COLUMN_PLAYER_NUM, player_num, -1);
 	g_object_unref(pixbuf);
 }
Index: client/gtk/settingscreen.c
===================================================================
--- client/gtk/settingscreen.c	(revision 1493)
+++ client/gtk/settingscreen.c	(working copy)
@@ -208,8 +208,7 @@ static GtkWidget *settings_create_conten
 			gchar *old = island_bonus;
 			gchar *number = g_strdup_printf("%d",
 							g_array_index
-							(game_params->
-							 island_discovery_bonus,
+							(game_params->island_discovery_bonus,
 							 gint, idx));
 			island_bonus =
 			    g_strconcat(island_bonus, ", ", number, NULL);
Index: client/gtk/gui.c
===================================================================
--- client/gtk/gui.c	(revision 1493)
+++ client/gtk/gui.c	(working copy)
@@ -1280,8 +1280,7 @@ static void gui_toolbar_show_accelerator
 				} else {
 					gtk_tool_button_set_label(tbtn,
 								  _(entries
-								    [j].
-								    label));
+								    [j].label));
 				}
 				break;
 			}
Index: client/gtk/connect.c
===================================================================
--- client/gtk/connect.c	(revision 1493)
+++ client/gtk/connect.c	(working copy)
@@ -477,8 +477,7 @@ static void meta_notify(NetEvent event, 
 				if (split_result[1]) {
 					if (metaserver_info.server)
 						g_free
-						    (metaserver_info.
-						     server);
+						    (metaserver_info.server);
 					metaserver_info.server =
 					    g_strdup(split_result[1]);
 					if (metaserver_info.port)
@@ -513,9 +512,8 @@ static void meta_notify(NetEvent event, 
 					    atoi(p);
 					p += strspn(p, "0123456789");
 					if (*p == '.')
-						metaserver_info.
-						    version_minor =
-						    atoi(p + 1);
+						metaserver_info.version_minor
+						    = atoi(p + 1);
 				}
 			}
 			if (metaserver_info.version_major < 1) {

Attachment: signature.asc
Description: Digital signature

Reply via email to