diff --git a/include/econfig-spec.h b/include/econfig-spec.h index 03d54162..5f0ad91a 100644 --- a/include/econfig-spec.h +++ b/include/econfig-spec.h @@ -73,17 +73,13 @@ EMPCFBOTH((fvname), (vname), int, NSC_INT, KM_OPTION, (descr)) EMPCF_COMMENT("\n### Server configuration and information") EMPCFBOTH("custom_tables", custom_tables, char *, NSC_STRING, KM_INTERNAL, "Custom configuration table files, separated by space") -EMPCFBOTH("data", gamedir, char *, NSC_STRING, KM_INTERNAL, +EMPCFBOTH("data", gamedir_conf, char *, NSC_STRING, KM_INTERNAL, "Directory where this game's data is stored") -EMPCF_COMMENT("# Note: Use an absolute name here, the interpretation of a relative\n" - "# name may change.") -EMPCFBOTH("info", infodir, char *, NSC_STRING, KM_INTERNAL, +EMPCFBOTH("info", infodir_conf, char *, NSC_STRING, KM_INTERNAL, "Directory where info pages are stored, can be shared among games") EMPCF_COMMENT("# Set this to your build tree's info.nr to run the server without\n" - "# installing it.\n" - "# Note: Use an absolute name here, the interpretation of a relative\n" - "# name may change.") -EMPCFBOTH("builtin", builtindir, char *, NSC_STRING, KM_INTERNAL, + "# installing it.") +EMPCFBOTH("builtin", builtindir_conf, char *, NSC_STRING, KM_INTERNAL, "Directory where builtin files are stored") EMPCF_COMMENT("# Set this to your source tree's src/lib/global to run the server\n" "# without installing it, else leave it alone.") diff --git a/include/optlist.h b/include/optlist.h index 2dc68343..083dcd9b 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -45,6 +45,9 @@ extern char dflt_econfig[]; #undef EMP_CONFIG_H_OUTPUT extern char *configdir; +extern char *builtindir; +extern char *gamedir; +extern char *infodir; extern char *schedulefil; extern char motdfil[]; diff --git a/include/prototypes.h b/include/prototypes.h index 24d14f3e..84462efa 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -321,6 +321,8 @@ extern int xundump(FILE *, char *, int *, int); /* * src/lib/gen/ *.c */ +/* fnameat.c */ +extern char *fnameat(const char *, const char *); /* fsize.c */ extern int fsize(int); extern int blksize(int); diff --git a/src/lib/common/emp_config.c b/src/lib/common/emp_config.c index 7997b9a5..17488622 100644 --- a/src/lib/common/emp_config.c +++ b/src/lib/common/emp_config.c @@ -201,8 +201,10 @@ set_paths(char *econfig) } #endif /* !_WIN32 */ - schedulefil = malloc(strlen(configdir) + 10); - sprintf(schedulefil, "%s/schedule", configdir); + infodir = fnameat(infodir_conf, configdir); + gamedir = fnameat(gamedir_conf, configdir); + builtindir = fnameat(builtindir_conf, configdir); + schedulefil = fnameat("schedule", configdir); free(cwd); } diff --git a/src/lib/gen/fnameat.c b/src/lib/gen/fnameat.c new file mode 100644 index 00000000..1f4a942c --- /dev/null +++ b/src/lib/gen/fnameat.c @@ -0,0 +1,73 @@ +/* + * Empire - A multi-player, client/server Internet based war game. + * Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak, + * Ken Stevens, Steve McClure + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * --- + * + * See files README, COPYING and CREDITS in the root of the source + * tree for related information and legal notices. It is expected + * that future projects/authors will amend these files as needed. + * + * --- + * + * fnameat.c: Interpret file names relative to a directory + * + * Known contributors to this file: + * Markus Armbruster, 2008 + */ + +#include + +#include +#include "prototypes.h" + +static int fname_is_abs(const char *); + +/* + * Interpret FNAME relative to directory DIR. + * Return FNAME if it is absolute, or DIR is null or empty. + * Else return a malloc'ed string containing DIR/FNAME, or null + * pointer when that fails. + */ +char * +fnameat(const char *fname, const char *dir) +{ + char *res; + + if (fname_is_abs(fname) || !dir || !*dir) + return (char *)fname; + + res = malloc(strlen(dir) + 1 + strlen(fname) + 1); + if (!res) + return NULL; + + sprintf(res, "%s/%s", dir, fname); + return res; +} + +static int +fname_is_abs(const char *fname) +{ +#ifdef _WIN32 + /* Treat as absolute if it starts with '/', '\\' or a drive */ + return fname[0] == '/' || fname[0] == '\\' + || (fname[0] != 0 && fname[1] == ':'); +#else + return fname[0] == '/'; +#endif +} diff --git a/src/lib/global/path.c.in b/src/lib/global/path.c.in index 5a4fbc3e..47ff1d46 100644 --- a/src/lib/global/path.c.in +++ b/src/lib/global/path.c.in @@ -53,15 +53,19 @@ char *custom_tables = ""; char *schedulefil; /* Where to find built-in configuration tables (relative to configdir) */ +char *builtindir_conf = "@builtindir@"; +/* Where to find built-in configuration tables (absolute) */ char *builtindir = "@builtindir@"; -/* Where to find info pages (relative to gamedir) */ -/* TODO UI wart, make it relative to configdir */ -char *infodir = "@einfodir@"; +/* Where to find info pages (relative to configdir) */ +char *infodir_conf = "@einfodir@"; +/* Where to find info pages (absolute) */ +char *infodir; /* Where this game's data is stored (relative to configdir) */ -/* FIXME relative broken in utility programs */ -char *gamedir = "@gamedir@"; +char *gamedir_conf = "@gamedir@"; +/* Where this game's data is stored (absolute) */ +char *gamedir; /* These are relative to gamedir: */ char teldir[] = "tel";