Commit | Line | Data |
---|---|---|
da1ddb48 | 1 | /*- |
9189ca05 KB |
2 | * Copyright (c) 1991, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
da1ddb48 | 4 | * |
49016dbd KB |
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. | |
da1ddb48 KB |
9 | * |
10 | * %sccs.include.redist.c% | |
11 | */ | |
12 | ||
13 | #ifndef lint | |
9189ca05 | 14 | static char sccsid[] = "@(#)save.c 8.1 (Berkeley) %G%"; |
da1ddb48 KB |
15 | #endif /* not lint */ |
16 | ||
49016dbd KB |
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 | }; | |
0294e1a5 | 91 | |
49016dbd KB |
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; | |
49016dbd KB |
98 | long sum; |
99 | int i; | |
0294e1a5 | 100 | |
49016dbd KB |
101 | crc_start(); |
102 | for (p = save_array; p->address != NULL; p++) | |
103 | sum = crc(p->address, p->width); | |
104 | srandom((int) sum); | |
0294e1a5 | 105 | |
49016dbd KB |
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; | |
0294e1a5 | 112 | } |
49016dbd KB |
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); | |
0294e1a5 | 119 | } |
49016dbd KB |
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; | |
0294e1a5 | 132 | |
49016dbd KB |
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; | |
0294e1a5 | 139 | } |
49016dbd KB |
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; | |
0294e1a5 | 158 | } |