Annotation of early-roguelike/rogue5/save.c, Revision 1.1.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