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