]> granicus.if.org Git - nethack/commitdiff
internal self-recover fix and bones name buffers
authornhmall <nhmall@nethack.org>
Fri, 22 Nov 2019 04:41:11 +0000 (23:41 -0500)
committernhmall <nhmall@nethack.org>
Fri, 22 Nov 2019 04:41:11 +0000 (23:41 -0500)
doc/fixes37.0
include/decl.h
src/files.c
sys/winnt/Makefile.msc
sys/winnt/windmain.c

index ce51bf64fd687e446620c8e1d88c041ec56977c3..08e5903a495082a5bc683ea276c2f5078932659d 100644 (file)
@@ -7,6 +7,8 @@ hero polymorphed into a vampire can use #monster to shape-shift rather than
        just do a one-shot polymorph into bat/cloud/wolf and shifted vampire
        hero can use #monster again to take on another form (randomly chosen
        among the shiftable shapes and true vampire form)
+adjust bones filename buffer sizes to accommodate suffix
+fix internal self-recover to work with recent fields added to checkpoint file
 
 
 Fixes to Pre-3.7.0 Problems that Were Exposed Via git Repository
index c57eafc18938cd2e297cceb8cf0f9b2f04cd1a3d..4cd23a7bc60b9807254f1ae35cd520ddbe1df594 100644 (file)
@@ -10,7 +10,7 @@
 #if !defined(MICRO) && !defined(VMS) && !defined(WIN32)
 #define LOCKNAMESIZE (PL_NSIZ + 14) /* long enough for uid+name+.99 */
 #define LOCKNAMEINIT "1lock"
-#define BONESINIT "bonesnn.xxx"
+#define BONESINIT "bonesnn.xxx.le"
 #define BONESSIZE sizeof(BONESINIT)
 #else
 #if defined(MICRO)
 #if defined(VMS)
 #define LOCKNAMESIZE (PL_NSIZ + 17) /* long enough for _uid+name+.99;1 */
 #define LOCKNAMEINIT "1lock"
-#define BONESINIT "bonesnn.xxx;1"
+#define BONESINIT "bonesnn.xxx_le;1"
 #define BONESSIZE sizeof(BONESINIT)
 #endif
 #if defined(WIN32)
 #define LOCKNAMESIZE (PL_NSIZ + 25) /* long enough for username+-+name+.99 */
 #define LOCKNAMEINIT ""
-#define BONESINIT "bonesnn.xxx"
+#define BONESINIT "bonesnn.xxx.le"
 #define BONESSIZE sizeof(BONESINIT)
 #endif
 #endif
@@ -170,6 +170,7 @@ struct sinfo {
     int exiting;                /* an exit handler is executing */
     int in_moveloop;
     int in_impossible;
+    int in_self_recover;
 #ifdef PANICLOG
     int in_paniclog;
 #endif
index 6677f3e64ed0e4885bfffee7fb2c767a1415e3ef..eb8f09756a13ec536caabc76697be693bc8f4c66 100644 (file)
@@ -757,12 +757,12 @@ d_level *lev;
     char *dptr;
 
     /*
-     * "bonD0.nn"   = bones for level nn in the main dungeon;
-     * "bonM0.T"    = bones for Minetown;
-     * "bonQBar.n"  = bones for level n in the Barbarian quest;
-     * "bon3D0.nn"  = \
-     * "bon3M0.T"   =  > same as above, but for bones pool #3.
-     * "bon3QBar.n" = /
+     * "bonD0.nn.le"   = bones for level nn in the main dungeon;
+     * "bonM0.T.le"    = bones for Minetown;
+     * "bonQBar.n.le"  = bones for level n in the Barbarian quest;
+     * "bon3D0.nn.le"  = \
+     * "bon3M0.T.le"   =  > same as above, but for bones pool #3.
+     * "bon3QBar.n.le" = /
      *
      * Return value for content validation skips "bon" and the
      * pool number (if present), making it feasible for the admin
@@ -1032,6 +1032,17 @@ boolean regularize_it;
     if (idx > historical && idx <= ascii)
         sfindicator = sfoprocs[idx].ext;
 #endif
+    if (g.program_state.in_self_recover) {
+        /* self_recover needs to be done as historical
+           structlevel content until that process is
+           re-written to use something other than
+           copy_bytes() to retrieve data content from
+           level files (which are structlevel) and
+           place it into the save file.
+        */
+        idx = historical;
+        sfindicator = sfoprocs[idx].ext;
+    }
 #ifdef VMS
     Sprintf(g.SAVEF, "[.save]%d%s", getuid(), g.plname);
     regoffset = 7;
