-/* $NetBSD: save.c,v 1.12 2012/01/07 22:23:16 dholland Exp $ */
+/* $NetBSD: save.c,v 1.14 2014/03/22 22:04:40 dholland Exp $ */
/*-
* Copyright (c) 1991, 1993
#if 0
static char sccsid[] = "@(#)save.c 8.1 (Berkeley) 5/31/93";
#else
-__RCSID("$NetBSD: save.c,v 1.12 2012/01/07 22:23:16 dholland Exp $");
+__RCSID("$NetBSD: save.c,v 1.14 2014/03/22 22:04:40 dholland Exp $");
#endif
#endif /* not lint */
#include "hdr.h"
#include "extern.h"
+#define __arraycount(a) (sizeof(a) / sizeof(*(a)))
+
struct savefile {
FILE *f;
const char *name;
bool warned;
- unsigned bintextpos;
+ size_t bintextpos;
uint32_t key;
- uint32_t sum;
+ struct crcstate crc;
unsigned char pad[8];
unsigned padpos;
};
#define BINTEXT_WIDTH 60
-#define FORMAT_VERSION 1
+#define FORMAT_VERSION 2
+#define FORMAT_VERSION_NOSUM 1
static const char header[] = "Adventure save file\n";
////////////////////////////////////////////////////////////
sf->warned = false;
sf->bintextpos = 0;
sf->key = 0;
- sf->sum = 0;
+ crc_start(&sf->crc);
memset(sf->pad, 0, sizeof(sf->pad));
sf->padpos = 0;
return sf;
for (i=0; i<datalen; i++) {
val = val ^ 0xbadc0ffee;
val = (val << 4) | (val >> 60);
- val += udata[i] ^ 0xbeef;
+ val += udata[i] ^ 0xbeefU;
}
uval = (unsigned char *)&val;
savefile_key(struct savefile *sf, uint32_t key)
{
sf->key = 0;
- sf->sum = 0;
+ crc_start(&sf->crc);
hash(&sf->key, sizeof(sf->key), sf->pad, sizeof(sf->pad));
sf->padpos = 0;
}
}
pos += amt;
}
+ crc_add(&sf->crc, data, len);
return 0;
}
}
pos += amt;
}
+ crc_add(&sf->crc, data, len);
return 0;
}
struct compat_saveinfo {
void *address;
- int width;
+ size_t width;
};
static const struct compat_saveinfo compat_savearray[] =
const struct compat_saveinfo *p;
char *s;
long sum, cksum = 0;
- int i;
+ size_t i;
+ struct crcstate crc;
if ((in = fopen(infile, "rb")) == NULL) {
fprintf(stderr,
}
fclose(in);
- crc_start(); /* See if she cheated */
+ crc_start(&crc); /* See if she cheated */
for (p = compat_savearray; p->address != NULL; p++)
- cksum = crc(p->address, p->width);
+ crc_add(&crc, p->address, p->width);
+ cksum = crc_get(&crc);
if (sum != cksum) /* Tsk tsk */
return 2; /* Altered the file */
/* We successfully restored, so this really was a save file */
uint32_t key, writeable_key;
uint32_t version;
unsigned i, j, n;
- uint32_t val;
+ uint32_t val, sum;
sf = savefile_open(outfile, true);
if (sf == NULL) {
}
#endif
- sf->sum = htonl(sf->sum);
- if (savefile_binwrite(sf, &sf->sum, sizeof(&sf->sum))) {
+ sum = htonl(crc_get(&sf->crc));
+ if (savefile_binwrite(sf, &sum, sizeof(&sum))) {
savefile_close(sf);
return 1;
}
uint32_t version, key, sum;
unsigned i, j, n;
uint32_t val;
+ bool skipsum = false;
sf = savefile_open(infile, false);
if (sf == NULL) {
return 1;
}
version = ntohl(version);
- if (version != FORMAT_VERSION) {
+ switch (version) {
+ case FORMAT_VERSION:
+ break;
+ case FORMAT_VERSION_NOSUM:
+ skipsum = true;
+ break;
+ default:
savefile_close(sf);
fprintf(stderr,
"Oh dear, that file must be from the future. I don't know"
}
sum = ntohl(sum);
/* See if she cheated */
- if (sum != sf->sum) {
+ if (!skipsum && sum != crc_get(&sf->crc)) {
/* Tsk tsk, altered the file */
savefile_close(sf);
return 2;