xref: /minix3/minix/commands/minix-service/parse.c (revision 181fb1b2b562251d07c6fcffd262fd8efbcd2ee0)
1c58da9fbSDavid van Moolenbroek 
2c58da9fbSDavid van Moolenbroek #define _MINIX_SYSTEM 1
3c58da9fbSDavid van Moolenbroek 
4c58da9fbSDavid van Moolenbroek #include <stdarg.h>
5c58da9fbSDavid van Moolenbroek #include <assert.h>
6c58da9fbSDavid van Moolenbroek #include <stdlib.h>
7c58da9fbSDavid van Moolenbroek #include <stdio.h>
8c58da9fbSDavid van Moolenbroek #include <string.h>
9c58da9fbSDavid van Moolenbroek #include <errno.h>
10c58da9fbSDavid van Moolenbroek #include <pwd.h>
11c58da9fbSDavid van Moolenbroek #include <err.h>
12c58da9fbSDavid van Moolenbroek #include <unistd.h>
13c58da9fbSDavid van Moolenbroek #include <limits.h>
14c58da9fbSDavid van Moolenbroek #include <lib.h>
15c58da9fbSDavid van Moolenbroek #include <minix/config.h>
16c58da9fbSDavid van Moolenbroek #include <minix/com.h>
17c58da9fbSDavid van Moolenbroek #include <minix/const.h>
18c58da9fbSDavid van Moolenbroek #include <minix/type.h>
19c58da9fbSDavid van Moolenbroek #include <minix/ipc.h>
20c58da9fbSDavid van Moolenbroek #include <minix/rs.h>
21c58da9fbSDavid van Moolenbroek #include <minix/syslib.h>
22c58da9fbSDavid van Moolenbroek #include <minix/bitmap.h>
23c58da9fbSDavid van Moolenbroek #include <minix/paths.h>
24c58da9fbSDavid van Moolenbroek #include <minix/sef.h>
25c58da9fbSDavid van Moolenbroek #include <minix/dmap.h>
26c58da9fbSDavid van Moolenbroek #include <minix/priv.h>
27c58da9fbSDavid van Moolenbroek #include <sys/types.h>
28c58da9fbSDavid van Moolenbroek #include <sys/stat.h>
29*181fb1b2SDavid van Moolenbroek #include <sys/socket.h>
30c58da9fbSDavid van Moolenbroek #include <configfile.h>
31c58da9fbSDavid van Moolenbroek 
32c58da9fbSDavid van Moolenbroek #include <machine/archtypes.h>
33c58da9fbSDavid van Moolenbroek #include <minix/timers.h>
34c58da9fbSDavid van Moolenbroek 
35c58da9fbSDavid van Moolenbroek #include "config.h"
36c58da9fbSDavid van Moolenbroek #include "proto.h"
37c58da9fbSDavid van Moolenbroek 
38c58da9fbSDavid van Moolenbroek static int class_recurs;       /* Nesting level of class statements */
39c58da9fbSDavid van Moolenbroek #define MAX_CLASS_RECURS        100     /* Max nesting level for classes */
40c58da9fbSDavid van Moolenbroek 
41c58da9fbSDavid van Moolenbroek #include "parse.h"
42c58da9fbSDavid van Moolenbroek 
43c58da9fbSDavid van Moolenbroek static void do_service(config_t *cpe, config_t *config, struct rs_config *);
44c58da9fbSDavid van Moolenbroek 
do_class(config_t * cpe,config_t * config,struct rs_config * rs_config)45c58da9fbSDavid van Moolenbroek static void do_class(config_t *cpe, config_t *config, struct rs_config *rs_config)
46c58da9fbSDavid van Moolenbroek {
47c58da9fbSDavid van Moolenbroek 	config_t *cp, *cp1;
48c58da9fbSDavid van Moolenbroek 
49c58da9fbSDavid van Moolenbroek 	if (class_recurs > MAX_CLASS_RECURS)
50c58da9fbSDavid van Moolenbroek 	{
51c58da9fbSDavid van Moolenbroek 		fatal(
52c58da9fbSDavid van Moolenbroek 		"do_class: nesting level too high for class '%s' at %s:%d",
53c58da9fbSDavid van Moolenbroek 			cpe->word, cpe->file, cpe->line);
54c58da9fbSDavid van Moolenbroek 	}
55c58da9fbSDavid van Moolenbroek 	class_recurs++;
56c58da9fbSDavid van Moolenbroek 
57c58da9fbSDavid van Moolenbroek 	/* Process classes */
58c58da9fbSDavid van Moolenbroek 	for (; cpe; cpe= cpe->next)
59c58da9fbSDavid van Moolenbroek 	{
60c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_SUBLIST)
61c58da9fbSDavid van Moolenbroek 		{
62c58da9fbSDavid van Moolenbroek 			fatal("do_class: unexpected sublist at %s:%d",
63c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
64c58da9fbSDavid van Moolenbroek 		}
65c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_STRING)
66c58da9fbSDavid van Moolenbroek 		{
67c58da9fbSDavid van Moolenbroek 			fatal("do_uid: unexpected string at %s:%d",
68c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
69c58da9fbSDavid van Moolenbroek 		}
70c58da9fbSDavid van Moolenbroek 
71c58da9fbSDavid van Moolenbroek 		/* Find entry for the class */
72c58da9fbSDavid van Moolenbroek 		for (cp= config; cp; cp= cp->next)
73c58da9fbSDavid van Moolenbroek 		{
74c58da9fbSDavid van Moolenbroek 			if (!(cp->flags & CFG_SUBLIST))
75c58da9fbSDavid van Moolenbroek 			{
76c58da9fbSDavid van Moolenbroek 				fatal("do_class: expected list at %s:%d",
77c58da9fbSDavid van Moolenbroek 					cp->file, cp->line);
78c58da9fbSDavid van Moolenbroek 			}
79c58da9fbSDavid van Moolenbroek 			cp1= cp->list;
80c58da9fbSDavid van Moolenbroek 			if ((cp1->flags & CFG_STRING) ||
81c58da9fbSDavid van Moolenbroek 				(cp1->flags & CFG_SUBLIST))
82c58da9fbSDavid van Moolenbroek 			{
83c58da9fbSDavid van Moolenbroek 				fatal("do_class: expected word at %s:%d",
84c58da9fbSDavid van Moolenbroek 					cp1->file, cp1->line);
85c58da9fbSDavid van Moolenbroek 			}
86c58da9fbSDavid van Moolenbroek 
87c58da9fbSDavid van Moolenbroek 			/* At this place we expect the word KW_SERVICE */
88c58da9fbSDavid van Moolenbroek 			if (strcmp(cp1->word, KW_SERVICE) != 0)
89c58da9fbSDavid van Moolenbroek 				fatal("do_class: exected word '%S' at %s:%d",
90c58da9fbSDavid van Moolenbroek 					KW_SERVICE, cp1->file, cp1->line);
91c58da9fbSDavid van Moolenbroek 
92c58da9fbSDavid van Moolenbroek 			cp1= cp1->next;
93c58da9fbSDavid van Moolenbroek 			if ((cp1->flags & CFG_STRING) ||
94c58da9fbSDavid van Moolenbroek 				(cp1->flags & CFG_SUBLIST))
95c58da9fbSDavid van Moolenbroek 			{
96c58da9fbSDavid van Moolenbroek 				fatal("do_class: expected word at %s:%d",
97c58da9fbSDavid van Moolenbroek 					cp1->file, cp1->line);
98c58da9fbSDavid van Moolenbroek 			}
99c58da9fbSDavid van Moolenbroek 
100c58da9fbSDavid van Moolenbroek 			/* At this place we expect the name of the service */
101c58da9fbSDavid van Moolenbroek 			if (strcmp(cp1->word, cpe->word) == 0)
102c58da9fbSDavid van Moolenbroek 				break;
103c58da9fbSDavid van Moolenbroek 		}
104c58da9fbSDavid van Moolenbroek 		if (cp == NULL)
105c58da9fbSDavid van Moolenbroek 		{
106c58da9fbSDavid van Moolenbroek 			fatal(
107c58da9fbSDavid van Moolenbroek 			"do_class: no entry found for class '%s' at %s:%d",
108c58da9fbSDavid van Moolenbroek 				cpe->word, cpe->file, cpe->line);
109c58da9fbSDavid van Moolenbroek 		}
110c58da9fbSDavid van Moolenbroek 		do_service(cp1->next, config, rs_config);
111c58da9fbSDavid van Moolenbroek 	}
112c58da9fbSDavid van Moolenbroek 
113c58da9fbSDavid van Moolenbroek 	class_recurs--;
114c58da9fbSDavid van Moolenbroek }
115c58da9fbSDavid van Moolenbroek 
do_uid(config_t * cpe,struct rs_start * rs_start)116c58da9fbSDavid van Moolenbroek static void do_uid(config_t *cpe, struct rs_start *rs_start)
117c58da9fbSDavid van Moolenbroek {
118c58da9fbSDavid van Moolenbroek 	uid_t uid;
119c58da9fbSDavid van Moolenbroek 	struct passwd *pw;
120c58da9fbSDavid van Moolenbroek 	char *check;
121c58da9fbSDavid van Moolenbroek 
122c58da9fbSDavid van Moolenbroek 	/* Process a uid */
123c58da9fbSDavid van Moolenbroek 	if (cpe->next != NULL)
124c58da9fbSDavid van Moolenbroek 	{
125c58da9fbSDavid van Moolenbroek 		fatal("do_uid: just one uid/login expected at %s:%d",
126c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
127c58da9fbSDavid van Moolenbroek 	}
128c58da9fbSDavid van Moolenbroek 
129c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_SUBLIST)
130c58da9fbSDavid van Moolenbroek 	{
131c58da9fbSDavid van Moolenbroek 		fatal("do_uid: unexpected sublist at %s:%d",
132c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
133c58da9fbSDavid van Moolenbroek 	}
134c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_STRING)
135c58da9fbSDavid van Moolenbroek 	{
136c58da9fbSDavid van Moolenbroek 		fatal("do_uid: unexpected string at %s:%d",
137c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
138c58da9fbSDavid van Moolenbroek 	}
139c58da9fbSDavid van Moolenbroek 	pw= getpwnam(cpe->word);
140c58da9fbSDavid van Moolenbroek 	if (pw != NULL)
141c58da9fbSDavid van Moolenbroek 		uid= pw->pw_uid;
142c58da9fbSDavid van Moolenbroek 	else
143c58da9fbSDavid van Moolenbroek 	{
144c58da9fbSDavid van Moolenbroek 		if (!strncmp(cpe->word, KW_SELF, strlen(KW_SELF)+1))
145c58da9fbSDavid van Moolenbroek 		{
146c58da9fbSDavid van Moolenbroek 			uid= getuid();	/* Real uid */
147c58da9fbSDavid van Moolenbroek 		}
148c58da9fbSDavid van Moolenbroek 		else {
149c58da9fbSDavid van Moolenbroek 			uid= strtol(cpe->word, &check, 0);
150c58da9fbSDavid van Moolenbroek 			if (check[0] != '\0')
151c58da9fbSDavid van Moolenbroek 			{
152c58da9fbSDavid van Moolenbroek 				fatal("do_uid: bad uid/login '%s' at %s:%d",
153c58da9fbSDavid van Moolenbroek 					cpe->word, cpe->file, cpe->line);
154c58da9fbSDavid van Moolenbroek 			}
155c58da9fbSDavid van Moolenbroek 		}
156c58da9fbSDavid van Moolenbroek 	}
157c58da9fbSDavid van Moolenbroek 
158c58da9fbSDavid van Moolenbroek 	rs_start->rss_uid= uid;
159c58da9fbSDavid van Moolenbroek }
160c58da9fbSDavid van Moolenbroek 
do_sigmgr(config_t * cpe,struct rs_start * rs_start)161c58da9fbSDavid van Moolenbroek static void do_sigmgr(config_t *cpe, struct rs_start *rs_start)
162c58da9fbSDavid van Moolenbroek {
163c58da9fbSDavid van Moolenbroek 	endpoint_t sigmgr_ep;
164c58da9fbSDavid van Moolenbroek 	int r;
165c58da9fbSDavid van Moolenbroek 
166c58da9fbSDavid van Moolenbroek 	/* Process a signal manager value */
167c58da9fbSDavid van Moolenbroek 	if (cpe->next != NULL)
168c58da9fbSDavid van Moolenbroek 	{
169c58da9fbSDavid van Moolenbroek 		fatal("do_sigmgr: just one sigmgr value expected at %s:%d",
170c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
171c58da9fbSDavid van Moolenbroek 	}
172c58da9fbSDavid van Moolenbroek 
173c58da9fbSDavid van Moolenbroek 
174c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_SUBLIST)
175c58da9fbSDavid van Moolenbroek 	{
176c58da9fbSDavid van Moolenbroek 		fatal("do_sigmgr: unexpected sublist at %s:%d",
177c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
178c58da9fbSDavid van Moolenbroek 	}
179c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_STRING)
180c58da9fbSDavid van Moolenbroek 	{
181c58da9fbSDavid van Moolenbroek 		fatal("do_sigmgr: unexpected string at %s:%d",
182c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
183c58da9fbSDavid van Moolenbroek 	}
184c58da9fbSDavid van Moolenbroek 
185c58da9fbSDavid van Moolenbroek 	if(!strcmp(cpe->word, "SELF")) {
186c58da9fbSDavid van Moolenbroek 		sigmgr_ep = SELF;
187c58da9fbSDavid van Moolenbroek 	}
188c58da9fbSDavid van Moolenbroek 	else {
189c58da9fbSDavid van Moolenbroek 		if((r = minix_rs_lookup(cpe->word, &sigmgr_ep))) {
190c58da9fbSDavid van Moolenbroek 			fatal("do_sigmgr: unknown sigmgr %s at %s:%d",
191c58da9fbSDavid van Moolenbroek 			cpe->word, cpe->file, cpe->line);
192c58da9fbSDavid van Moolenbroek 		}
193c58da9fbSDavid van Moolenbroek 	}
194c58da9fbSDavid van Moolenbroek 
195c58da9fbSDavid van Moolenbroek 	rs_start->rss_sigmgr= sigmgr_ep;
196c58da9fbSDavid van Moolenbroek }
197c58da9fbSDavid van Moolenbroek 
do_type(config_t * cpe,struct rs_config * rs_config)198c58da9fbSDavid van Moolenbroek static void do_type(config_t *cpe, struct rs_config *rs_config)
199c58da9fbSDavid van Moolenbroek {
200c58da9fbSDavid van Moolenbroek 	if (cpe->next != NULL)
201c58da9fbSDavid van Moolenbroek 	{
202c58da9fbSDavid van Moolenbroek 		fatal("do_type: just one type value expected at %s:%d",
203c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
204c58da9fbSDavid van Moolenbroek 	}
205c58da9fbSDavid van Moolenbroek 
206c58da9fbSDavid van Moolenbroek 
207c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_SUBLIST)
208c58da9fbSDavid van Moolenbroek 	{
209c58da9fbSDavid van Moolenbroek 		fatal("do_type: unexpected sublist at %s:%d",
210c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
211c58da9fbSDavid van Moolenbroek 	}
212c58da9fbSDavid van Moolenbroek 	if ((cpe->flags & CFG_STRING))
213c58da9fbSDavid van Moolenbroek 	{
214c58da9fbSDavid van Moolenbroek 		fatal("do_type: unexpected string at %s:%d",
215c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
216c58da9fbSDavid van Moolenbroek 	}
217c58da9fbSDavid van Moolenbroek 
218c58da9fbSDavid van Moolenbroek 	if(rs_config->type)
219c58da9fbSDavid van Moolenbroek 		fatal("do_type: another type at %s:%d",
220c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
221c58da9fbSDavid van Moolenbroek 
222c58da9fbSDavid van Moolenbroek 	if(!strcmp(cpe->word, KW_NET))
223c58da9fbSDavid van Moolenbroek 		rs_config->type = KW_NET;
224c58da9fbSDavid van Moolenbroek 	else
225c58da9fbSDavid van Moolenbroek 		fatal("do_type: odd type at %s:%d",
226c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
227c58da9fbSDavid van Moolenbroek }
228c58da9fbSDavid van Moolenbroek 
do_descr(config_t * cpe,struct rs_config * rs_config)229c58da9fbSDavid van Moolenbroek static void do_descr(config_t *cpe, struct rs_config *rs_config)
230c58da9fbSDavid van Moolenbroek {
231c58da9fbSDavid van Moolenbroek 	if (cpe->next != NULL)
232c58da9fbSDavid van Moolenbroek 	{
233c58da9fbSDavid van Moolenbroek 		fatal("do_descr: just one description expected at %s:%d",
234c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
235c58da9fbSDavid van Moolenbroek 	}
236c58da9fbSDavid van Moolenbroek 
237c58da9fbSDavid van Moolenbroek 
238c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_SUBLIST)
239c58da9fbSDavid van Moolenbroek 	{
240c58da9fbSDavid van Moolenbroek 		fatal("do_descr: unexpected sublist at %s:%d",
241c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
242c58da9fbSDavid van Moolenbroek 	}
243c58da9fbSDavid van Moolenbroek 	if (!(cpe->flags & CFG_STRING))
244c58da9fbSDavid van Moolenbroek 	{
245c58da9fbSDavid van Moolenbroek 		fatal("do_descr: expected string at %s:%d",
246c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
247c58da9fbSDavid van Moolenbroek 	}
248c58da9fbSDavid van Moolenbroek 
249c58da9fbSDavid van Moolenbroek 	if(rs_config->descr)
250c58da9fbSDavid van Moolenbroek 		fatal("do_descr: another descr at %s:%d",
251c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
252c58da9fbSDavid van Moolenbroek 	rs_config->descr = cpe->word;
253c58da9fbSDavid van Moolenbroek }
254c58da9fbSDavid van Moolenbroek 
do_scheduler(config_t * cpe,struct rs_start * rs_start)255c58da9fbSDavid van Moolenbroek static void do_scheduler(config_t *cpe, struct rs_start *rs_start)
256c58da9fbSDavid van Moolenbroek {
257c58da9fbSDavid van Moolenbroek 	endpoint_t scheduler_ep;
258c58da9fbSDavid van Moolenbroek 	int r;
259c58da9fbSDavid van Moolenbroek 
260c58da9fbSDavid van Moolenbroek 	/* Process a scheduler value */
261c58da9fbSDavid van Moolenbroek 	if (cpe->next != NULL)
262c58da9fbSDavid van Moolenbroek 	{
263c58da9fbSDavid van Moolenbroek 		fatal("do_scheduler: just one scheduler value expected at %s:%d",
264c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
265c58da9fbSDavid van Moolenbroek 	}
266c58da9fbSDavid van Moolenbroek 
267c58da9fbSDavid van Moolenbroek 
268c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_SUBLIST)
269c58da9fbSDavid van Moolenbroek 	{
270c58da9fbSDavid van Moolenbroek 		fatal("do_scheduler: unexpected sublist at %s:%d",
271c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
272c58da9fbSDavid van Moolenbroek 	}
273c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_STRING)
274c58da9fbSDavid van Moolenbroek 	{
275c58da9fbSDavid van Moolenbroek 		fatal("do_scheduler: unexpected string at %s:%d",
276c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
277c58da9fbSDavid van Moolenbroek 	}
278c58da9fbSDavid van Moolenbroek 
279c58da9fbSDavid van Moolenbroek 	if(!strcmp(cpe->word, "KERNEL")) {
280c58da9fbSDavid van Moolenbroek 		scheduler_ep = KERNEL;
281c58da9fbSDavid van Moolenbroek 	}
282c58da9fbSDavid van Moolenbroek 	else {
283c58da9fbSDavid van Moolenbroek 		if((r = minix_rs_lookup(cpe->word, &scheduler_ep))) {
284c58da9fbSDavid van Moolenbroek 			fatal("do_scheduler: unknown scheduler %s at %s:%d",
285c58da9fbSDavid van Moolenbroek 			cpe->word, cpe->file, cpe->line);
286c58da9fbSDavid van Moolenbroek 		}
287c58da9fbSDavid van Moolenbroek 	}
288c58da9fbSDavid van Moolenbroek 
289c58da9fbSDavid van Moolenbroek 	rs_start->rss_scheduler= scheduler_ep;
290c58da9fbSDavid van Moolenbroek }
291c58da9fbSDavid van Moolenbroek 
do_priority(config_t * cpe,struct rs_start * rs_start)292c58da9fbSDavid van Moolenbroek static void do_priority(config_t *cpe, struct rs_start *rs_start)
293c58da9fbSDavid van Moolenbroek {
294c58da9fbSDavid van Moolenbroek 	int priority_val;
295c58da9fbSDavid van Moolenbroek 	char *check;
296c58da9fbSDavid van Moolenbroek 
297c58da9fbSDavid van Moolenbroek 	/* Process a priority value */
298c58da9fbSDavid van Moolenbroek 	if (cpe->next != NULL)
299c58da9fbSDavid van Moolenbroek 	{
300c58da9fbSDavid van Moolenbroek 		fatal("do_priority: just one priority value expected at %s:%d",
301c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
302c58da9fbSDavid van Moolenbroek 	}
303c58da9fbSDavid van Moolenbroek 
304c58da9fbSDavid van Moolenbroek 
305c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_SUBLIST)
306c58da9fbSDavid van Moolenbroek 	{
307c58da9fbSDavid van Moolenbroek 		fatal("do_priority: unexpected sublist at %s:%d",
308c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
309c58da9fbSDavid van Moolenbroek 	}
310c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_STRING)
311c58da9fbSDavid van Moolenbroek 	{
312c58da9fbSDavid van Moolenbroek 		fatal("do_priority: unexpected string at %s:%d",
313c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
314c58da9fbSDavid van Moolenbroek 	}
315c58da9fbSDavid van Moolenbroek 	priority_val= strtol(cpe->word, &check, 0);
316c58da9fbSDavid van Moolenbroek 	if (check[0] != '\0')
317c58da9fbSDavid van Moolenbroek 	{
318c58da9fbSDavid van Moolenbroek 		fatal("do_priority: bad priority value '%s' at %s:%d",
319c58da9fbSDavid van Moolenbroek 			cpe->word, cpe->file, cpe->line);
320c58da9fbSDavid van Moolenbroek 	}
321c58da9fbSDavid van Moolenbroek 
322c58da9fbSDavid van Moolenbroek 	if (priority_val < 0 || priority_val >= NR_SCHED_QUEUES)
323c58da9fbSDavid van Moolenbroek 	{
324c58da9fbSDavid van Moolenbroek 		fatal("do_priority: priority %d out of range at %s:%d",
325c58da9fbSDavid van Moolenbroek 			priority_val, cpe->file, cpe->line);
326c58da9fbSDavid van Moolenbroek 	}
327c58da9fbSDavid van Moolenbroek 	rs_start->rss_priority= priority_val;
328c58da9fbSDavid van Moolenbroek }
329c58da9fbSDavid van Moolenbroek 
do_quantum(config_t * cpe,struct rs_start * rs_start)330c58da9fbSDavid van Moolenbroek static void do_quantum(config_t *cpe, struct rs_start *rs_start)
331c58da9fbSDavid van Moolenbroek {
332c58da9fbSDavid van Moolenbroek 	int quantum_val;
333c58da9fbSDavid van Moolenbroek 	char *check;
334c58da9fbSDavid van Moolenbroek 
335c58da9fbSDavid van Moolenbroek 	/* Process a quantum value */
336c58da9fbSDavid van Moolenbroek 	if (cpe->next != NULL)
337c58da9fbSDavid van Moolenbroek 	{
338c58da9fbSDavid van Moolenbroek 		fatal("do_quantum: just one quantum value expected at %s:%d",
339c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
340c58da9fbSDavid van Moolenbroek 	}
341c58da9fbSDavid van Moolenbroek 
342c58da9fbSDavid van Moolenbroek 
343c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_SUBLIST)
344c58da9fbSDavid van Moolenbroek 	{
345c58da9fbSDavid van Moolenbroek 		fatal("do_quantum: unexpected sublist at %s:%d",
346c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
347c58da9fbSDavid van Moolenbroek 	}
348c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_STRING)
349c58da9fbSDavid van Moolenbroek 	{
350c58da9fbSDavid van Moolenbroek 		fatal("do_quantum: unexpected string at %s:%d",
351c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
352c58da9fbSDavid van Moolenbroek 	}
353c58da9fbSDavid van Moolenbroek 	quantum_val= strtol(cpe->word, &check, 0);
354c58da9fbSDavid van Moolenbroek 	if (check[0] != '\0')
355c58da9fbSDavid van Moolenbroek 	{
356c58da9fbSDavid van Moolenbroek 		fatal("do_quantum: bad quantum value '%s' at %s:%d",
357c58da9fbSDavid van Moolenbroek 			cpe->word, cpe->file, cpe->line);
358c58da9fbSDavid van Moolenbroek 	}
359c58da9fbSDavid van Moolenbroek 
360c58da9fbSDavid van Moolenbroek 	if (quantum_val <= 0)
361c58da9fbSDavid van Moolenbroek 	{
362c58da9fbSDavid van Moolenbroek 		fatal("do_quantum: quantum %d out of range at %s:%d",
363c58da9fbSDavid van Moolenbroek 			quantum_val, cpe->file, cpe->line);
364c58da9fbSDavid van Moolenbroek 	}
365c58da9fbSDavid van Moolenbroek 	rs_start->rss_quantum= quantum_val;
366c58da9fbSDavid van Moolenbroek }
367c58da9fbSDavid van Moolenbroek 
do_cpu(config_t * cpe,struct rs_start * rs_start)368c58da9fbSDavid van Moolenbroek static void do_cpu(config_t *cpe, struct rs_start *rs_start)
369c58da9fbSDavid van Moolenbroek {
370c58da9fbSDavid van Moolenbroek 	int cpu;
371c58da9fbSDavid van Moolenbroek 	char *check;
372c58da9fbSDavid van Moolenbroek 
373c58da9fbSDavid van Moolenbroek 	/* Process a quantum value */
374c58da9fbSDavid van Moolenbroek 	if (cpe->next != NULL)
375c58da9fbSDavid van Moolenbroek 	{
376c58da9fbSDavid van Moolenbroek 		fatal("do_cpu: just one value expected at %s:%d",
377c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
378c58da9fbSDavid van Moolenbroek 	}
379c58da9fbSDavid van Moolenbroek 
380c58da9fbSDavid van Moolenbroek 
381c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_SUBLIST)
382c58da9fbSDavid van Moolenbroek 	{
383c58da9fbSDavid van Moolenbroek 		fatal("do_cpu: unexpected sublist at %s:%d",
384c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
385c58da9fbSDavid van Moolenbroek 	}
386c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_STRING)
387c58da9fbSDavid van Moolenbroek 	{
388c58da9fbSDavid van Moolenbroek 		fatal("do_cpu: unexpected string at %s:%d",
389c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
390c58da9fbSDavid van Moolenbroek 	}
391c58da9fbSDavid van Moolenbroek 	cpu= strtol(cpe->word, &check, 0);
392c58da9fbSDavid van Moolenbroek 	if (check[0] != '\0')
393c58da9fbSDavid van Moolenbroek 	{
394c58da9fbSDavid van Moolenbroek 		fatal("do_cpu: bad value '%s' at %s:%d",
395c58da9fbSDavid van Moolenbroek 			cpe->word, cpe->file, cpe->line);
396c58da9fbSDavid van Moolenbroek 	}
397c58da9fbSDavid van Moolenbroek 
398c58da9fbSDavid van Moolenbroek 	if (cpu < 0)
399c58da9fbSDavid van Moolenbroek 	{
400c58da9fbSDavid van Moolenbroek 		fatal("do_cpu: %d out of range at %s:%d",
401c58da9fbSDavid van Moolenbroek 			cpu, cpe->file, cpe->line);
402c58da9fbSDavid van Moolenbroek 	}
403c58da9fbSDavid van Moolenbroek 	rs_start->rss_cpu= cpu;
404c58da9fbSDavid van Moolenbroek }
405c58da9fbSDavid van Moolenbroek 
do_irq(config_t * cpe,struct rs_start * rs_start)406c58da9fbSDavid van Moolenbroek static void do_irq(config_t *cpe, struct rs_start *rs_start)
407c58da9fbSDavid van Moolenbroek {
408c58da9fbSDavid van Moolenbroek 	int irq;
409c58da9fbSDavid van Moolenbroek 	int first;
410c58da9fbSDavid van Moolenbroek 	char *check;
411c58da9fbSDavid van Moolenbroek 
412c58da9fbSDavid van Moolenbroek 	/* Process a list of IRQs */
413c58da9fbSDavid van Moolenbroek 	first = TRUE;
414c58da9fbSDavid van Moolenbroek 	for (; cpe; cpe= cpe->next)
415c58da9fbSDavid van Moolenbroek 	{
416c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_SUBLIST)
417c58da9fbSDavid van Moolenbroek 		{
418c58da9fbSDavid van Moolenbroek 			fatal("do_irq: unexpected sublist at %s:%d",
419c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
420c58da9fbSDavid van Moolenbroek 		}
421c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_STRING)
422c58da9fbSDavid van Moolenbroek 		{
423c58da9fbSDavid van Moolenbroek 			fatal("do_irq: unexpected string at %s:%d",
424c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
425c58da9fbSDavid van Moolenbroek 		}
426c58da9fbSDavid van Moolenbroek 
427c58da9fbSDavid van Moolenbroek 		/* No IRQ allowed? (default) */
428c58da9fbSDavid van Moolenbroek 		if(!strcmp(cpe->word, KW_NONE)) {
429c58da9fbSDavid van Moolenbroek 			if(!first || cpe->next) {
430c58da9fbSDavid van Moolenbroek 				fatal("do_irq: %s keyword not allowed in list",
431c58da9fbSDavid van Moolenbroek 				KW_NONE);
432c58da9fbSDavid van Moolenbroek 			}
433c58da9fbSDavid van Moolenbroek 			break;
434c58da9fbSDavid van Moolenbroek 		}
435c58da9fbSDavid van Moolenbroek 
436c58da9fbSDavid van Moolenbroek 		/* All IRQs are allowed? */
437c58da9fbSDavid van Moolenbroek 		if(!strcmp(cpe->word, KW_ALL)) {
438c58da9fbSDavid van Moolenbroek 			if(!first || cpe->next) {
439c58da9fbSDavid van Moolenbroek 				fatal("do_irq: %s keyword not allowed in list",
440c58da9fbSDavid van Moolenbroek 				KW_ALL);
441c58da9fbSDavid van Moolenbroek 			}
442c58da9fbSDavid van Moolenbroek 			rs_start->rss_nr_irq = RSS_IO_ALL;
443c58da9fbSDavid van Moolenbroek 			break;
444c58da9fbSDavid van Moolenbroek 		}
445c58da9fbSDavid van Moolenbroek 
446c58da9fbSDavid van Moolenbroek 		/* Set single IRQs as specified in the configuration. */
447c58da9fbSDavid van Moolenbroek 		irq= strtoul(cpe->word, &check, 0);
448c58da9fbSDavid van Moolenbroek 		if (check[0] != '\0')
449c58da9fbSDavid van Moolenbroek 		{
450c58da9fbSDavid van Moolenbroek 			fatal("do_irq: bad irq '%s' at %s:%d",
451c58da9fbSDavid van Moolenbroek 				cpe->word, cpe->file, cpe->line);
452c58da9fbSDavid van Moolenbroek 		}
453c58da9fbSDavid van Moolenbroek 		if (rs_start->rss_nr_irq >= RSS_NR_IRQ)
454c58da9fbSDavid van Moolenbroek 			fatal("do_irq: too many IRQs (max %d)", RSS_NR_IRQ);
455c58da9fbSDavid van Moolenbroek 		rs_start->rss_irq[rs_start->rss_nr_irq]= irq;
456c58da9fbSDavid van Moolenbroek 		rs_start->rss_nr_irq++;
457c58da9fbSDavid van Moolenbroek 		first = FALSE;
458c58da9fbSDavid van Moolenbroek 	}
459c58da9fbSDavid van Moolenbroek }
460c58da9fbSDavid van Moolenbroek 
do_io(config_t * cpe,struct rs_start * rs_start)461c58da9fbSDavid van Moolenbroek static void do_io(config_t *cpe, struct rs_start *rs_start)
462c58da9fbSDavid van Moolenbroek {
463c58da9fbSDavid van Moolenbroek 	unsigned base, len;
464c58da9fbSDavid van Moolenbroek 	int first;
465c58da9fbSDavid van Moolenbroek 	char *check;
466c58da9fbSDavid van Moolenbroek 
467c58da9fbSDavid van Moolenbroek 	/* Process a list of I/O ranges */
468c58da9fbSDavid van Moolenbroek 	first = TRUE;
469c58da9fbSDavid van Moolenbroek 	for (; cpe; cpe= cpe->next)
470c58da9fbSDavid van Moolenbroek 	{
471c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_SUBLIST)
472c58da9fbSDavid van Moolenbroek 		{
473c58da9fbSDavid van Moolenbroek 			fatal("do_io: unexpected sublist at %s:%d",
474c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
475c58da9fbSDavid van Moolenbroek 		}
476c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_STRING)
477c58da9fbSDavid van Moolenbroek 		{
478c58da9fbSDavid van Moolenbroek 			fatal("do_io: unexpected string at %s:%d",
479c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
480c58da9fbSDavid van Moolenbroek 		}
481c58da9fbSDavid van Moolenbroek 
482c58da9fbSDavid van Moolenbroek 		/* No range allowed? (default) */
483c58da9fbSDavid van Moolenbroek 		if(!strcmp(cpe->word, KW_NONE)) {
484c58da9fbSDavid van Moolenbroek 			if(!first || cpe->next) {
485c58da9fbSDavid van Moolenbroek 				fatal("do_io: %s keyword not allowed in list",
486c58da9fbSDavid van Moolenbroek 				KW_NONE);
487c58da9fbSDavid van Moolenbroek 			}
488c58da9fbSDavid van Moolenbroek 			break;
489c58da9fbSDavid van Moolenbroek 		}
490c58da9fbSDavid van Moolenbroek 
491c58da9fbSDavid van Moolenbroek 		/* All ranges are allowed? */
492c58da9fbSDavid van Moolenbroek 		if(!strcmp(cpe->word, KW_ALL)) {
493c58da9fbSDavid van Moolenbroek 			if(!first || cpe->next) {
494c58da9fbSDavid van Moolenbroek 				fatal("do_io: %s keyword not allowed in list",
495c58da9fbSDavid van Moolenbroek 				KW_ALL);
496c58da9fbSDavid van Moolenbroek 			}
497c58da9fbSDavid van Moolenbroek 			rs_start->rss_nr_io = RSS_IO_ALL;
498c58da9fbSDavid van Moolenbroek 			break;
499c58da9fbSDavid van Moolenbroek 		}
500c58da9fbSDavid van Moolenbroek 
501c58da9fbSDavid van Moolenbroek 		/* Set single ranges as specified in the configuration. */
502c58da9fbSDavid van Moolenbroek 		base= strtoul(cpe->word, &check, 0x10);
503c58da9fbSDavid van Moolenbroek 		len= 1;
504c58da9fbSDavid van Moolenbroek 		if (check[0] == ':')
505c58da9fbSDavid van Moolenbroek 		{
506c58da9fbSDavid van Moolenbroek 			len= strtoul(check+1, &check, 0x10);
507c58da9fbSDavid van Moolenbroek 		}
508c58da9fbSDavid van Moolenbroek 		if (check[0] != '\0')
509c58da9fbSDavid van Moolenbroek 		{
510c58da9fbSDavid van Moolenbroek 			fatal("do_io: bad I/O range '%s' at %s:%d",
511c58da9fbSDavid van Moolenbroek 				cpe->word, cpe->file, cpe->line);
512c58da9fbSDavid van Moolenbroek 		}
513c58da9fbSDavid van Moolenbroek 
514c58da9fbSDavid van Moolenbroek 		if (rs_start->rss_nr_io >= RSS_NR_IO)
515c58da9fbSDavid van Moolenbroek 			fatal("do_io: too many I/O ranges (max %d)", RSS_NR_IO);
516c58da9fbSDavid van Moolenbroek 		rs_start->rss_io[rs_start->rss_nr_io].base= base;
517c58da9fbSDavid van Moolenbroek 		rs_start->rss_io[rs_start->rss_nr_io].len= len;
518c58da9fbSDavid van Moolenbroek 		rs_start->rss_nr_io++;
519c58da9fbSDavid van Moolenbroek 		first = FALSE;
520c58da9fbSDavid van Moolenbroek 	}
521c58da9fbSDavid van Moolenbroek }
522c58da9fbSDavid van Moolenbroek 
do_pci_device(config_t * cpe,struct rs_start * rs_start)523c58da9fbSDavid van Moolenbroek static void do_pci_device(config_t *cpe, struct rs_start *rs_start)
524c58da9fbSDavid van Moolenbroek {
525c58da9fbSDavid van Moolenbroek 	u16_t vid, did, sub_vid, sub_did;
526c58da9fbSDavid van Moolenbroek 	char *check, *check2;
527c58da9fbSDavid van Moolenbroek 
528c58da9fbSDavid van Moolenbroek 	/* Process a list of PCI device IDs */
529c58da9fbSDavid van Moolenbroek 	for (; cpe; cpe= cpe->next)
530c58da9fbSDavid van Moolenbroek 	{
531c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_SUBLIST)
532c58da9fbSDavid van Moolenbroek 		{
533c58da9fbSDavid van Moolenbroek 			fatal("do_pci_device: unexpected sublist at %s:%d",
534c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
535c58da9fbSDavid van Moolenbroek 		}
536c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_STRING)
537c58da9fbSDavid van Moolenbroek 		{
538c58da9fbSDavid van Moolenbroek 			fatal("do_pci_device: unexpected string at %s:%d",
539c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
540c58da9fbSDavid van Moolenbroek 		}
541c58da9fbSDavid van Moolenbroek 		vid= strtoul(cpe->word, &check, 0x10);
542c58da9fbSDavid van Moolenbroek 		if (check[0] != ':' && /* LEGACY: */ check[0] != '/') {
543c58da9fbSDavid van Moolenbroek 			fatal("do_pci_device: bad ID '%s' at %s:%d",
544c58da9fbSDavid van Moolenbroek 				cpe->word, cpe->file, cpe->line);
545c58da9fbSDavid van Moolenbroek 		}
546c58da9fbSDavid van Moolenbroek 		did= strtoul(check+1, &check, 0x10);
547c58da9fbSDavid van Moolenbroek 		if (check[0] == '/') {
548c58da9fbSDavid van Moolenbroek 			sub_vid= strtoul(check+1, &check, 0x10);
549c58da9fbSDavid van Moolenbroek 			if (check[0] == ':')
550c58da9fbSDavid van Moolenbroek 				sub_did= strtoul(check+1, &check2, 0x10);
551c58da9fbSDavid van Moolenbroek 			if (check[0] != ':' || check2[0] != '\0') {
552c58da9fbSDavid van Moolenbroek 				fatal("do_pci_device: bad ID '%s' at %s:%d",
553c58da9fbSDavid van Moolenbroek 					cpe->word, cpe->file, cpe->line);
554c58da9fbSDavid van Moolenbroek 			}
555c58da9fbSDavid van Moolenbroek 		} else if (check[0] != '\0') {
556c58da9fbSDavid van Moolenbroek 			fatal("do_pci_device: bad ID '%s' at %s:%d",
557c58da9fbSDavid van Moolenbroek 				cpe->word, cpe->file, cpe->line);
558c58da9fbSDavid van Moolenbroek 		} else {
559c58da9fbSDavid van Moolenbroek 			sub_vid = NO_SUB_VID;
560c58da9fbSDavid van Moolenbroek 			sub_did = NO_SUB_DID;
561c58da9fbSDavid van Moolenbroek 		}
562c58da9fbSDavid van Moolenbroek 		if (rs_start->rss_nr_pci_id >= RS_NR_PCI_DEVICE)
563c58da9fbSDavid van Moolenbroek 		{
564c58da9fbSDavid van Moolenbroek 			fatal("do_pci_device: too many device IDs (max %d)",
565c58da9fbSDavid van Moolenbroek 				RS_NR_PCI_DEVICE);
566c58da9fbSDavid van Moolenbroek 		}
567c58da9fbSDavid van Moolenbroek 		rs_start->rss_pci_id[rs_start->rss_nr_pci_id].vid= vid;
568c58da9fbSDavid van Moolenbroek 		rs_start->rss_pci_id[rs_start->rss_nr_pci_id].did= did;
569c58da9fbSDavid van Moolenbroek 		rs_start->rss_pci_id[rs_start->rss_nr_pci_id].sub_vid= sub_vid;
570c58da9fbSDavid van Moolenbroek 		rs_start->rss_pci_id[rs_start->rss_nr_pci_id].sub_did= sub_did;
571c58da9fbSDavid van Moolenbroek 		rs_start->rss_nr_pci_id++;
572c58da9fbSDavid van Moolenbroek 	}
573c58da9fbSDavid van Moolenbroek }
574c58da9fbSDavid van Moolenbroek 
do_pci_class(config_t * cpe,struct rs_start * rs_start)575c58da9fbSDavid van Moolenbroek static void do_pci_class(config_t *cpe, struct rs_start *rs_start)
576c58da9fbSDavid van Moolenbroek {
577c58da9fbSDavid van Moolenbroek 	u8_t baseclass, subclass, interface;
578c58da9fbSDavid van Moolenbroek 	u32_t class_id, mask;
579c58da9fbSDavid van Moolenbroek 	char *check;
580c58da9fbSDavid van Moolenbroek 
581c58da9fbSDavid van Moolenbroek 	/* Process a list of PCI device class IDs */
582c58da9fbSDavid van Moolenbroek 	for (; cpe; cpe= cpe->next)
583c58da9fbSDavid van Moolenbroek 	{
584c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_SUBLIST)
585c58da9fbSDavid van Moolenbroek 		{
586c58da9fbSDavid van Moolenbroek 			fatal("do_pci_device: unexpected sublist at %s:%d",
587c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
588c58da9fbSDavid van Moolenbroek 		}
589c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_STRING)
590c58da9fbSDavid van Moolenbroek 		{
591c58da9fbSDavid van Moolenbroek 			fatal("do_pci_device: unexpected string at %s:%d",
592c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
593c58da9fbSDavid van Moolenbroek 		}
594c58da9fbSDavid van Moolenbroek 
595c58da9fbSDavid van Moolenbroek 		baseclass= strtoul(cpe->word, &check, 0x10);
596c58da9fbSDavid van Moolenbroek 		subclass= 0;
597c58da9fbSDavid van Moolenbroek 		interface= 0;
598c58da9fbSDavid van Moolenbroek 		mask= 0xff0000;
599c58da9fbSDavid van Moolenbroek 		if (check[0] == '/')
600c58da9fbSDavid van Moolenbroek 		{
601c58da9fbSDavid van Moolenbroek 			subclass= strtoul(check+1, &check, 0x10);
602c58da9fbSDavid van Moolenbroek 			mask= 0xffff00;
603c58da9fbSDavid van Moolenbroek 			if (check[0] == '/')
604c58da9fbSDavid van Moolenbroek 			{
605c58da9fbSDavid van Moolenbroek 				interface= strtoul(check+1, &check, 0x10);
606c58da9fbSDavid van Moolenbroek 				mask= 0xffffff;
607c58da9fbSDavid van Moolenbroek 			}
608c58da9fbSDavid van Moolenbroek 		}
609c58da9fbSDavid van Moolenbroek 
610c58da9fbSDavid van Moolenbroek 		if (check[0] != '\0')
611c58da9fbSDavid van Moolenbroek 		{
612c58da9fbSDavid van Moolenbroek 			fatal("do_pci_class: bad class ID '%s' at %s:%d",
613c58da9fbSDavid van Moolenbroek 				cpe->word, cpe->file, cpe->line);
614c58da9fbSDavid van Moolenbroek 		}
615c58da9fbSDavid van Moolenbroek 		class_id= (baseclass << 16) | (subclass << 8) | interface;
616c58da9fbSDavid van Moolenbroek 		if (rs_start->rss_nr_pci_class >= RS_NR_PCI_CLASS)
617c58da9fbSDavid van Moolenbroek 		{
618c58da9fbSDavid van Moolenbroek 			fatal("do_pci_class: too many class IDs (max %d)",
619c58da9fbSDavid van Moolenbroek 				RS_NR_PCI_CLASS);
620c58da9fbSDavid van Moolenbroek 		}
621c58da9fbSDavid van Moolenbroek 		rs_start->rss_pci_class[rs_start->rss_nr_pci_class].pciclass=
622c58da9fbSDavid van Moolenbroek 			class_id;
623c58da9fbSDavid van Moolenbroek 		rs_start->rss_pci_class[rs_start->rss_nr_pci_class].mask= mask;
624c58da9fbSDavid van Moolenbroek 		rs_start->rss_nr_pci_class++;
625c58da9fbSDavid van Moolenbroek 	}
626c58da9fbSDavid van Moolenbroek }
627c58da9fbSDavid van Moolenbroek 
do_pci(config_t * cpe,struct rs_start * rs_start)628c58da9fbSDavid van Moolenbroek static void do_pci(config_t *cpe, struct rs_start *rs_start)
629c58da9fbSDavid van Moolenbroek {
630c58da9fbSDavid van Moolenbroek 	if (cpe == NULL)
631c58da9fbSDavid van Moolenbroek 		return;	/* Empty PCI statement */
632c58da9fbSDavid van Moolenbroek 
633c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_SUBLIST)
634c58da9fbSDavid van Moolenbroek 	{
635c58da9fbSDavid van Moolenbroek 		fatal("do_pci: unexpected sublist at %s:%d",
636c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
637c58da9fbSDavid van Moolenbroek 	}
638c58da9fbSDavid van Moolenbroek 	if (cpe->flags & CFG_STRING)
639c58da9fbSDavid van Moolenbroek 	{
640c58da9fbSDavid van Moolenbroek 		fatal("do_pci: unexpected string at %s:%d",
641c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
642c58da9fbSDavid van Moolenbroek 	}
643c58da9fbSDavid van Moolenbroek 
644c58da9fbSDavid van Moolenbroek 	if (strcmp(cpe->word, KW_DEVICE) == 0)
645c58da9fbSDavid van Moolenbroek 	{
646c58da9fbSDavid van Moolenbroek 		do_pci_device(cpe->next, rs_start);
647c58da9fbSDavid van Moolenbroek 		return;
648c58da9fbSDavid van Moolenbroek 	}
649c58da9fbSDavid van Moolenbroek 	if (strcmp(cpe->word, KW_CLASS) == 0)
650c58da9fbSDavid van Moolenbroek 	{
651c58da9fbSDavid van Moolenbroek 		do_pci_class(cpe->next, rs_start);
652c58da9fbSDavid van Moolenbroek 		return;
653c58da9fbSDavid van Moolenbroek 	}
654c58da9fbSDavid van Moolenbroek 	fatal("do_pci: unexpected word '%s' at %s:%d",
655c58da9fbSDavid van Moolenbroek 		cpe->word, cpe->file, cpe->line);
656c58da9fbSDavid van Moolenbroek }
657c58da9fbSDavid van Moolenbroek 
do_ipc(config_t * cpe,struct rs_start * rs_start)658c58da9fbSDavid van Moolenbroek static void do_ipc(config_t *cpe, struct rs_start *rs_start)
659c58da9fbSDavid van Moolenbroek {
660c58da9fbSDavid van Moolenbroek 	char *list;
661c58da9fbSDavid van Moolenbroek 	const char *word;
662c58da9fbSDavid van Moolenbroek 	char *word_all = RSS_IPC_ALL;
663c58da9fbSDavid van Moolenbroek 	char *word_all_sys = RSS_IPC_ALL_SYS;
664c58da9fbSDavid van Moolenbroek 	size_t listsize, wordlen;
665c58da9fbSDavid van Moolenbroek 	int first;
666c58da9fbSDavid van Moolenbroek 
667c58da9fbSDavid van Moolenbroek 	list= NULL;
668c58da9fbSDavid van Moolenbroek 	listsize= 1;
669c58da9fbSDavid van Moolenbroek 	list= malloc(listsize);
670c58da9fbSDavid van Moolenbroek 	if (list == NULL)
671c58da9fbSDavid van Moolenbroek 		fatal("do_ipc: unable to malloc %d bytes", listsize);
672c58da9fbSDavid van Moolenbroek 	list[0]= '\0';
673c58da9fbSDavid van Moolenbroek 
674c58da9fbSDavid van Moolenbroek 	/* Process a list of process names that are allowed to be
675c58da9fbSDavid van Moolenbroek 	 * contacted
676c58da9fbSDavid van Moolenbroek 	 */
677c58da9fbSDavid van Moolenbroek 	first = TRUE;
678c58da9fbSDavid van Moolenbroek 	for (; cpe; cpe= cpe->next)
679c58da9fbSDavid van Moolenbroek 	{
680c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_SUBLIST)
681c58da9fbSDavid van Moolenbroek 		{
682c58da9fbSDavid van Moolenbroek 			fatal("do_ipc: unexpected sublist at %s:%d",
683c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
684c58da9fbSDavid van Moolenbroek 		}
685c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_STRING)
686c58da9fbSDavid van Moolenbroek 		{
687c58da9fbSDavid van Moolenbroek 			fatal("do_ipc: unexpected string at %s:%d",
688c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
689c58da9fbSDavid van Moolenbroek 		}
690c58da9fbSDavid van Moolenbroek 		word = cpe->word;
691c58da9fbSDavid van Moolenbroek 
692c58da9fbSDavid van Moolenbroek 		/* All (system) ipc targets are allowed? */
693c58da9fbSDavid van Moolenbroek 		if(!strcmp(word, KW_ALL) || !strcmp(word, KW_ALL_SYS)) {
694c58da9fbSDavid van Moolenbroek 			if(!first || cpe->next) {
695c58da9fbSDavid van Moolenbroek 				fatal("do_ipc: %s keyword not allowed in list",
696c58da9fbSDavid van Moolenbroek 				word);
697c58da9fbSDavid van Moolenbroek 			}
698c58da9fbSDavid van Moolenbroek 			word = !strcmp(word, KW_ALL) ? word_all : word_all_sys;
699c58da9fbSDavid van Moolenbroek 		}
700c58da9fbSDavid van Moolenbroek 
701c58da9fbSDavid van Moolenbroek 		wordlen= strlen(word);
702c58da9fbSDavid van Moolenbroek 
703c58da9fbSDavid van Moolenbroek 		listsize += 1 + wordlen;
704c58da9fbSDavid van Moolenbroek 		list= realloc(list, listsize);
705c58da9fbSDavid van Moolenbroek 		if (list == NULL)
706c58da9fbSDavid van Moolenbroek 		{
707c58da9fbSDavid van Moolenbroek 			fatal("do_ipc: unable to realloc %d bytes",
708c58da9fbSDavid van Moolenbroek 				listsize);
709c58da9fbSDavid van Moolenbroek 		}
710c58da9fbSDavid van Moolenbroek 		strcat(list, " ");
711c58da9fbSDavid van Moolenbroek 		strcat(list, word);
712c58da9fbSDavid van Moolenbroek 		first = FALSE;
713c58da9fbSDavid van Moolenbroek 	}
714c58da9fbSDavid van Moolenbroek #if 0
715c58da9fbSDavid van Moolenbroek 	printf("do_ipc: got list '%s'\n", list);
716c58da9fbSDavid van Moolenbroek #endif
717c58da9fbSDavid van Moolenbroek 
718c58da9fbSDavid van Moolenbroek 	if (rs_start->rss_ipc)
719c58da9fbSDavid van Moolenbroek 		fatal("do_ipc: req_ipc is set");
720c58da9fbSDavid van Moolenbroek         rs_start->rss_ipc = list+1;
721c58da9fbSDavid van Moolenbroek 	rs_start->rss_ipclen= strlen(rs_start->rss_ipc);
722c58da9fbSDavid van Moolenbroek }
723c58da9fbSDavid van Moolenbroek 
724c58da9fbSDavid van Moolenbroek 
725c58da9fbSDavid van Moolenbroek struct
726c58da9fbSDavid van Moolenbroek {
727c58da9fbSDavid van Moolenbroek 	char *label;
728c58da9fbSDavid van Moolenbroek 	int call_nr;
729c58da9fbSDavid van Moolenbroek } vm_table[] =
730c58da9fbSDavid van Moolenbroek {
731c58da9fbSDavid van Moolenbroek 	{ "EXIT",		VM_EXIT },
732c58da9fbSDavid van Moolenbroek 	{ "FORK",		VM_FORK },
733c58da9fbSDavid van Moolenbroek 	{ "EXEC_NEWMEM",	VM_EXEC_NEWMEM },
734c58da9fbSDavid van Moolenbroek 	{ "PUSH_SIG",		0 },
735c58da9fbSDavid van Moolenbroek 	{ "WILLEXIT",		VM_WILLEXIT },
736c58da9fbSDavid van Moolenbroek 	{ "ADDDMA",		VM_ADDDMA },
737c58da9fbSDavid van Moolenbroek 	{ "DELDMA",		VM_DELDMA },
738c58da9fbSDavid van Moolenbroek 	{ "GETDMA",		VM_GETDMA },
739c58da9fbSDavid van Moolenbroek 	{ "REMAP",		VM_REMAP },
740c58da9fbSDavid van Moolenbroek 	{ "REMAP_RO",		VM_REMAP_RO },
741c58da9fbSDavid van Moolenbroek 	{ "SHM_UNMAP",		VM_SHM_UNMAP },
742c58da9fbSDavid van Moolenbroek 	{ "GETPHYS",		VM_GETPHYS },
743c58da9fbSDavid van Moolenbroek 	{ "GETREF",		VM_GETREF },
744c58da9fbSDavid van Moolenbroek 	{ "RS_SET_PRIV",	VM_RS_SET_PRIV },
745c58da9fbSDavid van Moolenbroek 	{ "INFO",		VM_INFO },
746c58da9fbSDavid van Moolenbroek 	{ "RS_UPDATE",		VM_RS_UPDATE },
747c58da9fbSDavid van Moolenbroek 	{ "RS_MEMCTL",		VM_RS_MEMCTL },
748c58da9fbSDavid van Moolenbroek 	{ "PROCCTL",		VM_PROCCTL },
749c58da9fbSDavid van Moolenbroek 	{ "MAPCACHEPAGE",	VM_MAPCACHEPAGE },
750c58da9fbSDavid van Moolenbroek 	{ "SETCACHEPAGE",	VM_SETCACHEPAGE },
751c58da9fbSDavid van Moolenbroek 	{ "FORGETCACHEPAGE",	VM_FORGETCACHEPAGE },
752c58da9fbSDavid van Moolenbroek 	{ "CLEARCACHE",		VM_CLEARCACHE },
753c58da9fbSDavid van Moolenbroek 	{ "VFS_MMAP",		VM_VFS_MMAP },
754c58da9fbSDavid van Moolenbroek 	{ "VFS_REPLY",		VM_VFS_REPLY },
755c58da9fbSDavid van Moolenbroek 	{ "GETRUSAGE",		VM_GETRUSAGE },
756c58da9fbSDavid van Moolenbroek 	{ "RS_PREPARE",		VM_RS_PREPARE },
757c58da9fbSDavid van Moolenbroek 	{ NULL,			0 },
758c58da9fbSDavid van Moolenbroek };
759c58da9fbSDavid van Moolenbroek 
do_vm(config_t * cpe,struct rs_start * rs_start)760c58da9fbSDavid van Moolenbroek static void do_vm(config_t *cpe, struct rs_start *rs_start)
761c58da9fbSDavid van Moolenbroek {
762c58da9fbSDavid van Moolenbroek 	int i, first;
763c58da9fbSDavid van Moolenbroek 
764c58da9fbSDavid van Moolenbroek 	first = TRUE;
765c58da9fbSDavid van Moolenbroek 	for (; cpe; cpe = cpe->next)
766c58da9fbSDavid van Moolenbroek 	{
767c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_SUBLIST)
768c58da9fbSDavid van Moolenbroek 		{
769c58da9fbSDavid van Moolenbroek 			fatal("do_vm: unexpected sublist at %s:%d",
770c58da9fbSDavid van Moolenbroek 			      cpe->file, cpe->line);
771c58da9fbSDavid van Moolenbroek 		}
772c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_STRING)
773c58da9fbSDavid van Moolenbroek 		{
774c58da9fbSDavid van Moolenbroek 			fatal("do_vm: unexpected string at %s:%d",
775c58da9fbSDavid van Moolenbroek 			      cpe->file, cpe->line);
776c58da9fbSDavid van Moolenbroek 		}
777c58da9fbSDavid van Moolenbroek 
778c58da9fbSDavid van Moolenbroek 		/* Only basic calls allowed? (default). */
779c58da9fbSDavid van Moolenbroek 		if(!strcmp(cpe->word, KW_BASIC)) {
780c58da9fbSDavid van Moolenbroek 			if(!first || cpe->next) {
781c58da9fbSDavid van Moolenbroek 				fatal("do_vm: %s keyword not allowed in list",
782c58da9fbSDavid van Moolenbroek 				KW_NONE);
783c58da9fbSDavid van Moolenbroek 			}
784c58da9fbSDavid van Moolenbroek 			break;
785c58da9fbSDavid van Moolenbroek 		}
786c58da9fbSDavid van Moolenbroek 
787c58da9fbSDavid van Moolenbroek 		/* No calls allowed? */
788c58da9fbSDavid van Moolenbroek 		if(!strcmp(cpe->word, KW_NONE)) {
789c58da9fbSDavid van Moolenbroek 			if(!first || cpe->next) {
790c58da9fbSDavid van Moolenbroek 				fatal("do_vm: %s keyword not allowed in list",
791c58da9fbSDavid van Moolenbroek 				KW_NONE);
792c58da9fbSDavid van Moolenbroek 			}
793c58da9fbSDavid van Moolenbroek 			rs_start->rss_flags &= ~RSS_VM_BASIC_CALLS;
794c58da9fbSDavid van Moolenbroek 			break;
795c58da9fbSDavid van Moolenbroek 		}
796c58da9fbSDavid van Moolenbroek 
797c58da9fbSDavid van Moolenbroek 		/* All calls are allowed? */
798c58da9fbSDavid van Moolenbroek 		if(!strcmp(cpe->word, KW_ALL)) {
799c58da9fbSDavid van Moolenbroek 			if(!first || cpe->next) {
800c58da9fbSDavid van Moolenbroek 				fatal("do_vm: %s keyword not allowed in list",
801c58da9fbSDavid van Moolenbroek 				KW_ALL);
802c58da9fbSDavid van Moolenbroek 			}
803c58da9fbSDavid van Moolenbroek 			for (i = 0; i < NR_VM_CALLS; i++)
804c58da9fbSDavid van Moolenbroek 				SET_BIT(rs_start->rss_vm, i);
805c58da9fbSDavid van Moolenbroek 			break;
806c58da9fbSDavid van Moolenbroek 		}
807c58da9fbSDavid van Moolenbroek 
808c58da9fbSDavid van Moolenbroek 		/* Set single calls as specified in the configuration. */
809c58da9fbSDavid van Moolenbroek 		for (i = 0; vm_table[i].label != NULL; i++)
810c58da9fbSDavid van Moolenbroek 			if (!strcmp(cpe->word, vm_table[i].label))
811c58da9fbSDavid van Moolenbroek 				break;
812c58da9fbSDavid van Moolenbroek 		if (vm_table[i].label == NULL) {
813c58da9fbSDavid van Moolenbroek 			warning("do_vm: ignoring unknown call '%s' at %s:%d",
814c58da9fbSDavid van Moolenbroek 				cpe->word, cpe->file, cpe->line);
815c58da9fbSDavid van Moolenbroek 		} else if(vm_table[i].call_nr) {
816c58da9fbSDavid van Moolenbroek 			SET_BIT(rs_start->rss_vm,
817c58da9fbSDavid van Moolenbroek 				vm_table[i].call_nr - VM_RQ_BASE);
818c58da9fbSDavid van Moolenbroek 		}
819c58da9fbSDavid van Moolenbroek 
820c58da9fbSDavid van Moolenbroek 		first = FALSE;
821c58da9fbSDavid van Moolenbroek 	}
822c58da9fbSDavid van Moolenbroek }
823c58da9fbSDavid van Moolenbroek 
824c58da9fbSDavid van Moolenbroek struct
825c58da9fbSDavid van Moolenbroek {
826c58da9fbSDavid van Moolenbroek 	char *label;
827c58da9fbSDavid van Moolenbroek 	int call_nr;
828c58da9fbSDavid van Moolenbroek } system_tab[]=
829c58da9fbSDavid van Moolenbroek {
830c58da9fbSDavid van Moolenbroek 	{ "PRIVCTL",		SYS_PRIVCTL },
831c58da9fbSDavid van Moolenbroek 	{ "TRACE",		SYS_TRACE },
832c58da9fbSDavid van Moolenbroek 	{ "KILL",		SYS_KILL },
833c58da9fbSDavid van Moolenbroek 	{ "UMAP",		SYS_UMAP },
834c58da9fbSDavid van Moolenbroek 	{ "VIRCOPY",		SYS_VIRCOPY },
835c58da9fbSDavid van Moolenbroek 	{ "PHYSCOPY",		SYS_PHYSCOPY },
836c58da9fbSDavid van Moolenbroek 	{ "UMAP_REMOTE",	SYS_UMAP_REMOTE },
837c58da9fbSDavid van Moolenbroek 	{ "VUMAP",		SYS_VUMAP },
838c58da9fbSDavid van Moolenbroek 	{ "IRQCTL",		SYS_IRQCTL },
839c58da9fbSDavid van Moolenbroek 	{ "DEVIO",		SYS_DEVIO },
840c58da9fbSDavid van Moolenbroek 	{ "SDEVIO",		SYS_SDEVIO },
841c58da9fbSDavid van Moolenbroek 	{ "VDEVIO",		SYS_VDEVIO },
842c58da9fbSDavid van Moolenbroek 	{ "ABORT",		SYS_ABORT },
843c58da9fbSDavid van Moolenbroek 	{ "IOPENABLE",		SYS_IOPENABLE },
844c58da9fbSDavid van Moolenbroek 	{ "READBIOS",		SYS_READBIOS },
845c58da9fbSDavid van Moolenbroek 	{ "STIME",		SYS_STIME },
846c58da9fbSDavid van Moolenbroek 	{ "VMCTL",		SYS_VMCTL },
847c58da9fbSDavid van Moolenbroek 	{ "MEMSET",		SYS_MEMSET },
848c58da9fbSDavid van Moolenbroek 	{ "PADCONF",		SYS_PADCONF },
849c58da9fbSDavid van Moolenbroek 	{ NULL,		0 }
850c58da9fbSDavid van Moolenbroek };
851c58da9fbSDavid van Moolenbroek 
do_system(config_t * cpe,struct rs_start * rs_start)852c58da9fbSDavid van Moolenbroek static void do_system(config_t *cpe, struct rs_start *rs_start)
853c58da9fbSDavid van Moolenbroek {
854c58da9fbSDavid van Moolenbroek 	int i, first;
855c58da9fbSDavid van Moolenbroek 
856c58da9fbSDavid van Moolenbroek 	/* Process a list of 'system' calls that are allowed */
857c58da9fbSDavid van Moolenbroek 	first = TRUE;
858c58da9fbSDavid van Moolenbroek 	for (; cpe; cpe= cpe->next)
859c58da9fbSDavid van Moolenbroek 	{
860c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_SUBLIST)
861c58da9fbSDavid van Moolenbroek 		{
862c58da9fbSDavid van Moolenbroek 			fatal("do_system: unexpected sublist at %s:%d",
863c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
864c58da9fbSDavid van Moolenbroek 		}
865c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_STRING)
866c58da9fbSDavid van Moolenbroek 		{
867c58da9fbSDavid van Moolenbroek 			fatal("do_system: unexpected string at %s:%d",
868c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
869c58da9fbSDavid van Moolenbroek 		}
870c58da9fbSDavid van Moolenbroek 
871c58da9fbSDavid van Moolenbroek 		/* Only basic calls allowed? (default). */
872c58da9fbSDavid van Moolenbroek 		if(!strcmp(cpe->word, KW_BASIC)) {
873c58da9fbSDavid van Moolenbroek 			if(!first || cpe->next) {
874c58da9fbSDavid van Moolenbroek 				fatal("do_system: %s keyword not allowed in list",
875c58da9fbSDavid van Moolenbroek 				KW_NONE);
876c58da9fbSDavid van Moolenbroek 			}
877c58da9fbSDavid van Moolenbroek 			break;
878c58da9fbSDavid van Moolenbroek 		}
879c58da9fbSDavid van Moolenbroek 
880c58da9fbSDavid van Moolenbroek 		/* No calls allowed? */
881c58da9fbSDavid van Moolenbroek 		if(!strcmp(cpe->word, KW_NONE)) {
882c58da9fbSDavid van Moolenbroek 			if(!first || cpe->next) {
883c58da9fbSDavid van Moolenbroek 				fatal("do_system: %s keyword not allowed in list",
884c58da9fbSDavid van Moolenbroek 				KW_NONE);
885c58da9fbSDavid van Moolenbroek 			}
886c58da9fbSDavid van Moolenbroek 			rs_start->rss_flags &= ~RSS_SYS_BASIC_CALLS;
887c58da9fbSDavid van Moolenbroek 			break;
888c58da9fbSDavid van Moolenbroek 		}
889c58da9fbSDavid van Moolenbroek 
890c58da9fbSDavid van Moolenbroek 		/* All calls are allowed? */
891c58da9fbSDavid van Moolenbroek 		if(!strcmp(cpe->word, KW_ALL)) {
892c58da9fbSDavid van Moolenbroek 			if(!first || cpe->next) {
893c58da9fbSDavid van Moolenbroek 				fatal("do_system: %s keyword not allowed in list",
894c58da9fbSDavid van Moolenbroek 				KW_ALL);
895c58da9fbSDavid van Moolenbroek 			}
896c58da9fbSDavid van Moolenbroek 			for (i = 0; i < NR_SYS_CALLS; i++)
897c58da9fbSDavid van Moolenbroek 				SET_BIT(rs_start->rss_system, i);
898c58da9fbSDavid van Moolenbroek 			break;
899c58da9fbSDavid van Moolenbroek 		}
900c58da9fbSDavid van Moolenbroek 
901c58da9fbSDavid van Moolenbroek 		/* Set single calls as specified in the configuration. */
902c58da9fbSDavid van Moolenbroek 		for (i = 0; system_tab[i].label != NULL; i++)
903c58da9fbSDavid van Moolenbroek 			if (!strcmp(cpe->word, system_tab[i].label))
904c58da9fbSDavid van Moolenbroek 				break;
905c58da9fbSDavid van Moolenbroek 		if (system_tab[i].label == NULL) {
906c58da9fbSDavid van Moolenbroek 		   warning("do_system: ignoring unknown call '%s' at %s:%d",
907c58da9fbSDavid van Moolenbroek 				cpe->word, cpe->file, cpe->line);
908c58da9fbSDavid van Moolenbroek 		} else {
909c58da9fbSDavid van Moolenbroek 			SET_BIT(rs_start->rss_system,
910c58da9fbSDavid van Moolenbroek 				system_tab[i].call_nr - KERNEL_CALL);
911c58da9fbSDavid van Moolenbroek 		}
912c58da9fbSDavid van Moolenbroek 		first = FALSE;
913c58da9fbSDavid van Moolenbroek 	}
914c58da9fbSDavid van Moolenbroek }
915c58da9fbSDavid van Moolenbroek 
do_control(config_t * cpe,struct rs_start * rs_start)916c58da9fbSDavid van Moolenbroek static void do_control(config_t *cpe, struct rs_start *rs_start)
917c58da9fbSDavid van Moolenbroek {
918c58da9fbSDavid van Moolenbroek 	int nr_control = 0;
919c58da9fbSDavid van Moolenbroek 
920c58da9fbSDavid van Moolenbroek 	/* Process a list of 'control' labels. */
921c58da9fbSDavid van Moolenbroek 	for (; cpe; cpe= cpe->next)
922c58da9fbSDavid van Moolenbroek 	{
923c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_SUBLIST)
924c58da9fbSDavid van Moolenbroek 		{
925c58da9fbSDavid van Moolenbroek 			fatal("do_control: unexpected sublist at %s:%d",
926c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
927c58da9fbSDavid van Moolenbroek 		}
928c58da9fbSDavid van Moolenbroek 		if (cpe->flags & CFG_STRING)
929c58da9fbSDavid van Moolenbroek 		{
930c58da9fbSDavid van Moolenbroek 			fatal("do_control: unexpected string at %s:%d",
931c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
932c58da9fbSDavid van Moolenbroek 		}
933c58da9fbSDavid van Moolenbroek 		if (nr_control >= RS_NR_CONTROL)
934c58da9fbSDavid van Moolenbroek 		{
935c58da9fbSDavid van Moolenbroek 			fatal(
936c58da9fbSDavid van Moolenbroek 			"do_control: RS_NR_CONTROL is too small (%d needed)",
937c58da9fbSDavid van Moolenbroek 				nr_control+1);
938c58da9fbSDavid van Moolenbroek 		}
939c58da9fbSDavid van Moolenbroek 
940c58da9fbSDavid van Moolenbroek 		rs_start->rss_control[nr_control].l_addr = (char*) cpe->word;
941c58da9fbSDavid van Moolenbroek 		rs_start->rss_control[nr_control].l_len = strlen(cpe->word);
942c58da9fbSDavid van Moolenbroek 		rs_start->rss_nr_control = ++nr_control;
943c58da9fbSDavid van Moolenbroek 	}
944c58da9fbSDavid van Moolenbroek }
945c58da9fbSDavid van Moolenbroek 
946*181fb1b2SDavid van Moolenbroek static const struct {
947*181fb1b2SDavid van Moolenbroek 	const char *name;
948*181fb1b2SDavid van Moolenbroek 	int domain;
949*181fb1b2SDavid van Moolenbroek } domain_tab[] = {
950*181fb1b2SDavid van Moolenbroek 	/* PF_UNSPEC should not be in this table. */
951*181fb1b2SDavid van Moolenbroek 	{ "LOCAL",	PF_LOCAL	},
952*181fb1b2SDavid van Moolenbroek 	{ "INET",	PF_INET		},
953*181fb1b2SDavid van Moolenbroek 	{ "IMPLINK",	PF_IMPLINK	},
954*181fb1b2SDavid van Moolenbroek 	{ "PUP",	PF_PUP		},
955*181fb1b2SDavid van Moolenbroek 	{ "CHAOS",	PF_CHAOS	},
956*181fb1b2SDavid van Moolenbroek 	{ "NS",		PF_NS		},
957*181fb1b2SDavid van Moolenbroek 	{ "ISO",	PF_ISO		},
958*181fb1b2SDavid van Moolenbroek 	{ "ECMA",	PF_ECMA		},
959*181fb1b2SDavid van Moolenbroek 	{ "DATAKIT",	PF_DATAKIT	},
960*181fb1b2SDavid van Moolenbroek 	{ "CCITT",	PF_CCITT	},
961*181fb1b2SDavid van Moolenbroek 	{ "SNA",	PF_SNA		},
962*181fb1b2SDavid van Moolenbroek 	{ "DECnet",	PF_DECnet	},
963*181fb1b2SDavid van Moolenbroek 	{ "DLI",	PF_DLI		},
964*181fb1b2SDavid van Moolenbroek 	{ "LAT",	PF_LAT		},
965*181fb1b2SDavid van Moolenbroek 	{ "HYLINK",	PF_HYLINK	},
966*181fb1b2SDavid van Moolenbroek 	{ "APPLETALK",	PF_APPLETALK	},
967*181fb1b2SDavid van Moolenbroek 	{ "OROUTE",	PF_OROUTE	},
968*181fb1b2SDavid van Moolenbroek 	{ "LINK",	PF_LINK		},
969*181fb1b2SDavid van Moolenbroek 	{ "XTP",	PF_XTP		},
970*181fb1b2SDavid van Moolenbroek 	{ "COIP",	PF_COIP		},
971*181fb1b2SDavid van Moolenbroek 	{ "CNT",	PF_CNT		},
972*181fb1b2SDavid van Moolenbroek 	{ "RTIP",	PF_RTIP		},
973*181fb1b2SDavid van Moolenbroek 	{ "IPX",	PF_IPX		},
974*181fb1b2SDavid van Moolenbroek 	{ "INET6",	PF_INET6	},
975*181fb1b2SDavid van Moolenbroek 	{ "PIP",	PF_PIP		},
976*181fb1b2SDavid van Moolenbroek 	{ "ISDN",	PF_ISDN		},
977*181fb1b2SDavid van Moolenbroek 	{ "NATM",	PF_NATM		},
978*181fb1b2SDavid van Moolenbroek 	{ "ARP",	PF_ARP		},
979*181fb1b2SDavid van Moolenbroek 	{ "KEY",	PF_KEY		},
980*181fb1b2SDavid van Moolenbroek 	{ "BLUETOOTH",	PF_BLUETOOTH	},
981*181fb1b2SDavid van Moolenbroek 	/* There is no PF_IEEE80211. */
982*181fb1b2SDavid van Moolenbroek 	{ "MPLS",	PF_MPLS		},
983*181fb1b2SDavid van Moolenbroek 	{ "ROUTE",	PF_ROUTE	},
984*181fb1b2SDavid van Moolenbroek };
985*181fb1b2SDavid van Moolenbroek 
986*181fb1b2SDavid van Moolenbroek /*
987*181fb1b2SDavid van Moolenbroek  * Process a list of 'domain' protocol families for socket drivers.
988*181fb1b2SDavid van Moolenbroek  */
989*181fb1b2SDavid van Moolenbroek static void
do_domain(config_t * cpe,struct rs_start * rs_start)990*181fb1b2SDavid van Moolenbroek do_domain(config_t * cpe, struct rs_start * rs_start)
991*181fb1b2SDavid van Moolenbroek {
992*181fb1b2SDavid van Moolenbroek 	unsigned int i;
993*181fb1b2SDavid van Moolenbroek 	int nr_domain, domain;
994*181fb1b2SDavid van Moolenbroek 
995*181fb1b2SDavid van Moolenbroek 	for (nr_domain = 0; cpe != NULL; cpe = cpe->next) {
996*181fb1b2SDavid van Moolenbroek 		if (cpe->flags & CFG_SUBLIST) {
997*181fb1b2SDavid van Moolenbroek 			fatal("do_domain: unexpected sublist at %s:%d",
998*181fb1b2SDavid van Moolenbroek 			    cpe->file, cpe->line);
999*181fb1b2SDavid van Moolenbroek 		}
1000*181fb1b2SDavid van Moolenbroek 		if (cpe->flags & CFG_STRING) {
1001*181fb1b2SDavid van Moolenbroek 			fatal("do_domain: unexpected string at %s:%d",
1002*181fb1b2SDavid van Moolenbroek 			    cpe->file, cpe->line);
1003*181fb1b2SDavid van Moolenbroek 		}
1004*181fb1b2SDavid van Moolenbroek 		if (nr_domain >= __arraycount(rs_start->rss_domain)) {
1005*181fb1b2SDavid van Moolenbroek 			fatal("do_domain: NR_DOMAIN is too small (%d needed)",
1006*181fb1b2SDavid van Moolenbroek 			    nr_domain + 1);
1007*181fb1b2SDavid van Moolenbroek 		}
1008*181fb1b2SDavid van Moolenbroek 
1009*181fb1b2SDavid van Moolenbroek 		for (i = 0; i < __arraycount(domain_tab); i++)
1010*181fb1b2SDavid van Moolenbroek 			if (!strcmp(domain_tab[i].name, (char *)cpe->word))
1011*181fb1b2SDavid van Moolenbroek 				break;
1012*181fb1b2SDavid van Moolenbroek 		if (i < __arraycount(domain_tab))
1013*181fb1b2SDavid van Moolenbroek 			domain = domain_tab[i].domain;
1014*181fb1b2SDavid van Moolenbroek 		else
1015*181fb1b2SDavid van Moolenbroek 			domain = atoi((char *)cpe->word);
1016*181fb1b2SDavid van Moolenbroek 
1017*181fb1b2SDavid van Moolenbroek 		if (domain <= 0 || domain >= PF_MAX) {
1018*181fb1b2SDavid van Moolenbroek 			fatal("do_domain: unknown domain %s at %s:%d",
1019*181fb1b2SDavid van Moolenbroek 			    (char *)cpe->word, cpe->file, cpe->line);
1020*181fb1b2SDavid van Moolenbroek 		}
1021*181fb1b2SDavid van Moolenbroek 
1022*181fb1b2SDavid van Moolenbroek 		rs_start->rss_domain[nr_domain] = domain;
1023*181fb1b2SDavid van Moolenbroek 		rs_start->rss_nr_domain = ++nr_domain;
1024*181fb1b2SDavid van Moolenbroek 	}
1025*181fb1b2SDavid van Moolenbroek }
1026*181fb1b2SDavid van Moolenbroek 
do_service(config_t * cpe,config_t * config,struct rs_config * rs_config)1027c58da9fbSDavid van Moolenbroek static void do_service(config_t *cpe, config_t *config, struct rs_config *rs_config)
1028c58da9fbSDavid van Moolenbroek {
1029c58da9fbSDavid van Moolenbroek 	struct rs_start *rs_start = &rs_config->rs_start;
1030c58da9fbSDavid van Moolenbroek 	config_t *cp;
1031c58da9fbSDavid van Moolenbroek 
1032c58da9fbSDavid van Moolenbroek 	/* At this point we expect one sublist that contains the varios
1033c58da9fbSDavid van Moolenbroek 	 * resource allocations
1034c58da9fbSDavid van Moolenbroek 	 */
1035c58da9fbSDavid van Moolenbroek 	if (!(cpe->flags & CFG_SUBLIST))
1036c58da9fbSDavid van Moolenbroek 	{
1037c58da9fbSDavid van Moolenbroek 		fatal("do_service: expected list at %s:%d",
1038c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
1039c58da9fbSDavid van Moolenbroek 	}
1040c58da9fbSDavid van Moolenbroek 	if (cpe->next != NULL)
1041c58da9fbSDavid van Moolenbroek 	{
1042c58da9fbSDavid van Moolenbroek 		cpe= cpe->next;
1043c58da9fbSDavid van Moolenbroek 		fatal("do_service: expected end of list at %s:%d",
1044c58da9fbSDavid van Moolenbroek 			cpe->file, cpe->line);
1045c58da9fbSDavid van Moolenbroek 	}
1046c58da9fbSDavid van Moolenbroek 	cpe= cpe->list;
1047c58da9fbSDavid van Moolenbroek 
1048c58da9fbSDavid van Moolenbroek 	/* Process the list */
1049c58da9fbSDavid van Moolenbroek 	for (cp= cpe; cp; cp= cp->next)
1050c58da9fbSDavid van Moolenbroek 	{
1051c58da9fbSDavid van Moolenbroek 		if (!(cp->flags & CFG_SUBLIST))
1052c58da9fbSDavid van Moolenbroek 		{
1053c58da9fbSDavid van Moolenbroek 			fatal("do_service: expected list at %s:%d",
1054c58da9fbSDavid van Moolenbroek 				cp->file, cp->line);
1055c58da9fbSDavid van Moolenbroek 		}
1056c58da9fbSDavid van Moolenbroek 		cpe= cp->list;
1057c58da9fbSDavid van Moolenbroek 		if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
1058c58da9fbSDavid van Moolenbroek 		{
1059c58da9fbSDavid van Moolenbroek 			fatal("do_service: expected word at %s:%d",
1060c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
1061c58da9fbSDavid van Moolenbroek 		}
1062c58da9fbSDavid van Moolenbroek 
1063c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_CLASS) == 0)
1064c58da9fbSDavid van Moolenbroek 		{
1065c58da9fbSDavid van Moolenbroek 			do_class(cpe->next, config, rs_config);
1066c58da9fbSDavid van Moolenbroek 			continue;
1067c58da9fbSDavid van Moolenbroek 		}
1068c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_UID) == 0)
1069c58da9fbSDavid van Moolenbroek 		{
1070c58da9fbSDavid van Moolenbroek 			do_uid(cpe->next, rs_start);
1071c58da9fbSDavid van Moolenbroek 			continue;
1072c58da9fbSDavid van Moolenbroek 		}
1073c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_SIGMGR) == 0)
1074c58da9fbSDavid van Moolenbroek 		{
1075c58da9fbSDavid van Moolenbroek 			do_sigmgr(cpe->next, rs_start);
1076c58da9fbSDavid van Moolenbroek 			continue;
1077c58da9fbSDavid van Moolenbroek 		}
1078c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_TYPE) == 0)
1079c58da9fbSDavid van Moolenbroek 		{
1080c58da9fbSDavid van Moolenbroek 			do_type(cpe->next, rs_config);
1081c58da9fbSDavid van Moolenbroek 			continue;
1082c58da9fbSDavid van Moolenbroek 		}
1083c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_DESCR) == 0)
1084c58da9fbSDavid van Moolenbroek 		{
1085c58da9fbSDavid van Moolenbroek 			do_descr(cpe->next, rs_config);
1086c58da9fbSDavid van Moolenbroek 			continue;
1087c58da9fbSDavid van Moolenbroek 		}
1088c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_SCHEDULER) == 0)
1089c58da9fbSDavid van Moolenbroek 		{
1090c58da9fbSDavid van Moolenbroek 			do_scheduler(cpe->next, rs_start);
1091c58da9fbSDavid van Moolenbroek 			continue;
1092c58da9fbSDavid van Moolenbroek 		}
1093c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_PRIORITY) == 0)
1094c58da9fbSDavid van Moolenbroek 		{
1095c58da9fbSDavid van Moolenbroek 			do_priority(cpe->next, rs_start);
1096c58da9fbSDavid van Moolenbroek 			continue;
1097c58da9fbSDavid van Moolenbroek 		}
1098c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_QUANTUM) == 0)
1099c58da9fbSDavid van Moolenbroek 		{
1100c58da9fbSDavid van Moolenbroek 			do_quantum(cpe->next, rs_start);
1101c58da9fbSDavid van Moolenbroek 			continue;
1102c58da9fbSDavid van Moolenbroek 		}
1103c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_CPU) == 0)
1104c58da9fbSDavid van Moolenbroek 		{
1105c58da9fbSDavid van Moolenbroek 			do_cpu(cpe->next, rs_start);
1106c58da9fbSDavid van Moolenbroek 			continue;
1107c58da9fbSDavid van Moolenbroek 		}
1108c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_IRQ) == 0)
1109c58da9fbSDavid van Moolenbroek 		{
1110c58da9fbSDavid van Moolenbroek 			do_irq(cpe->next, rs_start);
1111c58da9fbSDavid van Moolenbroek 			continue;
1112c58da9fbSDavid van Moolenbroek 		}
1113c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_IO) == 0)
1114c58da9fbSDavid van Moolenbroek 		{
1115c58da9fbSDavid van Moolenbroek 			do_io(cpe->next, rs_start);
1116c58da9fbSDavid van Moolenbroek 			continue;
1117c58da9fbSDavid van Moolenbroek 		}
1118c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_PCI) == 0)
1119c58da9fbSDavid van Moolenbroek 		{
1120c58da9fbSDavid van Moolenbroek 			do_pci(cpe->next, rs_start);
1121c58da9fbSDavid van Moolenbroek 			continue;
1122c58da9fbSDavid van Moolenbroek 		}
1123c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_SYSTEM) == 0)
1124c58da9fbSDavid van Moolenbroek 		{
1125c58da9fbSDavid van Moolenbroek 			do_system(cpe->next, rs_start);
1126c58da9fbSDavid van Moolenbroek 			continue;
1127c58da9fbSDavid van Moolenbroek 		}
1128c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_IPC) == 0)
1129c58da9fbSDavid van Moolenbroek 		{
1130c58da9fbSDavid van Moolenbroek 			do_ipc(cpe->next, rs_start);
1131c58da9fbSDavid van Moolenbroek 			continue;
1132c58da9fbSDavid van Moolenbroek 		}
1133c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_VM) == 0)
1134c58da9fbSDavid van Moolenbroek 		{
1135c58da9fbSDavid van Moolenbroek 			do_vm(cpe->next, rs_start);
1136c58da9fbSDavid van Moolenbroek 			continue;
1137c58da9fbSDavid van Moolenbroek 		}
1138c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_CONTROL) == 0)
1139c58da9fbSDavid van Moolenbroek 		{
1140c58da9fbSDavid van Moolenbroek 			do_control(cpe->next, rs_start);
1141c58da9fbSDavid van Moolenbroek 			continue;
1142c58da9fbSDavid van Moolenbroek 		}
1143*181fb1b2SDavid van Moolenbroek 		if (strcmp(cpe->word, KW_DOMAIN) == 0)
1144*181fb1b2SDavid van Moolenbroek 		{
1145*181fb1b2SDavid van Moolenbroek 			do_domain(cpe->next, rs_start);
1146*181fb1b2SDavid van Moolenbroek 			continue;
1147*181fb1b2SDavid van Moolenbroek 		}
1148c58da9fbSDavid van Moolenbroek 	}
1149c58da9fbSDavid van Moolenbroek }
1150c58da9fbSDavid van Moolenbroek 
do_config(const char * label,char * filename,struct rs_config * rs_config)1151c58da9fbSDavid van Moolenbroek static const char *do_config(const char *label, char *filename, struct rs_config *rs_config)
1152c58da9fbSDavid van Moolenbroek {
1153c58da9fbSDavid van Moolenbroek 	config_t *config, *cp, *cpe;
1154c58da9fbSDavid van Moolenbroek 	struct passwd *pw;
1155c58da9fbSDavid van Moolenbroek 	struct rs_start *rs_start = &rs_config->rs_start;
1156c58da9fbSDavid van Moolenbroek 
1157c58da9fbSDavid van Moolenbroek 	if(!(config= config_read(filename, 0, NULL)))
1158c58da9fbSDavid van Moolenbroek 		return NULL; /* config file read failed. */
1159c58da9fbSDavid van Moolenbroek 
1160c58da9fbSDavid van Moolenbroek 	/* Set clean rs_start defaults. */
1161c58da9fbSDavid van Moolenbroek 	memset(rs_config, 0, sizeof(*rs_config));
1162c58da9fbSDavid van Moolenbroek 	if(!(pw= getpwnam(SERVICE_LOGIN)))
1163c58da9fbSDavid van Moolenbroek 		fatal("no passwd file entry for '%s'", SERVICE_LOGIN);
1164c58da9fbSDavid van Moolenbroek 	rs_start->rss_uid= pw->pw_uid;
1165c58da9fbSDavid van Moolenbroek 	rs_start->rss_sigmgr= DSRV_SM;
1166c58da9fbSDavid van Moolenbroek 	rs_start->rss_scheduler= DSRV_SCH;
1167c58da9fbSDavid van Moolenbroek 	rs_start->rss_priority= DSRV_Q;
1168c58da9fbSDavid van Moolenbroek 	rs_start->rss_quantum= DSRV_QT;
1169c58da9fbSDavid van Moolenbroek 	rs_start->rss_cpu = DSRV_CPU;
1170c58da9fbSDavid van Moolenbroek 	rs_start->rss_flags = RSS_VM_BASIC_CALLS | RSS_SYS_BASIC_CALLS;
1171c58da9fbSDavid van Moolenbroek 
1172c58da9fbSDavid van Moolenbroek 	/* Find an entry for our service */
1173c58da9fbSDavid van Moolenbroek 	for (cp= config; cp; cp= cp->next)
1174c58da9fbSDavid van Moolenbroek 	{
1175c58da9fbSDavid van Moolenbroek 		if (!(cp->flags & CFG_SUBLIST))
1176c58da9fbSDavid van Moolenbroek 		{
1177c58da9fbSDavid van Moolenbroek 			fatal("do_config: expected list at %s:%d",
1178c58da9fbSDavid van Moolenbroek 				cp->file, cp->line);
1179c58da9fbSDavid van Moolenbroek 		}
1180c58da9fbSDavid van Moolenbroek 		cpe= cp->list;
1181c58da9fbSDavid van Moolenbroek 		if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
1182c58da9fbSDavid van Moolenbroek 		{
1183c58da9fbSDavid van Moolenbroek 			fatal("do_config: expected word at %s:%d",
1184c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
1185c58da9fbSDavid van Moolenbroek 		}
1186c58da9fbSDavid van Moolenbroek 
1187c58da9fbSDavid van Moolenbroek 		/* At this place we expect the word KW_SERVICE */
1188c58da9fbSDavid van Moolenbroek 		if (strcmp(cpe->word, KW_SERVICE) != 0)
1189c58da9fbSDavid van Moolenbroek 			fatal("do_config: exected word '%S' at %s:%d",
1190c58da9fbSDavid van Moolenbroek 				KW_SERVICE, cpe->file, cpe->line);
1191c58da9fbSDavid van Moolenbroek 
1192c58da9fbSDavid van Moolenbroek 		cpe= cpe->next;
1193c58da9fbSDavid van Moolenbroek 		if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
1194c58da9fbSDavid van Moolenbroek 		{
1195c58da9fbSDavid van Moolenbroek 			fatal("do_config: expected word at %s:%d",
1196c58da9fbSDavid van Moolenbroek 				cpe->file, cpe->line);
1197c58da9fbSDavid van Moolenbroek 		}
1198c58da9fbSDavid van Moolenbroek 
1199c58da9fbSDavid van Moolenbroek 		/* At this place we expect the name of the service. */
1200c58da9fbSDavid van Moolenbroek 		if (!label || strcmp(cpe->word, label) == 0) {
1201c58da9fbSDavid van Moolenbroek 			label = cpe->word;
1202c58da9fbSDavid van Moolenbroek 			break;
1203c58da9fbSDavid van Moolenbroek 		}
1204c58da9fbSDavid van Moolenbroek 	}
1205c58da9fbSDavid van Moolenbroek 	if (cp == NULL)
1206c58da9fbSDavid van Moolenbroek 	{
1207c58da9fbSDavid van Moolenbroek 		fprintf(stderr, "minix-service: service '%s' not found in "
1208c58da9fbSDavid van Moolenbroek 		    "'%s'\n", label, filename);
1209c58da9fbSDavid van Moolenbroek 		exit(1);
1210c58da9fbSDavid van Moolenbroek 	}
1211c58da9fbSDavid van Moolenbroek 
1212c58da9fbSDavid van Moolenbroek 	cpe= cpe->next;
1213c58da9fbSDavid van Moolenbroek 
1214c58da9fbSDavid van Moolenbroek 	do_service(cpe, config, rs_config);
1215c58da9fbSDavid van Moolenbroek 
1216c58da9fbSDavid van Moolenbroek 	{
1217c58da9fbSDavid van Moolenbroek 		char *default_ipc = RSS_IPC_ALL_SYS;
1218c58da9fbSDavid van Moolenbroek 		if(!rs_start->rss_ipc) {
1219c58da9fbSDavid van Moolenbroek 		      rs_start->rss_ipc= default_ipc;
1220c58da9fbSDavid van Moolenbroek 		      rs_start->rss_ipclen= strlen(default_ipc);
1221c58da9fbSDavid van Moolenbroek 		}
1222c58da9fbSDavid van Moolenbroek 	}
1223c58da9fbSDavid van Moolenbroek 
1224c58da9fbSDavid van Moolenbroek 	/* config file read ok. */
1225c58da9fbSDavid van Moolenbroek 	return label;
1226c58da9fbSDavid van Moolenbroek }
1227c58da9fbSDavid van Moolenbroek 
1228c58da9fbSDavid van Moolenbroek /* returns failure */
parse_config(char * progname,int custom_config,char * req_config,struct rs_config * rs_config)1229c58da9fbSDavid van Moolenbroek const char *parse_config(char *progname, int custom_config, char *req_config,
1230c58da9fbSDavid van Moolenbroek 	struct rs_config *rs_config)
1231c58da9fbSDavid van Moolenbroek {
1232c58da9fbSDavid van Moolenbroek         char *specificconfig, *specific_pkg_config;
1233c58da9fbSDavid van Moolenbroek 	const char *l;
1234c58da9fbSDavid van Moolenbroek 
1235c58da9fbSDavid van Moolenbroek 	/* Config file specified? */
1236c58da9fbSDavid van Moolenbroek         if(custom_config)
1237c58da9fbSDavid van Moolenbroek           return do_config(progname, req_config, rs_config);
1238c58da9fbSDavid van Moolenbroek 
1239c58da9fbSDavid van Moolenbroek 	/* No specific config file. */
1240c58da9fbSDavid van Moolenbroek         if(asprintf(&specificconfig, "%s/%s", _PATH_SYSTEM_CONF_DIR,
1241c58da9fbSDavid van Moolenbroek               progname) < 0) {
1242c58da9fbSDavid van Moolenbroek               errx(1, "no memory");
1243c58da9fbSDavid van Moolenbroek         }
1244c58da9fbSDavid van Moolenbroek 
1245c58da9fbSDavid van Moolenbroek         if(asprintf(&specific_pkg_config, "%s/%s", _PATH_SYSTEM_CONF_PKG_DIR,
1246c58da9fbSDavid van Moolenbroek               progname) < 0) {
1247c58da9fbSDavid van Moolenbroek               errx(1, "no memory");
1248c58da9fbSDavid van Moolenbroek         }
1249c58da9fbSDavid van Moolenbroek 
1250c58da9fbSDavid van Moolenbroek         /* Try specific config filename first, in base system
1251c58da9fbSDavid van Moolenbroek 	 * and package locations, * and only if it fails, the global
1252c58da9fbSDavid van Moolenbroek 	 * system one.
1253c58da9fbSDavid van Moolenbroek          */
1254c58da9fbSDavid van Moolenbroek 	if((l=do_config(progname, specific_pkg_config, rs_config))) return l;
1255c58da9fbSDavid van Moolenbroek 	if((l=do_config(progname, specificconfig, rs_config))) return l;
1256c58da9fbSDavid van Moolenbroek 	if((l=do_config(progname, req_config, rs_config))) return l;
1257c58da9fbSDavid van Moolenbroek 
1258c58da9fbSDavid van Moolenbroek 	return NULL;
1259c58da9fbSDavid van Moolenbroek }
1260c58da9fbSDavid van Moolenbroek 
1261