Tue May 26 00:00:56 2009 UTC ()
sprintf -> snprintf


(dholland)
diff -r1.22 -r1.23 src/games/atc/input.c
diff -r1.19 -r1.20 src/games/atc/log.c
diff -r1.19 -r1.20 src/games/atc/update.c

cvs diff -r1.22 -r1.23 src/games/atc/input.c (switch to unified diff)

--- src/games/atc/input.c 2007/12/15 19:44:38 1.22
+++ src/games/atc/input.c 2009/05/26 00:00:56 1.23
@@ -1,677 +1,678 @@ @@ -1,677 +1,678 @@
1/* $NetBSD: input.c,v 1.22 2007/12/15 19:44:38 perry Exp $ */ 1/* $NetBSD: input.c,v 1.23 2009/05/26 00:00:56 dholland Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1990, 1993 4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Ed James. 8 * Ed James.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors 18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software 19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission. 20 * without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 */ 33 */
34 34
35/* 35/*
36 * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved. 36 * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
37 * 37 *
38 * Copy permission is hereby granted provided that this notice is 38 * Copy permission is hereby granted provided that this notice is
39 * retained on all partial or complete copies. 39 * retained on all partial or complete copies.
40 * 40 *
41 * For more info on this and all of my stuff, mail edjames@berkeley.edu. 41 * For more info on this and all of my stuff, mail edjames@berkeley.edu.
42 */ 42 */
43 43
44#include <sys/cdefs.h> 44#include <sys/cdefs.h>
45#ifndef lint 45#ifndef lint
46#if 0 46#if 0
47static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 5/31/93"; 47static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 5/31/93";
48#else 48#else
49__RCSID("$NetBSD: input.c,v 1.22 2007/12/15 19:44:38 perry Exp $"); 49__RCSID("$NetBSD: input.c,v 1.23 2009/05/26 00:00:56 dholland Exp $");
50#endif 50#endif
51#endif /* not lint */ 51#endif /* not lint */
52 52
53#include "include.h" 53#include "include.h"
54#include "pathnames.h" 54#include "pathnames.h"
55 55
56#define MAXRULES 6 56#define MAXRULES 6
57#define MAXDEPTH 15 57#define MAXDEPTH 15
58 58
59#define RETTOKEN '\n' 59#define RETTOKEN '\n'
60#define REDRAWTOKEN '\014' /* CTRL(L) */ 60#define REDRAWTOKEN '\014' /* CTRL(L) */
61#define SHELLTOKEN '!' 61#define SHELLTOKEN '!'
62#define HELPTOKEN '?' 62#define HELPTOKEN '?'
63#define ALPHATOKEN 256 63#define ALPHATOKEN 256
64#define NUMTOKEN 257 64#define NUMTOKEN 257
65 65
66typedef struct { 66typedef struct {
67 int token; 67 int token;
68 int to_state; 68 int to_state;
69 const char *str; 69 const char *str;
70 const char *(*func)(int); 70 const char *(*func)(int);
71} RULE; 71} RULE;
72 72
73typedef struct { 73typedef struct {
74 int num_rules; 74 int num_rules;
75 RULE *rule; 75 RULE *rule;
76} STATE; 76} STATE;
77 77
78typedef struct { 78typedef struct {
79 char str[20]; 79 char str[20];
80 int state; 80 int state;
81 int rule; 81 int rule;
82 int ch; 82 int ch;
83 int pos; 83 int pos;
84} STACK; 84} STACK;
85 85
86#define T_RULE stack[level].rule 86#define T_RULE stack[level].rule
87#define T_STATE stack[level].state 87#define T_STATE stack[level].state
88#define T_STR stack[level].str 88#define T_STR stack[level].str
89#define T_POS stack[level].pos 89#define T_POS stack[level].pos
90#define T_CH stack[level].ch 90#define T_CH stack[level].ch
91 91
92#define NUMELS(a) (sizeof (a) / sizeof (*(a))) 92#define NUMELS(a) (sizeof (a) / sizeof (*(a)))
93 93
94#define NUMSTATES NUMELS(st) 94#define NUMSTATES NUMELS(st)
95 95
96 96
97RULE state0[] = { { ALPHATOKEN, 1, "%c:", setplane}, 97RULE state0[] = { { ALPHATOKEN, 1, "%c:", setplane},
98 { RETTOKEN, -1, "", NULL }, 98 { RETTOKEN, -1, "", NULL },
99 { HELPTOKEN, 12, " [a-z]<ret>", NULL }}, 99 { HELPTOKEN, 12, " [a-z]<ret>", NULL }},
100 state1[] = { { 't', 2, " turn", turn },  100 state1[] = { { 't', 2, " turn", turn },
101 { 'a', 3, " altitude:", NULL },  101 { 'a', 3, " altitude:", NULL },
102 { 'c', 4, " circle", circle }, 102 { 'c', 4, " circle", circle },
103 { 'm', 7, " mark", mark }, 103 { 'm', 7, " mark", mark },
104 { 'u', 7, " unmark", unmark }, 104 { 'u', 7, " unmark", unmark },
105 { 'i', 7, " ignore", ignore }, 105 { 'i', 7, " ignore", ignore },
106 { HELPTOKEN, 12, " tacmui", NULL }}, 106 { HELPTOKEN, 12, " tacmui", NULL }},
107 state2[] = { { 'l', 6, " left", left },  107 state2[] = { { 'l', 6, " left", left },
108 { 'r', 6, " right", right },  108 { 'r', 6, " right", right },
109 { 'L', 4, " left 90", Left }, 109 { 'L', 4, " left 90", Left },
110 { 'R', 4, " right 90", Right },  110 { 'R', 4, " right 90", Right },
111 { 't', 11, " towards", NULL }, 111 { 't', 11, " towards", NULL },
112 { 'w', 4, " to 0", to_dir }, 112 { 'w', 4, " to 0", to_dir },
113 { 'e', 4, " to 45", to_dir }, 113 { 'e', 4, " to 45", to_dir },
114 { 'd', 4, " to 90", to_dir }, 114 { 'd', 4, " to 90", to_dir },
115 { 'c', 4, " to 135", to_dir }, 115 { 'c', 4, " to 135", to_dir },
116 { 'x', 4, " to 180", to_dir }, 116 { 'x', 4, " to 180", to_dir },
117 { 'z', 4, " to 225", to_dir }, 117 { 'z', 4, " to 225", to_dir },
118 { 'a', 4, " to 270", to_dir }, 118 { 'a', 4, " to 270", to_dir },
119 { 'q', 4, " to 315", to_dir }, 119 { 'q', 4, " to 315", to_dir },
120 { HELPTOKEN, 12, " lrLRt<dir>", NULL }}, 120 { HELPTOKEN, 12, " lrLRt<dir>", NULL }},
121 state3[] = { { '+', 10, " climb", climb },  121 state3[] = { { '+', 10, " climb", climb },
122 { 'c', 10, " climb", climb },  122 { 'c', 10, " climb", climb },
123 { '-', 10, " descend", descend },  123 { '-', 10, " descend", descend },
124 { 'd', 10, " descend", descend },  124 { 'd', 10, " descend", descend },
125 { NUMTOKEN, 7, " %c000 feet", setalt }, 125 { NUMTOKEN, 7, " %c000 feet", setalt },
126 { HELPTOKEN, 12, " +-cd[0-9]", NULL }}, 126 { HELPTOKEN, 12, " +-cd[0-9]", NULL }},
127 state4[] = { { '@', 9, " at", NULL },  127 state4[] = { { '@', 9, " at", NULL },
128 { 'a', 9, " at", NULL },  128 { 'a', 9, " at", NULL },
129 { RETTOKEN, -1, "", NULL }, 129 { RETTOKEN, -1, "", NULL },
130 { HELPTOKEN, 12, " @a<ret>", NULL }}, 130 { HELPTOKEN, 12, " @a<ret>", NULL }},
131 state5[] = { { NUMTOKEN, 7, "%c", delayb }, 131 state5[] = { { NUMTOKEN, 7, "%c", delayb },
132 { HELPTOKEN, 12, " [0-9]", NULL }}, 132 { HELPTOKEN, 12, " [0-9]", NULL }},
133 state6[] = { { '@', 9, " at", NULL }, 133 state6[] = { { '@', 9, " at", NULL },
134 { 'a', 9, " at", NULL }, 134 { 'a', 9, " at", NULL },
135 { 'w', 4, " 0", rel_dir }, 135 { 'w', 4, " 0", rel_dir },
136 { 'e', 4, " 45", rel_dir }, 136 { 'e', 4, " 45", rel_dir },
137 { 'd', 4, " 90", rel_dir }, 137 { 'd', 4, " 90", rel_dir },
138 { 'c', 4, " 135", rel_dir }, 138 { 'c', 4, " 135", rel_dir },
139 { 'x', 4, " 180", rel_dir }, 139 { 'x', 4, " 180", rel_dir },
140 { 'z', 4, " 225", rel_dir }, 140 { 'z', 4, " 225", rel_dir },
141 { 'a', 4, " 270", rel_dir }, 141 { 'a', 4, " 270", rel_dir },
142 { 'q', 4, " 315", rel_dir }, 142 { 'q', 4, " 315", rel_dir },
143 { RETTOKEN, -1, "", NULL },  143 { RETTOKEN, -1, "", NULL },
144 { HELPTOKEN, 12, " @a<dir><ret>",NULL }}, 144 { HELPTOKEN, 12, " @a<dir><ret>",NULL }},
145 state7[] = { { RETTOKEN, -1, "", NULL }, 145 state7[] = { { RETTOKEN, -1, "", NULL },
146 { HELPTOKEN, 12, " <ret>", NULL }}, 146 { HELPTOKEN, 12, " <ret>", NULL }},
147 state8[] = { { NUMTOKEN, 4, "%c", benum }, 147 state8[] = { { NUMTOKEN, 4, "%c", benum },
148 { HELPTOKEN, 12, " [0-9]", NULL }}, 148 { HELPTOKEN, 12, " [0-9]", NULL }},
149 state9[] = { { 'b', 5, " beacon #", NULL }, 149 state9[] = { { 'b', 5, " beacon #", NULL },
150 { '*', 5, " beacon #", NULL }, 150 { '*', 5, " beacon #", NULL },
151 { HELPTOKEN, 12, " b*", NULL }}, 151 { HELPTOKEN, 12, " b*", NULL }},
152 state10[] = { { NUMTOKEN, 7, " %c000 ft", setrelalt}, 152 state10[] = { { NUMTOKEN, 7, " %c000 ft", setrelalt},
153 { HELPTOKEN, 12, " [0-9]", NULL }}, 153 { HELPTOKEN, 12, " [0-9]", NULL }},
154 state11[] = { { 'b', 8, " beacon #", beacon },  154 state11[] = { { 'b', 8, " beacon #", beacon },
155 { '*', 8, " beacon #", beacon }, 155 { '*', 8, " beacon #", beacon },
156 { 'e', 8, " exit #", ex_it }, 156 { 'e', 8, " exit #", ex_it },
157 { 'a', 8, " airport #", airport }, 157 { 'a', 8, " airport #", airport },
158 { HELPTOKEN, 12, " b*ea", NULL }}, 158 { HELPTOKEN, 12, " b*ea", NULL }},
159 state12[] = { { -1, -1, "", NULL }}; 159 state12[] = { { -1, -1, "", NULL }};
160 160
161#define DEF_STATE(s) { NUMELS(s), (s) } 161#define DEF_STATE(s) { NUMELS(s), (s) }
162 162
163STATE st[] = { 163STATE st[] = {
164 DEF_STATE(state0), DEF_STATE(state1), DEF_STATE(state2), 164 DEF_STATE(state0), DEF_STATE(state1), DEF_STATE(state2),
165 DEF_STATE(state3), DEF_STATE(state4), DEF_STATE(state5), 165 DEF_STATE(state3), DEF_STATE(state4), DEF_STATE(state5),
166 DEF_STATE(state6), DEF_STATE(state7), DEF_STATE(state8), 166 DEF_STATE(state6), DEF_STATE(state7), DEF_STATE(state8),
167 DEF_STATE(state9), DEF_STATE(state10), DEF_STATE(state11), 167 DEF_STATE(state9), DEF_STATE(state10), DEF_STATE(state11),
168 DEF_STATE(state12) 168 DEF_STATE(state12)
169}; 169};
170 170
171PLANE p; 171PLANE p;
172STACK stack[MAXDEPTH]; 172STACK stack[MAXDEPTH];
173int level; 173int level;
174int tval; 174int tval;
175int dest_type, dest_no, dir; 175int dest_type, dest_no, dir;
176 176
177int 177int
178pop(void) 178pop(void)
179{ 179{
180 if (level == 0) 180 if (level == 0)
181 return (-1); 181 return (-1);
182 level--; 182 level--;
183 183
184 ioclrtoeol(T_POS); 184 ioclrtoeol(T_POS);
185 185
186 (void)strcpy(T_STR, ""); 186 (void)strcpy(T_STR, "");
187 T_RULE = -1; 187 T_RULE = -1;
188 T_CH = -1; 188 T_CH = -1;
189 return (0); 189 return (0);
190} 190}
191 191
192void 192void
193rezero(void) 193rezero(void)
194{ 194{
195 iomove(0); 195 iomove(0);
196 196
197 level = 0; 197 level = 0;
198 T_STATE = 0; 198 T_STATE = 0;
199 T_RULE = -1; 199 T_RULE = -1;
200 T_CH = -1; 200 T_CH = -1;
201 T_POS = 0; 201 T_POS = 0;
202 (void)strcpy(T_STR, ""); 202 (void)strcpy(T_STR, "");
203} 203}
204 204
205void 205void
206push(int ruleno, int ch) 206push(int ruleno, int ch)
207{ 207{
208 int newstate, newpos; 208 int newstate, newpos;
209 209
210 assert(level < (MAXDEPTH - 1)); 210 assert(level < (MAXDEPTH - 1));
211 (void)sprintf(T_STR, st[T_STATE].rule[ruleno].str, tval); 211 (void)snprintf(T_STR, sizeof(T_STR),
 212 st[T_STATE].rule[ruleno].str, tval);
212 T_RULE = ruleno; 213 T_RULE = ruleno;
213 T_CH = ch; 214 T_CH = ch;
214 newstate = st[T_STATE].rule[ruleno].to_state; 215 newstate = st[T_STATE].rule[ruleno].to_state;
215 newpos = T_POS + strlen(T_STR); 216 newpos = T_POS + strlen(T_STR);
216 217
217 ioaddstr(T_POS, T_STR); 218 ioaddstr(T_POS, T_STR);
218 219
219 if (level == 0) 220 if (level == 0)
220 ioclrtobot(); 221 ioclrtobot();
221 level++; 222 level++;
222 T_STATE = newstate; 223 T_STATE = newstate;
223 T_POS = newpos; 224 T_POS = newpos;
224 T_RULE = -1; 225 T_RULE = -1;
225 (void)strcpy(T_STR, ""); 226 (void)strcpy(T_STR, "");
226} 227}
227 228
228int 229int
229getcommand(void) 230getcommand(void)
230{ 231{
231 int c, i, done; 232 int c, i, done;
232 const char *s, *(*func)(int); 233 const char *s, *(*func)(int);
233 PLANE *pp; 234 PLANE *pp;
234 235
235 rezero(); 236 rezero();
236 237
237 do { 238 do {
238 c = gettoken(); 239 c = gettoken();
239 if (c == tty_new.c_cc[VERASE]) { 240 if (c == tty_new.c_cc[VERASE]) {
240 if (pop() < 0) 241 if (pop() < 0)
241 noise(); 242 noise();
242 } else if (c == tty_new.c_cc[VKILL]) { 243 } else if (c == tty_new.c_cc[VKILL]) {
243 while (pop() >= 0) 244 while (pop() >= 0)
244 ; 245 ;
245 } else { 246 } else {
246 done = 0; 247 done = 0;
247 for (i = 0; i < st[T_STATE].num_rules; i++) { 248 for (i = 0; i < st[T_STATE].num_rules; i++) {
248 if (st[T_STATE].rule[i].token == c || 249 if (st[T_STATE].rule[i].token == c ||
249 st[T_STATE].rule[i].token == tval) { 250 st[T_STATE].rule[i].token == tval) {
250 push(i, (c >= ALPHATOKEN) ? tval : c); 251 push(i, (c >= ALPHATOKEN) ? tval : c);
251 done = 1; 252 done = 1;
252 break; 253 break;
253 } 254 }
254 } 255 }
255 if (!done) 256 if (!done)
256 noise(); 257 noise();
257 } 258 }
258 } while (T_STATE != -1); 259 } while (T_STATE != -1);
259 260
260 if (level == 1) 261 if (level == 1)
261 return (1); /* forced update */ 262 return (1); /* forced update */
262 263
263 dest_type = T_NODEST; 264 dest_type = T_NODEST;
264  265
265 for (i = 0; i < level; i++) { 266 for (i = 0; i < level; i++) {
266 func = st[stack[i].state].rule[stack[i].rule].func; 267 func = st[stack[i].state].rule[stack[i].rule].func;
267 if (func != NULL) 268 if (func != NULL)
268 if ((s = (*func)(stack[i].ch)) != NULL) { 269 if ((s = (*func)(stack[i].ch)) != NULL) {
269 ioerror(stack[i].pos,  270 ioerror(stack[i].pos,
270 (int)strlen(stack[i].str), s); 271 (int)strlen(stack[i].str), s);
271 return (-1); 272 return (-1);
272 } 273 }
273 } 274 }
274 275
275 pp = findplane(p.plane_no); 276 pp = findplane(p.plane_no);
276 if (pp->new_altitude != p.new_altitude) 277 if (pp->new_altitude != p.new_altitude)
277 pp->new_altitude = p.new_altitude; 278 pp->new_altitude = p.new_altitude;
278 else if (pp->status != p.status) 279 else if (pp->status != p.status)
279 pp->status = p.status; 280 pp->status = p.status;
280 else { 281 else {
281 pp->new_dir = p.new_dir; 282 pp->new_dir = p.new_dir;
282 pp->delayd = p.delayd; 283 pp->delayd = p.delayd;
283 pp->delayd_no = p.delayd_no; 284 pp->delayd_no = p.delayd_no;
284 } 285 }
285 return (0); 286 return (0);
286} 287}
287 288
288void 289void
289noise(void) 290noise(void)
290{ 291{
291 (void)putchar('\07'); 292 (void)putchar('\07');
292 (void)fflush(stdout); 293 (void)fflush(stdout);
293} 294}
294 295
295int 296int
296gettoken(void) 297gettoken(void)
297{ 298{
298 while ((tval = getAChar()) == REDRAWTOKEN || tval == SHELLTOKEN) 299 while ((tval = getAChar()) == REDRAWTOKEN || tval == SHELLTOKEN)
299 { 300 {
300 if (tval == SHELLTOKEN) 301 if (tval == SHELLTOKEN)
301 { 302 {
302#ifdef BSD 303#ifdef BSD
303 struct itimerval itv; 304 struct itimerval itv;
304 itv.it_value.tv_sec = 0; 305 itv.it_value.tv_sec = 0;
305 itv.it_value.tv_usec = 0; 306 itv.it_value.tv_usec = 0;
306 (void)setitimer(ITIMER_REAL, &itv, NULL); 307 (void)setitimer(ITIMER_REAL, &itv, NULL);
307#endif 308#endif
308#ifdef SYSV 309#ifdef SYSV
309 int aval; 310 int aval;
310 aval = alarm(0); 311 aval = alarm(0);
311#endif 312#endif
312 if (fork() == 0) /* child */ 313 if (fork() == 0) /* child */
313 { 314 {
314 char *shell, *base; 315 char *shell, *base;
315 316
316 done_screen(); 317 done_screen();
317 318
318 /* run user's favorite shell */ 319 /* run user's favorite shell */
319 if ((shell = getenv("SHELL")) != NULL) 320 if ((shell = getenv("SHELL")) != NULL)
320 { 321 {
321 base = strrchr(shell, '/'); 322 base = strrchr(shell, '/');
322 if (base == NULL) 323 if (base == NULL)
323 base = shell; 324 base = shell;
324 else 325 else
325 base++; 326 base++;
326 (void)execl(shell, base, (char *) 0); 327 (void)execl(shell, base, (char *) 0);
327 } 328 }
328 else 329 else
329 (void)execl(_PATH_BSHELL, "sh",  330 (void)execl(_PATH_BSHELL, "sh",
330 (char *) 0); 331 (char *) 0);
331 332
332 exit(0); /* oops */ 333 exit(0); /* oops */
333 } 334 }
334 335
335 (void)wait(0); 336 (void)wait(0);
336 (void)tcsetattr(fileno(stdin), TCSADRAIN, &tty_new); 337 (void)tcsetattr(fileno(stdin), TCSADRAIN, &tty_new);
337#ifdef BSD 338#ifdef BSD
338 itv.it_value.tv_sec = 0; 339 itv.it_value.tv_sec = 0;
339 itv.it_value.tv_usec = 1; 340 itv.it_value.tv_usec = 1;
340 itv.it_interval.tv_sec = sp->update_secs; 341 itv.it_interval.tv_sec = sp->update_secs;
341 itv.it_interval.tv_usec = 0; 342 itv.it_interval.tv_usec = 0;
342 (void)setitimer(ITIMER_REAL, &itv, NULL); 343 (void)setitimer(ITIMER_REAL, &itv, NULL);
343#endif 344#endif
344#ifdef SYSV 345#ifdef SYSV
345 alarm(aval); 346 alarm(aval);
346#endif 347#endif
347 } 348 }
348 (void)redraw(); 349 (void)redraw();
349 } 350 }
350 351
351 if (isdigit(tval)) 352 if (isdigit(tval))
352 return (NUMTOKEN); 353 return (NUMTOKEN);
353 else if (isalpha(tval)) 354 else if (isalpha(tval))
354 return (ALPHATOKEN); 355 return (ALPHATOKEN);
355 else 356 else
356 return (tval); 357 return (tval);
357} 358}
358 359
359const char * 360const char *
360setplane(int c) 361setplane(int c)
361{ 362{
362 PLANE *pp; 363 PLANE *pp;
363 364
364 pp = findplane(number(c)); 365 pp = findplane(number(c));
365 if (pp == NULL) 366 if (pp == NULL)
366 return ("Unknown Plane"); 367 return ("Unknown Plane");
367 (void)memcpy(&p, pp, sizeof (p)); 368 (void)memcpy(&p, pp, sizeof (p));
368 p.delayd = 0; 369 p.delayd = 0;
369 return (NULL); 370 return (NULL);
370} 371}
371 372
372/* ARGSUSED */ 373/* ARGSUSED */
373const char * 374const char *
374turn(int c __unused) 375turn(int c __unused)
375{ 376{
376 if (p.altitude == 0) 377 if (p.altitude == 0)
377 return ("Planes at airports may not change direction"); 378 return ("Planes at airports may not change direction");
378 return (NULL); 379 return (NULL);
379} 380}
380 381
381/* ARGSUSED */ 382/* ARGSUSED */
382const char * 383const char *
383circle(int c __unused) 384circle(int c __unused)
384{ 385{
385 if (p.altitude == 0) 386 if (p.altitude == 0)
386 return ("Planes cannot circle on the ground"); 387 return ("Planes cannot circle on the ground");
387 p.new_dir = MAXDIR; 388 p.new_dir = MAXDIR;
388 return (NULL); 389 return (NULL);
389} 390}
390 391
391/* ARGSUSED */ 392/* ARGSUSED */
392const char * 393const char *
393left(int c __unused) 394left(int c __unused)
394{ 395{
395 dir = D_LEFT; 396 dir = D_LEFT;
396 p.new_dir = p.dir - 1; 397 p.new_dir = p.dir - 1;
397 if (p.new_dir < 0) 398 if (p.new_dir < 0)
398 p.new_dir += MAXDIR; 399 p.new_dir += MAXDIR;
399 return (NULL); 400 return (NULL);
400} 401}
401 402
402/* ARGSUSED */ 403/* ARGSUSED */
403const char * 404const char *
404right(int c __unused) 405right(int c __unused)
405{ 406{
406 dir = D_RIGHT; 407 dir = D_RIGHT;
407 p.new_dir = p.dir + 1; 408 p.new_dir = p.dir + 1;
408 if (p.new_dir >= MAXDIR) 409 if (p.new_dir >= MAXDIR)
409 p.new_dir -= MAXDIR; 410 p.new_dir -= MAXDIR;
410 return (NULL); 411 return (NULL);
411} 412}
412 413
413/* ARGSUSED */ 414/* ARGSUSED */
414const char * 415const char *
415Left(int c __unused) 416Left(int c __unused)
416{ 417{
417 p.new_dir = p.dir - 2; 418 p.new_dir = p.dir - 2;
418 if (p.new_dir < 0) 419 if (p.new_dir < 0)
419 p.new_dir += MAXDIR; 420 p.new_dir += MAXDIR;
420 return (NULL); 421 return (NULL);
421} 422}
422 423
423/* ARGSUSED */ 424/* ARGSUSED */
424const char * 425const char *
425Right(int c __unused) 426Right(int c __unused)
426{ 427{
427 p.new_dir = p.dir + 2; 428 p.new_dir = p.dir + 2;
428 if (p.new_dir >= MAXDIR) 429 if (p.new_dir >= MAXDIR)
429 p.new_dir -= MAXDIR; 430 p.new_dir -= MAXDIR;
430 return (NULL); 431 return (NULL);
431} 432}
432 433
433const char * 434const char *
434delayb(int c) 435delayb(int c)
435{ 436{
436 int xdiff, ydiff; 437 int xdiff, ydiff;
437 438
438 c -= '0'; 439 c -= '0';
439 440
440 if (c >= sp->num_beacons) 441 if (c >= sp->num_beacons)
441 return ("Unknown beacon"); 442 return ("Unknown beacon");
442 xdiff = sp->beacon[(int)c].x - p.xpos; 443 xdiff = sp->beacon[(int)c].x - p.xpos;
443 xdiff = SGN(xdiff); 444 xdiff = SGN(xdiff);
444 ydiff = sp->beacon[(int)c].y - p.ypos; 445 ydiff = sp->beacon[(int)c].y - p.ypos;
445 ydiff = SGN(ydiff); 446 ydiff = SGN(ydiff);
446 if (xdiff != displacement[p.dir].dx || ydiff != displacement[p.dir].dy) 447 if (xdiff != displacement[p.dir].dx || ydiff != displacement[p.dir].dy)
447 return ("Beacon is not in flight path"); 448 return ("Beacon is not in flight path");
448 p.delayd = 1; 449 p.delayd = 1;
449 p.delayd_no = c; 450 p.delayd_no = c;
450 451
451 if (dest_type != T_NODEST) { 452 if (dest_type != T_NODEST) {
452 switch (dest_type) { 453 switch (dest_type) {
453 case T_BEACON: 454 case T_BEACON:
454 xdiff = sp->beacon[dest_no].x - sp->beacon[(int)c].x; 455 xdiff = sp->beacon[dest_no].x - sp->beacon[(int)c].x;
455 ydiff = sp->beacon[dest_no].y - sp->beacon[(int)c].y; 456 ydiff = sp->beacon[dest_no].y - sp->beacon[(int)c].y;
456 break; 457 break;
457 case T_EXIT: 458 case T_EXIT:
458 xdiff = sp->exit[dest_no].x - sp->beacon[(int)c].x; 459 xdiff = sp->exit[dest_no].x - sp->beacon[(int)c].x;
459 ydiff = sp->exit[dest_no].y - sp->beacon[(int)c].y; 460 ydiff = sp->exit[dest_no].y - sp->beacon[(int)c].y;
460 break; 461 break;
461 case T_AIRPORT: 462 case T_AIRPORT:
462 xdiff = sp->airport[dest_no].x - sp->beacon[(int)c].x; 463 xdiff = sp->airport[dest_no].x - sp->beacon[(int)c].x;
463 ydiff = sp->airport[dest_no].y - sp->beacon[(int)c].y; 464 ydiff = sp->airport[dest_no].y - sp->beacon[(int)c].y;
464 break; 465 break;
465 default: 466 default:
466 return ("Bad case in delayb! Get help!"); 467 return ("Bad case in delayb! Get help!");
467 } 468 }
468 if (xdiff == 0 && ydiff == 0) 469 if (xdiff == 0 && ydiff == 0)
469 return ("Would already be there"); 470 return ("Would already be there");
470 p.new_dir = DIR_FROM_DXDY(xdiff, ydiff); 471 p.new_dir = DIR_FROM_DXDY(xdiff, ydiff);
471 if (p.new_dir == p.dir) 472 if (p.new_dir == p.dir)
472 return ("Already going in that direction"); 473 return ("Already going in that direction");
473 } 474 }
474 return (NULL); 475 return (NULL);
475} 476}
476 477
477/* ARGSUSED */ 478/* ARGSUSED */
478const char * 479const char *
479beacon(int c __unused) 480beacon(int c __unused)
480{ 481{
481 dest_type = T_BEACON; 482 dest_type = T_BEACON;
482 return (NULL); 483 return (NULL);
483} 484}
484 485
485/* ARGSUSED */ 486/* ARGSUSED */
486const char * 487const char *
487ex_it(int c __unused) 488ex_it(int c __unused)
488{ 489{
489 dest_type = T_EXIT; 490 dest_type = T_EXIT;
490 return (NULL); 491 return (NULL);
491} 492}
492 493
493/* ARGSUSED */ 494/* ARGSUSED */
494const char * 495const char *
495airport(int c __unused) 496airport(int c __unused)
496{ 497{
497 dest_type = T_AIRPORT; 498 dest_type = T_AIRPORT;
498 return (NULL); 499 return (NULL);
499} 500}
500 501
501/* ARGSUSED */ 502/* ARGSUSED */
502const char * 503const char *
503climb(int c __unused) 504climb(int c __unused)
504{ 505{
505 dir = D_UP; 506 dir = D_UP;
506 return (NULL); 507 return (NULL);
507} 508}
508 509
509/* ARGSUSED */ 510/* ARGSUSED */
510const char * 511const char *
511descend(int c __unused) 512descend(int c __unused)
512{ 513{
513 dir = D_DOWN; 514 dir = D_DOWN;
514 return (NULL); 515 return (NULL);
515} 516}
516 517
517const char * 518const char *
518setalt(int c) 519setalt(int c)
519{ 520{
520 int newalt = c - '0'; 521 int newalt = c - '0';
521 if ((p.altitude == newalt) && (p.new_altitude == p.altitude)) 522 if ((p.altitude == newalt) && (p.new_altitude == p.altitude))
522 return ("Already at that altitude"); 523 return ("Already at that altitude");
523 if (p.new_altitude == newalt) { 524 if (p.new_altitude == newalt) {
524 return ("Already going to that altitude"); 525 return ("Already going to that altitude");
525 } 526 }
526 p.new_altitude = newalt; 527 p.new_altitude = newalt;
527 return (NULL); 528 return (NULL);
528} 529}
529 530
530const char * 531const char *
531setrelalt(int c) 532setrelalt(int c)
532{ 533{
533 int newalt; 534 int newalt;
534 535
535 if (c == 0) 536 if (c == 0)
536 return ("altitude not changed"); 537 return ("altitude not changed");
537 538
538 switch (dir) { 539 switch (dir) {
539 case D_UP: 540 case D_UP:
540 newalt = p.altitude + c - '0'; 541 newalt = p.altitude + c - '0';
541 break; 542 break;
542 case D_DOWN: 543 case D_DOWN:
543 newalt = p.altitude - (c - '0'); 544 newalt = p.altitude - (c - '0');
544 break; 545 break;
545 default: 546 default:
546 return ("Unknown case in setrelalt! Get help!"); 547 return ("Unknown case in setrelalt! Get help!");
547 } 548 }
548 549
549 if (p.new_altitude == newalt) 550 if (p.new_altitude == newalt)
550 return ("Already going to that altitude"); 551 return ("Already going to that altitude");
551 552
552 p.new_altitude = newalt; 553 p.new_altitude = newalt;
553 554
554 if (p.new_altitude < 0) 555 if (p.new_altitude < 0)
555 return ("Altitude would be too low"); 556 return ("Altitude would be too low");
556 else if (p.new_altitude > 9) 557 else if (p.new_altitude > 9)
557 return ("Altitude would be too high"); 558 return ("Altitude would be too high");
558 return (NULL); 559 return (NULL);
559} 560}
560 561
561const char * 562const char *
562benum(int c) 563benum(int c)
563{ 564{
564 dest_no = c -= '0'; 565 dest_no = c -= '0';
565 566
566 switch (dest_type) { 567 switch (dest_type) {
567 case T_BEACON: 568 case T_BEACON:
568 if (c >= sp->num_beacons) 569 if (c >= sp->num_beacons)
569 return ("Unknown beacon"); 570 return ("Unknown beacon");
570 p.new_dir = DIR_FROM_DXDY(sp->beacon[(int)c].x - p.xpos, 571 p.new_dir = DIR_FROM_DXDY(sp->beacon[(int)c].x - p.xpos,
571 sp->beacon[(int)c].y - p.ypos); 572 sp->beacon[(int)c].y - p.ypos);
572 break; 573 break;
573 case T_EXIT: 574 case T_EXIT:
574 if (c >= sp->num_exits) 575 if (c >= sp->num_exits)
575 return ("Unknown exit"); 576 return ("Unknown exit");
576 p.new_dir = DIR_FROM_DXDY(sp->exit[(int)c].x - p.xpos, 577 p.new_dir = DIR_FROM_DXDY(sp->exit[(int)c].x - p.xpos,
577 sp->exit[(int)c].y - p.ypos); 578 sp->exit[(int)c].y - p.ypos);
578 break; 579 break;
579 case T_AIRPORT: 580 case T_AIRPORT:
580 if (c >= sp->num_airports) 581 if (c >= sp->num_airports)
581 return ("Unknown airport"); 582 return ("Unknown airport");
582 p.new_dir = DIR_FROM_DXDY(sp->airport[(int)c].x - p.xpos, 583 p.new_dir = DIR_FROM_DXDY(sp->airport[(int)c].x - p.xpos,
583 sp->airport[(int)c].y - p.ypos); 584 sp->airport[(int)c].y - p.ypos);
584 break; 585 break;
585 default: 586 default:
586 return ("Unknown case in benum! Get help!"); 587 return ("Unknown case in benum! Get help!");
587 } 588 }
588 return (NULL); 589 return (NULL);
589} 590}
590 591
591const char * 592const char *
592to_dir(int c) 593to_dir(int c)
593{ 594{
594 p.new_dir = dir_no(c); 595 p.new_dir = dir_no(c);
595 return (NULL); 596 return (NULL);
596} 597}
597 598
598const char * 599const char *
599rel_dir(int c) 600rel_dir(int c)
600{ 601{
601 int angle; 602 int angle;
602 603
603 angle = dir_no(c); 604 angle = dir_no(c);
604 switch (dir) { 605 switch (dir) {
605 case D_LEFT: 606 case D_LEFT:
606 p.new_dir = p.dir - angle; 607 p.new_dir = p.dir - angle;
607 if (p.new_dir < 0) 608 if (p.new_dir < 0)
608 p.new_dir += MAXDIR; 609 p.new_dir += MAXDIR;
609 break; 610 break;
610 case D_RIGHT: 611 case D_RIGHT:
611 p.new_dir = p.dir + angle; 612 p.new_dir = p.dir + angle;
612 if (p.new_dir >= MAXDIR) 613 if (p.new_dir >= MAXDIR)
613 p.new_dir -= MAXDIR; 614 p.new_dir -= MAXDIR;
614 break; 615 break;
615 default: 616 default:
616 return ("Bizarre direction in rel_dir! Get help!"); 617 return ("Bizarre direction in rel_dir! Get help!");
617 } 618 }
618 return (NULL); 619 return (NULL);
619} 620}
620 621
621/* ARGSUSED */ 622/* ARGSUSED */
622const char * 623const char *
623mark(int c __unused) 624mark(int c __unused)
624{ 625{
625 if (p.altitude == 0) 626 if (p.altitude == 0)
626 return ("Cannot mark planes on the ground"); 627 return ("Cannot mark planes on the ground");
627 if (p.status == S_MARKED) 628 if (p.status == S_MARKED)
628 return ("Already marked"); 629 return ("Already marked");
629 p.status = S_MARKED; 630 p.status = S_MARKED;
630 return (NULL); 631 return (NULL);
631} 632}
632 633
633/* ARGSUSED */ 634/* ARGSUSED */
634const char * 635const char *
635unmark(int c __unused) 636unmark(int c __unused)
636{ 637{
637 if (p.altitude == 0) 638 if (p.altitude == 0)
638 return ("Cannot unmark planes on the ground"); 639 return ("Cannot unmark planes on the ground");
639 if (p.status == S_UNMARKED) 640 if (p.status == S_UNMARKED)
640 return ("Already unmarked"); 641 return ("Already unmarked");
641 p.status = S_UNMARKED; 642 p.status = S_UNMARKED;
642 return (NULL); 643 return (NULL);
643} 644}
644 645
645/* ARGSUSED */ 646/* ARGSUSED */
646const char * 647const char *
647ignore(int c __unused) 648ignore(int c __unused)
648{ 649{
649 if (p.altitude == 0) 650 if (p.altitude == 0)
650 return ("Cannot ignore planes on the ground"); 651 return ("Cannot ignore planes on the ground");
651 if (p.status == S_IGNORED) 652 if (p.status == S_IGNORED)
652 return ("Already ignored"); 653 return ("Already ignored");
653 p.status = S_IGNORED; 654 p.status = S_IGNORED;
654 return (NULL); 655 return (NULL);
655} 656}
656 657
657int 658int
658dir_no(int ch) 659dir_no(int ch)
659{ 660{
660 int dirno; 661 int dirno;
661 662
662 dirno = -1; 663 dirno = -1;
663 switch (ch) { 664 switch (ch) {
664 case 'w': dirno = 0; break; 665 case 'w': dirno = 0; break;
665 case 'e': dirno = 1; break; 666 case 'e': dirno = 1; break;
666 case 'd': dirno = 2; break; 667 case 'd': dirno = 2; break;
667 case 'c': dirno = 3; break; 668 case 'c': dirno = 3; break;
668 case 'x': dirno = 4; break; 669 case 'x': dirno = 4; break;
669 case 'z': dirno = 5; break; 670 case 'z': dirno = 5; break;
670 case 'a': dirno = 6; break; 671 case 'a': dirno = 6; break;
671 case 'q': dirno = 7; break; 672 case 'q': dirno = 7; break;
672 default: 673 default:
673 (void)fprintf(stderr, "bad character in dir_no\n"); 674 (void)fprintf(stderr, "bad character in dir_no\n");
674 break; 675 break;
675 } 676 }
676 return (dirno); 677 return (dirno);
677} 678}

