| 2862 | extern uchar critical_sizes[], cscbuf[]; /* version.c */ |
| 2863 | |
| 2864 | boolean |
| 2865 | recover_savefile(void) |
| 2866 | { |
| 2867 | NHFILE *gnhfp, *lnhfp, *snhfp; |
| 2868 | int lev, savelev, hpid, |
| 2869 | pltmpsiz, cscount = get_critical_size_count(); |
| 2870 | xint8 levc; |
| 2871 | struct version_info version_data; |
| 2872 | int processed[256]; |
| 2873 | char savename[SAVESIZE], errbuf[BUFSZ], indicator, file_cscount; |
| 2874 | char tmpplbuf[PL_NSIZ_PLUS]; |
| 2875 | const char *savewrite_failure = (const char *) 0; |
| 2876 | off_t filesz = 0; |
| 2877 | |
| 2878 | for (lev = 0; lev < 256; lev++) |
| 2879 | processed[lev] = 0; |
| 2880 | |
| 2881 | /* level 0 file contains: |
| 2882 | * pid of creating process (ignored here) |
| 2883 | * level number for current level of save file |
| 2884 | * name of save file nethack would have created |
| 2885 | * player name |
| 2886 | * and game state |
| 2887 | */ |
| 2888 | |
| 2889 | gnhfp = open_levelfile(0, errbuf); |
| 2890 | if (!gnhfp) { |
| 2891 | raw_printf("%s\n", errbuf); |
| 2892 | return FALSE; |
| 2893 | } |
| 2894 | filesz = lseek(gnhfp->fd, 0L, SEEK_END); |
| 2895 | (void) lseek(gnhfp->fd, 0L, SEEK_SET); |
| 2896 | if ((size_t) filesz < (sizeof hpid |
| 2897 | + sizeof lev |
| 2898 | + sizeof savename |
| 2899 | + sizeof indicator |
| 2900 | + sizeof file_cscount |
| 2901 | + sizeof version_data + sizeof pltmpsiz)) { |
| 2902 | const char *fq_save; |
| 2903 | |
| 2904 | /* this indicates a .0 file that was created as part of |
| 2905 | * recover that did not complete. There could be an intact |
| 2906 | * savefile already there. Check for that and return TRUE |
| 2907 | * if there is. */ |
| 2908 | set_savefile_name(TRUE); |
| 2909 | fq_save = fqname(gs.SAVEF, SAVEPREFIX, 0); |
| 2910 | if (access(fq_save, F_OK) == 0) { |
| 2911 | close_nhfile(gnhfp); |
| 2912 | delete_levelfile(0); |
| 2913 | return TRUE; |
| 2914 | } else { |
| 2915 | /* savefile doesn't exist, so fall through */ |
| 2916 | } |
| 2917 | } |
| 2918 | if (read(gnhfp->fd, (genericptr_t) &hpid, sizeof hpid) != sizeof hpid) { |
| 2919 | raw_printf("\n%s\n%s\n", |
| 2920 | "Checkpoint data incompletely written" |
| 2921 | " or subsequently clobbered.", |
no test coverage detected