diff --git a/include/extern.h b/include/extern.h index 070dc9886..73d61975b 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1710792423 2024/03/18 20:07:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1398 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1711213872 2024/03/23 17:11:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1400 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1010,6 +1010,12 @@ extern NHFILE *create_savefile(void); extern NHFILE *open_savefile(void); extern int delete_savefile(void); extern NHFILE *restore_saved_game(void); +extern int check_panic_save(void); +#ifdef SELECTSAVED +extern char *plname_from_file(const char *, boolean) NONNULLARG1; +#endif +extern char **get_saved_games(void); +extern void free_saved_games(char **); extern void nh_compress(const char *); extern void nh_uncompress(const char *); extern boolean lock_file(const char *, int, int) NONNULLARG1; @@ -1032,11 +1038,6 @@ extern int read_sym_file(int); extern void paniclog(const char *, const char *) NONNULLPTRS; extern void testinglog(const char *, const char *, const char *); extern int validate_prefix_locations(char *); -#ifdef SELECTSAVED -extern char *plname_from_file(const char *, boolean) NONNULLARG1; -#endif -extern char **get_saved_games(void); -extern void free_saved_games(char **); #ifdef SELF_RECOVER extern boolean recover_savefile(void); extern void assure_syscf_file(void); @@ -3325,6 +3326,7 @@ extern void tty_utf8graphics_fixup(void); #ifdef UNIX extern void getlock(void); +extern void ask_about_panic_save(void); extern void regularize(char *) NONNULLARG1; #if defined(TIMED_DELAY) && !defined(msleep) && defined(SYSV) extern void msleep(unsigned); diff --git a/include/unixconf.h b/include/unixconf.h index 2c0d133e2..e27f542d2 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixconf.h $NHDT-Date: 1607461111 2020/12/08 20:58:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.49 $ */ +/* NetHack 3.7 unixconf.h $NHDT-Date: 1711213886 2024/03/23 17:11:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.57 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -118,6 +118,21 @@ #define TIMED_DELAY #endif +/* + * At start of game, if there are lock and level files for current + * character in the playground directory, ask whether to recover them + * (into a save file). + */ +/* #define SELF_RECOVER */ + +/* + * At start of game, if there is no save file to restore or lock and + * level files to recover but there is a panic save file for the current + * character, tell the player that it exists and ask whether to start a + * new game. Does not attempt to rename and restore the panic save file. + */ +#define CHECK_PANIC_SAVE + /* #define AVOID_WIN_IOCTL */ /* ensure USE_WIN_IOCTL remains undefined */ /* diff --git a/src/files.c b/src/files.c index 1fddb59d5..b44b2d737 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 files.c $NHDT-Date: 1693083234 2023/08/26 20:53:54 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.378 $ */ +/* NetHack 3.7 files.c $NHDT-Date: 1711213887 2024/03/23 17:11:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.397 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1205,6 +1205,50 @@ restore_saved_game(void) return nhfp; } +/* called if there is no save file for current character */ +int +check_panic_save(void) +{ + int result = 0; +#ifdef CHECK_PANIC_SAVE + FILE *cf; + const char *savef; + + set_error_savefile(); + savef = fqname(gs.SAVEF, SAVEPREFIX, 0); + + /* + * This duplicates part of docompress_file(). + * We don't want to start by uncompressing just to check for the + * file's existence and then have to recompress it. + */ + +#ifdef COMPRESS_EXTENSION + unsigned ln = (unsigned) (strlen(savef) + strlen(COMPRESS_EXTENSION)); + char *cfn = (char *) alloc(ln + 1); + + Strcpy(cfn, savef); + Strcat(cfn, COMPRESS_EXTENSION); + if ((cf = fopen(cfn, RDBMODE)) != NULL) { + (void) fclose(cf); + result = 1; + } + free((genericptr_t) cfn); +#endif /* COMPRESS_EXTENSION */ + + if (!result) { + /* maybe it has already been manually uncompressed */ + if ((cf = fopen(savef, RDBMODE)) != NULL) { + (void) fclose(cf); + result = 1; + } + } + + set_savefile_name(TRUE); /* reset to normal */ +#endif /* CHECK_PANIC_SAVE */ + return result; +} + #if defined(SELECTSAVED) char * @@ -1252,11 +1296,11 @@ plname_from_file(const char *filename, boolean without_wait_synch_per_file) #define EXTSTR "" #endif - if ( sscanf( filename, "%*[^/]/%d%63[^.]" EXTSTR, &uid, name ) == 2 ) { + if (sscanf(filename, "%*[^/]/%d%63[^.]" EXTSTR, &uid, name) == 2) { #undef EXTSTR /* "_" most likely means " ", which certainly looks nicer */ - for (k=0; name[k]; k++) - if ( name[k] == '_' ) + for (k = 0; name[k]; k++) + if (name[k] == '_') name[k] = ' '; return dupstr(name); } else @@ -1376,7 +1420,8 @@ get_saved_games(void) char *r; Sprintf(filename, "save/%d%s", uid, name); - r = plname_from_file(filename, ALLOW_WAITSYNCH_PERFILE); + r = plname_from_file(filename, + ALLOW_WAITSYNCH_PERFILE); if (r) result[j++] = r; } @@ -1629,6 +1674,7 @@ docompress_file(const char *filename, boolean uncomp) } free((genericptr_t) cfn); + return; } #endif /* COMPRESS : external compression */ diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 940b28619..1a22fd96a 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixmain.c $NHDT-Date: 1708737183 2024/02/24 01:13:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.126 $ */ +/* NetHack 3.7 unixmain.c $NHDT-Date: 1711213891 2024/03/23 17:11:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.127 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -305,6 +305,16 @@ main(int argc, char *argv[]) goto attempt_restore; } } + +#ifdef CHECK_PANIC_SAVE + /* no save file; check for a panic save; if the check finds one, + ask the player whether to proceed with a new game; it will + quit instead of returning if the answer isn't yes */ + if (check_panic_save()) + ask_about_panic_save(); +#endif + + /* no save file; start a new game */ newgame(); wd_message(); } diff --git a/sys/unix/unixunix.c b/sys/unix/unixunix.c index 7c21580d4..de465f9b1 100644 --- a/sys/unix/unixunix.c +++ b/sys/unix/unixunix.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixunix.c $NHDT-Date: 1687124609 2023/06/18 21:43:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ */ +/* NetHack 3.7 unixunix.c $NHDT-Date: 1711213894 2024/03/23 17:11:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.43 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -182,14 +182,17 @@ getlock(void) unlock_file(HLOCK); if (iflags.window_inited) { #ifdef SELF_RECOVER - c = yn_function("Old game in progress. Destroy [y], Recover [r], or Cancel [n]?", "ynr", 'n', FALSE); + c = yn_function( + "Old game in progress. Destroy [y], Recover [r], or Cancel [n]?", + "ynr", 'n', FALSE); #else /* this is a candidate for paranoid_confirmation */ c = y_n(destroy_old_game_prompt); #endif } else { #ifdef SELF_RECOVER - (void) raw_printf("\nThere is already a game in progress under your name. Do what?\n"); + (void) raw_printf( + "\nThere is already a game in progress under your name. Do what?\n"); (void) raw_printf("\n y - Destroy old game"); (void) raw_printf("\n r - Try to recover it"); (void) raw_printf("\n n - Cancel"); @@ -241,17 +244,54 @@ getlock(void) unlock_file(HLOCK); if (fd == -1) { error("cannot creat lock file (%s).", fq_lock); + /*NOTREACHED*/ } else { if (write(fd, (genericptr_t) &gh.hackpid, sizeof gh.hackpid) != sizeof gh.hackpid) { error("cannot write lock (%s)", fq_lock); + /*NOTREACHED*/ } if (close(fd) == -1) { error("cannot close lock (%s)", fq_lock); + /*NOTREACHED*/ } } } +/* caller couldn't find a regular save file but did find a panic one */ +void +ask_about_panic_save(void) +{ +#ifdef CHECK_PANIC_SAVE + static const char Instead_prompt[] = "Start a new game instead?"; + int c = '\0'; + + pline("There is no regular save file but there is a panic one."); + pline("It might be recoverable with demi-divine intervention."); + if (iflags.window_inited) { + c = yn_function(Instead_prompt, "yn\033q", 'n', FALSE); + } else { + raw_printf("%s [yn] (n) ", Instead_prompt); + (void) fflush(stdout); + do { + c = getchar(); + if (c == EOF || c == '\033' || c == '\0') + break; + c = lowc(c); + } while (!strchr("ynq\n", c)); + } + if (c != 'y') { + /* caller successfully called getlock() and made .0 */ + delete_levelfile(0); + unlock_file(HLOCK); /* just in case, release 'perm' */ + if (iflags.window_inited) + exit_nhwindows((char *) 0); + nh_terminate(EXIT_SUCCESS); + } +#endif + return; /* proceed with new game */ +} + /* normalize file name - we don't like .'s, /'s, spaces */ void regularize(char *s)