xref: /dragonfly/usr.bin/kenv/kenv.c (revision 2cd2d2b5)
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.2 2003/06/17 04:29:27 dillon 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 name2oid_oid[2];
50 	int real_oid[CTL_MAXNAME+4];
51 	size_t oidlen;
52 	int ch, error, hflag, i, slen;
53 	char *env, *eq, *name, *var, *val;
54 
55 	hflag = 0;
56 	env = NULL;
57 	while ((ch = getopt(argc, argv, "h")) != -1) {
58 		switch (ch) {
59 		case 'h':
60 			hflag++;
61 			break;
62 		default:
63 			usage();
64 		}
65 	}
66 	argc -= optind;
67 	argv += optind;
68 	if (argc > 0) {
69 		env = argv[0];
70 		argv++;
71 		argc--;
72 	}
73 	if (argc > 0)
74 		usage();
75 	name2oid_oid[0] = 0;	/* This is magic & undocumented! */
76 	name2oid_oid[1] = 3;
77 	oidlen = sizeof(real_oid);
78 	name = "kern.environment";
79 	error = sysctl(name2oid_oid, 2, real_oid, &oidlen, name, strlen(name));
80 	if (error < 0)
81 		err(1, "cannot find kern.environment base sysctl OID");
82 	oidlen /= sizeof (int);
83 	if (oidlen >= CTL_MAXNAME)
84 		errx(1, "kern.environment OID is too large!");
85 	real_oid[oidlen] = 0;
86 	for (i = 0; ; i++) {
87 		real_oid[oidlen + 1] = i;
88 		slen = sizeof(sbuf) - 1;
89 		error = sysctl(real_oid, oidlen + 2, sbuf, &slen, NULL, 0);
90 		if (error < 0) {
91 			if (errno != ENOENT)
92 				err(1, "sysctl kern.environment.%d\n", i);
93 			break;
94 		}
95 		sbuf[sizeof(sbuf) - 1] = '\0';
96 		eq = strchr(sbuf, '=');
97 		if (eq == NULL)
98 			err(1, "malformed environment string: %s\n", sbuf);
99 		var = sbuf;
100 		*eq = '\0';
101 		val = eq + 1;
102 		if (env) {
103 			if (strcmp(var, env) != 0)
104 				continue;
105 			printf("%s\n", val);
106 			break;
107 		}
108 		if (hflag) {
109 			if (strncmp(var, "hint.", 5) != 0)
110 				continue;
111 			/* FALLTHROUGH */
112 		}
113 		printf("%s=\"", var);
114 		while (*val) {
115 			switch (*val) {
116 			case '"':
117 				putchar('\\');
118 				putchar('"');
119 				break;
120 			case '\\':
121 				putchar('\\');
122 				putchar('\\');
123 				break;
124 			default:
125 				putchar(*val);
126 				break;
127 			}
128 			val++;
129 		}
130 		printf("\"\n");
131 	}
132 	exit(0);
133 }
134