void startup(void) { char *term; char *tptr; char *tbufptr, *pc; tptr = (char *) alloc(1024); tbufptr = tbuf; if(!(term = getenv("TERM"))) error("Can't get TERM."); if(!strncmp(term, "5620", 4)) flags.nonull = 1; /* this should be a termcap flag */ if(tgetent(tptr, term) < 1) error("Unknown terminal type: %s.", term); if ((pc = tgetstr("pc", &tbufptr))) PC = *pc; if(!(BC = tgetstr("le", &tbufptr))) { if(!tgetflag("bs")) error("Terminal must backspace."); BC = tbufptr; tbufptr += 2; *BC = '\b'; } HO = tgetstr("ho", &tbufptr); CO = tgetnum("co"); LI = tgetnum("li"); if(CO < COLNO || LI < ROWNO+2) setclipped(); if(!(CL = tgetstr("cl", &tbufptr))) error("Hack needs CL."); ND = tgetstr("nd", &tbufptr); if(tgetflag("os")) error("Hack can't have OS."); CE = tgetstr("ce", &tbufptr); UP = tgetstr("up", &tbufptr); /* It seems that xd is no longer supported, and we should use a linefeed instead; unfortunately this requires resetting CRMOD, and many output routines will have to be modified slightly. Let's leave that till the next release. */ XD = tgetstr("xd", &tbufptr); /* not: XD = tgetstr("do", &tbufptr); */ if(!(CM = tgetstr("cm", &tbufptr))) { if(!UP && !HO) error("Hack needs CM or UP or HO."); printf("Playing hack on terminals without cm is suspect...\n"); getret(); } SO = tgetstr("so", &tbufptr); SE = tgetstr("se", &tbufptr); SG = tgetnum("sg"); /* -1: not fnd; else # of spaces left by so */ if(!SO || !SE || (SG > 0)) SO = SE = 0; CD = tgetstr("cd", &tbufptr); set_whole_screen(); /* uses LI and CD */ if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n"); free(tptr); }
int main() { int n; while(scanf("%d", &n) != EOF) { printf("%d\n", getret(n)); } return 0; }
outrip(){ register char **dp = rip; register char *dpx; char buf[BUFSZ]; register x,y; cls(); (void) strcpy(buf, plname); buf[16] = 0; center(6, buf); (void) sprintf(buf, "%ld AU", u.ugold); center(7, buf); (void) sprintf(buf, "killed by%s", !strncmp(killer, "the ", STRLEN("the ")) ? "" : !strcmp(killer, "starvation") ? "" : index(vowels, *killer) ? " an" : " a"); center(8, buf); (void) strcpy(buf, killer); if(strlen(buf) > 16) { register int i,i0,i1; i0 = i1 = 0; for(i = 0; i <= 16; i++) if(buf[i] == ' ') i0 = i, i1 = i+1; if(!i0) i0 = i1 = 16; buf[i1 + 16] = 0; center(10, buf+i1); buf[i0] = 0; } center(9, buf); (void) sprintf(buf, "%4d", getyear()); center(11, buf); for(y=8; *dp; y++,dp++){ x = 0; dpx = *dp; while(dpx[x]) { while(dpx[x] == ' ') x++; curs(x,y); while(dpx[x] && dpx[x] != ' '){ extern int done_stopprint; if(done_stopprint) return; curx++; (void) putchar(dpx[x++]); } } } getret(); }
static void chdirx(char *dir, boolean wr) { gid_t gid; #ifdef SECURE if(dir /* User specified directory? */ #ifdef HACKDIR && strcmp(dir, HACKDIR) /* and not the default? */ #endif ) { /* revoke privs */ gid = getgid(); setresgid(gid, gid, gid); } #endif #ifdef HACKDIR if(dir == NULL) dir = HACKDIR; #endif if(dir && chdir(dir) < 0) { perror(dir); error("Cannot chdir to %s.", dir); } /* warn the player if he cannot write the record file */ /* perhaps we should also test whether . is writable */ /* unfortunately the access systemcall is worthless */ if(wr) { int fd; if(dir == NULL) dir = "."; if((fd = open(RECORD, O_RDWR)) < 0) { printf("Warning: cannot write %s/%s", dir, RECORD); getret(); } else (void) close(fd); } }
int child(int wt) { int status; int f; char *home; gid_t gid; f = fork(); if(f == 0){ /* child */ settty((char *) 0); /* also calls end_screen() */ /* revoke privs */ gid = getgid(); setresgid(gid, gid, gid); #ifdef CHDIR home = getenv("HOME"); if (home == NULL || *home == '\0') home = "/"; (void) chdir(home); #endif /* CHDIR */ return(1); } if(f == -1) { /* cannot fork */ pline("Fork failed. Try again."); return(0); } /* fork succeeded; wait for child to exit */ (void) signal(SIGINT,SIG_IGN); (void) signal(SIGQUIT,SIG_IGN); (void) wait(&status); gettty(); setftty(); (void) signal(SIGINT,done1); #ifdef WIZARD if(wizard) (void) signal(SIGQUIT,SIG_DFL); #endif /* WIZARD */ if(wt) getret(); docrt(); return(0); }
void outrip(void) { char buf[BUFSZ]; cls(); curs(1, 8); puts(riptop); (void) strcpy(buf, plname); buf[16] = 0; center(6, buf); (void) snprintf(buf, sizeof(buf), "%ld AU", u.ugold); center(7, buf); (void) snprintf(buf, sizeof(buf), "killed by%s", !strncmp(killer, "the ", 4) ? "" : !strcmp(killer, "starvation") ? "" : strchr(vowels, *killer) ? " an" : " a"); center(8, buf); (void) strlcpy(buf, killer, sizeof(buf)); { int i1; if ((i1 = strlen(buf)) > 16) { int i, i0; i0 = i1 = 0; for (i = 0; i <= 16; i++) if (buf[i] == ' ') i0 = i, i1 = i + 1; if (!i0) i0 = i1 = 16; buf[i1 + 16] = 0; buf[i0] = 0; } center(9, buf); center(10, buf + i1); } (void) snprintf(buf, sizeof(buf), "%4d", getyear()); center(11, buf); puts(ripbot); getret(); }
static void chdirx(const char *dir, bool wr) { #ifdef SECURE if (dir // User specified directory? #ifdef HACKDIR && strcmp(dir, HACKDIR) // and not the default? #endif ) { (void) setuid(getuid()); // Ron Wessels (void) setregid(getgid(), getgid()); } #endif #ifdef HACKDIR if (dir == NULL) dir = HACKDIR; #endif if (dir && chdir(dir) < 0) { perror(dir); error("Cannot chdir to %s.", dir); } // warn the player if he cannot write the record file // perhaps we should also test whether . is writable // unfortunately the access systemcall is worthless if (wr) { int fd; if (dir == NULL) dir = "."; if ((fd = open(RECORD, O_RDWR)) < 0) { printf("Warning: cannot write %s/%s", dir, RECORD); getret(); } else (void) close(fd); } }
bool child(bool wt) { int status; int f; f = fork(); if (f == 0) { /* child */ settty(NULL); /* also calls end_screen() */ /* revoke */ setgid(getgid()); #ifdef CHDIR chdir(getenv("HOME")); #endif /* CHDIR */ return (1); } if (f == -1) { /* cannot fork */ pline("Fork failed. Try again."); return (0); } /* fork succeeded; wait for child to exit */ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); wait(&status); gettty(); setftty(); signal(SIGINT, done1); #ifdef WIZARD if (wizard) signal(SIGQUIT, SIG_DFL); #endif /* WIZARD */ if (wt) getret(); docrt(); return (0); }
/* Be careful not to call panic from here! */ void done(const char *st1) { #ifdef WIZARD if(wizard && *st1 == 'd'){ u.uswldtim = 0; if(u.uhpmax < 0) u.uhpmax = 100; /* arbitrary */ u.uhp = u.uhpmax; pline("For some reason you are still alive."); flags.move = 0; if(multi > 0) multi = 0; else multi = -1; flags.botl = 1; return; } #endif /* WIZARD */ signal(SIGINT, done_intr); signal(SIGQUIT, done_intr); signal(SIGHUP, done_hangup); if(*st1 == 'q' && u.uhp < 1){ st1 = "died"; killer = "quit while already on Charon's boat"; } if(*st1 == 's') killer = "starvation"; else if(*st1 == 'd' && st1[1] == 'r') killer = "drowning"; else if(*st1 == 'p') killer = "panic"; else if(*st1 == 't') killer = "trickery"; else if(!index("bcd", *st1)) killer = st1; paybill(); clearlocks(); if(flags.toplin == 1) more(); if(index("bcds", *st1)){ #ifdef WIZARD if(!wizard) #endif /* WIZARD */ savebones(); if(!flags.notombstone) outrip(); } if(*st1 == 'c') killer = st1; /* after outrip() */ settty(NULL); /* does a clear_screen() */ if(!done_stopprint) printf("Goodbye %s %s...\n\n", pl_character, plname); { long int tmp; tmp = u.ugold - u.ugold0; if(tmp < 0) tmp = 0; if(*st1 == 'd' || *st1 == 'b') tmp -= tmp/10; u.urexp += tmp; u.urexp += 50 * maxdlevel; if(maxdlevel > 20) u.urexp += 1000*((maxdlevel > 30) ? 10 : maxdlevel - 20); } if(*st1 == 'e') { struct monst *mtmp; struct obj *otmp; int i; unsigned worthlessct = 0; boolean has_amulet = FALSE; killer = st1; keepdogs(); mtmp = mydogs; if(mtmp) { if(!done_stopprint) printf("You"); while(mtmp) { if(!done_stopprint) printf(" and %s", monnam(mtmp)); if(mtmp->mtame) u.urexp += mtmp->mhp; mtmp = mtmp->nmon; } if(!done_stopprint) printf("\nescaped from the dungeon with %ld points,\n", u.urexp); } else if(!done_stopprint) printf("You escaped from the dungeon with %ld points,\n", u.urexp); for(otmp = invent; otmp; otmp = otmp->nobj) { if(otmp->olet == GEM_SYM){ i = otmp->quan*objects[otmp->otyp].g_val; if(i == 0) { worthlessct += otmp->quan; continue; } u.urexp += i; if(!done_stopprint) printf("\t%s (worth %d Zorkmids),\n", doname(otmp), i); } else if(otmp->olet == AMULET_SYM) { i = (otmp->spe < 0) ? 2 : 5000; u.urexp += i; if(!done_stopprint) printf("\t%s (worth %d Zorkmids),\n", doname(otmp), i); if(otmp->spe >= 0) { has_amulet = TRUE; killer = "escaped (with amulet)"; } } } if(worthlessct) if(!done_stopprint) printf("\t%u worthless piece%s of coloured glass,\n", worthlessct, plur(worthlessct)); if(has_amulet) u.urexp *= 2; } else if(!done_stopprint) printf("You %s on dungeon level %d with %ld points,\n", st1, dlevel, u.urexp); if(!done_stopprint) printf("and %ld piece%s of gold, after %ld move%s.\n", u.ugold, plur(u.ugold), moves, plur(moves)); if(!done_stopprint) printf("You were level %u with a maximum of %d hit points when you %s.\n", u.ulevel, u.uhpmax, st1); if(*st1 == 'e' && !done_stopprint){ getret(); /* all those pieces of coloured glass ... */ cls(); } #ifdef WIZARD if(!wizard) #endif /* WIZARD */ topten(); if(done_stopprint) printf("\n\n"); exit(0); }
void getlock(void) { int i = 0, fd; (void) fflush(stdout); /* we ignore QUIT and INT at this point */ if (link(HLOCK, LLOCK) == -1) { int errnosv = errno; perror(HLOCK); printf("Cannot link %s to %s\n", LLOCK, HLOCK); switch (errnosv) { case ENOENT: printf("Perhaps there is no (empty) file %s ?\n", HLOCK); break; case EACCES: printf("It seems you don't have write permission here.\n"); break; case EEXIST: printf("(Try again or rm %s.)\n", LLOCK); break; default: printf("I don't know what is wrong."); } getret(); error("%s", ""); /* NOTREACHED */ } regularize(lock); glo(0); if (locknum > 25) locknum = 25; do { if (locknum) lock[0] = 'a' + i++; if ((fd = open(lock, O_RDONLY)) == -1) { if (errno == ENOENT) goto gotlock; /* no such file */ perror(lock); (void) unlink(LLOCK); error("Cannot open %s", lock); } if (veryold(fd))/* if true, this closes fd and unlinks lock */ goto gotlock; (void) close(fd); } while (i < locknum); (void) unlink(LLOCK); error(locknum ? "Too many hacks running now." : "There is a game in progress under your name."); gotlock: fd = creat(lock, FMASK); if (unlink(LLOCK) == -1) error("Cannot unlink %s.", LLOCK); if (fd == -1) { error("cannot creat lock file."); } else { if (write(fd, &hackpid, sizeof(hackpid)) != sizeof(hackpid)) { error("cannot write lock"); } if (close(fd) == -1) { error("cannot close lock"); } } }
static void parseoptions(char *opts, bool from_env) { char *op, *op2; unsigned num; boolean negated; if ((op = strchr(opts, ',')) != NULL) { *op++ = 0; parseoptions(op, from_env); } if ((op = strchr(opts, ' ')) != NULL) { op2 = op; while (*op++) if (*op != ' ') *op2++ = *op; } if (!*opts) return; negated = FALSE; while ((*opts == '!') || !strncmp(opts, "no", 2)) { if (*opts == '!') opts++; else opts += 2; negated = !negated; } if (!strncmp(opts, "standout", 8)) { flags.standout = !negated; return; } if (!strncmp(opts, "null", 3)) { flags.nonull = negated; return; } if (!strncmp(opts, "tombstone", 4)) { flags.notombstone = negated; return; } if (!strncmp(opts, "news", 4)) { flags.nonews = negated; return; } if (!strncmp(opts, "time", 4)) { flags.time = !negated; flags.botl = 1; return; } if (!strncmp(opts, "restonspace", 4)) { flags.no_rest_on_space = negated; return; } if (!strncmp(opts, "fixinv", 4)) { if (from_env) flags.invlet_constant = !negated; else pline("The fixinvlet option must be in HACKOPTIONS."); return; } if (!strncmp(opts, "male", 4)) { flags.female = negated; return; } if (!strncmp(opts, "female", 6)) { flags.female = !negated; return; } /* name:string */ if (!strncmp(opts, "name", 4)) { if (!from_env) { pline("The playername can be set only from HACKOPTIONS."); return; } op = strchr(opts, ':'); if (!op) goto bad; strncpy(plname, op + 1, sizeof(plname) - 1); return; } /* endgame:5t[op] 5a[round] o[wn] */ if (!strncmp(opts, "endgame", 3)) { op = strchr(opts, ':'); if (!op) goto bad; op++; while (*op) { num = 1; if (digit(*op)) { num = atoi(op); while (digit(*op)) op++; } else if (*op == '!') { negated = !negated; op++; } switch (*op) { case 't': flags.end_top = num; break; case 'a': flags.end_around = num; break; case 'o': flags.end_own = !negated; break; default: goto bad; } while (letter(*++op)) ; /* nothing */ if (*op == '/') op++; } return; } bad: if (!from_env) { if (!strncmp(opts, "help", 4)) { pline("%s%s%s", "To set options use `HACKOPTIONS=\"<options>\"' in your environment, or ", "give the command 'o' followed by the line `<options>' while playing. ", "Here <options> is a list of <option>s separated by commas."); pline("%s%s%s", "Simple (boolean) options are rest_on_space, news, time, ", "null, tombstone, (fe)male. ", "These can be negated by prefixing them with '!' or \"no\"."); pline("%s", "A string option is name, as in HACKOPTIONS=\"name:Merlin-W\"."); pline("%s%s%s", "A compound option is endgame; it is followed by a description of what ", "parts of the scorelist you want to see. You might for example say: ", "`endgame:own scores/5 top scores/4 around my score'."); return; } pline("Bad option: %s.", opts); pline("Type `o help<cr>' for help."); return; } puts("Bad syntax in HACKOPTIONS."); puts("Use for example:"); puts("HACKOPTIONS=\"!restonspace,notombstone,endgame:own/5 topscorers/4 around me\""); getret(); }
void u_init(void) { int i; char exper = 'y', pc; if (flags.female) /* should have been set in HACKOPTIONS */ strlcpy(roles[4], "Cave-woman", sizeof(roles[4])); for (i = 0; i < NR_OF_ROLES; i++) rolesyms[i] = roles[i][0]; rolesyms[i] = 0; if ((pc = pl_character[0]) != '\0') { if ('a' <= pc && pc <= 'z') pc += 'A' - 'a'; if ((i = role_index(pc)) >= 0) goto got_suffix; /* implies experienced */ printf("\nUnknown role: %c\n", pc); pl_character[0] = pc = 0; } printf("\nAre you an experienced player? [ny] "); while (!strchr("ynYN \n\004", (exper = readchar()))) bell(); if (exper == '\004') /* Give him an opportunity to get out */ end_of_input(); printf("%c\n", exper); /* echo */ if (strchr("Nn \n", exper)) { exper = 0; goto beginner; } printf("\nTell me what kind of character you are:\n"); printf("Are you"); for (i = 0; i < NR_OF_ROLES; i++) { printf(" a %s", roles[i]); if (i == 2) /* %% */ printf(",\n\t"); else if (i < NR_OF_ROLES - 2) printf(","); else if (i == NR_OF_ROLES - 2) printf(" or"); } printf("? [%s] ", rolesyms); while ((pc = readchar()) != '\0') { if ('a' <= pc && pc <= 'z') pc += 'A' - 'a'; if ((i = role_index(pc)) >= 0) { printf("%c\n", pc); /* echo */ fflush(stdout); /* should be seen */ break; } if (pc == '\n') break; if (pc == '\004') /* Give him the opportunity to get out */ end_of_input(); bell(); } if (pc == '\n') pc = 0; beginner: if (!pc) { printf("\nI'll choose a character for you.\n"); i = rn2(NR_OF_ROLES); pc = rolesyms[i]; printf("This game you will be a%s %s.\n", exper ? "n experienced" : "", roles[i]); getret(); /* give him some feedback in case mklev takes much time */ putchar('\n'); fflush(stdout); } if (exper) roles[i][0] = pc; got_suffix: strncpy(pl_character, roles[i], PL_CSIZ - 1); pl_character[PL_CSIZ - 1] = 0; flags.beginner = 1; u = zerou; u.usym = '@'; u.ulevel = 1; init_uhunger(); #ifdef QUEST u.uhorizon = 6; #endif /* QUEST */ uarm = uarm2 = uarmh = uarms = uarmg = uwep = uball = uchain = uleft = uright = 0; switch (pc) { case 'c': case 'C': Cave_man[2].trquan = 12 + rnd(9) * rnd(9); u.uhp = u.uhpmax = 16; u.ustr = u.ustrmax = 18; ini_inv(Cave_man); break; case 't': case 'T': Tourist[3].trquan = 20 + rnd(20); u.ugold = u.ugold0 = rnd(1000); u.uhp = u.uhpmax = 10; u.ustr = u.ustrmax = 8; ini_inv(Tourist); if (!rn2(25)) ini_inv(Tinopener); break; case 'w': case 'W': for (i = 1; i <= 4; i++) if (!rn2(5)) Wizard[i].trquan += rn2(3) - 1; u.uhp = u.uhpmax = 15; u.ustr = u.ustrmax = 16; ini_inv(Wizard); break; case 's': case 'S': Fast = INTRINSIC; Stealth = INTRINSIC; u.uhp = u.uhpmax = 12; u.ustr = u.ustrmax = 10; ini_inv(Speleologist); if (!rn2(10)) ini_inv(Tinopener); break; case 'k': case 'K': u.uhp = u.uhpmax = 12; u.ustr = u.ustrmax = 10; ini_inv(Knight); break; case 'f': case 'F': u.uhp = u.uhpmax = 14; u.ustr = u.ustrmax = 17; ini_inv(Fighter); break; default: /* impossible */ u.uhp = u.uhpmax = 12; u.ustr = u.ustrmax = 16; } find_ac(); if (!rn2(20)) { int d1 = rn2(7) - 2; /* biased variation */ u.ustr += d1; u.ustrmax += d1; } #ifdef WIZARD if (wizard) wiz_inv(); #endif /* WIZARD */ /* make sure he can carry all he has - especially for T's */ while (inv_weight() > 0 && u.ustr < 118) u.ustr++, u.ustrmax++; }
void tty_player_selection() { char pbuf[QBUFSZ]; char pick, pc; int i, linecount; linecount = wins[BASE_WINDOW]->cury+1; if ((pc = highc(pl_character[0])) != 0) { if(index(pl_classes, pc) != (char*) 0) goto got_suffix; tty_putstr(BASE_WINDOW, 0, ""); Sprintf(pbuf, "Unknown role: %c", pc); tty_putstr(BASE_WINDOW, 0, pbuf); linecount += 2; pl_character[0] = pc = 0; } #define PICK_PROMPT "Shall I pick a character for you? [Y, N, or Q(quit)] " tty_putstr(BASE_WINDOW, 0, ""); tty_putstr(BASE_WINDOW, 0, PICK_PROMPT); while(!index("yYnNqQ", (pick = readchar())) && !index(quitchars, pick)) tty_nhbell(); pick = index(quitchars, pick) ? 'Y' : highc(pick); tty_putsym(BASE_WINDOW, (int)strlen(PICK_PROMPT)+1, linecount, pick); /* echo */ if (pick == 'Q') { clearlocks(); tty_exit_nhwindows(NULL); terminate(0); } if (pick == 'Y') { tty_putstr(BASE_WINDOW, 0, ""); goto beginner; } tty_curs(BASE_WINDOW, 1, linecount+2); tty_putstr(BASE_WINDOW, 0, "What kind of character are you:"); tty_putstr(BASE_WINDOW, 0, ""); Sprintf(pbuf, " %s,", An(roles[0])); for(i = 1; roles[i]; i++) { Sprintf(eos(pbuf), " %s", an(roles[i])); if((((i + 1) % 4) == 0) && roles[i+1]) { Strcat(pbuf, ","); tty_putstr(BASE_WINDOW, 0, pbuf); linecount++; Strcpy(pbuf, " "); } else if(roles[i+1] && roles[i+2]) Strcat(pbuf, ","); if(roles[i+1] && !roles[i+2]) Strcat(pbuf, " or"); } Strcat(pbuf ,"?"); tty_putstr(BASE_WINDOW, 0, pbuf); Strcpy(pbuf, " ["); for(i = 0; roles[i]; i++) Sprintf(eos(pbuf), "%c,", pl_classes[i]); Strcat(pbuf, " or Q] "); tty_putstr(BASE_WINDOW, 0, pbuf); linecount += 5; while ((pc = readchar()) != 0) { if ((pc = highc(pc)) == 'Q') { clearlocks(); tty_exit_nhwindows(NULL); terminate(0); } if(index(pl_classes, pc) != (char *) 0) { tty_putsym(BASE_WINDOW, (int)strlen(pbuf)+1, linecount, pc); /* echo */ tty_putstr(BASE_WINDOW, 0, ""); tty_display_nhwindow(BASE_WINDOW, TRUE); break; } if(pc == '\n') { pc = 0; break; } tty_nhbell(); } beginner: if(!pc) { i = rn2((int)strlen(pl_classes)); pc = pl_classes[i]; tty_putstr(BASE_WINDOW, 0, ""); Sprintf(pbuf, "This game you will be %s.", an(roles[i])); tty_putstr(BASE_WINDOW, 0, pbuf); tty_putstr(BASE_WINDOW, 0, ""); tty_display_nhwindow(BASE_WINDOW, TRUE); getret(); } got_suffix: tty_clear_nhwindow(BASE_WINDOW); pl_character[0] = pc; return; }