sprintf -> snprintfdiff -r1.22 -r1.23 src/games/atc/input.c
(dholland)
--- 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 | |
47 | static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 5/31/93"; | 47 | static 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 | |||
66 | typedef struct { | 66 | typedef 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 | |||
73 | typedef struct { | 73 | typedef struct { | |
74 | int num_rules; | 74 | int num_rules; | |
75 | RULE *rule; | 75 | RULE *rule; | |
76 | } STATE; | 76 | } STATE; | |
77 | 77 | |||
78 | typedef struct { | 78 | typedef 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 | |||
97 | RULE state0[] = { { ALPHATOKEN, 1, "%c:", setplane}, | 97 | RULE 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 | |||
163 | STATE st[] = { | 163 | STATE 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 | |||
171 | PLANE p; | 171 | PLANE p; | |
172 | STACK stack[MAXDEPTH]; | 172 | STACK stack[MAXDEPTH]; | |
173 | int level; | 173 | int level; | |
174 | int tval; | 174 | int tval; | |
175 | int dest_type, dest_no, dir; | 175 | int dest_type, dest_no, dir; | |
176 | 176 | |||
177 | int | 177 | int | |
178 | pop(void) | 178 | pop(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 | |||
192 | void | 192 | void | |
193 | rezero(void) | 193 | rezero(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 | |||
205 | void | 205 | void | |
206 | push(int ruleno, int ch) | 206 | push(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 | |||
228 | int | 229 | int | |
229 | getcommand(void) | 230 | getcommand(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 | |||
288 | void | 289 | void | |
289 | noise(void) | 290 | noise(void) | |
290 | { | 291 | { | |
291 | (void)putchar('\07'); | 292 | (void)putchar('\07'); | |
292 | (void)fflush(stdout); | 293 | (void)fflush(stdout); | |
293 | } | 294 | } | |
294 | 295 | |||
295 | int | 296 | int | |
296 | gettoken(void) | 297 | gettoken(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 | |||
359 | const char * | 360 | const char * | |
360 | setplane(int c) | 361 | setplane(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 */ | |
373 | const char * | 374 | const char * | |
374 | turn(int c __unused) | 375 | turn(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 */ | |
382 | const char * | 383 | const char * | |
383 | circle(int c __unused) | 384 | circle(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 */ | |
392 | const char * | 393 | const char * | |
393 | left(int c __unused) | 394 | left(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 */ | |
403 | const char * | 404 | const char * | |
404 | right(int c __unused) | 405 | right(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 */ | |
414 | const char * | 415 | const char * | |
415 | Left(int c __unused) | 416 | Left(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 */ | |
424 | const char * | 425 | const char * | |
425 | Right(int c __unused) | 426 | Right(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 | |||
433 | const char * | 434 | const char * | |
434 | delayb(int c) | 435 | delayb(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 */ | |
478 | const char * | 479 | const char * | |
479 | beacon(int c __unused) | 480 | beacon(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 */ | |
486 | const char * | 487 | const char * | |
487 | ex_it(int c __unused) | 488 | ex_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 */ | |
494 | const char * | 495 | const char * | |
495 | airport(int c __unused) | 496 | airport(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 */ | |
502 | const char * | 503 | const char * | |
503 | climb(int c __unused) | 504 | climb(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 */ | |
510 | const char * | 511 | const char * | |
511 | descend(int c __unused) | 512 | descend(int c __unused) | |
512 | { | 513 | { | |
513 | dir = D_DOWN; | 514 | dir = D_DOWN; | |
514 | return (NULL); | 515 | return (NULL); | |
515 | } | 516 | } | |
516 | 517 | |||
517 | const char * | 518 | const char * | |
518 | setalt(int c) | 519 | setalt(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 | |||
530 | const char * | 531 | const char * | |
531 | setrelalt(int c) | 532 | setrelalt(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 | |||
561 | const char * | 562 | const char * | |
562 | benum(int c) | 563 | benum(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 | |||
591 | const char * | 592 | const char * | |
592 | to_dir(int c) | 593 | to_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 | |||
598 | const char * | 599 | const char * | |
599 | rel_dir(int c) | 600 | rel_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 */ | |
622 | const char * | 623 | const char * | |
623 | mark(int c __unused) | 624 | mark(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 */ | |
634 | const char * | 635 | const char * | |
635 | unmark(int c __unused) | 636 | unmark(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 */ | |
646 | const char * | 647 | const char * | |
647 | ignore(int c __unused) | 648 | ignore(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 | |||
657 | int | 658 | int | |
658 | dir_no(int ch) | 659 | dir_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 | } |
--- 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 | |
47 | static char sccsid[] = "@(#)log.c 8.1 (Berkeley) 5/31/93"; | 47 | static 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 | |||
56 | static FILE *score_fp; | 56 | static FILE *score_fp; | |
57 | 57 | |||
58 | int | 58 | int | |
59 | compar(const void *va, const void *vb) | 59 | compar(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 | |||
81 | const char * | 81 | const char * | |
82 | timestr(int t) | 82 | timestr(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 | |||
100 | void | 101 | void | |
101 | open_score_file(void) | 102 | open_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 | |||
139 | int | 140 | int | |
140 | log_score(int list_em) | 141 | log_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 */ | |
295 | void | 296 | void | |
296 | log_score_quit(int dummy __unused) | 297 | log_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 | } |
--- 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 | |
47 | static char sccsid[] = "@(#)update.c 8.1 (Berkeley) 5/31/93"; | 47 | static 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 */ | |
56 | void | 56 | void | |
57 | update(int dummy __unused) | 57 | update(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 | |||
221 | const char * | 222 | const char * | |
222 | command(const PLANE *pp) | 223 | command(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 | |||
251 | char | 257 | char | |
252 | name(const PLANE *p) | 258 | name(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 | |||
260 | int | 266 | int | |
261 | number(int l) | 267 | number(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 | |||
271 | int | 277 | int | |
272 | next_plane(void) | 278 | next_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 | |||
300 | int | 306 | int | |
301 | addplane(void) | 307 | addplane(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 | |||
373 | PLANE * | 379 | PLANE * | |
374 | findplane(int n) | 380 | findplane(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 | |||
387 | int | 393 | int | |
388 | too_close(const PLANE *p1, const PLANE *p2, int dist) | 394 | too_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 | |||
398 | int | 404 | int | |
399 | dir_deg(int d) | 405 | dir_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 | } |