src/lib/gen/emp_config.c

Go to the documentation of this file.
00001 /*
00002  *  Empire - A multi-player, client/server Internet based war game.
00003  *  Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
00004  *                           Ken Stevens, Steve McClure
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  *  ---
00021  *
00022  *  See files README, COPYING and CREDITS in the root of the source
00023  *  tree for related information and legal notices.  It is expected
00024  *  that future projects/authors will amend these files as needed.
00025  *
00026  *  ---
00027  *
00028  *  emp_config.c: Allows config file to control server config. from a file
00029  * 
00030  *  Known contributors to this file:
00031  *     Julian Onions, 1995
00032  *     Steve McClure, 1998-2000
00033  */
00034 
00035 /*
00036  * STILL TO DO
00037  *
00038  * Change other constants - such as MAXNOC etc.
00039  * Just requires variables to be assigned, then dynamic allocation in
00040  * a few places.  Some checks needed in the server to check the world
00041  * hasn't changed size etc.
00042  */
00043 
00044 #include <config.h>
00045 
00046 #include <assert.h>
00047 #include <ctype.h>
00048 #include <errno.h>
00049 #include <stdio.h>
00050 #include <string.h>
00051 #include <unistd.h>
00052 
00053 #include "file.h"
00054 #include "misc.h"
00055 #include "optlist.h"
00056 #include "prototypes.h"
00057 
00058 /* Dummy one */
00059 static int emp_config_dummy;
00060 
00061 /* things that can be changed */
00062 struct keymatch configkeys[] = {
00063 #define EMP_CONFIG_C_OUTPUT
00064 #include "econfig-spec.h"
00065 #undef  EMP_CONFIG_C_OUTPUT
00066 };
00067 
00068 static struct keymatch *keylookup(char *key, struct keymatch tbl[]);
00069 static void set_paths(char *);
00070 
00071 /*
00072  * read in empire configuration
00073  */
00074 int
00075 emp_config(char *file)
00076 {
00077     FILE *fp;
00078     char scanspace[1024];
00079     char *av[128];
00080     char buf[1024];
00081     struct keymatch *kp;
00082     int lno = 0;
00083     int errors = 0;
00084     int i;
00085 
00086     if (!file)
00087         file = dflt_econfig;
00088     errno = 0;
00089     if ((fp = fopen(file, "r")) == NULL) {
00090         if (file == dflt_econfig && errno == ENOENT)
00091             goto done;
00092         fprintf(stderr, "Can't open %s for reading (%s)\n",
00093                 file, strerror(errno));
00094         return -1;
00095     }
00096 
00097     while (fgets(buf, sizeof(buf), fp) != NULL) {
00098         ++lno;
00099         for (i = 0; buf[i] && isspace(buf[i]); ++i) ;
00100         if (!buf[i] || buf[i] == '#')
00101             continue;
00102         if (parse(buf, scanspace, av, NULL, NULL, NULL) < 0) {
00103             fprintf(stderr, "%s:%d: Can't parse line %s", file, lno, buf);
00104             errors = 1;
00105             continue;
00106         }
00107         if ((kp = keylookup(av[0], configkeys)) == NULL) {
00108             fprintf(stderr, "%s:%d: Unknown config key %s\n",
00109                     file, lno, av[0]);
00110             errors = 1;
00111             continue;
00112         }
00113         if (av[1] == NULL) {
00114             fprintf(stderr, "%s:%d: Config key %s needs a value\n",
00115                     file, lno, av[0]);
00116             errors = 1;
00117             continue;
00118         }
00119         i = 2;
00120         switch (kp->km_type) {
00121         case NSC_INT:
00122             *(int *)kp->km_data = atoi(av[1]);
00123             break;
00124         case NSC_FLOAT:
00125             *(float *)kp->km_data = atof(av[1]);
00126             break;
00127         case NSC_DOUBLE:
00128             *(double *)kp->km_data = atof(av[1]);
00129             break;
00130         case NSC_LONG:
00131             *(long *)kp->km_data = atol(av[1]);
00132             break;
00133         case NSC_STRING:
00134             if (kp->km_flags & KM_ALLOC)
00135                 free(*(char **)kp->km_data);
00136             *(char **)kp->km_data = strdup(av[1]);
00137             kp->km_flags |= KM_ALLOC;
00138             break;
00139         default:
00140             assert(0);
00141         }
00142         if (av[i] != NULL) {
00143             fprintf(stderr, "%s:%d: Junk after value of config key %s\n",
00144                     file, lno, av[0]);
00145             errors = 1;
00146         }
00147     }
00148 
00149     fclose(fp);
00150 
00151 done:
00152     WORLD_X &= ~1;              /* force even */
00153     set_paths(file);
00154 
00155     return -errors;
00156 }
00157 
00158 /* find the key in the table */
00159 static struct keymatch *
00160 keylookup(char *command, struct keymatch *tbl)
00161 {
00162     struct keymatch *kp;
00163 
00164     if (command == 0 || *command == 0)
00165         return 0;
00166     for (kp = tbl; kp->km_key != 0; kp++) {
00167         if (strcmp(kp->km_key, command) == 0)
00168             return kp;
00169     }
00170     return NULL;
00171 }
00172 
00173 static void
00174 set_paths(char *econfig)
00175 {
00176     char *slash;
00177     char *cwd = getcwd(NULL, 0);
00178 
00179 #ifdef _WIN32
00180     /* normalize path separator to '\\', for easier searching: */
00181     econfig = _fullpath(NULL, econfig, 0);
00182     slash = strrchr(econfig, '\\');
00183     configdir = malloc(slash - econfig + 1);
00184     memcpy(configdir, econfig, slash - econfig);
00185     configdir[slash - econfig] = 0;
00186 #else
00187     if ((slash = strrchr(econfig, '/'))) {
00188         configdir = malloc(slash - econfig + 1);
00189         memcpy(configdir, econfig, slash - econfig);
00190         configdir[slash - econfig] = 0;
00191     } else
00192         configdir = strdup(cwd);
00193 
00194     if (configdir[0] != '/') {
00195         char *tmp = configdir;
00196         size_t len = strlen(cwd);
00197 
00198         configdir = malloc(len + 1 + strlen(tmp) + 1);
00199         sprintf(configdir, "%s/%s", cwd, tmp);
00200         free(tmp);
00201     }
00202 #endif /* !_WIN32 */
00203 
00204     schedulefil = malloc(strlen(configdir) + 10);
00205     sprintf(schedulefil, "%s/schedule", configdir);
00206 
00207     free(cwd);
00208 }
00209 
00210 void
00211 print_config(FILE *fp)
00212 {
00213     struct keymatch *kp;
00214 
00215     fprintf(fp, "# Empire Configuration File:\n");
00216     for (kp = configkeys; kp->km_key; kp++) {
00217         if (kp->km_comment) {
00218             if (kp->km_comment[0] != '\n' && kp->km_comment[0] != '#')
00219                 fprintf(fp, "\n# ");
00220             fprintf(fp, "%s\n", kp->km_comment);
00221         }
00222         if (!kp->km_key[0])
00223             continue;
00224         switch (kp->km_type) {
00225         case NSC_STRING:
00226             fprintf(fp, "%s \"%s\"\n", kp->km_key, *(char **)kp->km_data);
00227             break;
00228         case NSC_INT:
00229             fprintf(fp, "%s %d\n", kp->km_key, *(int *)kp->km_data);
00230             break;
00231         case NSC_FLOAT:
00232             fprintf(fp, "%s %g\n", kp->km_key, *(float *)kp->km_data);
00233             break;
00234         case NSC_DOUBLE:
00235             fprintf(fp, "%s %g\n", kp->km_key, *(double *)kp->km_data);
00236             break;
00237         case NSC_LONG:
00238             fprintf(fp, "%s %ld\n", kp->km_key, *(long *)kp->km_data);
00239             break;
00240         default:
00241             assert(0);
00242         }
00243     }
00244 
00245     fprintf(fp, "\n");
00246 }

Generated on Fri Mar 28 11:01:14 2008 for empserver by  doxygen 1.5.2