Mercurial > hg > early-roguelike
comparison rogue4/mach_dep.c @ 12:9535a08ddc39
Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
| author | edwarj4 |
|---|---|
| date | Sat, 24 Oct 2009 16:52:52 +0000 |
| parents | |
| children | 63b9fd7d70ce |
comparison
equal
deleted
inserted
replaced
| 11:949d558c2162 | 12:9535a08ddc39 |
|---|---|
| 1 /* | |
| 2 * Various installation dependent routines | |
| 3 * | |
| 4 * @(#)mach_dep.c 4.23 (Berkeley) 5/19/82 | |
| 5 * | |
| 6 * Rogue: Exploring the Dungeons of Doom | |
| 7 * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman | |
| 8 * All rights reserved. | |
| 9 * | |
| 10 * See the file LICENSE.TXT for full copyright and licensing information. | |
| 11 */ | |
| 12 | |
| 13 /* | |
| 14 * The various tuneable defines are: | |
| 15 * | |
| 16 * SCOREFILE Where/if the score file should live. | |
| 17 * MAXLOAD What (if any) the maximum load average should be | |
| 18 * when people are playing. If defined, then | |
| 19 * LOADAV Should rogue define it's own routine to | |
| 20 * get the load average? | |
| 21 * NAMELIST If so, where does the system namelist hide? | |
| 22 * MAXUSERS What (if any) the maximum user count should be | |
| 23 * when people are playing. If defined, then | |
| 24 * UCOUNT Should rogue define it's own routine to | |
| 25 * count users? | |
| 26 * UTMP If so, where does the user list hide? | |
| 27 * CHECKTIME How often/if rogue should check during the game | |
| 28 * for high load average. | |
| 29 */ | |
| 30 | |
| 31 #include <limits.h> | |
| 32 #include <stdlib.h> | |
| 33 #include <stdio.h> | |
| 34 #include <curses.h> | |
| 35 #include <time.h> | |
| 36 #include <signal.h> | |
| 37 #include <sys/stat.h> | |
| 38 #include <fcntl.h> | |
| 39 #include <string.h> | |
| 40 #include "rogue.h" | |
| 41 | |
| 42 int num_checks; /* times we've gone over in checkout() */ | |
| 43 | |
| 44 #ifdef SCOREFILE | |
| 45 #ifdef LOCKFILE | |
| 46 static char *lockfile = LOCKFILE; | |
| 47 #endif | |
| 48 #endif | |
| 49 | |
| 50 /* | |
| 51 * init_check: | |
| 52 * Check out too see if it is proper to play the game now | |
| 53 */ | |
| 54 init_check() | |
| 55 { | |
| 56 if (too_much()) | |
| 57 { | |
| 58 printf("Sorry, %s, but the system is too loaded now.\n", whoami); | |
| 59 printf("Try again later. Meanwhile, why not enjoy a%s %s?\n", | |
| 60 vowelstr(fruit), fruit); | |
| 61 if (author()) | |
| 62 printf("However, since you're a good guy, it's up to you\n"); | |
| 63 else | |
| 64 exit(1); | |
| 65 } | |
| 66 } | |
| 67 | |
| 68 /* | |
| 69 * open_score: | |
| 70 * Open up the score file for future use, and then | |
| 71 * setuid(getuid()) in case we are running setuid. | |
| 72 */ | |
| 73 open_score() | |
| 74 { | |
| 75 #ifdef SCOREFILE | |
| 76 fd = open(SCOREFILE, O_RDWR | O_CREAT, 0666 ); | |
| 77 #else | |
| 78 fd = -1; | |
| 79 #endif | |
| 80 md_normaluser(); | |
| 81 } | |
| 82 | |
| 83 /* | |
| 84 * setup: | |
| 85 * Get starting setup for all games | |
| 86 */ | |
| 87 setup() | |
| 88 { | |
| 89 void auto_save(), quit(), endit(), tstp(); | |
| 90 #ifdef CHECKTIME | |
| 91 int checkout(); | |
| 92 #endif | |
| 93 | |
| 94 /* | |
| 95 * make sure that large terminals don't overflow the bounds | |
| 96 * of the program | |
| 97 */ | |
| 98 if (LINES > MAXLINES) | |
| 99 LINES = MAXLINES; | |
| 100 if (COLS > MAXCOLS) | |
| 101 COLS = MAXCOLS; | |
| 102 | |
| 103 #ifdef SIGHUP | |
| 104 signal(SIGHUP, auto_save); | |
| 105 #endif | |
| 106 #ifndef DUMP | |
| 107 signal(SIGILL, auto_save); | |
| 108 #ifdef SIGTRAP | |
| 109 signal(SIGTRAP, auto_save); | |
| 110 #endif | |
| 111 #ifdef SIGIOT | |
| 112 signal(SIGIOT, auto_save); | |
| 113 #endif | |
| 114 #ifdef SIGEMT | |
| 115 signal(SIGEMT, auto_save); | |
| 116 #endif | |
| 117 signal(SIGFPE, auto_save); | |
| 118 #ifdef SIGBUS | |
| 119 signal(SIGBUS, auto_save); | |
| 120 #endif | |
| 121 signal(SIGSEGV, auto_save); | |
| 122 #ifdef SIGSYS | |
| 123 signal(SIGSYS, auto_save); | |
| 124 #endif | |
| 125 signal(SIGTERM, auto_save); | |
| 126 #endif | |
| 127 | |
| 128 signal(SIGINT, quit); | |
| 129 #ifndef DUMP | |
| 130 #ifdef SIGQUIT | |
| 131 signal(SIGQUIT, endit); | |
| 132 #endif | |
| 133 #endif | |
| 134 #ifdef CHECKTIME | |
| 135 signal(SIGALRM, checkout); | |
| 136 alarm(CHECKTIME * 60); | |
| 137 num_checks = 0; | |
| 138 #endif | |
| 139 crmode(); /* Cbreak mode */ | |
| 140 noecho(); /* Echo off */ | |
| 141 } | |
| 142 | |
| 143 /* | |
| 144 * start_score: | |
| 145 * Start the scoring sequence | |
| 146 */ | |
| 147 start_score() | |
| 148 { | |
| 149 #ifdef SIGALRM | |
| 150 signal(SIGALRM, SIG_IGN); | |
| 151 #endif | |
| 152 } | |
| 153 | |
| 154 /* | |
| 155 * issymlink: | |
| 156 * See if the file has a symbolic link | |
| 157 */ | |
| 158 issymlink(sp) | |
| 159 char *sp; | |
| 160 { | |
| 161 #ifdef S_IFLNK | |
| 162 struct stat sbuf2; | |
| 163 | |
| 164 if (lstat(sp, &sbuf2) < 0) | |
| 165 return FALSE; | |
| 166 else | |
| 167 return ((sbuf2.st_mode & S_IFMT) != S_IFREG); | |
| 168 #else | |
| 169 return FALSE; | |
| 170 #endif | |
| 171 } | |
| 172 | |
| 173 /* | |
| 174 * too_much: | |
| 175 * See if the system is being used too much for this game | |
| 176 */ | |
| 177 too_much() | |
| 178 { | |
| 179 #ifdef MAXLOAD | |
| 180 double avec[3]; | |
| 181 | |
| 182 if (md_getloadavg(avec) == 0) | |
| 183 if (avec[2] > (MAXLOAD / 10.0)) | |
| 184 return(1); | |
| 185 #endif | |
| 186 #ifdef MAXUSERS | |
| 187 if (md_ucount() > MAXUSERS) | |
| 188 return(1) ; | |
| 189 #endif | |
| 190 return(0); | |
| 191 } | |
| 192 | |
| 193 /* | |
| 194 * author: | |
| 195 * See if a user is an author of the program | |
| 196 */ | |
| 197 author() | |
| 198 { | |
| 199 #ifdef WIZARD | |
| 200 if (wizard) | |
| 201 return TRUE; | |
| 202 #endif | |
| 203 switch (md_getuid()) | |
| 204 { | |
| 205 case 0: | |
| 206 return TRUE; | |
| 207 default: | |
| 208 return FALSE; | |
| 209 } | |
| 210 } | |
| 211 | |
| 212 /* | |
| 213 * checkout: | |
| 214 * Check each CHECKTIME seconds to see if the load is too high | |
| 215 */ | |
| 216 void | |
| 217 checkout(int s) | |
| 218 { | |
| 219 static char *msgs[] = { | |
| 220 "The load is too high to be playing. Please leave in %0.1f minutes", | |
| 221 "Please save your game. You have %0.1f minutes", | |
| 222 "Last warning. You have %0.1f minutes to leave", | |
| 223 }; | |
| 224 int checktime = 0; | |
| 225 | |
| 226 #ifdef SIGALRM | |
| 227 signal(SIGALRM, checkout); | |
| 228 #endif | |
| 229 | |
| 230 if (too_much()) | |
| 231 { | |
| 232 if (author()) | |
| 233 { | |
| 234 num_checks = 1; | |
| 235 chmsg("The load is rather high, O exaulted one"); | |
| 236 } | |
| 237 else if (num_checks++ == 3) | |
| 238 fatal("Sorry. You took to long. You are dead\n"); | |
| 239 | |
| 240 #ifdef CHECKTIME | |
| 241 checktime = (CHECKTIME * 60) / num_checks; | |
| 242 #endif | |
| 243 #ifdef SIGALRM | |
| 244 alarm(checktime); | |
| 245 #endif | |
| 246 | |
| 247 chmsg(msgs[num_checks - 1], ((double) checktime / 60.0)); | |
| 248 } | |
| 249 else | |
| 250 { | |
| 251 if (num_checks) | |
| 252 { | |
| 253 num_checks = 0; | |
| 254 chmsg("The load has dropped back down. You have a reprieve"); | |
| 255 } | |
| 256 #ifdef CHECKTIME | |
| 257 #ifdef SIGALRM | |
| 258 alarm(CHECKTIME * 60); | |
| 259 #endif | |
| 260 #endif | |
| 261 } | |
| 262 } | |
| 263 | |
| 264 /* | |
| 265 * chmsg: | |
| 266 * checkout()'s version of msg. If we are in the middle of a | |
| 267 * shell, do a printf instead of a msg to avoid the refresh. | |
| 268 */ | |
| 269 chmsg(fmt, arg) | |
| 270 char *fmt; | |
| 271 int arg; | |
| 272 { | |
| 273 if (in_shell) | |
| 274 { | |
| 275 printf(fmt, arg); | |
| 276 putchar('\n'); | |
| 277 fflush(stdout); | |
| 278 } | |
| 279 else | |
| 280 msg(fmt, arg); | |
| 281 } | |
| 282 | |
| 283 /* | |
| 284 * lock_sc: | |
| 285 * lock the score file. If it takes too long, ask the user if | |
| 286 * they care to wait. Return TRUE if the lock is successful. | |
| 287 */ | |
| 288 lock_sc() | |
| 289 { | |
| 290 #ifdef SCOREFILE | |
| 291 #ifdef LOCKFILE | |
| 292 register int cnt; | |
| 293 static struct stat sbuf; | |
| 294 | |
| 295 over: | |
| 296 if (creat(lockfile, 0000) > 0) | |
| 297 return TRUE; | |
| 298 for (cnt = 0; cnt < 5; cnt++) | |
| 299 { | |
| 300 md_sleep(1); | |
| 301 if (creat(lockfile, 0000) > 0) | |
| 302 return TRUE; | |
| 303 } | |
| 304 if (stat(lockfile, &sbuf) < 0) | |
| 305 { | |
| 306 creat(lockfile, 0000); | |
| 307 return TRUE; | |
| 308 } | |
| 309 if (time(NULL) - sbuf.st_mtime > 10) | |
| 310 { | |
| 311 if (md_unlink(lockfile) < 0) | |
| 312 return FALSE; | |
| 313 goto over; | |
| 314 } | |
| 315 else | |
| 316 { | |
| 317 printf("The score file is very busy. Do you want to wait longer\n"); | |
| 318 printf("for it to become free so your score can get posted?\n"); | |
| 319 printf("If so, type \"y\"\n"); | |
| 320 fgets(prbuf, MAXSTR, stdin); | |
| 321 if (prbuf[0] == 'y') | |
| 322 for (;;) | |
| 323 { | |
| 324 if (creat(lockfile, 0000) > 0) | |
| 325 return TRUE; | |
| 326 if (stat(lockfile, &sbuf) < 0) | |
| 327 { | |
| 328 creat(lockfile, 0000); | |
| 329 return TRUE; | |
| 330 } | |
| 331 if (time(NULL) - sbuf.st_mtime > 10) | |
| 332 { | |
| 333 if (md_unlink(lockfile) < 0) | |
| 334 return FALSE; | |
| 335 } | |
| 336 md_sleep(1); | |
| 337 } | |
| 338 else | |
| 339 return FALSE; | |
| 340 } | |
| 341 #endif | |
| 342 #endif | |
| 343 } | |
| 344 | |
| 345 /* | |
| 346 * unlock_sc: | |
| 347 * Unlock the score file | |
| 348 */ | |
| 349 unlock_sc() | |
| 350 { | |
| 351 #ifdef SCOREFILE | |
| 352 #ifdef LOCKFILE | |
| 353 md_unlink(lockfile); | |
| 354 #endif | |
| 355 #endif | |
| 356 } | |
| 357 | |
| 358 /* | |
| 359 * flush_type: | |
| 360 * Flush typeahead for traps, etc. | |
| 361 */ | |
| 362 flush_type() | |
| 363 { | |
| 364 flushinp(); | |
| 365 } |
