xref: /freebsd/usr.bin/getconf/getconf.c (revision 8aaffd78c0f517985c12fd1e3cbceeb6c6b98ef5)
1 /*
2  * Copyright 2000 Massachusetts Institute of Technology
3  *
4  * Permission to use, copy, modify, and distribute this software and
5  * its documentation for any purpose and without fee is hereby
6  * granted, provided that both the above copyright notice and this
7  * permission notice appear in all copies, that both the above
8  * copyright notice and this permission notice appear in all
9  * supporting documentation, and that the name of M.I.T. not be used
10  * in advertising or publicity pertaining to distribution of the
11  * software without specific, written prior permission.  M.I.T. makes
12  * no representations about the suitability of this software for any
13  * purpose.  It is provided "as is" without express or implied
14  * warranty.
15  *
16  * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
17  * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
18  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
20  * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #include <sys/types.h>
31 
32 #include <err.h>
33 #include <errno.h>
34 #include <stdbool.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <sysexits.h>
38 #include <unistd.h>
39 
40 #include "getconf.h"
41 
42 static void	do_allsys(void);
43 static void	do_allpath(const char *path);
44 static void	do_confstr(const char *name, int key);
45 static void	do_sysconf(const char *name, int key);
46 static void	do_pathconf(const char *name, int key, const char *path);
47 
48 static void
49 usage(void)
50 {
51 	fprintf(stderr,
52 "usage: getconf -a [pathname]\n"
53 "       getconf [-v prog_env] system_var\n"
54 "       getconf [-v prog_env] path_var pathname\n");
55 	exit(EX_USAGE);
56 }
57 
58 int
59 main(int argc, char **argv)
60 {
61 	bool aflag;
62 	int c, key, valid;
63 	const char *name, *vflag, *alt_path;
64 	intmax_t limitval;
65 	uintmax_t ulimitval;
66 
67 	aflag = false;
68 	vflag = NULL;
69 	while ((c = getopt(argc, argv, "av:")) != -1) {
70 		switch (c) {
71 		case 'a':
72 			aflag = true;
73 			break;
74 		case 'v':
75 			vflag = optarg;
76 			break;
77 
78 		default:
79 			usage();
80 		}
81 	}
82 
83 	if (aflag) {
84 		if (vflag != NULL)
85 			usage();
86 		if (argv[optind] == NULL)
87 			do_allsys();
88 		else
89 			do_allpath(argv[optind]);
90 		return (0);
91 	}
92 
93 	if ((name = argv[optind]) == NULL)
94 		usage();
95 
96 	if (vflag != NULL) {
97 		if ((valid = find_progenv(vflag, &alt_path)) == 0)
98 			errx(EX_USAGE, "invalid programming environment %s",
99 			     vflag);
100 		if (valid > 0 && alt_path != NULL) {
101 			if (argv[optind + 1] == NULL)
102 				execl(alt_path, "getconf", argv[optind],
103 				      (char *)NULL);
104 			else
105 				execl(alt_path, "getconf", argv[optind],
106 				      argv[optind + 1], (char *)NULL);
107 
108 			err(EX_OSERR, "execl: %s", alt_path);
109 		}
110 		if (valid < 0)
111 			errx(EX_UNAVAILABLE, "environment %s is not available",
112 			     vflag);
113 	}
114 
115 	if (argv[optind + 1] == NULL) { /* confstr or sysconf */
116 		if ((valid = find_unsigned_limit(name, &ulimitval)) != 0) {
117 			if (valid > 0)
118 				printf("%" PRIuMAX "\n", ulimitval);
119 			else
120 				printf("undefined\n");
121 			return 0;
122 		}
123 		if ((valid = find_limit(name, &limitval)) != 0) {
124 			if (valid > 0)
125 				printf("%" PRIdMAX "\n", limitval);
126 			else
127 				printf("undefined\n");
128 
129 			return 0;
130 		}
131 		if ((valid = find_confstr(name, &key)) != 0) {
132 			if (valid > 0)
133 				do_confstr(name, key);
134 			else
135 				printf("undefined\n");
136 		} else {
137 			valid = find_sysconf(name, &key);
138 			if (valid > 0) {
139 				do_sysconf(name, key);
140 			} else if (valid < 0) {
141 				printf("undefined\n");
142 			} else
143 				errx(EX_USAGE,
144 				     "no such configuration parameter `%s'",
145 				     name);
146 		}
147 	} else {
148 		valid = find_pathconf(name, &key);
149 		if (valid != 0) {
150 			if (valid > 0)
151 				do_pathconf(name, key, argv[optind + 1]);
152 			else
153 				printf("undefined\n");
154 		} else
155 			errx(EX_USAGE,
156 			     "no such path configuration parameter `%s'",
157 			     name);
158 	}
159 	return 0;
160 }
161 
162 static void
163 do_onestr(const char *name, int key)
164 {
165 	size_t len;
166 
167 	errno = 0;
168 	len = confstr(key, 0, 0);
169 	if (len == 0 && errno != 0) {
170 		warn("confstr: %s", name);
171 		return;
172 	}
173 	printf("%s: ", name);
174 	if (len == 0)
175 		printf("undefined\n");
176 	else {
177 		char buf[len + 1];
178 
179 		confstr(key, buf, len);
180 		printf("%s\n", buf);
181 	}
182 }
183 
184 static void
185 do_onesys(const char *name, int key)
186 {
187 	long value;
188 
189 	errno = 0;
190 	value = sysconf(key);
191 	if (value == -1 && errno != 0) {
192 		warn("sysconf: %s", name);
193 		return;
194 	}
195 	printf("%s: ", name);
196 	if (value == -1)
197 		printf("undefined\n");
198 	else
199 		printf("%ld\n", value);
200 }
201 
202 static void
203 do_allsys(void)
204 {
205 
206 	foreach_confstr(do_onestr);
207 	foreach_sysconf(do_onesys);
208 }
209 
210 static void
211 do_onepath(const char *name, int key, const char *path)
212 {
213 	long value;
214 
215 	errno = 0;
216 	value = pathconf(path, key);
217 	if (value == -1 && errno != EINVAL && errno != 0)
218 		warn("pathconf: %s", name);
219 	printf("%s: ", name);
220 	if (value == -1)
221 		printf("undefined\n");
222 	else
223 		printf("%ld\n", value);
224 }
225 
226 static void
227 do_allpath(const char *path)
228 {
229 
230 	foreach_pathconf(do_onepath, path);
231 }
232 
233 static void
234 do_confstr(const char *name, int key)
235 {
236 	size_t len;
237 	int savederr;
238 
239 	savederr = errno;
240 	errno = 0;
241 	len = confstr(key, 0, 0);
242 	if (len == 0) {
243 		if (errno)
244 			err(EX_OSERR, "confstr: %s", name);
245 		else
246 			printf("undefined\n");
247 	} else {
248 		char buf[len + 1];
249 
250 		confstr(key, buf, len);
251 		printf("%s\n", buf);
252 	}
253 	errno = savederr;
254 }
255 
256 static void
257 do_sysconf(const char *name, int key)
258 {
259 	long value;
260 
261 	errno = 0;
262 	value = sysconf(key);
263 	if (value == -1 && errno != 0)
264 		err(EX_OSERR, "sysconf: %s", name);
265 	else if (value == -1)
266 		printf("undefined\n");
267 	else
268 		printf("%ld\n", value);
269 }
270 
271 static void
272 do_pathconf(const char *name, int key, const char *path)
273 {
274 	long value;
275 
276 	errno = 0;
277 	value = pathconf(path, key);
278 	if (value == -1 && errno != 0)
279 		err(EX_OSERR, "pathconf: %s", name);
280 	else if (value == -1)
281 		printf("undefined\n");
282 	else
283 		printf("%ld\n", value);
284 }
285 
286