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.2 (Berkeley) 05/12/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 int crc(); 99 long sum; 100 int i; 101 102 crc_start(); 103 for (p = save_array; p->address != NULL; p++) 104 sum = crc(p->address, p->width); 105 srandom((int) sum); 106 107 if ((out = fopen(outfile, "wb")) == NULL) 108 { 109 fprintf(stderr, 110 "Hmm. The name \"%s\" appears to be magically blocked.\n", 111 outfile); 112 return 1; 113 } 114 fwrite(&sum, sizeof(sum), 1, out); /* Here's the random() key */ 115 for (p = save_array; p->address != NULL; p++) 116 { 117 for (s = p->address, i = 0; i < p->width; i++, s++) 118 *s = (*s ^ random()) & 0xFF; /* Lightly encrypt */ 119 fwrite(p->address, p->width, 1, out); 120 } 121 fclose(out); 122 return 0; 123 } 124 125 restore(infile) 126 char *infile; 127 { 128 FILE *in; 129 struct savestruct *p; 130 char *s; 131 long sum, cksum; 132 int i; 133 134 if ((in = fopen(infile, "rb")) == NULL) 135 { 136 fprintf(stderr, 137 "Hmm. The file \"%s\" appears to be magically blocked.\n", 138 infile); 139 return 1; 140 } 141 fread(&sum, sizeof(sum), 1, in); /* Get the seed */ 142 srandom((int) sum); 143 for (p = save_array; p->address != NULL; p++) 144 { 145 fread(p->address, p->width, 1, in); 146 for (s = p->address, i = 0; i < p->width; i++, s++) 147 *s = (*s ^ random()) & 0xFF; /* Lightly decrypt */ 148 } 149 fclose(in); 150 151 crc_start(); /* See if she cheated */ 152 for (p = save_array; p->address != NULL; p++) 153 cksum = crc(p->address, p->width); 154 if (sum != cksum) /* Tsk tsk */ 155 return 2; /* Altered the file */ 156 /* We successfully restored, so this really was a save file */ 157 /* Get rid of the file, but don't bother checking that we did */ 158 return 0; 159 } 160