@@ -1108,7 +1119,7 @@ boolean regularize_it;
                (idx == lendian) ? 'l' :
                (idx == ascii)   ? 'a' : '\0';
        }
-        sfindicator = sfoprocs[idx].ext;
+        sfindicator = (g.program_state.in_self_recover) ? "" : sfoprocs[idx].ext;
 #endif
 #endif
         } else
@@ -1176,6 +1187,7 @@ create_savefile()
     int failed = 0;
     const char *fq_save;
     NHFILE *nhfp = (NHFILE *) 0;
+    boolean do_historical = TRUE;
 
     fq_save = fqname(g.SAVEF, SAVEPREFIX, 0);
     nhfp = new_nhfile();
@@ -1186,7 +1198,21 @@ create_savefile()
         nhfp->mode = WRITING;
 #ifdef SYSCF
         if (sysopt.saveformat[0] > historical &&
-            sysopt.saveformat[0] <= ascii) {
+            sysopt.saveformat[0] <= ascii)
+            do_historical = FALSE;
+#endif /* SYSCF */
+        if (g.program_state.in_self_recover) {
+            do_historical = TRUE;       /* force it */
+            nhfp->structlevel = TRUE;
+            nhfp->fieldlevel = FALSE;
+            nhfp->addinfo = FALSE;
+            nhfp->style.deflt = FALSE;
+            nhfp->style.binary = TRUE;
+            nhfp->fnidx = historical;
+            nhfp->fd = -1;
+            nhfp->fpdef = (FILE *) 0;
+        }
+        if (!do_historical) {
             nhfp->structlevel = FALSE;
             nhfp->fieldlevel = TRUE;
             nhfp->addinfo = TRUE;
@@ -1203,7 +1229,6 @@ create_savefile()
                 failed = errno;
             }
         }
-#endif /* SYSCF */
         if (nhfp->structlevel) {
 #if defined(MICRO) || defined(WIN32)
             nhfp->fd = open(fq_save, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK);
@@ -1240,6 +1265,7 @@ open_savefile()
     int failed = 0;
     const char *fq_save;
     NHFILE *nhfp = (NHFILE *) 0;
+    boolean do_historical = TRUE;
 
     fq_save = fqname(g.SAVEF, SAVEPREFIX, 0);
     nhfp = new_nhfile();
@@ -1250,7 +1276,21 @@ open_savefile()
         nhfp->mode = READING;
 #ifdef SYSCF
         if (sysopt.saveformat[0] > historical &&
-            sysopt.saveformat[0] <= ascii) {
+            sysopt.saveformat[0] <= ascii)
+            do_historical = FALSE;
+#endif /* SYSCF */
+        if (g.program_state.in_self_recover) {
+            do_historical = TRUE;       /* force it */
+            nhfp->structlevel = TRUE;
+            nhfp->fieldlevel = FALSE;
+            nhfp->addinfo = FALSE;
+            nhfp->style.deflt = FALSE;
+            nhfp->style.binary = TRUE;
+            nhfp->fnidx = historical;
+            nhfp->fd = -1;
+            nhfp->fpdef = (FILE *) 0;
+        }
+        if (!do_historical) {
             nhfp->structlevel = FALSE;
             nhfp->fieldlevel = TRUE;
             nhfp->addinfo = TRUE;
@@ -1267,7 +1307,6 @@ open_savefile()
                 failed = errno;
             }
         }
