xref: /csrg-svn/sbin/mount_portal/conf.c (revision 66484)
154851Spendry /*
261515Sbostic  * Copyright (c) 1992, 1993
361515Sbostic  *	The Regents of the University of California.  All rights reserved.
454851Spendry  * All rights reserved.
554851Spendry  *
654851Spendry  * This code is derived from software donated to Berkeley by
754851Spendry  * Jan-Simon Pendry.
854851Spendry  *
954851Spendry  * %sccs.include.redist.c%
1054851Spendry  *
11*66484Spendry  *	@(#)conf.c	8.2 (Berkeley) 03/27/94
1254851Spendry  *
1354851Spendry  * $Id: conf.c,v 1.2 1992/05/27 07:09:27 jsp Exp jsp $
1454851Spendry  */
1554851Spendry 
1654851Spendry #include <stdio.h>
1754851Spendry #include <stdlib.h>
1854851Spendry #include <unistd.h>
1954851Spendry #include <string.h>
2054851Spendry #include <errno.h>
2154851Spendry #include <limits.h>
2254851Spendry #include <regexp.h>
2354851Spendry #include <sys/types.h>
2454979Spendry #include <sys/param.h>
2554851Spendry #include <sys/syslog.h>
2654851Spendry 
2754851Spendry #include "portald.h"
2854851Spendry 
2954851Spendry #define	ALLOC(ty)	(xmalloc(sizeof(ty)))
3054851Spendry 
3154851Spendry typedef struct path path;
3254851Spendry struct path {
3354851Spendry 	qelem p_q;		/* 2-way linked list */
3454851Spendry 	int p_lno;		/* Line number of this record */
3554851Spendry 	char *p_args;		/* copy of arg string (malloc) */
3654851Spendry 	char *p_key;		/* Pathname to match (also p_argv[0]) */
3754851Spendry 	regexp *p_re;		/* RE to match against pathname (malloc) */
3854851Spendry 	int p_argc;		/* number of elements in arg string */
3954851Spendry 	char **p_argv;		/* argv[] pointers into arg string (malloc) */
4054851Spendry };
4154851Spendry 
4254851Spendry static char *conf_file;		/* XXX for regerror */
4354851Spendry static path *curp;		/* XXX for regerror */
4454851Spendry 
4554851Spendry /*
4654851Spendry  * Add an element to a 2-way list,
4754851Spendry  * just after (pred)
4854851Spendry  */
ins_que(elem,pred)4954851Spendry static void ins_que(elem, pred)
5054851Spendry qelem *elem, *pred;
5154851Spendry {
5254851Spendry 	qelem *p = pred->q_forw;
5354851Spendry 	elem->q_back = pred;
5454851Spendry 	elem->q_forw = p;
5554851Spendry 	pred->q_forw = elem;
5654851Spendry 	p->q_back = elem;
5754851Spendry }
5854851Spendry 
5954851Spendry /*
6054851Spendry  * Remove an element from a 2-way list
6154851Spendry  */
rem_que(elem)6254851Spendry static void rem_que(elem)
6354851Spendry qelem *elem;
6454851Spendry {
6554851Spendry 	qelem *p = elem->q_forw;
6654851Spendry 	qelem *p2 = elem->q_back;
6754851Spendry 	p2->q_forw = p;
6854851Spendry 	p->q_back = p2;
6954851Spendry }
7054851Spendry 
7154851Spendry /*
7254851Spendry  * Error checking malloc
7354851Spendry  */
xmalloc(siz)7454851Spendry static void *xmalloc(siz)
7554851Spendry unsigned siz;
7654851Spendry {
7754851Spendry 	void *p = malloc(siz);
7854851Spendry 	if (p)
7954851Spendry 		return (p);
8054851Spendry 	syslog(LOG_ALERT, "malloc: failed to get %d bytes", siz);
8154851Spendry 	exit(1);
8254851Spendry }
8354851Spendry 
8454851Spendry /*
8554851Spendry  * Insert the path in the list.
8654851Spendry  * If there is already an element with the same key then
8754851Spendry  * the *second* one is ignored (return 0).  If the key is
8854851Spendry  * not found then the path is added to the end of the list
8954851Spendry  * and 1 is returned.
9054851Spendry  */
pinsert(p0,q0)9154851Spendry static int pinsert(p0, q0)
9254851Spendry path *p0;
9354851Spendry qelem *q0;
9454851Spendry {
9554851Spendry 	qelem *q;
9654851Spendry 
9754851Spendry 	if (p0->p_argc == 0)
9854851Spendry 		return (0);
9954851Spendry 
10054851Spendry 	for (q = q0->q_forw; q != q0; q = q->q_forw) {
10154851Spendry 		path *p = (path *) q;
10254851Spendry 		if (strcmp(p->p_key, p0->p_key) == 0)
10354851Spendry 			return (0);
10454851Spendry 	}
10554851Spendry 	ins_que(&p0->p_q, q0->q_back);
10654851Spendry 	return (1);
10754851Spendry 
10854851Spendry }
10954851Spendry 
regerror(s)11054851Spendry void regerror(s)
11154851Spendry const char *s;
11254851Spendry {
11354851Spendry 	syslog(LOG_ERR, "%s:%s: regcomp %s: %s",
11454851Spendry 			conf_file, curp->p_lno, curp->p_key, s);
11554851Spendry }
11654851Spendry 
palloc(cline,lno)11754851Spendry static path *palloc(cline, lno)
11854851Spendry char *cline;
11954851Spendry int lno;
12054851Spendry {
12154851Spendry 	int c;
12254851Spendry 	char *s;
12354851Spendry 	char *key;
12454851Spendry 	path *p;
12554851Spendry 	char **ap;
12654851Spendry 
12754851Spendry 	/*
12854851Spendry 	 * Implement comment chars
12954851Spendry 	 */
13054851Spendry 	s = strchr(cline, '#');
13154851Spendry 	if (s)
13254851Spendry 		*s = 0;
13354851Spendry 
13454851Spendry 	/*
13554851Spendry 	 * Do a pass through the string to count the number
13654851Spendry 	 * of arguments
13754851Spendry 	 */
13854851Spendry 	c = 0;
13954851Spendry 	key = strdup(cline);
14054851Spendry 	for (s = key; s != NULL; ) {
14154851Spendry 		char *val;
14254851Spendry 		while ((val = strsep(&s, " \t\n")) != NULL && *val == '\0')
14354851Spendry 			;
14454851Spendry 		if (val)
14554851Spendry 			c++;
14654851Spendry 	}
14754851Spendry 	c++;
14854851Spendry 	free(key);
14954851Spendry 
15054851Spendry 	if (c <= 1)
15154851Spendry 		return (0);
15254851Spendry 
15354851Spendry 	/*
15454851Spendry 	 * Now do another pass and generate a new path structure
15554851Spendry 	 */
15654851Spendry 	p = ALLOC(path);
15754851Spendry 	p->p_argc = 0;
15854851Spendry 	p->p_argv = xmalloc(c * sizeof(char *));
15954851Spendry 	p->p_args = strdup(cline);
16054851Spendry 	ap = p->p_argv;
16154851Spendry 	for (s = p->p_args; s != NULL; ) {
16254851Spendry 		char *val;
16354851Spendry 		while ((val = strsep(&s, " \t\n")) != NULL && *val == '\0')
16454851Spendry 			;
16554851Spendry 		if (val) {
16654851Spendry 			*ap++ = val;
16754851Spendry 			p->p_argc++;
16854851Spendry 		}
16954851Spendry 	}
17054851Spendry 	*ap = 0;
17154851Spendry 
17254851Spendry #ifdef DEBUG
17354851Spendry 	for (c = 0; c < p->p_argc; c++)
17454851Spendry 		printf("%sv[%d] = %s\n", c?"\t":"", c, p->p_argv[c]);
17554851Spendry #endif
17654851Spendry 
17754851Spendry 	p->p_key = p->p_argv[0];
17854851Spendry 	if (strpbrk(p->p_key, RE_CHARS)) {
17954851Spendry 		curp = p;			/* XXX */
18054851Spendry 		p->p_re = regcomp(p->p_key);
18154851Spendry 		curp = 0;			/* XXX */
18254851Spendry 	} else {
18354851Spendry 		p->p_re = 0;
18454851Spendry 	}
18554851Spendry 	p->p_lno = lno;
18654851Spendry 
18754851Spendry 	return (p);
18854851Spendry }
18954851Spendry 
19054851Spendry /*
19154851Spendry  * Free a path structure
19254851Spendry  */
pfree(p)19354851Spendry static void pfree(p)
19454851Spendry path *p;
19554851Spendry {
19654851Spendry 	free(p->p_args);
19754851Spendry 	if (p->p_re)
19854851Spendry 		free((char *) p->p_re);
19954851Spendry 	free((char *) p->p_argv);
20054851Spendry 	free((char *) p);
20154851Spendry }
20254851Spendry 
20354851Spendry /*
20454851Spendry  * Discard all currently held path structures on q0.
20554851Spendry  * and add all the ones on xq.
20654851Spendry  */
preplace(q0,xq)20754851Spendry static void preplace(q0, xq)
20854851Spendry qelem *q0;
20954851Spendry qelem *xq;
21054851Spendry {
21154851Spendry 	/*
21254851Spendry 	 * While the list is not empty,
21354851Spendry 	 * take the first element off the list
21454851Spendry 	 * and free it.
21554851Spendry 	 */
21654851Spendry 	while (q0->q_forw != q0) {
217*66484Spendry 		qelem *q = q0->q_forw;
21854851Spendry 		rem_que(q);
21954851Spendry 		pfree((path *) q);
22054851Spendry 	}
22154851Spendry 	while (xq->q_forw != xq) {
22254851Spendry 		qelem *q = xq->q_forw;
22354851Spendry 		rem_que(q);
22454851Spendry 		ins_que(q, q0);
22554851Spendry 	}
22654851Spendry }
22754851Spendry 
22854851Spendry /*
22954851Spendry  * Read the lines from the configuration file and
23054851Spendry  * add them to the list of paths.
23154851Spendry  */
readfp(q0,fp)23254851Spendry static void readfp(q0, fp)
23354851Spendry qelem *q0;
23454851Spendry FILE *fp;
23554851Spendry {
23654851Spendry 	char cline[LINE_MAX];
23754851Spendry 	int nread = 0;
23854851Spendry 	qelem q;
23954851Spendry 
24054851Spendry 	/*
24154851Spendry 	 * Make a new empty list.
24254851Spendry 	 */
24354851Spendry 	q.q_forw = q.q_back = &q;
24454851Spendry 
24554851Spendry 	/*
24654851Spendry 	 * Read the lines from the configuration file.
24754851Spendry 	 */
24854851Spendry 	while (fgets(cline, sizeof(cline), fp)) {
24954851Spendry 		path *p = palloc(cline, nread+1);
25054851Spendry 		if (p && !pinsert(p, &q))
25154851Spendry 			pfree(p);
25254851Spendry 		nread++;
25354851Spendry 	}
25454851Spendry 
25554851Spendry 	/*
25654851Spendry 	 * If some records were read, then throw
25754851Spendry 	 * away the old list and replace with the
25854851Spendry 	 * new one.
25954851Spendry 	 */
26054851Spendry 	if (nread)
26154851Spendry 		preplace(q0, &q);
26254851Spendry }
26354851Spendry 
26454851Spendry /*
26554851Spendry  * Read the configuration file (conf) and replace
26654851Spendry  * the existing path list with the new version.
26754851Spendry  * If the file is not readable, then no changes take place
26854851Spendry  */
conf_read(q,conf)26954851Spendry void conf_read(q, conf)
27054851Spendry qelem *q;
27154851Spendry char *conf;
27254851Spendry {
27354851Spendry 	FILE *fp = fopen(conf, "r");
27454851Spendry 	if (fp) {
27554851Spendry 		conf_file = conf;		/* XXX */
27654851Spendry 		readfp(q, fp);
27754851Spendry 		conf_file = 0;		/* XXX */
27854851Spendry 		(void) fclose(fp);
27954851Spendry 	} else {
28054851Spendry 		syslog(LOG_ERR, "open config file \"%s\": %s", conf, strerror(errno));
28154851Spendry 	}
28254851Spendry }
28354851Spendry 
28454851Spendry 
conf_match(q0,key)28554851Spendry char **conf_match(q0, key)
28654851Spendry qelem *q0;
28754851Spendry char *key;
28854851Spendry {
28954851Spendry 	qelem *q;
29054851Spendry 
29154851Spendry 	for (q = q0->q_forw; q != q0; q = q->q_forw) {
29254851Spendry 		path *p = (path *) q;
29354851Spendry 		if (p->p_re) {
29454851Spendry 			if (regexec(p->p_re, key))
29554851Spendry 				return (p->p_argv+1);
29654851Spendry 		} else {
29754851Spendry 			if (strncmp(p->p_key, key, strlen(p->p_key)) == 0)
29854851Spendry 				return (p->p_argv+1);
29954851Spendry 		}
30054851Spendry 	}
30154851Spendry 
30254851Spendry 	return (0);
30354851Spendry }
304