Annotation of 43BSD/games/rogue/machdep.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.