dhcpcd: update README.DRAGONFLY
[dragonfly.git] / games / hack / hack.save.c
blob398ad8b8eddb8dabb72e05f02ab70d726a5f19bf
1 /* $NetBSD: hack.save.c,v 1.16 2011/08/06 20:42:43 dholland Exp $ */
3 /*
4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5 * Amsterdam
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
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.
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.
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.
38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39 * All rights reserved.
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.
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.
64 #include <signal.h>
65 #include <stdlib.h>
66 #include <unistd.h>
67 #include <fcntl.h>
68 #include "hack.h"
69 #include "extern.h"
71 static int dosave0(int);
73 int
74 dosave(void)
76 if (dosave0(0)) {
77 settty("Be seeing you ...\n");
78 exit(0);
80 return (0);
83 #ifndef NOSAVEONHANGUP
84 void
85 hang_up(int n __unused)
87 (void) dosave0(1);
88 exit(1);
90 #endif /* NOSAVEONHANGUP */
92 /* returns 1 if save successful */
93 static int
94 dosave0(int hu)
96 int fd, ofd;
97 int tmp; /* not ! */
99 (void) signal(SIGHUP, SIG_IGN);
100 (void) signal(SIGINT, SIG_IGN);
101 if ((fd = creat(SAVEF, FMASK)) < 0) {
102 if (!hu)
103 pline("Cannot open save file. (Continue or Quit)");
104 (void) unlink(SAVEF); /* ab@unido */
105 return (0);
107 if (flags.moonphase == FULL_MOON) /* ut-sally!fletcher */
108 u.uluck--; /* and unido!ab */
109 savelev(fd, dlevel);
110 saveobjchn(fd, invent);
111 saveobjchn(fd, fcobj);
112 savemonchn(fd, fallen_down);
113 tmp = getuid();
114 bwrite(fd, &tmp, sizeof tmp);
115 bwrite(fd, &flags, sizeof(struct flag));
116 bwrite(fd, &dlevel, sizeof dlevel);
117 bwrite(fd, &maxdlevel, sizeof maxdlevel);
118 bwrite(fd, &moves, sizeof moves);
119 bwrite(fd, &u, sizeof(struct you));
120 if (u.ustuck)
121 bwrite(fd, &(u.ustuck->m_id), sizeof u.ustuck->m_id);
122 bwrite(fd, pl_character, sizeof pl_character);
123 bwrite(fd, genocided, sizeof genocided);
124 bwrite(fd, fut_geno, sizeof fut_geno);
125 savenames(fd);
126 for (tmp = 1; tmp <= maxdlevel; tmp++) {
128 if (tmp == dlevel || !level_exists[tmp])
129 continue;
130 glo(tmp);
131 if ((ofd = open(lock, O_RDONLY)) < 0) {
132 if (!hu)
133 pline("Error while saving: cannot read %s.", lock);
134 (void) close(fd);
135 (void) unlink(SAVEF);
136 if (!hu)
137 done("tricked");
138 return (0);
140 getlev(ofd, hackpid, tmp);
141 (void) close(ofd);
142 bwrite(fd, &tmp, sizeof tmp); /* level number */
143 savelev(fd, tmp); /* actual level */
144 (void) unlink(lock);
146 (void) close(fd);
147 glo(dlevel);
148 (void) unlink(lock); /* get rid of current level --jgm */
149 glo(0);
150 (void) unlink(lock);
151 return (1);
155 dorecover(int fd)
157 int nfd;
158 int tmp; /* not a ! */
159 unsigned mid; /* idem */
160 struct obj *otmp;
162 restoring = TRUE;
163 getlev(fd, 0, 0);
164 invent = restobjchn(fd);
165 for (otmp = invent; otmp; otmp = otmp->nobj)
166 if (otmp->owornmask)
167 setworn(otmp, otmp->owornmask);
168 fcobj = restobjchn(fd);
169 fallen_down = restmonchn(fd);
170 mread(fd, &tmp, sizeof tmp);
171 if (tmp != (int) getuid()) { /* strange ... */
172 (void) close(fd);
173 (void) unlink(SAVEF);
174 puts("Saved game was not yours.");
175 restoring = FALSE;
176 return (0);
178 mread(fd, &flags, sizeof(struct flag));
179 mread(fd, &dlevel, sizeof dlevel);
180 mread(fd, &maxdlevel, sizeof maxdlevel);
181 mread(fd, &moves, sizeof moves);
182 mread(fd, &u, sizeof(struct you));
183 if (u.ustuck)
184 mread(fd, &mid, sizeof mid);
185 mread(fd, pl_character, sizeof pl_character);
186 mread(fd, genocided, sizeof genocided);
187 mread(fd, fut_geno, sizeof fut_geno);
188 restnames(fd);
189 while (1) {
190 if (read(fd, &tmp, sizeof tmp) != sizeof tmp)
191 break;
192 getlev(fd, 0, tmp);
193 glo(tmp);
194 if ((nfd = creat(lock, FMASK)) < 0)
195 panic("Cannot open temp file %s!\n", lock);
196 savelev(nfd, tmp);
197 (void) close(nfd);
199 (void) lseek(fd, (off_t) 0, SEEK_SET);
200 getlev(fd, 0, 0);
201 (void) close(fd);
202 (void) unlink(SAVEF);
203 if (Punished) {
204 for (otmp = fobj; otmp; otmp = otmp->nobj)
205 if (otmp->olet == CHAIN_SYM)
206 goto chainfnd;
207 panic("Cannot find the iron chain?");
208 chainfnd:
209 uchain = otmp;
210 if (!uball) {
211 for (otmp = fobj; otmp; otmp = otmp->nobj)
212 if (otmp->olet == BALL_SYM && otmp->spe)
213 goto ballfnd;
214 panic("Cannot find the iron ball?");
215 ballfnd:
216 uball = otmp;
219 if (u.ustuck) {
220 struct monst *mtmp;
222 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
223 if (mtmp->m_id == mid)
224 goto monfnd;
225 panic("Cannot find the monster ustuck.");
226 monfnd:
227 u.ustuck = mtmp;
229 #ifndef QUEST
230 setsee(); /* only to recompute seelx etc. - these
231 * weren't saved */
232 #endif /* QUEST */
233 docrt();
234 restoring = FALSE;
235 return (1);
238 struct obj *
239 restobjchn(int fd)
241 struct obj *otmp, *otmp2 = NULL;
242 struct obj *first = 0;
243 int xl;
244 while (1) {
245 mread(fd, &xl, sizeof(xl));
246 if (xl == -1)
247 break;
248 otmp = newobj(xl);
249 if (!first)
250 first = otmp;
251 else
252 otmp2->nobj = otmp;
253 mread(fd, otmp, (unsigned) xl + sizeof(struct obj));
254 if (!otmp->o_id)
255 otmp->o_id = flags.ident++;
256 otmp2 = otmp;
258 if (first && otmp2->nobj) {
259 impossible("Restobjchn: error reading objchn.");
260 otmp2->nobj = 0;
262 return (first);
265 struct monst *
266 restmonchn(int fd)
268 struct monst *mtmp, *mtmp2 = NULL;
269 struct monst *first = 0;
270 int xl;
272 struct permonst *monbegin;
273 long differ;
275 mread(fd, &monbegin, sizeof(monbegin));
276 differ = (const char *) (&mons[0]) - (const char *) (monbegin);
278 #ifdef lint
279 /* suppress "used before set" warning from lint */
280 mtmp2 = 0;
281 #endif /* lint */
282 while (1) {
283 mread(fd, &xl, sizeof(xl));
284 if (xl == -1)
285 break;
286 mtmp = newmonst(xl);
287 if (!first)
288 first = mtmp;
289 else
290 mtmp2->nmon = mtmp;
291 mread(fd, mtmp, (unsigned) xl + sizeof(struct monst));
292 if (!mtmp->m_id)
293 mtmp->m_id = flags.ident++;
294 mtmp->data = (const struct permonst *)
295 ((const char *) mtmp->data + differ);
296 if (mtmp->minvent)
297 mtmp->minvent = restobjchn(fd);
298 mtmp2 = mtmp;
300 if (first && mtmp2->nmon) {
301 impossible("Restmonchn: error reading monchn.");
302 mtmp2->nmon = 0;
304 return (first);