cvs diff -r1.19 -r1.20 src/games/atc/log.c (switch to unified diff)

--- src/games/atc/log.c 2007/12/15 19:44:38 1.19
+++ src/games/atc/log.c 2009/05/26 00:00:56 1.20
@@ -1,300 +1,301 @@ @@ -1,300 +1,301 @@
1/* $NetBSD: log.c,v 1.19 2007/12/15 19:44:38 perry Exp $ */ 1/* $NetBSD: log.c,v 1.20 2009/05/26 00:00:56 dholland Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1990, 1993 4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Ed James. 8 * Ed James.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors 18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software 19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission. 20 * without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 */ 33 */
34 34
35/* 35/*
36 * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved. 36 * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
37 * 37 *
38 * Copy permission is hereby granted provided that this notice is 38 * Copy permission is hereby granted provided that this notice is
39 * retained on all partial or complete copies. 39 * retained on all partial or complete copies.
40 * 40 *
41 * For more info on this and all of my stuff, mail edjames@berkeley.edu. 41 * For more info on this and all of my stuff, mail edjames@berkeley.edu.
42 */ 42 */
43 43
44#include <sys/cdefs.h> 44#include <sys/cdefs.h>
45#ifndef lint 45#ifndef lint
46#if 0 46#if 0
47static char sccsid[] = "@(#)log.c 8.1 (Berkeley) 5/31/93"; 47static char sccsid[] = "@(#)log.c 8.1 (Berkeley) 5/31/93";
48#else 48#else
49__RCSID("$NetBSD: log.c,v 1.19 2007/12/15 19:44:38 perry Exp $"); 49__RCSID("$NetBSD: log.c,v 1.20 2009/05/26 00:00:56 dholland Exp $");
50#endif 50#endif
51#endif /* not lint */ 51#endif /* not lint */
52 52
53#include "include.h" 53#include "include.h"
54#include "pathnames.h" 54#include "pathnames.h"
55 55
56static FILE *score_fp; 56static FILE *score_fp;
57 57
58int 58int
59compar(const void *va, const void *vb) 59compar(const void *va, const void *vb)
60{ 60{
61 const SCORE *a, *b; 61 const SCORE *a, *b;
62 62
63 a = (const SCORE *)va; 63 a = (const SCORE *)va;
64 b = (const SCORE *)vb; 64 b = (const SCORE *)vb;
65 if (b->planes == a->planes) 65 if (b->planes == a->planes)
66 return (b->time - a->time); 66 return (b->time - a->time);
67 else 67 else
68 return (b->planes - a->planes); 68 return (b->planes - a->planes);
69} 69}
70 70
71#define SECAMIN 60 71#define SECAMIN 60
72#define MINAHOUR 60 72#define MINAHOUR 60
73#define HOURADAY 24 73#define HOURADAY 24
74#define SECAHOUR (SECAMIN * MINAHOUR) 74#define SECAHOUR (SECAMIN * MINAHOUR)
75#define SECADAY (SECAHOUR * HOURADAY) 75#define SECADAY (SECAHOUR * HOURADAY)
76#define DAY(t) ((t) / SECADAY) 76#define DAY(t) ((t) / SECADAY)
77#define HOUR(t) (((t) % SECADAY) / SECAHOUR) 77#define HOUR(t) (((t) % SECADAY) / SECAHOUR)
78#define MIN(t) (((t) % SECAHOUR) / SECAMIN) 78#define MIN(t) (((t) % SECAHOUR) / SECAMIN)
79#define SEC(t) ((t) % SECAMIN) 79#define SEC(t) ((t) % SECAMIN)
80 80
81const char * 81const char *
82timestr(int t) 82timestr(int t)
83{ 83{
84 static char s[80]; 84 static char s[80];
85 85
86 if (DAY(t) > 0) 86 if (DAY(t) > 0)
87 (void)sprintf(s, "%dd+%02dhrs", DAY(t), HOUR(t)); 87 (void)snprintf(s, sizeof(s), "%dd+%02dhrs", DAY(t), HOUR(t));
88 else if (HOUR(t) > 0) 88 else if (HOUR(t) > 0)
89 (void)sprintf(s, "%d:%02d:%02d", HOUR(t), MIN(t), SEC(t)); 89 (void)snprintf(s, sizeof(s), "%d:%02d:%02d", HOUR(t), MIN(t),
 90 SEC(t));
90 else if (MIN(t) > 0) 91 else if (MIN(t) > 0)
91 (void)sprintf(s, "%d:%02d", MIN(t), SEC(t)); 92 (void)snprintf(s, sizeof(s), "%d:%02d", MIN(t), SEC(t));
92 else if (SEC(t) > 0) 93 else if (SEC(t) > 0)
93 (void)sprintf(s, ":%02d", SEC(t)); 94 (void)snprintf(s, sizeof(s), ":%02d", SEC(t));
94 else 95 else
95 *s = '\0'; 96 *s = '\0';
96 97
97 return (s); 98 return (s);
98} 99}
99 100
100void 101void
101open_score_file(void) 102open_score_file(void)
102{ 103{
103 mode_t old_mask; 104 mode_t old_mask;
104 int score_fd; 105 int score_fd;
105 int flags; 106 int flags;
106 107
107 old_mask = umask(0); 108 old_mask = umask(0);
108#if defined(O_NOFOLLOW) 109#if defined(O_NOFOLLOW)
109 score_fd = open(_PATH_SCORE, O_CREAT|O_RDWR|O_NOFOLLOW, 0664); 110 score_fd = open(_PATH_SCORE, O_CREAT|O_RDWR|O_NOFOLLOW, 0664);
110#else 111#else
111 score_fd = open(_PATH_SCORE, O_CREAT|O_RDWR, 0664); 112 score_fd = open(_PATH_SCORE, O_CREAT|O_RDWR, 0664);
112#endif 113#endif
113 (void)umask(old_mask); 114 (void)umask(old_mask);
114 if (score_fd < 0) { 115 if (score_fd < 0) {
115 warn("open %s", _PATH_SCORE); 116 warn("open %s", _PATH_SCORE);
116 return; 117 return;
117 } 118 }
118 if (score_fd < 3) 119 if (score_fd < 3)
119 exit(1); 120 exit(1);
120 /* Set the close-on-exec flag. If this fails for any reason, quit 121 /* Set the close-on-exec flag. If this fails for any reason, quit
121 * rather than leave the score file open to tampering. */ 122 * rather than leave the score file open to tampering. */
122 flags = fcntl(score_fd, F_GETFD); 123 flags = fcntl(score_fd, F_GETFD);
123 if (flags < 0) 124 if (flags < 0)
124 err(1, "fcntl F_GETFD"); 125 err(1, "fcntl F_GETFD");
125 flags |= FD_CLOEXEC; 126 flags |= FD_CLOEXEC;
126 if (fcntl(score_fd, F_SETFD, flags) == -1) 127 if (fcntl(score_fd, F_SETFD, flags) == -1)
127 err(1, "fcntl F_SETFD"); 128 err(1, "fcntl F_SETFD");
128 /* 129 /*
129 * This is done to take advantage of stdio, while still  130 * This is done to take advantage of stdio, while still
130 * allowing a O_CREAT during the open(2) of the log file. 131 * allowing a O_CREAT during the open(2) of the log file.
131 */ 132 */
132 score_fp = fdopen(score_fd, "r+"); 133 score_fp = fdopen(score_fd, "r+");
133 if (score_fp == NULL) { 134 if (score_fp == NULL) {
134 warn("fdopen %s", _PATH_SCORE); 135 warn("fdopen %s", _PATH_SCORE);
135 return; 136 return;
136 } 137 }
137} 138}
138 139
139int 140int
140log_score(int list_em) 141log_score(int list_em)
141{ 142{
142 int i, num_scores = 0, good, changed = 0, found = 0; 143 int i, num_scores = 0, good, changed = 0, found = 0;
143 struct passwd *pw; 144 struct passwd *pw;
144 char *cp; 145 char *cp;
145 SCORE score[100], thisscore; 146 SCORE score[100], thisscore;
146 struct utsname lname; 147 struct utsname lname;
147 long offset; 148 long offset;
148 149
149 if (score_fp == NULL) { 150 if (score_fp == NULL) {
150 warnx("no score file available"); 151 warnx("no score file available");
151 return (-1); 152 return (-1);
152 } 153 }
153 154
154#ifdef BSD 155#ifdef BSD
155 if (flock(fileno(score_fp), LOCK_EX) < 0) 156 if (flock(fileno(score_fp), LOCK_EX) < 0)
156#endif 157#endif
157#ifdef SYSV 158#ifdef SYSV
158 if (lockf(fileno(score_fp), F_LOCK, 1) < 0) 159 if (lockf(fileno(score_fp), F_LOCK, 1) < 0)
159#endif 160#endif
160 { 161 {
161 warn("flock %s", _PATH_SCORE); 162 warn("flock %s", _PATH_SCORE);
162 return (-1); 163 return (-1);
163 } 164 }
164 for (;;) { 165 for (;;) {
165 good = fscanf(score_fp, SCORE_SCANF_FMT, 166 good = fscanf(score_fp, SCORE_SCANF_FMT,
166 score[num_scores].name,  167 score[num_scores].name,
167 score[num_scores].host,  168 score[num_scores].host,
168 score[num_scores].game, 169 score[num_scores].game,
169 &score[num_scores].planes,  170 &score[num_scores].planes,
170 &score[num_scores].time, 171 &score[num_scores].time,
171 &score[num_scores].real_time); 172 &score[num_scores].real_time);
172 if (good != 6 || ++num_scores >= NUM_SCORES) 173 if (good != 6 || ++num_scores >= NUM_SCORES)
173 break; 174 break;
174 } 175 }
175 if (!test_mode && !list_em) { 176 if (!test_mode && !list_em) {
176 if ((pw = (struct passwd *) getpwuid(getuid())) == NULL) { 177 if ((pw = (struct passwd *) getpwuid(getuid())) == NULL) {
177 (void)fprintf(stderr,  178 (void)fprintf(stderr,
178 "getpwuid failed for uid %d. Who are you?\n", 179 "getpwuid failed for uid %d. Who are you?\n",
179 (int)getuid()); 180 (int)getuid());
180 return (-1); 181 return (-1);
181 } 182 }
182 (void)strlcpy(thisscore.name, pw->pw_name, SCORE_NAME_LEN); 183 (void)strlcpy(thisscore.name, pw->pw_name, SCORE_NAME_LEN);
183 (void)uname(&lname); 184 (void)uname(&lname);
184 (void)strlcpy(thisscore.host, lname.nodename,  185 (void)strlcpy(thisscore.host, lname.nodename,
185 sizeof(thisscore.host)); 186 sizeof(thisscore.host));
186 187
187 cp = strrchr(filename, '/'); 188 cp = strrchr(filename, '/');
188 if (cp == NULL) { 189 if (cp == NULL) {
189 (void)fprintf(stderr, "log: where's the '/' in %s?\n",  190 (void)fprintf(stderr, "log: where's the '/' in %s?\n",
190 filename); 191 filename);
191 return (-1); 192 return (-1);
192 } 193 }
193 cp++; 194 cp++;
194 (void)strlcpy(thisscore.game, cp, SCORE_GAME_LEN); 195 (void)strlcpy(thisscore.game, cp, SCORE_GAME_LEN);
195 196
196 thisscore.time = clck; 197 thisscore.time = clck;
197 thisscore.planes = safe_planes; 198 thisscore.planes = safe_planes;
198 thisscore.real_time = time(0) - start_time; 199 thisscore.real_time = time(0) - start_time;
199 200
200 for (i = 0; i < num_scores; i++) { 201 for (i = 0; i < num_scores; i++) {
201 if (strcmp(thisscore.name, score[i].name) == 0 && 202 if (strcmp(thisscore.name, score[i].name) == 0 &&
202 strcmp(thisscore.host, score[i].host) == 0 && 203 strcmp(thisscore.host, score[i].host) == 0 &&
203 strcmp(thisscore.game, score[i].game) == 0) { 204 strcmp(thisscore.game, score[i].game) == 0) {
204 if (thisscore.time > score[i].time) { 205 if (thisscore.time > score[i].time) {
205 score[i].time = thisscore.time; 206 score[i].time = thisscore.time;
206 score[i].planes = thisscore.planes; 207 score[i].planes = thisscore.planes;
207 score[i].real_time = 208 score[i].real_time =
208 thisscore.real_time; 209 thisscore.real_time;
209 changed++; 210 changed++;
210 } 211 }
211 found++; 212 found++;
212 break; 213 break;
213 } 214 }
214 } 215 }
215 if (!found) { 216 if (!found) {
216 for (i = 0; i < num_scores; i++) { 217 for (i = 0; i < num_scores; i++) {
217 if (thisscore.time > score[i].time) { 218 if (thisscore.time > score[i].time) {
218 if (num_scores < NUM_SCORES) 219 if (num_scores < NUM_SCORES)
219 num_scores++; 220 num_scores++;
220 (void)memcpy(&score[num_scores - 1], 221 (void)memcpy(&score[num_scores - 1],
221 &score[i], sizeof (score[i])); 222 &score[i], sizeof (score[i]));
222 (void)memcpy(&score[i], &thisscore, 223 (void)memcpy(&score[i], &thisscore,
223 sizeof (score[i])); 224 sizeof (score[i]));
224 changed++; 225 changed++;
225 break; 226 break;
226 } 227 }
227 } 228 }
228 } 229 }
229 if (!found && !changed && num_scores < NUM_SCORES) { 230 if (!found && !changed && num_scores < NUM_SCORES) {
230 (void)memcpy(&score[num_scores], &thisscore, 231 (void)memcpy(&score[num_scores], &thisscore,
231 sizeof (score[num_scores])); 232 sizeof (score[num_scores]));
232 num_scores++; 233 num_scores++;
233 changed++; 234 changed++;
234 } 235 }
235 236
236 if (changed) { 237 if (changed) {
237 if (found) 238 if (found)
238 (void)puts("You beat your previous score!"); 239 (void)puts("You beat your previous score!");
239 else 240 else
240 (void)puts("You made the top players list!"); 241 (void)puts("You made the top players list!");
241 qsort(score, (size_t)num_scores, sizeof (*score), 242 qsort(score, (size_t)num_scores, sizeof (*score),
242 compar); 243 compar);
243 rewind(score_fp); 244 rewind(score_fp);
244 for (i = 0; i < num_scores; i++) 245 for (i = 0; i < num_scores; i++)
245 (void)fprintf(score_fp, "%s %s %s %d %d %d\n", 246 (void)fprintf(score_fp, "%s %s %s %d %d %d\n",
246 score[i].name, score[i].host,  247 score[i].name, score[i].host,
247 score[i].game, score[i].planes, 248 score[i].game, score[i].planes,
248 score[i].time, score[i].real_time); 249 score[i].time, score[i].real_time);
249 (void)fflush(score_fp); 250 (void)fflush(score_fp);
250 if (ferror(score_fp)) 251 if (ferror(score_fp))
251 warn("error writing %s", _PATH_SCORE); 252 warn("error writing %s", _PATH_SCORE);
252 /* It is just possible that updating an entry could 253 /* It is just possible that updating an entry could
253 * have reduced the length of the file, so we 254 * have reduced the length of the file, so we
254 * truncate it. The seeks are required for stream/fd 255 * truncate it. The seeks are required for stream/fd
255 * synchronisation by POSIX.1. */ 256 * synchronisation by POSIX.1. */
256 offset = ftell(score_fp); 257 offset = ftell(score_fp);
257 (void)lseek(fileno(score_fp), (off_t)0, SEEK_SET); 258 (void)lseek(fileno(score_fp), (off_t)0, SEEK_SET);
258 (void)ftruncate(fileno(score_fp), (off_t)offset); 259 (void)ftruncate(fileno(score_fp), (off_t)offset);
259 rewind(score_fp); 260 rewind(score_fp);
260 } else { 261 } else {
261 if (found) 262 if (found)
262 (void)puts( 263 (void)puts(
263 "You didn't beat your previous score."); 264 "You didn't beat your previous score.");
264 else 265 else
265 (void)puts( 266 (void)puts(
266 "You didn't make the top players list."); 267 "You didn't make the top players list.");
267 } 268 }
268 (void)putchar('\n'); 269 (void)putchar('\n');
269 } 270 }
270#ifdef BSD 271#ifdef BSD
271 (void)flock(fileno(score_fp), LOCK_UN); 272 (void)flock(fileno(score_fp), LOCK_UN);
272#endif 273#endif
273#ifdef SYSV 274#ifdef SYSV
274 /* lock will evaporate upon close */ 275 /* lock will evaporate upon close */
275#endif 276#endif
276 (void)fclose(score_fp); 277 (void)fclose(score_fp);
277 (void)printf("%2s: %-8s %-8s %-18s %4s %9s %4s\n", "#", "name", 278 (void)printf("%2s: %-8s %-8s %-18s %4s %9s %4s\n", "#", "name",
278 "host", "game", "time", "real time", "planes safe"); 279 "host", "game", "time", "real time", "planes safe");
279 (void)printf("-------------------------------------------------------"); 280 (void)printf("-------------------------------------------------------");
280 (void)printf("-------------------------\n"); 281 (void)printf("-------------------------\n");
281 for (i = 0; i < num_scores; i++) { 282 for (i = 0; i < num_scores; i++) {
282 cp = strchr(score[i].host, '.'); 283 cp = strchr(score[i].host, '.');
283 if (cp != NULL) 284 if (cp != NULL)
284 *cp = '\0'; 285 *cp = '\0';
285 (void)printf("%2d: %-8s %-8s %-18s %4d %9s %4d\n", i + 1, 286 (void)printf("%2d: %-8s %-8s %-18s %4d %9s %4d\n", i + 1,
286 score[i].name, score[i].host, score[i].game, 287 score[i].name, score[i].host, score[i].game,
287 score[i].time, timestr(score[i].real_time), 288 score[i].time, timestr(score[i].real_time),
288 score[i].planes); 289 score[i].planes);
289 } 290 }
290 (void)putchar('\n'); 291 (void)putchar('\n');
291 return (0); 292 return (0);
292} 293}
293 294
294/* ARGSUSED */ 295/* ARGSUSED */
295void 296void
296log_score_quit(int dummy __unused) 297log_score_quit(int dummy __unused)
297{ 298{
298 (void)log_score(0); 299 (void)log_score(0);
299 exit(0); 300 exit(0);
300} 301}

