Remove unneeded inclusions of <sys/cdefs.h> throughout the tree.
[games.git] / games / hack / hack.save.c
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 $ */
4
5 #include "hack.h"
6
7 extern char SAVEF[], nul[];
8
9 static bool dosave0(int);
10
11 int
12 dosave(void)
13 {
14         if (dosave0(0)) {
15                 settty("Be seeing you ...\n");
16                 exit(0);
17         }
18         return (0);
19 }
20
21 #ifndef NOSAVEONHANGUP
22 void
23 hangup(int n __unused)
24 {
25         dosave0(1);
26         exit(1);
27 }
28 #endif /* NOSAVEONHANGUP */
29
30 /* returns 1 if save successful */
31 static bool
32 dosave0(int hu)
33 {
34         int fd, ofd;
35         int tmp;        /* not ! */
36
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);
44         }
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);
76                 }
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);
82         }
83         close(fd);
84         glo(dlevel);
85         unlink(lock);   /* get rid of current level --jgm */
86         glo(0);
87         unlink(lock);
88         return (1);
89 }
90
91 bool
92 dorecover(int fd)
93 {
94         int nfd;
95         int tmp;                /* not a ! */
96         unsigned mid;           /* idem */
97         struct obj *otmp;
98
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);
114         }
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);
135         }
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;
154                 }
155         }
156         if (u.ustuck) {
157                 struct monst *mtmp;
158
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;
165         }
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);
172 }
173
174 struct obj *
175 restobjchn(int fd)
176 {
177         struct obj *otmp, *otmp2;
178         struct obj *first = NULL;
179         int xl;
180
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;
195         }
196         if (first && otmp2->nobj) {
197                 impossible("Restobjchn: error reading objchn.");
198                 otmp2->nobj = 0;
199         }
200         return (first);
201 }
202
203 struct monst *
204 restmonchn(int fd)
205 {
206         struct monst *mtmp, *mtmp2;
207         struct monst *first = NULL;
208         int xl;
209         struct permonst *monbegin;
210         long differ;
211
212         mread(fd, (char *)&monbegin, sizeof(monbegin));
213         differ = (char *)(&mons[0]) - (char *)(monbegin);
214
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;
234         }
235         if (first && mtmp2->nmon) {
236                 impossible("Restmonchn: error reading monchn.");
237                 mtmp2->nmon = 0;
238         }
239         return (first);
240 }