xref: /original-bsd/usr.bin/man/config.c (revision 82d4dc09)
1 /*
2  * Copyright (c) 1989 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)config.c	5.2 (Berkeley) 05/27/90";
20 #endif /* not lint */
21 
22 #include <sys/param.h>
23 #include <stdio.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <pwd.h>
28 #include "pathnames.h"
29 
30 #define	MAXLINE		1024
31 
32 extern char *progname;
33 
34 static FILE *cfp;
35 static char *buf;
36 
37 /*
38  * getpath --
39  *	read in the configuration file, calling a function with the line
40  *	from each matching section.
41  */
42 char *
43 getpath(sects)
44 	char **sects;
45 {
46 	register char **av, *p;
47 	size_t len;
48 	char **ar, line[MAXLINE], **getorder();
49 
50 	ar = getorder();
51 	openconfig();
52 	while (fgets(line, sizeof(line), cfp)) {
53 		if (!index(line, '\n')) {
54 			(void)fprintf(stderr, "%s: config line too long.\n",
55 			    progname);
56 			exit(1);
57 		}
58 		p = strtok(line, " \t\n");
59 		if (!p || *p == '#')
60 			continue;
61 		for (av = sects; *av; ++av)
62 			if (!strcmp(p, *av))
63 				break;
64 		if (!*av)
65 			continue;
66 		while (p = strtok((char *)NULL, " \t\n")) {
67 			len = strlen(p);
68 			if (p[len - 1] == '/')
69 				for (av = ar; *av; ++av)
70 					cadd(p, len, *av);
71 			else
72 				cadd(p, len, (char *)NULL);
73 		}
74 	}
75 	return(buf);
76 }
77 
78 static
79 cadd(add1, len1, add2)
80 char *add1, *add2;
81 register size_t len1;
82 {
83 	static size_t buflen;
84 	static char *bp, *endp;
85 	register size_t len2;
86 
87 	len2 = add2 ? strlen(add2) : 0;
88 	if (!bp || bp + len1 + len2 + 2 >= endp) {
89 		if (!(buf = realloc(buf, buflen += 1024)))
90 			enomem();
91 		if (!bp)
92 			bp = buf;
93 		endp = buf + buflen;
94 	}
95 	bcopy(add1, bp, len1);
96 	bp += len1;
97 	if (len2) {
98 		bcopy(add2, bp, len2);
99 		bp += len2;
100 	}
101 	*bp++ = ':';
102 	*bp = '\0';
103 }
104 
105 static
106 openconfig()
107 {
108 	if (cfp) {
109 		rewind(cfp);
110 		return;
111 	}
112 	if (!(cfp = fopen(_PATH_MANCONF, "r"))) {
113 		(void)fprintf(stderr, "%s: no configuration file %s.\n",
114 		    progname, _PATH_MANCONF);
115 		exit(1);
116 	}
117 }
118 
119 char **
120 getdb()
121 {
122 	register char *p;
123 	int cnt, num;
124 	char **ar, line[MAXLINE];
125 
126 	ar = NULL;
127 	num = 0;
128 	cnt = -1;
129 	openconfig();
130 	while (fgets(line, sizeof(line), cfp)) {
131 		if (!index(line, '\n')) {
132 			(void)fprintf(stderr, "%s: config line too long.\n",
133 			    progname);
134 			exit(1);
135 		}
136 		p = strtok(line, " \t\n");
137 #define	WHATDB	"_whatdb"
138 		if (!p || *p == '#' || strcmp(p, WHATDB))
139 			continue;
140 		while (p = strtok((char *)NULL, " \t\n")) {
141 			if (cnt == num - 1 &&
142 			    !(ar = realloc(ar, (num += 30) * sizeof(char **))))
143 				enomem();
144 			if (!(ar[++cnt] = strdup(p)))
145 				enomem();
146 		}
147 	}
148 	if (ar) {
149 		if (cnt == num - 1 &&
150 		    !(ar = realloc(ar, ++num * sizeof(char **))))
151 			enomem();
152 		ar[++cnt] = NULL;
153 	}
154 	return(ar);
155 }
156 
157 static char **
158 getorder()
159 {
160 	register char *p;
161 	int cnt, num;
162 	char **ar, line[MAXLINE];
163 
164 	ar = NULL;
165 	num = 0;
166 	cnt = -1;
167 	openconfig();
168 	while (fgets(line, sizeof(line), cfp)) {
169 		if (!index(line, '\n')) {
170 			(void)fprintf(stderr, "%s: config line too long.\n",
171 			    progname);
172 			exit(1);
173 		}
174 		p = strtok(line, " \t\n");
175 #define	SUBDIR	"_subdir"
176 		if (!p || *p == '#' || strcmp(p, SUBDIR))
177 			continue;
178 		while (p = strtok((char *)NULL, " \t\n")) {
179 			if (cnt == num - 1 &&
180 			    !(ar = realloc(ar, (num += 30) * sizeof(char **))))
181 				enomem();
182 			if (!(ar[++cnt] = strdup(p)))
183 				enomem();
184 		}
185 	}
186 	if (ar) {
187 		if (cnt == num - 1 &&
188 		    !(ar = realloc(ar, ++num * sizeof(char **))))
189 			enomem();
190 		ar[++cnt] = NULL;
191 	}
192 	return(ar);
193 }
194 
195 getsection(sect)
196 	char *sect;
197 {
198 	register char *p;
199 	char line[MAXLINE];
200 
201 	openconfig();
202 	while (fgets(line, sizeof(line), cfp)) {
203 		if (!index(line, '\n')) {
204 			(void)fprintf(stderr, "%s: config line too long.\n",
205 			    progname);
206 			exit(1);
207 		}
208 		p = strtok(line, " \t\n");
209 		if (!p || *p == '#')
210 			continue;
211 		if (!strcmp(p, sect))
212 			return(1);
213 	}
214 	return(0);
215 }
216 
217 enomem()
218 {
219 	(void)fprintf(stderr, "%s: %s\n", progname, strerror(ENOMEM));
220 	exit(1);
221 }
222