Rogue 3.6 reconstruction from http://rogue.rogueforge.net/rogue36/.
[rogue-pphs.git] / save.c
1 /*
2 * save and restore routines
3 *
4 * @(#)save.c 3.9 (Berkeley) 6/16/81
5 *
6 * Rogue: Exploring the Dungeons of Doom
7 * Copyright (C) 1980, 1981 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 "curses.h"
14 #include <ctype.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <signal.h>
18 #include <errno.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include "rogue.h"
22 #include "machdep.h"
23
24 typedef struct stat STAT;
25
26 extern char version[], encstr[];
27
28 STAT sbuf;
29
30 save_game()
31 {
32 register FILE *savef;
33 register int c;
34 char buf[80];
35
36 /*
37 * get file name
38 */
39 mpos = 0;
40 if (file_name[0] != '\0')
41 {
42 msg("Save file (%s)? ", file_name);
43 do
44 {
45 c = readchar(cw);
46 } while (c != 'n' && c != 'N' && c != 'y' && c != 'Y');
47 mpos = 0;
48 if (c == 'y' || c == 'Y')
49 {
50 msg("File name: %s", file_name);
51 goto gotfile;
52 }
53 }
54
55 do
56 {
57 msg("File name: ");
58 mpos = 0;
59 buf[0] = '\0';
60 if (get_str(buf, cw) == QUIT)
61 {
62 msg("");
63 return FALSE;
64 }
65 strcpy(file_name, buf);
66 gotfile:
67 if ((savef = fopen(file_name, "w")) == NULL)
68 msg(strerror(errno)); /* fake perror() */
69 } while (savef == NULL);
70
71 /*
72 * write out encrpyted file (after a stat)
73 * The fwrite is to force allocation of the buffer before the write
74 */
75 if (save_file(savef) != 0)
76 {
77 msg("Save game failed!");
78 return FALSE;
79 }
80 return TRUE;
81 }
82
83 /*
84 * automatically save a file. This is used if a HUP signal is
85 * recieved
86 */
87 void
88 auto_save(int p)
89 {
90 register FILE *savef;
91 register int i;
92
93 for (i = 0; i < NSIG; i++)
94 signal(i, SIG_IGN);
95 if (file_name[0] != '\0' && (savef = fopen(file_name, "w")) != NULL)
96 save_file(savef);
97 endwin();
98 exit(1);
99 }
100
101 /*
102 * write the saved game on the file
103 */
104 save_file(savef)
105 register FILE *savef;
106 {
107 char buf[80];
108 int ret;
109
110 wmove(cw, LINES-1, 0);
111 draw(cw);
112 fseek(savef, 0L, 0);
113
114 memset(buf,0,80);
115 strcpy(buf,version);
116 encwrite(buf,80,savef);
117 memset(buf,0,80);
118 strcpy(buf,"R36 2\n");
119 encwrite(buf,80,savef);
120 memset(buf,0,80);
121 sprintf(buf,"%d x %d\n", LINES, COLS);
122 encwrite(buf,80,savef);
123
124 ret = rs_save_file(savef);
125
126 fclose(savef);
127
128 return(ret);
129 }
130
131 restore(file, envp)
132 register char *file;
133 char **envp;
134 {
135 register int inf;
136 extern char **environ;
137 char buf[80];
138 int slines, scols;
139 int rogue_version = 0, savefile_version = 0;
140
141 if (strcmp(file, "-r") == 0)
142 file = file_name;
143 if ((inf = open(file, 0)) < 0)
144 {
145 perror(file);
146 return FALSE;
147 }
148
149 fflush(stdout);
150 encread(buf, 80, inf);
151
152 if (strcmp(buf, version) != 0)
153 {
154 printf("Sorry, saved game is out of date.\n");
155 return FALSE;
156 }
157
158 encread(buf, 80, inf);
159 sscanf(buf, "R%d %d\n", &rogue_version, &savefile_version);
160
161 if ((rogue_version != 36) && (savefile_version != 2))
162 {
163 printf("Sorry, saved game format is out of date.\n");
164 return FALSE;
165 }
166
167 encread(buf,80,inf);
168 sscanf(buf,"%d x %d\n",&slines, &scols);
169
170 /*
171 * we do not close the file so that we will have a hold of the
172 * inode for as long as possible
173 */
174
175 initscr();
176
177 if (slines > LINES)
178 {
179 endwin();
180 printf("Sorry, original game was played on a screen with %d lines.\n",slines);
181 printf("Current screen only has %d lines. Unable to restore game\n",LINES);
182 return(FALSE);
183 }
184
185 if (scols > COLS)
186 {
187 endwin();
188 printf("Sorry, original game was played on a screen with %d columns.\n",scols);
189 printf("Current screen only has %d columns. Unable to restore game\n",COLS);
190 return(FALSE);
191 }
192
193 cw = newwin(LINES, COLS, 0, 0);
194 mw = newwin(LINES, COLS, 0, 0);
195 hw = newwin(LINES, COLS, 0, 0);
196 nocrmode();
197 keypad(cw,1);
198 mpos = 0;
199 mvwprintw(cw, 0, 0, "%s", file);
200
201 if (rs_restore_file(inf) != 0)
202 {
203 endwin();
204 printf("Cannot restore file\n");
205 return(FALSE);
206 }
207
208 if (!wizard && (md_unlink_open_file(file, inf) < 0))
209 {
210 endwin();
211 printf("Cannot unlink file\n");
212 return FALSE;
213 }
214
215 environ = envp;
216 strcpy(file_name, file);
217 setup();
218 clearok(curscr, TRUE);
219 touchwin(cw);
220 srand(getpid());
221 status();
222 playit();
223 /*NOTREACHED*/
224 return(0);
225 }
226
227 /*
228 * perform an encrypted write
229 */
230 encwrite(starta, size, outf)
231 register void *starta;
232 unsigned int size;
233 register FILE *outf;
234 {
235 register char *ep;
236 register char *start = starta;
237 unsigned int o_size = size;
238 ep = encstr;
239
240 while (size)
241 {
242 if (putc(*start++ ^ *ep++, outf) == EOF)
243 return(o_size - size);
244 if (*ep == '\0')
245 ep = encstr;
246 size--;
247 }
248
249 return(o_size - size);
250 }
251
252 /*
253 * perform an encrypted read
254 */
255 encread(starta, size, inf)
256 register void *starta;
257 unsigned int size;
258 register int inf;
259 {
260 register char *ep;
261 register int read_size;
262 register char *start = starta;
263
264 if ((read_size = read(inf, start, size)) == -1 || read_size == 0)
265 return read_size;
266
267 ep = encstr;
268
269 while (size--)
270 {
271 *start++ ^= *ep++;
272 if (*ep == '\0')
273 ep = encstr;
274 }
275 return read_size;
276 }