Mercurial > hg > early-roguelike
comparison srogue/save.c @ 36:2128c7dc8a40
Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Thu, 25 Nov 2010 12:21:41 +0000 |
parents | |
children | 34d7a614855e |
comparison
equal
deleted
inserted
replaced
35:05018c63a721 | 36:2128c7dc8a40 |
---|---|
1 /* | |
2 * save and restore routines | |
3 * | |
4 * @(#)save.c 9.0 (rdk) 7/17/84 | |
5 * | |
6 * Super-Rogue | |
7 * Copyright (C) 1984 Robert D. Kindelberger | |
8 * All rights reserved. | |
9 * | |
10 * Based on "Rogue: Exploring the Dungeons of Doom" | |
11 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
12 * All rights reserved. | |
13 * | |
14 * See the file LICENSE.TXT for full copyright and licensing information. | |
15 */ | |
16 | |
17 #include <unistd.h> | |
18 #include <ctype.h> | |
19 #include <fcntl.h> | |
20 #include <sys/types.h> | |
21 #include <sys/stat.h> | |
22 #include <signal.h> | |
23 #include <errno.h> | |
24 #include "rogue.h" | |
25 #include "rogue.ext" | |
26 | |
27 #ifdef BSD | |
28 #define srand48(seed) srandom(seed) | |
29 #endif | |
30 | |
31 EXTCHAR version[]; | |
32 EXTCHAR *ctime(); | |
33 | |
34 typedef struct stat STAT; | |
35 STAT sbuf; | |
36 | |
37 /* | |
38 * ignore: | |
39 * Ignore ALL signals possible | |
40 */ | |
41 ignore() | |
42 { | |
43 int i; | |
44 | |
45 for (i = 0; i < NSIG; i++) | |
46 signal(i, SIG_IGN); | |
47 } | |
48 | |
49 /* | |
50 * save_game: | |
51 * Save the current game | |
52 */ | |
53 save_game() | |
54 { | |
55 reg FILE *savef; | |
56 reg int c; | |
57 char buf[LINLEN]; | |
58 | |
59 mpos = 0; | |
60 if (file_name[0] != '\0') { | |
61 msg("Save file (%s)? ", file_name); | |
62 do { | |
63 c = wgetch(cw); | |
64 if(c == ESCAPE) { | |
65 msg(""); | |
66 return FALSE; | |
67 } | |
68 } while (c != 'n' && c != 'y'); | |
69 mpos = 0; | |
70 if (c == 'y') | |
71 goto gotfile; | |
72 } | |
73 msg("File name: "); | |
74 mpos = 0; | |
75 buf[0] = '\0'; | |
76 if (get_str(buf, cw) == QUIT) { | |
77 msg(""); | |
78 return FALSE; | |
79 } | |
80 msg(""); | |
81 strcpy(file_name, buf); | |
82 gotfile: | |
83 c = dosave(); /* try to save this game */ | |
84 if (c == FALSE) | |
85 msg("Could not save game to file %s", file_name); | |
86 return c; | |
87 } | |
88 | |
89 /* | |
90 * auto_save: | |
91 * Automatically save a game | |
92 */ | |
93 void | |
94 auto_save(int a) | |
95 { | |
96 dosave(); /* save this game */ | |
97 byebye(1); /* so long for now */ | |
98 } | |
99 | |
100 /* | |
101 * game_err: | |
102 * When an error occurs. Set error flag and save game. | |
103 */ | |
104 void | |
105 game_err(int a) | |
106 { | |
107 int ok; | |
108 | |
109 ok = dosave(); /* try to save this game */ | |
110 clear(); | |
111 refresh(); | |
112 endwin(); | |
113 | |
114 printf("\nInternal error !!!\n\nYour game was "); | |
115 if (ok) | |
116 printf("saved."); | |
117 else | |
118 printf("NOT saveable."); | |
119 | |
120 fflush(stdout); | |
121 | |
122 #ifdef SIGIOT | |
123 signal(SIGIOT, SIG_DFL); /* allow core dump signal */ | |
124 #endif | |
125 | |
126 abort(); /* cause core dump */ | |
127 byebye(3); | |
128 } | |
129 | |
130 /* | |
131 * dosave: | |
132 * Set UID back to user and save the game | |
133 */ | |
134 dosave() | |
135 { | |
136 FILE *savef; | |
137 | |
138 ignore(); | |
139 setuid(playuid); | |
140 setgid(playgid); | |
141 umask(022); | |
142 | |
143 if (file_name[0] != '\0') { | |
144 if ((savef = fopen(file_name,"w")) != NULL) | |
145 { | |
146 save_file(savef); | |
147 return TRUE; | |
148 } | |
149 } | |
150 return FALSE; | |
151 } | |
152 | |
153 /* | |
154 * save_file: | |
155 * Do the actual save of this game to a file | |
156 */ | |
157 save_file(savef) | |
158 FILE *savef; | |
159 { | |
160 reg int fnum; | |
161 int slines = LINES; | |
162 int scols = COLS; | |
163 | |
164 #ifdef __DJGPP__ /* st_ino w/ DJGPP under WinXP broken */ | |
165 _djstat_flags |= _STAT_INODE; /* so turn off computing it for now */ | |
166 #endif | |
167 | |
168 /* | |
169 * force allocation of the buffer now so that inodes, etc | |
170 * can be checked when restoring saved games. | |
171 */ | |
172 fnum = fileno(savef); | |
173 fstat(fnum, &sbuf); | |
174 write(fnum, "RDK", 4); | |
175 lseek(fnum, 0L, 0); | |
176 encwrite(version,strlen(version)+1,savef); | |
177 encwrite(&sbuf.st_ino,sizeof(sbuf.st_ino),savef); | |
178 encwrite(&sbuf.st_dev,sizeof(sbuf.st_dev),savef); | |
179 encwrite(&sbuf.st_ctime,sizeof(sbuf.st_ctime),savef); | |
180 encwrite(&sbuf.st_mtime,sizeof(sbuf.st_mtime),savef); | |
181 encwrite(&slines,sizeof(slines),savef); | |
182 encwrite(&scols,sizeof(scols),savef); | |
183 msg(""); | |
184 rs_save_file(savef); | |
185 close(fnum); | |
186 signal(SIGINT, byebye); | |
187 signal(SIGQUIT, byebye); | |
188 wclear(cw); | |
189 draw(cw); | |
190 } | |
191 | |
192 /* | |
193 * restore: | |
194 * Restore a saved game from a file | |
195 */ | |
196 restore(file, envp) | |
197 char *file, **envp; | |
198 { | |
199 register inf, pid; | |
200 int ret_status; | |
201 #ifndef _AIX | |
202 extern char **environ; | |
203 #endif | |
204 #ifdef __DJGPP__ /* st_ino w/ DJGPP under WinXP broken */ | |
205 _djstat_flags |= _STAT_INODE; /* so turn off computing it for now */ | |
206 #endif | |
207 char buf[LINLEN]; | |
208 STAT sbuf2; | |
209 int slines, scols; | |
210 | |
211 if ((inf = open(file, O_RDONLY)) < 0) { | |
212 printf("Cannot read save game %s\n",file); | |
213 return FALSE; | |
214 } | |
215 | |
216 encread(buf, strlen(version) + 1, inf); | |
217 | |
218 if (strcmp(buf, version) != 0) { | |
219 printf("Sorry, saved game version is out of date.\n"); | |
220 return FALSE; | |
221 } | |
222 | |
223 fstat(inf, &sbuf2); | |
224 | |
225 encread(&sbuf.st_ino,sizeof(sbuf.st_ino), inf); | |
226 encread(&sbuf.st_dev,sizeof(sbuf.st_dev), inf); | |
227 encread(&sbuf.st_ctime,sizeof(sbuf.st_ctime), inf); | |
228 encread(&sbuf.st_mtime,sizeof(sbuf.st_mtime), inf); | |
229 encread(&slines,sizeof(slines),inf); | |
230 encread(&scols,sizeof(scols),inf); | |
231 | |
232 /* | |
233 * we do not close the file so that we will have a hold of the | |
234 * inode for as long as possible | |
235 */ | |
236 | |
237 if (!wizard) | |
238 { | |
239 if(sbuf2.st_ino!=sbuf.st_ino || sbuf2.st_dev!=sbuf.st_dev) { | |
240 printf("Sorry, saved game is not in the same file.\n"); | |
241 return FALSE; | |
242 } | |
243 } | |
244 | |
245 #ifdef __INTERIX | |
246 setenv("TERM","interix"); | |
247 #endif | |
248 | |
249 initscr(); | |
250 | |
251 if (slines > LINES) | |
252 { | |
253 endwin(); | |
254 printf("Sorry, original game was played on a screen with %d lines.\n",slines); | |
255 printf("Current screen only has %d lines. Unable to restore game\n",LINES); | |
256 return(FALSE); | |
257 } | |
258 | |
259 if (scols > COLS) | |
260 { | |
261 endwin(); | |
262 printf("Sorry, original game was played on a screen with %d columns.\n", scols); | |
263 printf("Current screen only has %d columns. Unable to restore game\n",COLS); | |
264 return(FALSE); | |
265 } | |
266 | |
267 cw = newwin(LINES, COLS, 0, 0); | |
268 mw = newwin(LINES, COLS, 0, 0); | |
269 hw = newwin(LINES, COLS, 0, 0); | |
270 | |
271 mpos = 0; | |
272 mvwprintw(cw, 0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime)); | |
273 | |
274 /* defeat multiple restarting from the same place */ | |
275 | |
276 if (!wizard) | |
277 { | |
278 if (sbuf2.st_nlink != 1) | |
279 { | |
280 endwin(); | |
281 printf("Cannot restore from a linked file\n"); | |
282 return FALSE; | |
283 } | |
284 } | |
285 | |
286 if (rs_restore_file(inf) == FALSE) | |
287 { | |
288 endwin(); | |
289 printf("Cannot restore file\n"); | |
290 return(FALSE); | |
291 } | |
292 | |
293 #if defined(__CYGWIN__) || defined(__DJGPP__) | |
294 close(inf); | |
295 #endif | |
296 if (!wizard) | |
297 { | |
298 #ifndef __DJGPP__ | |
299 endwin(); | |
300 while((pid = fork()) < 0) | |
301 sleep(1); | |
302 | |
303 /* set id to unlink file */ | |
304 if(pid == 0) | |
305 { | |
306 setuid(playuid); | |
307 setgid(playgid); | |
308 unlink(file); | |
309 exit(0); | |
310 } | |
311 /* wait for unlink to finish */ | |
312 else | |
313 { | |
314 while(wait(&ret_status) != pid) | |
315 continue; | |
316 if (ret_status < 0) | |
317 { | |
318 printf("Cannot unlink file\n"); | |
319 return FALSE; | |
320 } | |
321 } | |
322 #else | |
323 if (unlink(file) < 0) | |
324 { | |
325 printf("Cannot unlink file\n"); | |
326 return FALSE; | |
327 } | |
328 #endif | |
329 | |
330 } | |
331 | |
332 environ = envp; | |
333 | |
334 strcpy(file_name, file); | |
335 setup(); | |
336 restscr(cw); | |
337 srand48(getpid()); | |
338 playit(); | |
339 } |