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