147851Sbostic /*-
2*60733Sbostic * Copyright (c) 1991, 1993
3*60733Sbostic * The Regents of the University of California. All rights reserved.
447851Sbostic *
559968Sbostic * The game adventure was originally written in Fortran by Will Crowther
659968Sbostic * and Don Woods. It was later translated to C and enhanced by Jim
759968Sbostic * Gillogly. This code is derived from software contributed to Berkeley
859968Sbostic * by Jim Gillogly at The Rand Corporation.
947851Sbostic *
1047851Sbostic * %sccs.include.redist.c%
1147851Sbostic */
1247851Sbostic
1347851Sbostic #ifndef lint
14*60733Sbostic static char sccsid[] = "@(#)save.c 8.1 (Berkeley) 05/31/93";
1547851Sbostic #endif /* not lint */
1647851Sbostic
1759968Sbostic #include <stdio.h>
1859968Sbostic #include "hdr.h"
196739Srrh
2059968Sbostic struct savestruct
2159968Sbostic {
2259968Sbostic void *address;
2359968Sbostic int width;
2459968Sbostic };
256739Srrh
2659968Sbostic struct savestruct save_array[] =
2759968Sbostic {
2859968Sbostic &abbnum, sizeof(abbnum),
2959968Sbostic &attack, sizeof(attack),
3059968Sbostic &blklin, sizeof(blklin),
3159968Sbostic &bonus, sizeof(bonus),
3259968Sbostic &chloc, sizeof(chloc),
3359968Sbostic &chloc2, sizeof(chloc2),
3459968Sbostic &clock1, sizeof(clock1),
3559968Sbostic &clock2, sizeof(clock2),
3659968Sbostic &closed, sizeof(closed),
3759968Sbostic &closng, sizeof(closng),
3859968Sbostic &daltlc, sizeof(daltlc),
3959968Sbostic &demo, sizeof(demo),
4059968Sbostic &detail, sizeof(detail),
4159968Sbostic &dflag, sizeof(dflag),
4259968Sbostic &dkill, sizeof(dkill),
4359968Sbostic &dtotal, sizeof(dtotal),
4459968Sbostic &foobar, sizeof(foobar),
4559968Sbostic &gaveup, sizeof(gaveup),
4659968Sbostic &holdng, sizeof(holdng),
4759968Sbostic &iwest, sizeof(iwest),
4859968Sbostic &k, sizeof(k),
4959968Sbostic &k2, sizeof(k2),
5059968Sbostic &knfloc, sizeof(knfloc),
5159968Sbostic &kq, sizeof(kq),
5259968Sbostic &latncy, sizeof(latncy),
5359968Sbostic &limit, sizeof(limit),
5459968Sbostic &lmwarn, sizeof(lmwarn),
5559968Sbostic &loc, sizeof(loc),
5659968Sbostic &maxdie, sizeof(maxdie),
5759968Sbostic &mxscor, sizeof(mxscor),
5859968Sbostic &newloc, sizeof(newloc),
5959968Sbostic &numdie, sizeof(numdie),
6059968Sbostic &obj, sizeof(obj),
6159968Sbostic &oldlc2, sizeof(oldlc2),
6259968Sbostic &oldloc, sizeof(oldloc),
6359968Sbostic &panic, sizeof(panic),
6459968Sbostic &saved, sizeof(saved),
6559968Sbostic &savet, sizeof(savet),
6659968Sbostic &scorng, sizeof(scorng),
6759968Sbostic &spk, sizeof(spk),
6859968Sbostic &stick, sizeof(stick),
6959968Sbostic &tally, sizeof(tally),
7059968Sbostic &tally2, sizeof(tally2),
7159968Sbostic &tkk, sizeof(tkk),
7259968Sbostic &turns, sizeof(turns),
7359968Sbostic &verb, sizeof(verb),
7459968Sbostic &wd1, sizeof(wd1),
7559968Sbostic &wd2, sizeof(wd2),
7659968Sbostic &wzdark, sizeof(wzdark),
7759968Sbostic &yea, sizeof(yea),
7859968Sbostic atloc, sizeof(atloc),
7959968Sbostic dloc, sizeof(dloc),
8059968Sbostic dseen, sizeof(dseen),
8159968Sbostic fixed, sizeof(fixed),
8259968Sbostic hinted, sizeof(hinted),
8359968Sbostic link, sizeof(link),
8459968Sbostic odloc, sizeof(odloc),
8559968Sbostic place, sizeof(place),
8659968Sbostic prop, sizeof(prop),
8759968Sbostic tk, sizeof(tk),
886739Srrh
8959968Sbostic NULL, 0
9059968Sbostic };
9159968Sbostic
save(outfile)9259968Sbostic save(outfile) /* Two passes on data: first to get checksum, second */
9359968Sbostic char *outfile; /* to output the data using checksum to start random #s */
9459968Sbostic {
9559968Sbostic FILE *out;
9659968Sbostic struct savestruct *p;
9759968Sbostic char *s;
9859968Sbostic long sum;
9959968Sbostic int i;
10059968Sbostic
10159968Sbostic crc_start();
10259968Sbostic for (p = save_array; p->address != NULL; p++)
10359968Sbostic sum = crc(p->address, p->width);
10459968Sbostic srandom((int) sum);
10559968Sbostic
10659968Sbostic if ((out = fopen(outfile, "wb")) == NULL)
10759968Sbostic {
10859968Sbostic fprintf(stderr,
10959968Sbostic "Hmm. The name \"%s\" appears to be magically blocked.\n",
11059968Sbostic outfile);
11159968Sbostic return 1;
1126739Srrh }
11359968Sbostic fwrite(&sum, sizeof(sum), 1, out); /* Here's the random() key */
11459968Sbostic for (p = save_array; p->address != NULL; p++)
11559968Sbostic {
11659968Sbostic for (s = p->address, i = 0; i < p->width; i++, s++)
11759968Sbostic *s = (*s ^ random()) & 0xFF; /* Lightly encrypt */
11859968Sbostic fwrite(p->address, p->width, 1, out);
1196739Srrh }
12059968Sbostic fclose(out);
12159968Sbostic return 0;
12259968Sbostic }
1236739Srrh
restore(infile)12459968Sbostic restore(infile)
12559968Sbostic char *infile;
12659968Sbostic {
12759968Sbostic FILE *in;
12859968Sbostic struct savestruct *p;
12959968Sbostic char *s;
13059968Sbostic long sum, cksum;
13159968Sbostic int i;
13259968Sbostic
13359968Sbostic if ((in = fopen(infile, "rb")) == NULL)
13459968Sbostic {
13559968Sbostic fprintf(stderr,
13659968Sbostic "Hmm. The file \"%s\" appears to be magically blocked.\n",
13759968Sbostic infile);
13859968Sbostic return 1;
1396739Srrh }
14059968Sbostic fread(&sum, sizeof(sum), 1, in); /* Get the seed */
14159968Sbostic srandom((int) sum);
14259968Sbostic for (p = save_array; p->address != NULL; p++)
14359968Sbostic {
14459968Sbostic fread(p->address, p->width, 1, in);
14559968Sbostic for (s = p->address, i = 0; i < p->width; i++, s++)
14659968Sbostic *s = (*s ^ random()) & 0xFF; /* Lightly decrypt */
14759968Sbostic }
14859968Sbostic fclose(in);
14959968Sbostic
15059968Sbostic crc_start(); /* See if she cheated */
15159968Sbostic for (p = save_array; p->address != NULL; p++)
15259968Sbostic cksum = crc(p->address, p->width);
15359968Sbostic if (sum != cksum) /* Tsk tsk */
15459968Sbostic return 2; /* Altered the file */
15559968Sbostic /* We successfully restored, so this really was a save file */
15659968Sbostic /* Get rid of the file, but don't bother checking that we did */
15759968Sbostic return 0;
1586739Srrh }
159