Wed, 05 Feb 2014 14:07:43 +0100
added (single) client / server architecture
conf.mk | file | annotate | diff | comparison | revisions | |
src/Makefile | file | annotate | diff | comparison | revisions | |
src/main.c | file | annotate | diff | comparison | revisions | |
src/network.c | file | annotate | diff | comparison | revisions | |
src/network.h | file | annotate | diff | comparison | revisions | |
src/terminal-chess.h | file | annotate | diff | comparison | revisions |
1.1 --- a/conf.mk Thu Jan 23 14:45:34 2014 +0100 1.2 +++ b/conf.mk Wed Feb 05 14:07:43 2014 +0100 1.3 @@ -31,7 +31,7 @@ 1.4 RM = rm 1.5 1.6 # build related 1.7 -BIN = c2html 1.8 +BIN = terminal-chess 1.9 CC = gcc 1.10 CFLAGS = -g -O2 -std=gnu99 -Wall -Werror -pedantic 1.11 LD = gcc
2.1 --- a/src/Makefile Thu Jan 23 14:45:34 2014 +0100 2.2 +++ b/src/Makefile Wed Feb 05 14:07:43 2014 +0100 2.3 @@ -29,6 +29,7 @@ 2.4 include ../conf.mk 2.5 2.6 SRC = main.c 2.7 +SRC += network.c 2.8 2.9 OBJ = $(SRC:%.c=../build/%$(OBJ_EXT)) 2.10
3.1 --- a/src/main.c Thu Jan 23 14:45:34 2014 +0100 3.2 +++ b/src/main.c Wed Feb 05 14:07:43 2014 +0100 3.3 @@ -27,9 +27,98 @@ 3.4 * 3.5 */ 3.6 3.7 -#include <stdlib.h> 3.8 +#include "terminal-chess.h" 3.9 +#include <string.h> 3.10 + 3.11 +int get_settings(int argc, char **argv, Settings *settings) { 3.12 + char *valid; 3.13 + 3.14 + for (char opt ; (opt = getopt(argc, argv, "hp:")) != -1 ;) { 3.15 + switch (opt) { 3.16 + case 'p': 3.17 + if (strtol(optarg, &valid, 10) < 1025 || *valid != '\0') { 3.18 + fprintf(stderr, 3.19 + "Invalid port number (%s) - choose a number > 1024\n", 3.20 + optarg); 3.21 + return 1; 3.22 + } else { 3.23 + settings->port = optarg; 3.24 + } 3.25 + break; 3.26 + case 'h': 3.27 + case '?': 3.28 + settings->printhelp = 1; 3.29 + break; 3.30 + } 3.31 + } 3.32 + 3.33 + if (optind == argc - 1) { 3.34 + settings->serverhost = argv[optind]; 3.35 + } else if (optind < argc - 1) { 3.36 + fprintf(stderr, "Too many arguments\n"); 3.37 + return 1; 3.38 + } 3.39 + 3.40 + return 0; 3.41 +} 3.42 + 3.43 +Settings default_settings() { 3.44 + Settings settings; 3.45 + memset(&settings, 0, sizeof(Settings)); 3.46 + settings.port = "27015"; 3.47 + return settings; 3.48 +} 3.49 + 3.50 +int cleanup(Settings *settings, int exitcode) { 3.51 + if (settings->server) { 3.52 + if (net_destroy(settings->server)) { 3.53 + perror("Server shutdown failed"); 3.54 + } 3.55 + } 3.56 + 3.57 + return exitcode; 3.58 +} 3.59 3.60 int main(int argc, char **argv) { 3.61 - return EXIT_SUCCESS; 3.62 + 3.63 + Settings settings = default_settings(); 3.64 + get_settings(argc, argv, &settings); 3.65 + 3.66 + if (settings.printhelp) { 3.67 + printf( 3.68 + "Usage: %s [OPTION]... [HOST]\n" 3.69 + "Starts/joins a network chess game\n\n" 3.70 + " -h This help page\n" 3.71 + " -p TCP port to use (default: 27015)\n", 3.72 + argv[0]); 3.73 + return EXIT_SUCCESS; 3.74 + } 3.75 + 3.76 + Server server; 3.77 + settings.server = &server; 3.78 + 3.79 + if (is_server(&settings)) { 3.80 + if (net_find(&server, settings.serverhost, settings.port)) { 3.81 + perror("Can't find server"); 3.82 + return cleanup(&settings, EXIT_FAILURE); 3.83 + } 3.84 + 3.85 + if (net_connect(&server)) { 3.86 + perror("Can't connect to server"); 3.87 + return cleanup(&settings, EXIT_FAILURE); 3.88 + } 3.89 + } else { 3.90 + if (net_create(&server, settings.port)) { 3.91 + perror("Server creation failed"); 3.92 + return cleanup(&settings, EXIT_FAILURE); 3.93 + } 3.94 + 3.95 + if (net_listen(&server)) { 3.96 + perror("Listening for client failed"); 3.97 + return cleanup(&settings, EXIT_FAILURE); 3.98 + } 3.99 + } 3.100 + 3.101 + return cleanup(&settings, EXIT_SUCCESS); 3.102 } 3.103
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/network.c Wed Feb 05 14:07:43 2014 +0100 4.3 @@ -0,0 +1,115 @@ 4.4 +/* 4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 4.6 + * 4.7 + * Copyright 2014 Mike Becker. All rights reserved. 4.8 + * 4.9 + * Redistribution and use in source and binary forms, with or without 4.10 + * modification, are permitted provided that the following conditions are met: 4.11 + * 4.12 + * 1. Redistributions of source code must retain the above copyright 4.13 + * notice, this list of conditions and the following disclaimer. 4.14 + * 4.15 + * 2. Redistributions in binary form must reproduce the above copyright 4.16 + * notice, this list of conditions and the following disclaimer in the 4.17 + * documentation and/or other materials provided with the distribution. 4.18 + * 4.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 4.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 4.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 4.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 4.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 4.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 4.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4.29 + * POSSIBILITY OF SUCH DAMAGE. 4.30 + * 4.31 + */ 4.32 + 4.33 +#include <stdlib.h> 4.34 +#include <string.h> 4.35 +#include "network.h" 4.36 + 4.37 +int server_bind(Server *server) { 4.38 + server->fd = socket(server->info->ai_family, 4.39 + server->info->ai_socktype, server->info->ai_protocol); 4.40 + if (server->fd > -1) { 4.41 + int true = 1; 4.42 + setsockopt(server->fd, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(int)); 4.43 + if (bind(server->fd, 4.44 + server->info->ai_addr, server->info->ai_addrlen)) { 4.45 + server->fd = -1; 4.46 + return 1; 4.47 + } else { 4.48 + return 0; 4.49 + } 4.50 + } else { 4.51 + return 1; 4.52 + } 4.53 +} 4.54 + 4.55 +int net_create(Server *server, char* port) { 4.56 + return net_find(server, "localhost", port) || server_bind(server); 4.57 +} 4.58 + 4.59 +int getaddrinfo_intrnl(char *host, char *port, struct addrinfo **info) { 4.60 + struct addrinfo hints; 4.61 + memset(&hints, 0, sizeof(hints)); 4.62 + hints.ai_socktype = SOCK_STREAM; 4.63 + hints.ai_protocol = IPPROTO_TCP; 4.64 + 4.65 + return getaddrinfo(host, port, &hints, info); 4.66 +} 4.67 + 4.68 +int net_find(Server *server, char *host, char* port) { 4.69 + memset(server, 0, sizeof(Server)); 4.70 + server->fd = -1; 4.71 + 4.72 + return getaddrinfo_intrnl(host, port, &(server->info)); 4.73 +} 4.74 + 4.75 +int net_listen(Server *server) { 4.76 + listen(server->fd, 1); 4.77 + Client* client = calloc(1, sizeof(Client)); 4.78 + client->fd = -1; 4.79 + server->client = client; 4.80 + 4.81 + client->fd = accept(server->fd, 4.82 + &(client->address), &(client->address_len)); 4.83 + 4.84 + return client->fd == -1; 4.85 +} 4.86 + 4.87 +int net_connect(Server *server) { 4.88 + struct addrinfo *info; 4.89 + if (getaddrinfo_intrnl("localhost", NULL, &info)) { 4.90 + return 1; 4.91 + } 4.92 + 4.93 + Client* client = calloc(1, sizeof(Client)); 4.94 + client->fd = socket(info->ai_family, info->ai_socktype, info->ai_protocol); 4.95 + server->client = client; 4.96 + 4.97 + freeaddrinfo(info); 4.98 + if (client->fd == -1) { 4.99 + return 1; 4.100 + } 4.101 + 4.102 + return connect(client->fd, server->info->ai_addr, server->info->ai_addrlen); 4.103 +} 4.104 + 4.105 +int net_destroy(Server *server) { 4.106 + if (server->info) { 4.107 + freeaddrinfo(server->info); 4.108 + } 4.109 + if (server->client) { 4.110 + shutdown(server->client->fd, SHUT_RDWR); 4.111 + free(server->client); 4.112 + } 4.113 + if (server->fd > -1) { 4.114 + return shutdown(server->fd, SHUT_RDWR); 4.115 + } 4.116 + 4.117 + return EXIT_SUCCESS; 4.118 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/network.h Wed Feb 05 14:07:43 2014 +0100 5.3 @@ -0,0 +1,65 @@ 5.4 +/* 5.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 5.6 + * 5.7 + * Copyright 2014 Mike Becker. All rights reserved. 5.8 + * 5.9 + * Redistribution and use in source and binary forms, with or without 5.10 + * modification, are permitted provided that the following conditions are met: 5.11 + * 5.12 + * 1. Redistributions of source code must retain the above copyright 5.13 + * notice, this list of conditions and the following disclaimer. 5.14 + * 5.15 + * 2. Redistributions in binary form must reproduce the above copyright 5.16 + * notice, this list of conditions and the following disclaimer in the 5.17 + * documentation and/or other materials provided with the distribution. 5.18 + * 5.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 5.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 5.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 5.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 5.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 5.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 5.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 5.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 5.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 5.29 + * POSSIBILITY OF SUCH DAMAGE. 5.30 + * 5.31 + */ 5.32 + 5.33 +#ifndef TCHESS_NETWORK_H 5.34 +#define TCHESS_NETWORK_H 5.35 + 5.36 +#include <sys/socket.h> 5.37 +#include <netdb.h> 5.38 + 5.39 +#ifdef __cplusplus 5.40 +extern "C" { 5.41 +#endif 5.42 + 5.43 +typedef struct { 5.44 + int fd; 5.45 + struct sockaddr address; 5.46 + socklen_t address_len; 5.47 +} Client; 5.48 + 5.49 +typedef struct { 5.50 + int fd; 5.51 + struct addrinfo* info; 5.52 + Client *client; 5.53 +} Server; 5.54 + 5.55 +int net_create(Server *server, char* port); 5.56 +int net_find(Server *server, char* host, char* port); 5.57 + 5.58 +int net_listen(Server *server); 5.59 +int net_destroy(Server *server); 5.60 +int net_connect(Server *server); 5.61 + 5.62 + 5.63 +#ifdef __cplusplus 5.64 +} 5.65 +#endif 5.66 + 5.67 +#endif /* TCHESS_NETWORK_H */ 5.68 +
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/terminal-chess.h Wed Feb 05 14:07:43 2014 +0100 6.3 @@ -0,0 +1,56 @@ 6.4 +/* 6.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 6.6 + * 6.7 + * Copyright 2014 Mike Becker. All rights reserved. 6.8 + * 6.9 + * Redistribution and use in source and binary forms, with or without 6.10 + * modification, are permitted provided that the following conditions are met: 6.11 + * 6.12 + * 1. Redistributions of source code must retain the above copyright 6.13 + * notice, this list of conditions and the following disclaimer. 6.14 + * 6.15 + * 2. Redistributions in binary form must reproduce the above copyright 6.16 + * notice, this list of conditions and the following disclaimer in the 6.17 + * documentation and/or other materials provided with the distribution. 6.18 + * 6.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 6.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 6.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 6.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 6.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 6.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 6.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 6.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 6.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 6.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 6.29 + * POSSIBILITY OF SUCH DAMAGE. 6.30 + * 6.31 + */ 6.32 + 6.33 +#include <stdlib.h> 6.34 +#include <stdio.h> 6.35 +#include <getopt.h> 6.36 +#include "network.h" 6.37 + 6.38 +#ifndef TERMINAL_CHESS_H 6.39 +#define TERMINAL_CHESS_H 6.40 + 6.41 +#ifdef __cplusplus 6.42 +extern "C" { 6.43 +#endif 6.44 + 6.45 +typedef struct { 6.46 + int printhelp; 6.47 + char* port; 6.48 + char* serverhost; /* NULL, if we are about to start a server */ 6.49 + Server *server; 6.50 +} Settings; 6.51 + 6.52 +#define is_server(settings) ((settings)->serverhost) 6.53 + 6.54 +#ifdef __cplusplus 6.55 +} 6.56 +#endif 6.57 + 6.58 +#endif /* TERMINAL_CHESS_H */ 6.59 +