Initial import from FreeBSD RELENG_4:
[dragonfly.git] / games / adventure / save.c
1 /*-
2  * Copyright (c) 1991, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * The game adventure was originally written in Fortran by Will Crowther
6  * and Don Woods.  It was later translated to C and enhanced by Jim
7  * Gillogly.  This code is derived from software contributed to Berkeley
8  * by Jim Gillogly at The Rand Corporation.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. 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  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  */
38
39 #ifndef lint
40 #if 0
41 static char sccsid[] = "@(#)save.c      8.1 (Berkeley) 5/31/93";
42 #endif
43 static const char rcsid[] =
44  "$FreeBSD: src/games/adventure/save.c,v 1.8 1999/12/19 00:21:51 billf Exp $";
45 #endif /* not lint */
46
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <sys/types.h>
50 #include "hdr.h"
51
52 struct savestruct
53 {
54         void *address;
55         int width;
56 };
57
58 struct savestruct save_array[] =
59 {
60         {&abbnum,        sizeof(abbnum)},
61         {&attack,        sizeof(attack)},
62         {&blklin,        sizeof(blklin)},
63         {&bonus,         sizeof(bonus)},
64         {&chloc,         sizeof(chloc)},
65         {&chloc2,        sizeof(chloc2)},
66         {&clock1,        sizeof(clock1)},
67         {&clock2,        sizeof(clock2)},
68         {&closed,        sizeof(closed)},
69         {&closng,        sizeof(closng)},
70         {&daltlc,        sizeof(daltlc)},
71         {&demo,          sizeof(demo)},
72         {&detail,        sizeof(detail)},
73         {&dflag,         sizeof(dflag)},
74         {&dkill,         sizeof(dkill)},
75         {&dtotal,        sizeof(dtotal)},
76         {&foobar,        sizeof(foobar)},
77         {&gaveup,        sizeof(gaveup)},
78         {&holdng,        sizeof(holdng)},
79         {&iwest,         sizeof(iwest)},
80         {&k,             sizeof(k)},
81         {&k2,            sizeof(k2)},
82         {&knfloc,        sizeof(knfloc)},
83         {&kq,            sizeof(kq)},
84         {&latncy,        sizeof(latncy)},
85         {&limit,         sizeof(limit)},
86         {&lmwarn,        sizeof(lmwarn)},
87         {&loc,           sizeof(loc)},
88         {&maxdie,        sizeof(maxdie)},
89         {&mxscor,        sizeof(mxscor)},
90         {&newloc,        sizeof(newloc)},
91         {&numdie,        sizeof(numdie)},
92         {&obj,           sizeof(obj)},
93         {&oldlc2,        sizeof(oldlc2)},
94         {&oldloc,        sizeof(oldloc)},
95         {&panic,         sizeof(panic)},
96         {&saved,         sizeof(saved)},
97         {&savet,         sizeof(savet)},
98         {&scorng,        sizeof(scorng)},
99         {&spk,           sizeof(spk)},
100         {&stick,         sizeof(stick)},
101         {&tally,         sizeof(tally)},
102         {&tally2,        sizeof(tally2)},
103         {&tkk,           sizeof(tkk)},
104         {&turns,         sizeof(turns)},
105         {&verb,          sizeof(verb)},
106         {&wd1,           sizeof(wd1)},
107         {&wd2,           sizeof(wd2)},
108         {&wzdark,        sizeof(wzdark)},
109         {&yea,           sizeof(yea)},
110         {atloc,          sizeof(atloc)},
111         {dloc,           sizeof(dloc)},
112         {dseen,          sizeof(dseen)},
113         {fixed,          sizeof(fixed)},
114         {hinted,         sizeof(hinted)},
115         {linkx,           sizeof(linkx)},
116         {odloc,          sizeof(odloc)},
117         {place,          sizeof(place)},
118         {prop,           sizeof(prop)},
119         {tk,             sizeof(tk)},
120
121         {NULL,   0}
122 };
123
124 int
125 save(outfile)   /* Two passes on data: first to get checksum, second */
126 const char *outfile;  /* to output the data using checksum to start random #s */
127 {
128         FILE *out;
129         struct savestruct *p;
130         char *s;
131         long sum;
132         int i;
133
134         crc_start();
135         for (p = save_array; p->address != NULL; p++)
136                 sum = crc(p->address, p->width);
137         srandom((int) sum);
138
139         if ((out = fopen(outfile, "wb")) == NULL)
140         {
141             fprintf(stderr,
142                 "Hmm.  The name \"%s\" appears to be magically blocked.\n",
143                 outfile);
144             return 1;
145         }
146
147         fwrite(&sum, sizeof(sum), 1, out);      /* Here's the random() key */
148         for (p = save_array; p->address != NULL; p++)
149         {
150                 for (s = p->address, i = 0; i < p->width; i++, s++)
151                         *s = (*s ^ random()) & 0xFF;      /* Lightly encrypt */
152                 fwrite(p->address, p->width, 1, out);
153         }
154         fclose(out);
155         return 0;
156 }
157
158 int
159 restore(infile)
160 const char *infile;
161 {
162         FILE *in;
163         struct savestruct *p;
164         char *s;
165         long sum, cksum;
166         int i;
167
168         cksum = 0;
169         if ((in = fopen(infile, "rb")) == NULL)
170         {
171             fprintf(stderr,
172                 "Hmm.  The file \"%s\" appears to be magically blocked.\n",
173                 infile);
174             return 1;
175         }
176
177         fread(&sum, sizeof(sum), 1, in);        /* Get the seed */
178         srandom((int) sum);
179         for (p = save_array; p->address != NULL; p++)
180         {
181                 fread(p->address, p->width, 1, in);
182                 for (s = p->address, i = 0; i < p->width; i++, s++)
183                         *s = (*s ^ random()) & 0xFF;  /* Lightly decrypt */
184         }
185         fclose(in);
186
187         crc_start();                            /* See if she cheated */
188         for (p = save_array; p->address != NULL; p++)
189                 cksum = crc(p->address, p->width);
190         if (sum != cksum)                       /* Tsk tsk */
191             return 2;                           /* Altered the file */
192         /* We successfully restored, so this really was a save file */
193         /* Get rid of the file, but don't bother checking that we did */
194         return 0;
195 }