Annotation of 43BSDReno/games/hack/hack.main.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
                      2: /* hack.main.c - version 1.0.3 */
                      3: 
                      4: #include <stdio.h>
                      5: #include <signal.h>
                      6: #include "hack.h"
                      7: 
                      8: #ifdef QUEST
                      9: #define        gamename        "quest"
                     10: #else
                     11: #define        gamename        "hack"
                     12: #endif QUEST
                     13: 
                     14: extern char *getlogin(), *getenv();
                     15: extern char plname[PL_NSIZ], pl_character[PL_CSIZ];
                     16: extern struct permonst mons[CMNUM+2];
                     17: extern char genocided[], fut_geno[];
                     18: 
                     19: int (*afternmv)();
                     20: int (*occupation)();
                     21: char *occtxt;                  /* defined when occupation != NULL */
                     22: 
                     23: int done1();
                     24: int hangup();
                     25: 
                     26: int hackpid;                           /* current pid */
                     27: int locknum;                           /* max num of players */
                     28: #ifdef DEF_PAGER
                     29: char *catmore;                         /* default pager */
                     30: #endif DEF_PAGER
                     31: char SAVEF[PL_NSIZ + 11] = "save/";    /* save/99999player */
                     32: char *hname;           /* name of the game (argv[0] of call) */
                     33: char obuf[BUFSIZ];     /* BUFSIZ is defined in stdio.h */
                     34: 
                     35: extern char *nomovemsg;
                     36: extern long wailmsg;
                     37: 
                     38: main(argc,argv)
                     39: int argc;
                     40: char *argv[];
                     41: {
                     42:        register int fd;
                     43: #ifdef CHDIR
                     44:        register char *dir;
                     45: #endif CHDIR
                     46: 
                     47:        hname = argv[0];
                     48:        hackpid = getpid();
                     49: 
                     50: #ifdef CHDIR                   /* otherwise no chdir() */
                     51:        /*
                     52:         * See if we must change directory to the playground.
                     53:         * (Perhaps hack runs suid and playground is inaccessible
                     54:         *  for the player.)
                     55:         * The environment variable HACKDIR is overridden by a
                     56:         *  -d command line option (must be the first option given)
                     57:         */
                     58: 
                     59:        dir = getenv("HACKDIR");
                     60:        if(argc > 1 && !strncmp(argv[1], "-d", 2)) {
                     61:                argc--;
                     62:                argv++;
                     63:                dir = argv[0]+2;
                     64:                if(*dir == '=' || *dir == ':') dir++;
                     65:                if(!*dir && argc > 1) {
                     66:                        argc--;
                     67:                        argv++;
                     68:                        dir = argv[0];
                     69:                }
                     70:                if(!*dir)
                     71:                    error("Flag -d must be followed by a directory name.");
                     72:        }
                     73: #endif CHDIR
                     74: 
                     75:        /*
                     76:         * Who am i? Algorithm: 1. Use name as specified in HACKOPTIONS
                     77:         *                      2. Use $USER or $LOGNAME        (if 1. fails)
                     78:         *                      3. Use getlogin()               (if 2. fails)
                     79:         * The resulting name is overridden by command line options.
                     80:         * If everything fails, or if the resulting name is some generic
                     81:         * account like "games", "play", "player", "hack" then eventually
                     82:         * we'll ask him.
                     83:         * Note that we trust him here; it is possible to play under
                     84:         * somebody else's name.
                     85:         */
                     86:        { register char *s;
                     87: 
                     88:          initoptions();
                     89:          if(!*plname && (s = getenv("USER")))
                     90:                (void) strncpy(plname, s, sizeof(plname)-1);
                     91:          if(!*plname && (s = getenv("LOGNAME")))
                     92:                (void) strncpy(plname, s, sizeof(plname)-1);
                     93:          if(!*plname && (s = getlogin()))
                     94:                (void) strncpy(plname, s, sizeof(plname)-1);
                     95:        }
                     96: 
                     97:        /*
                     98:         * Now we know the directory containing 'record' and
                     99:         * may do a prscore().
                    100:         */
                    101:        if(argc > 1 && !strncmp(argv[1], "-s", 2)) {
                    102: #ifdef CHDIR
                    103:                chdirx(dir,0);
                    104: #endif CHDIR
                    105:                prscore(argc, argv);
                    106:                exit(0);
                    107:        }
                    108: 
                    109:        /*
                    110:         * It seems he really wants to play.
                    111:         * Remember tty modes, to be restored on exit.
                    112:         */
                    113:        gettty();
                    114:        setbuf(stdout,obuf);
                    115:        setrandom();
                    116:        startup();
                    117:        cls();
                    118:        u.uhp = 1;      /* prevent RIP on early quits */
                    119:        u.ux = FAR;     /* prevent nscr() */
                    120:        (void) signal(SIGHUP, hangup);
                    121: 
                    122:        /*
                    123:         * Find the creation date of this game,
                    124:         * so as to avoid restoring outdated savefiles.
                    125:         */
                    126:        gethdate(hname);
                    127: 
                    128:        /*
                    129:         * We cannot do chdir earlier, otherwise gethdate will fail.
                    130:         */
                    131: #ifdef CHDIR
                    132:        chdirx(dir,1);
                    133: #endif CHDIR
                    134: 
                    135:        /*
                    136:         * Process options.
                    137:         */
                    138:        while(argc > 1 && argv[1][0] == '-'){
                    139:                argv++;
                    140:                argc--;
                    141:                switch(argv[0][1]){
                    142: #ifdef WIZARD
                    143:                case 'D':
                    144: /*                     if(!strcmp(getlogin(), WIZARD)) */
                    145:                                wizard = TRUE;
                    146: /*                     else
                    147:                                printf("Sorry.\n"); */
                    148:                        break;
                    149: #endif WIZARD
                    150: #ifdef NEWS
                    151:                case 'n':
                    152:                        flags.nonews = TRUE;
                    153:                        break;
                    154: #endif NEWS
                    155:                case 'u':
                    156:                        if(argv[0][2])
                    157:                          (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
                    158:                        else if(argc > 1) {
                    159:                          argc--;
                    160:                          argv++;
                    161:                          (void) strncpy(plname, argv[0], sizeof(plname)-1);
                    162:                        } else
                    163:                                printf("Player name expected after -u\n");
                    164:                        break;
                    165:                default:
                    166:                        /* allow -T for Tourist, etc. */
                    167:                        (void) strncpy(pl_character, argv[0]+1,
                    168:                                sizeof(pl_character)-1);
                    169: 
                    170:                        /* printf("Unknown option: %s\n", *argv); */
                    171:                }
                    172:        }
                    173: 
                    174:        if(argc > 1)
                    175:                locknum = atoi(argv[1]);
                    176: #ifdef MAX_NR_OF_PLAYERS
                    177:        if(!locknum || locknum > MAX_NR_OF_PLAYERS)
                    178:                locknum = MAX_NR_OF_PLAYERS;
                    179: #endif MAX_NR_OF_PLAYERS
                    180: #ifdef DEF_PAGER
                    181:        if(!(catmore = getenv("HACKPAGER")) && !(catmore = getenv("PAGER")))
                    182:                catmore = DEF_PAGER;
                    183: #endif DEF_PAGER
                    184: #ifdef MAIL
                    185:        getmailstatus();
                    186: #endif MAIL
                    187: #ifdef WIZARD
                    188:        if(wizard) (void) strcpy(plname, "wizard"); else
                    189: #endif WIZARD
                    190:        if(!*plname || !strncmp(plname, "player", 4)
                    191:                    || !strncmp(plname, "games", 4))
                    192:                askname();
                    193:        plnamesuffix();         /* strip suffix from name; calls askname() */
                    194:                                /* again if suffix was whole name */
                    195:                                /* accepts any suffix */
                    196: #ifdef WIZARD
                    197:        if(!wizard) {
                    198: #endif WIZARD
                    199:                /*
                    200:                 * check for multiple games under the same name
                    201:                 * (if !locknum) or check max nr of players (otherwise)
                    202:                 */
                    203:                (void) signal(SIGQUIT,SIG_IGN);
                    204:                (void) signal(SIGINT,SIG_IGN);
                    205:                if(!locknum)
                    206:                        (void) strcpy(lock,plname);
                    207:                getlock();      /* sets lock if locknum != 0 */
                    208: #ifdef WIZARD
                    209:        } else {
                    210:                register char *sfoo;
                    211:                (void) strcpy(lock,plname);
                    212:                if(sfoo = getenv("MAGIC"))
                    213:                        while(*sfoo) {
                    214:                                switch(*sfoo++) {
                    215:                                case 'n': (void) srandom(*sfoo++);
                    216:                                        break;
                    217:                                }
                    218:                        }
                    219:                if(sfoo = getenv("GENOCIDED")){
                    220:                        if(*sfoo == '!'){
                    221:                                register struct permonst *pm = mons;
                    222:                                register char *gp = genocided;
                    223: 
                    224:                                while(pm < mons+CMNUM+2){
                    225:                                        if(!index(sfoo, pm->mlet))
                    226:                                                *gp++ = pm->mlet;
                    227:                                        pm++;
                    228:                                }
                    229:                                *gp = 0;
                    230:                        } else
                    231:                                (void) strcpy(genocided, sfoo);
                    232:                        (void) strcpy(fut_geno, genocided);
                    233:                }
                    234:        }
                    235: #endif WIZARD
                    236:        setftty();
                    237:        (void) sprintf(SAVEF, "save/%d%s", getuid(), plname);
                    238:        regularize(SAVEF+5);            /* avoid . or / in name */
                    239:        if((fd = open(SAVEF,0)) >= 0 &&
                    240:           (uptodate(fd) || unlink(SAVEF) == 666)) {
                    241:                (void) signal(SIGINT,done1);
                    242:                pline("Restoring old save file...");
                    243:                (void) fflush(stdout);
                    244:                if(!dorecover(fd))
                    245:                        goto not_recovered;
                    246:                pline("Hello %s, welcome to %s!", plname, gamename);
                    247:                flags.move = 0;
                    248:        } else {
                    249: not_recovered:
                    250:                fobj = fcobj = invent = 0;
                    251:                fmon = fallen_down = 0;
                    252:                ftrap = 0;
                    253:                fgold = 0;
                    254:                flags.ident = 1;
                    255:                init_objects();
                    256:                u_init();
                    257: 
                    258:                (void) signal(SIGINT,done1);
                    259:                mklev();
                    260:                u.ux = xupstair;
                    261:                u.uy = yupstair;
                    262:                (void) inshop();
                    263:                setsee();
                    264:                flags.botlx = 1;
                    265:                makedog();
                    266:                { register struct monst *mtmp;
                    267:                  if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp);     /* riv05!a3 */
                    268:                }
                    269:                seemons();
                    270: #ifdef NEWS
                    271:                if(flags.nonews || !readnews())
                    272:                        /* after reading news we did docrt() already */
                    273: #endif NEWS
                    274:                        docrt();
                    275: 
                    276:                /* give welcome message before pickup messages */
                    277:                pline("Hello %s, welcome to %s!", plname, gamename);
                    278: 
                    279:                pickup(1);
                    280:                read_engr_at(u.ux,u.uy);
                    281:                flags.move = 1;
                    282:        }
                    283: 
                    284:        flags.moonphase = phase_of_the_moon();
                    285:        if(flags.moonphase == FULL_MOON) {
                    286:                pline("You are lucky! Full moon tonight.");
                    287:                u.uluck++;
                    288:        } else if(flags.moonphase == NEW_MOON) {
                    289:                pline("Be careful! New moon tonight.");
                    290:        }
                    291: 
                    292:        initrack();
                    293: 
                    294:        for(;;) {
                    295:                if(flags.move) {        /* actual time passed */
                    296: 
                    297:                        settrack();
                    298: 
                    299:                        if(moves%2 == 0 ||
                    300:                          (!(Fast & ~INTRINSIC) && (!Fast || rn2(3)))) {
                    301:                                extern struct monst *makemon();
                    302:                                movemon();
                    303:                                if(!rn2(70))
                    304:                                    (void) makemon((struct permonst *)0, 0, 0);
                    305:                        }
                    306:                        if(Glib) glibr();
                    307:                        timeout();
                    308:                        ++moves;
                    309:                        if(flags.time) flags.botl = 1;
                    310:                        if(u.uhp < 1) {
                    311:                                pline("You die...");
                    312:                                done("died");
                    313:                        }
                    314:                        if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50){
                    315:                            wailmsg = moves;
                    316:                            if(u.uhp == 1)
                    317:                            pline("You hear the wailing of the Banshee...");
                    318:                            else
                    319:                            pline("You hear the howling of the CwnAnnwn...");
                    320:                        }
                    321:                        if(u.uhp < u.uhpmax) {
                    322:                                if(u.ulevel > 9) {
                    323:                                        if(Regeneration || !(moves%3)) {
                    324:                                            flags.botl = 1;
                    325:                                            u.uhp += rnd((int) u.ulevel-9);
                    326:                                            if(u.uhp > u.uhpmax)
                    327:                                                u.uhp = u.uhpmax;
                    328:                                        }
                    329:                                } else if(Regeneration ||
                    330:                                        (!(moves%(22-u.ulevel*2)))) {
                    331:                                        flags.botl = 1;
                    332:                                        u.uhp++;
                    333:                                }
                    334:                        }
                    335:                        if(Teleportation && !rn2(85)) tele();
                    336:                        if(Searching && multi >= 0) (void) dosearch();
                    337:                        gethungry();
                    338:                        invault();
                    339:                        amulet();
                    340:                }
                    341:                if(multi < 0) {
                    342:                        if(!++multi){
                    343:                                pline(nomovemsg ? nomovemsg :
                    344:                                        "You can move again.");
                    345:                                nomovemsg = 0;
                    346:                                if(afternmv) (*afternmv)();
                    347:                                afternmv = 0;
                    348:                        }
                    349:                }
                    350: 
                    351:                find_ac();
                    352: #ifndef QUEST
                    353:                if(!flags.mv || Blind)
                    354: #endif QUEST
                    355:                {
                    356:                        seeobjs();
                    357:                        seemons();
                    358:                        nscr();
                    359:                }
                    360:                if(flags.botl || flags.botlx) bot();
                    361: 
                    362:                flags.move = 1;
                    363: 
                    364:                if(multi >= 0 && occupation) {
                    365:                        if(monster_nearby())
                    366:                                stop_occupation();
                    367:                        else if ((*occupation)() == 0)
                    368:                                occupation = 0;
                    369:                        continue;
                    370:                }
                    371: 
                    372:                if(multi > 0) {
                    373: #ifdef QUEST
                    374:                        if(flags.run >= 4) finddir();
                    375: #endif QUEST
                    376:                        lookaround();
                    377:                        if(!multi) {    /* lookaround may clear multi */
                    378:                                flags.move = 0;
                    379:                                continue;
                    380:                        }
                    381:                        if(flags.mv) {
                    382:                                if(multi < COLNO && !--multi)
                    383:                                        flags.mv = flags.run = 0;
                    384:                                domove();
                    385:                        } else {
                    386:                                --multi;
                    387:                                rhack(save_cm);
                    388:                        }
                    389:                } else if(multi == 0) {
                    390: #ifdef MAIL
                    391:                        ckmailstatus();
                    392: #endif MAIL
                    393:                        rhack((char *) 0);
                    394:                }
                    395:                if(multi && multi%7 == 0)
                    396:                        (void) fflush(stdout);
                    397:        }
                    398: }
                    399: 
                    400: glo(foo)
                    401: register foo;
                    402: {
                    403:        /* construct the string  xlock.n  */
                    404:        register char *tf;
                    405: 
                    406:        tf = lock;
                    407:        while(*tf && *tf != '.') tf++;
                    408:        (void) sprintf(tf, ".%d", foo);
                    409: }
                    410: 
                    411: /*
                    412:  * plname is filled either by an option (-u Player  or  -uPlayer) or
                    413:  * explicitly (-w implies wizard) or by askname.
                    414:  * It may still contain a suffix denoting pl_character.
                    415:  */
                    416: askname(){
                    417: register int c,ct;
                    418:        printf("\nWho are you? ");
                    419:        (void) fflush(stdout);
                    420:        ct = 0;
                    421:        while((c = getchar()) != '\n'){
                    422:                if(c == EOF) error("End of input\n");
                    423:                /* some people get confused when their erase char is not ^H */
                    424:                if(c == '\010') {
                    425:                        if(ct) ct--;
                    426:                        continue;
                    427:                }
                    428:                if(c != '-')
                    429:                if(c < 'A' || (c > 'Z' && c < 'a') || c > 'z') c = '_';
                    430:                if(ct < sizeof(plname)-1) plname[ct++] = c;
                    431:        }
                    432:        plname[ct] = 0;
                    433:        if(ct == 0) askname();
                    434: }
                    435: 
                    436: /*VARARGS1*/
                    437: impossible(s,x1,x2)
                    438: register char *s;
                    439: {
                    440:        pline(s,x1,x2);
                    441:        pline("Program in disorder - perhaps you'd better Quit.");
                    442: }
                    443: 
                    444: #ifdef CHDIR
                    445: static
                    446: chdirx(dir, wr)
                    447: char *dir;
                    448: boolean wr;
                    449: {
                    450: 
                    451: #ifdef SECURE
                    452:        if(dir                                  /* User specified directory? */
                    453: #ifdef HACKDIR
                    454:               && strcmp(dir, HACKDIR)          /* and not the default? */
                    455: #endif HACKDIR
                    456:                ) {
                    457:                (void) setuid(getuid());                /* Ron Wessels */
                    458:                (void) setgid(getgid());
                    459:        }
                    460: #endif SECURE
                    461: 
                    462: #ifdef HACKDIR
                    463:        if(dir == NULL)
                    464:                dir = HACKDIR;
                    465: #endif HACKDIR
                    466: 
                    467:        if(dir && chdir(dir) < 0) {
                    468:                perror(dir);
                    469:                error("Cannot chdir to %s.", dir);
                    470:        }
                    471: 
                    472:        /* warn the player if he cannot write the record file */
                    473:        /* perhaps we should also test whether . is writable */
                    474:        /* unfortunately the access systemcall is worthless */
                    475:        if(wr) {
                    476:            register fd;
                    477: 
                    478:            if(dir == NULL)
                    479:                dir = ".";
                    480:            if((fd = open(RECORD, 2)) < 0) {
                    481:                printf("Warning: cannot write %s/%s", dir, RECORD);
                    482:                getret();
                    483:            } else
                    484:                (void) close(fd);
                    485:        }
                    486: }
                    487: #endif CHDIR
                    488: 
                    489: stop_occupation()
                    490: {
                    491:        if(occupation) {
                    492:                pline("You stop %s.", occtxt);
                    493:                occupation = 0;
                    494:        }
                    495: }

unix.superglobalmegacorp.com

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