config.c revision bbe1b32b
1bbe1b32bSmrg/* $Xorg: config.c,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */
2bbe1b32bSmrg/*
3bbe1b32bSmrgCopyright 1987, 1998  The Open Group
4bbe1b32bSmrg
5bbe1b32bSmrgPermission to use, copy, modify, distribute, and sell this software and its
6bbe1b32bSmrgdocumentation for any purpose is hereby granted without fee, provided that
7bbe1b32bSmrgthe above copyright notice appear in all copies and that both that
8bbe1b32bSmrgcopyright notice and this permission notice appear in supporting
9bbe1b32bSmrgdocumentation.
10bbe1b32bSmrg
11bbe1b32bSmrgThe above copyright notice and this permission notice shall be included in
12bbe1b32bSmrgall copies or substantial portions of the Software.
13bbe1b32bSmrg
14bbe1b32bSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15bbe1b32bSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16bbe1b32bSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17bbe1b32bSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18bbe1b32bSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19bbe1b32bSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20bbe1b32bSmrg
21bbe1b32bSmrgExcept as contained in this notice, the name of The Open Group shall not be
22bbe1b32bSmrgused in advertising or otherwise to promote the sale, use or other dealings
23bbe1b32bSmrgin this Software without prior written authorization from The Open Group.
24bbe1b32bSmrg * Copyright 1990, 1991 Network Computing Devices;
25bbe1b32bSmrg * Portions Copyright 1987 by Digital Equipment Corporation
26bbe1b32bSmrg *
27bbe1b32bSmrg * Permission to use, copy, modify, distribute, and sell this software and its
28bbe1b32bSmrg * documentation for any purpose is hereby granted without fee, provided that
29bbe1b32bSmrg * the above copyright notice appear in all copies and that both that
30bbe1b32bSmrg * copyright notice and this permission notice appear in supporting
31bbe1b32bSmrg * documentation, and that the names of Network Computing Devices,
32bbe1b32bSmrg * or Digital not be used in advertising or
33bbe1b32bSmrg * publicity pertaining to distribution of the software without specific,
34bbe1b32bSmrg * written prior permission.  Network Computing Devices, or Digital
35bbe1b32bSmrg * make no representations about the
36bbe1b32bSmrg * suitability of this software for any purpose.  It is provided "as is"
37bbe1b32bSmrg * without express or implied warranty.
38bbe1b32bSmrg *
39bbe1b32bSmrg * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
40bbe1b32bSmrg * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
41bbe1b32bSmrg * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE
42bbe1b32bSmrg * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
43bbe1b32bSmrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
44bbe1b32bSmrg * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
45bbe1b32bSmrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
46bbe1b32bSmrg *
47bbe1b32bSmrg * $NCDXorg: @(#)config.c,v 4.6 1991/07/09 14:08:09 lemke Exp $
48bbe1b32bSmrg *
49bbe1b32bSmrg */
50bbe1b32bSmrg/* $XFree86: xc/programs/xfs/os/config.c,v 3.15 2002/05/31 18:46:12 dawes Exp $ */
51bbe1b32bSmrg
52bbe1b32bSmrg#include	<xfs-config.h>
53bbe1b32bSmrg
54bbe1b32bSmrg#include	<stdio.h>
55bbe1b32bSmrg#include	<stdlib.h>
56bbe1b32bSmrg#include	<ctype.h>
57bbe1b32bSmrg#include	<X11/Xtrans/Xtrans.h>
58bbe1b32bSmrg#include	<X11/Xos.h>
59bbe1b32bSmrg#include	"misc.h"
60bbe1b32bSmrg#include	"configstr.h"
61bbe1b32bSmrg#include	"osdep.h"
62bbe1b32bSmrg#include	"globals.h"
63bbe1b32bSmrg#include	"access.h"
64bbe1b32bSmrg#include	"difsutils.h"
65bbe1b32bSmrg#ifdef FONTCACHE
66bbe1b32bSmrg#include	<X11/extensions/fontcacheP.h>
67bbe1b32bSmrg#endif
68bbe1b32bSmrg#include	<X11/fonts/fontutil.h>
69bbe1b32bSmrg#include	"difs.h"
70bbe1b32bSmrg
71bbe1b32bSmrgstatic const char * const default_config_files[] = {
72bbe1b32bSmrg#ifdef DEFAULT_CONFIG_FILE
73bbe1b32bSmrg    DEFAULT_CONFIG_FILE,
74bbe1b32bSmrg#else
75bbe1b32bSmrg    "/usr/lib/X11/fs/config",
76bbe1b32bSmrg#endif
77bbe1b32bSmrg    NULL
78bbe1b32bSmrg};
79bbe1b32bSmrg
80bbe1b32bSmrgextern int portFromCmdline;
81bbe1b32bSmrg
82bbe1b32bSmrgstatic char *font_catalogue = NULL;
83bbe1b32bSmrg
84bbe1b32bSmrgstatic char *config_set_int(ConfigOptionPtr parm, char *val);
85bbe1b32bSmrgstatic char *config_set_bool(ConfigOptionPtr parm, char *val);
86bbe1b32bSmrgstatic char *config_set_catalogue(ConfigOptionPtr parm, char *val);
87bbe1b32bSmrgstatic char *config_set_glyph_caching_mode(ConfigOptionPtr parm, char *val);
88bbe1b32bSmrgstatic char *config_set_list(ConfigOptionPtr parm, char *val);
89bbe1b32bSmrgstatic char *config_set_file(ConfigOptionPtr parm, char *val);
90bbe1b32bSmrgstatic char *config_set_resolutions(ConfigOptionPtr parm, char *val);
91bbe1b32bSmrgstatic char *config_set_ignored_transports(ConfigOptionPtr parm, char *val);
92bbe1b32bSmrgstatic char *config_set_snf_format(ConfigOptionPtr parm, char *val);
93bbe1b32bSmrg
94bbe1b32bSmrg/* these need to be in lower case and alphabetical order so a
95bbe1b32bSmrg * binary search lookup can be used
96bbe1b32bSmrg */
97bbe1b32bSmrgstatic ConfigOptionRec config_options[] = {
98bbe1b32bSmrg    {"alternate-servers", config_set_list},
99bbe1b32bSmrg#ifdef FONTCACHE
100bbe1b32bSmrg    {"cache-balance", config_set_int},
101bbe1b32bSmrg    {"cache-hi-mark", config_set_int},
102bbe1b32bSmrg    {"cache-low-mark", config_set_int},
103bbe1b32bSmrg#endif
104bbe1b32bSmrg    {"catalogue", config_set_catalogue},
105bbe1b32bSmrg    {"client-limit", config_set_int},
106bbe1b32bSmrg    {"clone-self", config_set_bool},
107bbe1b32bSmrg    {"default-point-size", config_set_int},
108bbe1b32bSmrg    {"default-resolutions", config_set_resolutions},
109bbe1b32bSmrg    {"deferglyphs", config_set_glyph_caching_mode},
110bbe1b32bSmrg    {"error-file", config_set_file},
111bbe1b32bSmrg    {"no-listen", config_set_ignored_transports},
112bbe1b32bSmrg    {"port", config_set_int},
113bbe1b32bSmrg    {"server-number", config_set_int},
114bbe1b32bSmrg    {"snf-format", config_set_snf_format},
115bbe1b32bSmrg    {"trusted-clients", config_set_list},
116bbe1b32bSmrg    {"use-syslog", config_set_bool},
117bbe1b32bSmrg    {(char *) 0, 0},
118bbe1b32bSmrg};
119bbe1b32bSmrg
120bbe1b32bSmrgchar       *ConfigErrors[] = {
121bbe1b32bSmrg    "",
122bbe1b32bSmrg    "CONFIG: insufficient memory to load configuration file \"%s\"\n",
123bbe1b32bSmrg    "CONFIG: can't open configuration file \"%s\"\n",
124bbe1b32bSmrg    "CONFIG: error reading configuration file \"%s\"\n",
125bbe1b32bSmrg    "CONFIG: bad value \"%s\" for parameter \"%s\"\n",
126bbe1b32bSmrg    "CONFIG: unknown parameter \"%s\"\n",
127bbe1b32bSmrg    "CONFIG: missing '=' after parameter \"%s\"\n",
128bbe1b32bSmrg    "CONFIG: value out of range for parameter \"%s\"\n",
129bbe1b32bSmrg    "CONFIG: syntax error near parameter \"%s\"\n",
130bbe1b32bSmrg    "CONFIG: missing value for parameter \"%s\"\n",
131bbe1b32bSmrg    "CONFIG: extra value for parameter \"%s\"\n",
132bbe1b32bSmrg};
133bbe1b32bSmrg
134bbe1b32bSmrg#define	iseol(c)	((c) == '\n' || (c) == '\r' || (c) == '\f')
135bbe1b32bSmrg#define	skip_whitespace(c)	while(isspace(*(c)) || *(c) == ',') (c)++;
136bbe1b32bSmrg#define	skip_val(c)	while(!isspace(*(c)) && *(c) != ',' && *(c) != '\0')\
137bbe1b32bSmrg						(c) ++;
138bbe1b32bSmrg#define	skip_list_val(c)	while(!isspace(*(c)) && *(c) != '\0')\
139bbe1b32bSmrg						(c) ++;
140bbe1b32bSmrg#define	blank_comment(c)	while (!iseol(*(c)) && *(c) != '\0')	\
141bbe1b32bSmrg						*(c)++= ' ';
142bbe1b32bSmrg
143bbe1b32bSmrgstatic char *
144bbe1b32bSmrgnext_assign(char *c)
145bbe1b32bSmrg{
146bbe1b32bSmrg    int         nesting = 0;
147bbe1b32bSmrg
148bbe1b32bSmrg    while (*c != '\0') {
149bbe1b32bSmrg	if (*c == '(')
150bbe1b32bSmrg	    nesting++;
151bbe1b32bSmrg	else if (*c == ')')
152bbe1b32bSmrg	    nesting--;
153bbe1b32bSmrg	else if (*c == '=' && nesting == 0)
154bbe1b32bSmrg	    return c;
155bbe1b32bSmrg	c++;
156bbe1b32bSmrg    }
157bbe1b32bSmrg    return (char *) 0;
158bbe1b32bSmrg}
159bbe1b32bSmrg
160bbe1b32bSmrgstatic void
161bbe1b32bSmrgstrip_comments(char *data)
162bbe1b32bSmrg{
163bbe1b32bSmrg    char       *c;
164bbe1b32bSmrg
165bbe1b32bSmrg    c = data;
166bbe1b32bSmrg    while ((c = strchr(c, '#')) != NULL) {
167bbe1b32bSmrg	if (c == data || *(c - 1) != '\\') {
168bbe1b32bSmrg	    blank_comment(c);
169bbe1b32bSmrg	} else {
170bbe1b32bSmrg	    c++;
171bbe1b32bSmrg	}
172bbe1b32bSmrg    }
173bbe1b32bSmrg}
174bbe1b32bSmrg
175bbe1b32bSmrgstatic ConfigOptionPtr
176bbe1b32bSmrgmatch_param_name(char *name)
177bbe1b32bSmrg{
178bbe1b32bSmrg    int         pos,
179bbe1b32bSmrg                rc,
180bbe1b32bSmrg                low,
181bbe1b32bSmrg                high;
182bbe1b32bSmrg
183bbe1b32bSmrg    low = 0;
184bbe1b32bSmrg    high = sizeof(config_options) / sizeof(ConfigOptionRec) - 2;
185bbe1b32bSmrg    pos = high >> 1;
186bbe1b32bSmrg
187bbe1b32bSmrg    while (low <= high) {
188bbe1b32bSmrg	rc = strcmp(name, config_options[pos].parm_name);
189bbe1b32bSmrg	if (rc == 0) {
190bbe1b32bSmrg	    return &config_options[pos];
191bbe1b32bSmrg	} else if (rc < 0) {
192bbe1b32bSmrg	    high = pos - 1;
193bbe1b32bSmrg	} else {
194bbe1b32bSmrg	    low = pos + 1;
195bbe1b32bSmrg	}
196bbe1b32bSmrg	pos = ((high + low) >> 1);
197bbe1b32bSmrg    }
198bbe1b32bSmrg    return 0;
199bbe1b32bSmrg}
200bbe1b32bSmrg
201bbe1b32bSmrgstatic int
202bbe1b32bSmrgparse_config(char *data)
203bbe1b32bSmrg{
204bbe1b32bSmrg    char       *c,
205bbe1b32bSmrg               *val = NULL,
206bbe1b32bSmrg               *next_eq,
207bbe1b32bSmrg               *consumed,
208bbe1b32bSmrg               *p;
209bbe1b32bSmrg    char        param_name[64];
210bbe1b32bSmrg    Bool        equals_missing;
211bbe1b32bSmrg    ConfigOptionPtr param;
212bbe1b32bSmrg
213bbe1b32bSmrg    c = data;
214bbe1b32bSmrg    skip_whitespace(c);
215bbe1b32bSmrg
216bbe1b32bSmrg    while (*c != '\0') {
217bbe1b32bSmrg	equals_missing = FALSE;
218bbe1b32bSmrg
219bbe1b32bSmrg	/* get parm name in lower case */
220bbe1b32bSmrg	p = c;
221bbe1b32bSmrg	while (isalnum(*c) || *c == '-') {
222bbe1b32bSmrg	    if (isupper(*c))
223bbe1b32bSmrg		*c = tolower(*c);
224bbe1b32bSmrg	    c++;
225bbe1b32bSmrg	}
226bbe1b32bSmrg	memmove( param_name, p, min(sizeof(param_name), (int) (c - p)));
227bbe1b32bSmrg	param_name[(int) (c - p)] = '\0';
228bbe1b32bSmrg
229bbe1b32bSmrg	/* check for junk */
230bbe1b32bSmrg	if (!isspace(*c) && *c != '=') {
231bbe1b32bSmrg	    ErrorF(ConfigErrors[CONFIG_ERR_SYNTAX], param_name);
232bbe1b32bSmrg	    /* eat garbage */
233bbe1b32bSmrg	    while (!isspace(*c) && *c != '=' && *c != '\0')
234bbe1b32bSmrg		c++;
235bbe1b32bSmrg	}
236bbe1b32bSmrg	skip_whitespace(c);
237bbe1b32bSmrg	if (*c != '=') {
238bbe1b32bSmrg	    ErrorF(ConfigErrors[CONFIG_ERR_NOEQUALS], param_name);
239bbe1b32bSmrg	    equals_missing = TRUE;
240bbe1b32bSmrg	} else {
241bbe1b32bSmrg	    c++;
242bbe1b32bSmrg	}
243bbe1b32bSmrg
244bbe1b32bSmrg	skip_whitespace(c);
245bbe1b32bSmrg
246bbe1b32bSmrg	/* find next assignment to guess where the value ends */
247bbe1b32bSmrg	if ((next_eq = next_assign(c)) != NULL) {
248bbe1b32bSmrg	    /* back up over whitespace */
249bbe1b32bSmrg	    for (val = next_eq - 1; val >= c &&
250bbe1b32bSmrg		    (isspace(*val) || *val == ',');
251bbe1b32bSmrg		    val--);
252bbe1b32bSmrg
253bbe1b32bSmrg	    /* back over parm name */
254bbe1b32bSmrg	    for (; val >= c && (isalnum(*val) || *val == '-'); val--);
255bbe1b32bSmrg
256bbe1b32bSmrg	    if (val <= c) {
257bbe1b32bSmrg		/* no value, ignore */
258bbe1b32bSmrg		ErrorF(ConfigErrors[CONFIG_ERR_NOVALUE], param_name);
259bbe1b32bSmrg		continue;
260bbe1b32bSmrg	    }
261bbe1b32bSmrg	    *val = '\0';
262bbe1b32bSmrg	} else if (*c == '\0') {
263bbe1b32bSmrg	    /* no value, ignore */
264bbe1b32bSmrg	    ErrorF(ConfigErrors[CONFIG_ERR_NOVALUE], param_name);
265bbe1b32bSmrg	    continue;
266bbe1b32bSmrg	}
267bbe1b32bSmrg	/* match parm name */
268bbe1b32bSmrg	if (equals_missing) {
269bbe1b32bSmrg	    equals_missing = FALSE;
270bbe1b32bSmrg	} else if ((param = match_param_name(param_name)) == NULL) {
271bbe1b32bSmrg	    ErrorF(ConfigErrors[CONFIG_ERR_UNKNOWN], param_name);
272bbe1b32bSmrg	} else {
273bbe1b32bSmrg	    consumed = (param->set_func) (param, c);
274bbe1b32bSmrg
275bbe1b32bSmrg	    skip_whitespace(consumed);
276bbe1b32bSmrg	    if (*consumed != '\0') {
277bbe1b32bSmrg		ErrorF(ConfigErrors[CONFIG_ERR_EXTRAVALUE],
278bbe1b32bSmrg		       param_name);
279bbe1b32bSmrg	    }
280bbe1b32bSmrg	}
281bbe1b32bSmrg
282bbe1b32bSmrg	if (next_eq != NULL)
283bbe1b32bSmrg	    c = val + 1;
284bbe1b32bSmrg	else			/* last setting */
285bbe1b32bSmrg	    break;
286bbe1b32bSmrg    }
287bbe1b32bSmrg    return FSSuccess;
288bbe1b32bSmrg}
289bbe1b32bSmrg
290bbe1b32bSmrg/*
291bbe1b32bSmrg * handles anything that should be set once the file is parsed
292bbe1b32bSmrg */
293bbe1b32bSmrgvoid
294bbe1b32bSmrgSetConfigValues(void)
295bbe1b32bSmrg{
296bbe1b32bSmrg    int         err,
297bbe1b32bSmrg                num;
298bbe1b32bSmrg
299bbe1b32bSmrg    if (font_catalogue == NULL) {
300bbe1b32bSmrg	FatalError("font catalogue is missing/empty\n");
301bbe1b32bSmrg    }
302bbe1b32bSmrg
303bbe1b32bSmrg    err = SetFontCatalogue(font_catalogue, &num);
304bbe1b32bSmrg    if (err != FSSuccess) {
305bbe1b32bSmrg	FatalError("element #%d (starting at 0) of font path is bad or has a bad font:\n\"%s\"\n",
306bbe1b32bSmrg		   num, font_catalogue);
307bbe1b32bSmrg    }
308bbe1b32bSmrg    InitErrors();
309bbe1b32bSmrg    fsfree((char *) font_catalogue);
310bbe1b32bSmrg    font_catalogue = NULL;
311bbe1b32bSmrg}
312bbe1b32bSmrg
313bbe1b32bSmrg#ifdef __UNIXOS2__
314bbe1b32bSmrgchar *__XFSRedirRoot(char *fname)
315bbe1b32bSmrg{
316bbe1b32bSmrg    static char redirname[300]; /* enough for long filenames */
317bbe1b32bSmrg    char *root;
318bbe1b32bSmrg
319bbe1b32bSmrg    /* if name does not start with /, assume it is not root-based */
320bbe1b32bSmrg    if (fname==0 || !(fname[0]=='/' || fname[0]=='\\'))
321bbe1b32bSmrg	return fname;
322bbe1b32bSmrg
323bbe1b32bSmrg    root = (char*)getenv("X11ROOT");
324bbe1b32bSmrg    if (root==0 ||
325bbe1b32bSmrg	(fname[1]==':' && isalpha(fname[0])) ||
326bbe1b32bSmrg	((strlen(fname)+strlen(root)+2) > 300))
327bbe1b32bSmrg	return fname;
328bbe1b32bSmrg    sprintf(redirname,"%s%s",root,fname);
329bbe1b32bSmrg    return redirname;
330bbe1b32bSmrg}
331bbe1b32bSmrg#endif
332bbe1b32bSmrg
333bbe1b32bSmrg/* If argument is NULL, uses first file found from default_config_files */
334bbe1b32bSmrgint
335bbe1b32bSmrgReadConfigFile(const char *filename)
336bbe1b32bSmrg{
337bbe1b32bSmrg    FILE       *fp;
338bbe1b32bSmrg    int         ret;
339bbe1b32bSmrg    int         len;
340bbe1b32bSmrg    int         i;
341bbe1b32bSmrg    char       *data;
342bbe1b32bSmrg
343bbe1b32bSmrg    data = (char *) fsalloc(CONFIG_MAX_FILESIZE);
344bbe1b32bSmrg    if (!data) {
345bbe1b32bSmrg	ErrorF(ConfigErrors[CONFIG_ERR_MEMORY], filename);
346bbe1b32bSmrg	return FSBadAlloc;
347bbe1b32bSmrg    }
348bbe1b32bSmrg    if (filename != NULL) {
349bbe1b32bSmrg#ifdef __UNIXOS2__
350bbe1b32bSmrg	filename = __XFSRedirRoot(filename);
351bbe1b32bSmrg#endif
352bbe1b32bSmrg	fp = fopen(filename, "r");
353bbe1b32bSmrg	if (fp == NULL) {
354bbe1b32bSmrg	    ErrorF(ConfigErrors[CONFIG_ERR_OPEN], filename);
355bbe1b32bSmrg	}
356bbe1b32bSmrg    } else {
357bbe1b32bSmrg	for (i = 0; default_config_files[i] != NULL; i++) {
358bbe1b32bSmrg	    filename = default_config_files[i];
359bbe1b32bSmrg#ifdef __UNIXOS2__
360bbe1b32bSmrg	    filename = __XFSRedirRoot(filename);
361bbe1b32bSmrg#endif
362bbe1b32bSmrg	    if ((fp = fopen(filename, "r")) != NULL)
363bbe1b32bSmrg		break;
364bbe1b32bSmrg	}
365bbe1b32bSmrg	if (fp == NULL) {
366bbe1b32bSmrg	    for (i = 0; default_config_files[i] != NULL; i++) {
367bbe1b32bSmrg		ErrorF(ConfigErrors[CONFIG_ERR_OPEN], default_config_files[i]);
368bbe1b32bSmrg	    }
369bbe1b32bSmrg	}
370bbe1b32bSmrg    }
371bbe1b32bSmrg    if (fp == NULL) {
372bbe1b32bSmrg	fsfree(data);
373bbe1b32bSmrg	return FSBadName;
374bbe1b32bSmrg    }
375bbe1b32bSmrg    ret = fread(data, sizeof(char), CONFIG_MAX_FILESIZE, fp);
376bbe1b32bSmrg    if (ret <= 0) {
377bbe1b32bSmrg	fsfree(data);
378bbe1b32bSmrg	(void) fclose(fp);
379bbe1b32bSmrg	ErrorF(ConfigErrors[CONFIG_ERR_READ], filename);
380bbe1b32bSmrg	return FSBadName;
381bbe1b32bSmrg    }
382bbe1b32bSmrg    len = ftell(fp);
383bbe1b32bSmrg    len = min(len, CONFIG_MAX_FILESIZE);
384bbe1b32bSmrg    data[len] = '\0';		/* NULL terminate the data */
385bbe1b32bSmrg
386bbe1b32bSmrg    (void) fclose(fp);
387bbe1b32bSmrg
388bbe1b32bSmrg    strip_comments(data);
389bbe1b32bSmrg    ret = parse_config(data);
390bbe1b32bSmrg
391bbe1b32bSmrg    fsfree(data);
392bbe1b32bSmrg
393bbe1b32bSmrg    return ret;
394bbe1b32bSmrg}
395bbe1b32bSmrg
396bbe1b32bSmrgstruct nameVal {
397bbe1b32bSmrg    char       *name;
398bbe1b32bSmrg    int         val;
399bbe1b32bSmrg};
400bbe1b32bSmrg
401bbe1b32bSmrgstatic char *
402bbe1b32bSmrgconfig_parse_nameVal (
403bbe1b32bSmrg    char       *c,
404bbe1b32bSmrg    int        *ret,
405bbe1b32bSmrg    int		*pval,
406bbe1b32bSmrg    struct nameVal   *name_val)
407bbe1b32bSmrg{
408bbe1b32bSmrg    char       *start,
409bbe1b32bSmrg                t;
410bbe1b32bSmrg    int         i,
411bbe1b32bSmrg                len;
412bbe1b32bSmrg
413bbe1b32bSmrg    start = c;
414bbe1b32bSmrg    skip_val(c);
415bbe1b32bSmrg    t = *c;
416bbe1b32bSmrg    *c = '\0';
417bbe1b32bSmrg    len = c - start;
418bbe1b32bSmrg
419bbe1b32bSmrg    for (i = 0; name_val[i].name; i++) {
420bbe1b32bSmrg	if (!strncmpnocase(start, name_val[i].name, len)) {
421bbe1b32bSmrg	    *pval = name_val[i].val;
422bbe1b32bSmrg	    *ret = 0;
423bbe1b32bSmrg	    *c = t;
424bbe1b32bSmrg	    return c;
425bbe1b32bSmrg	}
426bbe1b32bSmrg    }
427bbe1b32bSmrg    ErrorF(ConfigErrors[CONFIG_ERR_VALUE], start);
428bbe1b32bSmrg    *c = t;
429bbe1b32bSmrg    *ret = -1;
430bbe1b32bSmrg    return c;
431bbe1b32bSmrg}
432bbe1b32bSmrg
433bbe1b32bSmrgstatic char *
434bbe1b32bSmrgconfig_parse_bool (
435bbe1b32bSmrg    char	*c,
436bbe1b32bSmrg    int		*ret,
437bbe1b32bSmrg    Bool	*pval)
438bbe1b32bSmrg{
439bbe1b32bSmrg    static struct nameVal bool_val[] = {
440bbe1b32bSmrg    	    { "yes",   TRUE },
441bbe1b32bSmrg    	    { "on",    TRUE },
442bbe1b32bSmrg    	    { "1",     TRUE },
443bbe1b32bSmrg    	    { "true",  TRUE },
444bbe1b32bSmrg    	    { "no",    FALSE },
445bbe1b32bSmrg    	    { "off",   FALSE },
446bbe1b32bSmrg    	    { "0",     FALSE },
447bbe1b32bSmrg    	    { "false", FALSE },
448bbe1b32bSmrg    	    { (char *) 0, 0 },
449bbe1b32bSmrg    };
450bbe1b32bSmrg    return config_parse_nameVal (c, ret, pval, bool_val);
451bbe1b32bSmrg}
452bbe1b32bSmrg
453bbe1b32bSmrgstatic char *
454bbe1b32bSmrgconfig_parse_int(
455bbe1b32bSmrg    char       *c,
456bbe1b32bSmrg    int        *ret,
457bbe1b32bSmrg    int        *pval)
458bbe1b32bSmrg{
459bbe1b32bSmrg    char       *start,
460bbe1b32bSmrg                t;
461bbe1b32bSmrg
462bbe1b32bSmrg    start = c;
463bbe1b32bSmrg    while (*c != '\0' && !isspace(*c) && *c != ',') {
464bbe1b32bSmrg	if (!isdigit(*c)) {	/* error */
465bbe1b32bSmrg	    skip_val(c);
466bbe1b32bSmrg	    t = *c;
467bbe1b32bSmrg	    *c = '\0';
468bbe1b32bSmrg	    ErrorF(ConfigErrors[CONFIG_ERR_VALUE], start);
469bbe1b32bSmrg	    *ret = -1;
470bbe1b32bSmrg	    *c = t;
471bbe1b32bSmrg	    return c;
472bbe1b32bSmrg	}
473bbe1b32bSmrg	c++;
474bbe1b32bSmrg    }
475bbe1b32bSmrg    t = *c;
476bbe1b32bSmrg    *c = '\0';
477bbe1b32bSmrg    *ret = 0;
478bbe1b32bSmrg    *pval = atoi(start);
479bbe1b32bSmrg    *c = t;
480bbe1b32bSmrg    return c;
481bbe1b32bSmrg}
482bbe1b32bSmrg
483bbe1b32bSmrg
484bbe1b32bSmrg/* config option sets */
485bbe1b32bSmrg/* these have to know how to do the real work and tweak the proper things */
486bbe1b32bSmrgstatic char *
487bbe1b32bSmrgconfig_set_int(
488bbe1b32bSmrg    ConfigOptionPtr parm,
489bbe1b32bSmrg    char       *val)
490bbe1b32bSmrg{
491bbe1b32bSmrg    int         ival,
492bbe1b32bSmrg                ret;
493bbe1b32bSmrg
494bbe1b32bSmrg    val = config_parse_int(val, &ret, &ival);
495bbe1b32bSmrg    if (ret == -1)
496bbe1b32bSmrg	return val;
497bbe1b32bSmrg
498bbe1b32bSmrg    /* now do individual attribute checks */
499bbe1b32bSmrg    if (!strcmp(parm->parm_name, "port") && !portFromCmdline) {
500bbe1b32bSmrg	ListenPort = ival;
501bbe1b32bSmrg    } else if (!strcmp(parm->parm_name, "client-limit")) {
502bbe1b32bSmrg	AccessSetConnectionLimit(ival);
503bbe1b32bSmrg    } else if (!strcmp(parm->parm_name, "default-point-size")) {
504bbe1b32bSmrg	SetDefaultPointSize(ival);
505bbe1b32bSmrg    }
506bbe1b32bSmrg#ifdef FONTCACHE
507bbe1b32bSmrg    else if (!strcmp(parm->parm_name, "cache-balance")) {
508bbe1b32bSmrg	cacheSettings.balance = ival;
509bbe1b32bSmrg    } else if (!strcmp(parm->parm_name, "cache-hi-mark")) {
510bbe1b32bSmrg	cacheSettings.himark = ival * 1024;
511bbe1b32bSmrg    } else if (!strcmp(parm->parm_name, "cache-low-mark")) {
512bbe1b32bSmrg	cacheSettings.lowmark = ival * 1024;
513bbe1b32bSmrg    }
514bbe1b32bSmrg#endif
515bbe1b32bSmrg    return val;
516bbe1b32bSmrg}
517bbe1b32bSmrg
518bbe1b32bSmrgstatic char *
519bbe1b32bSmrgconfig_set_bool(
520bbe1b32bSmrg    ConfigOptionPtr parm,
521bbe1b32bSmrg    char       *val)
522bbe1b32bSmrg{
523bbe1b32bSmrg    int
524bbe1b32bSmrg                ret;
525bbe1b32bSmrg    Bool        bval;
526bbe1b32bSmrg
527bbe1b32bSmrg    val = config_parse_bool(val, &ret, &bval);
528bbe1b32bSmrg    if (ret == -1)
529bbe1b32bSmrg	return val;
530bbe1b32bSmrg
531bbe1b32bSmrg    /* now do individual attribute checks */
532bbe1b32bSmrg    if (!strcmp(parm->parm_name, "use-syslog")) {
533bbe1b32bSmrg	UseSyslog = bval;
534bbe1b32bSmrg    } else if (!strcmp(parm->parm_name, "clone-self")) {
535bbe1b32bSmrg	CloneSelf = bval;
536bbe1b32bSmrg    }
537bbe1b32bSmrg    return val;
538bbe1b32bSmrg}
539bbe1b32bSmrg
540bbe1b32bSmrgstatic char *
541bbe1b32bSmrgconfig_set_file(
542bbe1b32bSmrg    ConfigOptionPtr parm,
543bbe1b32bSmrg    char       *val)
544bbe1b32bSmrg{
545bbe1b32bSmrg    char       *start = val,
546bbe1b32bSmrg                t;
547bbe1b32bSmrg
548bbe1b32bSmrg    skip_val(val);
549bbe1b32bSmrg    t = *val;
550bbe1b32bSmrg    *val = '\0';
551bbe1b32bSmrg    if (!strcmp(parm->parm_name, "error-file")) {
552bbe1b32bSmrg#ifndef __UNIXOS2__
553bbe1b32bSmrg	memmove( ErrorFile, start, val - start + 1);
554bbe1b32bSmrg#else
555bbe1b32bSmrg	strcpy( ErrorFile, __XFSRedirRoot(start));
556bbe1b32bSmrg#endif
557bbe1b32bSmrg    }
558bbe1b32bSmrg    *val = t;
559bbe1b32bSmrg    return val;
560bbe1b32bSmrg}
561bbe1b32bSmrg
562bbe1b32bSmrgstatic char *
563bbe1b32bSmrgconfig_set_catalogue(
564bbe1b32bSmrg    ConfigOptionPtr parm,
565bbe1b32bSmrg    char       *val)
566bbe1b32bSmrg{
567bbe1b32bSmrg    char       *b;
568bbe1b32bSmrg
569bbe1b32bSmrg    if (!strcmp(parm->parm_name, "catalogue")) {
570bbe1b32bSmrg	/* stash it for later */
571bbe1b32bSmrg	fsfree((char *) font_catalogue);	/* dump any previous one */
572bbe1b32bSmrg	b = font_catalogue = (char *) fsalloc(strlen(val) + 1);
573bbe1b32bSmrg	if (!font_catalogue)
574bbe1b32bSmrg	    FatalError("insufficent memory for font catalogue\n");
575bbe1b32bSmrg	while (*val) {		/* remove all the gunk */
576bbe1b32bSmrg	    if (!isspace(*val)) {
577bbe1b32bSmrg		*b++ = *val;
578bbe1b32bSmrg	    }
579bbe1b32bSmrg	    val++;
580bbe1b32bSmrg	}
581bbe1b32bSmrg	*b = '\0';
582bbe1b32bSmrg    }
583bbe1b32bSmrg    return val;
584bbe1b32bSmrg}
585bbe1b32bSmrg
586bbe1b32bSmrgstatic char *
587bbe1b32bSmrgconfig_set_list(
588bbe1b32bSmrg    ConfigOptionPtr parm,
589bbe1b32bSmrg    char       *val)
590bbe1b32bSmrg{
591bbe1b32bSmrg    char       *start = val,
592bbe1b32bSmrg                t;
593bbe1b32bSmrg
594bbe1b32bSmrg    skip_list_val(val);
595bbe1b32bSmrg    t = *val;
596bbe1b32bSmrg    *val = '\0';
597bbe1b32bSmrg    if (!strcmp(parm->parm_name, "alternate-servers")) {
598bbe1b32bSmrg	SetAlternateServers(start);
599bbe1b32bSmrg    }
600bbe1b32bSmrg    *val = t;
601bbe1b32bSmrg    return val;
602bbe1b32bSmrg}
603bbe1b32bSmrg
604bbe1b32bSmrgstatic char *
605bbe1b32bSmrgconfig_set_ignored_transports(
606bbe1b32bSmrg    ConfigOptionPtr parm,
607bbe1b32bSmrg    char       *val)
608bbe1b32bSmrg{
609bbe1b32bSmrg    char       *start = val,
610bbe1b32bSmrg                t;
611bbe1b32bSmrg
612bbe1b32bSmrg    skip_list_val(val);
613bbe1b32bSmrg    t = *val;
614bbe1b32bSmrg    *val = '\0';
615bbe1b32bSmrg    _FontTransNoListen(start);
616bbe1b32bSmrg    *val = t;
617bbe1b32bSmrg    return val;
618bbe1b32bSmrg}
619bbe1b32bSmrg
620bbe1b32bSmrgstatic char *
621bbe1b32bSmrgconfig_set_glyph_caching_mode(
622bbe1b32bSmrg    ConfigOptionPtr parm,
623bbe1b32bSmrg    char       *val)
624bbe1b32bSmrg{
625bbe1b32bSmrg    char       *start = val,
626bbe1b32bSmrg                t;
627bbe1b32bSmrg
628bbe1b32bSmrg    skip_list_val(val);
629bbe1b32bSmrg    t = *val;
630bbe1b32bSmrg    *val = '\0';
631bbe1b32bSmrg    if (!strcmp(parm->parm_name, "deferglyphs")) {
632bbe1b32bSmrg	ParseGlyphCachingMode(start);
633bbe1b32bSmrg    }
634bbe1b32bSmrg    *val = t;
635bbe1b32bSmrg    return val;
636bbe1b32bSmrg}
637bbe1b32bSmrg
638bbe1b32bSmrgstatic char *
639bbe1b32bSmrgconfig_set_resolutions(
640bbe1b32bSmrg    ConfigOptionPtr parm,
641bbe1b32bSmrg    char       *val)
642bbe1b32bSmrg{
643bbe1b32bSmrg    char       *start = val,
644bbe1b32bSmrg                t;
645bbe1b32bSmrg    int         err;
646bbe1b32bSmrg
647bbe1b32bSmrg    skip_list_val(val);
648bbe1b32bSmrg    t = *val;
649bbe1b32bSmrg    *val = '\0';
650bbe1b32bSmrg    if (!strcmp(parm->parm_name, "default-resolutions")) {
651bbe1b32bSmrg	err = SetDefaultResolutions(start);
652bbe1b32bSmrg	if (err != FSSuccess) {
653bbe1b32bSmrg	    FatalError("bogus resolution list \"%s\"\n", start);
654bbe1b32bSmrg	}
655bbe1b32bSmrg    }
656bbe1b32bSmrg    *val = t;
657bbe1b32bSmrg    return val;
658bbe1b32bSmrg}
659bbe1b32bSmrg
660bbe1b32bSmrg
661bbe1b32bSmrgstatic char *
662bbe1b32bSmrgconfig_parse_endian(
663bbe1b32bSmrg    char       *c,
664bbe1b32bSmrg    int        *ret,
665bbe1b32bSmrg    int		*pval)
666bbe1b32bSmrg{
667bbe1b32bSmrg    static struct nameVal endian_val[] = {
668bbe1b32bSmrg	{ "lsb",      LSBFirst },
669bbe1b32bSmrg	{ "little",   LSBFirst },
670bbe1b32bSmrg	{ "lsbfirst", LSBFirst },
671bbe1b32bSmrg	{ "msb",      MSBFirst },
672bbe1b32bSmrg	{ "big",      MSBFirst },
673bbe1b32bSmrg	{ "msbfirst", MSBFirst },
674bbe1b32bSmrg	{ (char *) 0, 0 },
675bbe1b32bSmrg    };
676bbe1b32bSmrg    return config_parse_nameVal (c, ret, pval, endian_val);
677bbe1b32bSmrg}
678bbe1b32bSmrg
679bbe1b32bSmrg/* ARGSUSED */
680bbe1b32bSmrgstatic char *
681bbe1b32bSmrgconfig_set_snf_format (
682bbe1b32bSmrg    ConfigOptionPtr parm,
683bbe1b32bSmrg    char	    *val)
684bbe1b32bSmrg{
685bbe1b32bSmrg    int	    bit, byte, glyph, scan;
686bbe1b32bSmrg    int	    ret;
687bbe1b32bSmrg
688bbe1b32bSmrg    val = config_parse_endian (val, &ret, &bit);
689bbe1b32bSmrg    if (ret == -1)
690bbe1b32bSmrg	return val;
691bbe1b32bSmrg    skip_whitespace (val);
692bbe1b32bSmrg    val = config_parse_endian (val, &ret, &byte);
693bbe1b32bSmrg    if (ret == -1)
694bbe1b32bSmrg	return val;
695bbe1b32bSmrg    skip_whitespace (val);
696bbe1b32bSmrg    val = config_parse_int (val, &ret, &glyph);
697bbe1b32bSmrg    if (ret == -1)
698bbe1b32bSmrg	return val;
699bbe1b32bSmrg    skip_whitespace (val);
700bbe1b32bSmrg    val = config_parse_int (val, &ret, &scan);
701bbe1b32bSmrg    if (ret == -1)
702bbe1b32bSmrg	return val;
703bbe1b32bSmrg    SnfSetFormat (bit, byte, glyph, scan);
704bbe1b32bSmrg    return val;
705bbe1b32bSmrg}
706