Annotation of early-roguelike/rogue4/mach_dep.c, Revision 1.1
1.1 ! rubenllo 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 <errno.h>
! 41:
! 42: #ifdef CHECKTIME
! 43: #include <unistd.h>
! 44: #endif
! 45:
! 46: #include "rogue.h"
! 47:
! 48: int num_checks; /* times we've gone over in checkout() */
! 49:
! 50: #ifdef SCOREFILE
! 51: #ifdef LOCKFILE
! 52: static char *lockfile = LOCKFILE;
! 53: #endif
! 54: #endif
! 55:
! 56: int too_much(void);
! 57: bool author(void);
! 58: void checkout(int s);
! 59: void chmsg(char *fmt, int arg);
! 60:
! 61: /*
! 62: * init_check:
! 63: * Check out too see if it is proper to play the game now
! 64: */
! 65: void
! 66: init_check(void)
! 67: {
! 68: if (too_much())
! 69: {
! 70: printf("Sorry, %s, but the system is too loaded now.\n", whoami);
! 71: printf("Try again later. Meanwhile, why not enjoy a%s %s?\n",
! 72: vowelstr(fruit), fruit);
! 73: if (author())
! 74: printf("However, since you're a good guy, it's up to you\n");
! 75: else
! 76: exit(1);
! 77: }
! 78: }
! 79:
! 80: /*
! 81: * open_score:
! 82: * Open up the score file for future use, and then
! 83: * setuid(getuid()) in case we are running setuid.
! 84: */
! 85: void
! 86: open_score(void)
! 87: {
! 88: #ifdef SCOREFILE
! 89: score_file = fopen(SCOREFILE, "r+");
! 90: if ((score_file == NULL) && (errno == ENOENT)) {
! 91: score_file = fopen(SCOREFILE, "w+");
! 92: }
! 93: #else
! 94: score_file = NULL;
! 95: #endif
! 96: if (!use_savedir)
! 97: md_normaluser();
! 98: return;
! 99: }
! 100:
! 101: void
! 102: open_log(void)
! 103: {
! 104: #ifdef LOGFILE
! 105: log_file = fopen(LOGFILE, "a");
! 106: #else
! 107: log_file = NULL;
! 108: #endif
! 109: return;
! 110: }
! 111:
! 112: /*
! 113: * setup:
! 114: * Get starting setup for all games
! 115: */
! 116: void
! 117: setup(void)
! 118: {
! 119: void auto_save(), quit(), endit(), tstp();
! 120:
! 121: /*
! 122: * make sure that large terminals don't overflow the bounds
! 123: * of the program
! 124: */
! 125: if (LINES > MAXLINES)
! 126: LINES = MAXLINES;
! 127: if (COLS > MAXCOLS)
! 128: COLS = MAXCOLS;
! 129:
! 130: #ifdef SIGHUP
! 131: signal(SIGHUP, auto_save);
! 132: #endif
! 133: #ifndef DUMP
! 134: signal(SIGILL, auto_save);
! 135: #ifdef SIGTRAP
! 136: signal(SIGTRAP, auto_save);
! 137: #endif
! 138: #ifdef SIGIOT
! 139: signal(SIGIOT, auto_save);
! 140: #endif
! 141: #ifdef SIGEMT
! 142: signal(SIGEMT, auto_save);
! 143: #endif
! 144: signal(SIGFPE, auto_save);
! 145: #ifdef SIGBUS
! 146: signal(SIGBUS, auto_save);
! 147: #endif
! 148: /* Don't bother saving a game that segfaulted. */
! 149: signal(SIGSEGV, SIG_DFL);
! 150: #ifdef SIGSYS
! 151: signal(SIGSYS, auto_save);
! 152: #endif
! 153: signal(SIGTERM, auto_save);
! 154: #endif
! 155:
! 156: signal(SIGINT, quit);
! 157: #ifndef DUMP
! 158: #ifdef SIGQUIT
! 159: signal(SIGQUIT, endit);
! 160: #endif
! 161: #endif
! 162: #ifdef CHECKTIME
! 163: signal(SIGALRM, checkout);
! 164: alarm(CHECKTIME * 60);
! 165: num_checks = 0;
! 166: #endif
! 167: nonl();
! 168: crmode(); /* Cbreak mode */
! 169: noecho(); /* Echo off */
! 170: }
! 171:
! 172: /*
! 173: * start_score:
! 174: * Start the scoring sequence
! 175: */
! 176: void
! 177: start_score(void)
! 178: {
! 179: #ifdef SIGALRM
! 180: signal(SIGALRM, SIG_IGN);
! 181: #endif
! 182: }
! 183:
! 184: /*
! 185: * issymlink:
! 186: * See if the file has a symbolic link
! 187: */
! 188: bool
! 189: issymlink(char *sp)
! 190: {
! 191: #ifdef S_IFLNK
! 192: struct stat sbuf2;
! 193:
! 194: if (lstat(sp, &sbuf2) < 0)
! 195: return FALSE;
! 196: else
! 197: return ((sbuf2.st_mode & S_IFMT) != S_IFREG);
! 198: #else
! 199: return FALSE;
! 200: #endif
! 201: }
! 202:
! 203: /*
! 204: * too_much:
! 205: * See if the system is being used too much for this game
! 206: */
! 207: int
! 208: too_much(void)
! 209: {
! 210: #ifdef MAXLOAD
! 211: double avec[3];
! 212:
! 213: if (md_getloadavg(avec) == 0)
! 214: if (avec[2] > (MAXLOAD / 10.0))
! 215: return(1);
! 216: #endif
! 217: #ifdef MAXUSERS
! 218: if (md_ucount() > MAXUSERS)
! 219: return(1) ;
! 220: #endif
! 221: return(0);
! 222: }
! 223:
! 224: /*
! 225: * author:
! 226: * See if a user is an author of the program
! 227: */
! 228: bool
! 229: author(void)
! 230: {
! 231: #ifdef WIZARD
! 232: if (wizard)
! 233: return TRUE;
! 234: #endif
! 235: switch (md_getuid())
! 236: {
! 237: case 0:
! 238: return TRUE;
! 239: default:
! 240: return FALSE;
! 241: }
! 242: }
! 243:
! 244: /*
! 245: * checkout:
! 246: * Check each CHECKTIME seconds to see if the load is too high
! 247: */
! 248: void
! 249: checkout(int s)
! 250: {
! 251: static char *msgs[] = {
! 252: "The load is too high to be playing. Please leave in %0.1f minutes",
! 253: "Please save your game. You have %0.1f minutes",
! 254: "Last warning. You have %0.1f minutes to leave",
! 255: };
! 256: int checktime = 0;
! 257:
! 258: #ifdef SIGALRM
! 259: signal(SIGALRM, checkout);
! 260: #endif
! 261:
! 262: if (too_much())
! 263: {
! 264: if (author())
! 265: {
! 266: num_checks = 1;
! 267: chmsg("The load is rather high, O exaulted one", 0);
! 268: }
! 269: else if (num_checks++ == 3)
! 270: fatal("Sorry. You took to long. You are dead\n");
! 271:
! 272: #ifdef CHECKTIME
! 273: checktime = (CHECKTIME * 60) / num_checks;
! 274: #ifdef SIGALRM
! 275: alarm(checktime);
! 276: #endif
! 277: #endif
! 278:
! 279: chmsg(msgs[num_checks - 1], ((double) checktime / 60.0));
! 280: }
! 281: else
! 282: {
! 283: if (num_checks)
! 284: {
! 285: num_checks = 0;
! 286: chmsg("The load has dropped back down. You have a reprieve", 0);
! 287: }
! 288: #ifdef CHECKTIME
! 289: #ifdef SIGALRM
! 290: alarm(CHECKTIME * 60);
! 291: #endif
! 292: #endif
! 293: }
! 294: }
! 295:
! 296: /*
! 297: * chmsg:
! 298: * checkout()'s version of msg. If we are in the middle of a
! 299: * shell, do a printf instead of a msg to avoid the refresh.
! 300: */
! 301: void
! 302: chmsg(char *fmt, int arg)
! 303: {
! 304: if (in_shell)
! 305: {
! 306: printf(fmt, arg);
! 307: putchar('\n');
! 308: fflush(stdout);
! 309: }
! 310: else
! 311: msg(fmt, arg);
! 312: }
! 313:
! 314: /*
! 315: * lock_sc:
! 316: * lock the score file. If it takes too long, ask the user if
! 317: * they care to wait. Return TRUE if the lock is successful.
! 318: */
! 319: bool
! 320: lock_sc(void)
! 321: {
! 322: #ifdef SCOREFILE
! 323: #ifdef LOCKFILE
! 324: register int cnt;
! 325: static struct stat sbuf;
! 326:
! 327: over:
! 328: if (creat(lockfile, 0000) > 0)
! 329: return TRUE;
! 330: for (cnt = 0; cnt < 5; cnt++)
! 331: {
! 332: md_sleep(1);
! 333: if (creat(lockfile, 0000) > 0)
! 334: return TRUE;
! 335: }
! 336: if (stat(lockfile, &sbuf) < 0)
! 337: {
! 338: creat(lockfile, 0000);
! 339: return TRUE;
! 340: }
! 341: if (time(NULL) - sbuf.st_mtime > 10)
! 342: {
! 343: if (md_unlink(lockfile) < 0)
! 344: return FALSE;
! 345: goto over;
! 346: }
! 347: else
! 348: {
! 349: printf("The score file is very busy. Do you want to wait longer\n");
! 350: printf("for it to become free so your score can get posted?\n");
! 351: printf("If so, type \"y\"\n");
! 352: fgets(prbuf, MAXSTR, stdin);
! 353: if (prbuf[0] == 'y')
! 354: for (;;)
! 355: {
! 356: if (creat(lockfile, 0000) > 0)
! 357: return TRUE;
! 358: if (stat(lockfile, &sbuf) < 0)
! 359: {
! 360: creat(lockfile, 0000);
! 361: return TRUE;
! 362: }
! 363: if (time(NULL) - sbuf.st_mtime > 10)
! 364: {
! 365: if (md_unlink(lockfile) < 0)
! 366: return FALSE;
! 367: }
! 368: md_sleep(1);
! 369: }
! 370: else
! 371: return FALSE;
! 372: }
! 373: #endif
! 374: #endif
! 375: return TRUE;
! 376: }
! 377:
! 378: /*
! 379: * unlock_sc:
! 380: * Unlock the score file
! 381: */
! 382: void
! 383: unlock_sc(void)
! 384: {
! 385: #ifdef SCOREFILE
! 386: #ifdef LOCKFILE
! 387: md_unlink(lockfile);
! 388: #endif
! 389: #endif
! 390: }
! 391:
! 392: /*
! 393: * flush_type:
! 394: * Flush typeahead for traps, etc.
! 395: */
! 396: void
! 397: flush_type(void)
! 398: {
! 399: flushinp();
! 400: }
CVSweb