# 2.11BSD#431 - /usr/src/games/hack/hack.main.c

##### Functions

    askname           X
    glo               X
    impossible        X
    main              X
    stop_occupation   X

##### Variables

    SAVEF             X
    catmore           X
    hackpid           X
    hname             X
    locknum           X
    obuf              X
    occtxt            X

##### Macros

    gamename          X

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

#### Defined functions

askname defined in line 420; used 3 times

- in line 191, 437
- in /usr/src/games/hack/hack.u_init.c line 342

chdirx defined in line 449; used 2 times

- in line 102, 131

glo defined in line 404; used 10 times

- in /usr/src/games/hack/hack.do.c line 132, 164
- in /usr/src/games/hack/hack.end.c line 470
- in /usr/src/games/hack/hack.save.c line 68, 83-85(2), 130
- in /usr/src/games/hack/hack.unix.c line 172-175(2), 212

impossible defined in line 441; used 32 times

- in /usr/src/games/hack/hack.do_wear.c line 243
- in /usr/src/games/hack/hack.engrave.c line 96, 301
- in /usr/src/games/hack/hack.mklev.c line 329
- in /usr/src/games/hack/hack.potion.c line 172
- in /usr/src/games/hack/hack.pri.c line 59, 160-165(2)
- in /usr/src/games/hack/hack.read.c line 424
- in /usr/src/games/hack/hack.save.c line 194, 234
- in /usr/src/games/hack/hack.shk.c line 276, 395, 430, 436, 535-542(3), 642, 654
- in /usr/src/games/hack/hack.steal.c line 86, 129, 135
- in /usr/src/games/hack/hack.trap.c line 133, 222, 358
- in /usr/src/games/hack/hack.vault.c line 102, 169
- in /usr/src/games/hack/hack.worn.c line 33-37(2)
- in /usr/src/games/hack/hack.zap.c line 67, 116

main defined in line 37; never used
stop_occupation defined in line 493; used 4 times

- in line 370
- in /usr/src/games/hack/hack.mhitu.c line 361
- in /usr/src/games/hack/hack.steal.c line 103
- in /usr/src/games/hack/hack.zap.c line 506

#### Defined variables

SAVEF defined in line 30; used 10 times

- in line 241-244(4)
- in /usr/src/games/hack/hack.lev.c line 269
- in /usr/src/games/hack/hack.save.c line 39-41(2), 72, 110, 139

catmore defined in line 28; used 3 times

- in line 180-181(3)

hackpid defined in line 25; used 3 times

- in line 47
- in /usr/src/games/hack/hack.lev.c line 37(2)

hname defined in line 31; used 2 times

- in line 46, 125

locknum defined in line 26; used 5 times

- in line 174-177(4), 204

obuf defined in line 32; used 1 times

- in line 113

occtxt defined in line 20; used 5 times

- in line 496
- in /usr/src/games/hack/hack.apply.c line 425, 443
- in /usr/src/games/hack/hack.eat.c line 156
- in /usr/src/games/hack/hack.invent.c line 812

#### Defined macros

gamename defined in line 13; used 2 times

- in line 250, 281

Last modified: 1997-10-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1695 |