]> git.pond.sub.org Git - empserver/blob - src/client/servcmd.c
Rewrite much of client's playing phase code:
[empserver] / src / client / servcmd.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See files README, COPYING and CREDITS in the root of the source
23  *  tree for related information and legal notices.  It is expected
24  *  that future projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  servercmd.c: Change the state depending on the command from the server.
29  * 
30  *  Known contributors to this file:
31  *     Dave Pare, 1989
32  *     Steve McClure, 1998
33  *     Ron Koenderink, 2005
34  */
35
36 #include <config.h>
37
38 #include <assert.h>
39 #include <ctype.h>
40 #include <errno.h>
41 #include <fcntl.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include "misc.h"
45 #include "proto.h"
46 #include "secure.h"
47
48 int eight_bit_clean;
49 FILE *auxfp;
50
51 static FILE *redir_fp;
52 static FILE *pipe_fp;
53
54 static void prompt(int, char *, char *);
55 static void doredir(char *p);
56 static void dopipe(char *p);
57 static void doexecute(char *p);
58
59 void
60 servercmd(int code, char *arg, int len)
61 {
62     static int nmin, nbtu;
63     static char the_prompt[1024];
64     static char teles[64];
65
66     switch (code) {
67     case C_PROMPT:
68         if (sscanf(arg, "%d %d", &nmin, &nbtu) != 2) {
69             fprintf(stderr, "prompt: bad server prompt %s\n", arg);
70         }
71         snprintf(the_prompt, sizeof(the_prompt), "[%d:%d] Command : ",
72                  nmin, nbtu);
73         prompt(code, the_prompt, teles);
74         break;
75     case C_FLUSH:
76         snprintf(the_prompt, sizeof(the_prompt), "%.*s", len - 1, arg);
77         prompt(code, the_prompt, teles);
78         break;
79     case C_EXECUTE:
80         doexecute(arg);
81         break;
82     case C_EXIT:
83         printf("Exit: %s", arg);
84         if (auxfp)
85             fprintf(auxfp, "Exit: %s", arg);
86         break;
87     case C_FLASH:
88         printf("\n%s", arg);
89         if (auxfp)
90             fprintf(auxfp, "\n%s", arg);
91         break;
92     case C_INFORM:
93         if (*arg) {
94             snprintf(teles, sizeof(teles), "(%.*s )", len -1, arg);
95             if (!redir_fp && !pipe_fp) {
96                 putchar('\07');
97                 prompt(code, the_prompt, teles);
98             }
99         } else
100             teles[0] = 0;
101         break;
102     case C_PIPE:
103         dopipe(arg);
104         break;
105     case C_REDIR:
106         doredir(arg);
107         break;
108     default:
109         assert(0);
110         break;
111     }
112 }
113
114 static void
115 prompt(int code, char *prompt, char *teles)
116 {
117     char *nl;
118
119     if (code == C_PROMPT) {
120         if (redir_fp) {
121             (void)fclose(redir_fp);
122             redir_fp = NULL;
123         } else if (pipe_fp) {
124             (void)pclose(pipe_fp);
125             pipe_fp = NULL;
126         }
127     }
128     nl = code == C_PROMPT || code == C_INFORM ? "\n" : "";
129     printf("%s%s%s", nl, teles, prompt);
130     fflush(stdout);
131     if (auxfp) {
132         fprintf(auxfp, "%s%s%s", nl, teles, prompt);
133         fflush(auxfp);
134     }
135 }
136
137 static char *
138 fname(char *s)
139 {
140     char *beg, *end;
141
142     for (beg = s; isspace(*(unsigned char *)beg); beg++) ;
143     for (end = beg; !isspace(*(unsigned char *)end); end++) ;
144     *end = 0;
145     return beg;
146 }
147
148 /*
149  * opens redir_fp if successful
150  */
151 static void
152 doredir(char *p)
153 {
154     int mode;
155     int fd;
156
157     if (redir_fp) {
158         (void)fclose(redir_fp);
159         redir_fp = NULL;
160     }
161
162     if (!seen_input(p)) {
163         fprintf(stderr, "WARNING!  Server attempted to redirect %s\n",
164                 p);
165         return;
166     }
167
168     if (*p++ != '>') {
169         fprintf(stderr, "WARNING!  Weird redirection %s", p);
170         return;
171     }
172
173     mode = O_WRONLY | O_CREAT;
174     if (*p == '>') {
175         mode |= O_APPEND;
176         p++;
177     } else if (*p == '!') {
178         mode |= O_TRUNC;
179         p++;
180     } else
181         mode |= O_EXCL;
182
183     p = fname(p);
184     if (*p == 0) {
185         fprintf(stderr, "Redirection lacks a file name\n");
186         return;
187     }
188
189     fd = open(p, mode, 0600);
190     redir_fp = fd < 0 ? NULL : fdopen(fd, "w");
191     if (!redir_fp) {
192         fprintf(stderr, "Can't redirect to %s: %s\n",
193                 p, strerror(errno));
194     }
195 }
196
197 /*
198  * opens "pipe_fp" if successful
199  */
200 static void
201 dopipe(char *p)
202 {
203     if (!seen_input(p)) {
204         fprintf(stderr, "WARNING!  Server attempted to pipe %s", p);
205         return;
206     }
207
208     if (*p++ != '|') {
209         fprintf(stderr, "WARNING!  Weird pipe %s", p);
210         return;
211     }
212
213     for (; *p && isspace(*p); p++) ;
214     if (*p == 0) {
215         fprintf(stderr, "Redirection lacks a command\n");
216         return;
217     }
218
219     if ((pipe_fp = popen(p, "w")) == NULL) {
220         fprintf(stderr, "Can't redirect to pipe %s: %s\n",
221                 p, strerror(errno));
222     }
223 }
224
225 static void
226 doexecute(char *p)
227 {
228     if (!seen_input(p)) {
229         fprintf(stderr,
230                 "WARNING!  Server attempted to read file %s",
231                 p);
232         return;
233     }
234
235     p = fname(p);
236     if (*p == 0) {
237         fprintf(stderr, "Need a file to execute\n");
238         return;
239     }
240
241     if ((input_fd = open(p, O_RDONLY)) < 0) {
242         fprintf(stderr, "Can't open execute file %s: %s\n",
243                 p, strerror(errno));
244         return;
245     }
246 }
247
248 void
249 outch(char c)
250 {
251     if (auxfp)
252         putc(c, auxfp);
253     if (redir_fp)
254         putc(c, redir_fp);
255     else if (pipe_fp)
256         putc(c, pipe_fp);
257     else if (eight_bit_clean) {
258         if (c == 14)
259             putso();
260         else if (c == 15)
261             putse();
262         else
263             putchar(c);
264     } else if (c & 0x80) {
265         putso();
266         putchar(c & 0x7f);
267         putse();
268     } else
269         putchar(c);
270 }