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