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