xref: /freebsd/usr.bin/getconf/getconf.c (revision 81ad6265)
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/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #include <sys/types.h>
34 
35 #include <err.h>
36 #include <errno.h>
37 #include <stdbool.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <sysexits.h>
41 #include <unistd.h>
42 
43 #include "getconf.h"
44 
45 static void	do_allsys(void);
46 static void	do_allpath(const char *path);
47 static void	do_confstr(const char *name, int key);
48 static void	do_sysconf(const char *name, int key);
49 static void	do_pathconf(const char *name, int key, const char *path);
50 
51 static void
52 usage(void)
53 {
54 	fprintf(stderr,
55 "usage: getconf -a [pathname]\n"
56 "       getconf [-v prog_env] system_var\n"
57 "       getconf [-v prog_env] path_var pathname\n");
58 	exit(EX_USAGE);
59 }
60 
61 int
62 main(int argc, char **argv)
63 {
64 	bool aflag;
65 	int c, key, valid;
66 	const char *name, *vflag, *alt_path;
67 	intmax_t limitval;
68 	uintmax_t ulimitval;
69 
70 	aflag = false;
71 	vflag = NULL;
72 	while ((c = getopt(argc, argv, "av:")) != -1) {
73 		switch (c) {
74 		case 'a':
75 			aflag = true;
76 			break;
77 		case 'v':
78 			vflag = optarg;
79 			break;
80 
81 		default:
82 			usage();
83 		}
84 	}
85 
86 	if (aflag) {
87 		if (vflag != NULL)
88 			usage();
89 		if (argv[optind] == NULL)
90 			do_allsys();
91 		else
92 			do_allpath(argv[optind]);
93 		return (0);
94 	}
95 
96 	if ((name = argv[optind]) == NULL)
97 		usage();
98 
99 	if (vflag != NULL) {
100 		if ((valid = find_progenv(vflag, &alt_path)) == 0)
101 			errx(EX_USAGE, "invalid programming environment %s",
102 			     vflag);
103 		if (valid > 0 && alt_path != NULL) {
104 			if (argv[optind + 1] == NULL)
105 				execl(alt_path, "getconf", argv[optind],
106 				      (char *)NULL);
107 			else
108 				execl(alt_path, "getconf", argv[optind],
109 				      argv[optind + 1], (char *)NULL);
110 
111 			err(EX_OSERR, "execl: %s", alt_path);
112 		}
113 		if (valid < 0)
114 			errx(EX_UNAVAILABLE, "environment %s is not available",
115 			     vflag);
116 	}
117 
118 	if (argv[optind + 1] == NULL) { /* confstr or sysconf */
119 		if ((valid = find_unsigned_limit(name, &ulimitval)) != 0) {
120 			if (valid > 0)
121 				printf("%" PRIuMAX "\n", ulimitval);
122 			else
123 				printf("undefined\n");
124 			return 0;
125 		}
126 		if ((valid = find_limit(name, &limitval)) != 0) {
127 			if (valid > 0)
128 				printf("%" PRIdMAX "\n", limitval);
129 			else
130 				printf("undefined\n");
131 
132 			return 0;
133 		}
134 		if ((valid = find_confstr(name, &key)) != 0) {
135 			if (valid > 0)
136 				do_confstr(name, key);
137 			else
138 				printf("undefined\n");
139 		} else {
140 			valid = find_sysconf(name, &key);
141 			if (valid > 0) {
142 				do_sysconf(name, key);
143 			} else if (valid < 0) {
144 				printf("undefined\n");
145 			} else
146 				errx(EX_USAGE,
147 				     "no such configuration parameter `%s'",
148 				     name);
149 		}
150 	} else {
151 		valid = find_pathconf(name, &key);
152 		if (valid != 0) {
153 			if (valid > 0)
154 				do_pathconf(name, key, argv[optind + 1]);
155 			else
156 				printf("undefined\n");
157 		} else
158 			errx(EX_USAGE,
159 			     "no such path configuration parameter `%s'",
160 			     name);
161 	}
162 	return 0;
163 }
164 
165 static void
166 do_onestr(const char *name, int key)
167 {
168 	size_t len;
169 
170 	errno = 0;
171 	len = confstr(key, 0, 0);
172 	if (len == 0 && errno != 0) {
173 		warn("confstr: %s", name);
174 		return;
175 	}
176 	printf("%s: ", name);
177 	if (len == 0)
178 		printf("undefined\n");
179 	else {
180 		char buf[len + 1];
181 
182 		confstr(key, buf, len);
183 		printf("%s\n", buf);
184 	}
185 }
186 
187 static void
188 do_onesys(const char *name, int key)
189 {
190 	long value;
191 
192 	errno = 0;
193 	value = sysconf(key);
194 	if (value == -1 && errno != 0) {
195 		warn("sysconf: %s", name);
196 		return;
197 	}
198 	printf("%s: ", name);
199 	if (value == -1)
200 		printf("undefined\n");
201 	else
202 		printf("%ld\n", value);
203 }
204 
205 static void
206 do_allsys(void)
207 {
208 
209 	foreach_confstr(do_onestr);
210 	foreach_sysconf(do_onesys);
211 }
212 
213 static void
214 do_onepath(const char *name, int key, const char *path)
215 {
216 	long value;
217 
218 	errno = 0;
219 	value = pathconf(path, key);
220 	if (value == -1 && errno != EINVAL && errno != 0)
221 		warn("pathconf: %s", name);
222 	printf("%s: ", name);
223 	if (value == -1)
224 		printf("undefined\n");
225 	else
226 		printf("%ld\n", value);
227 }
228 
229 static void
230 do_allpath(const char *path)
231 {
232 
233 	foreach_pathconf(do_onepath, path);
234 }
235 
236 static void
237 do_confstr(const char *name, int key)
238 {
239 	size_t len;
240 	int savederr;
241 
242 	savederr = errno;
243 	errno = 0;
244 	len = confstr(key, 0, 0);
245 	if (len == 0) {
246 		if (errno)
247 			err(EX_OSERR, "confstr: %s", name);
248 		else
249 			printf("undefined\n");
250 	} else {
251 		char buf[len + 1];
252 
253 		confstr(key, buf, len);
254 		printf("%s\n", buf);
255 	}
256 	errno = savederr;
257 }
258 
259 static void
260 do_sysconf(const char *name, int key)
261 {
262 	long value;
263 
264 	errno = 0;
265 	value = sysconf(key);
266 	if (value == -1 && errno != 0)
267 		err(EX_OSERR, "sysconf: %s", name);
268 	else if (value == -1)
269 		printf("undefined\n");
270 	else
271 		printf("%ld\n", value);
272 }
273 
274 static void
275 do_pathconf(const char *name, int key, const char *path)
276 {
277 	long value;
278 
279 	errno = 0;
280 	value = pathconf(path, key);
281 	if (value == -1 && errno != 0)
282 		err(EX_OSERR, "pathconf: %s", name);
283 	else if (value == -1)
284 		printf("undefined\n");
285 	else
286 		printf("%ld\n", value);
287 }
288 
289