kenv.c revision 128698
162813Speter/*
262813Speter * Copyright (c) 2000  Peter Wemm <peter@freebsd.org>
362813Speter *
462813Speter * Redistribution and use in source and binary forms, with or without
562813Speter * modification, are permitted provided that the following conditions
662813Speter * are met:
762813Speter * 1. Redistributions of source code must retain the above copyright
862813Speter *    notice, this list of conditions and the following disclaimer.
962813Speter * 2. Redistributions in binary form must reproduce the above copyright
1062813Speter *    notice, this list of conditions and the following disclaimer in the
1162813Speter *    documentation and/or other materials provided with the distribution.
1262813Speter *
1362813Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
1462813Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1562813Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1662813Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
1762813Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1862813Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1962813Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2062813Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2162813Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2262813Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2362813Speter * SUCH DAMAGE.
2462813Speter */
2599112Sobrien
2699112Sobrien#include <sys/cdefs.h>
2799112Sobrien__FBSDID("$FreeBSD: head/bin/kenv/kenv.c 128698 2004-04-28 01:27:36Z das $");
2899112Sobrien
2962813Speter#include <sys/types.h>
3062813Speter#include <sys/sysctl.h>
31128698Sdas#include <err.h>
32128698Sdas#include <kenv.h>
33128698Sdas#include <stdio.h>
3462813Speter#include <stdlib.h>
3562813Speter#include <string.h>
3662813Speter#include <unistd.h>
3762813Speter
3894937Smuxstatic void	usage(void);
3994937Smuxstatic int	kdumpenv(void);
4094937Smuxstatic int	kgetenv(char *);
4194937Smuxstatic int	ksetenv(char *, char *);
4294937Smuxstatic int	kunsetenv(char *);
4362813Speter
4494937Smuxstatic int hflag = 0;
4594937Smuxstatic int uflag = 0;
4694937Smux
4762813Speterstatic void
4862813Speterusage(void)
4962813Speter{
5094937Smux	(void)fprintf(stderr, "%s\n%s\n%s\n",
5194937Smux	    "usage: kenv [-h]",
5294937Smux	    "       kenv variable[=value]",
5394937Smux	    "       kenv -u variable");
5486404Sdd	exit(1);
5562813Speter}
5662813Speter
5762813Speterint
5862813Spetermain(int argc, char **argv)
5962813Speter{
6094937Smux	char *env, *eq, *val;
6194937Smux	int ch, error;
6262813Speter
6394937Smux	error = 0;
6494937Smux	val = NULL;
6562813Speter	env = NULL;
6694937Smux	while ((ch = getopt(argc, argv, "hu")) != -1) {
6762813Speter		switch (ch) {
6862813Speter		case 'h':
6962813Speter			hflag++;
7062813Speter			break;
7194937Smux		case 'u':
7294937Smux			uflag++;
7394937Smux			break;
7462813Speter		default:
7562813Speter			usage();
7662813Speter		}
7762813Speter	}
7862813Speter	argc -= optind;
7962813Speter	argv += optind;
8062813Speter	if (argc > 0) {
8162813Speter		env = argv[0];
8294937Smux		eq = strchr(env, '=');
8394937Smux		if (eq != NULL) {
8494937Smux			*eq++ = '\0';
8594937Smux			val = eq;
8694937Smux		}
8762813Speter		argv++;
8862813Speter		argc--;
8962813Speter	}
9094937Smux	if (hflag && (env != NULL))
9162813Speter		usage();
9294937Smux	if ((argc > 0) || (uflag && (env == NULL)))
9394937Smux		usage();
94128698Sdas	if (env == NULL) {
95128698Sdas		error = kdumpenv();
96128698Sdas		if (error)
97128698Sdas			warn("kdumpenv");
98128698Sdas	} else if (val == NULL) {
9994937Smux		if (uflag) {
10094937Smux			error = kunsetenv(env);
10194937Smux			if (error)
10294937Smux				warnx("unable to unset %s", env);
10394937Smux		} else {
10494937Smux			error = kgetenv(env);
10594937Smux			if (error)
10694937Smux				warnx("unable to get %s", env);
10762813Speter		}
10894937Smux	} else {
10994937Smux		error = ksetenv(env, val);
11094937Smux		if (error)
11194937Smux			warnx("unable to set %s to %s", env, val);
11294937Smux	}
11394937Smux	return (error);
11494937Smux}
11594937Smux
11694937Smuxstatic int
11794937Smuxkdumpenv()
11894937Smux{
11994937Smux	char *buf, *cp;
120128698Sdas	int buflen, envlen;
12194937Smux
122128698Sdas	envlen = kenv(KENV_DUMP, NULL, NULL, 0);
123128698Sdas	if (envlen < 0)
12494937Smux		return (-1);
125128698Sdas	for (;;) {
126128698Sdas		buflen = envlen * 120 / 100;
127128698Sdas		buf = malloc(buflen + 1);
128128698Sdas		if (buf == NULL)
129128698Sdas			return (-1);
130128698Sdas		memset(buf, 0, buflen + 1);	/* Be defensive */
131128698Sdas		envlen = kenv(KENV_DUMP, NULL, buf, buflen);
132128698Sdas		if (envlen < 0) {
133128698Sdas			free(buf);
134128698Sdas			return (-1);
135128698Sdas		}
136128698Sdas		if (envlen > buflen)
137128698Sdas			free(buf);
138128698Sdas		else
139128698Sdas			break;
140128698Sdas	}
141128698Sdas
14294937Smux	for (; *buf != '\0'; buf += strlen(buf) + 1) {
14362813Speter		if (hflag) {
14494937Smux			if (strncmp(buf, "hint.", 5) != 0)
14562813Speter				continue;
14662813Speter		}
14794937Smux		cp = strchr(buf, '=');
14894937Smux		if (cp == NULL)
14994937Smux			continue;
15094937Smux		*cp++ = '\0';
15194937Smux		printf("%s=\"%s\"\n", buf, cp);
15294937Smux		buf = cp;
15362813Speter	}
15494937Smux	return (0);
15562813Speter}
15694937Smux
15794937Smuxstatic int
15894937Smuxkgetenv(char *env)
15994937Smux{
16094937Smux	char buf[1024];
16194937Smux	int ret;
16294937Smux
16394937Smux	ret = kenv(KENV_GET, env, buf, sizeof(buf));
16494937Smux	if (ret == -1)
16594937Smux		return (ret);
16694937Smux	printf("%s\n", buf);
16794937Smux	return (0);
16894937Smux}
16994937Smux
17094937Smuxstatic int
17194937Smuxksetenv(char *env, char *val)
17294937Smux{
17394937Smux	int ret;
17494937Smux
17594937Smux	ret = kenv(KENV_SET, env, val, strlen(val)+1);
17694937Smux	if (ret == 0)
17794937Smux		printf("%s=\"%s\"\n", env, val);
17894937Smux	return (ret);
17994937Smux}
18094937Smux
18194937Smuxstatic int
18294937Smuxkunsetenv(char *env)
18394937Smux{
18494937Smux	int ret;
18594937Smux
18694937Smux	ret = kenv(KENV_UNSET, env, NULL, 0);
18794937Smux	return (ret);
18894937Smux}
189