cvs diff -r1.19 -r1.20 src/games/atc/update.c (switch to unified diff)

--- src/games/atc/update.c 2007/12/15 19:44:38 1.19
+++ src/games/atc/update.c 2009/05/26 00:00:56 1.20
@@ -1,413 +1,419 @@ @@ -1,413 +1,419 @@
1/* $NetBSD: update.c,v 1.19 2007/12/15 19:44:38 perry Exp $ */ 1/* $NetBSD: update.c,v 1.20 2009/05/26 00:00:56 dholland Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1990, 1993 4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Ed James. 8 * Ed James.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors 18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software 19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission. 20 * without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 */ 33 */
34 34
35/* 35/*
36 * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved. 36 * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
37 * 37 *
38 * Copy permission is hereby granted provided that this notice is 38 * Copy permission is hereby granted provided that this notice is
39 * retained on all partial or complete copies. 39 * retained on all partial or complete copies.
40 * 40 *
41 * For more info on this and all of my stuff, mail edjames@berkeley.edu. 41 * For more info on this and all of my stuff, mail edjames@berkeley.edu.
42 */ 42 */
43 43
44#include <sys/cdefs.h> 44#include <sys/cdefs.h>
45#ifndef lint 45#ifndef lint
46#if 0 46#if 0
47static char sccsid[] = "@(#)update.c 8.1 (Berkeley) 5/31/93"; 47static char sccsid[] = "@(#)update.c 8.1 (Berkeley) 5/31/93";
48#else 48#else
49__RCSID("$NetBSD: update.c,v 1.19 2007/12/15 19:44:38 perry Exp $"); 49__RCSID("$NetBSD: update.c,v 1.20 2009/05/26 00:00:56 dholland Exp $");
50#endif 50#endif
51#endif /* not lint */ 51#endif /* not lint */
52 52
53#include "include.h" 53#include "include.h"
54 54
55/* ARGSUSED */ 55/* ARGSUSED */
56void 56void
57update(int dummy __unused) 57update(int dummy __unused)
58{ 58{
59 int i, dir_diff, unclean; 59 int i, dir_diff, unclean;
60 PLANE *pp, *p1, *p2; 60 PLANE *pp, *p1, *p2;
61 61
62#ifdef SYSV 62#ifdef SYSV
63 alarm(0); 63 alarm(0);
64 signal(SIGALRM, update); 64 signal(SIGALRM, update);
65#endif 65#endif
66 66
67 clck++; 67 clck++;
68 68
69 erase_all(); 69 erase_all();
70 70
71 /* put some planes in the air */ 71 /* put some planes in the air */
72 do { 72 do {
73 unclean = 0; 73 unclean = 0;
74 for (pp = ground.head; pp != NULL; pp = pp->next) { 74 for (pp = ground.head; pp != NULL; pp = pp->next) {
75 if (pp->new_altitude > 0) { 75 if (pp->new_altitude > 0) {
76 delete(&ground, pp); 76 delete(&ground, pp);
77 append(&air, pp); 77 append(&air, pp);
78 unclean = 1; 78 unclean = 1;
79 break; 79 break;
80 } 80 }
81 } 81 }
82 } while (unclean); 82 } while (unclean);
83 83
84 /* do altitude change and basic movement */ 84 /* do altitude change and basic movement */
85 for (pp = air.head; pp != NULL; pp = pp->next) { 85 for (pp = air.head; pp != NULL; pp = pp->next) {
86 /* type 0 only move every other turn */ 86 /* type 0 only move every other turn */
87 if (pp->plane_type == 0 && clck & 1) 87 if (pp->plane_type == 0 && clck & 1)
88 continue; 88 continue;
89 89
90 pp->fuel--; 90 pp->fuel--;
91 if (pp->fuel < 0) 91 if (pp->fuel < 0)
92 loser(pp, "ran out of fuel."); 92 loser(pp, "ran out of fuel.");
93 93
94 pp->altitude += SGN(pp->new_altitude - pp->altitude); 94 pp->altitude += SGN(pp->new_altitude - pp->altitude);
95 95
96 if (!pp->delayd) { 96 if (!pp->delayd) {
97 dir_diff = pp->new_dir - pp->dir; 97 dir_diff = pp->new_dir - pp->dir;
98 /* 98 /*
99 * Allow for circle commands 99 * Allow for circle commands
100 */ 100 */
101 if (pp->new_dir >= 0 && pp->new_dir < MAXDIR) { 101 if (pp->new_dir >= 0 && pp->new_dir < MAXDIR) {
102 if (dir_diff > MAXDIR/2) 102 if (dir_diff > MAXDIR/2)
103 dir_diff -= MAXDIR; 103 dir_diff -= MAXDIR;
104 else if (dir_diff < -(MAXDIR/2)) 104 else if (dir_diff < -(MAXDIR/2))
105 dir_diff += MAXDIR; 105 dir_diff += MAXDIR;
106 } 106 }
107 if (dir_diff > 2) 107 if (dir_diff > 2)
108 dir_diff = 2; 108 dir_diff = 2;
109 else if (dir_diff < -2) 109 else if (dir_diff < -2)
110 dir_diff = -2; 110 dir_diff = -2;
111 pp->dir += dir_diff; 111 pp->dir += dir_diff;
112 if (pp->dir >= MAXDIR) 112 if (pp->dir >= MAXDIR)
113 pp->dir -= MAXDIR; 113 pp->dir -= MAXDIR;
114 else if (pp->dir < 0) 114 else if (pp->dir < 0)
115 pp->dir += MAXDIR; 115 pp->dir += MAXDIR;
116 } 116 }
117 pp->xpos += displacement[pp->dir].dx; 117 pp->xpos += displacement[pp->dir].dx;
118 pp->ypos += displacement[pp->dir].dy; 118 pp->ypos += displacement[pp->dir].dy;
119 119
120 if (pp->delayd && pp->xpos == sp->beacon[pp->delayd_no].x && 120 if (pp->delayd && pp->xpos == sp->beacon[pp->delayd_no].x &&
121 pp->ypos == sp->beacon[pp->delayd_no].y) { 121 pp->ypos == sp->beacon[pp->delayd_no].y) {
122 pp->delayd = 0; 122 pp->delayd = 0;
123 if (pp->status == S_UNMARKED) 123 if (pp->status == S_UNMARKED)
124 pp->status = S_MARKED; 124 pp->status = S_MARKED;
125 } 125 }
126 126
127 switch (pp->dest_type) { 127 switch (pp->dest_type) {
128 case T_AIRPORT: 128 case T_AIRPORT:
129 if (pp->xpos == sp->airport[pp->dest_no].x && 129 if (pp->xpos == sp->airport[pp->dest_no].x &&
130 pp->ypos == sp->airport[pp->dest_no].y && 130 pp->ypos == sp->airport[pp->dest_no].y &&
131 pp->altitude == 0) { 131 pp->altitude == 0) {
132 if (pp->dir != sp->airport[pp->dest_no].dir) 132 if (pp->dir != sp->airport[pp->dest_no].dir)
133 loser(pp, "landed in the wrong direction."); 133 loser(pp, "landed in the wrong direction.");
134 else { 134 else {
135 pp->status = S_GONE; 135 pp->status = S_GONE;
136 continue; 136 continue;
137 } 137 }
138 } 138 }
139 break; 139 break;
140 case T_EXIT: 140 case T_EXIT:
141 if (pp->xpos == sp->exit[pp->dest_no].x && 141 if (pp->xpos == sp->exit[pp->dest_no].x &&
142 pp->ypos == sp->exit[pp->dest_no].y) { 142 pp->ypos == sp->exit[pp->dest_no].y) {
143 if (pp->altitude != 9) 143 if (pp->altitude != 9)
144 loser(pp, "exited at the wrong altitude."); 144 loser(pp, "exited at the wrong altitude.");
145 else { 145 else {
146 pp->status = S_GONE; 146 pp->status = S_GONE;
147 continue; 147 continue;
148 } 148 }
149 } 149 }
150 break; 150 break;
151 default: 151 default:
152 loser(pp, "has a bizarre destination, get help!"); 152 loser(pp, "has a bizarre destination, get help!");
153 } 153 }
154 if (pp->altitude > 9) 154 if (pp->altitude > 9)
155 /* "this is impossible" */ 155 /* "this is impossible" */
156 loser(pp, "exceeded flight ceiling."); 156 loser(pp, "exceeded flight ceiling.");
157 if (pp->altitude <= 0) { 157 if (pp->altitude <= 0) {
158 for (i = 0; i < sp->num_airports; i++) 158 for (i = 0; i < sp->num_airports; i++)
159 if (pp->xpos == sp->airport[i].x && 159 if (pp->xpos == sp->airport[i].x &&
160 pp->ypos == sp->airport[i].y) { 160 pp->ypos == sp->airport[i].y) {
161 if (pp->dest_type == T_AIRPORT) 161 if (pp->dest_type == T_AIRPORT)
162 loser(pp,  162 loser(pp,
163 "landed at the wrong airport."); 163 "landed at the wrong airport.");
164 else 164 else
165 loser(pp,  165 loser(pp,
166 "landed instead of exited."); 166 "landed instead of exited.");
167 } 167 }
168 loser(pp, "crashed on the ground."); 168 loser(pp, "crashed on the ground.");
169 } 169 }
170 if (pp->xpos < 1 || pp->xpos >= sp->width - 1 || 170 if (pp->xpos < 1 || pp->xpos >= sp->width - 1 ||
171 pp->ypos < 1 || pp->ypos >= sp->height - 1) { 171 pp->ypos < 1 || pp->ypos >= sp->height - 1) {
172 for (i = 0; i < sp->num_exits; i++) 172 for (i = 0; i < sp->num_exits; i++)
173 if (pp->xpos == sp->exit[i].x && 173 if (pp->xpos == sp->exit[i].x &&
174 pp->ypos == sp->exit[i].y) { 174 pp->ypos == sp->exit[i].y) {
175 if (pp->dest_type == T_EXIT) 175 if (pp->dest_type == T_EXIT)
176 loser(pp,  176 loser(pp,
177 "exited via the wrong exit."); 177 "exited via the wrong exit.");
178 else 178 else
179 loser(pp,  179 loser(pp,
180 "exited instead of landed."); 180 "exited instead of landed.");
181 } 181 }
182 loser(pp, "illegally left the flight arena."); 182 loser(pp, "illegally left the flight arena.");
183 } 183 }
184 } 184 }
185 185
186 /* 186 /*
187 * Traverse the list once, deleting the planes that are gone. 187 * Traverse the list once, deleting the planes that are gone.
188 */ 188 */
189 for (pp = air.head; pp != NULL; pp = p2) { 189 for (pp = air.head; pp != NULL; pp = p2) {
190 p2 = pp->next; 190 p2 = pp->next;
191 if (pp->status == S_GONE) { 191 if (pp->status == S_GONE) {
192 safe_planes++; 192 safe_planes++;
193 delete(&air, pp); 193 delete(&air, pp);
194 } 194 }
195 } 195 }
196 196
197 draw_all(); 197 draw_all();
198 198
199 for (p1 = air.head; p1 != NULL; p1 = p1->next) 199 for (p1 = air.head; p1 != NULL; p1 = p1->next)
200 for (p2 = p1->next; p2 != NULL; p2 = p2->next) 200 for (p2 = p1->next; p2 != NULL; p2 = p2->next)
201 if (too_close(p1, p2, 1)) { 201 if (too_close(p1, p2, 1)) {
202 static char buf[80]; 202 static char buf[80];
203 203
204 (void)sprintf(buf, "collided with plane '%c'.", 204 (void)snprintf(buf, sizeof(buf),
 205 "collided with plane '%c'.",
205 name(p2)); 206 name(p2));
206 loser(p1, buf); 207 loser(p1, buf);
207 } 208 }
208 /* 209 /*
209 * Check every other update. Actually, only add on even updates. 210 * Check every other update. Actually, only add on even updates.
210 * Otherwise, prop jobs show up *on* entrance. Remember that 211 * Otherwise, prop jobs show up *on* entrance. Remember that
211 * we don't update props on odd updates. 212 * we don't update props on odd updates.
212 */ 213 */
213 if ((rand() % sp->newplane_time) == 0) 214 if ((rand() % sp->newplane_time) == 0)
214 (void)addplane(); 215 (void)addplane();
215 216
216#ifdef SYSV 217#ifdef SYSV
217 alarm(sp->update_secs); 218 alarm(sp->update_secs);
218#endif 219#endif
219} 220}
220 221
221const char * 222const char *
222command(const PLANE *pp) 223command(const PLANE *pp)
223{ 224{
224 static char buf[50], *bp, *comm_start; 225 static char buf[50], *bp, *comm_start;
 226 size_t bpsize;
225 227
226 buf[0] = '\0'; 228 buf[0] = '\0';
227 bp = buf; 229 bp = buf;
228 (void)sprintf(bp, "%c%d%c%c%d: ", name(pp), pp->altitude,  230 bpsize = sizeof(buf);
 231 (void)snprintf(bp, bpsize, "%c%d%c%c%d: ", name(pp), pp->altitude,
229 (pp->fuel < LOWFUEL) ? '*' : ' ', 232 (pp->fuel < LOWFUEL) ? '*' : ' ',
230 (pp->dest_type == T_AIRPORT) ? 'A' : 'E', pp->dest_no); 233 (pp->dest_type == T_AIRPORT) ? 'A' : 'E', pp->dest_no);
231 234
232 comm_start = bp = strchr(buf, '\0'); 235 comm_start = bp = strchr(buf, '\0');
 236 bpsize = buf + sizeof(buf) - bp;
233 if (pp->altitude == 0) 237 if (pp->altitude == 0)
234 (void)sprintf(bp, "Holding @ A%d", pp->orig_no); 238 (void)snprintf(bp, bpsize, "Holding @ A%d", pp->orig_no);
235 else if (pp->new_dir >= MAXDIR || pp->new_dir < 0) 239 else if (pp->new_dir >= MAXDIR || pp->new_dir < 0)
236 (void)strcpy(bp, "Circle"); 240 (void)snprintf(bp, bpsize, "Circle");
237 else if (pp->new_dir != pp->dir) 241 else if (pp->new_dir != pp->dir)
238 (void)sprintf(bp, "%d", dir_deg(pp->new_dir)); 242 (void)snprintf(bp, bpsize, "%d", dir_deg(pp->new_dir));
239 243
240 bp = strchr(buf, '\0'); 244 bp = strchr(buf, '\0');
 245 bpsize = buf + sizeof(buf) - bp;
241 if (pp->delayd) 246 if (pp->delayd)
242 (void)sprintf(bp, " @ B%d", pp->delayd_no); 247 (void)snprintf(bp, bpsize, " @ B%d", pp->delayd_no);
243 248
244 bp = strchr(buf, '\0'); 249 bp = strchr(buf, '\0');
 250 bpsize = buf + sizeof(buf) - bp;
245 if (*comm_start == '\0' &&  251 if (*comm_start == '\0' &&
246 (pp->status == S_UNMARKED || pp->status == S_IGNORED)) 252 (pp->status == S_UNMARKED || pp->status == S_IGNORED))
247 (void)strcpy(bp, "---------"); 253 (void)snprintf(bp, bpsize, "---------");
248 return (buf); 254 return (buf);
249} 255}
250 256
251char 257char
252name(const PLANE *p) 258name(const PLANE *p)
253{ 259{
254 if (p->plane_type == 0) 260 if (p->plane_type == 0)
255 return ('A' + p->plane_no); 261 return ('A' + p->plane_no);
256 else 262 else
257 return ('a' + p->plane_no); 263 return ('a' + p->plane_no);
258} 264}
259 265
260int 266int
261number(int l) 267number(int l)
262{ 268{
263 if (islower((unsigned char)l)) 269 if (islower((unsigned char)l))
264 return (l - 'a'); 270 return (l - 'a');
265 else if (isupper((unsigned char)l)) 271 else if (isupper((unsigned char)l))
266 return (l - 'A'); 272 return (l - 'A');
267 else 273 else
268 return (-1); 274 return (-1);
269} 275}
270 276
271int 277int
272next_plane(void) 278next_plane(void)
273{ 279{
274 static int last_plane = -1; 280 static int last_plane = -1;
275 PLANE *pp; 281 PLANE *pp;
276 int found, start_plane = last_plane; 282 int found, start_plane = last_plane;
277 283
278 do { 284 do {
279 found = 0; 285 found = 0;
280 last_plane++; 286 last_plane++;
281 if (last_plane >= 26) 287 if (last_plane >= 26)
282 last_plane = 0; 288 last_plane = 0;
283 for (pp = air.head; pp != NULL; pp = pp->next) 289 for (pp = air.head; pp != NULL; pp = pp->next)
284 if (pp->plane_no == last_plane) { 290 if (pp->plane_no == last_plane) {
285 found++; 291 found++;
286 break; 292 break;
287 } 293 }
288 if (!found) 294 if (!found)
289 for (pp = ground.head; pp != NULL; pp = pp->next) 295 for (pp = ground.head; pp != NULL; pp = pp->next)
290 if (pp->plane_no == last_plane) { 296 if (pp->plane_no == last_plane) {
291 found++; 297 found++;
292 break; 298 break;
293 } 299 }
294 } while (found && last_plane != start_plane); 300 } while (found && last_plane != start_plane);
295 if (last_plane == start_plane) 301 if (last_plane == start_plane)
296 return (-1); 302 return (-1);
297 return (last_plane); 303 return (last_plane);
298} 304}
299 305
300int 306int
301addplane(void) 307addplane(void)
302{ 308{
303 PLANE p, *pp, *p1; 309 PLANE p, *pp, *p1;
304 int i, num_starts, isclose, rnd, rnd2, pnum; 310 int i, num_starts, isclose, rnd, rnd2, pnum;
305 311
306 (void)memset(&p, 0, sizeof (p)); 312 (void)memset(&p, 0, sizeof (p));
307 313
308 p.status = S_MARKED; 314 p.status = S_MARKED;
309 p.plane_type = random() % 2; 315 p.plane_type = random() % 2;
310 316
311 num_starts = sp->num_exits + sp->num_airports; 317 num_starts = sp->num_exits + sp->num_airports;
312 rnd = random() % num_starts; 318 rnd = random() % num_starts;
313 319
314 if (rnd < sp->num_exits) { 320 if (rnd < sp->num_exits) {
315 p.dest_type = T_EXIT; 321 p.dest_type = T_EXIT;
316 p.dest_no = rnd; 322 p.dest_no = rnd;
317 } else { 323 } else {
318 p.dest_type = T_AIRPORT; 324 p.dest_type = T_AIRPORT;
319 p.dest_no = rnd - sp->num_exits; 325 p.dest_no = rnd - sp->num_exits;
320 } 326 }
321 327
322 /* loop until we get a plane not near another */ 328 /* loop until we get a plane not near another */
323 for (i = 0; i < num_starts; i++) { 329 for (i = 0; i < num_starts; i++) {
324 /* loop till we get a different start point */ 330 /* loop till we get a different start point */
325 while ((rnd2 = random() % num_starts) == rnd) 331 while ((rnd2 = random() % num_starts) == rnd)
326 ; 332 ;
327 if (rnd2 < sp->num_exits) { 333 if (rnd2 < sp->num_exits) {
328 p.orig_type = T_EXIT; 334 p.orig_type = T_EXIT;
329 p.orig_no = rnd2; 335 p.orig_no = rnd2;
330 p.xpos = sp->exit[rnd2].x; 336 p.xpos = sp->exit[rnd2].x;
331 p.ypos = sp->exit[rnd2].y; 337 p.ypos = sp->exit[rnd2].y;
332 p.new_dir = p.dir = sp->exit[rnd2].dir; 338 p.new_dir = p.dir = sp->exit[rnd2].dir;
333 p.altitude = p.new_altitude = 7; 339 p.altitude = p.new_altitude = 7;
334 isclose = 0; 340 isclose = 0;
335 for (p1 = air.head; p1 != NULL; p1 = p1->next) 341 for (p1 = air.head; p1 != NULL; p1 = p1->next)
336 if (too_close(p1, &p, 4)) { 342 if (too_close(p1, &p, 4)) {
337 isclose++; 343 isclose++;
338 break; 344 break;
339 } 345 }
340 if (isclose) 346 if (isclose)
341 continue; 347 continue;
342 } else { 348 } else {
343 p.orig_type = T_AIRPORT; 349 p.orig_type = T_AIRPORT;
344 p.orig_no = rnd2 - sp->num_exits; 350 p.orig_no = rnd2 - sp->num_exits;
345 p.xpos = sp->airport[p.orig_no].x; 351 p.xpos = sp->airport[p.orig_no].x;
346 p.ypos = sp->airport[p.orig_no].y; 352 p.ypos = sp->airport[p.orig_no].y;
347 p.new_dir = p.dir = sp->airport[p.orig_no].dir; 353 p.new_dir = p.dir = sp->airport[p.orig_no].dir;
348 p.altitude = p.new_altitude = 0; 354 p.altitude = p.new_altitude = 0;
349 } 355 }
350 p.fuel = sp->width + sp->height; 356 p.fuel = sp->width + sp->height;
351 break; 357 break;
352 } 358 }
353 if (i >= num_starts) 359 if (i >= num_starts)
354 return (-1); 360 return (-1);
355 pnum = next_plane(); 361 pnum = next_plane();
356 if (pnum < 0) 362 if (pnum < 0)
357 return (-1); 363 return (-1);
358 p.plane_no = pnum; 364 p.plane_no = pnum;
359 365
360 pp = newplane(); 366 pp = newplane();
361 if (pp == NULL) 367 if (pp == NULL)
362 loser(NULL, "Out of memory!"); 368 loser(NULL, "Out of memory!");
363 (void)memcpy(pp, &p, sizeof (p)); 369 (void)memcpy(pp, &p, sizeof (p));
364 370
365 if (pp->orig_type == T_AIRPORT) 371 if (pp->orig_type == T_AIRPORT)
366 append(&ground, pp); 372 append(&ground, pp);
367 else 373 else
368 append(&air, pp); 374 append(&air, pp);
369 375
370 return (pp->dest_type); 376 return (pp->dest_type);
371} 377}
372 378
373PLANE * 379PLANE *
374findplane(int n) 380findplane(int n)
375{ 381{
376 PLANE *pp; 382 PLANE *pp;
377 383
378 for (pp = air.head; pp != NULL; pp = pp->next) 384 for (pp = air.head; pp != NULL; pp = pp->next)
379 if (pp->plane_no == n) 385 if (pp->plane_no == n)
380 return (pp); 386 return (pp);
381 for (pp = ground.head; pp != NULL; pp = pp->next) 387 for (pp = ground.head; pp != NULL; pp = pp->next)
382 if (pp->plane_no == n) 388 if (pp->plane_no == n)
383 return (pp); 389 return (pp);
384 return (NULL); 390 return (NULL);
385} 391}
386 392
387int 393int
388too_close(const PLANE *p1, const PLANE *p2, int dist) 394too_close(const PLANE *p1, const PLANE *p2, int dist)
389{ 395{
390 if (ABS(p1->altitude - p2->altitude) <= dist && 396 if (ABS(p1->altitude - p2->altitude) <= dist &&
391 ABS(p1->xpos - p2->xpos) <= dist &&  397 ABS(p1->xpos - p2->xpos) <= dist &&
392 ABS(p1->ypos - p2->ypos) <= dist) 398 ABS(p1->ypos - p2->ypos) <= dist)
393 return (1); 399 return (1);
394 else 400 else
395 return (0); 401 return (0);
396} 402}
397 403
398int 404int
399dir_deg(int d) 405dir_deg(int d)
400{ 406{
401 switch (d) { 407 switch (d) {
402 case 0: return (0); 408 case 0: return (0);
403 case 1: return (45); 409 case 1: return (45);
404 case 2: return (90); 410 case 2: return (90);
405 case 3: return (135); 411 case 3: return (135);
406 case 4: return (180); 412 case 4: return (180);
407 case 5: return (225); 413 case 5: return (225);
408 case 6: return (270); 414 case 6: return (270);
409 case 7: return (315); 415 case 7: return (315);
410 default: 416 default:
411 return (-1); 417 return (-1);
412 } 418 }
413} 419}