From 5750107b65f7cbcb28b542d8beaffbcd9479fa72 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sat, 17 May 2008 17:00:57 +0200 Subject: [PATCH] Make server check game state file sizes on startup Certain tables have a fixed size depending on configuration: EF_SECTOR has WORLD_SZ() elements, EF_NATION, EF_MAP and EF_BMAP have MAXNOC elements, and EF_REALM has MAXNOC * MAXNOR elements. Bad things happen if the files backing them are shorter. Pass expected size to ef_open(), and make it fail when the actual size differs. --- include/file.h | 2 +- src/lib/common/file.c | 9 ++++++++- src/lib/subs/fileinit.c | 36 +++++++++++++++++++----------------- src/util/empdump.c | 2 +- src/util/files.c | 2 +- 5 files changed, 30 insertions(+), 21 deletions(-) diff --git a/include/file.h b/include/file.h index 795177840..b14d0bc6b 100644 --- a/include/file.h +++ b/include/file.h @@ -181,7 +181,7 @@ extern int ef_read(int, int, void *); extern void *ef_ptr(int, int); extern char *ef_nameof(int); extern time_t ef_mtime(int); -extern int ef_open(int, int); +extern int ef_open(int, int, int); extern int ef_check(int); extern int ef_close(int); extern int ef_flush(int); diff --git a/src/lib/common/file.c b/src/lib/common/file.c index 9586bc4dd..b1032a310 100644 --- a/src/lib/common/file.c +++ b/src/lib/common/file.c @@ -55,11 +55,12 @@ static void do_blank(struct empfile *, void *, int, int); * Open the file-backed table TYPE (EF_SECTOR, ...). * HOW are flags to control operation. Naturally, immutable flags are * not permitted. + * If NELT is non-negative, the table must have that many elements. * Return non-zero on success, zero on failure. * You must call ef_close() before the next ef_open(). */ int -ef_open(int type, int how) +ef_open(int type, int how, int nelt) { struct empfile *ep; struct flock lock; @@ -105,6 +106,12 @@ ef_open(int type, int how) return 0; } ep->fids = fsiz / ep->size; + if (nelt >= 0 && nelt != ep->fids) { + logerror("Can't open %s (got %d records instead of %d)", + ep->file, ep->fids, nelt); + close(fd); + return 0; + } /* allocate cache */ if (ep->flags & EFF_STATIC) { diff --git a/src/lib/subs/fileinit.c b/src/lib/subs/fileinit.c index 4e6fb5351..870dd065c 100644 --- a/src/lib/subs/fileinit.c +++ b/src/lib/subs/fileinit.c @@ -34,6 +34,8 @@ #include #include "file.h" +#include "nat.h" +#include "optlist.h" #include "prototypes.h" struct fileinit { @@ -86,23 +88,23 @@ ef_open_srv(void) { int failed = 0; - failed |= !ef_open(EF_NATION, EFF_MEM); - failed |= !ef_open(EF_SECTOR, EFF_MEM); - failed |= !ef_open(EF_SHIP, EFF_MEM); - failed |= !ef_open(EF_PLANE, EFF_MEM); - failed |= !ef_open(EF_LAND, EFF_MEM); - failed |= !ef_open(EF_GAME, EFF_MEM); - failed |= !ef_open(EF_NEWS, 0); - failed |= !ef_open(EF_LOAN, 0); - failed |= !ef_open(EF_TREATY, 0); - failed |= !ef_open(EF_NUKE, EFF_MEM); - failed |= !ef_open(EF_POWER, 0); - failed |= !ef_open(EF_TRADE, 0); - failed |= !ef_open(EF_MAP, EFF_MEM); - failed |= !ef_open(EF_BMAP, EFF_MEM); - failed |= !ef_open(EF_COMM, 0); - failed |= !ef_open(EF_LOST, 0); - failed |= !ef_open(EF_REALM, EFF_MEM); + failed |= !ef_open(EF_NATION, EFF_MEM, MAXNOC); + failed |= !ef_open(EF_SECTOR, EFF_MEM, WORLD_SZ()); + failed |= !ef_open(EF_SHIP, EFF_MEM, -1); + failed |= !ef_open(EF_PLANE, EFF_MEM, -1); + failed |= !ef_open(EF_LAND, EFF_MEM, -1); + failed |= !ef_open(EF_GAME, EFF_MEM, 1); + failed |= !ef_open(EF_NEWS, 0, -1); + failed |= !ef_open(EF_LOAN, 0, -1); + failed |= !ef_open(EF_TREATY, 0, -1); + failed |= !ef_open(EF_NUKE, EFF_MEM, -1); + failed |= !ef_open(EF_POWER, 0, -1); + failed |= !ef_open(EF_TRADE, 0, -1); + failed |= !ef_open(EF_MAP, EFF_MEM, MAXNOC); + failed |= !ef_open(EF_BMAP, EFF_MEM, MAXNOC); + failed |= !ef_open(EF_COMM, 0, -1); + failed |= !ef_open(EF_LOST, 0, -1); + failed |= !ef_open(EF_REALM, EFF_MEM, MAXNOC * MAXNOR); if (!failed) failed |= ef_init_view(EF_COUNTRY, EF_NATION); if (failed) { diff --git a/src/util/empdump.c b/src/util/empdump.c index 9497d01ad..3b14a7bd3 100644 --- a/src/util/empdump.c +++ b/src/util/empdump.c @@ -136,7 +136,7 @@ main(int argc, char *argv[]) for (i = 0; i < EF_MAX; i++) { if (!EF_IS_GAME_STATE(i)) continue; - if (!ef_open(i, EFF_MEM | private)) + if (!ef_open(i, EFF_MEM | private, -1)) exit(1); } diff --git a/src/util/files.c b/src/util/files.c index 4618ba6ef..4151e20d3 100644 --- a/src/util/files.c +++ b/src/util/files.c @@ -131,7 +131,7 @@ main(int argc, char *argv[]) for (i = 0; i < EF_MAX; i++) { if (!EF_IS_GAME_STATE(i)) continue; - if (!ef_open(i, EFF_CREATE)) { + if (!ef_open(i, EFF_CREATE, -1)) { perror("ef_open"); exit(1); } -- 2.43.0