aboutsummaryrefslogtreecommitdiff
path: root/bin/kenv
diff options
context:
space:
mode:
authorMaxime Henrion <mux@FreeBSD.org>2002-04-17 13:08:14 +0000
committerMaxime Henrion <mux@FreeBSD.org>2002-04-17 13:08:14 +0000
commit41196280aca35b06bb55ebb4bb855b401959fd85 (patch)
treefa41b138f6f660725a488c2b9cf51a3a4daa1e50 /bin/kenv
parentd786139c76ad8d7cd25f962f7e67d4af98685418 (diff)
downloadsrc-41196280aca35b06bb55ebb4bb855b401959fd85.tar.gz
src-41196280aca35b06bb55ebb4bb855b401959fd85.zip
Use the new functionalities provided by the kenv(2) syscall.
Reviewed by: peter
Notes
Notes: svn path=/head/; revision=94937
Diffstat (limited to 'bin/kenv')
-rw-r--r--bin/kenv/Makefile1
-rw-r--r--bin/kenv/kenv.120
-rw-r--r--bin/kenv/kenv.c167
3 files changed, 122 insertions, 66 deletions
diff --git a/bin/kenv/Makefile b/bin/kenv/Makefile
index 33a6dfc3bff5..0dffae599847 100644
--- a/bin/kenv/Makefile
+++ b/bin/kenv/Makefile
@@ -1,5 +1,6 @@
# $FreeBSD$
PROG= kenv
+WARNS?= 4
.include <bsd.prog.mk>
diff --git a/bin/kenv/kenv.1 b/bin/kenv/kenv.1
index fb0e050afbdc..241b49074933 100644
--- a/bin/kenv/kenv.1
+++ b/bin/kenv/kenv.1
@@ -28,15 +28,20 @@
.Os
.Sh NAME
.Nm kenv
-.Nd dump the kernel environment
+.Nd dump or modify the kernel environment
.Sh SYNOPSIS
.Nm
.Op Fl h
-.Op Ar variable
+.Nm
+.Ar variable Ns Op = Ns Ar value
+.Nm
+.Fl u
+.Ar variable
.Sh DESCRIPTION
The
.Nm
-utility will dump the kernel environment.
+utility will dump the kernel environment if
+invoked without arguments.
If the
.Fl h
option is specified, it will limit the report to kernel probe hints.
@@ -45,6 +50,15 @@ If an optional
name is specified,
.Nm
will only report that value.
+If the
+.Fl u
+option is specified,
+.Nm
+will delete the given environment variable.
+If the environment variable is followed by an optional
+.Ar value
+.Nm
+will set the environment variable to this value.
.Sh SEE ALSO
.Xr loader 8
.Sh HISTORY
diff --git a/bin/kenv/kenv.c b/bin/kenv/kenv.c
index 4704d510fd2f..622458d5f132 100644
--- a/bin/kenv/kenv.c
+++ b/bin/kenv/kenv.c
@@ -31,33 +31,45 @@
#include <string.h>
#include <errno.h>
#include <err.h>
+#include <kenv.h>
#include <unistd.h>
-static char sbuf[1024];
+static void usage(void);
+static int kdumpenv(void);
+static int kgetenv(char *);
+static int ksetenv(char *, char *);
+static int kunsetenv(char *);
+
+static int hflag = 0;
+static int uflag = 0;
static void
usage(void)
{
- (void)fprintf(stderr, "usage: kenv [-h] [variable]\n");
+ (void)fprintf(stderr, "%s\n%s\n%s\n",
+ "usage: kenv [-h]",
+ " kenv variable[=value]",
+ " kenv -u variable");
exit(1);
}
int
main(int argc, char **argv)
{
- int name2oid_oid[2];
- int real_oid[CTL_MAXNAME+4];
- size_t oidlen;
- int ch, error, hflag, i, slen;
- char *env, *eq, *name, *var, *val;
+ char *env, *eq, *val;
+ int ch, error;
- hflag = 0;
+ error = 0;
+ val = NULL;
env = NULL;
- while ((ch = getopt(argc, argv, "h")) != -1) {
+ while ((ch = getopt(argc, argv, "hu")) != -1) {
switch (ch) {
case 'h':
hflag++;
break;
+ case 'u':
+ uflag++;
+ break;
default:
usage();
}
@@ -66,67 +78,96 @@ main(int argc, char **argv)
argv += optind;
if (argc > 0) {
env = argv[0];
+ eq = strchr(env, '=');
+ if (eq != NULL) {
+ *eq++ = '\0';
+ val = eq;
+ }
argv++;
argc--;
}
- if (argc > 0)
+ if (hflag && (env != NULL))
usage();
- name2oid_oid[0] = 0; /* This is magic & undocumented! */
- name2oid_oid[1] = 3;
- oidlen = sizeof(real_oid);
- name = "kern.environment";
- error = sysctl(name2oid_oid, 2, real_oid, &oidlen, name, strlen(name));
- if (error < 0)
- err(1, "cannot find kern.environment base sysctl OID");
- oidlen /= sizeof (int);
- if (oidlen >= CTL_MAXNAME)
- errx(1, "kern.environment OID is too large!");
- real_oid[oidlen] = 0;
- for (i = 0; ; i++) {
- real_oid[oidlen + 1] = i;
- slen = sizeof(sbuf) - 1;
- error = sysctl(real_oid, oidlen + 2, sbuf, &slen, NULL, 0);
- if (error < 0) {
- if (errno != ENOENT)
- err(1, "sysctl kern.environment.%d\n", i);
- break;
- }
- sbuf[sizeof(sbuf) - 1] = '\0';
- eq = strchr(sbuf, '=');
- if (eq == NULL)
- err(1, "malformed environment string: %s\n", sbuf);
- var = sbuf;
- *eq = '\0';
- val = eq + 1;
- if (env) {
- if (strcmp(var, env) != 0)
- continue;
- printf("%s\n", val);
- break;
+ if ((argc > 0) || (uflag && (env == NULL)))
+ usage();
+ if (env == NULL)
+ kdumpenv();
+ else if (val == NULL) {
+ if (uflag) {
+ error = kunsetenv(env);
+ if (error)
+ warnx("unable to unset %s", env);
+ } else {
+ error = kgetenv(env);
+ if (error)
+ warnx("unable to get %s", env);
}
+ } else {
+ error = ksetenv(env, val);
+ if (error)
+ warnx("unable to set %s to %s", env, val);
+ }
+ return (error);
+}
+
+static int
+kdumpenv()
+{
+ char *buf, *cp;
+ int len;
+
+ len = kenv(KENV_DUMP, NULL, NULL, 0);
+ len = len * 120 / 100;
+ buf = malloc(len);
+ if (buf == NULL)
+ return (-1);
+ /* Be defensive */
+ memset(buf, 0, len);
+ kenv(KENV_DUMP, NULL, buf, len);
+ for (; *buf != '\0'; buf += strlen(buf) + 1) {
if (hflag) {
- if (strncmp(var, "hint.", 5) != 0)
+ if (strncmp(buf, "hint.", 5) != 0)
continue;
- /* FALLTHROUGH */
}
- printf("%s=\"", var);
- while (*val) {
- switch (*val) {
- case '"':
- putchar('\\');
- putchar('"');
- break;
- case '\\':
- putchar('\\');
- putchar('\\');
- break;
- default:
- putchar(*val);
- break;
- }
- val++;
- }
- printf("\"\n");
+ cp = strchr(buf, '=');
+ if (cp == NULL)
+ continue;
+ *cp++ = '\0';
+ printf("%s=\"%s\"\n", buf, cp);
+ buf = cp;
}
- exit(0);
+ return (0);
+}
+
+static int
+kgetenv(char *env)
+{
+ char buf[1024];
+ int ret;
+
+ ret = kenv(KENV_GET, env, buf, sizeof(buf));
+ if (ret == -1)
+ return (ret);
+ printf("%s\n", buf);
+ return (0);
+}
+
+static int
+ksetenv(char *env, char *val)
+{
+ int ret;
+
+ ret = kenv(KENV_SET, env, val, strlen(val)+1);
+ if (ret == 0)
+ printf("%s=\"%s\"\n", env, val);
+ return (ret);
+}
+
+static int
+kunsetenv(char *env)
+{
+ int ret;
+
+ ret = kenv(KENV_UNSET, env, NULL, 0);
+ return (ret);
}