diff --git a/include/extern.h b/include/extern.h index cbc02543c..d1429d6d5 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)extern.h 3.4 2002/03/29 */ +/* SCCS Id: @(#)extern.h 3.4 2002/08/22 */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -605,8 +605,8 @@ E void FDECL(store_version, (int)); E void NDECL(set_lock_and_bones); #endif E void FDECL(set_levelfile_name, (char *,int)); -E int FDECL(create_levelfile, (int)); -E int FDECL(open_levelfile, (int)); +E int FDECL(create_levelfile, (int,char *)); +E int FDECL(open_levelfile, (int,char *)); E void FDECL(delete_levelfile, (int)); E void NDECL(clearlocks); E int FDECL(create_bonesfile, (d_level*,char **)); @@ -1643,7 +1643,7 @@ E NhRegion* FDECL(create_gas_cloud, (XCHAR_P, XCHAR_P, int, int)); E void FDECL(inven_inuse, (BOOLEAN_P)); E int FDECL(dorecover, (int)); -E void NDECL(trickery); +E void FDECL(trickery, (char *)); E void FDECL(getlev, (int,int,XCHAR_P,BOOLEAN_P)); E void NDECL(minit); E boolean FDECL(lookup_id_mapping, (unsigned, unsigned *)); diff --git a/src/do.c b/src/do.c index e320e28a8..35eef72f3 100644 --- a/src/do.c +++ b/src/do.c @@ -7,19 +7,6 @@ #include "hack.h" #include "lev.h" -#include -#ifdef _MSC_VER /* MSC 6.0 defines errno quite differently */ -# if (_MSC_VER >= 600) -# define SKIP_ERRNO -# endif -#endif -#ifndef SKIP_ERRNO -#ifdef _DCC -const -#endif -extern int errno; -#endif - #ifdef SINKS # ifdef OVLB STATIC_DCL void FDECL(trycall, (struct obj *)); @@ -838,14 +825,14 @@ STATIC_OVL int currentlevel_rewrite() { register int fd; + char whynot[BUFSZ]; /* since level change might be a bit slow, flush any buffered screen * output (like "you fall through a trap door") */ mark_synch(); - fd = create_levelfile(ledger_no(&u.uz)); - - if(fd < 0) { + fd = create_levelfile(ledger_no(&u.uz), whynot); + if (fd < 0) { /* * This is not quite impossible: e.g., we may have * exceeded our quota. If that is the case then we @@ -853,8 +840,7 @@ currentlevel_rewrite() * Another possibility is that the directory was not * writable. */ - pline("Cannot create level file for level %d.", - ledger_no(&u.uz)); + pline("%s", whynot); return -1; } @@ -914,6 +900,7 @@ boolean at_stairs, falling, portal; familiar = FALSE; boolean new = FALSE; /* made a new level? */ struct monst *mtmp; + char whynot[BUFSZ]; if (dunlev(newlevel) > dunlevs_in_dungeon(newlevel)) newlevel->dlevel = dunlevs_in_dungeon(newlevel); @@ -1049,11 +1036,11 @@ boolean at_stairs, falling, portal; new = TRUE; /* made the level */ } else { /* returning to previously visited level; reload it */ - fd = open_levelfile(new_ledger); + fd = open_levelfile(new_ledger, whynot); if (fd < 0) { - pline("Cannot open file (#%d) for level %d (errno %d).", - (int) new_ledger, depth(&u.uz), errno); + pline("%s", whynot); pline("Probably someone removed it."); + killer = whynot; done(TRICKED); /* we'll reach here if running in wizard mode */ error("Cannot continue this game."); diff --git a/src/end.c b/src/end.c index d3b36782a..d63a9aac6 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)end.c 3.4 2001/09/24 */ +/* SCCS Id: @(#)end.c 3.4 2002/08/22 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -549,6 +549,19 @@ int how; struct obj *corpse = (struct obj *)0; long umoney; + if (how == TRICKED) { + if (killer) { + paniclog("trickery", killer); + killer = 0; + } +#ifdef WIZARD + if (wizard) { + You("are a very tricky wizard, it seems."); + return; + } +#endif + } + /* kilbuf: used to copy killer in case it comes from something like * xname(), which would otherwise get overwritten when we call * xname() when listing possessions @@ -561,12 +574,7 @@ int how; killer_format = KILLED_BY; Strcpy(kilbuf, (!killer || how >= PANICKED ? deaths[how] : killer)); killer = kilbuf; -#ifdef WIZARD - if (wizard && how == TRICKED) { - You("are a very tricky wizard, it seems."); - return; - } -#endif + if (how < PANICKED) u.umortality++; if (Lifesaved && (how <= GENOCIDED)) { pline("But wait..."); diff --git a/src/files.c b/src/files.c index dce5f8c50..d44824ef6 100644 --- a/src/files.c +++ b/src/files.c @@ -15,8 +15,17 @@ #include #endif -#if defined(NOCWD_ASSUMPTIONS) #include +#ifdef _MSC_VER /* MSC 6.0 defines errno quite differently */ +# if (_MSC_VER >= 600) +# define SKIP_ERRNO +# endif +#endif +#ifndef SKIP_ERRNO +# ifdef _DCC +const +# endif +extern int errno; #endif #if defined(UNIX) && defined(QT_GRAPHICS) @@ -24,10 +33,6 @@ #endif #if defined(UNIX) || defined(VMS) -#include -# ifndef SKIP_ERRNO -extern int errno; -# endif #include #endif @@ -404,12 +409,14 @@ int lev; } int -create_levelfile(lev) +create_levelfile(lev, errbuf) int lev; +char errbuf[]; { int fd; const char *fq_lock; + if (errbuf) *errbuf = '\0'; set_levelfile_name(lock, lev); fq_lock = fqname(lock, LEVELPREFIX, 0); @@ -434,18 +441,24 @@ int lev; if (fd >= 0) level_info[lev].flags |= LFILE_EXISTS; + else if (errbuf) /* failure explanation */ + Sprintf(errbuf, + "Cannot create file \"%s\" for level %d (errno %d).", + lock, lev, errno); return fd; } int -open_levelfile(lev) +open_levelfile(lev, errbuf) int lev; +char errbuf[]; { int fd; const char *fq_lock; + if (errbuf) *errbuf = '\0'; set_levelfile_name(lock, lev); fq_lock = fqname(lock, LEVELPREFIX, 0); #ifdef MFLOPPY @@ -463,6 +476,15 @@ int lev; # endif fd = open(fq_lock, O_RDONLY | O_BINARY, 0); #endif + + /* for failure, return an explanation that our caller can use; + settle for `lock' instead of `fq_lock' because the latter + might end up being too big for nethack's BUFSZ */ + if (fd < 0 && errbuf) + Sprintf(errbuf, + "Cannot open file \"%s\" for level %d (errno %d).", + lock, lev, errno); + return fd; } @@ -553,7 +575,7 @@ int fd; { if (lftrack.fd == fd) { really_close(); /* close it, but reopen it to hold it */ - fd = open_levelfile(0); + fd = open_levelfile(0, (char *)0); lftrack.nethack_thinks_it_is_open = FALSE; return 0; } @@ -2180,7 +2202,7 @@ recover_savefile() xchar levc; struct version_info version_data; int processed[256]; - char savename[SAVESIZE]; + char savename[SAVESIZE], errbuf[BUFSZ]; for (lev = 0; lev < 256; lev++) processed[lev] = 0; @@ -2191,9 +2213,9 @@ recover_savefile() * name of save file nethack would have created * and game state */ - gfd = open_levelfile(0); + gfd = open_levelfile(0, errbuf); if (gfd < 0) { - raw_printf("Cannot open level 0 for %s.\n", lock); + raw_printf("%s\n", errbuf); return FALSE; } if (read(gfd, (genericptr_t) &hpid, sizeof hpid) != sizeof hpid) { @@ -2232,9 +2254,9 @@ recover_savefile() return FALSE; } - lfd = open_levelfile(savelev); + lfd = open_levelfile(savelev, errbuf); if (lfd < 0) { - raw_printf("\nCannot open level of save for %s.\n", lock); + raw_printf("\n%s\n", errbuf); (void)close(gfd); (void)close(sfd); delete_savefile(); @@ -2273,7 +2295,7 @@ recover_savefile() * maximum level number (for the endlevel) must be < 256 */ if (lev != savelev) { - lfd = open_levelfile(lev); + lfd = open_levelfile(lev, (char *)0); if (lfd >= 0) { /* any or all of these may not exist */ levc = (xchar) lev; diff --git a/src/restore.c b/src/restore.c index 3874c5f2a..e044f0bee 100644 --- a/src/restore.c +++ b/src/restore.c @@ -484,10 +484,14 @@ xchar ltmp; #endif { register int nfd; + char whynot[BUFSZ]; - nfd = create_levelfile(ltmp); - - if (nfd < 0) panic("Cannot open temp level %d!", ltmp); + nfd = create_levelfile(ltmp, whynot); + if (nfd < 0) { + /* BUG: should suppress any attempt to write a panic + save file if file creation is now failing... */ + panic("restlevelfile: %s", whynot); + } #ifdef MFLOPPY if (!savelev(nfd, ltmp, COUNT_SAVE)) { @@ -675,11 +679,13 @@ register int fd; } void -trickery() +trickery(reason) +char *reason; { pline("Strange, this map is not as I remember it."); pline("Somebody is trying some trickery here..."); pline("This game is void."); + killer = reason; done(TRICKED); } @@ -719,16 +725,18 @@ boolean ghostly; #else mread(fd, (genericptr_t) &dlvl, sizeof(dlvl)); #endif - if((pid && pid != hpid) || (lev && dlvl != lev)) { + if ((pid && pid != hpid) || (lev && dlvl != lev)) { + char trickbuf[BUFSZ]; + + if (pid && pid != hpid) + Sprintf(trickbuf, "PID (%d) doesn't match saved PID (%d)!", + hpid, pid); + else + Sprintf(trickbuf, "This is level %d, not %d!", dlvl, lev); #ifdef WIZARD - if (wizard) { - if (pid && pid != hpid) - pline("PID (%d) doesn't match saved PID (%d)!", hpid, pid); - else if (lev && dlvl != lev) - pline("This is level %d, not %d!", dlvl, lev); - } + if (wizard) pline(trickbuf); #endif - trickery(); + trickery(trickbuf); } #ifdef RLECOMP diff --git a/src/save.c b/src/save.c index ee4d51e1f..d6bd9509a 100644 --- a/src/save.c +++ b/src/save.c @@ -1,9 +1,10 @@ -/* SCCS Id: @(#)save.c 3.4 2002/01/19 */ +/* SCCS Id: @(#)save.c 3.4 2002/08/22 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" #include "lev.h" +#include "quest.h" #ifndef NO_SIGNAL #include @@ -12,8 +13,6 @@ #include #endif -#include "quest.h" - #ifdef MFLOPPY long bytes_counted; static int count_only; @@ -117,6 +116,7 @@ dosave0() register int fd, ofd; xchar ltmp; d_level uz_save; + char whynot[BUFSZ]; if (!SAVEF[0]) return 0; @@ -150,7 +150,6 @@ dosave0() HUP mark_synch(); /* flush any buffered screen output */ fd = create_savefile(); - if(fd < 0) { HUP pline("Cannot open save file."); (void) delete_savefile(); /* ab@unido */ @@ -243,11 +242,12 @@ dosave0() } mark_synch(); #endif - ofd = open_levelfile(ltmp); + ofd = open_levelfile(ltmp, whynot); if (ofd < 0) { - HUP pline("Cannot read level %d.", ltmp); + HUP pline("%s", whynot); (void) close(fd); (void) delete_savefile(); + HUP killer = whynot; HUP done(TRICKED); return(0); } @@ -328,6 +328,7 @@ savestateinlock() { int fd, hpid; static boolean havestate = TRUE; + char whynot[BUFSZ]; /* When checkpointing is on, the full state needs to be written * on each checkpoint. When checkpointing is off, only the pid @@ -347,24 +348,30 @@ savestateinlock() * to any internal compression schemes since they must be * readable by an external utility */ - fd = open_levelfile(0); + fd = open_levelfile(0, whynot); if (fd < 0) { - pline("Cannot open level 0."); + pline("%s", whynot); pline("Probably someone removed it."); + killer = whynot; done(TRICKED); return; } (void) read(fd, (genericptr_t) &hpid, sizeof(hpid)); if (hackpid != hpid) { - pline("Level 0 pid bad!"); + Sprintf(whynot, + "Level #0 pid (%d) doesn't match ours (%d)!", + hpid, hackpid); + pline("%s", whynot); + killer = whynot; done(TRICKED); } (void) close(fd); - fd = create_levelfile(0); + fd = create_levelfile(0, whynot); if (fd < 0) { - pline("Cannot rewrite level 0."); + pline("%s", whynot); + killer = whynot; done(TRICKED); return; } diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 41d8ed31c..6b1d91db4 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)pcmain.c 3.4 1997/01/22 */ +/* SCCS Id: @(#)pcmain.c 3.4 2002/08/22 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -338,7 +338,7 @@ char *argv[]; /* Set up level 0 file to keep the game state. */ - fd = create_levelfile(0); + fd = create_levelfile(0, (char *)0); if (fd < 0) { raw_print("Cannot create lock file"); } else {