Annotation of early-roguelike/arogue5/save.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * save and restore routines
! 3: *
! 4: * Advanced Rogue
! 5: * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
! 6: * All rights reserved.
! 7: *
! 8: * Based on "Rogue: Exploring the Dungeons of Doom"
! 9: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 10: * All rights reserved.
! 11: *
! 12: * See the file LICENSE.TXT for full copyright and licensing information.
! 13: */
! 14:
! 15: #include "curses.h"
! 16: #include <stdlib.h>
! 17: #include <string.h>
! 18: #include <fcntl.h>
! 19: #include <errno.h>
! 20: #include <ctype.h>
! 21: #include <sys/types.h>
! 22: #include <sys/stat.h>
! 23: #include <signal.h>
! 24: #include <time.h>
! 25: #include "rogue.h"
! 26:
! 27: bool save_file(FILE *savef);
! 28:
! 29: typedef struct stat STAT;
! 30:
! 31: extern char version[], encstr[];
! 32: /* extern bool _endwin; */
! 33:
! 34: STAT sbuf;
! 35:
! 36: bool
! 37: save_game(void)
! 38: {
! 39: register FILE *savef;
! 40: register int c;
! 41: char buf[LINELEN];
! 42:
! 43: /*
! 44: * get file name
! 45: */
! 46: mpos = 0;
! 47: if (file_name[0] != '\0')
! 48: {
! 49: if (use_savedir)
! 50: msg("Save game? ");
! 51: else
! 52: msg("Save file (%s)? ", file_name);
! 53: do
! 54: {
! 55: c = readchar();
! 56: if (c == ESCAPE) return(0);
! 57: } while (c != 'n' && c != 'N' && c != 'y' && c != 'Y');
! 58: mpos = 0;
! 59: if (c == 'y' || c == 'Y')
! 60: {
! 61: msg("File name: %s", file_name);
! 62: goto gotfile;
! 63: }
! 64: if (use_savedir) {
! 65: msg("");
! 66: return FALSE;
! 67: }
! 68: }
! 69:
! 70: do
! 71: {
! 72: msg("File name: ");
! 73: mpos = 0;
! 74: buf[0] = '\0';
! 75: if (get_str(buf, msgw) == QUIT)
! 76: {
! 77: msg("");
! 78: return FALSE;
! 79: }
! 80: msg("");
! 81: strcpy(file_name, buf);
! 82: gotfile:
! 83: if ((savef = fopen(file_name, "w")) == NULL)
! 84: {
! 85: msg(strerror(errno)); /* fake perror() */
! 86: if (use_savedir)
! 87: return FALSE;
! 88: }
! 89: } while (savef == NULL);
! 90:
! 91: /*
! 92: * write out encrpyted file (after a stat)
! 93: * The fwrite is to force allocation of the buffer before the write
! 94: */
! 95: if (save_file(savef) != 0) {
! 96: msg("Cannot create save file.");
! 97: md_unlink(file_name);
! 98: return(FALSE);
! 99: }
! 100: else return(TRUE);
! 101: }
! 102:
! 103: /*
! 104: * automatically save a file. This is used if a HUP signal is
! 105: * recieved
! 106: */
! 107: void
! 108: auto_save(int sig)
! 109: {
! 110: register FILE *savef;
! 111: register int i;
! 112:
! 113: NOOP(sig);
! 114:
! 115: for (i = 0; i < NSIG; i++)
! 116: signal(i, SIG_IGN);
! 117: if (file_name[0] != '\0' &&
! 118: pstats.s_hpt > 0 &&
! 119: (savef = fopen(file_name, "w")) != NULL)
! 120: save_file(savef);
! 121: exit(1);
! 122: }
! 123:
! 124: /*
! 125: * write the saved game on the file
! 126: */
! 127: bool
! 128: save_file(FILE *savef)
! 129: {
! 130: int ret;
! 131: int slines = LINES;
! 132: int scols = COLS;
! 133:
! 134: wmove(cw, LINES-1, 0);
! 135: draw(cw);
! 136: fwrite("junk", 1, 5, savef);
! 137: fseek(savef, 0L, 0);
! 138: /* _endwin = TRUE; */
! 139:
! 140: encwrite(version,strlen(version)+1,savef);
! 141: sprintf(prbuf,"%d x %d\n", LINES, COLS);
! 142: encwrite(prbuf,80,savef);
! 143:
! 144: msg("");
! 145: ret = rs_save_file(savef);
! 146:
! 147: fclose(savef);
! 148:
! 149: return(ret);
! 150: }
! 151:
! 152: bool
! 153: restore(char *file, char **envp)
! 154: {
! 155: FILE *inf;
! 156: #ifndef _AIX
! 157: extern char **environ;
! 158: #endif
! 159: char buf[LINELEN];
! 160: STAT sbuf2;
! 161: int oldcol, oldline; /* Old number of columns and lines */
! 162:
! 163: if (strcmp(file, "-r") == 0)
! 164: file = file_name;
! 165:
! 166: if ((inf = fopen(file, "r")) == NULL)
! 167: {
! 168: if (use_savedir && errno == ENOENT)
! 169: {
! 170: /* No such game in SAVEDIR */
! 171: return TRUE;
! 172: }
! 173: perror(file);
! 174: return FALSE;
! 175: }
! 176:
! 177: fflush(stdout);
! 178:
! 179: encread(buf, strlen(version) + 1, inf);
! 180:
! 181: if (strcmp(buf, version) != 0)
! 182: {
! 183: printf("Sorry, saved game is out of date.\n");
! 184: return FALSE;
! 185: }
! 186:
! 187: /*
! 188: * Get the lines and columns from the previous game
! 189: */
! 190:
! 191: encread(buf, 80, inf);
! 192: sscanf(buf, "%d x %d\n", &oldline, &oldcol);
! 193: stat(file, &sbuf2);
! 194: fflush(stdout);
! 195:
! 196: /*
! 197: * Set the new terminal and make sure we aren't going to a smaller screen.
! 198: */
! 199:
! 200: initscr();
! 201:
! 202: if (COLS < oldcol || LINES < oldline) {
! 203: endwin();
! 204: printf("\nCannot restart the game on a smaller screen.\n");
! 205: return FALSE;
! 206: }
! 207:
! 208: cw = newwin(LINES, COLS, 0, 0);
! 209: mw = newwin(LINES, COLS, 0, 0);
! 210: hw = newwin(LINES, COLS, 0, 0);
! 211: msgw = newwin(4, COLS, 0, 0);
! 212: keypad(cw,1);
! 213: keypad(msgw,1);
! 214:
! 215: mpos = 0;
! 216: mvwprintw(cw, 0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime));
! 217:
! 218: /*
! 219: * defeat multiple restarting from the same place
! 220: */
! 221: if (!wizard) {
! 222: if (sbuf2.st_nlink != 1) {
! 223: endwin();
! 224: printf("\nCannot restore from a linked file\n");
! 225: return FALSE;
! 226: }
! 227: }
! 228:
! 229: if (rs_restore_file(inf) != 0)
! 230: {
! 231: endwin();
! 232: printf("\nCannot restore file\n");
! 233: return(FALSE);
! 234: }
! 235:
! 236: if (!wizard)
! 237: {
! 238: if (md_unlink(file) < 0) {
! 239: fclose(inf); /* only close if system insists */
! 240: if (md_unlink(file) < 0) {
! 241: endwin();
! 242: printf("\nCannot unlink file\n");
! 243: return FALSE;
! 244: }
! 245: }
! 246: }
! 247:
! 248: if (pstats.s_hpt <= 0) {
! 249: endwin();
! 250: printf("This character is already dead.\n");
! 251: return FALSE;
! 252: }
! 253:
! 254: environ = envp;
! 255: strcpy(file_name, file);
! 256: setup();
! 257: clearok(curscr, TRUE);
! 258: touchwin(cw);
! 259: srand(md_random_seed());
! 260: playit();
! 261: /*NOTREACHED*/
! 262: return(FALSE);
! 263: }
! 264:
! 265: /*
! 266: * perform an encrypted write
! 267: */
! 268: int
! 269: encwrite(char *start, unsigned int size, FILE *outf)
! 270: {
! 271: register char *ep;
! 272: register int num_written = 0;
! 273:
! 274: ep = encstr;
! 275:
! 276: while (size--)
! 277: {
! 278: if (putc(*start++ ^ *ep++, outf) == EOF && ferror(outf))
! 279: return(num_written);
! 280: num_written++;
! 281: if (*ep == '\0')
! 282: ep = encstr;
! 283: }
! 284: return(num_written);
! 285: }
! 286:
! 287: /*
! 288: * perform an encrypted read
! 289: */
! 290: int
! 291: encread(char *start, unsigned int size, FILE *inf)
! 292: {
! 293: register char *ep;
! 294: register int read_size;
! 295:
! 296: if ((read_size = fread(start, 1, size, inf)) == 0)
! 297: return read_size;
! 298:
! 299: ep = encstr;
! 300:
! 301: size = read_size;
! 302: while (size--)
! 303: {
! 304: *start++ ^= *ep++;
! 305: if (*ep == '\0')
! 306: ep = encstr;
! 307: }
! 308: return read_size;
! 309: }
CVSweb