[BACK]Return to mach_dep.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / rogue5

Annotation of early-roguelike/rogue5/mach_dep.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:  * Various installation dependent routines
                      3:  *
                      4:  * @(#)mach_dep.c      4.37 (Berkeley) 05/23/83
                      5:  *
                      6:  * Rogue: Exploring the Dungeons of Doom
                      7:  * Copyright (C) 1980-1983, 1985, 1999 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:  *     ALLSCORES       Score file is top ten scores, not top ten
                     18:  *                     players.  This is only useful when only a few
                     19:  *                     people will be playing; otherwise the score file
                     20:  *                     gets hogged by just a few people.
                     21:  *     NUMSCORES       Number of scores in the score file (default 10).
                     22:  *     NUMNAME         String version of NUMSCORES (first character
                     23:  *                     should be capitalized) (default "Ten").
                     24:  *     MAXLOAD         What (if any) the maximum load average should be
                     25:  *                     when people are playing.  Since it is divided
                     26:  *                     by 10, to specify a load limit of 4.0, MAXLOAD
                     27:  *                     should be "40".  If defined, then
                     28:  *      LOADAV         Should it use it's own routine to get
                     29:  *                     the load average?
                     30:  *      NAMELIST       If so, where does the system namelist
                     31:  *                     hide?
                     32:  *     MAXUSERS        What (if any) the maximum user count should be
                     33:  *                     when people are playing.  If defined, then
                     34:  *      UCOUNT         Should it use it's own routine to count
                     35:  *                     users?
                     36:  *      UTMP           If so, where does the user list hide?
                     37:  *     CHECKTIME       How often/if it should check during the game
                     38:  *                     for high load average.
                     39:  */
                     40:
                     41: #include <signal.h>
                     42: #include <sys/types.h>
                     43: #include <sys/stat.h>
                     44: #include <limits.h>
                     45: #include <string.h>
                     46: #include <fcntl.h>
                     47: #include <errno.h>
                     48: #include <time.h>
                     49: #include <curses.h>
                     50: #include "extern.h"
                     51:
                     52: #define NOOP(x) (x += 0)
                     53:
                     54: # ifndef NUMSCORES
                     55: #      define  NUMSCORES       10
                     56: #      define  NUMNAME         "Ten"
                     57: # endif
                     58:
                     59: #ifdef CHECKTIME
                     60: static int num_checks = 0;             /* times we've gone over in checkout() */
                     61: #endif /* CHECKTIME */
                     62:
                     63: /*
                     64:  * init_check:
                     65:  *     Check out too see if it is proper to play the game now
                     66:  */
                     67:
                     68: void
                     69: init_check(void)
                     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
                     88:  */
                     89:
                     90: void
                     91: open_score(void)
                     92: {
                     93: #ifdef SCOREFILE
                     94:     char *scorefile = SCOREFILE;
                     95:
                     96:     numscores = NUMSCORES;
                     97:     Numname = NUMNAME;
                     98:
                     99: #ifdef ALLSCORES
                    100:     allscore = TRUE;
                    101: #else  /* ALLSCORES */
                    102:     allscore = FALSE;
                    103: #endif /* ALLSCORES */
                    104:
                    105:      /*
                    106:       * We drop setgid privileges after opening the score file, so subsequent
                    107:       * open()'s will fail.  Just reuse the earlier filehandle.
                    108:       */
                    109:
                    110:     if (scoreboard != NULL) {
                    111:         rewind(scoreboard);
                    112:         return;
                    113:     }
                    114:
                    115:     scoreboard = fopen(scorefile, "r+");
                    116:
                    117:     if ((scoreboard == NULL) && (errno == ENOENT))
                    118:     {
                    119:        scoreboard = fopen(scorefile, "w+");
                    120:         md_chmod(scorefile,0664);
                    121:     }
                    122:
                    123:     if (scoreboard == NULL) {
                    124:          fprintf(stderr, "Could not open %s for writing: %s\n", scorefile, strerror(errno));
                    125:          fflush(stderr);
                    126:     }
                    127: #else
                    128:     scoreboard = NULL;
                    129: #endif
                    130: }
                    131:
                    132: void
                    133: open_log(void)
                    134: {
                    135: #ifdef LOGFILE
                    136:     logfi = fopen(LOGFILE, "a");
                    137:     if (logfi == NULL)
                    138:     {
                    139:         fprintf(stderr, "Could not open %s for appending: %s\n", LOGFILE,
                    140:                 strerror(errno));
                    141:         fflush(stderr);
                    142:     }
                    143: #endif
                    144:     return;
                    145: }
                    146:
                    147: /*
                    148:  * getltchars:
                    149:  *     Get the local tty chars for later use
                    150:  */
                    151:
                    152: void
                    153: getltchars(void)
                    154: {
                    155:     got_ltc = TRUE;
                    156:     orig_dsusp = md_dsuspchar();
                    157:     md_setdsuspchar( md_suspchar() );
                    158: }
                    159:
                    160: /*
                    161:  * setup:
                    162:  *     Get starting setup for all games
                    163:  */
                    164:
                    165: void
                    166: setup(void)
                    167: {
                    168: #ifndef DUMP
                    169:     md_onsignal_autosave();
                    170: #else
                    171:     md_onsignal_default();
                    172: #endif
                    173:
                    174: #ifdef CHECKTIME
                    175:     md_start_checkout_timer(CHECKTIME*60);
                    176:     num_checks = 0;
                    177: #endif
                    178:
                    179:     raw();                             /* Raw mode */
                    180:     noecho();                          /* Echo off */
                    181:     nonl();
                    182:     keypad(stdscr,1);
                    183:     getltchars();                      /* get the local tty chars */
                    184: }
                    185:
                    186: /*
                    187:  * resetltchars:
                    188:  *      Reset the local tty chars to original values.
                    189:  */
                    190: void
                    191: resetltchars(void)
                    192: {
                    193:     if (got_ltc) {
                    194:         md_setdsuspchar(orig_dsusp);
                    195:     }
                    196: }
                    197:
                    198: /*
                    199:  * playltchars:
                    200:  *      Set local tty chars to the values we use when playing.
                    201:  */
                    202: void
                    203: playltchars(void)
                    204: {
                    205:     if (got_ltc) {
                    206:         md_setdsuspchar( md_suspchar() );
                    207:     }
                    208: }
                    209:
                    210: /*
                    211:  * start_score:
                    212:  *     Start the scoring sequence
                    213:  */
                    214:
                    215: void
                    216: start_score(void)
                    217: {
                    218: #ifdef CHECKTIME
                    219:     md_stop_checkout_timer();
                    220: #endif
                    221: }
                    222:
                    223: /*
                    224:  * is_symlink:
                    225:  *      See if the file has a symbolic link
                    226:   */
                    227: int
                    228: is_symlink(char *sp)
                    229: {
                    230: #ifdef S_IFLNK
                    231:     struct stat sbuf2;
                    232:
                    233:     if (lstat(sp, &sbuf2) < 0)
                    234:         return FALSE;
                    235:     else
                    236:         return ((sbuf2.st_mode & S_IFMT) != S_IFREG);
                    237: #else
                    238:        NOOP(sp);
                    239:     return FALSE;
                    240: #endif
                    241: }
                    242:
                    243: #if defined(MAXLOAD) || defined(MAXUSERS)
                    244: /*
                    245:  * too_much:
                    246:  *     See if the system is being used too much for this game
                    247:  */
                    248: int
                    249: too_much(void)
                    250: {
                    251: #ifdef MAXLOAD
                    252:     double avec[3];
                    253: #else
                    254:     int cnt;
                    255: #endif
                    256:
                    257: #ifdef MAXLOAD
                    258:     md_loadav(avec);
                    259:     if (avec[1] > (MAXLOAD / 10.0))
                    260:        return TRUE;
                    261: #endif
                    262: #ifdef MAXUSERS
                    263:     if (ucount() > MAXUSERS)
                    264:        return TRUE;
                    265: #endif
                    266:     return FALSE;
                    267: }
                    268:
                    269: /*
                    270:  * author:
                    271:  *     See if a user is an author of the program
                    272:  */
                    273: int
                    274: author(void)
                    275: {
                    276: #ifdef MASTER
                    277:     if (wizard)
                    278:        return TRUE;
                    279: #endif
                    280:     switch (md_getuid())
                    281:     {
                    282:        case -1:
                    283:            return TRUE;
                    284:        default:
                    285:            return FALSE;
                    286:     }
                    287: }
                    288: #endif
                    289:
                    290: #ifdef CHECKTIME
                    291: /*
                    292:  * checkout:
                    293:  *     Check each CHECKTIME seconds to see if the load is too high
                    294:  */
                    295:
                    296: checkout(int sig)
                    297: {
                    298:     char *msgs[] = {
                    299:        "The load is too high to be playing.  Please leave in %0.1f minutes",
                    300:        "Please save your game.  You have %0.1f minutes",
                    301:        "Last warning.  You have %0.1f minutes to leave",
                    302:     };
                    303:     int checktime;
                    304:
                    305:     if (too_much())
                    306:     {
                    307:        if (author())
                    308:        {
                    309:            num_checks = 1;
                    310:            chmsg("The load is rather high, O exaulted one");
                    311:        }
                    312:        else if (num_checks++ == 3)
                    313:            fatal("Sorry.  You took too long.  You are dead\n");
                    314:        checktime = (CHECKTIME * 60) / num_checks;
                    315:        chmsg(msgs[num_checks - 1], ((double) checktime / 60.0));
                    316:     }
                    317:     else
                    318:     {
                    319:        if (num_checks)
                    320:        {
                    321:            num_checks = 0;
                    322:            chmsg("The load has dropped back down.  You have a reprieve");
                    323:        }
                    324:        checktime = (CHECKTIME * 60);
                    325:     }
                    326:
                    327:        md_start_checkout_timer(checktime);
                    328: }
                    329:
                    330: /*
                    331:  * chmsg:
                    332:  *     checkout()'s version of msg.  If we are in the middle of a
                    333:  *     shell, do a printf instead of a msg to a the refresh.
                    334:  */
                    335: /* VARARGS1 */
                    336:
                    337: chmsg(char *fmt, int arg)
                    338: {
                    339:     if (!in_shell)
                    340:        msg(fmt, arg);
                    341:     else
                    342:     {
                    343:        printf(fmt, arg);
                    344:        putchar('\n');
                    345:        fflush(stdout);
                    346:     }
                    347: }
                    348: #endif
                    349:
                    350: #ifdef UCOUNT
                    351: /*
                    352:  * ucount:
                    353:  *     count number of users on the system
                    354:  */
                    355: #include <utmp.h>
                    356:
                    357: struct utmp buf;
                    358:
                    359: int
                    360: ucount(void)
                    361: {
                    362:     struct utmp *up;
                    363:     FILE *utmp;
                    364:     int count;
                    365:
                    366:     if ((utmp = fopen(UTMP, "r")) == NULL)
                    367:        return 0;
                    368:
                    369:     up = &buf;
                    370:     count = 0;
                    371:
                    372:     while (fread(up, 1, sizeof (*up), utmp) > 0)
                    373:        if (buf.ut_name[0] != '\0')
                    374:            count++;
                    375:     fclose(utmp);
                    376:     return count;
                    377: }
                    378: #endif
                    379:
                    380: /*
                    381:  * lock_sc:
                    382:  *     lock the score file.  If it takes too long, ask the user if
                    383:  *     they care to wait.  Return TRUE if the lock is successful.
                    384:  */
                    385: static FILE *lfd = NULL;
                    386: int
                    387: lock_sc(void)
                    388: {
                    389: #if defined(SCOREFILE) && defined(LOCKFILE)
                    390:     int cnt;
                    391:     struct stat sbuf;
                    392:     char *lockfile = LOCKFILE;
                    393:
                    394: over:
                    395:     if ((lfd=fopen(lockfile, "w+")) != NULL)
                    396:        return TRUE;
                    397:     for (cnt = 0; cnt < 5; cnt++)
                    398:     {
                    399:        md_sleep(1);
                    400:        if ((lfd=fopen(lockfile, "w+")) != NULL)
                    401:            return TRUE;
                    402:     }
                    403:     if (stat(lockfile, &sbuf) < 0)
                    404:     {
                    405:        lfd=fopen(lockfile, "w+");
                    406:        return TRUE;
                    407:     }
                    408:     if (time(NULL) - sbuf.st_mtime > 10)
                    409:     {
                    410:        if (md_unlink(lockfile) < 0)
                    411:            return FALSE;
                    412:        goto over;
                    413:     }
                    414:     else
                    415:     {
                    416:        printf("The score file is very busy.  Do you want to wait longer\n");
                    417:        printf("for it to become free so your score can get posted?\n");
                    418:        printf("If so, type \"y\"\n");
                    419:        (void) fgets(prbuf, MAXSTR, stdin);
                    420:        if (prbuf[0] == 'y')
                    421:            for (;;)
                    422:            {
                    423:                if ((lfd=fopen(lockfile, "w+")) != 0)
                    424:                    return TRUE;
                    425:                if (stat(lockfile, &sbuf) < 0)
                    426:                {
                    427:                    lfd=fopen(lockfile, "w+");
                    428:                    return TRUE;
                    429:                }
                    430:                if (time(NULL) - sbuf.st_mtime > 10)
                    431:                {
                    432:                    if (md_unlink(lockfile) < 0)
                    433:                        return FALSE;
                    434:                }
                    435:                md_sleep(1);
                    436:            }
                    437:        else
                    438:            return FALSE;
                    439:     }
                    440: #else
                    441:     return TRUE;
                    442: #endif
                    443: }
                    444:
                    445: /*
                    446:  * unlock_sc:
                    447:  *     Unlock the score file
                    448:  */
                    449:
                    450: void
                    451: unlock_sc(void)
                    452: {
                    453: #if defined(SCOREFILE) && defined(LOCKFILE)
                    454:     if (lfd != NULL)
                    455:         fclose(lfd);
                    456:     lfd = NULL;
                    457:     md_unlink(LOCKFILE);
                    458: #endif
                    459: }
                    460:
                    461: /*
                    462:  * flush_type:
                    463:  *     Flush typeahead for traps, etc.
                    464:  */
                    465:
                    466: void
                    467: flush_type(void)
                    468: {
                    469:     flushinp();
                    470: }

CVSweb