misc.c revision 1.1 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.1 cgd static char sccsid[] = "@(#)misc.c 5.5 (Berkeley) 2/28/91";
36 1.1 cgd #endif /* not lint */
37 1.1 cgd
38 1.1 cgd # include "monop.ext"
39 1.1 cgd # include <ctype.h>
40 1.1 cgd # include <signal.h>
41 1.1 cgd
42 1.1 cgd # define execsh(sh) execl(sh, shell_name[roll(1, num_names)-1], 0)
43 1.1 cgd
44 1.1 cgd static char *shell_def = "/bin/csh",
45 1.1 cgd *shell_name[] = {
46 1.1 cgd ".Hi Mom!",
47 1.1 cgd ".Kick Me",
48 1.1 cgd ".I'm really the next process down",
49 1.1 cgd ".Hi Kids!",
50 1.1 cgd ".This space for rent",
51 1.1 cgd ".Singin' in the rain....",
52 1.1 cgd ".I am but a Cog in the Wheel of Life",
53 1.1 cgd ".Look out!!! Behind you!!!!!",
54 1.1 cgd ".Looking for a good time, sailor?",
55 1.1 cgd ".I don't get NO respect...",
56 1.1 cgd ".Augghh! You peeked!"
57 1.1 cgd };
58 1.1 cgd
59 1.1 cgd static int num_names = sizeof shell_name / sizeof (char *);;
60 1.1 cgd
61 1.1 cgd char *shell_in();
62 1.1 cgd
63 1.1 cgd /*
64 1.1 cgd * This routine executes a truncated set of commands until a
65 1.1 cgd * "yes or "no" answer is gotten.
66 1.1 cgd */
67 1.1 cgd getyn(prompt)
68 1.1 cgd reg char *prompt; {
69 1.1 cgd
70 1.1 cgd reg int com;
71 1.1 cgd
72 1.1 cgd for (;;)
73 1.1 cgd if ((com=getinp(prompt, yn)) < 2)
74 1.1 cgd return com;
75 1.1 cgd else
76 1.1 cgd (*func[com-2])();
77 1.1 cgd }
78 1.1 cgd /*
79 1.1 cgd * This routine tells the player if he's out of money.
80 1.1 cgd */
81 1.1 cgd notify() {
82 1.1 cgd
83 1.1 cgd if (cur_p->money < 0)
84 1.1 cgd printf("That leaves you $%d in debt\n", -cur_p->money);
85 1.1 cgd else if (cur_p->money == 0)
86 1.1 cgd printf("that leaves you broke\n");
87 1.1 cgd else if (fixing && !told_em && cur_p->money > 0) {
88 1.1 cgd printf("-- You are now Solvent ---\n");
89 1.1 cgd told_em = TRUE;
90 1.1 cgd }
91 1.1 cgd }
92 1.1 cgd /*
93 1.1 cgd * This routine switches to the next player
94 1.1 cgd */
95 1.1 cgd next_play() {
96 1.1 cgd
97 1.1 cgd player = ++player % num_play;
98 1.1 cgd cur_p = &play[player];
99 1.1 cgd num_doub = 0;
100 1.1 cgd }
101 1.1 cgd /*
102 1.1 cgd * This routine gets an integer from the keyboard after the
103 1.1 cgd * given prompt.
104 1.1 cgd */
105 1.1 cgd get_int(prompt)
106 1.1 cgd reg char *prompt; {
107 1.1 cgd
108 1.1 cgd reg int num;
109 1.1 cgd reg char *sp;
110 1.1 cgd char buf[257];
111 1.1 cgd
112 1.1 cgd for (;;) {
113 1.1 cgd inter:
114 1.1 cgd printf(prompt);
115 1.1 cgd num = 0;
116 1.1 cgd for (sp = buf; (*sp=getchar()) != '\n'; sp++)
117 1.1 cgd if (*sp == -1) /* check for interrupted system call */
118 1.1 cgd goto inter;
119 1.1 cgd if (sp == buf)
120 1.1 cgd continue;
121 1.1 cgd for (sp = buf; isspace(*sp); sp++)
122 1.1 cgd continue;
123 1.1 cgd for (; isdigit(*sp); sp++)
124 1.1 cgd num = num * 10 + *sp - '0';
125 1.1 cgd if (*sp == '\n')
126 1.1 cgd return num;
127 1.1 cgd else
128 1.1 cgd printf("I can't understand that\n");
129 1.1 cgd }
130 1.1 cgd }
131 1.1 cgd /*
132 1.1 cgd * This routine sets the monopoly flag from the list given.
133 1.1 cgd */
134 1.1 cgd set_ownlist(pl)
135 1.1 cgd int pl; {
136 1.1 cgd
137 1.1 cgd reg int num; /* general counter */
138 1.1 cgd reg MON *orig; /* remember starting monop ptr */
139 1.1 cgd reg OWN *op; /* current owned prop */
140 1.1 cgd OWN *orig_op; /* origianl prop before loop */
141 1.1 cgd
142 1.1 cgd op = play[pl].own_list;
143 1.1 cgd #ifdef DEBUG
144 1.1 cgd printf("op [%d] = play[pl [%d] ].own_list;\n", op, pl);
145 1.1 cgd #endif
146 1.1 cgd while (op) {
147 1.1 cgd #ifdef DEBUG
148 1.1 cgd printf("op->sqr->type = %d\n", op->sqr->type);
149 1.1 cgd #endif
150 1.1 cgd switch (op->sqr->type) {
151 1.1 cgd case UTIL:
152 1.1 cgd #ifdef DEBUG
153 1.1 cgd printf(" case UTIL:\n");
154 1.1 cgd #endif
155 1.1 cgd for (num = 0; op && op->sqr->type == UTIL; op = op->next)
156 1.1 cgd num++;
157 1.1 cgd play[pl].num_util = num;
158 1.1 cgd #ifdef DEBUG
159 1.1 cgd printf("play[pl].num_util = num [%d];\n", num);
160 1.1 cgd #endif
161 1.1 cgd break;
162 1.1 cgd case RR:
163 1.1 cgd #ifdef DEBUG
164 1.1 cgd printf(" case RR:\n");
165 1.1 cgd #endif
166 1.1 cgd for (num = 0; op && op->sqr->type == RR; op = op->next) {
167 1.1 cgd #ifdef DEBUG
168 1.1 cgd printf("iter: %d\n", num);
169 1.1 cgd printf("op = %d, op->sqr = %d, op->sqr->type = %d\n", op, op->sqr, op->sqr->type);
170 1.1 cgd #endif
171 1.1 cgd num++;
172 1.1 cgd }
173 1.1 cgd play[pl].num_rr = num;
174 1.1 cgd #ifdef DEBUG
175 1.1 cgd printf("play[pl].num_rr = num [%d];\n", num);
176 1.1 cgd #endif
177 1.1 cgd break;
178 1.1 cgd case PRPTY:
179 1.1 cgd #ifdef DEBUG
180 1.1 cgd printf(" case PRPTY:\n");
181 1.1 cgd #endif
182 1.1 cgd orig = op->sqr->desc->mon_desc;
183 1.1 cgd orig_op = op;
184 1.1 cgd num = 0;
185 1.1 cgd while (op && op->sqr->desc->mon_desc == orig) {
186 1.1 cgd #ifdef DEBUG
187 1.1 cgd printf("iter: %d\n", num);
188 1.1 cgd #endif
189 1.1 cgd num++;
190 1.1 cgd #ifdef DEBUG
191 1.1 cgd printf("op = op->next ");
192 1.1 cgd #endif
193 1.1 cgd op = op->next;
194 1.1 cgd #ifdef DEBUG
195 1.1 cgd printf("[%d];\n", op);
196 1.1 cgd #endif
197 1.1 cgd }
198 1.1 cgd #ifdef DEBUG
199 1.1 cgd printf("num = %d\n");
200 1.1 cgd #endif
201 1.1 cgd if (orig == 0) {
202 1.1 cgd printf("panic: bad monopoly descriptor: orig = %d\n", orig);
203 1.1 cgd printf("player # %d\n", pl+1);
204 1.1 cgd printhold(pl);
205 1.1 cgd printf("orig_op = %d\n", orig_op);
206 1.1 cgd printf("orig_op->sqr->type = %d (PRPTY)\n", op->sqr->type);
207 1.1 cgd printf("orig_op->next = %d\n", op->next);
208 1.1 cgd printf("orig_op->sqr->desc = %d\n", op->sqr->desc);
209 1.1 cgd printf("op = %d\n", op);
210 1.1 cgd printf("op->sqr->type = %d (PRPTY)\n", op->sqr->type);
211 1.1 cgd printf("op->next = %d\n", op->next);
212 1.1 cgd printf("op->sqr->desc = %d\n", op->sqr->desc);
213 1.1 cgd printf("num = %d\n", num);
214 1.1 cgd }
215 1.1 cgd #ifdef DEBUG
216 1.1 cgd printf("orig->num_in = %d\n", orig->num_in);
217 1.1 cgd #endif
218 1.1 cgd if (num == orig->num_in)
219 1.1 cgd is_monop(orig, pl);
220 1.1 cgd else
221 1.1 cgd isnot_monop(orig);
222 1.1 cgd break;
223 1.1 cgd }
224 1.1 cgd }
225 1.1 cgd }
226 1.1 cgd /*
227 1.1 cgd * This routine sets things up as if it is a new monopoly
228 1.1 cgd */
229 1.1 cgd is_monop(mp, pl)
230 1.1 cgd reg MON *mp;
231 1.1 cgd int pl; {
232 1.1 cgd
233 1.1 cgd reg char *sp;
234 1.1 cgd reg int i;
235 1.1 cgd
236 1.1 cgd mp->owner = pl;
237 1.1 cgd mp->num_own = mp->num_in;
238 1.1 cgd for (i = 0; i < mp->num_in; i++)
239 1.1 cgd mp->sq[i]->desc->monop = TRUE;
240 1.1 cgd mp->name = mp->mon_n;
241 1.1 cgd }
242 1.1 cgd /*
243 1.1 cgd * This routine sets things up as if it is no longer a monopoly
244 1.1 cgd */
245 1.1 cgd isnot_monop(mp)
246 1.1 cgd reg MON *mp; {
247 1.1 cgd
248 1.1 cgd reg char *sp;
249 1.1 cgd reg int i;
250 1.1 cgd
251 1.1 cgd mp->owner = -1;
252 1.1 cgd for (i = 0; i < mp->num_in; i++)
253 1.1 cgd mp->sq[i]->desc->monop = FALSE;
254 1.1 cgd mp->name = mp->not_m;
255 1.1 cgd }
256 1.1 cgd /*
257 1.1 cgd * This routine gives a list of the current player's routine
258 1.1 cgd */
259 1.1 cgd list() {
260 1.1 cgd
261 1.1 cgd printhold(player);
262 1.1 cgd }
263 1.1 cgd /*
264 1.1 cgd * This routine gives a list of a given players holdings
265 1.1 cgd */
266 1.1 cgd list_all() {
267 1.1 cgd
268 1.1 cgd reg int pl;
269 1.1 cgd
270 1.1 cgd while ((pl=getinp("Whose holdings do you want to see? ", name_list)) < num_play)
271 1.1 cgd printhold(pl);
272 1.1 cgd }
273 1.1 cgd /*
274 1.1 cgd * This routine gives the players a chance before it exits.
275 1.1 cgd */
276 1.1 cgd void
277 1.1 cgd quit() {
278 1.1 cgd
279 1.1 cgd putchar('\n');
280 1.1 cgd if (getyn("Do you all really want to quit? ", yn) == 0)
281 1.1 cgd exit(0);
282 1.1 cgd signal(SIGINT, quit);
283 1.1 cgd }
284 1.1 cgd /*
285 1.1 cgd * This routine copies one structure to another
286 1.1 cgd */
287 1.1 cgd cpy_st(s1, s2, size)
288 1.1 cgd reg int *s1, *s2, size; {
289 1.1 cgd
290 1.1 cgd size /= 2;
291 1.1 cgd while (size--)
292 1.1 cgd *s1++ = *s2++;
293 1.1 cgd }
294 1.1 cgd /*
295 1.1 cgd * This routine forks off a shell. It uses the users login shell
296 1.1 cgd */
297 1.1 cgd shell_out() {
298 1.1 cgd
299 1.1 cgd static char *shell = NULL;
300 1.1 cgd
301 1.1 cgd printline();
302 1.1 cgd if (shell == NULL)
303 1.1 cgd shell = shell_in();
304 1.1 cgd fflush(stdout);
305 1.1 cgd if (!fork()) {
306 1.1 cgd signal(SIGINT, SIG_DFL);
307 1.1 cgd execsh(shell);
308 1.1 cgd }
309 1.1 cgd ignoresigs();
310 1.1 cgd wait();
311 1.1 cgd resetsigs();
312 1.1 cgd putchar('\n');
313 1.1 cgd printline();
314 1.1 cgd }
315 1.1 cgd /*
316 1.1 cgd * This routine looks up the users login shell
317 1.1 cgd */
318 1.1 cgd # include <sys/types.h>
319 1.1 cgd # include <pwd.h>
320 1.1 cgd
321 1.1 cgd char *getenv();
322 1.1 cgd
323 1.1 cgd char *
324 1.1 cgd shell_in() {
325 1.1 cgd
326 1.1 cgd reg struct passwd *pp;
327 1.1 cgd reg char *sp;
328 1.1 cgd
329 1.1 cgd if ((sp = getenv("SHELL")) == NULL) {
330 1.1 cgd pp = getpwuid(getuid());
331 1.1 cgd if (pp->pw_shell[0] != '\0')
332 1.1 cgd return pp->pw_shell;
333 1.1 cgd else
334 1.1 cgd return shell_def;
335 1.1 cgd /*return (*(pp->pw_shell) != '\0' ? pp->pw_shell : shell_def);*/
336 1.1 cgd }
337 1.1 cgd return sp;
338 1.1 cgd }
339 1.1 cgd /*
340 1.1 cgd * This routine sets things up to ignore all the signals.
341 1.1 cgd */
342 1.1 cgd ignoresigs() {
343 1.1 cgd
344 1.1 cgd reg int i;
345 1.1 cgd
346 1.1 cgd for (i = 0; i < NSIG; i++)
347 1.1 cgd signal(i, SIG_IGN);
348 1.1 cgd }
349 1.1 cgd /*
350 1.1 cgd * This routine sets up things as they were before.
351 1.1 cgd */
352 1.1 cgd resetsigs() {
353 1.1 cgd
354 1.1 cgd reg int i;
355 1.1 cgd
356 1.1 cgd for (i = 0; i < NSIG; i++)
357 1.1 cgd signal(i, SIG_DFL);
358 1.1 cgd signal(SIGINT, quit);
359 1.1 cgd }
360