+
+ /* XXX: If generated name is not unique, this will return an error,
+ which violates the protocol. */
+ for (i = 0; i < server->num_clients; i++) {
+ if (strcmp (ttt_client_get_name (server->clients[i]), name) == 0) {
+ error = TTT_ERROR_INVALIDNAME;
+ goto CLEANUP_LOCK;
+ }
+ }
+
+ printf ("Client %s has joined.\n", name);
+ free (name);
+
+ server->num_clients++;
+
+ if (server->num_clients > server->clients_size) {
+ if (server->clients_size == 0)
+ server->clients_size = 1;
+ else
+ server->clients_size *= 2;
+
+ server->clients = xrealloc (server->clients,
+ server->clients_size * sizeof (ttt_client_t *));
+ }
+
+ server->clients [server->num_clients - 1] = client;
+
+ CLEANUP_LOCK:
+ pthread_mutex_unlock (&server->mutex);
+
+ return error;
+}
+
+/* Exported: See ttt-server.h for documentation. */
+void
+ttt_server_unregister_client (ttt_server_t *server, ttt_client_t *client)
+{
+ int i;
+
+ pthread_mutex_lock (&server->mutex);
+
+ for (i = 0; i < server->num_clients; i++)
+ if (server->clients[i] == client)
+ break;
+
+ assert (i < server->num_clients);
+
+ printf ("Client %s has left.\n", ttt_client_get_name (client));
+
+ memmove (&server->clients[i], &server->clients[i+1],
+ (server->num_clients - i - 1) * sizeof (ttt_client_t *));
+
+ server->num_clients--;
+
+ pthread_mutex_unlock (&server->mutex);
+}
+
+void
+ttt_server_broadcast (ttt_server_t *server, const char *message)
+{
+ int i;
+
+ pthread_mutex_lock (&server->mutex);
+
+ for (i = 0; i < server->num_clients; i++)
+ ttt_client_send (server->clients[i], message);
+
+ pthread_mutex_unlock (&server->mutex);
+}
+
+/* Exported: See ttt-server.h for documentation. */
+const char*
+ttt_server_get_host (ttt_server_t *server)
+{
+ return server->host;
+}
+
+/* Exported: See ttt-server.h for documentation. */
+const char*
+ttt_server_get_port (ttt_server_t *server)
+{
+ return server->port;