--- a/src/server.c Tue May 26 15:29:00 2026 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,173 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2016 Mike Becker. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "network.h" -#include "game.h" -#include "chess/pgn.h" -#include <ncurses.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <signal.h> - -static int server_fd = -1; -static void interrupt_listen(int sig) { - if (server_fd > -1) { - // this interrupts - close(server_fd); - } -} - -static int server_open(Server *server, Settings *settings) { - printw("\nListening for client...\n"); - refresh(); - if (settings->usedomainsocket - ? net_create_sock(server, settings->serverhost) - : net_create_tcp(server, settings->port)) { - addstr("Server creation failed"); - return 1; - } - - // allow Ctrl+C to interrupt the listening process - server_fd = server->fd; - signal(SIGINT, interrupt_listen); - - if (net_listen(server)) { - addstr("Listening for client failed or interrupted"); - return 1; - } - - // restore default action - signal(SIGINT, SIG_DFL); - - return 0; -} - -static int server_handshake(Client *client) { - net_send_code(client->fd, NETCODE_VERSION); - if (net_recieve_code(client->fd) != NETCODE_VERSION) { - addstr("Client uses an incompatible software version."); - return 1; - } - - addstr("Client connected - transmitting gameinfo..."); - refresh(); - - return 0; -} - -int server_run(Settings *settings) { - Server server; - - dump_gameinfo(&(settings->gameinfo)); - GameState gamestate; - gamestate_init(&gamestate); - if (settings->continuepgn) { - /* preload PGN data before handshake */ - FILE *pgnfile = fopen(settings->continuepgn, "r"); - if (pgnfile) { - int result = read_pgn(pgnfile, &gamestate, - &(settings->gameinfo)); - long position = ftell(pgnfile); - fclose(pgnfile); - if (result) { - printw("Invalid PGN file content at position %ld:\n%s\n", - position, pgn_error_str(result)); - return 1; - } - if (!is_game_running(&gamestate)) { - addstr("Game has ended. Use -s to analyze it locally.\n"); - return 1; - } - addch('\n'); - dump_moveinfo(&gamestate); - addch('\n'); - } else { - printw("Can't read PGN file (%s)\n", strerror(errno)); - return 1; - } - } - - if (server_open(&server, settings)) { - net_destroy(&server); - return 1; - } - - if (server_handshake(server.client)) { - net_destroy(&server); - return 1; - } - - int fd = server.client->fd; - if (settings->continuepgn) { - /* Continue game, send PGN data */ - uint16_t mc = gamestate.movecount; - size_t pgndata_size = sizeof(GameInfo)+sizeof(mc)+mc*sizeof(Move); - char *pgndata = malloc(pgndata_size); - memcpy(pgndata, &(settings->gameinfo), sizeof(GameInfo)); - unsigned offset = sizeof(GameInfo); - memcpy(pgndata+offset, &mc, sizeof(mc)); - offset += sizeof(mc); - memcpy(pgndata+offset, gamestate.moves, mc*sizeof(Move)); - net_send_data(fd, NETCODE_PGNDATA, pgndata, pgndata_size); - free(pgndata); - } else { - /* Start new game */ - net_send_data(fd, NETCODE_GAMEINFO, - &(settings->gameinfo), sizeof(GameInfo)); - } - addstr("\rClient connected - awaiting challenge acceptance..."); - refresh(); - int code = net_recieve_code(fd); - int exitcode = 0; - if (code == NETCODE_ACCEPT) { - addstr("\rClient connected - challenge accepted."); - clrtoeol(); - game_play(settings, &gamestate, fd); - net_destroy(&server); - game_review(settings, &gamestate); - } else if (code == NETCODE_DECLINE) { - addstr("\rClient connected - challenge declined."); - clrtoeol(); - net_destroy(&server); - } else if (code == NETCODE_CONNLOST) { - addstr("\rClient connected - but gave no response."); - clrtoeol(); - net_destroy(&server); - } else { - addstr("\rInvalid client response"); - clrtoeol(); - - net_destroy(&server); - exitcode = 1; - } - gamestate_cleanup(&gamestate); - return exitcode; -}