misc.c revision 1.2 1 1.1 cgd /*
2 1.1 cgd * Copyright (c) 1980 Regents of the University of California.
3 1.1 cgd * All rights reserved.
4 1.1 cgd *
5 1.1 cgd * Redistribution and use in source and binary forms, with or without
6 1.1 cgd * modification, are permitted provided that the following conditions
7 1.1 cgd * are met:
8 1.1 cgd * 1. Redistributions of source code must retain the above copyright
9 1.1 cgd * notice, this list of conditions and the following disclaimer.
10 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
11 1.1 cgd * notice, this list of conditions and the following disclaimer in the
12 1.1 cgd * documentation and/or other materials provided with the distribution.
13 1.1 cgd * 3. All advertising materials mentioning features or use of this software
14 1.1 cgd * must display the following acknowledgement:
15 1.1 cgd * This product includes software developed by the University of
16 1.1 cgd * California, Berkeley and its contributors.
17 1.1 cgd * 4. Neither the name of the University nor the names of its contributors
18 1.1 cgd * may be used to endorse or promote products derived from this software
19 1.1 cgd * without specific prior written permission.
20 1.1 cgd *
21 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 1.1 cgd * SUCH DAMAGE.
32 1.1 cgd */
33 1.1 cgd
34 1.1 cgd #ifndef lint
35 1.2 mycroft /*static char sccsid[] = "from: @(#)misc.c 5.5 (Berkeley) 2/28/91";*/
36 1.2 mycroft static char rcsid[] = "$Id: misc.c,v 1.2 1993/08/01 18:53:37 mycroft Exp $";
37 1.1 cgd #endif /* not lint */
38 1.1 cgd
39 1.1 cgd # include "monop.ext"
40 1.1 cgd # include <ctype.h>
41 1.1 cgd # include <signal.h>
42 1.1 cgd
43 1.1 cgd # define execsh(sh) execl(sh, shell_name[roll(1, num_names)-1], 0)
44 1.1 cgd
45 1.1 cgd static char *shell_def = "/bin/csh",
46 1.1 cgd *shell_name[] = {
47 1.1 cgd ".Hi Mom!",
48 1.1 cgd ".Kick Me",
49 1.1 cgd ".I'm really the next process down",
50 1.1 cgd ".Hi Kids!",
51 1.1 cgd ".This space for rent",
52 1.1 cgd ".Singin' in the rain....",
53 1.1 cgd ".I am but a Cog in the Wheel of Life",
54 1.1 cgd ".Look out!!! Behind you!!!!!",
55 1.1 cgd ".Looking for a good time, sailor?",
56 1.1 cgd ".I don't get NO respect...",
57 1.1 cgd ".Augghh! You peeked!"
58 1.1 cgd };
59 1.1 cgd
60 1.1 cgd static int num_names = sizeof shell_name / sizeof (char *);;
61 1.1 cgd
62 1.1 cgd char *shell_in();
63 1.1 cgd
64 1.1 cgd /*
65 1.1 cgd * This routine executes a truncated set of commands until a
66 1.1 cgd * "yes or "no" answer is gotten.
67 1.1 cgd */
68 1.1 cgd getyn(prompt)
69 1.1 cgd reg char *prompt; {
70 1.1 cgd
71 1.1 cgd reg int com;
72 1.1 cgd
73 1.1 cgd for (;;)
74 1.1 cgd if ((com=getinp(prompt, yn)) < 2)
75 1.1 cgd return com;
76 1.1 cgd else
77 1.1 cgd (*func[com-2])();
78 1.1 cgd }
79 1.1 cgd /*
80 1.1 cgd * This routine tells the player if he's out of money.
81 1.1 cgd */
82 1.1 cgd notify() {
83 1.1 cgd
84 1.1 cgd if (cur_p->money < 0)
85 1.1 cgd printf("That leaves you $%d in debt\n", -cur_p->money);
86 1.1 cgd else if (cur_p->money == 0)
87 1.1 cgd printf("that leaves you broke\n");
88 1.1 cgd else if (fixing && !told_em && cur_p->money > 0) {
89 1.1 cgd printf("-- You are now Solvent ---\n");
90 1.1 cgd told_em = TRUE;
91 1.1 cgd }
92 1.1 cgd }
93 1.1 cgd /*
94 1.1 cgd * This routine switches to the next player
95 1.1 cgd */
96 1.1 cgd next_play() {
97 1.1 cgd
98 1.1 cgd player = ++player % num_play;
99 1.1 cgd cur_p = &play[player];
100 1.1 cgd num_doub = 0;
101 1.1 cgd }
102 1.1 cgd /*
103 1.1 cgd * This routine gets an integer from the keyboard after the
104 1.1 cgd * given prompt.
105 1.1 cgd */
106 1.1 cgd get_int(prompt)
107 1.1 cgd reg char *prompt; {
108 1.1 cgd
109 1.1 cgd reg int num;
110 1.1 cgd reg char *sp;
111 1.1 cgd char buf[257];
112 1.1 cgd
113 1.1 cgd for (;;) {
114 1.1 cgd inter:
115 1.1 cgd printf(prompt);
116 1.1 cgd num = 0;
117 1.1 cgd for (sp = buf; (*sp=getchar()) != '\n'; sp++)
118 1.1 cgd if (*sp == -1) /* check for interrupted system call */
119 1.1 cgd goto inter;
120 1.1 cgd if (sp == buf)
121 1.1 cgd continue;
122 1.1 cgd for (sp = buf; isspace(*sp); sp++)
123 1.1 cgd continue;
124 1.1 cgd for (; isdigit(*sp); sp++)
125 1.1 cgd num = num * 10 + *sp - '0';
126 1.1 cgd if (*sp == '\n')
127 1.1 cgd return num;
128 1.1 cgd else
129 1.1 cgd printf("I can't understand that\n");
130 1.1 cgd }
131 1.1 cgd }
132 1.1 cgd /*
133 1.1 cgd * This routine sets the monopoly flag from the list given.
134 1.1 cgd */
135 1.1 cgd set_ownlist(pl)
136 1.1 cgd int pl; {
137 1.1 cgd
138 1.1 cgd reg int num; /* general counter */
139 1.1 cgd reg MON *orig; /* remember starting monop ptr */
140 1.1 cgd reg OWN *op; /* current owned prop */
141 1.1 cgd OWN *orig_op; /* origianl prop before loop */
142 1.1 cgd
143 1.1 cgd op = play[pl].own_list;
144 1.1 cgd #ifdef DEBUG
145 1.1 cgd printf("op [%d] = play[pl [%d] ].own_list;\n", op, pl);
146 1.1 cgd #endif
147 1.1 cgd while (op) {
148 1.1 cgd #ifdef DEBUG
149 1.1 cgd printf("op->sqr->type = %d\n", op->sqr->type);
150 1.1 cgd #endif
151 1.1 cgd switch (op->sqr->type) {
152 1.1 cgd case UTIL:
153 1.1 cgd #ifdef DEBUG
154 1.1 cgd printf(" case UTIL:\n");
155 1.1 cgd #endif
156 1.1 cgd for (num = 0; op && op->sqr->type == UTIL; op = op->next)
157 1.1 cgd num++;
158 1.1 cgd play[pl].num_util = num;
159 1.1 cgd #ifdef DEBUG
160 1.1 cgd printf("play[pl].num_util = num [%d];\n", num);
161 1.1 cgd #endif
162 1.1 cgd break;
163 1.1 cgd case RR:
164 1.1 cgd #ifdef DEBUG
165 1.1 cgd printf(" case RR:\n");
166 1.1 cgd #endif
167 1.1 cgd for (num = 0; op && op->sqr->type == RR; op = op->next) {
168 1.1 cgd #ifdef DEBUG
169 1.1 cgd printf("iter: %d\n", num);
170 1.1 cgd printf("op = %d, op->sqr = %d, op->sqr->type = %d\n", op, op->sqr, op->sqr->type);
171 1.1 cgd #endif
172 1.1 cgd num++;
173 1.1 cgd }
174 1.1 cgd play[pl].num_rr = num;
175 1.1 cgd #ifdef DEBUG
176 1.1 cgd printf("play[pl].num_rr = num [%d];\n", num);
177 1.1 cgd #endif
178 1.1 cgd break;
179 1.1 cgd case PRPTY:
180 1.1 cgd #ifdef DEBUG
181 1.1 cgd printf(" case PRPTY:\n");
182 1.1 cgd #endif
183 1.1 cgd orig = op->sqr->desc->mon_desc;
184 1.1 cgd orig_op = op;
185 1.1 cgd num = 0;
186 1.1 cgd while (op && op->sqr->desc->mon_desc == orig) {
187 1.1 cgd #ifdef DEBUG
188 1.1 cgd printf("iter: %d\n", num);
189 1.1 cgd #endif
190 1.1 cgd num++;
191 1.1 cgd #ifdef DEBUG
192 1.1 cgd printf("op = op->next ");
193 1.1 cgd #endif
194 1.1 cgd op = op->next;
195 1.1 cgd #ifdef DEBUG
196 1.1 cgd printf("[%d];\n", op);
197 1.1 cgd #endif
198 1.1 cgd }
199 1.1 cgd #ifdef DEBUG
200 1.1 cgd printf("num = %d\n");
201 1.1 cgd #endif
202 1.1 cgd if (orig == 0) {
203 1.1 cgd printf("panic: bad monopoly descriptor: orig = %d\n", orig);
204 1.1 cgd printf("player # %d\n", pl+1);
205 1.1 cgd printhold(pl);
206 1.1 cgd printf("orig_op = %d\n", orig_op);
207 1.1 cgd printf("orig_op->sqr->type = %d (PRPTY)\n", op->sqr->type);
208 1.1 cgd printf("orig_op->next = %d\n", op->next);
209 1.1 cgd printf("orig_op->sqr->desc = %d\n", op->sqr->desc);
210 1.1 cgd printf("op = %d\n", op);
211 1.1 cgd printf("op->sqr->type = %d (PRPTY)\n", op->sqr->type);
212 1.1 cgd printf("op->next = %d\n", op->next);
213 1.1 cgd printf("op->sqr->desc = %d\n", op->sqr->desc);
214 1.1 cgd printf("num = %d\n", num);
215 1.1 cgd }
216 1.1 cgd #ifdef DEBUG
217 1.1 cgd printf("orig->num_in = %d\n", orig->num_in);
218 1.1 cgd #endif
219 1.1 cgd if (num == orig->num_in)
220 1.1 cgd is_monop(orig, pl);
221 1.1 cgd else
222 1.1 cgd isnot_monop(orig);
223 1.1 cgd break;
224 1.1 cgd }
225 1.1 cgd }
226 1.1 cgd }
227 1.1 cgd /*
228 1.1 cgd * This routine sets things up as if it is a new monopoly
229 1.1 cgd */
230 1.1 cgd is_monop(mp, pl)
231 1.1 cgd reg MON *mp;
232 1.1 cgd int pl; {
233 1.1 cgd
234 1.1 cgd reg char *sp;
235 1.1 cgd reg int i;
236 1.1 cgd
237 1.1 cgd mp->owner = pl;
238 1.1 cgd mp->num_own = mp->num_in;
239 1.1 cgd for (i = 0; i < mp->num_in; i++)
240 1.1 cgd mp->sq[i]->desc->monop = TRUE;
241 1.1 cgd mp->name = mp->mon_n;
242 1.1 cgd }
243 1.1 cgd /*
244 1.1 cgd * This routine sets things up as if it is no longer a monopoly
245 1.1 cgd */
246 1.1 cgd isnot_monop(mp)
247 1.1 cgd reg MON *mp; {
248 1.1 cgd
249 1.1 cgd reg char *sp;
250 1.1 cgd reg int i;
251 1.1 cgd
252 1.1 cgd mp->owner = -1;
253 1.1 cgd for (i = 0; i < mp->num_in; i++)
254 1.1 cgd mp->sq[i]->desc->monop = FALSE;
255 1.1 cgd mp->name = mp->not_m;
256 1.1 cgd }
257 1.1 cgd /*
258 1.1 cgd * This routine gives a list of the current player's routine
259 1.1 cgd */
260 1.1 cgd list() {
261 1.1 cgd
262 1.1 cgd printhold(player);
263 1.1 cgd }
264 1.1 cgd /*
265 1.1 cgd * This routine gives a list of a given players holdings
266 1.1 cgd */
267 1.1 cgd list_all() {
268 1.1 cgd
269 1.1 cgd reg int pl;
270 1.1 cgd
271 1.1 cgd while ((pl=getinp("Whose holdings do you want to see? ", name_list)) < num_play)
272 1.1 cgd printhold(pl);
273 1.1 cgd }
274 1.1 cgd /*
275 1.1 cgd * This routine gives the players a chance before it exits.
276 1.1 cgd */
277 1.1 cgd void
278 1.1 cgd quit() {
279 1.1 cgd
280 1.1 cgd putchar('\n');
281 1.1 cgd if (getyn("Do you all really want to quit? ", yn) == 0)
282 1.1 cgd exit(0);
283 1.1 cgd signal(SIGINT, quit);
284 1.1 cgd }
285 1.1 cgd /*
286 1.1 cgd * This routine copies one structure to another
287 1.1 cgd */
288 1.1 cgd cpy_st(s1, s2, size)
289 1.1 cgd reg int *s1, *s2, size; {
290 1.1 cgd
291 1.1 cgd size /= 2;
292 1.1 cgd while (size--)
293 1.1 cgd *s1++ = *s2++;
294 1.1 cgd }
295 1.1 cgd /*
296 1.1 cgd * This routine forks off a shell. It uses the users login shell
297 1.1 cgd */
298 1.1 cgd shell_out() {
299 1.1 cgd
300 1.1 cgd static char *shell = NULL;
301 1.1 cgd
302 1.1 cgd printline();
303 1.1 cgd if (shell == NULL)
304 1.1 cgd shell = shell_in();
305 1.1 cgd fflush(stdout);
306 1.1 cgd if (!fork()) {
307 1.1 cgd signal(SIGINT, SIG_DFL);
308 1.1 cgd execsh(shell);
309 1.1 cgd }
310 1.1 cgd ignoresigs();
311 1.1 cgd wait();
312 1.1 cgd resetsigs();
313 1.1 cgd putchar('\n');
314 1.1 cgd printline();
315 1.1 cgd }
316 1.1 cgd /*
317 1.1 cgd * This routine looks up the users login shell
318 1.1 cgd */
319 1.1 cgd # include <sys/types.h>
320 1.1 cgd # include <pwd.h>
321 1.1 cgd
322 1.1 cgd char *getenv();
323 1.1 cgd
324 1.1 cgd char *
325 1.1 cgd shell_in() {
326 1.1 cgd
327 1.1 cgd reg struct passwd *pp;
328 1.1 cgd reg char *sp;
329 1.1 cgd
330 1.1 cgd if ((sp = getenv("SHELL")) == NULL) {
331 1.1 cgd pp = getpwuid(getuid());
332 1.1 cgd if (pp->pw_shell[0] != '\0')
333 1.1 cgd return pp->pw_shell;
334 1.1 cgd else
335 1.1 cgd return shell_def;
336 1.1 cgd /*return (*(pp->pw_shell) != '\0' ? pp->pw_shell : shell_def);*/
337 1.1 cgd }
338 1.1 cgd return sp;
339 1.1 cgd }
340 1.1 cgd /*
341 1.1 cgd * This routine sets things up to ignore all the signals.
342 1.1 cgd */
343 1.1 cgd ignoresigs() {
344 1.1 cgd
345 1.1 cgd reg int i;
346 1.1 cgd
347 1.1 cgd for (i = 0; i < NSIG; i++)
348 1.1 cgd signal(i, SIG_IGN);
349 1.1 cgd }
350 1.1 cgd /*
351 1.1 cgd * This routine sets up things as they were before.
352 1.1 cgd */
353 1.1 cgd resetsigs() {
354 1.1 cgd
355 1.1 cgd reg int i;
356 1.1 cgd
357 1.1 cgd for (i = 0; i < NSIG; i++)
358 1.1 cgd signal(i, SIG_DFL);
359 1.1 cgd signal(SIGINT, quit);
360 1.1 cgd }
361