xref: /original-bsd/games/adventure/save.c (revision b8aab004)
1 /*-
2  * Copyright (c) 1991, 1993 The Regents of the University of California.
3  * 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  * %sccs.include.redist.c%
11  */
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)save.c	5.3 (Berkeley) 05/13/93";
15 #endif /* not lint */
16 
17 #include <stdio.h>
18 #include "hdr.h"
19 
20 struct savestruct
21 {
22 	void *address;
23 	int width;
24 };
25 
26 struct savestruct save_array[] =
27 {
28 	&abbnum,        sizeof(abbnum),
29 	&attack,        sizeof(attack),
30 	&blklin,        sizeof(blklin),
31 	&bonus,         sizeof(bonus),
32 	&chloc,         sizeof(chloc),
33 	&chloc2,        sizeof(chloc2),
34 	&clock1,        sizeof(clock1),
35 	&clock2,        sizeof(clock2),
36 	&closed,        sizeof(closed),
37 	&closng,        sizeof(closng),
38 	&daltlc,        sizeof(daltlc),
39 	&demo,          sizeof(demo),
40 	&detail,        sizeof(detail),
41 	&dflag,         sizeof(dflag),
42 	&dkill,         sizeof(dkill),
43 	&dtotal,        sizeof(dtotal),
44 	&foobar,        sizeof(foobar),
45 	&gaveup,        sizeof(gaveup),
46 	&holdng,        sizeof(holdng),
47 	&iwest,         sizeof(iwest),
48 	&k,             sizeof(k),
49 	&k2,            sizeof(k2),
50 	&knfloc,        sizeof(knfloc),
51 	&kq,            sizeof(kq),
52 	&latncy,        sizeof(latncy),
53 	&limit,         sizeof(limit),
54 	&lmwarn,        sizeof(lmwarn),
55 	&loc,           sizeof(loc),
56 	&maxdie,        sizeof(maxdie),
57 	&mxscor,        sizeof(mxscor),
58 	&newloc,        sizeof(newloc),
59 	&numdie,        sizeof(numdie),
60 	&obj,           sizeof(obj),
61 	&oldlc2,        sizeof(oldlc2),
62 	&oldloc,        sizeof(oldloc),
63 	&panic,         sizeof(panic),
64 	&saved,         sizeof(saved),
65 	&savet,         sizeof(savet),
66 	&scorng,        sizeof(scorng),
67 	&spk,           sizeof(spk),
68 	&stick,         sizeof(stick),
69 	&tally,         sizeof(tally),
70 	&tally2,        sizeof(tally2),
71 	&tkk,           sizeof(tkk),
72 	&turns,         sizeof(turns),
73 	&verb,          sizeof(verb),
74 	&wd1,           sizeof(wd1),
75 	&wd2,           sizeof(wd2),
76 	&wzdark,        sizeof(wzdark),
77 	&yea,           sizeof(yea),
78 	atloc,          sizeof(atloc),
79 	dloc,           sizeof(dloc),
80 	dseen,          sizeof(dseen),
81 	fixed,          sizeof(fixed),
82 	hinted,         sizeof(hinted),
83 	link,           sizeof(link),
84 	odloc,          sizeof(odloc),
85 	place,          sizeof(place),
86 	prop,           sizeof(prop),
87 	tk,             sizeof(tk),
88 
89 	NULL,   0
90 };
91 
92 save(outfile)   /* Two passes on data: first to get checksum, second */
93 char *outfile;  /* to output the data using checksum to start random #s */
94 {
95 	FILE *out;
96 	struct savestruct *p;
97 	char *s;
98 	long sum;
99 	int i;
100 
101 	crc_start();
102 	for (p = save_array; p->address != NULL; p++)
103 		sum = crc(p->address, p->width);
104 	srandom((int) sum);
105 
106 	if ((out = fopen(outfile, "wb")) == NULL)
107 	{
108 	    fprintf(stderr,
109 		"Hmm.  The name \"%s\" appears to be magically blocked.\n",
110 		outfile);
111 	    return 1;
112 	}
113 	fwrite(&sum, sizeof(sum), 1, out);      /* Here's the random() key */
114 	for (p = save_array; p->address != NULL; p++)
115 	{
116 		for (s = p->address, i = 0; i < p->width; i++, s++)
117 			*s = (*s ^ random()) & 0xFF;      /* Lightly encrypt */
118 		fwrite(p->address, p->width, 1, out);
119 	}
120 	fclose(out);
121 	return 0;
122 }
123 
124 restore(infile)
125 char *infile;
126 {
127 	FILE *in;
128 	struct savestruct *p;
129 	char *s;
130 	long sum, cksum;
131 	int i;
132 
133 	if ((in = fopen(infile, "rb")) == NULL)
134 	{
135 	    fprintf(stderr,
136 		"Hmm.  The file \"%s\" appears to be magically blocked.\n",
137 		infile);
138 	    return 1;
139 	}
140 	fread(&sum, sizeof(sum), 1, in);        /* Get the seed */
141 	srandom((int) sum);
142 	for (p = save_array; p->address != NULL; p++)
143 	{
144 		fread(p->address, p->width, 1, in);
145 		for (s = p->address, i = 0; i < p->width; i++, s++)
146 			*s = (*s ^ random()) & 0xFF;  /* Lightly decrypt */
147 	}
148 	fclose(in);
149 
150 	crc_start();                            /* See if she cheated */
151 	for (p = save_array; p->address != NULL; p++)
152 		cksum = crc(p->address, p->width);
153 	if (sum != cksum)                       /* Tsk tsk */
154 	    return 2;                           /* Altered the file */
155 	/* We successfully restored, so this really was a save file */
156 	/* Get rid of the file, but don't bother checking that we did */
157 	return 0;
158 }
159