Annotation of early-roguelike/rogue3/save.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * save and restore routines
! 3: *
! 4: * @(#)save.c 3.9 (Berkeley) 6/16/81
! 5: *
! 6: * Rogue: Exploring the Dungeons of Doom
! 7: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 8: * All rights reserved.
! 9: *
! 10: * See the file LICENSE.TXT for full copyright and licensing information.
! 11: */
! 12:
! 13: #include "curses.h"
! 14: #include <ctype.h>
! 15: #include <sys/types.h>
! 16: #include <sys/stat.h>
! 17: #include <signal.h>
! 18: #include <errno.h>
! 19: #include <string.h>
! 20: #include <stdlib.h>
! 21: #include "machdep.h"
! 22: #include "rogue.h"
! 23:
! 24: typedef struct stat STAT;
! 25:
! 26: extern char version[], encstr[];
! 27:
! 28: STAT sbuf;
! 29:
! 30: int
! 31: save_game()
! 32: {
! 33: FILE *savef;
! 34: int c;
! 35: char buf[80];
! 36:
! 37: /*
! 38: * get file name
! 39: */
! 40: mpos = 0;
! 41: if (file_name[0] != '\0')
! 42: {
! 43: if (use_savedir)
! 44: msg("Save game? ");
! 45: else
! 46: msg("Save file (%s)? ", file_name);
! 47: do
! 48: {
! 49: c = readchar(cw);
! 50: } while (c != 'n' && c != 'N' && c != 'y' && c != 'Y');
! 51: mpos = 0;
! 52: if (c == 'y' || c == 'Y')
! 53: {
! 54: msg("File name: %s", file_name);
! 55: goto gotfile;
! 56: }
! 57: if (use_savedir)
! 58: return FALSE;
! 59: /* because you're not allowed to change the savefile if
! 60: you're using the system savedir! */
! 61: }
! 62:
! 63: do
! 64: {
! 65: msg("File name: ");
! 66: mpos = 0;
! 67: buf[0] = '\0';
! 68: if (get_str(buf, cw) == QUIT)
! 69: {
! 70: msg("");
! 71: return FALSE;
! 72: }
! 73: strcpy(file_name, buf);
! 74: gotfile:
! 75: if ((savef = fopen(file_name, "w")) == NULL)
! 76: {
! 77: msg(strerror(errno)); /* fake perror() */
! 78: if (use_savedir)
! 79: return FALSE;
! 80: }
! 81: } while (savef == NULL);
! 82:
! 83: /*
! 84: * write out encrypted file (after a stat)
! 85: * The fwrite is to force allocation of the buffer before the write
! 86: */
! 87: if (save_file(savef) != 0)
! 88: {
! 89: msg("Save game failed!");
! 90: return FALSE;
! 91: }
! 92: return TRUE;
! 93: }
! 94:
! 95: /*
! 96: * automatically save a file. This is used if a HUP signal is
! 97: * recieved
! 98: */
! 99: void
! 100: auto_save(int p)
! 101: {
! 102: FILE *savef;
! 103: int i;
! 104:
! 105: for (i = 0; i < NSIG; i++)
! 106: signal(i, SIG_IGN);
! 107: if (file_name[0] != '\0' && (savef = fopen(file_name, "w")) != NULL)
! 108: save_file(savef);
! 109: endwin();
! 110: exit(1);
! 111: }
! 112:
! 113: /*
! 114: * write the saved game on the file
! 115: */
! 116: int
! 117: save_file(FILE *savef)
! 118: {
! 119: char buf[80];
! 120: int ret;
! 121:
! 122: wmove(cw, LINES-1, 0);
! 123: draw(cw);
! 124: (void) fseek(savef, 0L, 0);
! 125:
! 126: memset(buf,0,80);
! 127: strcpy(buf,version);
! 128: encwrite(buf,80,savef);
! 129: memset(buf,0,80);
! 130: strcpy(buf,"R36 2\n");
! 131: encwrite(buf,80,savef);
! 132: memset(buf,0,80);
! 133: sprintf(buf,"%d x %d\n", LINES, COLS);
! 134: encwrite(buf,80,savef);
! 135:
! 136: ret = rs_save_file(savef);
! 137:
! 138: fclose(savef);
! 139:
! 140: return(ret);
! 141: }
! 142:
! 143: int
! 144: restore(char *file, char **envp)
! 145: {
! 146: FILE *inf;
! 147: extern char **environ;
! 148: char buf[80];
! 149: int slines, scols;
! 150: int rogue_version = 0, savefile_version = 0;
! 151:
! 152: if (strcmp(file, "-r") == 0)
! 153: file = file_name;
! 154:
! 155: if ((inf = fopen(file, "r")) == NULL)
! 156: {
! 157: if (use_savedir && errno == ENOENT)
! 158: {
! 159: /* We're using the system savefile and it doesn't exist.
! 160: * This isn't a fatal error, we'll just start a new game. */
! 161: return TRUE;
! 162: }
! 163: else
! 164: {
! 165: perror(file);
! 166: return FALSE;
! 167: }
! 168: }
! 169:
! 170: fflush(stdout);
! 171: encread(buf, 80, inf);
! 172:
! 173: if (strcmp(buf, version) != 0)
! 174: {
! 175: printf("Sorry, saved game is out of date.\n");
! 176: return FALSE;
! 177: }
! 178:
! 179: encread(buf, 80, inf);
! 180: (void) sscanf(buf, "R%d %d\n", &rogue_version, &savefile_version);
! 181:
! 182: if ((rogue_version != 36) && (savefile_version != 2))
! 183: {
! 184: printf("Sorry, saved game format is out of date.\n");
! 185: return FALSE;
! 186: }
! 187:
! 188: encread(buf,80,inf);
! 189: (void) sscanf(buf,"%d x %d\n",&slines, &scols);
! 190:
! 191: /*
! 192: * we do not close the file so that we will have a hold of the
! 193: * inode for as long as possible
! 194: */
! 195:
! 196: initscr();
! 197:
! 198: if (slines > LINES)
! 199: {
! 200: endwin();
! 201: printf("Sorry, original game was played on a screen with %d lines.\n",slines);
! 202: printf("Current screen only has %d lines. Unable to restore game\n",LINES);
! 203: return(FALSE);
! 204: }
! 205:
! 206: if (scols > COLS)
! 207: {
! 208: endwin();
! 209: printf("Sorry, original game was played on a screen with %d columns.\n",scols);
! 210: printf("Current screen only has %d columns. Unable to restore game\n",COLS);
! 211: return(FALSE);
! 212: }
! 213:
! 214: cw = newwin(LINES, COLS, 0, 0);
! 215: mw = newwin(LINES, COLS, 0, 0);
! 216: hw = newwin(LINES, COLS, 0, 0);
! 217: nonl();
! 218: nocrmode();
! 219: keypad(cw,1);
! 220: mpos = 0;
! 221: mvwprintw(cw, 0, 0, "%s", file);
! 222:
! 223: if (rs_restore_file(inf) != 0)
! 224: {
! 225: endwin();
! 226: printf("Cannot restore file\n");
! 227: return(FALSE);
! 228: }
! 229:
! 230: if (!wizard && (md_unlink_open_file(file, inf) < 0))
! 231: {
! 232: endwin();
! 233: printf("Cannot unlink file\n");
! 234: return FALSE;
! 235: }
! 236:
! 237: if (pstats.s_hpt <= 0) {
! 238: endwin();
! 239: printf("This character is already dead.\n");
! 240: return FALSE;
! 241: }
! 242:
! 243: environ = envp;
! 244: strcpy(file_name, file);
! 245: setup();
! 246: clearok(curscr, TRUE);
! 247: touchwin(cw);
! 248: srand(md_random_seed());
! 249: status();
! 250: playit();
! 251: /*NOTREACHED*/
! 252: return(0);
! 253: }
! 254:
! 255: static int encerrno = 0;
! 256:
! 257: int
! 258: encerror()
! 259: {
! 260: return encerrno;
! 261: }
! 262:
! 263: void
! 264: encseterr(int err)
! 265: {
! 266: encerrno = err;
! 267: }
! 268:
! 269: int
! 270: encclearerr()
! 271: {
! 272: int n = encerrno;
! 273:
! 274: encerrno = 0;
! 275:
! 276: return(n);
! 277: }
! 278:
! 279: /*
! 280: * perform an encrypted write
! 281: */
! 282: size_t
! 283: encwrite(const void *buf, size_t size, FILE *outf)
! 284: {
! 285: char *ep;
! 286: const char *start = buf;
! 287: size_t o_size = size;
! 288: ep = encstr;
! 289:
! 290: while (size)
! 291: {
! 292: if (putc(*start++ ^ *ep++, outf) == EOF)
! 293: return(o_size - size);
! 294: if (*ep == '\0')
! 295: ep = encstr;
! 296: size--;
! 297: }
! 298:
! 299: return(o_size - size);
! 300: }
! 301:
! 302: /*
! 303: * perform an encrypted read
! 304: */
! 305: size_t
! 306: encread(void *buf, size_t size, FILE *inf)
! 307: {
! 308: char *ep;
! 309: size_t read_size;
! 310: char *start = buf;
! 311:
! 312: if ((read_size = fread(start,1,size,inf)) == 0)
! 313: return 0;
! 314:
! 315: ep = encstr;
! 316:
! 317: while (size--)
! 318: {
! 319: *start++ ^= *ep++;
! 320: if (*ep == '\0')
! 321: ep = encstr;
! 322: }
! 323: return read_size;
! 324: }
CVSweb