-#endif /* SYSCF */
         if (nhfp->structlevel) {
 #ifdef MAC
             nhfp->fd = macopen(fq_save, O_RDONLY | O_BINARY, SAVE_TYPE);
@@ -3943,14 +3982,15 @@ boolean
 recover_savefile()
 {
     NHFILE *gnhfp, *lnhfp, *snhfp;
-    int lev, savelev, hpid, pltmpsiz;
+    int lev, savelev, hpid, pltmpsiz, filecmc;
     xchar levc;
     struct version_info version_data;
     int processed[256];
-    char savename[SAVESIZE], errbuf[BUFSZ];
+    char savename[SAVESIZE], errbuf[BUFSZ], indicator;
     struct savefile_info sfi;
     char tmpplbuf[PL_NSIZ];
-
+    const char *savewrite_failure = (const char *) 0;
+    
     for (lev = 0; lev < 256; lev++)
         processed[lev] = 0;
 
@@ -3985,6 +4025,10 @@ recover_savefile()
     }
     if ((read(gnhfp->fd, (genericptr_t) savename, sizeof savename)
          != sizeof savename)
+        || (read(gnhfp->fd, (genericptr_t) &indicator, sizeof indicator)
+            != sizeof indicator)
+        || (read(gnhfp->fd, (genericptr_t) &filecmc, sizeof filecmc)
+            != sizeof filecmc)
         || (read(gnhfp->fd, (genericptr_t) &version_data, sizeof version_data)
             != sizeof version_data)
         || (read(gnhfp->fd, (genericptr_t) &sfi, sizeof sfi) != sizeof sfi)
@@ -3997,6 +4041,7 @@ recover_savefile()
     }
 
     /* save file should contain:
+     *  format indicator and cmc
      *  version info
      *  savefile info
      *  player name
@@ -4004,6 +4049,22 @@ recover_savefile()
      *  (non-level-based) game state
      *  other levels
      */
+
+    /*
+     * Things are different now. We could be in a situation
+     * where the default save file format is not structlevel.
+     * self-recover is currently written to use copy_bytes()
+     * to move content from the level files into the savefile.
+     * Until the code is updated to use something other than
+     * copy_bytes, what we need to do is force the recovery
+     * save to be structlevel, finish creating it, then read
+     * it back in. The save after that can be fieldlevel again.
+     *
+     * Set a flag for the savefile routines to know the
+     * circumstances and act accordingly:
+     *    g.program_state.in_self_recover
+     */
+    g.program_state.in_self_recover = TRUE;
     set_savefile_name(TRUE);
     snhfp = create_savefile();
     if (!snhfp) {
@@ -4021,47 +4082,66 @@ recover_savefile()
         return FALSE;
     }
 
-    if (write(snhfp->fd, (genericptr_t) &version_data, sizeof version_data)
-        != sizeof version_data) {
-        raw_printf("\nError writing %s; recovery failed.", g.SAVEF);
-        close_nhfile(gnhfp);
-        close_nhfile(snhfp);
-        close_nhfile(lnhfp);
-        delete_savefile();
-        return FALSE;
+    /*
+     * Our savefile output format might _not_ be structlevel.
+     * We have to check and use the correct output routine here.
+     */
+    /*store_formatindicator(snhfp); */
+    store_version(snhfp);
+#if 0
+    if (snhfp->structlevel) {
+        if (write(snhfp->fd, (genericptr_t) &version_data, sizeof version_data)
+            != sizeof version_data)
+            savewrite_failure = "version_info";
+    }
+    if (snhfp->fieldlevel) {
+        sfo_version_info(snhfp, (struct version_info *) &version_data,
+                         "version", "version_info", 1);
+        savewrite_failure = (const char *) 0;
     }
+    if (savewrite_failure)
+        goto cleanup;
+#endif
 
-    if (write(snhfp->fd, (genericptr_t) &sfi, sizeof sfi) != sizeof sfi) {
-        raw_printf("\nError writing %s; recovery failed (savefile_info).\n",
-                   g.SAVEF);
-        close_nhfile(gnhfp);
-        close_nhfile(snhfp);
-        close_nhfile(lnhfp);
-        delete_savefile();
-        return FALSE;
+    if (snhfp->structlevel) {
+        if (write(snhfp->fd, (genericptr_t) &sfi, sizeof sfi) != sizeof sfi)
+            savewrite_failure = "savefileinfo";
+    }
+    if (snhfp->fieldlevel) {
+        sfo_savefile_info(snhfp, &sfsaveinfo, "savefileinfo", "savefile_info", 1);
+        savewrite_failure = (const char *) 0;
     }
+    if (savewrite_failure)
+        goto cleanup;
 
-    if (write(snhfp->fd, (genericptr_t) &pltmpsiz, sizeof pltmpsiz)
-        != sizeof pltmpsiz) {
-        raw_printf("Error writing %s; recovery failed (player name size).\n",
-                   g.SAVEF);
-        close_nhfile(gnhfp);
-        close_nhfile(snhfp);
-        close_nhfile(lnhfp);
-        delete_savefile();
-        return FALSE;
+    if (snhfp->structlevel) {         
+        if (write(snhfp->fd, (genericptr_t) &pltmpsiz, sizeof pltmpsiz)
+            != sizeof pltmpsiz)
+            savewrite_failure = "player name size";
     }
+    if (snhfp->fieldlevel) {
+        sfo_int(snhfp, &pltmpsiz, "plname", "plname_size", 1);
+        savewrite_failure = (const char *) 0;
+    }
+    if (savewrite_failure)
+        goto cleanup;
 
-    if (write(snhfp->fd, (genericptr_t) &tmpplbuf, pltmpsiz) != pltmpsiz) {
-        raw_printf("Error writing %s; recovery failed (player name).\n",
-                   g.SAVEF);
-        close_nhfile(gnhfp);
-        close_nhfile(snhfp);
-        close_nhfile(lnhfp);
-        delete_savefile();
-        return FALSE;
+    if (snhfp->structlevel) {
+        if (write(snhfp->fd, (genericptr_t) &tmpplbuf, pltmpsiz) != pltmpsiz)
+            savewrite_failure = "player name";
+    }
+    if (snhfp->fieldlevel) {
+        sfo_str(snhfp, tmpplbuf, "plname", "tmpplbuf", pltmpsiz);
+        savewrite_failure = (const char *) 0;
     }
+    if (savewrite_failure)
+        goto cleanup;
 
+    /*
+     * copy_bytes isn't good enough anymore.
+     * We could be reading from a structlevel file but
+     * writing into a fieldlevel save file. Yikes!
+     */
     if (!copy_bytes(lnhfp->fd, snhfp->fd)) {
         close_nhfile(gnhfp);
         close_nhfile(snhfp);
@@ -4116,6 +4196,20 @@ recover_savefile()
             (void) unlink(fq_lock);
         }
     }
+ cleanup:
+    if (savewrite_failure) {
+        raw_printf("\nError writing %s; recovery failed (%s).\n",
+                   g.SAVEF, savewrite_failure);
+        close_nhfile(gnhfp);
+        close_nhfile(snhfp);
+        close_nhfile(lnhfp);
+        g.program_state.in_self_recover = FALSE;
+        delete_savefile();
+        return FALSE;
+    }
+    /* we don't clear g.program_state.in_self_recover here, we
+       leave it as a flag to reload the structlevel savefile
+       in the caller. The caller should then clear it. */
     return TRUE;
 }
 
index a4449bf763c2f0b5c9fdbe078744ec309d1b8326..484f5576efaddbd6880089632b6b26c5fc590638 100644 (file)
@@ -2027,6 +2027,7 @@ $(O)vision.o: vision.c $(HACK_H) $(INCL)\vis_tab.h
 $(O)weapon.o: weapon.c $(HACK_H)
 $(O)were.o: were.c $(HACK_H)
 $(O)wield.o: wield.c $(HACK_H)
+$(O)windmain.o: $(MSWSYS)\windmain.c $(HACK_H)
 #$(O)windows.o: windows.c $(HACK_H) $(INCL)\wingem.h $(INCL)\winGnome.h
 $(O)wizard.o: wizard.c $(HACK_H) $(INCL)\qtext.h
 $(O)worm.o: worm.c $(HACK_H) $(INCL)\lev.h
index 56b4e3c6fe60c8aa62bd56efbb0344ddff6e6259..9b2e8f4bed545dba63296648be416be45f4d37c1 100644 (file)
@@ -503,6 +503,10 @@ attempt_restore:
                 }
             }
         }
+        if (g.program_state.in_self_recover) {
+            g.program_state.in_self_recover = FALSE;
+            set_savefile_name(TRUE);
+       }
     }
 
     if (!resuming) {