Annotation of early-roguelike/rogue5/save.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * save and restore routines
! 3: *
! 4: * @(#)save.c 4.33 (Berkeley) 06/01/83
! 5: *
! 6: * Rogue: Exploring the Dungeons of Doom
! 7: * Copyright (C) 1980-1983, 1985, 1999 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 <stdlib.h>
! 14: #include <sys/types.h>
! 15: #include <sys/stat.h>
! 16: #include <errno.h>
! 17: #include <signal.h>
! 18: #include <string.h>
! 19: #include <curses.h>
! 20: #include "rogue.h"
! 21: #include "score.h"
! 22:
! 23: /*
! 24: * save_game:
! 25: * Implement the "save game" command
! 26: */
! 27:
! 28: void
! 29: save_game(void)
! 30: {
! 31: FILE *savef;
! 32: int c;
! 33: char buf[MAXSTR];
! 34: struct stat sbuf;
! 35: /*
! 36: * get file name
! 37: */
! 38: mpos = 0;
! 39: over:
! 40: if (file_name[0] != '\0')
! 41: {
! 42: for (;;)
! 43: {
! 44: if (use_savedir)
! 45: msg("Save game? ");
! 46: else
! 47: msg("Save file (%s)? ", file_name);
! 48: c = readchar();
! 49: mpos = 0;
! 50: if (c == ESCAPE)
! 51: {
! 52: msg("");
! 53: return;
! 54: }
! 55: else if (c == 'n' || c == 'N' || c == 'y' || c == 'Y')
! 56: break;
! 57: else
! 58: msg("please answer Y or N");
! 59: }
! 60: if (c == 'y' || c == 'Y')
! 61: {
! 62: addstr("Yes\n");
! 63: refresh();
! 64: strcpy(buf, file_name);
! 65: goto gotfile;
! 66: }
! 67: }
! 68:
! 69: if (use_savedir) /* User chose N, changing location isn't allowed. */
! 70: goto quit_it;
! 71: do
! 72: {
! 73: mpos = 0;
! 74: msg("file name: ");
! 75: buf[0] = '\0';
! 76: if (get_str(buf, stdscr) == QUIT)
! 77: {
! 78: quit_it:
! 79: msg("");
! 80: return;
! 81: }
! 82: mpos = 0;
! 83: gotfile:
! 84: /*
! 85: * test to see if the file exists
! 86: */
! 87: if (stat(buf, &sbuf) >= 0 && !use_savedir)
! 88: {
! 89: for (;;)
! 90: {
! 91: msg("File exists. Do you wish to overwrite it?");
! 92: mpos = 0;
! 93: if ((c = readchar()) == ESCAPE)
! 94: goto quit_it;
! 95: if (c == 'y' || c == 'Y')
! 96: break;
! 97: else if (c == 'n' || c == 'N')
! 98: goto over;
! 99: else
! 100: msg("Please answer Y or N");
! 101: }
! 102: msg("file name: %s", buf);
! 103: md_unlink(file_name);
! 104: }
! 105: strcpy(file_name, buf);
! 106: if ((savef = fopen(file_name, "w")) == NULL)
! 107: {
! 108: msg(strerror(errno));
! 109: if (use_savedir)
! 110: return;
! 111: }
! 112: } while (savef == NULL);
! 113: msg("");
! 114: save_file(savef);
! 115: /* NOTREACHED */
! 116: }
! 117:
! 118: /*
! 119: * auto_save:
! 120: * Automatically save a file. This is used if a HUP signal is
! 121: * recieved
! 122: */
! 123:
! 124: void
! 125: auto_save(int sig)
! 126: {
! 127: FILE *savef;
! 128: NOOP(sig);
! 129:
! 130: md_ignoreallsignals();
! 131: if (file_name[0] != '\0' && ((savef = fopen(file_name, "w")) != NULL ||
! 132: (md_unlink_open_file(file_name, savef) >= 0 && (savef = fopen(file_name, "w")) != NULL)))
! 133: save_file(savef);
! 134: exit(0);
! 135: }
! 136:
! 137: /*
! 138: * save_file:
! 139: * Write the saved game on the file
! 140: */
! 141:
! 142: void
! 143: save_file(FILE *savef)
! 144: {
! 145: char buf[80];
! 146: mvcur(0, COLS - 1, LINES - 1, 0);
! 147: putchar('\n');
! 148: endwin();
! 149: resetltchars();
! 150: md_chmod(file_name, 0644);
! 151: encwrite(version, strlen(version)+1, savef);
! 152: sprintf(buf,"%d x %d\n", LINES, COLS);
! 153: encwrite(buf,80,savef);
! 154: rs_save_file(savef);
! 155: fflush(savef);
! 156: fclose(savef);
! 157: printf("See you soon, %s!\n", whoami);
! 158: exit(0);
! 159: }
! 160:
! 161: /*
! 162: * restore:
! 163: * Restore a saved game from a file with elaborate checks for file
! 164: * integrity from cheaters
! 165: */
! 166: int
! 167: restore(const char *file)
! 168: {
! 169: FILE *inf;
! 170: int syml;
! 171: char buf[MAXSTR];
! 172: struct stat sbuf2;
! 173: int lines, cols;
! 174:
! 175: if (strcmp(file, "-r") == 0)
! 176: file = file_name;
! 177:
! 178: md_tstphold();
! 179:
! 180: if ((inf = fopen(file,"r")) == NULL)
! 181: {
! 182: /* If a system savefile doesn't exist, start a new game. */
! 183: if (use_savedir && errno == ENOENT)
! 184: return TRUE;
! 185: perror(file);
! 186: return FALSE;
! 187: }
! 188: stat(file, &sbuf2);
! 189: syml = is_symlink(file);
! 190:
! 191: fflush(stdout);
! 192: encread(buf, strlen(version) + 1, inf);
! 193: if (strcmp(buf, version) != 0)
! 194: {
! 195: printf("Sorry, saved game is out of date.\n");
! 196: return FALSE;
! 197: }
! 198: encread(buf,80,inf);
! 199: (void) sscanf(buf,"%d x %d\n", &lines, &cols);
! 200:
! 201: initscr(); /* Start up cursor package */
! 202: keypad(stdscr, 1);
! 203:
! 204: if (lines > LINES)
! 205: {
! 206: endwin();
! 207: printf("Sorry, original game was played on a screen with %d lines.\n",lines);
! 208: printf("Current screen only has %d lines. Unable to restore game\n",LINES);
! 209: return(FALSE);
! 210: }
! 211: if (cols > COLS)
! 212: {
! 213: endwin();
! 214: printf("Sorry, original game was played on a screen with %d columns.\n",cols);
! 215: printf("Current screen only has %d columns. Unable to restore game\n",COLS);
! 216: return(FALSE);
! 217: }
! 218:
! 219: hw = newwin(LINES, COLS, 0, 0);
! 220: setup();
! 221:
! 222: rs_restore_file(inf);
! 223: /*
! 224: * we do not close the file so that we will have a hold of the
! 225: * inode for as long as possible
! 226: */
! 227:
! 228: if (
! 229: #ifdef MASTER
! 230: !wizard &&
! 231: #endif
! 232: md_unlink_open_file(file, inf) < 0)
! 233: {
! 234: printf("Cannot unlink file\n");
! 235: return FALSE;
! 236: }
! 237: mpos = 0;
! 238: /* printw(0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime)); */
! 239: /*
! 240: printw("%s: %s", file, ctime(&sbuf2.st_mtime));
! 241: */
! 242: clearok(stdscr,TRUE);
! 243: /*
! 244: * defeat multiple restarting from the same place
! 245: */
! 246: #ifdef MASTER
! 247: if (!wizard)
! 248: #endif
! 249: if (sbuf2.st_nlink != 1 || syml)
! 250: {
! 251: endwin();
! 252: printf("\nCannot restore from a linked file\n");
! 253: return FALSE;
! 254: }
! 255:
! 256: if (pstats.s_hpt <= 0)
! 257: {
! 258: endwin();
! 259: printf("\n\"He's dead, Jim\"\n");
! 260: return FALSE;
! 261: }
! 262:
! 263: md_tstpresume();
! 264:
! 265: strcpy(file_name, file);
! 266: clearok(curscr, TRUE);
! 267: srand(md_random_seed());
! 268: msg("file name: %s", file);
! 269: playit();
! 270: /*NOTREACHED*/
! 271: return(0);
! 272: }
! 273:
! 274: static int encerrno = 0;
! 275:
! 276: int
! 277: encerror()
! 278: {
! 279: return encerrno;
! 280: }
! 281:
! 282: void
! 283: encseterr(int err)
! 284: {
! 285: encerrno = err;
! 286: }
! 287:
! 288: int
! 289: encclearerr()
! 290: {
! 291: int n = encerrno;
! 292:
! 293: encerrno = 0;
! 294:
! 295: return(n);
! 296: }
! 297:
! 298: /*
! 299: * encwrite:
! 300: * Perform an encrypted write
! 301: */
! 302:
! 303: size_t
! 304: encwrite(const char *start, size_t size, FILE *outf)
! 305: {
! 306: const char *e1, *e2;
! 307: char fb;
! 308: int temp;
! 309: size_t o_size = size;
! 310: e1 = encstr;
! 311: e2 = statlist;
! 312: fb = 0;
! 313:
! 314: if (encerrno) {
! 315: errno = encerrno;
! 316: return 0;
! 317: }
! 318:
! 319: while(size)
! 320: {
! 321: if (putc(*start++ ^ *e1 ^ *e2 ^ fb, outf) == EOF)
! 322: {
! 323: encerrno = errno;
! 324: break;
! 325: }
! 326:
! 327: temp = *e1++;
! 328: fb = fb + ((char) (temp * *e2++));
! 329: if (*e1 == '\0')
! 330: e1 = encstr;
! 331: if (*e2 == '\0')
! 332: e2 = statlist;
! 333: size--;
! 334: }
! 335:
! 336: return(o_size - size);
! 337: }
! 338:
! 339: /*
! 340: * encread:
! 341: * Perform an encrypted read
! 342: */
! 343: size_t
! 344: encread(char *start, size_t size, FILE *inf)
! 345: {
! 346: const char *e1, *e2;
! 347: char fb;
! 348: int temp;
! 349: size_t read_size;
! 350: size_t items;
! 351: fb = 0;
! 352:
! 353: if (encerrno) {
! 354: errno = encerrno;
! 355: return 0;
! 356: }
! 357:
! 358: items = read_size = fread(start,1,size,inf);
! 359:
! 360: e1 = encstr;
! 361: e2 = statlist;
! 362:
! 363: while (read_size--)
! 364: {
! 365: *start++ ^= *e1 ^ *e2 ^ fb;
! 366: temp = *e1++;
! 367: fb = fb + (char)(temp * *e2++);
! 368: if (*e1 == '\0')
! 369: e1 = encstr;
! 370: if (*e2 == '\0')
! 371: e2 = statlist;
! 372: }
! 373:
! 374: if (items != size)
! 375: encerrno = errno;
! 376:
! 377: return(items);
! 378: }
! 379:
! 380: /*
! 381: * read_scrore
! 382: * Read in the score file
! 383: */
! 384: void
! 385: rd_score(SCORE *top_ten)
! 386: {
! 387: char scoreline[100];
! 388: int i;
! 389:
! 390: if (scoreboard == NULL)
! 391: return;
! 392:
! 393: rewind(scoreboard);
! 394:
! 395: for(i = 0; i < numscores; i++)
! 396: {
! 397: encread(top_ten[i].sc_name, MAXSTR, scoreboard);
! 398: scoreline[0] = '\0';
! 399: encread(scoreline, 100, scoreboard);
! 400: (void) sscanf(scoreline, " %u %d %u %d %d %x \n",
! 401: &top_ten[i].sc_uid, &top_ten[i].sc_score,
! 402: &top_ten[i].sc_flags, &top_ten[i].sc_monster,
! 403: &top_ten[i].sc_level, &top_ten[i].sc_time);
! 404: }
! 405:
! 406: rewind(scoreboard);
! 407: }
! 408:
! 409: /*
! 410: * write_scrore
! 411: * Read in the score file
! 412: */
! 413: void
! 414: wr_score(SCORE *top_ten)
! 415: {
! 416: char scoreline[100];
! 417: int i;
! 418:
! 419: if (scoreboard == NULL)
! 420: return;
! 421:
! 422: rewind(scoreboard);
! 423:
! 424: encerrno = 0;
! 425: for(i = 0; i < numscores; i++)
! 426: {
! 427: memset(scoreline,0,100);
! 428: encwrite(top_ten[i].sc_name, MAXSTR, scoreboard);
! 429: sprintf(scoreline, " %u %d %u %u %d %x \n",
! 430: top_ten[i].sc_uid, top_ten[i].sc_score,
! 431: top_ten[i].sc_flags, top_ten[i].sc_monster,
! 432: top_ten[i].sc_level, top_ten[i].sc_time);
! 433: encwrite(scoreline,100,scoreboard);
! 434: }
! 435:
! 436: rewind(scoreboard);
! 437: }
CVSweb