]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - games/adventure/save.c
1. Don't overwrite scorefiles if they already exist.
[FreeBSD/FreeBSD.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$";
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 save(outfile)   /* Two passes on data: first to get checksum, second */
125 const char *outfile;  /* to output the data using checksum to start random #s */
126 {
127         FILE *out;
128         struct savestruct *p;
129         char *s;
130         long sum;
131         int i;
132
133         crc_start();
134         for (p = save_array; p->address != NULL; p++)
135                 sum = crc(p->address, p->width);
136         srandom((int) sum);
137
138         if ((out = fopen(outfile, "wb")) == NULL)
139         {
140             fprintf(stderr,
141                 "Hmm.  The name \"%s\" appears to be magically blocked.\n",
142                 outfile);
143             return 1;
144         }
145
146         fwrite(&sum, sizeof(sum), 1, out);      /* Here's the random() key */
147         for (p = save_array; p->address != NULL; p++)
148         {
149                 for (s = p->address, i = 0; i < p->width; i++, s++)
150                         *s = (*s ^ random()) & 0xFF;      /* Lightly encrypt */
151                 fwrite(p->address, p->width, 1, out);
152         }
153         fclose(out);
154         return 0;
155 }
156
157 restore(infile)
158 const char *infile;
159 {
160         FILE *in;
161         struct savestruct *p;
162         char *s;
163         long sum, cksum;
164         int i;
165
166         if ((in = fopen(infile, "rb")) == NULL)
167         {
168             fprintf(stderr,
169                 "Hmm.  The file \"%s\" appears to be magically blocked.\n",
170                 infile);
171             return 1;
172         }
173
174         fread(&sum, sizeof(sum), 1, in);        /* Get the seed */
175         srandom((int) sum);
176         for (p = save_array; p->address != NULL; p++)
177         {
178                 fread(p->address, p->width, 1, in);
179                 for (s = p->address, i = 0; i < p->width; i++, s++)
180                         *s = (*s ^ random()) & 0xFF;  /* Lightly decrypt */
181         }
182         fclose(in);
183
184         crc_start();                            /* See if she cheated */
185         for (p = save_array; p->address != NULL; p++)
186                 cksum = crc(p->address, p->width);
187         if (sum != cksum)                       /* Tsk tsk */
188             return 2;                           /* Altered the file */
189         /* We successfully restored, so this really was a save file */
190         /* Get rid of the file, but don't bother checking that we did */
191         return 0;
192 }