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
42static void	do_allsys(void);
43static void	do_allpath(const char *path);
44static void	do_confstr(const char *name, int key);
45static void	do_sysconf(const char *name, int key);
46static void	do_pathconf(const char *name, int key, const char *path);
47
48static void
49usage(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
58int
59main(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
162static void
163do_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
184static void
185do_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
202static void
203do_allsys(void)
204{
205
206	foreach_confstr(do_onestr);
207	foreach_sysconf(do_onesys);
208}
209
210static void
211do_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
226static void
227do_allpath(const char *path)
228{
229
230	foreach_pathconf(do_onepath, path);
231}
232
233static void
234do_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
256static void
257do_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
271static void
272do_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