Sun, 29 Mar 2026 15:35:55 +0200
fix wrong way of granting permissions
/* * 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. * */ #define PROGRAM_VERSION "1.0 alpha" #include "game.h" #include "input.h" #include "network.h" #include "colors.h" #include <string.h> #include <time.h> #include <getopt.h> #include <locale.h> #include <sys/stat.h> int get_settings(int argc, char **argv, Settings *settings) { char *valid; unsigned long int time, port; uint8_t timeunit = 60; size_t len; bool port_set = false; for (int opt ; (opt = getopt(argc, argv, "a:bc:Fhp:rsS:t:uUv")) != -1 ;) { switch (opt) { case 'c': settings->continuepgn = optarg; break; case 'b': settings->gameinfo.servercolor = BLACK; break; case 'r': settings->gameinfo.servercolor = rand() & 1 ? WHITE : BLACK; break; case 's': settings->singlemachine = true; break; case 'F': settings->disableflip = true; break; case 'u': if (port_set) { fprintf(stderr, "Cannot use Unix domain sockets " "when a TCP port was specified.\n"); return 1; } settings->usedomainsocket = true; break; case 'U': settings->unicode = false; break; case 't': case 'a': len = strlen(optarg); if (optarg[len-1] == 's') { optarg[len-1] = '\0'; timeunit = 1; } if ((time = strtoul(optarg, &valid, 10))*timeunit > UINT16_MAX || *valid != '\0') { fprintf(stderr, "Specified time is invalid (%s)" "- Maximum: 65535 seconds (1092 minutes)\n", optarg); return 1; } else { settings->gameinfo.timecontrol = 1; if (opt=='t') { settings->gameinfo.time = timeunit * time; } else { settings->gameinfo.addtime = time; } } break; case 'p': if (port_set) { fprintf(stderr, "Cannot use -p twice.\n"); return 1; } if (settings->usedomainsocket) { fprintf(stderr, "Cannot specify TCP port " "when using Unix domain sockets.\n"); return 1; } port = strtol(optarg, &valid, 10); if (port < 1025 || port > 65535 || *valid != '\0') { fprintf(stderr, "Invalid port number (%s) - choose a number between " "1025 and 65535\n", optarg); return 1; } else { settings->port = (short) port; port_set = true; } break; case 'v': printf("terminal-chess : Version %s (Netcode Version %d)\n", PROGRAM_VERSION, NETCODE_VERSION); exit(0); case 'h': case '?': printf( "Usage: terminal-chess [OPTION]... [HOST]\n" "Starts/joins a network chess game\n" "\nGeneral options\n" " -c <PGN file> Continue the specified game\n" " -h This help page\n" " -p TCP port to use (default: 27015)\n" " -u Use Unix domain socket instead of TCP\n" " -U Disables unicode pieces\n" " -v Print version information and exits\n" "\nServer options\n" " -a <time> Specifies the time to add after each move\n" " -b Server plays black pieces (default: white)\n" " -r Distribute color randomly\n" " -t <time> Specifies time limit (default: no limit)\n" "\nHot seat\n" " -s Play a hot seat game (network options are ignored)\n" " -F Do not automatically flip the board in hot seat games\n" "\nNotes\n" "The time unit for -a is seconds and for -t minutes by default. To " "specify\nseconds for the -t option, use the s suffix.\n" "Example: -t 150s\n\n" "Use '-' for PGN files to read PGN data from standard input\n\n" "When playing over Unix domain socket, the HOST denotes the socket path.\n" "When the path doest not exist, a game is created. Otherwise, the program\n" "joins the existing game. When HOST is omitted, /tmp/chess.sock is used.\n" ); exit(0); } } if (optind == argc - 1) { settings->serverhost = argv[optind]; } else if (optind < argc - 1) { fprintf(stderr, "Too many arguments\n"); return 1; } if (settings->continuepgn) { if (settings->serverhost) { fprintf(stderr, "Can't continue a game when joining a server.\n"); return 1; } } if (settings->usedomainsocket) { if (!settings->serverhost) { settings->serverhost = "/tmp/chess.sock"; } struct stat st; if (stat(settings->serverhost, &st) == 0) { if (S_ISSOCK(st.st_mode)) { settings->ishost = false; } else { fprintf(stderr, "%s is not a Unix domain socket.\n", settings->serverhost); return 1; } } else { settings->ishost = true; } } else { settings->ishost = !settings->serverhost; } return 0; } static Settings settings; static void init_settings(void) { memset(&settings, 0, sizeof(settings)); settings.gameinfo.servercolor = WHITE; settings.port = 27015; settings.unicode = !!setlocale(LC_CTYPE, "C.UTF-8"); } static void cleanup() { endwin(); if (settings.usedomainsocket && settings.ishost) { remove(settings.serverhost); } } int main(int argc, char **argv) { srand(time(NULL)); init_settings(); if (get_settings(argc, argv, &settings)) { return 1; } initscr(); halfdelay(1); keypad(stdscr, true); if (has_colors()) { start_color(); init_colorpairs(); bkgd(COLOR_PAIR(COL_APP)); } else { fprintf(stderr, "Non-colored terminals are not supported yet."); endwin(); return EXIT_FAILURE; } atexit(cleanup); int exitcode; if (settings.singlemachine) { game_play_singlemachine(&settings); exitcode = EXIT_SUCCESS; } else { exitcode = settings.ishost ? server_run(&settings) : client_run(&settings); } mvaddstr(getmaxy(stdscr)-1, 0, "Game has ended. Press any key to leave..."); clrtoeol(); refresh(); cbreak(); flushinp(); getch(); return exitcode; }