xref: /netbsd-src/usr.sbin/wsmoused/config.c (revision 15ba121760dfe10b11049e25af697d98b39da32d)
1*15ba1217Sjmmv /* $NetBSD: config.c,v 1.3 2003/08/06 18:07:53 jmmv Exp $ */
268e2c804Sjmmv 
368e2c804Sjmmv /*
468e2c804Sjmmv  * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
568e2c804Sjmmv  * All rights reserved.
668e2c804Sjmmv  *
768e2c804Sjmmv  * This code is derived from software contributed to The NetBSD Foundation
8*15ba1217Sjmmv  * by Julio M. Merino Vidal.
968e2c804Sjmmv  *
1068e2c804Sjmmv  * Redistribution and use in source and binary forms, with or without
1168e2c804Sjmmv  * modification, are permitted provided that the following conditions
1268e2c804Sjmmv  * are met:
1368e2c804Sjmmv  * 1. Redistributions of source code must retain the above copyright
1468e2c804Sjmmv  *    notice, this list of conditions and the following disclaimer.
1568e2c804Sjmmv  * 2. The name authors may not be used to endorse or promote products
1668e2c804Sjmmv  *    derived from this software without specific prior written
1768e2c804Sjmmv  *    permission.
1868e2c804Sjmmv  *
1968e2c804Sjmmv  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
2068e2c804Sjmmv  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2168e2c804Sjmmv  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2268e2c804Sjmmv  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
2368e2c804Sjmmv  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2468e2c804Sjmmv  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
2568e2c804Sjmmv  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2668e2c804Sjmmv  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2768e2c804Sjmmv  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2868e2c804Sjmmv  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2968e2c804Sjmmv  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3068e2c804Sjmmv  */
3168e2c804Sjmmv 
3268e2c804Sjmmv #include <sys/cdefs.h>
3368e2c804Sjmmv 
3468e2c804Sjmmv #ifndef lint
35*15ba1217Sjmmv __RCSID("$NetBSD: config.c,v 1.3 2003/08/06 18:07:53 jmmv Exp $");
3668e2c804Sjmmv #endif /* not lint */
3768e2c804Sjmmv 
3868e2c804Sjmmv #include <sys/time.h>
3968e2c804Sjmmv #include <dev/wscons/wsconsio.h>
40*15ba1217Sjmmv 
4168e2c804Sjmmv #include <stdio.h>
4268e2c804Sjmmv #include <stdlib.h>
4368e2c804Sjmmv #include <err.h>
4468e2c804Sjmmv #include <errno.h>
4568e2c804Sjmmv #include <string.h>
4668e2c804Sjmmv 
4768e2c804Sjmmv #include "pathnames.h"
4868e2c804Sjmmv #include "wsmoused.h"
4968e2c804Sjmmv 
50*15ba1217Sjmmv /* --------------------------------------------------------------------- */
51*15ba1217Sjmmv 
52*15ba1217Sjmmv /*
53*15ba1217Sjmmv  * Global variables.
54*15ba1217Sjmmv  */
55*15ba1217Sjmmv 
5668e2c804Sjmmv static struct block *Global = NULL;
5768e2c804Sjmmv 
58*15ba1217Sjmmv /* --------------------------------------------------------------------- */
59*15ba1217Sjmmv 
6068e2c804Sjmmv /* Prototypes for config_yacc.y (only used here) */
6168e2c804Sjmmv struct block *config_parse(FILE *);
6268e2c804Sjmmv 
63*15ba1217Sjmmv /* --------------------------------------------------------------------- */
64*15ba1217Sjmmv 
65*15ba1217Sjmmv /* Creates a new, empty property.  Returns a pointer to it. */
6668e2c804Sjmmv struct prop *
prop_new(void)6768e2c804Sjmmv prop_new(void)
6868e2c804Sjmmv {
6968e2c804Sjmmv 	struct prop *p;
7068e2c804Sjmmv 
7168e2c804Sjmmv 	p = (struct prop *) calloc(1, sizeof(struct prop));
7268e2c804Sjmmv 	if (p == NULL)
7368e2c804Sjmmv 		err(EXIT_FAILURE, "calloc");
7468e2c804Sjmmv 	return p;
7568e2c804Sjmmv }
7668e2c804Sjmmv 
77*15ba1217Sjmmv /* --------------------------------------------------------------------- */
78*15ba1217Sjmmv 
79*15ba1217Sjmmv /* Frees a property created with prop_new.  All data stored in the property
80*15ba1217Sjmmv  * is also destroyed. */
8168e2c804Sjmmv void
prop_free(struct prop * p)8268e2c804Sjmmv prop_free(struct prop *p)
8368e2c804Sjmmv {
84*15ba1217Sjmmv 
8568e2c804Sjmmv 	free(p->p_name);
8668e2c804Sjmmv 	free(p->p_value);
8768e2c804Sjmmv 	free(p);
8868e2c804Sjmmv }
8968e2c804Sjmmv 
90*15ba1217Sjmmv /* --------------------------------------------------------------------- */
91*15ba1217Sjmmv 
92*15ba1217Sjmmv /* Creates a new, empty block, with the specified type (see BLOCK_* macros).
93*15ba1217Sjmmv  * Returns a pointer to it. */
9468e2c804Sjmmv struct block *
block_new(int type)9568e2c804Sjmmv block_new(int type)
9668e2c804Sjmmv {
9768e2c804Sjmmv 	struct block *b;
9868e2c804Sjmmv 
9968e2c804Sjmmv 	b = (struct block *) calloc(1, sizeof(struct block));
10068e2c804Sjmmv 	if (b == NULL)
10168e2c804Sjmmv 		err(EXIT_FAILURE, "calloc");
10268e2c804Sjmmv 	b->b_type = type;
10368e2c804Sjmmv 	return b;
10468e2c804Sjmmv }
10568e2c804Sjmmv 
106*15ba1217Sjmmv /* --------------------------------------------------------------------- */
107*15ba1217Sjmmv 
108*15ba1217Sjmmv /* Frees a block created with block_new.  All data contained inside the block
109*15ba1217Sjmmv  * is also destroyed. */
11068e2c804Sjmmv void
block_free(struct block * b)11168e2c804Sjmmv block_free(struct block *b)
11268e2c804Sjmmv {
11368e2c804Sjmmv 	int i;
11468e2c804Sjmmv 
11568e2c804Sjmmv 	if (b->b_name != NULL)
11668e2c804Sjmmv 		free(b->b_name);
11768e2c804Sjmmv 
11868e2c804Sjmmv 	for (i = 0; i < b->b_prop_count; i++)
11968e2c804Sjmmv 		prop_free(b->b_prop[i]);
12068e2c804Sjmmv 	for (i = 0; i < b->b_child_count; i++)
12168e2c804Sjmmv 		block_free(b->b_child[i]);
12268e2c804Sjmmv 
12368e2c804Sjmmv 	free(b);
12468e2c804Sjmmv }
12568e2c804Sjmmv 
126*15ba1217Sjmmv /* --------------------------------------------------------------------- */
127*15ba1217Sjmmv 
128*15ba1217Sjmmv /* Adds a property to a block. */
12968e2c804Sjmmv void
block_add_prop(struct block * b,struct prop * p)13068e2c804Sjmmv block_add_prop(struct block *b, struct prop *p)
13168e2c804Sjmmv {
132*15ba1217Sjmmv 
13368e2c804Sjmmv 	if (p == NULL)
13468e2c804Sjmmv 		return;
13568e2c804Sjmmv 
13668e2c804Sjmmv 	if (b->b_prop_count >= MAX_PROPS)
13768e2c804Sjmmv 		errx(EXIT_FAILURE, "too many properties for current block");
13868e2c804Sjmmv 	else {
13968e2c804Sjmmv 		b->b_prop[b->b_prop_count] = p;
14068e2c804Sjmmv 		b->b_prop_count++;
14168e2c804Sjmmv 	}
14268e2c804Sjmmv }
14368e2c804Sjmmv 
144*15ba1217Sjmmv /* --------------------------------------------------------------------- */
145*15ba1217Sjmmv 
146*15ba1217Sjmmv /* Adds a child (block) to a block. */
14768e2c804Sjmmv void
block_add_child(struct block * b,struct block * c)14868e2c804Sjmmv block_add_child(struct block *b, struct block *c)
14968e2c804Sjmmv {
150*15ba1217Sjmmv 
15168e2c804Sjmmv 	if (c == NULL)
15268e2c804Sjmmv 		return;
15368e2c804Sjmmv 
15468e2c804Sjmmv 	if (b->b_child_count >= MAX_BLOCKS)
15568e2c804Sjmmv 		errx(EXIT_FAILURE, "too many childs for current block");
15668e2c804Sjmmv 	else {
15768e2c804Sjmmv 		c->b_parent = b;
15868e2c804Sjmmv 		b->b_child[b->b_child_count] = c;
15968e2c804Sjmmv 		b->b_child_count++;
16068e2c804Sjmmv 	}
16168e2c804Sjmmv }
16268e2c804Sjmmv 
163*15ba1217Sjmmv /* --------------------------------------------------------------------- */
164*15ba1217Sjmmv 
165*15ba1217Sjmmv /* Get the value of a property in the specified block (or in its parents).
166*15ba1217Sjmmv  * If not found, return the value given in def. */
16768e2c804Sjmmv char *
block_get_propval(struct block * b,const char * pname,char * def)168*15ba1217Sjmmv block_get_propval(struct block *b, const char *pname, char *def)
16968e2c804Sjmmv {
17068e2c804Sjmmv 	int pc;
17168e2c804Sjmmv 
17268e2c804Sjmmv 	if (b == NULL)
17368e2c804Sjmmv 		return def;
17468e2c804Sjmmv 
17568e2c804Sjmmv 	while (b != NULL) {
17668e2c804Sjmmv 		for (pc = 0; pc < b->b_prop_count; pc++)
17768e2c804Sjmmv 			if (strcmp(b->b_prop[pc]->p_name, pname) == 0)
17868e2c804Sjmmv 				return b->b_prop[pc]->p_value;
17968e2c804Sjmmv 		b = b->b_parent;
18068e2c804Sjmmv 	}
18168e2c804Sjmmv 
18268e2c804Sjmmv 	return def;
18368e2c804Sjmmv }
18468e2c804Sjmmv 
185*15ba1217Sjmmv /* --------------------------------------------------------------------- */
186*15ba1217Sjmmv 
187*15ba1217Sjmmv /* Get the value of a property in the specified block converting it to an
18868e2c804Sjmmv  * integer, if possible.  If the property cannot be found in the given
18968e2c804Sjmmv  * block, all its parents are tried.  If after all not found (or conversion
190*15ba1217Sjmmv  * not possible), return the value given in def. */
19168e2c804Sjmmv int
block_get_propval_int(struct block * b,const char * pname,int def)192*15ba1217Sjmmv block_get_propval_int(struct block *b, const char *pname, int def)
19368e2c804Sjmmv {
19468e2c804Sjmmv 	char *ptr;
195*15ba1217Sjmmv 	int pc, ret;
19668e2c804Sjmmv 
19768e2c804Sjmmv 	if (b == NULL)
19868e2c804Sjmmv 		return def;
19968e2c804Sjmmv 
20068e2c804Sjmmv 	while (b != NULL) {
20168e2c804Sjmmv 		for (pc = 0; pc < b->b_prop_count; pc++)
20268e2c804Sjmmv 			if (strcmp(b->b_prop[pc]->p_name, pname) == 0) {
20368e2c804Sjmmv 				ret = (int) strtol(b->b_prop[pc]->p_value,
20468e2c804Sjmmv 				    &ptr, 10);
20568e2c804Sjmmv 				if (b->b_prop[pc]->p_value == ptr) {
20668e2c804Sjmmv 					warnx("expected integer in `%s' "
20768e2c804Sjmmv 					    "property", pname);
20868e2c804Sjmmv 					return def;
20968e2c804Sjmmv 				}
21068e2c804Sjmmv 				return ret;
21168e2c804Sjmmv 			}
21268e2c804Sjmmv 		b = b->b_parent;
21368e2c804Sjmmv 	}
21468e2c804Sjmmv 
21568e2c804Sjmmv 	return def;
21668e2c804Sjmmv }
21768e2c804Sjmmv 
218*15ba1217Sjmmv /* --------------------------------------------------------------------- */
219*15ba1217Sjmmv 
220*15ba1217Sjmmv /* Gets a mode block (childs of the global scope), which matches the
221*15ba1217Sjmmv  * specified name. */
22268e2c804Sjmmv struct block *
config_get_mode(const char * modename)223*15ba1217Sjmmv config_get_mode(const char *modename)
22468e2c804Sjmmv {
22568e2c804Sjmmv 	int bc;
226*15ba1217Sjmmv 	struct block *b;
227*15ba1217Sjmmv 
228*15ba1217Sjmmv 	b = Global;
229*15ba1217Sjmmv 
230*15ba1217Sjmmv 	if (strcmp(modename, "Global") == 0)
231*15ba1217Sjmmv 		return Global;
23268e2c804Sjmmv 
23368e2c804Sjmmv 	if (b != NULL)
23468e2c804Sjmmv 		for (bc = 0; bc < b->b_child_count; bc++)
23568e2c804Sjmmv 			if (strcmp(b->b_child[bc]->b_name, modename) == 0)
23668e2c804Sjmmv 				return b->b_child[bc];
23768e2c804Sjmmv 
23868e2c804Sjmmv 	return NULL;
23968e2c804Sjmmv }
24068e2c804Sjmmv 
241*15ba1217Sjmmv /* --------------------------------------------------------------------- */
242*15ba1217Sjmmv 
243*15ba1217Sjmmv /* Reads the configuration file. */
24468e2c804Sjmmv void
config_read(const char * conffile,int opt)245*15ba1217Sjmmv config_read(const char *conffile, int opt)
24668e2c804Sjmmv {
24768e2c804Sjmmv 	FILE *f;
24868e2c804Sjmmv 
24968e2c804Sjmmv 	errno = 0;
25068e2c804Sjmmv 	f = fopen(conffile, "r");
25168e2c804Sjmmv 	if (f != NULL) {
25268e2c804Sjmmv 		Global = config_parse(f);
25368e2c804Sjmmv 		if (Global == NULL)
25468e2c804Sjmmv 			errx(EXIT_FAILURE, "%s contains fatal errors",
25568e2c804Sjmmv 			     conffile);
25668e2c804Sjmmv 	} else if (errno != ENOENT || opt) {
25768e2c804Sjmmv 		err(EXIT_FAILURE, "cannot open %s", conffile);
25868e2c804Sjmmv 	}
25968e2c804Sjmmv }
26068e2c804Sjmmv 
261*15ba1217Sjmmv /* --------------------------------------------------------------------- */
262*15ba1217Sjmmv 
263*15ba1217Sjmmv /* Destroys all the configuration data. */
26468e2c804Sjmmv void
config_free(void)26568e2c804Sjmmv config_free(void)
26668e2c804Sjmmv {
267*15ba1217Sjmmv 
26873b21378Sjmmv 	if (Global != NULL)
26968e2c804Sjmmv 		block_free(Global);
27068e2c804Sjmmv }
271