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

unix.superglobalmegacorp.com

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