]> granicus.if.org Git - nethack/commitdiff
level file handling and trickery feedback
authornethack.rankin <nethack.rankin>
Fri, 23 Aug 2002 14:52:25 +0000 (14:52 +0000)
committernethack.rankin <nethack.rankin>
Fri, 23 Aug 2002 14:52:25 +0000 (14:52 +0000)
1) consolidate all core usage of `errno' in files.c;
2) give more feedback for any failure by create_levelfile or open_levelfile,
   similar to what was being done for problems during level change;
3) include trickery info in paniclog (many instances of "trickery" seem to
   be due to disk or quota problems rather than user misbehavior...).

The create_levelfile call in pcmain probably ought to be changed to use
error feedback, but in the meantime this should continue working.

Perhaps error() should be modified to update paniclog too, but I didn't
want to go through all its port-specific incarnations making changes.

include/extern.h
src/do.c
src/end.c
src/files.c
src/restore.c
src/save.c
sys/share/pcmain.c

index cbc02543c7d72a29df52a2e1211d9ff511b68bf1..d1429d6d510bb61536dd586786dd2cc6d68a8e20 100644 (file)
@@ -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 *));
index e320e28a80fae97eaeb42257e1687273d8a98a7e..35eef72f37f09f57179eb3ce2a49577dc6ed84af 100644 (file)
--- a/src/do.c
+++ b/src/do.c
@@ -7,19 +7,6 @@
 #include "hack.h"
 #include "lev.h"
 
-#include <errno.h>
-#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.");
index d3b36782a12dba1a18d1426759ee38c5dc29a578..d63a9aac656e00b8c835af5a748957574811ec45 100644 (file)
--- 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...");
index dce5f8c5048dd46e1b305f416f99419adbdcab80..d44824ef68f01bf90694b33ad24a1dd1dc9ed69e 100644 (file)
 #include <fcntl.h>
 #endif
 
-#if defined(NOCWD_ASSUMPTIONS)
 #include <errno.h>
+#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)
 #endif
 
 #if defined(UNIX) || defined(VMS)
-#include <errno.h>
-# ifndef SKIP_ERRNO
-extern int errno;
-# endif
 #include <signal.h>
 #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;
index 3874c5f2ac80514de00d856f1c328aa3adad88fd..e044f0bee44d2bd4ea592fdf7661114550d92048 100644 (file)
@@ -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
index ee4d51e1fa9b67e1d0bbbcaee9077b3bb6ccd88c..d6bd9509a409054f052b8a4ccd340b545724f360 100644 (file)
@@ -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 <signal.h>
@@ -12,8 +13,6 @@
 #include <fcntl.h>
 #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;
                }
index 41d8ed31c2315c01e57e10168a0bbf143642c8ad..6b1d91db4580949bd0bdb230ccd7004a3e87cd43 100644 (file)
@@ -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 {