xref: /freebsd/bin/kenv/kenv.c (revision 3157ba21)
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 
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28 
29 #include <sys/types.h>
30 #include <sys/sysctl.h>
31 #include <err.h>
32 #include <kenv.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37 
38 static void	usage(void);
39 static int	kdumpenv(void);
40 static int	kgetenv(char *);
41 static int	ksetenv(char *, char *);
42 static int	kunsetenv(char *);
43 
44 static int hflag = 0;
45 static int qflag = 0;
46 static int uflag = 0;
47 
48 static void
49 usage(void)
50 {
51 	(void)fprintf(stderr, "%s\n%s\n%s\n",
52 	    "usage: kenv [-hq]",
53 	    "       kenv [-q] variable[=value]",
54 	    "       kenv [-q] -u variable");
55 	exit(1);
56 }
57 
58 int
59 main(int argc, char **argv)
60 {
61 	char *env, *eq, *val;
62 	int ch, error;
63 
64 	error = 0;
65 	val = NULL;
66 	env = NULL;
67 	while ((ch = getopt(argc, argv, "hqu")) != -1) {
68 		switch (ch) {
69 		case 'h':
70 			hflag++;
71 			break;
72 		case 'q':
73 			qflag++;
74 			break;
75 		case 'u':
76 			uflag++;
77 			break;
78 		default:
79 			usage();
80 		}
81 	}
82 	argc -= optind;
83 	argv += optind;
84 	if (argc > 0) {
85 		env = argv[0];
86 		eq = strchr(env, '=');
87 		if (eq != NULL) {
88 			*eq++ = '\0';
89 			val = eq;
90 		}
91 		argv++;
92 		argc--;
93 	}
94 	if (hflag && (env != NULL))
95 		usage();
96 	if ((argc > 0) || (uflag && (env == NULL)))
97 		usage();
98 	if (env == NULL) {
99 		error = kdumpenv();
100 		if (error && !qflag)
101 			warn("kdumpenv");
102 	} else if (val == NULL) {
103 		if (uflag) {
104 			error = kunsetenv(env);
105 			if (error && !qflag)
106 				warnx("unable to unset %s", env);
107 		} else {
108 			error = kgetenv(env);
109 			if (error && !qflag)
110 				warnx("unable to get %s", env);
111 		}
112 	} else {
113 		error = ksetenv(env, val);
114 		if (error && !qflag)
115 			warnx("unable to set %s to %s", env, val);
116 	}
117 	return (error);
118 }
119 
120 static int
121 kdumpenv(void)
122 {
123 	char *buf, *cp;
124 	int buflen, envlen;
125 
126 	envlen = kenv(KENV_DUMP, NULL, NULL, 0);
127 	if (envlen < 0)
128 		return (-1);
129 	for (;;) {
130 		buflen = envlen * 120 / 100;
131 		buf = malloc(buflen + 1);
132 		if (buf == NULL)
133 			return (-1);
134 		memset(buf, 0, buflen + 1);	/* Be defensive */
135 		envlen = kenv(KENV_DUMP, NULL, buf, buflen);
136 		if (envlen < 0) {
137 			free(buf);
138 			return (-1);
139 		}
140 		if (envlen > buflen)
141 			free(buf);
142 		else
143 			break;
144 	}
145 
146 	for (; *buf != '\0'; buf += strlen(buf) + 1) {
147 		if (hflag) {
148 			if (strncmp(buf, "hint.", 5) != 0)
149 				continue;
150 		}
151 		cp = strchr(buf, '=');
152 		if (cp == NULL)
153 			continue;
154 		*cp++ = '\0';
155 		printf("%s=\"%s\"\n", buf, cp);
156 		buf = cp;
157 	}
158 	return (0);
159 }
160 
161 static int
162 kgetenv(char *env)
163 {
164 	char buf[1024];
165 	int ret;
166 
167 	ret = kenv(KENV_GET, env, buf, sizeof(buf));
168 	if (ret == -1)
169 		return (ret);
170 	printf("%s\n", buf);
171 	return (0);
172 }
173 
174 static int
175 ksetenv(char *env, char *val)
176 {
177 	int ret;
178 
179 	ret = kenv(KENV_SET, env, val, strlen(val)+1);
180 	if (ret == 0)
181 		printf("%s=\"%s\"\n", env, val);
182 	return (ret);
183 }
184 
185 static int
186 kunsetenv(char *env)
187 {
188 	int ret;
189 
190 	ret = kenv(KENV_UNSET, env, NULL, 0);
191 	return (ret);
192 }
193