xref: /dragonfly/games/adventure/save.c (revision 3f5e28f4)
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.3 2007/04/18 18:32:12 swildner 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 /* Two passes on data: first to get checksum, second */
121 /* to output the data using checksum to start random #s */
122 int
123 save(const char *outfile)
124 {
125 	FILE *out;
126 	struct savestruct *p;
127 	char *s;
128 	long sum;
129 	int i;
130 
131 	crc_start();
132 	for (p = save_array; p->address != NULL; p++)
133 		sum = crc(p->address, p->width);
134 	srandom((int) sum);
135 
136 	if ((out = fopen(outfile, "wb")) == NULL)
137 	{
138 	    fprintf(stderr,
139 		"Hmm.  The name \"%s\" appears to be magically blocked.\n",
140 		outfile);
141 	    return 1;
142 	}
143 
144 	fwrite(&sum, sizeof(sum), 1, out);      /* Here's the random() key */
145 	for (p = save_array; p->address != NULL; p++)
146 	{
147 		for (s = p->address, i = 0; i < p->width; i++, s++)
148 			*s = (*s ^ random()) & 0xFF;      /* Lightly encrypt */
149 		fwrite(p->address, p->width, 1, out);
150 	}
151 	fclose(out);
152 	return 0;
153 }
154 
155 int
156 restore(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 }
192