Merge from vendor branch OPENSSL:
[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  * @(#)save.c   8.1 (Berkeley) 5/31/93
39  * $FreeBSD: src/games/adventure/save.c,v 1.8 1999/12/19 00:21:51 billf Exp $
40  * $DragonFly: src/games/adventure/save.c,v 1.2 2003/06/17 04:25:22 dillon Exp $
41  */
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <sys/types.h>
46 #include "hdr.h"
47
48 struct savestruct
49 {
50         void *address;
51         int width;
52 };
53
54 struct savestruct save_array[] =
55 {
56         {&abbnum,        sizeof(abbnum)},
57         {&attack,        sizeof(attack)},
58         {&blklin,        sizeof(blklin)},
59         {&bonus,         sizeof(bonus)},
60         {&chloc,         sizeof(chloc)},
61         {&chloc2,        sizeof(chloc2)},
62         {&clock1,        sizeof(clock1)},
63         {&clock2,        sizeof(clock2)},
64         {&closed,        sizeof(closed)},
65         {&closng,        sizeof(closng)},
66         {&daltlc,        sizeof(daltlc)},
67         {&demo,          sizeof(demo)},
68         {&detail,        sizeof(detail)},
69         {&dflag,         sizeof(dflag)},
70         {&dkill,         sizeof(dkill)},
71         {&dtotal,        sizeof(dtotal)},
72         {&foobar,        sizeof(foobar)},
73         {&gaveup,        sizeof(gaveup)},
74         {&holdng,        sizeof(holdng)},
75         {&iwest,         sizeof(iwest)},
76         {&k,             sizeof(k)},
77         {&k2,            sizeof(k2)},
78         {&knfloc,        sizeof(knfloc)},
79         {&kq,            sizeof(kq)},
80         {&latncy,        sizeof(latncy)},
81         {&limit,         sizeof(limit)},
82         {&lmwarn,        sizeof(lmwarn)},
83         {&loc,           sizeof(loc)},
84         {&maxdie,        sizeof(maxdie)},
85         {&mxscor,        sizeof(mxscor)},
86         {&newloc,        sizeof(newloc)},
87         {&numdie,        sizeof(numdie)},
88         {&obj,           sizeof(obj)},
89         {&oldlc2,        sizeof(oldlc2)},
90         {&oldloc,        sizeof(oldloc)},
91         {&panic,         sizeof(panic)},
92         {&saved,         sizeof(saved)},
93         {&savet,         sizeof(savet)},
94         {&scorng,        sizeof(scorng)},
95         {&spk,           sizeof(spk)},
96         {&stick,         sizeof(stick)},
97         {&tally,         sizeof(tally)},
98         {&tally2,        sizeof(tally2)},
99         {&tkk,           sizeof(tkk)},
100         {&turns,         sizeof(turns)},
101         {&verb,          sizeof(verb)},
102         {&wd1,           sizeof(wd1)},
103         {&wd2,           sizeof(wd2)},
104         {&wzdark,        sizeof(wzdark)},
105         {&yea,           sizeof(yea)},
106         {atloc,          sizeof(atloc)},
107         {dloc,           sizeof(dloc)},
108         {dseen,          sizeof(dseen)},
109         {fixed,          sizeof(fixed)},
110         {hinted,         sizeof(hinted)},
111         {linkx,           sizeof(linkx)},
112         {odloc,          sizeof(odloc)},
113         {place,          sizeof(place)},
114         {prop,           sizeof(prop)},
115         {tk,             sizeof(tk)},
116
117         {NULL,   0}
118 };
119
120 int
121 save(outfile)   /* Two passes on data: first to get checksum, second */
122 const char *outfile;  /* to output the data using checksum to start random #s */
123 {
124         FILE *out;
125         struct savestruct *p;
126         char *s;
127         long sum;
128         int i;
129
130         crc_start();
131         for (p = save_array; p->address != NULL; p++)
132                 sum = crc(p->address, p->width);
133         srandom((int) sum);
134
135         if ((out = fopen(outfile, "wb")) == NULL)
136         {
137             fprintf(stderr,
138                 "Hmm.  The name \"%s\" appears to be magically blocked.\n",
139                 outfile);
140             return 1;
141         }
142
143         fwrite(&sum, sizeof(sum), 1, out);      /* Here's the random() key */
144         for (p = save_array; p->address != NULL; p++)
145         {
146                 for (s = p->address, i = 0; i < p->width; i++, s++)
147                         *s = (*s ^ random()) & 0xFF;      /* Lightly encrypt */
148                 fwrite(p->address, p->width, 1, out);
149         }
150         fclose(out);
151         return 0;
152 }
153
154 int
155 restore(infile)
156 const char *infile;
157 {
158         FILE *in;
159         struct savestruct *p;
160         char *s;
161         long sum, cksum;
162         int i;
163
164         cksum = 0;
165         if ((in = fopen(infile, "rb")) == NULL)
166         {
167             fprintf(stderr,
168                 "Hmm.  The file \"%s\" appears to be magically blocked.\n",
169                 infile);
170             return 1;
171         }
172
173         fread(&sum, sizeof(sum), 1, in);        /* Get the seed */
174         srandom((int) sum);
175         for (p = save_array; p->address != NULL; p++)
176         {
177                 fread(p->address, p->width, 1, in);
178                 for (s = p->address, i = 0; i < p->width; i++, s++)
179                         *s = (*s ^ random()) & 0xFF;  /* Lightly decrypt */
180         }
181         fclose(in);
182
183         crc_start();                            /* See if she cheated */
184         for (p = save_array; p->address != NULL; p++)
185                 cksum = crc(p->address, p->width);
186         if (sum != cksum)                       /* Tsk tsk */
187             return 2;                           /* Altered the file */
188         /* We successfully restored, so this really was a save file */
189         /* Get rid of the file, but don't bother checking that we did */
190         return 0;
191 }