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