save.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /* $NetBSD: save.c,v 1.8 2003/08/07 09:36:51 agc Exp $ */
  2. /*-
  3. * Copyright (c) 1991, 1993
  4. * The Regents of the University of California. All rights reserved.
  5. *
  6. * The game adventure was originally written in Fortran by Will Crowther
  7. * and Don Woods. It was later translated to C and enhanced by Jim
  8. * Gillogly. This code is derived from software contributed to Berkeley
  9. * by Jim Gillogly at The Rand Corporation.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. * 3. Neither the name of the University nor the names of its contributors
  20. * may be used to endorse or promote products derived from this software
  21. * without specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33. * SUCH DAMAGE.
  34. */
  35. #include <sys/cdefs.h>
  36. #ifndef lint
  37. #if 0
  38. static char sccsid[] = "@(#)save.c 8.1 (Berkeley) 5/31/93";
  39. #else
  40. __RCSID("$NetBSD: save.c,v 1.8 2003/08/07 09:36:51 agc Exp $");
  41. #endif
  42. #endif /* not lint */
  43. #include <err.h>
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include "hdr.h"
  47. #include "extern.h"
  48. struct savestruct {
  49. void *address;
  50. int width;
  51. };
  52. struct savestruct save_array[] =
  53. {
  54. {&abbnum, sizeof(abbnum)},
  55. {&attack, sizeof(attack)},
  56. {&blklin, sizeof(blklin)},
  57. {&bonus, sizeof(bonus)},
  58. {&chloc, sizeof(chloc)},
  59. {&chloc2, sizeof(chloc2)},
  60. {&clock1, sizeof(clock1)},
  61. {&clock2, sizeof(clock2)},
  62. {&closed, sizeof(closed)},
  63. {&closng, sizeof(closng)},
  64. {&daltlc, sizeof(daltlc)},
  65. {&demo, sizeof(demo)},
  66. {&detail, sizeof(detail)},
  67. {&dflag, sizeof(dflag)},
  68. {&dkill, sizeof(dkill)},
  69. {&dtotal, sizeof(dtotal)},
  70. {&foobar, sizeof(foobar)},
  71. {&gaveup, sizeof(gaveup)},
  72. {&holdng, sizeof(holdng)},
  73. {&iwest, sizeof(iwest)},
  74. {&k, sizeof(k)},
  75. {&k2, sizeof(k2)},
  76. {&knfloc, sizeof(knfloc)},
  77. {&kq, sizeof(kq)},
  78. {&latncy, sizeof(latncy)},
  79. {&limit, sizeof(limit)},
  80. {&lmwarn, sizeof(lmwarn)},
  81. {&loc, sizeof(loc)},
  82. {&maxdie, sizeof(maxdie)},
  83. {&mxscor, sizeof(mxscor)},
  84. {&newloc, sizeof(newloc)},
  85. {&numdie, sizeof(numdie)},
  86. {&obj, sizeof(obj)},
  87. {&oldlc2, sizeof(oldlc2)},
  88. {&oldloc, sizeof(oldloc)},
  89. {&panic, sizeof(panic)},
  90. {&saveday, sizeof(saveday)},
  91. {&savet, sizeof(savet)},
  92. {&scorng, sizeof(scorng)},
  93. {&spk, sizeof(spk)},
  94. {&stick, sizeof(stick)},
  95. {&tally, sizeof(tally)},
  96. {&tally2, sizeof(tally2)},
  97. {&tkk, sizeof(tkk)},
  98. {&turns, sizeof(turns)},
  99. {&verb, sizeof(verb)},
  100. {&wd1, sizeof(wd1)},
  101. {&wd2, sizeof(wd2)},
  102. {&wzdark, sizeof(wzdark)},
  103. {&yea, sizeof(yea)},
  104. {atloc, sizeof(atloc)},
  105. {dloc, sizeof(dloc)},
  106. {dseen, sizeof(dseen)},
  107. {fixed, sizeof(fixed)},
  108. {hinted, sizeof(hinted)},
  109. {links, sizeof(links)},
  110. {odloc, sizeof(odloc)},
  111. {place, sizeof(place)},
  112. {prop, sizeof(prop)},
  113. {tk, sizeof(tk)},
  114. {NULL, 0}
  115. };
  116. int
  117. save(outfile) /* Two passes on data: first to get checksum,
  118. * second */
  119. const char *outfile; /* to output the data using checksum to start
  120. * random #s */
  121. {
  122. FILE *out;
  123. struct savestruct *p;
  124. char *s;
  125. long sum;
  126. int i;
  127. crc_start();
  128. for (p = save_array; p->address != NULL; p++)
  129. sum = crc(p->address, p->width);
  130. srandom((int) sum);
  131. if ((out = fopen(outfile, "wb")) == NULL) {
  132. fprintf(stderr,
  133. "Hmm. The name \"%s\" appears to be magically blocked.\n",
  134. outfile);
  135. return 1;
  136. }
  137. fwrite(&sum, sizeof(sum), 1, out); /* Here's the random() key */
  138. for (p = save_array; p->address != NULL; p++) {
  139. for (s = p->address, i = 0; i < p->width; i++, s++)
  140. *s = (*s ^ random()) & 0xFF; /* Lightly encrypt */
  141. fwrite(p->address, p->width, 1, out);
  142. }
  143. if (fclose(out) != 0) {
  144. warn("writing %s", outfile);
  145. return 1;
  146. }
  147. return 0;
  148. }
  149. int
  150. restore(infile)
  151. const char *infile;
  152. {
  153. FILE *in;
  154. struct savestruct *p;
  155. char *s;
  156. long sum, cksum = 0;
  157. int i;
  158. if ((in = fopen(infile, "rb")) == NULL) {
  159. fprintf(stderr,
  160. "Hmm. The file \"%s\" appears to be magically blocked.\n",
  161. infile);
  162. return 1;
  163. }
  164. fread(&sum, sizeof(sum), 1, in); /* Get the seed */
  165. srandom((int) sum);
  166. for (p = save_array; p->address != NULL; p++) {
  167. fread(p->address, p->width, 1, in);
  168. for (s = p->address, i = 0; i < p->width; i++, s++)
  169. *s = (*s ^ random()) & 0xFF; /* Lightly decrypt */
  170. }
  171. fclose(in);
  172. crc_start(); /* See if she cheated */
  173. for (p = save_array; p->address != NULL; p++)
  174. cksum = crc(p->address, p->width);
  175. if (sum != cksum) /* Tsk tsk */
  176. return 2; /* Altered the file */
  177. /* We successfully restored, so this really was a save file */
  178. /* Get rid of the file, but don't bother checking that we did */
  179. return 0;
  180. }