xref: /dragonfly/usr.bin/kenv/kenv.c (revision 67640b13)
1 /*
2  * Copyright (c) 2000  Peter Wemm <peter@freebsd.org>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  * $FreeBSD: src/usr.bin/kenv/kenv.c,v 1.1.2.2 2001/12/19 04:52:15 dd Exp $
26  * $DragonFly: src/usr.bin/kenv/kenv.c,v 1.3 2005/02/25 14:55:51 joerg Exp $
27  */
28 #include <sys/types.h>
29 #include <sys/sysctl.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <err.h>
35 #include <unistd.h>
36 
37 static char sbuf[1024];
38 
39 static void
40 usage(void)
41 {
42 	(void)fprintf(stderr, "usage: kenv [-h] [variable]\n");
43 	exit(1);
44 }
45 
46 int
47 main(int argc, char **argv)
48 {
49 	int real_oid[CTL_MAXNAME];
50 	size_t oidlen, slen;
51 	int ch, error, hflag, i;
52 	char *env, *eq, *var, *val;
53 
54 	hflag = 0;
55 	env = NULL;
56 	while ((ch = getopt(argc, argv, "h")) != -1) {
57 		switch (ch) {
58 		case 'h':
59 			hflag++;
60 			break;
61 		default:
62 			usage();
63 		}
64 	}
65 	argc -= optind;
66 	argv += optind;
67 	if (argc > 0) {
68 		env = argv[0];
69 		argv++;
70 		argc--;
71 	}
72 	if (argc > 0)
73 		usage();
74 	oidlen = __arysize(real_oid);
75 	error = sysctlnametomib("kern.environment", real_oid, &oidlen);
76 	if (error)
77 		err(1, "cannot find kern.environment base sysctl OID");
78 	if (oidlen + 1 >= __arysize(real_oid))
79 		errx(1, "kern.environment base OID too large");
80 	real_oid[oidlen] = 0;
81 	for (i = 0; ; i++) {
82 		real_oid[oidlen + 1] = i;
83 		slen = sizeof(sbuf) - 1;
84 		error = sysctl(real_oid, oidlen + 2, sbuf, &slen, NULL, 0);
85 		if (error < 0) {
86 			if (errno != ENOENT)
87 				err(1, "sysctl kern.environment.%d\n", i);
88 			break;
89 		}
90 		sbuf[sizeof(sbuf) - 1] = '\0';
91 		eq = strchr(sbuf, '=');
92 		if (eq == NULL)
93 			err(1, "malformed environment string: %s\n", sbuf);
94 		var = sbuf;
95 		*eq = '\0';
96 		val = eq + 1;
97 		if (env) {
98 			if (strcmp(var, env) != 0)
99 				continue;
100 			printf("%s\n", val);
101 			break;
102 		}
103 		if (hflag) {
104 			if (strncmp(var, "hint.", 5) != 0)
105 				continue;
106 			/* FALLTHROUGH */
107 		}
108 		printf("%s=\"", var);
109 		while (*val) {
110 			switch (*val) {
111 			case '"':
112 				putchar('\\');
113 				putchar('"');
114 				break;
115 			case '\\':
116 				putchar('\\');
117 				putchar('\\');
118 				break;
119 			default:
120 				putchar(*val);
121 				break;
122 			}
123 			val++;
124 		}
125 		printf("\"\n");
126 	}
127 	exit(0);
128 }
129