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 /* send the encoded data to the decoder process */
36 dprintf(timeseal_globals.decoder_conn, "%s\n", s);
38 if (!fd_gets(line, sizeof(line), timeseal_globals.decoder_conn)) {
39 d_printf("Bad result from timeseal decoder? (t=%u)\n", t);
40 close(timeseal_globals.decoder_conn);
41 timeseal_globals.decoder_conn = -1;
44 line[strlen(line)-1] = 0;
46 p = strchr(line, ':');
48 d_printf("Badly formed timeseal decoder line: [%s]\n", line);
49 close(timeseal_globals.decoder_conn);
50 timeseal_globals.decoder_conn = -1;
61 initialise the timeseal decoder sub-process
63 void timeseal_init(const char *path)
68 /* use a socketpair to get a bi-directional pipe with large buffers */
69 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != 0) {
70 d_printf("Failed to create socket pair!\n");
83 open("/dev/null", O_WRONLY); /* stderr */
84 execl(path, "[timeseal]", NULL);
88 timeseal_globals.decoder_conn = fd[1];
94 parse a command line from a user on *con that may be timeseal encoded.
95 return 1 if the command should be processed further, 0 if the command
98 int timeseal_parse(char *command, struct connection_t *con)
102 /* do we have a decoder sub-process? */
103 if (timeseal_globals.decoder_conn <= 0) return 1;
105 /* are they using timeseal on this connection? */
106 if (!con->timeseal_init && !con->timeseal) return 1;
111 /* this wasn't encoded using timeseal */
112 d_printf("Non-timeseal data [%s]\n", command);
113 con->timeseal_init = 0;
117 if (con->timeseal_init) {
118 con->timeseal_init = 0;
120 d_printf("Connected with timeseal %s\n", command);
121 if (strncmp(command, "TIMESTAMP|", 10) == 0) {
128 /* now check for the special move time tag */
129 if (strcmp(command, "
\ 29") == 0) {
130 int p = player_find(con->fd);
131 struct player *pp = &player_globals.parray[p];
132 if (p >= 0 && pp->game >= 0) {
134 if (game_globals.garray[g].game_state.onMove !=
138 if (pp->side == WHITE) {
139 if (game_globals.garray[g].wTimeWhenReceivedMove == 0) {
140 game_globals.garray[g].wTimeWhenReceivedMove = t;
143 if (game_globals.garray[g].bTimeWhenReceivedMove == 0) {
144 game_globals.garray[g].bTimeWhenReceivedMove = t;
147 if (game_globals.garray[g].flag_pending != FLAG_NONE) {
148 ExecuteFlagCmd(p, net_globals.con[pp->socket]);
151 /* we have processed this special tag - don't process it further */
159 used to call flag on players with timeseal
161 void ExecuteFlagCmd(int p, struct connection_t *con)
163 struct player *pp = &player_globals.parray[p];
166 if (pp->game == -1) {
170 gg = &game_globals.garray[pp->game];
172 if (pp->side == WHITE) {
173 gg->wRealTime -= con->time - gg->wTimeWhenReceivedMove;
174 gg->wTimeWhenReceivedMove = con->time;
175 if (gg->wRealTime < 0) {
176 pcommand(pp->opponent, "flag");
178 } else if (pp->side == BLACK) {
179 gg->bRealTime -= con->time - gg->wTimeWhenReceivedMove;
180 gg->bTimeWhenReceivedMove = con->time;
181 if (gg->bRealTime < 0) {
182 pcommand(pp->opponent, "flag");
186 game_update_time(pp->game);
187 gg->flag_pending = FLAG_NONE;