xref: /netbsd/usr.sbin/wsmoused/config.c (revision 15ba1217)
1 /* $NetBSD: config.c,v 1.3 2003/08/06 18:07:53 jmmv Exp $ */
2 
3 /*
4  * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Julio M. Merino Vidal.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. The name authors may not be used to endorse or promote products
16  *    derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
20  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 
34 #ifndef lint
35 __RCSID("$NetBSD: config.c,v 1.3 2003/08/06 18:07:53 jmmv Exp $");
36 #endif /* not lint */
37 
38 #include <sys/time.h>
39 #include <dev/wscons/wsconsio.h>
40 
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <err.h>
44 #include <errno.h>
45 #include <string.h>
46 
47 #include "pathnames.h"
48 #include "wsmoused.h"
49 
50 /* --------------------------------------------------------------------- */
51 
52 /*
53  * Global variables.
54  */
55 
56 static struct block *Global = NULL;
57 
58 /* --------------------------------------------------------------------- */
59 
60 /* Prototypes for config_yacc.y (only used here) */
61 struct block *config_parse(FILE *);
62 
63 /* --------------------------------------------------------------------- */
64 
65 /* Creates a new, empty property.  Returns a pointer to it. */
66 struct prop *
prop_new(void)67 prop_new(void)
68 {
69 	struct prop *p;
70 
71 	p = (struct prop *) calloc(1, sizeof(struct prop));
72 	if (p == NULL)
73 		err(EXIT_FAILURE, "calloc");
74 	return p;
75 }
76 
77 /* --------------------------------------------------------------------- */
78 
79 /* Frees a property created with prop_new.  All data stored in the property
80  * is also destroyed. */
81 void
prop_free(struct prop * p)82 prop_free(struct prop *p)
83 {
84 
85 	free(p->p_name);
86 	free(p->p_value);
87 	free(p);
88 }
89 
90 /* --------------------------------------------------------------------- */
91 
92 /* Creates a new, empty block, with the specified type (see BLOCK_* macros).
93  * Returns a pointer to it. */
94 struct block *
block_new(int type)95 block_new(int type)
96 {
97 	struct block *b;
98 
99 	b = (struct block *) calloc(1, sizeof(struct block));
100 	if (b == NULL)
101 		err(EXIT_FAILURE, "calloc");
102 	b->b_type = type;
103 	return b;
104 }
105 
106 /* --------------------------------------------------------------------- */
107 
108 /* Frees a block created with block_new.  All data contained inside the block
109  * is also destroyed. */
110 void
block_free(struct block * b)111 block_free(struct block *b)
112 {
113 	int i;
114 
115 	if (b->b_name != NULL)
116 		free(b->b_name);
117 
118 	for (i = 0; i < b->b_prop_count; i++)
119 		prop_free(b->b_prop[i]);
120 	for (i = 0; i < b->b_child_count; i++)
121 		block_free(b->b_child[i]);
122 
123 	free(b);
124 }
125 
126 /* --------------------------------------------------------------------- */
127 
128 /* Adds a property to a block. */
129 void
block_add_prop(struct block * b,struct prop * p)130 block_add_prop(struct block *b, struct prop *p)
131 {
132 
133 	if (p == NULL)
134 		return;
135 
136 	if (b->b_prop_count >= MAX_PROPS)
137 		errx(EXIT_FAILURE, "too many properties for current block");
138 	else {
139 		b->b_prop[b->b_prop_count] = p;
140 		b->b_prop_count++;
141 	}
142 }
143 
144 /* --------------------------------------------------------------------- */
145 
146 /* Adds a child (block) to a block. */
147 void
block_add_child(struct block * b,struct block * c)148 block_add_child(struct block *b, struct block *c)
149 {
150 
151 	if (c == NULL)
152 		return;
153 
154 	if (b->b_child_count >= MAX_BLOCKS)
155 		errx(EXIT_FAILURE, "too many childs for current block");
156 	else {
157 		c->b_parent = b;
158 		b->b_child[b->b_child_count] = c;
159 		b->b_child_count++;
160 	}
161 }
162 
163 /* --------------------------------------------------------------------- */
164 
165 /* Get the value of a property in the specified block (or in its parents).
166  * If not found, return the value given in def. */
167 char *
block_get_propval(struct block * b,const char * pname,char * def)168 block_get_propval(struct block *b, const char *pname, char *def)
169 {
170 	int pc;
171 
172 	if (b == NULL)
173 		return def;
174 
175 	while (b != NULL) {
176 		for (pc = 0; pc < b->b_prop_count; pc++)
177 			if (strcmp(b->b_prop[pc]->p_name, pname) == 0)
178 				return b->b_prop[pc]->p_value;
179 		b = b->b_parent;
180 	}
181 
182 	return def;
183 }
184 
185 /* --------------------------------------------------------------------- */
186 
187 /* Get the value of a property in the specified block converting it to an
188  * integer, if possible.  If the property cannot be found in the given
189  * block, all its parents are tried.  If after all not found (or conversion
190  * not possible), return the value given in def. */
191 int
block_get_propval_int(struct block * b,const char * pname,int def)192 block_get_propval_int(struct block *b, const char *pname, int def)
193 {
194 	char *ptr;
195 	int pc, ret;
196 
197 	if (b == NULL)
198 		return def;
199 
200 	while (b != NULL) {
201 		for (pc = 0; pc < b->b_prop_count; pc++)
202 			if (strcmp(b->b_prop[pc]->p_name, pname) == 0) {
203 				ret = (int) strtol(b->b_prop[pc]->p_value,
204 				    &ptr, 10);
205 				if (b->b_prop[pc]->p_value == ptr) {
206 					warnx("expected integer in `%s' "
207 					    "property", pname);
208 					return def;
209 				}
210 				return ret;
211 			}
212 		b = b->b_parent;
213 	}
214 
215 	return def;
216 }
217 
218 /* --------------------------------------------------------------------- */
219 
220 /* Gets a mode block (childs of the global scope), which matches the
221  * specified name. */
222 struct block *
config_get_mode(const char * modename)223 config_get_mode(const char *modename)
224 {
225 	int bc;
226 	struct block *b;
227 
228 	b = Global;
229 
230 	if (strcmp(modename, "Global") == 0)
231 		return Global;
232 
233 	if (b != NULL)
234 		for (bc = 0; bc < b->b_child_count; bc++)
235 			if (strcmp(b->b_child[bc]->b_name, modename) == 0)
236 				return b->b_child[bc];
237 
238 	return NULL;
239 }
240 
241 /* --------------------------------------------------------------------- */
242 
243 /* Reads the configuration file. */
244 void
config_read(const char * conffile,int opt)245 config_read(const char *conffile, int opt)
246 {
247 	FILE *f;
248 
249 	errno = 0;
250 	f = fopen(conffile, "r");
251 	if (f != NULL) {
252 		Global = config_parse(f);
253 		if (Global == NULL)
254 			errx(EXIT_FAILURE, "%s contains fatal errors",
255 			     conffile);
256 	} else if (errno != ENOENT || opt) {
257 		err(EXIT_FAILURE, "cannot open %s", conffile);
258 	}
259 }
260 
261 /* --------------------------------------------------------------------- */
262 
263 /* Destroys all the configuration data. */
264 void
config_free(void)265 config_free(void)
266 {
267 
268 	if (Global != NULL)
269 		block_free(Global);
270 }
271