|
|
1.1 ! root 1: /* ! 2: * Various installation dependent routines ! 3: * ! 4: * @(#)find.c 4.37 (Berkeley) 5/23/83 ! 5: */ ! 6: ! 7: /* ! 8: * The various tuneable defines are: ! 9: * ! 10: * SCOREFILE Where/if the score file should live. ! 11: * ALLSCORES Score file is top ten scores, not top ten ! 12: * players. This is only useful when only a few ! 13: * people will be playing; otherwise the score file ! 14: * gets hogged by just a few people. ! 15: * NUMSCORES Number of scores in the score file (default 10). ! 16: * NUMNAME String version of NUMSCORES (first character ! 17: * should be capitalized) (default "Ten"). ! 18: * MAXLOAD What (if any) the maximum load average should be ! 19: * when people are playing. Since it is divided ! 20: * by 10, to specify a load limit of 4.0, MAXLOAD ! 21: * should be "40". If defined, then ! 22: * LOADAV Should it use it's own routine to get ! 23: * the load average? ! 24: * NAMELIST If so, where does the system namelist ! 25: * hide? ! 26: * MAXUSERS What (if any) the maximum user count should be ! 27: * when people are playing. If defined, then ! 28: * UCOUNT Should it use it's own routine to count ! 29: * users? ! 30: * UTMP If so, where does the user list hide? ! 31: * CHECKTIME How often/if it should check during the game ! 32: * for high load average. ! 33: */ ! 34: ! 35: #include <curses.h> ! 36: #include "extern.h" ! 37: #include <signal.h> ! 38: #include <sys/types.h> ! 39: #include <sys/stat.h> ! 40: ! 41: #ifdef SCOREFILE ! 42: ! 43: static char *Lockfile = "/tmp/.fredlock"; ! 44: ! 45: # ifndef NUMSCORES ! 46: # define NUMSCORES 10 ! 47: # define NUMNAME "Ten" ! 48: # endif ! 49: ! 50: unsigned int numscores = NUMSCORES; ! 51: char *Numname = NUMNAME; ! 52: ! 53: # ifdef ALLSCORES ! 54: bool Allscore = TRUE; ! 55: # else ALLSCORES ! 56: bool Allscore = FALSE; ! 57: # endif ALLSCORES ! 58: ! 59: #endif SCOREFILE ! 60: ! 61: #ifdef CHECKTIME ! 62: static int Num_checks; /* times we've gone over in checkout() */ ! 63: #endif CHECKTIME ! 64: ! 65: /* ! 66: * init_check: ! 67: * Check out too see if it is proper to play the game now ! 68: */ ! 69: init_check() ! 70: { ! 71: #if defined(MAXLOAD) || defined(MAXUSERS) ! 72: if (too_much()) ! 73: { ! 74: printf("Sorry, %s, but the system is too loaded now.\n", Whoami); ! 75: printf("Try again later. Meanwhile, why not enjoy a%s %s?\n", ! 76: vowelstr(Fruit), Fruit); ! 77: if (author()) ! 78: printf("However, since you're a good guy, it's up to you\n"); ! 79: else ! 80: exit(1); ! 81: } ! 82: #endif ! 83: } ! 84: ! 85: /* ! 86: * open_score: ! 87: * Open up the score file for future use, and then ! 88: * setuid(getuid()) in case we are running setuid. ! 89: */ ! 90: open_score() ! 91: { ! 92: #ifdef SCOREFILE ! 93: Fd = open(SCOREFILE, 2); ! 94: if (Fd < 0) ! 95: perror(SCOREFILE); ! 96: #else ! 97: Fd = -1; ! 98: #endif ! 99: setuid(getuid()); ! 100: setgid(getgid()); ! 101: } ! 102: ! 103: /* ! 104: * setup: ! 105: * Get starting setup for all games ! 106: */ ! 107: setup() ! 108: { ! 109: int auto_save(), quit(), endit(), tstp(); ! 110: #ifdef CHECKTIME ! 111: int checkout(); ! 112: #endif ! 113: ! 114: signal(SIGHUP, auto_save); ! 115: #ifndef DUMP ! 116: signal(SIGILL, auto_save); ! 117: signal(SIGTRAP, auto_save); ! 118: signal(SIGIOT, auto_save); ! 119: signal(SIGEMT, auto_save); ! 120: signal(SIGFPE, auto_save); ! 121: signal(SIGBUS, auto_save); ! 122: signal(SIGSEGV, auto_save); ! 123: signal(SIGSYS, auto_save); ! 124: signal(SIGTERM, auto_save); ! 125: #endif ! 126: ! 127: signal(SIGINT, quit); ! 128: #ifndef DUMP ! 129: signal(SIGQUIT, endit); ! 130: #endif ! 131: #ifdef CHECKTIME ! 132: signal(SIGALRM, checkout); ! 133: alarm(CHECKTIME * 60); ! 134: Num_checks = 0; ! 135: #endif ! 136: crmode(); /* Cbreak mode */ ! 137: noecho(); /* Echo off */ ! 138: #ifdef TIOCGLTC ! 139: getltchars(); /* get the local tty chars */ ! 140: #endif ! 141: } ! 142: ! 143: /* ! 144: * getltchars: ! 145: * Get the local tty chars for later use ! 146: */ ! 147: getltchars() ! 148: { ! 149: #ifdef TIOCGLTC ! 150: ioctl(1, TIOCGLTC, &Ltc); ! 151: Got_ltc = TRUE; ! 152: Orig_dsusp = Ltc.t_dsuspc; ! 153: Ltc.t_dsuspc = Ltc.t_suspc; ! 154: ioctl(1, TIOCSLTC, &Ltc); ! 155: #endif ! 156: } ! 157: ! 158: /* ! 159: * start_score: ! 160: * Start the scoring sequence ! 161: */ ! 162: start_score() ! 163: { ! 164: #ifdef CHECKTIME ! 165: signal(SIGALRM, SIG_IGN); ! 166: #endif ! 167: } ! 168: ! 169: /* ! 170: * symlink: ! 171: * See if the file has a symbolic link ! 172: */ ! 173: symlink(sp) ! 174: char *sp; ! 175: { ! 176: #ifdef S_IFLNK ! 177: struct stat sbuf2; ! 178: ! 179: if (lstat(sp, &sbuf2) < 0) ! 180: return FALSE; ! 181: else ! 182: return ((sbuf2.st_mode & S_IFMT) != S_IFREG); ! 183: #else ! 184: return FALSE; ! 185: #endif ! 186: } ! 187: ! 188: #if defined(MAXLOAD) || defined(MAXUSERS) ! 189: /* ! 190: * too_much: ! 191: * See if the system is being used too much for this game ! 192: */ ! 193: too_much() ! 194: { ! 195: #ifdef MAXLOAD ! 196: double avec[3]; ! 197: #else ! 198: register int cnt; ! 199: #endif ! 200: ! 201: #ifdef MAXLOAD ! 202: loadav(avec); ! 203: if (avec[1] > (MAXLOAD / 10.0)) ! 204: return TRUE; ! 205: #endif ! 206: #ifdef MAXUSERS ! 207: if (ucount() > MAXUSERS) ! 208: return TRUE; ! 209: #endif ! 210: return FALSE; ! 211: } ! 212: ! 213: /* ! 214: * author: ! 215: * See if a user is an author of the program ! 216: */ ! 217: author() ! 218: { ! 219: #ifdef MASTER ! 220: if (Wizard) ! 221: return TRUE; ! 222: #endif ! 223: switch (getuid()) ! 224: { ! 225: case -1: ! 226: return TRUE; ! 227: default: ! 228: return FALSE; ! 229: } ! 230: } ! 231: #endif ! 232: ! 233: #ifdef CHECKTIME ! 234: /* ! 235: * checkout: ! 236: * Check each CHECKTIME seconds to see if the load is too high ! 237: */ ! 238: checkout() ! 239: { ! 240: static char *msgs[] = { ! 241: "The load is too high to be playing. Please leave in %0.1f minutes", ! 242: "Please save your game. You have %0.1f minutes", ! 243: "Last warning. You have %0.1f minutes to leave", ! 244: }; ! 245: int checktime; ! 246: ! 247: signal(SIGALRM, checkout); ! 248: if (too_much()) ! 249: { ! 250: if (author()) ! 251: { ! 252: Num_checks = 1; ! 253: chmsg("The load is rather high, O exaulted one"); ! 254: } ! 255: else if (Num_checks++ == 3) ! 256: fatal("Sorry. You took too long. You are dead\n"); ! 257: checktime = (CHECKTIME * 60) / Num_checks; ! 258: alarm(checktime); ! 259: chmsg(msgs[Num_checks - 1], ((double) checktime / 60.0)); ! 260: } ! 261: else ! 262: { ! 263: if (Num_checks) ! 264: { ! 265: Num_checks = 0; ! 266: chmsg("The load has dropped back down. You have a reprieve"); ! 267: } ! 268: alarm(CHECKTIME * 60); ! 269: } ! 270: } ! 271: ! 272: /* ! 273: * chmsg: ! 274: * checkout()'s version of msg. If we are in the middle of a ! 275: * shell, do a printf instead of a msg to avoid the refresh. ! 276: */ ! 277: /* VARARGS1 */ ! 278: chmsg(fmt, arg) ! 279: char *fmt; ! 280: int arg; ! 281: { ! 282: if (!In_shell) ! 283: msg(fmt, arg); ! 284: else ! 285: { ! 286: printf(fmt, arg); ! 287: putchar('\n'); ! 288: fflush(stdout); ! 289: } ! 290: } ! 291: #endif ! 292: ! 293: #ifdef LOADAV ! 294: /* ! 295: * loadav: ! 296: * Looking up load average in core (for system where the loadav() ! 297: * system call isn't defined ! 298: */ ! 299: ! 300: #include <nlist.h> ! 301: ! 302: struct nlist avenrun = { ! 303: "_avenrun" ! 304: }; ! 305: ! 306: loadav(avg) ! 307: register double *avg; ! 308: { ! 309: register int kmem; ! 310: ! 311: if ((kmem = open("/dev/kmem", 0)) < 0) ! 312: goto bad; ! 313: nlist(NAMELIST, &avenrun); ! 314: if (avenrun.n_type == 0) ! 315: { ! 316: close(kmem); ! 317: bad: ! 318: avg[0] = 0.0; ! 319: avg[1] = 0.0; ! 320: avg[2] = 0.0; ! 321: return; ! 322: } ! 323: ! 324: lseek(kmem, (long) avenrun.n_value, 0); ! 325: read(kmem, (char *) avg, 3 * sizeof (double)); ! 326: close(kmem); ! 327: } ! 328: #endif ! 329: ! 330: #ifdef UCOUNT ! 331: /* ! 332: * ucount: ! 333: * Count number of users on the system ! 334: */ ! 335: #include <utmp.h> ! 336: ! 337: struct utmp buf; ! 338: ! 339: ucount() ! 340: { ! 341: register struct utmp *up; ! 342: register FILE *utmp; ! 343: register int count; ! 344: ! 345: if ((utmp = fopen(UTMP, "r")) == NULL) ! 346: return 0; ! 347: ! 348: up = &buf; ! 349: count = 0; ! 350: ! 351: while (fread(up, 1, sizeof (*up), utmp) > 0) ! 352: if (buf.ut_name[0] != '\0') ! 353: count++; ! 354: fclose(utmp); ! 355: return count; ! 356: } ! 357: #endif ! 358: ! 359: /* ! 360: * lock_sc: ! 361: * lock the score file. If it takes too long, ask the user if ! 362: * they care to wait. Return TRUE if the lock is successful. ! 363: */ ! 364: lock_sc() ! 365: { ! 366: #ifdef SCOREFILE ! 367: register int cnt; ! 368: static struct stat sbuf; ! 369: time_t time(); ! 370: ! 371: over: ! 372: close(8); /* just in case there are no files left */ ! 373: if (creat(Lockfile, 0000) >= 0) ! 374: return TRUE; ! 375: for (cnt = 0; cnt < 5; cnt++) ! 376: { ! 377: sleep(1); ! 378: if (creat(Lockfile, 0000) >= 0) ! 379: return TRUE; ! 380: } ! 381: if (stat(Lockfile, &sbuf) < 0) ! 382: { ! 383: creat(Lockfile, 0000); ! 384: return TRUE; ! 385: } ! 386: if (time(NULL) - sbuf.st_mtime > 10) ! 387: { ! 388: if (unlink(Lockfile) < 0) ! 389: return FALSE; ! 390: goto over; ! 391: } ! 392: else ! 393: { ! 394: printf("The score file is very busy. Do you want to wait longer\n"); ! 395: printf("for it to become free so your score can get posted?\n"); ! 396: printf("If so, type \"y\"\n"); ! 397: fgets(Prbuf, MAXSTR, stdin); ! 398: if (Prbuf[0] == 'y') ! 399: for (;;) ! 400: { ! 401: if (creat(Lockfile, 0000) >= 0) ! 402: return TRUE; ! 403: if (stat(Lockfile, &sbuf) < 0) ! 404: { ! 405: creat(Lockfile, 0000); ! 406: return TRUE; ! 407: } ! 408: if (time(NULL) - sbuf.st_mtime > 10) ! 409: { ! 410: if (unlink(Lockfile) < 0) ! 411: return FALSE; ! 412: } ! 413: sleep(1); ! 414: } ! 415: else ! 416: return FALSE; ! 417: } ! 418: #endif ! 419: } ! 420: ! 421: /* ! 422: * unlock_sc: ! 423: * Unlock the score file ! 424: */ ! 425: unlock_sc() ! 426: { ! 427: #ifdef SCOREFILE ! 428: unlink(Lockfile); ! 429: #endif ! 430: } ! 431: ! 432: /* ! 433: * flush_type: ! 434: * Flush typeahead for traps, etc. ! 435: */ ! 436: flush_type() ! 437: { ! 438: crmode(); ! 439: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.