/* * Savefile handling. * * Savefiles are lightly obfuscated. In an open-source program, of * course, we cannot *prevent* people from fudging savefiles. But we * can at least stop the doorknob-rattlers. */ #include #include #include #include #include #include "pline.h" #include "screen.h" #include "mon-@-you.h" #include "stdio-util.h" #include "save.h" #define EB 189 #define CSE 73 #define CSB 69 #define CP 3988292384UL static const unsigned char dv[EB] = { 219, 112, 43, 250, 206, 66, 222, 81, 180, 69, 71, 60, 195, 208, 165, 248, 57, 115, 223, 34, 96, 109, 41, 188, 194, 52, 216, 161, 185, 75, 251, 45, 62, 93, 247, 240, 213, 242, 67, 44, 196, 82, 198, 94, 174, 192, 239, 46, 49, 190, 167, 177, 252, 50, 163, 102, 123, 179, 113, 70, 176, 87, 89, 168, 255, 235, 119, 230, 68, 37, 63, 61, 80, 181, 91, 173, 39, 111, 74, 120, 101, 100, 186, 118, 187, 164, 227, 35, 197, 243, 231, 105, 199, 237, 210, 55, 217, 184, 254, 48, 72, 162, 36, 85, 166, 233, 253, 92, 221, 204, 236, 40, 114, 189, 171, 90, 211, 33, 169, 220, 218, 88, 79, 215, 200, 83, 97, 238, 76, 56, 47, 65, 193, 203, 104, 228, 182, 86, 42, 98, 178, 54, 249, 77, 121, 207, 124, 175, 99, 107, 53, 126, 241, 209, 78, 117, 103, 214, 201, 205, 212, 232, 172, 106, 224, 110, 244, 226, 73, 225, 38, 202, 246, 64, 58, 245, 191, 116, 122, 234, 170, 84, 229, 59, 183, 108, 125, 51, 95 }; static char *encode(const char *b, int l, FILE *to) { if (fwrite(b,1,l,to) < l) return(strdup("fwrite failed")); if (fflush(to) == EOF) return(strdup("fflush failed")); return(0); } static char *gen_save(FILE *f) { if (fprintf(f,"foo\n") < 0) return(strdup("fprintf failed")); return(0); } /* * Save the game to fn. If successful, this does not return (it * exits); on failure, returns, after doing pline() or the like to * report the error(s). */ void savegame_save(const char *fn) { char *sb; int lb; char *se; int le; FILE *f; int fd; int i; char *errmsg; fd = open(fn,O_WRONLY|O_CREAT|O_TRUNC|O_EXCL,0666); if (fd < 0) { pline("Can't open %s: %s",fn,strerror(errno)); return; } f = fopenmalloc(&sb,&lb); errmsg = gen_save(f); fclose(f); if (errmsg) { pline("%s",errmsg); free(errmsg); free(sb); return; } f = fopenmalloc(&se,&le); errmsg = encode(sb,lb,f); fclose(f); if (errmsg) { pline("%s",errmsg); free(errmsg); free(se); free(sb); return; } i = write(fd,se,le); close(fd); if (i < 0) { i = errno; ftruncate(fd,0); unlink(fn); pline("Savefile write error: %s",strerror(i)); return; } if (i != le) { ftruncate(fd,0); unlink(fn); pline("Savefile write error, wanted %d did %d",le,i); return; } close(fd); cleanupscreen(); printf("Saved.\n"); exit(0); } /* * Restore the game from fn. If successful, returns with the game * loaded; on failure, reports the error(s) and exits. This is called * before the user interface starts, so errors are reported by fprintf * to stderr rather than pline() or the like. */ void savegame_restore(const char *fn) { (void)fn; }