1139969Simp/*- 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$"); 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); 40251156Sdelphijstatic int kgetenv(const char *); 41251156Sdelphijstatic int ksetenv(const char *, char *); 42251156Sdelphijstatic int kunsetenv(const char *); 4362813Speter 4494937Smuxstatic int hflag = 0; 45236118Smdfstatic int Nflag = 0; 46150101Srwatsonstatic int qflag = 0; 4794937Smuxstatic int uflag = 0; 48236118Smdfstatic int vflag = 0; 4994937Smux 5062813Speterstatic void 5162813Speterusage(void) 5262813Speter{ 5394937Smux (void)fprintf(stderr, "%s\n%s\n%s\n", 54236118Smdf "usage: kenv [-hNq]", 55236118Smdf " kenv [-qv] variable[=value]", 56150101Srwatson " kenv [-q] -u variable"); 5786404Sdd exit(1); 5862813Speter} 5962813Speter 6062813Speterint 6162813Spetermain(int argc, char **argv) 6262813Speter{ 6394937Smux char *env, *eq, *val; 6494937Smux int ch, error; 6562813Speter 6694937Smux error = 0; 6794937Smux val = NULL; 6862813Speter env = NULL; 69236118Smdf while ((ch = getopt(argc, argv, "hNquv")) != -1) { 7062813Speter switch (ch) { 7162813Speter case 'h': 7262813Speter hflag++; 7362813Speter break; 74236118Smdf case 'N': 75236118Smdf Nflag++; 76236118Smdf break; 77150101Srwatson case 'q': 78150101Srwatson qflag++; 79150101Srwatson break; 8094937Smux case 'u': 8194937Smux uflag++; 8294937Smux break; 83236118Smdf case 'v': 84236118Smdf vflag++; 85236118Smdf break; 8662813Speter default: 8762813Speter usage(); 8862813Speter } 8962813Speter } 9062813Speter argc -= optind; 9162813Speter argv += optind; 9262813Speter if (argc > 0) { 9362813Speter env = argv[0]; 9494937Smux eq = strchr(env, '='); 9594937Smux if (eq != NULL) { 9694937Smux *eq++ = '\0'; 9794937Smux val = eq; 9894937Smux } 9962813Speter argv++; 10062813Speter argc--; 10162813Speter } 102236118Smdf if ((hflag || Nflag) && env != NULL) 10362813Speter usage(); 104236118Smdf if (argc > 0 || ((uflag || vflag) && env == NULL)) 10594937Smux usage(); 106128698Sdas if (env == NULL) { 107128698Sdas error = kdumpenv(); 108150101Srwatson if (error && !qflag) 109128698Sdas warn("kdumpenv"); 110128698Sdas } else if (val == NULL) { 11194937Smux if (uflag) { 11294937Smux error = kunsetenv(env); 113150101Srwatson if (error && !qflag) 11494937Smux warnx("unable to unset %s", env); 11594937Smux } else { 11694937Smux error = kgetenv(env); 117150101Srwatson if (error && !qflag) 11894937Smux warnx("unable to get %s", env); 11962813Speter } 12094937Smux } else { 12194937Smux error = ksetenv(env, val); 122150101Srwatson if (error && !qflag) 12394937Smux warnx("unable to set %s to %s", env, val); 12494937Smux } 12594937Smux return (error); 12694937Smux} 12794937Smux 12894937Smuxstatic int 129201177Sedkdumpenv(void) 13094937Smux{ 13194937Smux char *buf, *cp; 132128698Sdas int buflen, envlen; 13394937Smux 134128698Sdas envlen = kenv(KENV_DUMP, NULL, NULL, 0); 135128698Sdas if (envlen < 0) 13694937Smux return (-1); 137128698Sdas for (;;) { 138128698Sdas buflen = envlen * 120 / 100; 139128698Sdas buf = malloc(buflen + 1); 140128698Sdas if (buf == NULL) 141128698Sdas return (-1); 142128698Sdas memset(buf, 0, buflen + 1); /* Be defensive */ 143128698Sdas envlen = kenv(KENV_DUMP, NULL, buf, buflen); 144128698Sdas if (envlen < 0) { 145128698Sdas free(buf); 146128698Sdas return (-1); 147128698Sdas } 148128698Sdas if (envlen > buflen) 149128698Sdas free(buf); 150128698Sdas else 151128698Sdas break; 152128698Sdas } 153128698Sdas 15494937Smux for (; *buf != '\0'; buf += strlen(buf) + 1) { 15562813Speter if (hflag) { 15694937Smux if (strncmp(buf, "hint.", 5) != 0) 15762813Speter continue; 15862813Speter } 15994937Smux cp = strchr(buf, '='); 16094937Smux if (cp == NULL) 16194937Smux continue; 16294937Smux *cp++ = '\0'; 163236118Smdf if (Nflag) 164236118Smdf printf("%s\n", buf); 165236118Smdf else 166236118Smdf printf("%s=\"%s\"\n", buf, cp); 16794937Smux buf = cp; 16862813Speter } 16994937Smux return (0); 17062813Speter} 17194937Smux 17294937Smuxstatic int 173251156Sdelphijkgetenv(const char *env) 17494937Smux{ 17594937Smux char buf[1024]; 17694937Smux int ret; 17794937Smux 17894937Smux ret = kenv(KENV_GET, env, buf, sizeof(buf)); 17994937Smux if (ret == -1) 18094937Smux return (ret); 181236118Smdf if (vflag) 182236118Smdf printf("%s=\"%s\"\n", env, buf); 183236118Smdf else 184236118Smdf printf("%s\n", buf); 18594937Smux return (0); 18694937Smux} 18794937Smux 18894937Smuxstatic int 189251156Sdelphijksetenv(const char *env, char *val) 19094937Smux{ 19194937Smux int ret; 19294937Smux 19394937Smux ret = kenv(KENV_SET, env, val, strlen(val)+1); 19494937Smux if (ret == 0) 19594937Smux printf("%s=\"%s\"\n", env, val); 19694937Smux return (ret); 19794937Smux} 19894937Smux 19994937Smuxstatic int 200251156Sdelphijkunsetenv(const char *env) 20194937Smux{ 20294937Smux int ret; 20394937Smux 20494937Smux ret = kenv(KENV_UNSET, env, NULL, 0); 20594937Smux return (ret); 20694937Smux} 207