]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.save.c
Grammar fix, from ray at raylai org via jmc@openbsd.
[bsdgames-darwin.git] / hack / hack.save.c
1 /* $NetBSD: hack.save.c,v 1.8 2003/04/02 18:36:40 jsm Exp $ */
2
3 /*
4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5 * Amsterdam
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * - Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * - Neither the name of the Stichting Centrum voor Wiskunde en
20 * Informatica, nor the names of its contributors may be used to endorse or
21 * promote products derived from this software without specific prior
22 * written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37 /*
38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39 * All rights reserved.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 */
63
64 #include <sys/cdefs.h>
65 #ifndef lint
66 __RCSID("$NetBSD: hack.save.c,v 1.8 2003/04/02 18:36:40 jsm Exp $");
67 #endif /* not lint */
68
69 #include <signal.h>
70 #include <stdlib.h>
71 #include <unistd.h>
72 #include <fcntl.h>
73 #include "hack.h"
74 #include "extern.h"
75
76
77 int
78 dosave()
79 {
80 if (dosave0(0)) {
81 settty("Be seeing you ...\n");
82 exit(0);
83 }
84 return (0);
85 }
86
87 #ifndef NOSAVEONHANGUP
88 void
89 hangup(n)
90 int n __attribute__((__unused__));
91 {
92 (void) dosave0(1);
93 exit(1);
94 }
95 #endif /* NOSAVEONHANGUP */
96
97 /* returns 1 if save successful */
98 int
99 dosave0(hu)
100 int hu;
101 {
102 int fd, ofd;
103 int tmp; /* not ! */
104
105 (void) signal(SIGHUP, SIG_IGN);
106 (void) signal(SIGINT, SIG_IGN);
107 if ((fd = creat(SAVEF, FMASK)) < 0) {
108 if (!hu)
109 pline("Cannot open save file. (Continue or Quit)");
110 (void) unlink(SAVEF); /* ab@unido */
111 return (0);
112 }
113 if (flags.moonphase == FULL_MOON) /* ut-sally!fletcher */
114 u.uluck--; /* and unido!ab */
115 savelev(fd, dlevel);
116 saveobjchn(fd, invent);
117 saveobjchn(fd, fcobj);
118 savemonchn(fd, fallen_down);
119 tmp = getuid();
120 bwrite(fd, (char *) &tmp, sizeof tmp);
121 bwrite(fd, (char *) &flags, sizeof(struct flag));
122 bwrite(fd, (char *) &dlevel, sizeof dlevel);
123 bwrite(fd, (char *) &maxdlevel, sizeof maxdlevel);
124 bwrite(fd, (char *) &moves, sizeof moves);
125 bwrite(fd, (char *) &u, sizeof(struct you));
126 if (u.ustuck)
127 bwrite(fd, (char *) &(u.ustuck->m_id), sizeof u.ustuck->m_id);
128 bwrite(fd, (char *) pl_character, sizeof pl_character);
129 bwrite(fd, (char *) genocided, sizeof genocided);
130 bwrite(fd, (char *) fut_geno, sizeof fut_geno);
131 savenames(fd);
132 for (tmp = 1; tmp <= maxdlevel; tmp++) {
133
134 if (tmp == dlevel || !level_exists[tmp])
135 continue;
136 glo(tmp);
137 if ((ofd = open(lock, O_RDONLY)) < 0) {
138 if (!hu)
139 pline("Error while saving: cannot read %s.", lock);
140 (void) close(fd);
141 (void) unlink(SAVEF);
142 if (!hu)
143 done("tricked");
144 return (0);
145 }
146 getlev(ofd, hackpid, tmp);
147 (void) close(ofd);
148 bwrite(fd, (char *) &tmp, sizeof tmp); /* level number */
149 savelev(fd, tmp); /* actual level */
150 (void) unlink(lock);
151 }
152 (void) close(fd);
153 glo(dlevel);
154 (void) unlink(lock); /* get rid of current level --jgm */
155 glo(0);
156 (void) unlink(lock);
157 return (1);
158 }
159
160 int
161 dorecover(fd)
162 int fd;
163 {
164 int nfd;
165 int tmp; /* not a ! */
166 unsigned mid; /* idem */
167 struct obj *otmp;
168
169 restoring = TRUE;
170 getlev(fd, 0, 0);
171 invent = restobjchn(fd);
172 for (otmp = invent; otmp; otmp = otmp->nobj)
173 if (otmp->owornmask)
174 setworn(otmp, otmp->owornmask);
175 fcobj = restobjchn(fd);
176 fallen_down = restmonchn(fd);
177 mread(fd, (char *) &tmp, sizeof tmp);
178 if (tmp != getuid()) { /* strange ... */
179 (void) close(fd);
180 (void) unlink(SAVEF);
181 puts("Saved game was not yours.");
182 restoring = FALSE;
183 return (0);
184 }
185 mread(fd, (char *) &flags, sizeof(struct flag));
186 mread(fd, (char *) &dlevel, sizeof dlevel);
187 mread(fd, (char *) &maxdlevel, sizeof maxdlevel);
188 mread(fd, (char *) &moves, sizeof moves);
189 mread(fd, (char *) &u, sizeof(struct you));
190 if (u.ustuck)
191 mread(fd, (char *) &mid, sizeof mid);
192 mread(fd, (char *) pl_character, sizeof pl_character);
193 mread(fd, (char *) genocided, sizeof genocided);
194 mread(fd, (char *) fut_geno, sizeof fut_geno);
195 restnames(fd);
196 while (1) {
197 if (read(fd, (char *) &tmp, sizeof tmp) != sizeof tmp)
198 break;
199 getlev(fd, 0, tmp);
200 glo(tmp);
201 if ((nfd = creat(lock, FMASK)) < 0)
202 panic("Cannot open temp file %s!\n", lock);
203 savelev(nfd, tmp);
204 (void) close(nfd);
205 }
206 (void) lseek(fd, (off_t) 0, SEEK_SET);
207 getlev(fd, 0, 0);
208 (void) close(fd);
209 (void) unlink(SAVEF);
210 if (Punished) {
211 for (otmp = fobj; otmp; otmp = otmp->nobj)
212 if (otmp->olet == CHAIN_SYM)
213 goto chainfnd;
214 panic("Cannot find the iron chain?");
215 chainfnd:
216 uchain = otmp;
217 if (!uball) {
218 for (otmp = fobj; otmp; otmp = otmp->nobj)
219 if (otmp->olet == BALL_SYM && otmp->spe)
220 goto ballfnd;
221 panic("Cannot find the iron ball?");
222 ballfnd:
223 uball = otmp;
224 }
225 }
226 if (u.ustuck) {
227 struct monst *mtmp;
228
229 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
230 if (mtmp->m_id == mid)
231 goto monfnd;
232 panic("Cannot find the monster ustuck.");
233 monfnd:
234 u.ustuck = mtmp;
235 }
236 #ifndef QUEST
237 setsee(); /* only to recompute seelx etc. - these
238 * weren't saved */
239 #endif /* QUEST */
240 docrt();
241 restoring = FALSE;
242 return (1);
243 }
244
245 struct obj *
246 restobjchn(fd)
247 int fd;
248 {
249 struct obj *otmp, *otmp2 = NULL;
250 struct obj *first = 0;
251 int xl;
252 while (1) {
253 mread(fd, (char *) &xl, sizeof(xl));
254 if (xl == -1)
255 break;
256 otmp = newobj(xl);
257 if (!first)
258 first = otmp;
259 else
260 otmp2->nobj = otmp;
261 mread(fd, (char *) otmp, (unsigned) xl + sizeof(struct obj));
262 if (!otmp->o_id)
263 otmp->o_id = flags.ident++;
264 otmp2 = otmp;
265 }
266 if (first && otmp2->nobj) {
267 impossible("Restobjchn: error reading objchn.");
268 otmp2->nobj = 0;
269 }
270 return (first);
271 }
272
273 struct monst *
274 restmonchn(fd)
275 int fd;
276 {
277 struct monst *mtmp, *mtmp2 = NULL;
278 struct monst *first = 0;
279 int xl;
280
281 struct permonst *monbegin;
282 long differ;
283
284 mread(fd, (char *) &monbegin, sizeof(monbegin));
285 differ = (const char *) (&mons[0]) - (const char *) (monbegin);
286
287 #ifdef lint
288 /* suppress "used before set" warning from lint */
289 mtmp2 = 0;
290 #endif /* lint */
291 while (1) {
292 mread(fd, (char *) &xl, sizeof(xl));
293 if (xl == -1)
294 break;
295 mtmp = newmonst(xl);
296 if (!first)
297 first = mtmp;
298 else
299 mtmp2->nmon = mtmp;
300 mread(fd, (char *) mtmp, (unsigned) xl + sizeof(struct monst));
301 if (!mtmp->m_id)
302 mtmp->m_id = flags.ident++;
303 mtmp->data = (const struct permonst *)
304 ((const char *) mtmp->data + differ);
305 if (mtmp->minvent)
306 mtmp->minvent = restobjchn(fd);
307 mtmp2 = mtmp;
308 }
309 if (first && mtmp2->nmon) {
310 impossible("Restmonchn: error reading monchn.");
311 mtmp2->nmon = 0;
312 }
313 return (first);
314 }