1 1.17 dholland /* $NetBSD: hack.main.c,v 1.17 2011/08/06 20:42:43 dholland Exp $ */ 2 1.4 christos 3 1.2 mycroft /* 4 1.8 jsm * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, 5 1.8 jsm * Amsterdam 6 1.8 jsm * All rights reserved. 7 1.8 jsm * 8 1.8 jsm * Redistribution and use in source and binary forms, with or without 9 1.8 jsm * modification, are permitted provided that the following conditions are 10 1.8 jsm * met: 11 1.8 jsm * 12 1.8 jsm * - Redistributions of source code must retain the above copyright notice, 13 1.8 jsm * this list of conditions and the following disclaimer. 14 1.8 jsm * 15 1.8 jsm * - Redistributions in binary form must reproduce the above copyright 16 1.8 jsm * notice, this list of conditions and the following disclaimer in the 17 1.8 jsm * documentation and/or other materials provided with the distribution. 18 1.8 jsm * 19 1.8 jsm * - Neither the name of the Stichting Centrum voor Wiskunde en 20 1.8 jsm * Informatica, nor the names of its contributors may be used to endorse or 21 1.8 jsm * promote products derived from this software without specific prior 22 1.8 jsm * written permission. 23 1.8 jsm * 24 1.8 jsm * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 25 1.8 jsm * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26 1.8 jsm * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 27 1.8 jsm * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 28 1.8 jsm * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 1.8 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 1.8 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 1.8 jsm * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 1.8 jsm * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 1.8 jsm * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 1.8 jsm * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 1.8 jsm */ 36 1.8 jsm 37 1.8 jsm /* 38 1.8 jsm * Copyright (c) 1982 Jay Fenlason <hack (at) gnu.org> 39 1.8 jsm * All rights reserved. 40 1.8 jsm * 41 1.8 jsm * Redistribution and use in source and binary forms, with or without 42 1.8 jsm * modification, are permitted provided that the following conditions 43 1.8 jsm * are met: 44 1.8 jsm * 1. Redistributions of source code must retain the above copyright 45 1.8 jsm * notice, this list of conditions and the following disclaimer. 46 1.8 jsm * 2. Redistributions in binary form must reproduce the above copyright 47 1.8 jsm * notice, this list of conditions and the following disclaimer in the 48 1.8 jsm * documentation and/or other materials provided with the distribution. 49 1.8 jsm * 3. The name of the author may not be used to endorse or promote products 50 1.8 jsm * derived from this software without specific prior written permission. 51 1.8 jsm * 52 1.8 jsm * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 53 1.8 jsm * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 54 1.8 jsm * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 55 1.8 jsm * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 56 1.8 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 57 1.8 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 58 1.8 jsm * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 59 1.8 jsm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 60 1.8 jsm * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 61 1.8 jsm * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 1.2 mycroft */ 63 1.2 mycroft 64 1.4 christos #include <sys/cdefs.h> 65 1.2 mycroft #ifndef lint 66 1.17 dholland __RCSID("$NetBSD: hack.main.c,v 1.17 2011/08/06 20:42:43 dholland Exp $"); 67 1.4 christos #endif /* not lint */ 68 1.1 cgd 69 1.1 cgd #include <signal.h> 70 1.4 christos #include <stdlib.h> 71 1.4 christos #include <unistd.h> 72 1.4 christos #include <fcntl.h> 73 1.1 cgd #include "hack.h" 74 1.4 christos #include "extern.h" 75 1.1 cgd 76 1.1 cgd #ifdef QUEST 77 1.1 cgd #define gamename "quest" 78 1.1 cgd #else 79 1.1 cgd #define gamename "hack" 80 1.1 cgd #endif 81 1.1 cgd 82 1.9 jsm int (*afternmv)(void); 83 1.9 jsm int (*occupation)(void); 84 1.6 jsm const char *occtxt; /* defined when occupation != NULL */ 85 1.1 cgd 86 1.4 christos int hackpid; /* current pid */ 87 1.4 christos int locknum; /* max num of players */ 88 1.1 cgd #ifdef DEF_PAGER 89 1.6 jsm const char *catmore; /* default pager */ 90 1.1 cgd #endif 91 1.4 christos char SAVEF[PL_NSIZ + 11] = "save/"; /* save/99999player */ 92 1.4 christos char *hname; /* name of the game (argv[0] of call) */ 93 1.14 dholland 94 1.14 dholland static char obuf[BUFSIZ]; /* BUFSIZ is defined in stdio.h */ 95 1.4 christos 96 1.9 jsm int main(int, char *[]); 97 1.9 jsm static void chdirx(const char *, boolean); 98 1.4 christos 99 1.4 christos int 100 1.11 dholland main(int argc, char *argv[]) 101 1.1 cgd { 102 1.4 christos int fd; 103 1.1 cgd #ifdef CHDIR 104 1.4 christos char *dir; 105 1.1 cgd #endif 106 1.1 cgd 107 1.6 jsm /* Check for dirty tricks with closed fds 0, 1, 2 */ 108 1.6 jsm fd = open("/dev/null", O_RDONLY); 109 1.6 jsm if (fd < 3) 110 1.6 jsm exit(1); 111 1.6 jsm close(fd); 112 1.6 jsm 113 1.1 cgd hname = argv[0]; 114 1.1 cgd hackpid = getpid(); 115 1.1 cgd 116 1.1 cgd #ifdef CHDIR /* otherwise no chdir() */ 117 1.1 cgd /* 118 1.1 cgd * See if we must change directory to the playground. 119 1.1 cgd * (Perhaps hack runs suid and playground is inaccessible 120 1.1 cgd * for the player.) 121 1.1 cgd * The environment variable HACKDIR is overridden by a 122 1.1 cgd * -d command line option (must be the first option given) 123 1.1 cgd */ 124 1.1 cgd 125 1.1 cgd dir = getenv("HACKDIR"); 126 1.4 christos if (argc > 1 && !strncmp(argv[1], "-d", 2)) { 127 1.1 cgd argc--; 128 1.1 cgd argv++; 129 1.4 christos dir = argv[0] + 2; 130 1.4 christos if (*dir == '=' || *dir == ':') 131 1.4 christos dir++; 132 1.4 christos if (!*dir && argc > 1) { 133 1.1 cgd argc--; 134 1.1 cgd argv++; 135 1.1 cgd dir = argv[0]; 136 1.1 cgd } 137 1.4 christos if (!*dir) 138 1.4 christos error("Flag -d must be followed by a directory name."); 139 1.1 cgd } 140 1.1 cgd #endif 141 1.1 cgd 142 1.1 cgd /* 143 1.1 cgd * Who am i? Algorithm: 1. Use name as specified in HACKOPTIONS 144 1.1 cgd * 2. Use $USER or $LOGNAME (if 1. fails) 145 1.1 cgd * 3. Use getlogin() (if 2. fails) 146 1.1 cgd * The resulting name is overridden by command line options. 147 1.1 cgd * If everything fails, or if the resulting name is some generic 148 1.1 cgd * account like "games", "play", "player", "hack" then eventually 149 1.1 cgd * we'll ask him. 150 1.1 cgd * Note that we trust him here; it is possible to play under 151 1.1 cgd * somebody else's name. 152 1.1 cgd */ 153 1.4 christos { 154 1.4 christos char *s; 155 1.1 cgd 156 1.4 christos initoptions(); 157 1.4 christos if (!*plname && (s = getenv("USER"))) 158 1.4 christos (void) strncpy(plname, s, sizeof(plname) - 1); 159 1.4 christos if (!*plname && (s = getenv("LOGNAME"))) 160 1.4 christos (void) strncpy(plname, s, sizeof(plname) - 1); 161 1.4 christos if (!*plname && (s = getlogin())) 162 1.4 christos (void) strncpy(plname, s, sizeof(plname) - 1); 163 1.1 cgd } 164 1.1 cgd 165 1.1 cgd /* 166 1.1 cgd * Now we know the directory containing 'record' and 167 1.1 cgd * may do a prscore(). 168 1.1 cgd */ 169 1.4 christos if (argc > 1 && !strncmp(argv[1], "-s", 2)) { 170 1.1 cgd #ifdef CHDIR 171 1.4 christos chdirx(dir, 0); 172 1.1 cgd #endif 173 1.1 cgd prscore(argc, argv); 174 1.1 cgd exit(0); 175 1.1 cgd } 176 1.1 cgd /* 177 1.1 cgd * It seems he really wants to play. 178 1.1 cgd * Remember tty modes, to be restored on exit. 179 1.1 cgd */ 180 1.1 cgd gettty(); 181 1.4 christos setbuf(stdout, obuf); 182 1.1 cgd setrandom(); 183 1.1 cgd startup(); 184 1.1 cgd cls(); 185 1.4 christos u.uhp = 1; /* prevent RIP on early quits */ 186 1.4 christos u.ux = FAR; /* prevent nscr() */ 187 1.15 roy (void) signal(SIGHUP, hang_up); 188 1.1 cgd 189 1.1 cgd /* 190 1.1 cgd * Find the creation date of this game, 191 1.1 cgd * so as to avoid restoring outdated savefiles. 192 1.1 cgd */ 193 1.1 cgd gethdate(hname); 194 1.1 cgd 195 1.1 cgd /* 196 1.1 cgd * We cannot do chdir earlier, otherwise gethdate will fail. 197 1.1 cgd */ 198 1.1 cgd #ifdef CHDIR 199 1.4 christos chdirx(dir, 1); 200 1.1 cgd #endif 201 1.1 cgd 202 1.1 cgd /* 203 1.1 cgd * Process options. 204 1.1 cgd */ 205 1.4 christos while (argc > 1 && argv[1][0] == '-') { 206 1.1 cgd argv++; 207 1.1 cgd argc--; 208 1.4 christos switch (argv[0][1]) { 209 1.1 cgd #ifdef WIZARD 210 1.1 cgd case 'D': 211 1.4 christos /* if(!strcmp(getlogin(), WIZARD)) */ 212 1.4 christos wizard = TRUE; 213 1.4 christos /* 214 1.4 christos * else printf("Sorry.\n"); 215 1.4 christos */ 216 1.1 cgd break; 217 1.1 cgd #endif 218 1.1 cgd #ifdef NEWS 219 1.1 cgd case 'n': 220 1.1 cgd flags.nonews = TRUE; 221 1.1 cgd break; 222 1.1 cgd #endif 223 1.1 cgd case 'u': 224 1.4 christos if (argv[0][2]) 225 1.4 christos (void) strncpy(plname, argv[0] + 2, sizeof(plname) - 1); 226 1.4 christos else if (argc > 1) { 227 1.4 christos argc--; 228 1.4 christos argv++; 229 1.4 christos (void) strncpy(plname, argv[0], sizeof(plname) - 1); 230 1.1 cgd } else 231 1.1 cgd printf("Player name expected after -u\n"); 232 1.1 cgd break; 233 1.1 cgd default: 234 1.1 cgd /* allow -T for Tourist, etc. */ 235 1.4 christos (void) strncpy(pl_character, argv[0] + 1, 236 1.4 christos sizeof(pl_character) - 1); 237 1.1 cgd 238 1.1 cgd /* printf("Unknown option: %s\n", *argv); */ 239 1.1 cgd } 240 1.1 cgd } 241 1.1 cgd 242 1.4 christos if (argc > 1) 243 1.1 cgd locknum = atoi(argv[1]); 244 1.1 cgd #ifdef MAX_NR_OF_PLAYERS 245 1.4 christos if (!locknum || locknum > MAX_NR_OF_PLAYERS) 246 1.1 cgd locknum = MAX_NR_OF_PLAYERS; 247 1.1 cgd #endif 248 1.1 cgd #ifdef DEF_PAGER 249 1.5 kleink if (((catmore = getenv("HACKPAGER")) == NULL && 250 1.5 kleink (catmore = getenv("PAGER")) == NULL) || 251 1.5 kleink catmore[0] == '\0') 252 1.1 cgd catmore = DEF_PAGER; 253 1.1 cgd #endif 254 1.1 cgd #ifdef MAIL 255 1.1 cgd getmailstatus(); 256 1.1 cgd #endif 257 1.1 cgd #ifdef WIZARD 258 1.4 christos if (wizard) 259 1.4 christos (void) strcpy(plname, "wizard"); 260 1.4 christos else 261 1.1 cgd #endif 262 1.4 christos if (!*plname || !strncmp(plname, "player", 4) 263 1.1 cgd || !strncmp(plname, "games", 4)) 264 1.1 cgd askname(); 265 1.1 cgd plnamesuffix(); /* strip suffix from name; calls askname() */ 266 1.4 christos /* again if suffix was whole name */ 267 1.4 christos /* accepts any suffix */ 268 1.1 cgd #ifdef WIZARD 269 1.4 christos if (!wizard) { 270 1.1 cgd #endif 271 1.1 cgd /* 272 1.1 cgd * check for multiple games under the same name 273 1.1 cgd * (if !locknum) or check max nr of players (otherwise) 274 1.1 cgd */ 275 1.4 christos (void) signal(SIGQUIT, SIG_IGN); 276 1.4 christos (void) signal(SIGINT, SIG_IGN); 277 1.4 christos if (!locknum) 278 1.4 christos (void) strcpy(lock, plname); 279 1.1 cgd getlock(); /* sets lock if locknum != 0 */ 280 1.1 cgd #ifdef WIZARD 281 1.1 cgd } else { 282 1.4 christos char *sfoo; 283 1.4 christos (void) strcpy(lock, plname); 284 1.4 christos if ((sfoo = getenv("MAGIC")) != NULL) 285 1.4 christos while (*sfoo) { 286 1.4 christos switch (*sfoo++) { 287 1.4 christos case 'n': 288 1.4 christos (void) srandom(*sfoo++); 289 1.1 cgd break; 290 1.1 cgd } 291 1.1 cgd } 292 1.4 christos if ((sfoo = getenv("GENOCIDED")) != NULL) { 293 1.4 christos if (*sfoo == '!') { 294 1.6 jsm const struct permonst *pm = mons; 295 1.4 christos char *gp = genocided; 296 1.1 cgd 297 1.4 christos while (pm < mons + CMNUM + 2) { 298 1.4 christos if (!strchr(sfoo, pm->mlet)) 299 1.1 cgd *gp++ = pm->mlet; 300 1.1 cgd pm++; 301 1.1 cgd } 302 1.1 cgd *gp = 0; 303 1.1 cgd } else 304 1.13 dholland (void) strlcpy(genocided, sfoo, 305 1.13 dholland sizeof(genocided)); 306 1.1 cgd (void) strcpy(fut_geno, genocided); 307 1.1 cgd } 308 1.1 cgd } 309 1.1 cgd #endif 310 1.1 cgd setftty(); 311 1.12 dholland (void) snprintf(SAVEF, sizeof(SAVEF), "save/%d%s", getuid(), plname); 312 1.4 christos regularize(SAVEF + 5); /* avoid . or / in name */ 313 1.6 jsm if ((fd = open(SAVEF, O_RDONLY)) >= 0 && 314 1.4 christos (uptodate(fd) || unlink(SAVEF) == 666)) { 315 1.4 christos (void) signal(SIGINT, done1); 316 1.1 cgd pline("Restoring old save file..."); 317 1.1 cgd (void) fflush(stdout); 318 1.4 christos if (!dorecover(fd)) 319 1.1 cgd goto not_recovered; 320 1.1 cgd pline("Hello %s, welcome to %s!", plname, gamename); 321 1.1 cgd flags.move = 0; 322 1.1 cgd } else { 323 1.1 cgd not_recovered: 324 1.1 cgd fobj = fcobj = invent = 0; 325 1.1 cgd fmon = fallen_down = 0; 326 1.1 cgd ftrap = 0; 327 1.1 cgd fgold = 0; 328 1.1 cgd flags.ident = 1; 329 1.1 cgd init_objects(); 330 1.1 cgd u_init(); 331 1.1 cgd 332 1.4 christos (void) signal(SIGINT, done1); 333 1.1 cgd mklev(); 334 1.1 cgd u.ux = xupstair; 335 1.1 cgd u.uy = yupstair; 336 1.1 cgd (void) inshop(); 337 1.1 cgd setsee(); 338 1.1 cgd flags.botlx = 1; 339 1.1 cgd makedog(); 340 1.4 christos { 341 1.4 christos struct monst *mtmp; 342 1.4 christos if ((mtmp = m_at(u.ux, u.uy)) != NULL) 343 1.4 christos mnexto(mtmp); /* riv05!a3 */ 344 1.1 cgd } 345 1.1 cgd seemons(); 346 1.1 cgd #ifdef NEWS 347 1.4 christos if (flags.nonews || !readnews()) 348 1.1 cgd /* after reading news we did docrt() already */ 349 1.1 cgd #endif 350 1.1 cgd docrt(); 351 1.1 cgd 352 1.1 cgd /* give welcome message before pickup messages */ 353 1.1 cgd pline("Hello %s, welcome to %s!", plname, gamename); 354 1.1 cgd 355 1.1 cgd pickup(1); 356 1.4 christos read_engr_at(u.ux, u.uy); 357 1.1 cgd flags.move = 1; 358 1.1 cgd } 359 1.1 cgd 360 1.1 cgd flags.moonphase = phase_of_the_moon(); 361 1.4 christos if (flags.moonphase == FULL_MOON) { 362 1.1 cgd pline("You are lucky! Full moon tonight."); 363 1.1 cgd u.uluck++; 364 1.4 christos } else if (flags.moonphase == NEW_MOON) { 365 1.1 cgd pline("Be careful! New moon tonight."); 366 1.1 cgd } 367 1.1 cgd initrack(); 368 1.1 cgd 369 1.4 christos for (;;) { 370 1.4 christos if (flags.move) { /* actual time passed */ 371 1.1 cgd 372 1.1 cgd settrack(); 373 1.1 cgd 374 1.4 christos if (moves % 2 == 0 || 375 1.4 christos (!(Fast & ~INTRINSIC) && (!Fast || rn2(3)))) { 376 1.1 cgd movemon(); 377 1.4 christos if (!rn2(70)) 378 1.4 christos (void) makemon((struct permonst *) 0, 0, 0); 379 1.1 cgd } 380 1.4 christos if (Glib) 381 1.4 christos glibr(); 382 1.1 cgd timeout(); 383 1.1 cgd ++moves; 384 1.4 christos if (flags.time) 385 1.4 christos flags.botl = 1; 386 1.4 christos if (u.uhp < 1) { 387 1.1 cgd pline("You die..."); 388 1.1 cgd done("died"); 389 1.1 cgd } 390 1.4 christos if (u.uhp * 10 < u.uhpmax && moves - wailmsg > 50) { 391 1.4 christos wailmsg = moves; 392 1.4 christos if (u.uhp == 1) 393 1.4 christos pline("You hear the wailing of the Banshee..."); 394 1.4 christos else 395 1.4 christos pline("You hear the howling of the CwnAnnwn..."); 396 1.1 cgd } 397 1.4 christos if (u.uhp < u.uhpmax) { 398 1.4 christos if (u.ulevel > 9) { 399 1.4 christos if (Regeneration || !(moves % 3)) { 400 1.4 christos flags.botl = 1; 401 1.4 christos u.uhp += rnd((int) u.ulevel - 9); 402 1.4 christos if (u.uhp > u.uhpmax) 403 1.4 christos u.uhp = u.uhpmax; 404 1.1 cgd } 405 1.4 christos } else if (Regeneration || 406 1.4 christos (!(moves % (22 - u.ulevel * 2)))) { 407 1.1 cgd flags.botl = 1; 408 1.1 cgd u.uhp++; 409 1.1 cgd } 410 1.1 cgd } 411 1.4 christos if (Teleportation && !rn2(85)) 412 1.4 christos tele(); 413 1.4 christos if (Searching && multi >= 0) 414 1.4 christos (void) dosearch(); 415 1.1 cgd gethungry(); 416 1.1 cgd invault(); 417 1.1 cgd amulet(); 418 1.1 cgd } 419 1.4 christos if (multi < 0) { 420 1.4 christos if (!++multi) { 421 1.16 joerg if (nomovemsg) 422 1.16 joerg pline("%s", nomovemsg); 423 1.16 joerg else 424 1.16 joerg pline("You can move again."); 425 1.1 cgd nomovemsg = 0; 426 1.4 christos if (afternmv) 427 1.4 christos (*afternmv) (); 428 1.1 cgd afternmv = 0; 429 1.1 cgd } 430 1.1 cgd } 431 1.1 cgd find_ac(); 432 1.1 cgd #ifndef QUEST 433 1.4 christos if (!flags.mv || Blind) 434 1.1 cgd #endif 435 1.1 cgd { 436 1.1 cgd seeobjs(); 437 1.1 cgd seemons(); 438 1.1 cgd nscr(); 439 1.1 cgd } 440 1.4 christos if (flags.botl || flags.botlx) 441 1.4 christos bot(); 442 1.1 cgd 443 1.1 cgd flags.move = 1; 444 1.1 cgd 445 1.4 christos if (multi >= 0 && occupation) { 446 1.4 christos if (monster_nearby()) 447 1.1 cgd stop_occupation(); 448 1.4 christos else if ((*occupation) () == 0) 449 1.1 cgd occupation = 0; 450 1.1 cgd continue; 451 1.1 cgd } 452 1.4 christos if (multi > 0) { 453 1.1 cgd #ifdef QUEST 454 1.4 christos if (flags.run >= 4) 455 1.4 christos finddir(); 456 1.1 cgd #endif 457 1.1 cgd lookaround(); 458 1.4 christos if (!multi) { /* lookaround may clear multi */ 459 1.1 cgd flags.move = 0; 460 1.1 cgd continue; 461 1.1 cgd } 462 1.4 christos if (flags.mv) { 463 1.4 christos if (multi < COLNO && !--multi) 464 1.1 cgd flags.mv = flags.run = 0; 465 1.1 cgd domove(); 466 1.1 cgd } else { 467 1.1 cgd --multi; 468 1.1 cgd rhack(save_cm); 469 1.1 cgd } 470 1.4 christos } else if (multi == 0) { 471 1.1 cgd #ifdef MAIL 472 1.1 cgd ckmailstatus(); 473 1.1 cgd #endif 474 1.17 dholland rhack(NULL); 475 1.1 cgd } 476 1.4 christos if (multi && multi % 7 == 0) 477 1.1 cgd (void) fflush(stdout); 478 1.1 cgd } 479 1.1 cgd } 480 1.1 cgd 481 1.4 christos void 482 1.11 dholland glo(int foo) 483 1.1 cgd { 484 1.1 cgd /* construct the string xlock.n */ 485 1.13 dholland size_t pos; 486 1.1 cgd 487 1.13 dholland pos = 0; 488 1.13 dholland while (lock[pos] && lock[pos] != '.') 489 1.13 dholland pos++; 490 1.13 dholland (void) snprintf(lock + pos, sizeof(lock) - pos, ".%d", foo); 491 1.1 cgd } 492 1.1 cgd 493 1.1 cgd /* 494 1.1 cgd * plname is filled either by an option (-u Player or -uPlayer) or 495 1.1 cgd * explicitly (-w implies wizard) or by askname. 496 1.1 cgd * It may still contain a suffix denoting pl_character. 497 1.1 cgd */ 498 1.4 christos void 499 1.11 dholland askname(void) 500 1.4 christos { 501 1.4 christos int c, ct; 502 1.1 cgd printf("\nWho are you? "); 503 1.1 cgd (void) fflush(stdout); 504 1.1 cgd ct = 0; 505 1.4 christos while ((c = getchar()) != '\n') { 506 1.4 christos if (c == EOF) 507 1.4 christos error("End of input\n"); 508 1.1 cgd /* some people get confused when their erase char is not ^H */ 509 1.4 christos if (c == '\010') { 510 1.4 christos if (ct) 511 1.4 christos ct--; 512 1.1 cgd continue; 513 1.1 cgd } 514 1.4 christos if (c != '-') 515 1.4 christos if (c < 'A' || (c > 'Z' && c < 'a') || c > 'z') 516 1.4 christos c = '_'; 517 1.10 dholland if (ct < (int)sizeof(plname) - 1) 518 1.4 christos plname[ct++] = c; 519 1.1 cgd } 520 1.1 cgd plname[ct] = 0; 521 1.4 christos if (ct == 0) 522 1.4 christos askname(); 523 1.1 cgd } 524 1.1 cgd 525 1.4 christos /* VARARGS1 */ 526 1.4 christos void 527 1.4 christos impossible(const char *s, ...) 528 1.1 cgd { 529 1.4 christos va_list ap; 530 1.4 christos 531 1.4 christos va_start(ap, s); 532 1.4 christos vpline(s, ap); 533 1.4 christos va_end(ap); 534 1.1 cgd pline("Program in disorder - perhaps you'd better Quit."); 535 1.1 cgd } 536 1.1 cgd 537 1.1 cgd #ifdef CHDIR 538 1.1 cgd static void 539 1.11 dholland chdirx(const char *dir, boolean wr) 540 1.1 cgd { 541 1.1 cgd 542 1.1 cgd #ifdef SECURE 543 1.4 christos if (dir /* User specified directory? */ 544 1.1 cgd #ifdef HACKDIR 545 1.4 christos && strcmp(dir, HACKDIR) /* and not the default? */ 546 1.1 cgd #endif 547 1.1 cgd ) { 548 1.4 christos (void) setuid(getuid()); /* Ron Wessels */ 549 1.1 cgd (void) setgid(getgid()); 550 1.1 cgd } 551 1.1 cgd #endif 552 1.1 cgd 553 1.1 cgd #ifdef HACKDIR 554 1.4 christos if (dir == NULL) 555 1.1 cgd dir = HACKDIR; 556 1.1 cgd #endif 557 1.1 cgd 558 1.4 christos if (dir && chdir(dir) < 0) { 559 1.1 cgd perror(dir); 560 1.1 cgd error("Cannot chdir to %s.", dir); 561 1.1 cgd } 562 1.1 cgd /* warn the player if he cannot write the record file */ 563 1.1 cgd /* perhaps we should also test whether . is writable */ 564 1.1 cgd /* unfortunately the access systemcall is worthless */ 565 1.4 christos if (wr) { 566 1.4 christos int fd; 567 1.1 cgd 568 1.4 christos if (dir == NULL) 569 1.4 christos dir = "."; 570 1.6 jsm if ((fd = open(RECORD, O_RDWR)) < 0) { 571 1.4 christos printf("Warning: cannot write %s/%s", dir, RECORD); 572 1.4 christos getret(); 573 1.4 christos } else 574 1.4 christos (void) close(fd); 575 1.1 cgd } 576 1.1 cgd } 577 1.1 cgd #endif 578 1.1 cgd 579 1.4 christos void 580 1.11 dholland stop_occupation(void) 581 1.1 cgd { 582 1.4 christos if (occupation) { 583 1.1 cgd pline("You stop %s.", occtxt); 584 1.1 cgd occupation = 0; 585 1.1 cgd } 586 1.1 cgd } 587