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.
This commit is contained in:
parent
b37ebbbde3
commit
5750107b65
5 changed files with 30 additions and 21 deletions
|
@ -181,7 +181,7 @@ extern int ef_read(int, int, void *);
|
||||||
extern void *ef_ptr(int, int);
|
extern void *ef_ptr(int, int);
|
||||||
extern char *ef_nameof(int);
|
extern char *ef_nameof(int);
|
||||||
extern time_t ef_mtime(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_check(int);
|
||||||
extern int ef_close(int);
|
extern int ef_close(int);
|
||||||
extern int ef_flush(int);
|
extern int ef_flush(int);
|
||||||
|
|
|
@ -55,11 +55,12 @@ static void do_blank(struct empfile *, void *, int, int);
|
||||||
* Open the file-backed table TYPE (EF_SECTOR, ...).
|
* Open the file-backed table TYPE (EF_SECTOR, ...).
|
||||||
* HOW are flags to control operation. Naturally, immutable flags are
|
* HOW are flags to control operation. Naturally, immutable flags are
|
||||||
* not permitted.
|
* not permitted.
|
||||||
|
* If NELT is non-negative, the table must have that many elements.
|
||||||
* Return non-zero on success, zero on failure.
|
* Return non-zero on success, zero on failure.
|
||||||
* You must call ef_close() before the next ef_open().
|
* You must call ef_close() before the next ef_open().
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ef_open(int type, int how)
|
ef_open(int type, int how, int nelt)
|
||||||
{
|
{
|
||||||
struct empfile *ep;
|
struct empfile *ep;
|
||||||
struct flock lock;
|
struct flock lock;
|
||||||
|
@ -105,6 +106,12 @@ ef_open(int type, int how)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ep->fids = fsiz / ep->size;
|
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 */
|
/* allocate cache */
|
||||||
if (ep->flags & EFF_STATIC) {
|
if (ep->flags & EFF_STATIC) {
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
#include "nat.h"
|
||||||
|
#include "optlist.h"
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
|
|
||||||
struct fileinit {
|
struct fileinit {
|
||||||
|
@ -86,23 +88,23 @@ ef_open_srv(void)
|
||||||
{
|
{
|
||||||
int failed = 0;
|
int failed = 0;
|
||||||
|
|
||||||
failed |= !ef_open(EF_NATION, EFF_MEM);
|
failed |= !ef_open(EF_NATION, EFF_MEM, MAXNOC);
|
||||||
failed |= !ef_open(EF_SECTOR, EFF_MEM);
|
failed |= !ef_open(EF_SECTOR, EFF_MEM, WORLD_SZ());
|
||||||
failed |= !ef_open(EF_SHIP, EFF_MEM);
|
failed |= !ef_open(EF_SHIP, EFF_MEM, -1);
|
||||||
failed |= !ef_open(EF_PLANE, EFF_MEM);
|
failed |= !ef_open(EF_PLANE, EFF_MEM, -1);
|
||||||
failed |= !ef_open(EF_LAND, EFF_MEM);
|
failed |= !ef_open(EF_LAND, EFF_MEM, -1);
|
||||||
failed |= !ef_open(EF_GAME, EFF_MEM);
|
failed |= !ef_open(EF_GAME, EFF_MEM, 1);
|
||||||
failed |= !ef_open(EF_NEWS, 0);
|
failed |= !ef_open(EF_NEWS, 0, -1);
|
||||||
failed |= !ef_open(EF_LOAN, 0);
|
failed |= !ef_open(EF_LOAN, 0, -1);
|
||||||
failed |= !ef_open(EF_TREATY, 0);
|
failed |= !ef_open(EF_TREATY, 0, -1);
|
||||||
failed |= !ef_open(EF_NUKE, EFF_MEM);
|
failed |= !ef_open(EF_NUKE, EFF_MEM, -1);
|
||||||
failed |= !ef_open(EF_POWER, 0);
|
failed |= !ef_open(EF_POWER, 0, -1);
|
||||||
failed |= !ef_open(EF_TRADE, 0);
|
failed |= !ef_open(EF_TRADE, 0, -1);
|
||||||
failed |= !ef_open(EF_MAP, EFF_MEM);
|
failed |= !ef_open(EF_MAP, EFF_MEM, MAXNOC);
|
||||||
failed |= !ef_open(EF_BMAP, EFF_MEM);
|
failed |= !ef_open(EF_BMAP, EFF_MEM, MAXNOC);
|
||||||
failed |= !ef_open(EF_COMM, 0);
|
failed |= !ef_open(EF_COMM, 0, -1);
|
||||||
failed |= !ef_open(EF_LOST, 0);
|
failed |= !ef_open(EF_LOST, 0, -1);
|
||||||
failed |= !ef_open(EF_REALM, EFF_MEM);
|
failed |= !ef_open(EF_REALM, EFF_MEM, MAXNOC * MAXNOR);
|
||||||
if (!failed)
|
if (!failed)
|
||||||
failed |= ef_init_view(EF_COUNTRY, EF_NATION);
|
failed |= ef_init_view(EF_COUNTRY, EF_NATION);
|
||||||
if (failed) {
|
if (failed) {
|
||||||
|
|
|
@ -136,7 +136,7 @@ main(int argc, char *argv[])
|
||||||
for (i = 0; i < EF_MAX; i++) {
|
for (i = 0; i < EF_MAX; i++) {
|
||||||
if (!EF_IS_GAME_STATE(i))
|
if (!EF_IS_GAME_STATE(i))
|
||||||
continue;
|
continue;
|
||||||
if (!ef_open(i, EFF_MEM | private))
|
if (!ef_open(i, EFF_MEM | private, -1))
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ main(int argc, char *argv[])
|
||||||
for (i = 0; i < EF_MAX; i++) {
|
for (i = 0; i < EF_MAX; i++) {
|
||||||
if (!EF_IS_GAME_STATE(i))
|
if (!EF_IS_GAME_STATE(i))
|
||||||
continue;
|
continue;
|
||||||
if (!ef_open(i, EFF_CREATE)) {
|
if (!ef_open(i, EFF_CREATE, -1)) {
|
||||||
perror("ef_open");
|
perror("ef_open");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue