1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64: #include <sys/cdefs.h>
65: #ifndef lint
66: __RCSID("$NetBSD: hack.main.c,v 1.9 2004/01/27 20:30:29 jsm Exp $");
67: #endif
68:
69: #include <signal.h>
70: #include <stdlib.h>
71: #include <unistd.h>
72: #include <fcntl.h>
73: #include "hack.h"
74: #include "extern.h"
75:
76: #ifdef QUEST
77: #define gamename "quest"
78: #else
79: #define gamename "hack"
80: #endif
81:
82: int (*afternmv)(void);
83: int (*occupation)(void);
84: const char *occtxt;
85:
86: int hackpid;
87: int locknum;
88: #ifdef DEF_PAGER
89: const char *catmore;
90: #endif
91: char SAVEF[PL_NSIZ + 11] = "save/";
92: char *hname;
93: char obuf[BUFSIZ];
94:
95: int main(int, char *[]);
96: static void chdirx(const char *, boolean);
97:
98: int
99: main(argc, argv)
100: int argc;
101: char *argv[];
102: {
103: int fd;
104: #ifdef CHDIR
105: char *dir;
106: #endif
107:
108:
109: fd = open("/dev/null", O_RDONLY);
110: if (fd < 3)
111: exit(1);
112: close(fd);
113:
114: hname = argv[0];
115: hackpid = getpid();
116:
117: #ifdef CHDIR
118:
119:
120:
121:
122:
123:
124:
125:
126: dir = getenv("HACKDIR");
127: if (argc > 1 && !strncmp(argv[1], "-d", 2)) {
128: argc--;
129: argv++;
130: dir = argv[0] + 2;
131: if (*dir == '=' || *dir == ':')
132: dir++;
133: if (!*dir && argc > 1) {
134: argc--;
135: argv++;
136: dir = argv[0];
137: }
138: if (!*dir)
139: error("Flag -d must be followed by a directory name.");
140: }
141: #endif
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154: {
155: char *s;
156:
157: initoptions();
158: if (!*plname && (s = getenv("USER")))
159: (void) strncpy(plname, s, sizeof(plname) - 1);
160: if (!*plname && (s = getenv("LOGNAME")))
161: (void) strncpy(plname, s, sizeof(plname) - 1);
162: if (!*plname && (s = getlogin()))
163: (void) strncpy(plname, s, sizeof(plname) - 1);
164: }
165:
166:
167:
168:
169:
170: if (argc > 1 && !strncmp(argv[1], "-s", 2)) {
171: #ifdef CHDIR
172: chdirx(dir, 0);
173: #endif
174: prscore(argc, argv);
175: exit(0);
176: }
177:
178:
179:
180:
181: gettty();
182: setbuf(stdout, obuf);
183: setrandom();
184: startup();
185: cls();
186: u.uhp = 1;
187: u.ux = FAR;
188: (void) signal(SIGHUP, hangup);
189:
190:
191:
192:
193:
194: gethdate(hname);
195:
196:
197:
198:
199: #ifdef CHDIR
200: chdirx(dir, 1);
201: #endif
202:
203:
204:
205:
206: while (argc > 1 && argv[1][0] == '-') {
207: argv++;
208: argc--;
209: switch (argv[0][1]) {
210: #ifdef WIZARD
211: case 'D':
212:
213: wizard = TRUE;
214:
215:
216:
217: break;
218: #endif
219: #ifdef NEWS
220: case 'n':
221: flags.nonews = TRUE;
222: break;
223: #endif
224: case 'u':
225: if (argv[0][2])
226: (void) strncpy(plname, argv[0] + 2, sizeof(plname) - 1);
227: else if (argc > 1) {
228: argc--;
229: argv++;
230: (void) strncpy(plname, argv[0], sizeof(plname) - 1);
231: } else
232: printf("Player name expected after -u\n");
233: break;
234: default:
235:
236: (void) strncpy(pl_character, argv[0] + 1,
237: sizeof(pl_character) - 1);
238:
239:
240: }
241: }
242:
243: if (argc > 1)
244: locknum = atoi(argv[1]);
245: #ifdef MAX_NR_OF_PLAYERS
246: if (!locknum || locknum > MAX_NR_OF_PLAYERS)
247: locknum = MAX_NR_OF_PLAYERS;
248: #endif
249: #ifdef DEF_PAGER
250: if (((catmore = getenv("HACKPAGER")) == NULL &&
251: (catmore = getenv("PAGER")) == NULL) ||
252: catmore[0] == '\0')
253: catmore = DEF_PAGER;
254: #endif
255: #ifdef MAIL
256: getmailstatus();
257: #endif
258: #ifdef WIZARD
259: if (wizard)
260: (void) strcpy(plname, "wizard");
261: else
262: #endif
263: if (!*plname || !strncmp(plname, "player", 4)
264: || !strncmp(plname, "games", 4))
265: askname();
266: plnamesuffix();
267:
268:
269: #ifdef WIZARD
270: if (!wizard) {
271: #endif
272:
273:
274:
275:
276: (void) signal(SIGQUIT, SIG_IGN);
277: (void) signal(SIGINT, SIG_IGN);
278: if (!locknum)
279: (void) strcpy(lock, plname);
280: getlock();
281: #ifdef WIZARD
282: } else {
283: char *sfoo;
284: (void) strcpy(lock, plname);
285: if ((sfoo = getenv("MAGIC")) != NULL)
286: while (*sfoo) {
287: switch (*sfoo++) {
288: case 'n':
289: (void) srandom(*sfoo++);
290: break;
291: }
292: }
293: if ((sfoo = getenv("GENOCIDED")) != NULL) {
294: if (*sfoo == '!') {
295: const struct permonst *pm = mons;
296: char *gp = genocided;
297:
298: while (pm < mons + CMNUM + 2) {
299: if (!strchr(sfoo, pm->mlet))
300: *gp++ = pm->mlet;
301: pm++;
302: }
303: *gp = 0;
304: } else
305: (void) strcpy(genocided, sfoo);
306: (void) strcpy(fut_geno, genocided);
307: }
308: }
309: #endif
310: setftty();
311: (void) sprintf(SAVEF, "save/%d%s", getuid(), plname);
312: regularize(SAVEF + 5);
313: if ((fd = open(SAVEF, O_RDONLY)) >= 0 &&
314: (uptodate(fd) || unlink(SAVEF) == 666)) {
315: (void) signal(SIGINT, done1);
316: pline("Restoring old save file...");
317: (void) fflush(stdout);
318: if (!dorecover(fd))
319: goto not_recovered;
320: pline("Hello %s, welcome to %s!", plname, gamename);
321: flags.move = 0;
322: } else {
323: not_recovered:
324: fobj = fcobj = invent = 0;
325: fmon = fallen_down = 0;
326: ftrap = 0;
327: fgold = 0;
328: flags.ident = 1;
329: init_objects();
330: u_init();
331:
332: (void) signal(SIGINT, done1);
333: mklev();
334: u.ux = xupstair;
335: u.uy = yupstair;
336: (void) inshop();
337: setsee();
338: flags.botlx = 1;
339: makedog();
340: {
341: struct monst *mtmp;
342: if ((mtmp = m_at(u.ux, u.uy)) != NULL)
343: mnexto(mtmp);
344: }
345: seemons();
346: #ifdef NEWS
347: if (flags.nonews || !readnews())
348:
349: #endif
350: docrt();
351:
352:
353: pline("Hello %s, welcome to %s!", plname, gamename);
354:
355: pickup(1);
356: read_engr_at(u.ux, u.uy);
357: flags.move = 1;
358: }
359:
360: flags.moonphase = phase_of_the_moon();
361: if (flags.moonphase == FULL_MOON) {
362: pline("You are lucky! Full moon tonight.");
363: u.uluck++;
364: } else if (flags.moonphase == NEW_MOON) {
365: pline("Be careful! New moon tonight.");
366: }
367: initrack();
368:
369: for (;;) {
370: if (flags.move) {
371:
372: settrack();
373:
374: if (moves % 2 == 0 ||
375: (!(Fast & ~INTRINSIC) && (!Fast || rn2(3)))) {
376: movemon();
377: if (!rn2(70))
378: (void) makemon((struct permonst *) 0, 0, 0);
379: }
380: if (Glib)
381: glibr();
382: timeout();
383: ++moves;
384: if (flags.time)
385: flags.botl = 1;
386: if (u.uhp < 1) {
387: pline("You die...");
388: done("died");
389: }
390: if (u.uhp * 10 < u.uhpmax && moves - wailmsg > 50) {
391: wailmsg = moves;
392: if (u.uhp == 1)
393: pline("You hear the wailing of the Banshee...");
394: else
395: pline("You hear the howling of the CwnAnnwn...");
396: }
397: if (u.uhp < u.uhpmax) {
398: if (u.ulevel > 9) {
399: if (Regeneration || !(moves % 3)) {
400: flags.botl = 1;
401: u.uhp += rnd((int) u.ulevel - 9);
402: if (u.uhp > u.uhpmax)
403: u.uhp = u.uhpmax;
404: }
405: } else if (Regeneration ||
406: (!(moves % (22 - u.ulevel * 2)))) {
407: flags.botl = 1;
408: u.uhp++;
409: }
410: }
411: if (Teleportation && !rn2(85))
412: tele();
413: if (Searching && multi >= 0)
414: (void) dosearch();
415: gethungry();
416: invault();
417: amulet();
418: }
419: if (multi < 0) {
420: if (!++multi) {
421: pline(nomovemsg ? nomovemsg :
422: "You can move again.");
423: nomovemsg = 0;
424: if (afternmv)
425: (*afternmv) ();
426: afternmv = 0;
427: }
428: }
429: find_ac();
430: #ifndef QUEST
431: if (!flags.mv || Blind)
432: #endif
433: {
434: seeobjs();
435: seemons();
436: nscr();
437: }
438: if (flags.botl || flags.botlx)
439: bot();
440:
441: flags.move = 1;
442:
443: if (multi >= 0 && occupation) {
444: if (monster_nearby())
445: stop_occupation();
446: else if ((*occupation) () == 0)
447: occupation = 0;
448: continue;
449: }
450: if (multi > 0) {
451: #ifdef QUEST
452: if (flags.run >= 4)
453: finddir();
454: #endif
455: lookaround();
456: if (!multi) {
457: flags.move = 0;
458: continue;
459: }
460: if (flags.mv) {
461: if (multi < COLNO && !--multi)
462: flags.mv = flags.run = 0;
463: domove();
464: } else {
465: --multi;
466: rhack(save_cm);
467: }
468: } else if (multi == 0) {
469: #ifdef MAIL
470: ckmailstatus();
471: #endif
472: rhack((char *) 0);
473: }
474: if (multi && multi % 7 == 0)
475: (void) fflush(stdout);
476: }
477: }
478:
479: void
480: glo(foo)
481: int foo;
482: {
483:
484: char *tf;
485:
486: tf = lock;
487: while (*tf && *tf != '.')
488: tf++;
489: (void) sprintf(tf, ".%d", foo);
490: }
491:
492:
493:
494:
495:
496:
497: void
498: askname()
499: {
500: int c, ct;
501: printf("\nWho are you? ");
502: (void) fflush(stdout);
503: ct = 0;
504: while ((c = getchar()) != '\n') {
505: if (c == EOF)
506: error("End of input\n");
507:
508: if (c == '\010') {
509: if (ct)
510: ct--;
511: continue;
512: }
513: if (c != '-')
514: if (c < 'A' || (c > 'Z' && c < 'a') || c > 'z')
515: c = '_';
516: if ((size_t)ct < sizeof(plname) - 1)
517: plname[ct++] = c;
518: }
519: plname[ct] = 0;
520: if (ct == 0)
521: askname();
522: }
523:
524:
525: void
526: impossible(const char *s, ...)
527: {
528: va_list ap;
529:
530: va_start(ap, s);
531: vpline(s, ap);
532: va_end(ap);
533: pline("Program in disorder - perhaps you'd better Quit.");
534: }
535:
536: #ifdef CHDIR
537: static void
538: chdirx(dir, wr)
539: const char *dir;
540: boolean wr;
541: {
542:
543: #ifdef SECURE
544: if (dir
545: #ifdef HACKDIR
546: && strcmp(dir, HACKDIR)
547: #endif
548: ) {
549: (void) setuid(getuid());
550: (void) setregid(getgid(), getgid());
551: }
552: #endif
553:
554: #ifdef HACKDIR
555: if (dir == NULL)
556: