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