Annotation of 43BSDReno/games/hack/hack.main.c, revision 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.