periodic(8): Sync with FreeBSD current
[dragonfly.git] / games / hack / hack.save.c
blobafe4343300f01e84691cbfeb441f87275c0bfcc8
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.save.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.save.c,v 1.4 1999/11/16 10:26:37 marcel Exp $ */
5 #include "hack.h"
7 extern char SAVEF[], nul[];
9 static bool dosave0(int);
11 int
12 dosave(void)
14 if (dosave0(0)) {
15 settty("Be seeing you ...\n");
16 exit(0);
18 return (0);
21 #ifndef NOSAVEONHANGUP
22 void
23 hangup(int n __unused)
25 dosave0(1);
26 exit(1);
28 #endif /* NOSAVEONHANGUP */
30 /* returns 1 if save successful */
31 static bool
32 dosave0(int hu)
34 int fd, ofd;
35 int tmp; /* not ! */
37 signal(SIGHUP, SIG_IGN);
38 signal(SIGINT, SIG_IGN);
39 if ((fd = creat(SAVEF, FMASK)) < 0) {
40 if (!hu)
41 pline("Cannot open save file. (Continue or Quit)");
42 unlink(SAVEF); /* ab@unido */
43 return (0);
45 if (flags.moonphase == FULL_MOON) /* ut-sally!fletcher */
46 u.uluck--; /* and unido!ab */
47 savelev(fd, dlevel);
48 saveobjchn(fd, invent);
49 saveobjchn(fd, fcobj);
50 savemonchn(fd, fallen_down);
51 tmp = getuid();
52 bwrite(fd, (char *)&tmp, sizeof(tmp));
53 bwrite(fd, (char *)&flags, sizeof(struct flag));
54 bwrite(fd, (char *)&dlevel, sizeof(dlevel));
55 bwrite(fd, (char *)&maxdlevel, sizeof(maxdlevel));
56 bwrite(fd, (char *)&moves, sizeof(moves));
57 bwrite(fd, (char *)&u, sizeof(struct you));
58 if (u.ustuck)
59 bwrite(fd, (char *)&(u.ustuck->m_id), sizeof(u.ustuck->m_id));
60 bwrite(fd, (char *)pl_character, sizeof(pl_character));
61 bwrite(fd, (char *)genocided, sizeof(genocided));
62 bwrite(fd, (char *)fut_geno, sizeof(fut_geno));
63 savenames(fd);
64 for (tmp = 1; tmp <= maxdlevel; tmp++) {
65 if (tmp == dlevel || !level_exists[tmp])
66 continue;
67 glo(tmp);
68 if ((ofd = open(lock, O_RDONLY)) < 0) {
69 if (!hu)
70 pline("Error while saving: cannot read %s.", lock);
71 close(fd);
72 unlink(SAVEF);
73 if (!hu)
74 done("tricked");
75 return (0);
77 getlev(ofd, hackpid, tmp);
78 close(ofd);
79 bwrite(fd, (char *)&tmp, sizeof(tmp)); /* level number */
80 savelev(fd, tmp); /* actual level */
81 unlink(lock);
83 close(fd);
84 glo(dlevel);
85 unlink(lock); /* get rid of current level --jgm */
86 glo(0);
87 unlink(lock);
88 return (1);
91 bool
92 dorecover(int fd)
94 int nfd;
95 int tmp; /* not a ! */
96 unsigned mid; /* idem */
97 struct obj *otmp;
99 restoring = TRUE;
100 getlev(fd, 0, 0);
101 invent = restobjchn(fd);
102 for (otmp = invent; otmp; otmp = otmp->nobj)
103 if (otmp->owornmask)
104 setworn(otmp, otmp->owornmask);
105 fcobj = restobjchn(fd);
106 fallen_down = restmonchn(fd);
107 mread(fd, (char *)&tmp, sizeof(tmp));
108 if (tmp != (int)getuid()) { /* strange ... */
109 close(fd);
110 unlink(SAVEF);
111 puts("Saved game was not yours.");
112 restoring = FALSE;
113 return (0);
115 mread(fd, (char *)&flags, sizeof(struct flag));
116 mread(fd, (char *)&dlevel, sizeof(dlevel));
117 mread(fd, (char *)&maxdlevel, sizeof(maxdlevel));
118 mread(fd, (char *)&moves, sizeof(moves));
119 mread(fd, (char *)&u, sizeof(struct you));
120 if (u.ustuck)
121 mread(fd, (char *)&mid, sizeof(mid));
122 mread(fd, (char *)pl_character, sizeof(pl_character));
123 mread(fd, (char *)genocided, sizeof(genocided));
124 mread(fd, (char *)fut_geno, sizeof(fut_geno));
125 restnames(fd);
126 for (;;) {
127 if (read(fd, (char *)&tmp, sizeof(tmp)) != sizeof(tmp))
128 break;
129 getlev(fd, 0, tmp);
130 glo(tmp);
131 if ((nfd = creat(lock, FMASK)) < 0)
132 panic("Cannot open temp file %s!\n", lock);
133 savelev(nfd, tmp);
134 close(nfd);
136 lseek(fd, (off_t)0, SEEK_SET);
137 getlev(fd, 0, 0);
138 close(fd);
139 unlink(SAVEF);
140 if (Punished) {
141 for (otmp = fobj; otmp; otmp = otmp->nobj)
142 if (otmp->olet == CHAIN_SYM)
143 goto chainfnd;
144 panic("Cannot find the iron chain?");
145 chainfnd:
146 uchain = otmp;
147 if (!uball) {
148 for (otmp = fobj; otmp; otmp = otmp->nobj)
149 if (otmp->olet == BALL_SYM && otmp->spe)
150 goto ballfnd;
151 panic("Cannot find the iron ball?");
152 ballfnd:
153 uball = otmp;
156 if (u.ustuck) {
157 struct monst *mtmp;
159 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
160 if (mtmp->m_id == mid)
161 goto monfnd;
162 panic("Cannot find the monster ustuck.");
163 monfnd:
164 u.ustuck = mtmp;
166 #ifndef QUEST
167 setsee(); /* only to recompute seelx etc. - these weren't saved */
168 #endif /* QUEST */
169 docrt();
170 restoring = FALSE;
171 return (1);
174 struct obj *
175 restobjchn(int fd)
177 struct obj *otmp, *otmp2;
178 struct obj *first = NULL;
179 int xl;
181 /* suppress "used before set" warning from lint */
182 otmp2 = NULL;
183 for (;;) {
184 mread(fd, (char *)&xl, sizeof(xl));
185 if (xl == -1)
186 break;
187 otmp = newobj(xl);
188 if (!first)
189 first = otmp;
190 else
191 otmp2->nobj = otmp;
192 mread(fd, (char *)otmp, (unsigned)xl + sizeof(struct obj));
193 if (!otmp->o_id) otmp->o_id = flags.ident++;
194 otmp2 = otmp;
196 if (first && otmp2->nobj) {
197 impossible("Restobjchn: error reading objchn.");
198 otmp2->nobj = 0;
200 return (first);
203 struct monst *
204 restmonchn(int fd)
206 struct monst *mtmp, *mtmp2;
207 struct monst *first = NULL;
208 int xl;
209 struct permonst *monbegin;
210 long differ;
212 mread(fd, (char *)&monbegin, sizeof(monbegin));
213 differ = (char *)(&mons[0]) - (char *)(monbegin);
215 /* suppress "used before set" warning from lint */
216 mtmp2 = NULL;
217 for (;;) {
218 mread(fd, (char *)&xl, sizeof(xl));
219 if (xl == -1)
220 break;
221 mtmp = newmonst(xl);
222 if (!first)
223 first = mtmp;
224 else
225 mtmp2->nmon = mtmp;
226 mread(fd, (char *)mtmp, (unsigned)xl + sizeof(struct monst));
227 if (!mtmp->m_id)
228 mtmp->m_id = flags.ident++;
229 mtmp->data = (struct permonst *)
230 ((char *)mtmp->data + differ);
231 if (mtmp->minvent)
232 mtmp->minvent = restobjchn(fd);
233 mtmp2 = mtmp;
235 if (first && mtmp2->nmon) {
236 impossible("Restmonchn: error reading monchn.");
237 mtmp2->nmon = 0;
239 return (first);