diff --git a/include/file.h b/include/file.h index 1f405e0f..3a92c5bd 100644 --- a/include/file.h +++ b/include/file.h @@ -41,7 +41,6 @@ struct empfile { char *name; /* Empire name (e.g., "treaty") */ char *file; /* file name (relative to data directory) */ int flags; /* misc stuff */ - int mode; /* O_flags */ int size; /* size of object */ void (*init) (int, char *); /* call this when object is created */ int (*postread) (int, char *); /* specific massage routines for items */ @@ -62,13 +61,19 @@ struct empfile { * group of such a file's record can be safely obtained by * dereferencing its memory address cast to struct genitem *. */ -#define EFF_XY bit(0) /* has location */ -#define EFF_MEM bit(1) /* stored entirely in-memory */ -#define EFF_OWNER bit(2) /* has concept of owner */ -#define EFF_GROUP bit(3) /* has concept of group */ +#define EFF_XY bit(0) +#define EFF_OWNER bit(1) +#define EFF_GROUP bit(2) +/* Table is entirely in memory */ +#define EFF_MEM bit(3) +/* Table is read-only */ +#define EFF_RDONLY bit(4) +/* Create table file, clobbering any existing file */ +#define EFF_CREATE bit(5) +/* Table is allocated statically */ /* Flags that may be passed to ef_open() */ -#define EFF_OPEN EFF_MEM +#define EFF_OPEN (EFF_MEM | EFF_RDONLY | EFF_CREATE) /* * Empire `file types' @@ -129,7 +134,7 @@ extern int ef_read(int, int, void *); extern char *ef_ptr(int, int); extern char *ef_nameof(int); extern time_t ef_mtime(int); -extern int ef_open(int, int, int); +extern int ef_open(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 000be6f3..e86eda4e 100644 --- a/src/lib/common/file.c +++ b/src/lib/common/file.c @@ -50,20 +50,16 @@ static void fillcache(struct empfile *ep, int start); /* * Open the binary file for table TYPE (EF_SECTOR, ...). - * MODE is passed to open(). * HOW are EFF_OPEN flags to control operation. * Return non-zero on success, zero on failure. * You must call ef_close() before the next ef_open(). */ int -ef_open(int type, int mode, int how) +ef_open(int type, int how) { struct empfile *ep; - int size; + int oflags, size; -#if defined(_WIN32) - mode |= O_BINARY; -#endif if (ef_check(type) < 0) return 0; if (CANT_HAPPEN(how & ~EFF_OPEN)) @@ -71,14 +67,21 @@ ef_open(int type, int mode, int how) ep = &empfile[type]; if (CANT_HAPPEN(ep->fd >= 0)) return 0; - if ((ep->fd = open(ep->file, mode, 0660)) < 0) { + oflags = O_RDWR; + if (how & EFF_RDONLY) + oflags = O_RDONLY; + if (how & EFF_CREATE) + oflags |= O_CREAT | O_TRUNC; +#if defined(_WIN32) + oflags |= O_BINARY; +#endif + if ((ep->fd = open(ep->file, oflags, 0660)) < 0) { logerror("%s: open failed", ep->file); return 0; } ep->baseid = 0; ep->cids = 0; - ep->mode = mode; - ep->flags |= how; + ep->flags = (ep->flags & ~EFF_OPEN) | (how ^ ~EFF_CREATE); ep->fids = fsize(ep->fd) / ep->size; if (ep->flags & EFF_MEM) ep->csize = ep->fids; @@ -145,8 +148,14 @@ ef_flush(int type) /* no cache implies never opened */ return 0; } - size = ep->csize * ep->size; - if (ep->mode > 0 && (ep->flags & EFF_MEM)) { + /* + * We don't know which cache entries are dirty. ef_write() writes + * through, but direct updates through ef_ptr() don't. They are + * allowed only with EFF_MEM. Assume the whole cash is dirty + * then. + */ + if (!(ep->flags & EFF_RDONLY) && (ep->flags & EFF_MEM)) { + size = ep->csize * ep->size; if ((r = lseek(ep->fd, 0L, SEEK_SET)) < 0) { logerror("ef_flush: %s cache lseek(%d, 0L, SEEK_SET) -> %d", ep->name, ep->fd, r); @@ -158,7 +167,6 @@ ef_flush(int type) return 0; } } - /*ef_zapcache(type); */ return 1; } @@ -287,7 +295,7 @@ ef_extend(int type, int count) struct empfile *ep; char *tmpobj; int cur, max; - int mode, how; + int how; int r; if (ef_check(type) < 0) @@ -316,10 +324,9 @@ ef_extend(int type, int count) if (ep->flags & EFF_MEM) { /* XXX this will cause problems if there are ef_ptrs (to the * old allocated structure) active when we do the re-open */ - mode = ep->mode; how = ep->flags; ef_close(type); - ef_open(type, mode, how); + ef_open(type, how); } else { ep->fids += count; } diff --git a/src/lib/global/file.c b/src/lib/global/file.c index a9ad7d58..945e6f24 100644 --- a/src/lib/global/file.c +++ b/src/lib/global/file.c @@ -57,103 +57,103 @@ struct empfile empfile[] = { /* Dynamic game data */ {EF_SECTOR, "sect", "sector", EFF_XY | EFF_OWNER, - 0, sizeof(struct sctstr), NULL, NULL, NULL, + sizeof(struct sctstr), NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, sect_ca}, {EF_SHIP, "ship", "ship", EFF_XY | EFF_OWNER | EFF_GROUP, - 0, sizeof(struct shpstr), NULL, NULL, NULL, + sizeof(struct shpstr), NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, ship_ca}, {EF_PLANE, "plane", "plane", EFF_XY | EFF_OWNER | EFF_GROUP, - 0, sizeof(struct plnstr), NULL, NULL, NULL, + sizeof(struct plnstr), NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, plane_ca}, {EF_LAND, "land", "land", EFF_XY | EFF_OWNER | EFF_GROUP, - 0, sizeof(struct lndstr), NULL, NULL, NULL, + sizeof(struct lndstr), NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, land_ca}, {EF_NUKE, "nuke", "nuke", EFF_XY | EFF_OWNER, - 0, sizeof(struct nukstr), NULL, NULL, NULL, + sizeof(struct nukstr), NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, nuke_ca}, {EF_NEWS, "news", "news", 0, - 0, sizeof(struct nwsstr), NULL, NULL, NULL, + sizeof(struct nwsstr), NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, news_ca}, {EF_TREATY, "treaty", "treaty", 0, - 0, sizeof(struct trtstr), NULL, NULL, NULL, + sizeof(struct trtstr), NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, treaty_ca}, {EF_TRADE, "trade", "trade", 0, - 0, sizeof(struct trdstr), NULL, NULL, NULL, + sizeof(struct trdstr), NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, trade_ca}, {EF_POWER, "pow", "power", 0, - 0, sizeof(struct powstr), NULL, NULL, NULL, + sizeof(struct powstr), NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, NULL}, {EF_NATION, "nat", "nation", EFF_OWNER, - 0, sizeof(struct natstr), NULL, NULL, NULL, + sizeof(struct natstr), NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, nat_ca}, {EF_LOAN, "loan", "loan", 0, - 0, sizeof(struct lonstr), NULL, NULL, NULL, + sizeof(struct lonstr), NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, loan_ca}, {EF_MAP, "map", "map", 0, - 0, DEF_WORLD_X * DEF_WORLD_Y / 2, NULL, NULL, NULL, + DEF_WORLD_X * DEF_WORLD_Y / 2, NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, NULL}, {EF_BMAP, "bmap", "bmap", 0, - 0, DEF_WORLD_X * DEF_WORLD_Y / 2, NULL, NULL, NULL, + DEF_WORLD_X * DEF_WORLD_Y / 2, NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, NULL}, {EF_COMM, "commodity", "commodity", 0, - 0, sizeof(struct comstr), NULL, NULL, NULL, + sizeof(struct comstr), NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, commodity_ca}, {EF_LOST, "lost", "lostitems", EFF_OWNER, - 0, sizeof(struct loststr), NULL, NULL, NULL, + sizeof(struct loststr), NULL, NULL, NULL, -1, -1, 0, 0, NULL, 0, lost_ca}, /* Static game data (configuation) */ {EF_SECTOR_CHR, "sect chr", NULL, EFF_MEM, - 0, sizeof(dchr[0]), NULL, NULL, NULL, + sizeof(dchr[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)dchr, 0, dchr_ca}, {EF_SHIP_CHR, "ship chr", NULL, EFF_MEM, - 0, sizeof(mchr[0]), NULL, NULL, NULL, + sizeof(mchr[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)mchr, 0, mchr_ca}, {EF_PLANE_CHR, "plane chr", NULL, EFF_MEM, - 0, sizeof(plchr[0]), NULL, NULL, NULL, + sizeof(plchr[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)plchr, 0, plchr_ca}, {EF_LAND_CHR, "land chr", NULL, EFF_MEM, - 0, sizeof(lchr[0]), NULL, NULL, NULL, + sizeof(lchr[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)lchr, 0, lchr_ca}, {EF_NUKE_CHR, "nuke chr", NULL, EFF_MEM, - 0, sizeof(nchr[0]), NULL, NULL, NULL, + sizeof(nchr[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)nchr, 0, nchr_ca}, #if 0 /* FIXME rpt[] lacks sentinel, xdchr() doesn't terminate */ {EF_, "news chr", NULL, EFF_MEM, - 0, sizeof(rpt[0]), NULL, NULL, NULL, + sizeof(rpt[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)rpt, 0, rpt_ca}, #endif {EF_TREATY_CHR, "treaty chr", NULL, EFF_MEM, - 0, sizeof(tchr[0]), NULL, NULL, NULL, + sizeof(tchr[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)tchr, 0, tchr_ca}, {EF_ITEM, "item", NULL, EFF_MEM, - 0, sizeof(ichr[0]), NULL, NULL, NULL, + sizeof(ichr[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)ichr, 0, ichr_ca}, {EF_INFRASTRUCTURE, "infrastructure", NULL, EFF_MEM, - 0, sizeof(intrchr[0]), NULL, NULL, NULL, + sizeof(intrchr[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)intrchr, 0, intrchr_ca}, {EF_PRODUCT, "product", NULL, EFF_MEM, - 0, sizeof(pchr[0]), NULL, NULL, NULL, + sizeof(pchr[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)pchr, 0, pchr_ca}, {EF_TABLE, "table", NULL, EFF_MEM, - 0, sizeof(empfile[0]), NULL, NULL, NULL, + sizeof(empfile[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)empfile, 0, empfile_ca}, {EF_SHIP_CHR_FLAGS, "ship chr flags", NULL, EFF_MEM, - 0, sizeof(ship_chr_flags[0]), NULL, NULL, NULL, + sizeof(ship_chr_flags[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)ship_chr_flags, 0, lookup_ca}, {EF_PLANE_CHR_FLAGS, "plane chr flags", NULL, EFF_MEM, - 0, sizeof(plane_chr_flags[0]), NULL, NULL, NULL, + sizeof(plane_chr_flags[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)plane_chr_flags, 0, lookup_ca}, {EF_LAND_CHR_FLAGS, "land chr flags", NULL, EFF_MEM, - 0, sizeof(land_chr_flags[0]), NULL, NULL, NULL, + sizeof(land_chr_flags[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)land_chr_flags, 0, lookup_ca}, {EF_NUKE_CHR_FLAGS, "nuke chr flags", NULL, EFF_MEM, - 0, sizeof(nuke_chr_flags[0]), NULL, NULL, NULL, + sizeof(nuke_chr_flags[0]), NULL, NULL, NULL, -1, -1, 0, 0, (char *)nuke_chr_flags, 0, lookup_ca}, /* Sentinel */ {EF_BAD, NULL, NULL, 0, - 0, 0, NULL, NULL, NULL, + 0, NULL, NULL, NULL, -1, -1, 0,0,NULL, 0, NULL} }; diff --git a/src/server/main.c b/src/server/main.c index ffaed471..d1968063 100644 --- a/src/server/main.c +++ b/src/server/main.c @@ -38,7 +38,6 @@ #include #endif #include -#include #include #include @@ -360,21 +359,21 @@ static void init_files(void) { int failed = 0; - failed |= !ef_open(EF_NATION, O_RDWR, EFF_MEM); - failed |= !ef_open(EF_SECTOR, O_RDWR, EFF_MEM); - failed |= !ef_open(EF_SHIP, O_RDWR, EFF_MEM); - failed |= !ef_open(EF_PLANE, O_RDWR, EFF_MEM); - failed |= !ef_open(EF_LAND, O_RDWR, EFF_MEM); - failed |= !ef_open(EF_NEWS, O_RDWR, 0); - failed |= !ef_open(EF_LOAN, O_RDWR, 0); - failed |= !ef_open(EF_TREATY, O_RDWR, 0); - failed |= !ef_open(EF_NUKE, O_RDWR, EFF_MEM); - failed |= !ef_open(EF_POWER, O_RDWR, 0); - failed |= !ef_open(EF_TRADE, O_RDWR, 0); - failed |= !ef_open(EF_MAP, O_RDWR, EFF_MEM); - failed |= !ef_open(EF_BMAP, O_RDWR, EFF_MEM); - failed |= !ef_open(EF_COMM, O_RDWR, 0); - failed |= !ef_open(EF_LOST, O_RDWR, 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_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); if (failed) { logerror("Missing files, giving up"); exit(EXIT_FAILURE); diff --git a/src/util/files.c b/src/util/files.c index 189ef1a7..89c4e05e 100644 --- a/src/util/files.c +++ b/src/util/files.c @@ -123,7 +123,7 @@ main(int argc, char *argv[]) exit(1); } for (i = 0; i < EF_MAX; i++) { - if (!ef_open(i, O_RDWR | O_CREAT | O_TRUNC, 0)) { + if (!ef_open(i, EFF_CREATE)) { perror("ef_open"); exit(1); }