2 Copyright 2002 Andrew Tridgell <tridge@samba.org>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* glue code that connects the chess server to the external timeseal
25 send a string to the decoder sub-process and return the modified (decoded) string
26 the return value is the decoded timestamp. It will be zero if the decoder didn't
27 recognise the input as valid timeseal data
29 static unsigned decode(unsigned char *s)
35 snprintf(line, 1000, "%s", s); // [HGM] limit length to 1000, to prevent crashing timeseal decoder
37 /* send the encoded data to the decoder process */
38 dprintf(timeseal_globals.decoder_conn, "%s\n", line);
40 if (!fd_gets(line, sizeof(line), timeseal_globals.decoder_conn)) {
41 d_printf("Bad result from timeseal decoder? (t=%u)\n", t);
42 close(timeseal_globals.decoder_conn);
43 timeseal_globals.decoder_conn = -1;
46 line[strlen(line)-1] = 0;
48 p = strchr(line, ':');
50 d_printf("Badly formed timeseal decoder line: [%s]\n", line);
51 close(timeseal_globals.decoder_conn);
52 timeseal_globals.decoder_conn = -1;
63 initialise the timeseal decoder sub-process
65 void timeseal_init(const char *path)
70 /* use a socketpair to get a bi-directional pipe with large buffers */
71 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != 0) {
72 d_printf("Failed to create socket pair!\n");
85 open("/dev/null", O_WRONLY); /* stderr */
86 execl(path, "[timeseal]", NULL);
90 timeseal_globals.decoder_conn = fd[1];
96 parse a command line from a user on *con that may be timeseal encoded.
97 return 1 if the command should be processed further, 0 if the command
100 int timeseal_parse(char *command, struct connection_t *con)
104 /* do we have a decoder sub-process? */
105 if (timeseal_globals.decoder_conn <= 0) return 1;
107 /* are they using timeseal on this connection? */
108 if (!con->timeseal_init && !con->timeseal) return 1;
113 /* this wasn't encoded using timeseal */
114 d_printf("Non-timeseal data [%s]\n", command);
115 con->timeseal_init = 0;
119 if (con->timeseal_init) {
120 con->timeseal_init = 0;
122 d_printf("Connected with timeseal %s\n", command);
123 if (strncmp(command, "TIMESTAMP|", 10) == 0) {
130 /* now check for the special move time tag */
131 if (strcmp(command, "
\ 29") == 0) {
132 int p = player_find(con->fd);
133 struct player *pp = &player_globals.parray[p];
134 if (p >= 0 && pp->game >= 0) {
136 if (game_globals.garray[g].game_state.onMove !=
140 if (pp->side == WHITE) {
141 if (game_globals.garray[g].wTimeWhenReceivedMove == 0) {
142 game_globals.garray[g].wTimeWhenReceivedMove = t;
145 if (game_globals.garray[g].bTimeWhenReceivedMove == 0) {
146 game_globals.garray[g].bTimeWhenReceivedMove = t;
149 if (game_globals.garray[g].flag_pending != FLAG_NONE) {
150 ExecuteFlagCmd(p, net_globals.con[pp->socket]);
153 /* we have processed this special tag - don't process it further */
161 used to call flag on players with timeseal
163 void ExecuteFlagCmd(int p, struct connection_t *con)
165 struct player *pp = &player_globals.parray[p];
168 if (pp->game == -1) {
172 gg = &game_globals.garray[pp->game];
174 if (pp->side == WHITE) {
175 gg->wRealTime -= con->time - gg->wTimeWhenReceivedMove;
176 gg->wTimeWhenReceivedMove = con->time;
177 if (gg->wRealTime < 0) {
178 pcommand(pp->opponent, "flag");
180 } else if (pp->side == BLACK) {
181 gg->bRealTime -= con->time - gg->bTimeWhenReceivedMove;
182 gg->bTimeWhenReceivedMove = con->time;
183 if (gg->bRealTime < 0) {
184 pcommand(pp->opponent, "flag");
188 game_update_time(pp->game);
189 gg->flag_pending = FLAG_NONE;