home *** CD-ROM | disk | FTP | other *** search
- /* $XConsortium: config.c,v 1.6 91/07/25 12:15:45 keith Exp $ */
- /*
- * Copyright 1990, 1991 Network Computing Devices;
- * Portions Copyright 1987 by Digital Equipment Corporation and the
- * Massachusetts Institute of Technology
- *
- * Permission to use, copy, modify, and distribute this protoype software
- * and its documentation to Members and Affiliates of the MIT X Consortium
- * any purpose and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the names of Network Computing Devices, Digital or
- * MIT not be used in advertising or publicity pertaining to distribution of
- * the software without specific, written prior permission.
- *
- * NETWORK COMPUTING DEVICES, DIGITAL AND MIT DISCLAIM ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, DIGITAL OR MIT BE
- * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $NCDId: @(#)config.c,v 4.6 1991/07/09 14:08:09 lemke Exp $
- *
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <X11/Xos.h>
- #include "misc.h"
- #include "configstr.h"
- #include "osdep.h"
- #include "globals.h"
- #include "access.h"
-
- static char *font_catalogue = NULL;
-
- static char *config_set_int(),
- *config_set_bool(),
- *config_set_catalogue(),
- *config_set_list(),
- *config_set_file(),
- *config_set_resolutions(),
- *config_set_snf_format();
-
- /* these need to be in lower case and alphabetical order so a
- * binary search lookup can be used
- */
- static ConfigOptionRec config_options[] = {
- {"alternate-servers", config_set_list},
- {"catalogue", config_set_catalogue},
- {"client-limit", config_set_int},
- {"clone-self", config_set_bool},
- {"default-point-size", config_set_int},
- {"default-resolutions", config_set_resolutions},
- {"error-file", config_set_file},
- {"port", config_set_int},
- {"server-number", config_set_int},
- {"snf-format", config_set_snf_format},
- {"trusted-clients", config_set_list},
- {"use-syslog", config_set_bool},
- {(char *) 0, 0},
- };
-
- char *ConfigErrors[] = {
- "",
- "CONFIG: insufficient memory to load configuration file \"%s\"\n",
- "CONFIG: can't open configuration file \"%s\"\n",
- "CONFIG: error reading configuration file \"%s\"\n",
- "CONFIG: bad value \"%s\" for parameter \"%s\"\n",
- "CONFIG: unknown parameter \"%s\"\n",
- "CONFIG: missing '=' after parameter \"%s\"\n",
- "CONFIG: value out of range for parameter \"%s\"\n",
- "CONFIG: syntax error near parameter \"%s\"\n",
- "CONFIG: missing value for parameter \"%s\"\n",
- "CONFIG: extra value for parameter \"%s\"\n",
- };
-
- #define iseol(c) ((c) == '\n' || (c) == '\r' || (c) == '\f')
- #define skip_whitespace(c) while(isspace(*(c)) || *(c) == ',') (c)++;
- #define skip_val(c) while(!isspace(*(c)) && *(c) != ',' && *(c) != '\0')\
- (c) ++;
- #define skip_list_val(c) while(!isspace(*(c)) && *(c) != '\0')\
- (c) ++;
- #define blank_comment(c) while (!iseol(*(c)) && *(c) != '\0') \
- *(c)++= ' ';
-
- static char *
- next_assign(c)
- char *c;
- {
- int nesting = 0;
-
- while (*c != '\0') {
- if (*c == '(')
- nesting++;
- else if (*c == ')')
- nesting--;
- else if (*c == '=' && nesting == 0)
- return c;
- c++;
- }
- return (char *) 0;
- }
-
- static void
- strip_comments(data)
- char *data;
- {
- char *c;
-
- c = data;
- while ((c = index(c, '#')) != NULL) {
- if (c == data || *(c - 1) != '\\') {
- blank_comment(c);
- } else {
- c++;
- }
- }
- }
-
- static ConfigOptionPtr
- match_param_name(name)
- char *name;
- {
- int pos,
- rc,
- low,
- high;
-
- low = 0;
- high = sizeof(config_options) / sizeof(ConfigOptionRec) - 2;
- pos = high >> 1;
-
- while (low <= high) {
- rc = strcmp(name, config_options[pos].parm_name);
- if (rc == 0) {
- return &config_options[pos];
- } else if (rc < 0) {
- high = pos - 1;
- } else {
- low = pos + 1;
- }
- pos = ((high + low) >> 1);
- }
- return 0;
- }
-
- static int
- parse_config(data)
- char *data;
- {
- char *c,
- *val,
- *next_eq,
- *consumed,
- *p;
- char param_name[64];
- Bool equals_missing;
- ConfigOptionPtr param;
-
- c = data;
- skip_whitespace(c);
-
- while (*c != '\0') {
- equals_missing = FALSE;
-
- /* get parm name in lower case */
- p = c;
- while (isalnum(*c) || *c == '-') {
- if (isupper(*c))
- *c = tolower(*c);
- c++;
- }
- bcopy(p, param_name, min(sizeof(param_name), (int) (c - p)));
- param_name[(int) (c - p)] = '\0';
-
- /* check for junk */
- if (!isspace(*c) && *c != '=') {
- ErrorF(ConfigErrors[CONFIG_ERR_SYNTAX], param_name);
- /* eat garbage */
- while (!isspace(*c) && *c != '=' && *c != '\0')
- c++;
- }
- skip_whitespace(c);
- if (*c != '=') {
- ErrorF(ConfigErrors[CONFIG_ERR_NOEQUALS], param_name);
- equals_missing = TRUE;
- } else {
- c++;
- }
-
- skip_whitespace(c);
-
- /* find next assignment to guess where the value ends */
- if ((next_eq = next_assign(c)) != NULL) {
- /* back up over whitespace */
- for (val = next_eq - 1; val >= c &&
- (isspace(*val) || *val == ',');
- val--);
-
- /* back over parm name */
- for (; val >= c && (isalnum(*val) || *val == '-'); val--);
-
- if (val <= c) {
- /* no value, ignore */
- ErrorF(ConfigErrors[CONFIG_ERR_NOVALUE], param_name);
- continue;
- }
- *val = '\0';
- } else if (*c == '\0') {
- /* no value, ignore */
- ErrorF(ConfigErrors[CONFIG_ERR_NOVALUE], param_name);
- continue;
- }
- /* match parm name */
- if (equals_missing) {
- equals_missing = FALSE;
- } else if ((param = match_param_name(param_name)) == NULL) {
- ErrorF(ConfigErrors[CONFIG_ERR_UNKNOWN], param_name);
- } else {
- consumed = (param->set_func) (param, c);
-
- skip_whitespace(consumed);
- if (*consumed != '\0') {
- ErrorF(ConfigErrors[CONFIG_ERR_EXTRAVALUE],
- param_name);
- }
- }
-
- if (next_eq != NULL)
- c = val + 1;
- else /* last setting */
- break;
- }
- return FSSuccess;
- }
-
- /*
- * handles anything that should be set once the file is parsed
- */
- void
- SetConfigValues()
- {
- int err,
- num;
-
- err = SetFontCatalogue(font_catalogue, &num);
- if (err != FSSuccess) {
- FatalError("Element #%d of font path \"%s\" is bad\n",
- num, font_catalogue);
- }
- InitErrors();
- fsfree((char *) font_catalogue);
- font_catalogue = NULL;
- }
-
- int
- ReadConfigFile(filename)
- char *filename;
- {
- FILE *fp;
- int ret;
- int len;
- char *data;
-
- data = (char *) fsalloc(CONFIG_MAX_FILESIZE);
- if (!data) {
- ErrorF(ConfigErrors[CONFIG_ERR_MEMORY], filename);
- return -1;
- }
- if ((fp = fopen(filename, "r")) == NULL) {
- ErrorF(ConfigErrors[CONFIG_ERR_OPEN], filename);
- return -1;
- }
- ret = fread(data, sizeof(char), CONFIG_MAX_FILESIZE, fp);
- if (ret <= 0) {
- ErrorF(ConfigErrors[CONFIG_ERR_READ], filename);
- return -1;
- }
- len = ftell(fp);
- len = min(len, CONFIG_MAX_FILESIZE);
- data[len] = '\0'; /* NULL terminate the data */
-
- (void) fclose(fp);
-
- strip_comments(data);
- ret = parse_config(data);
-
- fsfree(data);
-
- return ret;
- }
-
- struct nameVal {
- char *name;
- int val;
- };
-
- static char *
- config_parse_nameVal (c, ret, pval, name_val)
- char *c;
- int *ret;
- int *pval;
- struct nameVal *name_val;
- {
- char *start,
- t;
- int i,
- len;
-
- start = c;
- skip_val(c);
- t = *c;
- *c = '\0';
- len = c - start;
-
- for (i = 0; name_val[i].name; i++) {
- if (!strncmpnocase(start, name_val[i].name, len)) {
- *pval = name_val[i].val;
- *ret = 0;
- *c = t;
- return c;
- }
- }
- ErrorF(ConfigErrors[CONFIG_ERR_VALUE], start);
- *c = t;
- *ret = -1;
- return c;
- }
-
- static char *
- config_parse_bool (c, ret, pval)
- char *c;
- int *ret;
- Bool *pval;
- {
- static struct nameVal bool_val[] = {
- "yes", TRUE,
- "on", TRUE,
- "1", TRUE,
- "true", TRUE,
- "no", FALSE,
- "off", FALSE,
- "0", FALSE,
- "false", FALSE,
- (char *) 0, 0,
- };
- return config_parse_nameVal (c, ret, pval, bool_val);
- }
-
- static char *
- config_parse_int(c, ret, pval)
- char *c;
- int *ret;
- int *pval;
- {
- char *start,
- t;
-
- start = c;
- while (*c != '\0' && !isspace(*c) && *c != ',') {
- if (!isdigit(*c)) { /* error */
- skip_val(c);
- t = *c;
- *c = '\0';
- ErrorF(ConfigErrors[CONFIG_ERR_VALUE], start);
- *ret = -1;
- *c = t;
- return c;
- }
- c++;
- }
- t = *c;
- *c = '\0';
- *ret = 0;
- *pval = atoi(start);
- *c = t;
- return c;
- }
-
-
- /* config option sets */
- /* these have to know how to do the real work and tweak the proper things */
- static char *
- config_set_int(parm, val)
- ConfigOptionPtr parm;
- char *val;
- {
- int ival,
- ret;
- extern int ListenPort;
- extern void SetDefaultPointSize();
-
- val = config_parse_int(val, &ret, &ival);
- if (ret == -1)
- return val;
-
- /* now do individual attribute checks */
- if (!strcmp(parm->parm_name, "port")) {
- ListenPort = ival;
- } else if (!strcmp(parm->parm_name, "client-limit")) {
- AccessSetConnectionLimit(ival);
- } else if (!strcmp(parm->parm_name, "default-point-size")) {
- SetDefaultPointSize(ival);
- }
- return val;
- }
-
- static char *
- config_set_bool(parm, val)
- ConfigOptionPtr parm;
- char *val;
- {
- int
- ret;
- Bool bval;
- extern int ClientLimit;
- extern Bool UseSyslog,
- CloneSelf;
-
- val = config_parse_bool(val, &ret, &bval);
- if (ret == -1)
- return val;
-
- /* now do individual attribute checks */
- if (!strcmp(parm->parm_name, "use-syslog")) {
- UseSyslog = bval;
- } else if (!strcmp(parm->parm_name, "clone-self")) {
- CloneSelf = bval;
- }
- return val;
- }
-
- static char *
- config_set_file(parm, val)
- ConfigOptionPtr parm;
- char *val;
- {
- extern char ErrorFile[];
- char *start = val,
- t;
-
- skip_val(val);
- t = *val;
- *val = '\0';
- if (!strcmp(parm->parm_name, "error-file")) {
- bcopy(start, ErrorFile, val - start + 1);
- }
- *val = t;
- return val;
- }
-
- static char *
- config_set_catalogue(parm, val)
- ConfigOptionPtr parm;
- char *val;
- {
- char *b;
-
- if (!strcmp(parm->parm_name, "catalogue")) {
- /* stash it for later */
- fsfree((char *) font_catalogue); /* dump any previous one */
- b = font_catalogue = (char *) fsalloc(strlen(val) + 1);
- if (!font_catalogue)
- FatalError("Insufficent memory for font catalogue\n");
- while (*val) { /* remove all the gunk */
- if (!isspace(*val)) {
- *b++ = *val;
- }
- val++;
- }
- *b = '\0';
- }
- return val;
- }
-
- static char *
- config_set_list(parm, val)
- ConfigOptionPtr parm;
- char *val;
- {
- char *start = val,
- t;
-
- skip_list_val(val);
- t = *val;
- *val = '\0';
- if (!strcmp(parm->parm_name, "alternate-servers")) {
- SetAlternateServers(start);
- }
- *val = t;
- return val;
- }
-
- static char *
- config_set_resolutions(parm, val)
- ConfigOptionPtr parm;
- char *val;
- {
- char *start = val,
- t;
- int err;
-
- skip_list_val(val);
- t = *val;
- *val = '\0';
- if (!strcmp(parm->parm_name, "default-resolutions")) {
- err = SetDefaultResolutions(start);
- if (err != FSSuccess) {
- FatalError("Bogus resolution list \"%s\"\n", start);
- }
- }
- *val = t;
- return val;
- }
-
-
- static char *
- config_parse_endian(c, ret, pval)
- char *c;
- int *ret;
- int *pval;
- {
- static struct nameVal endian_val[] = {
- "lsb", LSBFirst,
- "little", LSBFirst,
- "lsbfirst", LSBFirst,
- "msb", MSBFirst,
- "big", MSBFirst,
- "msbfirst", MSBFirst,
- (char *) 0, 0,
- };
- return config_parse_nameVal (c, ret, pval, endian_val);
- }
-
- static char *
- config_set_snf_format (parm, val)
- ConfigOptionPtr parm;
- char *val;
- {
- char *start = val,
- t;
- int err;
- int bit, byte, glyph, scan;
- int ret;
-
- val = config_parse_endian (val, &ret, &bit);
- if (ret == -1)
- return val;
- skip_whitespace (val);
- val = config_parse_endian (val, &ret, &byte);
- if (ret == -1)
- return val;
- skip_whitespace (val);
- val = config_parse_int (val, &ret, &glyph);
- if (ret == -1)
- return val;
- skip_whitespace (val);
- val = config_parse_int (val, &ret, &scan);
- if (ret == -1)
- return val;
- SnfSetFormat (bit, byte, glyph, scan);
- return val;
- }
-