kenv.c revision 225736
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: stable/9/bin/kenv/kenv.c 201177 2009-12-29 08:45:07Z ed $");
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
38static void	usage(void);
39static int	kdumpenv(void);
40static int	kgetenv(char *);
41static int	ksetenv(char *, char *);
42static int	kunsetenv(char *);
43
44static int hflag = 0;
45static int qflag = 0;
46static int uflag = 0;
47
48static void
49usage(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
58int
59main(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
120static int
121kdumpenv(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
161static int
162kgetenv(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
174static int
175ksetenv(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
185static int
186kunsetenv(char *env)
187{
188	int ret;
189
190	ret = kenv(KENV_UNSET, env, NULL, 0);
191	return (ret);
192}
193