Annotation of 43BSD/games/rogue/machdep.c, revision 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.