comparison arogue7/save.c @ 125:adfa37e67084

Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Fri, 08 May 2015 15:24:40 -0400
parents
children b786053d2f37
comparison
equal deleted inserted replaced
124:d10fc4a065ac 125:adfa37e67084
1 /*
2 * save.c - save and restore routines
3 *
4 * Advanced Rogue
5 * Copyright (C) 1984, 1985, 1986 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 /*
16 * save and restore routines
17 *
18 */
19
20 #include "curses.h"
21 #include <ctype.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <signal.h>
25 #include "rogue.h"
26 #include <fcntl.h>
27 #include <errno.h>
28 #include "mach_dep.h"
29 #ifdef PC7300
30 #include "sys/window.h"
31 extern struct uwdata wdata;
32 #endif
33
34 #if u370 || uts
35 #define ENCREAD(b,n,fd) read(fd,b,n)
36 #define ENCWRITE(b,n,fd) write(fd,b,n)
37 #endif
38 #ifndef ENCREAD
39 #define ENCREAD encread
40 #define ENCWRITE encwrite
41 #endif
42
43 typedef struct stat STAT;
44
45 extern char version[], encstr[];
46 /* extern bool _endwin; */
47 extern int errno;
48
49 STAT sbuf;
50
51 bool
52 save_game()
53 {
54 register int savefd;
55 register int c;
56 char buf[LINELEN];
57
58 /*
59 * get file name
60 */
61 mpos = 0;
62 if (file_name[0] != '\0')
63 {
64 msg("Save file (%s)? ", file_name);
65 do
66 {
67 c = readchar();
68 if (c == ESCAPE) return(0);
69 } while (c != 'n' && c != 'N' && c != 'y' && c != 'Y');
70 mpos = 0;
71 if (c == 'y' || c == 'Y')
72 {
73 msg("File name: %s", file_name);
74 goto gotfile;
75 }
76 }
77
78 do
79 {
80 msg("File name: ");
81 mpos = 0;
82 buf[0] = '\0';
83 if (get_str(buf, msgw) == QUIT)
84 {
85 msg("");
86 return FALSE;
87 }
88 strcpy(file_name, buf);
89 gotfile:
90 if ((savefd = open(file_name, O_WRONLY|O_CREAT|O_TRUNC,0666)) < 0)
91 msg(strerror(errno)); /* fake perror() */
92 } while (savefd < 0);
93
94 /*
95 * write out encrpyted file (after a stat)
96 */
97 if (save_file(savefd) == FALSE) {
98 msg("Cannot create save file.");
99 unlink(file_name);
100 return(FALSE);
101 }
102 else return(TRUE);
103 }
104
105 /*
106 * automatically save a file. This is used if a HUP signal is
107 * recieved
108 */
109 void
110 auto_save(sig)
111 int sig;
112 {
113 register int savefd;
114 register int i;
115
116 for (i = 0; i < NSIG; i++)
117 signal(i, SIG_IGN);
118 if (file_name[0] != '\0' &&
119 pstats.s_hpt > 0 &&
120 (savefd = open(file_name, O_WRONLY|O_CREAT|O_TRUNC, 0600)) >= 0)
121 save_file(savefd);
122 endwin();
123 #ifdef PC7300
124 endhardwin();
125 #endif
126 exit(1);
127 }
128
129 /*
130 * write the saved game on the file
131 */
132 bool
133 save_file(savefd)
134 register int savefd;
135 {
136 register unsigned num_to_write, num_written;
137 FILE *savef;
138 int ret;
139
140 wmove(cw, lines-1, 0);
141 draw(cw);
142 lseek(savefd, 0L, 0);
143 fstat(savefd, &sbuf);
144 num_to_write = strlen(version) + 1;
145 num_written = ENCWRITE(version, num_to_write, savefd);
146 sprintf(prbuf,"%d x %d\n", LINES, COLS);
147 ENCWRITE(prbuf,80,savefd);
148 savef = (FILE *) fdopen(savefd,"wb");
149 ret = rs_save_file(savef);
150 fclose(savef);
151 if (num_to_write == num_written && ret == 0) return(TRUE);
152 else return(FALSE);
153 }
154
155 restore(file, envp)
156 register char *file;
157 char **envp;
158 {
159 register int inf;
160 extern char **environ;
161 char buf[LINELEN];
162 STAT sbuf2;
163 int oldcol, oldline; /* Old number of columns and lines */
164
165 if (strcmp(file, "-r") == 0)
166 file = file_name;
167 if ((inf = open(file, 0)) < 0)
168 {
169 perror(file);
170 return FALSE;
171 }
172
173 fflush(stdout);
174 ENCREAD(buf, strlen(version) + 1, inf);
175 if (strcmp(buf, version) != 0)
176 {
177 printf("Sorry, saved game is out of date.\n");
178 return FALSE;
179 }
180
181 /*
182 * Get the lines and columns from the previous game
183 */
184
185 ENCREAD(buf, 80, inf);
186 sscanf(buf, "%d x %d\n", &oldline, &oldcol);
187 fstat(inf, &sbuf2);
188 fflush(stdout);
189
190 initscr();
191
192 if (COLS < oldcol || LINES < oldline) {
193 endwin();
194 printf("Cannot restart the game on a smaller screen.\n");
195 return FALSE;
196 }
197
198 setup();
199 /*
200 * Set up windows
201 */
202 cw = newwin(lines, cols, 0, 0);
203 mw = newwin(lines, cols, 0, 0);
204 hw = newwin(lines, cols, 0, 0);
205 msgw = newwin(4, cols, 0, 0);
206
207 keypad(cw,1);
208 keypad(msgw,1);
209
210 if (rs_restore_file(inf) != 0)
211 {
212 printf("Cannot restore file\n");
213 close(inf);
214 return(FALSE);
215 }
216
217 cols = COLS;
218 lines = LINES;
219 if (cols > 85) cols = 85;
220 if (lines > 24) lines = 24;
221
222 mpos = 0;
223 mvwprintw(msgw, 0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime));
224
225 /*
226 * defeat multiple restarting from the same place
227 */
228 if (!wizard && md_unlink_open_file(file, inf) < 0) {
229 printf("Cannot unlink file\n");
230 return FALSE;
231 }
232
233 environ = envp;
234 strcpy(file_name, file);
235 setup();
236 clearok(curscr, TRUE);
237 touchwin(cw);
238 srand(getpid());
239 playit();
240 /*NOTREACHED*/
241 return(0);
242 }
243
244 #define ENCWBSIZ 1024
245 /*
246 * perform an encrypted write
247 */
248 encwrite(start, size, outf)
249 register char *start;
250 register unsigned size;
251 register int outf;
252 {
253 register char *ep;
254 register int i = 0;
255 int num_written = 0;
256 auto char buf[ENCWBSIZ];
257
258 ep = encstr;
259
260 while (size--)
261 {
262 buf[i++] = *start++ ^ *ep++ ;
263 if (*ep == '\0')
264 ep = encstr;
265
266 if (i == ENCWBSIZ || size == 0) {
267 if (write(outf, buf, (unsigned)i) < i)
268 return(num_written);
269 else {
270 num_written += i;
271 i = 0;
272 }
273 }
274 }
275 return(num_written);
276 }
277
278 /*
279 * perform an encrypted read
280 */
281 encread(start, size, inf)
282 register char *start;
283 register unsigned size;
284 register int inf;
285 {
286 register char *ep;
287 register int read_size;
288
289 if ((read_size = read(inf, start, size)) == -1 || read_size == 0)
290 return read_size;
291
292 ep = encstr;
293
294 size = read_size;
295 while (size--)
296 {
297 *start++ ^= *ep++;
298 if (*ep == '\0')
299 ep = encstr;
300 }
301 return read_size;
302 }