comparison rogue5/save.c @ 33:f502bf60e6e4

Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author elwin
date Mon, 24 May 2010 20:10:59 +0000
parents
children 655c317b6237
comparison
equal deleted inserted replaced
32:2dcd75e6a736 33:f502bf60e6e4
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 msg("save file (%s)? ", file_name);
45 c = readchar();
46 mpos = 0;
47 if (c == ESCAPE)
48 {
49 msg("");
50 return;
51 }
52 else if (c == 'n' || c == 'N' || c == 'y' || c == 'Y')
53 break;
54 else
55 msg("please answer Y or N");
56 }
57 if (c == 'y' || c == 'Y')
58 {
59 addstr("Yes\n");
60 refresh();
61 strcpy(buf, file_name);
62 goto gotfile;
63 }
64 }
65
66 do
67 {
68 mpos = 0;
69 msg("file name: ");
70 buf[0] = '\0';
71 if (get_str(buf, stdscr) == QUIT)
72 {
73 quit_it:
74 msg("");
75 return;
76 }
77 mpos = 0;
78 gotfile:
79 /*
80 * test to see if the file exists
81 */
82 if (stat(buf, &sbuf) >= 0)
83 {
84 for (;;)
85 {
86 msg("File exists. Do you wish to overwrite it?");
87 mpos = 0;
88 if ((c = readchar()) == ESCAPE)
89 goto quit_it;
90 if (c == 'y' || c == 'Y')
91 break;
92 else if (c == 'n' || c == 'N')
93 goto over;
94 else
95 msg("Please answer Y or N");
96 }
97 msg("file name: %s", buf);
98 md_unlink(file_name);
99 }
100 strcpy(file_name, buf);
101 if ((savef = fopen(file_name, "w")) == NULL)
102 msg(strerror(errno));
103 } while (savef == NULL);
104 msg("");
105 save_file(savef);
106 /* NOTREACHED */
107 }
108
109 /*
110 * auto_save:
111 * Automatically save a file. This is used if a HUP signal is
112 * recieved
113 */
114
115 void
116 auto_save(int sig)
117 {
118 FILE *savef;
119 NOOP(sig);
120
121 md_ignoreallsignals();
122 if (file_name[0] != '\0' && ((savef = fopen(file_name, "w")) != NULL ||
123 (md_unlink_open_file(file_name, savef) >= 0 && (savef = fopen(file_name, "w")) != NULL)))
124 save_file(savef);
125 exit(0);
126 }
127
128 /*
129 * save_file:
130 * Write the saved game on the file
131 */
132
133 void
134 save_file(FILE *savef)
135 {
136 char buf[80];
137 mvcur(0, COLS - 1, LINES - 1, 0);
138 putchar('\n');
139 endwin();
140 resetltchars();
141 md_chmod(file_name, 0400);
142 encwrite(version, strlen(version)+1, savef);
143 sprintf(buf,"%d x %d\n", LINES, COLS);
144 encwrite(buf,80,savef);
145 rs_save_file(savef);
146 fflush(savef);
147 fclose(savef);
148 exit(0);
149 }
150
151 /*
152 * restore:
153 * Restore a saved game from a file with elaborate checks for file
154 * integrity from cheaters
155 */
156 int
157 restore(const char *file)
158 {
159 FILE *inf;
160 int syml;
161 char buf[MAXSTR];
162 struct stat sbuf2;
163 int lines, cols;
164
165 if (strcmp(file, "-r") == 0)
166 file = file_name;
167
168 md_tstphold();
169
170 if ((inf = fopen(file,"r")) == NULL)
171 {
172 perror(file);
173 return FALSE;
174 }
175 stat(file, &sbuf2);
176 syml = is_symlink(file);
177
178 fflush(stdout);
179 encread(buf, strlen(version) + 1, inf);
180 if (strcmp(buf, version) != 0)
181 {
182 printf("Sorry, saved game is out of date.\n");
183 return FALSE;
184 }
185 encread(buf,80,inf);
186 (void) sscanf(buf,"%d x %d\n", &lines, &cols);
187
188 initscr(); /* Start up cursor package */
189 keypad(stdscr, 1);
190
191 if (lines > LINES)
192 {
193 endwin();
194 printf("Sorry, original game was played on a screen with %d lines.\n",lines);
195 printf("Current screen only has %d lines. Unable to restore game\n",LINES);
196 return(FALSE);
197 }
198 if (cols > COLS)
199 {
200 endwin();
201 printf("Sorry, original game was played on a screen with %d columns.\n",cols);
202 printf("Current screen only has %d columns. Unable to restore game\n",COLS);
203 return(FALSE);
204 }
205
206 hw = newwin(LINES, COLS, 0, 0);
207 setup();
208
209 rs_restore_file(inf);
210 /*
211 * we do not close the file so that we will have a hold of the
212 * inode for as long as possible
213 */
214
215 if (
216 #ifdef MASTER
217 !wizard &&
218 #endif
219 md_unlink_open_file(file, inf) < 0)
220 {
221 printf("Cannot unlink file\n");
222 return FALSE;
223 }
224 mpos = 0;
225 /* printw(0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime)); */
226 /*
227 printw("%s: %s", file, ctime(&sbuf2.st_mtime));
228 */
229 clearok(stdscr,TRUE);
230 /*
231 * defeat multiple restarting from the same place
232 */
233 #ifdef MASTER
234 if (!wizard)
235 #endif
236 if (sbuf2.st_nlink != 1 || syml)
237 {
238 endwin();
239 printf("\nCannot restore from a linked file\n");
240 return FALSE;
241 }
242
243 if (pstats.s_hpt <= 0)
244 {
245 endwin();
246 printf("\n\"He's dead, Jim\"\n");
247 return FALSE;
248 }
249
250 md_tstpresume();
251
252 strcpy(file_name, file);
253 clearok(curscr, TRUE);
254 srand(md_getpid());
255 msg("file name: %s", file);
256 playit();
257 /*NOTREACHED*/
258 return(0);
259 }
260
261 static int encerrno = 0;
262
263 int
264 encerror()
265 {
266 return encerrno;
267 }
268
269 void
270 encseterr(int err)
271 {
272 encerrno = err;
273 }
274
275 int
276 encclearerr()
277 {
278 int n = encerrno;
279
280 encerrno = 0;
281
282 return(n);
283 }
284
285 /*
286 * encwrite:
287 * Perform an encrypted write
288 */
289
290 size_t
291 encwrite(const char *start, size_t size, FILE *outf)
292 {
293 const char *e1, *e2;
294 char fb;
295 int temp;
296 size_t o_size = size;
297 e1 = encstr;
298 e2 = statlist;
299 fb = 0;
300
301 if (encerrno) {
302 errno = encerrno;
303 return 0;
304 }
305
306 while(size)
307 {
308 if (putc(*start++ ^ *e1 ^ *e2 ^ fb, outf) == EOF)
309 {
310 encerrno = errno;
311 break;
312 }
313
314 temp = *e1++;
315 fb = fb + ((char) (temp * *e2++));
316 if (*e1 == '\0')
317 e1 = encstr;
318 if (*e2 == '\0')
319 e2 = statlist;
320 size--;
321 }
322
323 return(o_size - size);
324 }
325
326 /*
327 * encread:
328 * Perform an encrypted read
329 */
330 size_t
331 encread(char *start, size_t size, FILE *inf)
332 {
333 const char *e1, *e2;
334 char fb;
335 int temp;
336 size_t read_size;
337 size_t items;
338 fb = 0;
339
340 if (encerrno) {
341 errno = encerrno;
342 return 0;
343 }
344
345 items = read_size = fread(start,1,size,inf);
346
347 e1 = encstr;
348 e2 = statlist;
349
350 while (read_size--)
351 {
352 *start++ ^= *e1 ^ *e2 ^ fb;
353 temp = *e1++;
354 fb = fb + (char)(temp * *e2++);
355 if (*e1 == '\0')
356 e1 = encstr;
357 if (*e2 == '\0')
358 e2 = statlist;
359 }
360
361 if (items != size)
362 encerrno = errno;
363
364 return(items);
365 }
366
367 /*
368 * read_scrore
369 * Read in the score file
370 */
371 void
372 rd_score(SCORE *top_ten)
373 {
374 char scoreline[100];
375 int i;
376
377 if (scoreboard == NULL)
378 return;
379
380 rewind(scoreboard);
381
382 for(i = 0; i < numscores; i++)
383 {
384 encread(top_ten[i].sc_name, MAXSTR, scoreboard);
385 scoreline[0] = '\0';
386 encread(scoreline, 100, scoreboard);
387 (void) sscanf(scoreline, " %u %d %u %d %d %x \n",
388 &top_ten[i].sc_uid, &top_ten[i].sc_score,
389 &top_ten[i].sc_flags, &top_ten[i].sc_monster,
390 &top_ten[i].sc_level, &top_ten[i].sc_time);
391 }
392
393 rewind(scoreboard);