]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - bin/kenv/kenv.c
cdn-patch: fix checkyesno warning in efi keysource
[FreeBSD/FreeBSD.git] / bin / kenv / kenv.c
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$");
28
29 #include <sys/types.h>
30 #include <sys/sysctl.h>
31 #include <err.h>
32 #include <errno.h>
33 #include <kenv.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38
39 static void     usage(void);
40 static int      kdumpenv(int dump_type);
41 static int      kgetenv(const char *);
42 static int      ksetenv(const char *, char *);
43 static int      kunsetenv(const char *);
44
45 static int hflag = 0;
46 static int lflag = 0;
47 static int Nflag = 0;
48 static int qflag = 0;
49 static int sflag = 0;
50 static int uflag = 0;
51 static int vflag = 0;
52
53 static void
54 usage(void)
55 {
56         (void)fprintf(stderr, "%s\n%s\n%s\n",
57             "usage: kenv [-l|-s] [-hNq]",
58             "       kenv [-qv] variable[=value]",
59             "       kenv [-q] -u variable");
60         exit(1);
61 }
62
63 int
64 main(int argc, char **argv)
65 {
66         char *env, *eq, *val;
67         int ch, error;
68
69         val = NULL;
70         env = NULL;
71         while ((ch = getopt(argc, argv, "hlNqsuv")) != -1) {
72                 switch (ch) {
73                 case 'h':
74                         hflag++;
75                         break;
76                 case 'l':
77                         lflag++;
78                         break;
79                 case 'N':
80                         Nflag++;
81                         break;
82                 case 'q':
83                         qflag++;
84                         break;
85                 case 's':
86                         sflag++;
87                         break;
88                 case 'u':
89                         uflag++;
90                         break;
91                 case 'v':
92                         vflag++;
93                         break;
94                 default:
95                         usage();
96                 }
97         }
98         argc -= optind;
99         argv += optind;
100         if (argc > 0) {
101                 env = argv[0];
102                 eq = strchr(env, '=');
103                 if (eq != NULL) {
104                         *eq++ = '\0';
105                         val = eq;
106                 }
107                 argv++;
108                 argc--;
109         }
110         if ((hflag || Nflag) && env != NULL)
111                 usage();
112         if (lflag && sflag)
113                 usage();
114         if (argc > 0 || ((uflag || vflag) && env == NULL))
115                 usage();
116         if (env == NULL) {
117                 if (lflag)
118                         error = kdumpenv(KENV_DUMP_LOADER);
119                 else if (sflag)
120                         error = kdumpenv(KENV_DUMP_STATIC);
121                 else
122                         error = kdumpenv(KENV_DUMP);
123                 if (error && !qflag) {
124                         if (errno == ENOENT)
125                                 warnx("requested environment is unavailable");
126                         else
127                                 warn("kdumpenv");
128                 }
129         } else if (val == NULL) {
130                 if (uflag) {
131                         error = kunsetenv(env);
132                         if (error && !qflag)
133                                 warnx("unable to unset %s", env);
134                 } else {
135                         error = kgetenv(env);
136                         if (error && !qflag)
137                                 warnx("unable to get %s", env);
138                 }
139         } else {
140                 error = ksetenv(env, val);
141                 if (error && !qflag)
142                         warnx("unable to set %s to %s", env, val);
143         }
144         return (error);
145 }
146
147 static int
148 kdumpenv(int dump_type)
149 {
150         char *buf, *bp, *cp;
151         int buflen, envlen;
152
153         envlen = kenv(dump_type, NULL, NULL, 0);
154         if (envlen < 0)
155                 return (-1);
156         for (;;) {
157                 buflen = envlen * 120 / 100;
158                 buf = calloc(1, buflen + 1);
159                 if (buf == NULL)
160                         return (-1);
161                 envlen = kenv(dump_type, NULL, buf, buflen);
162                 if (envlen < 0) {
163                         free(buf);
164                         return (-1);
165                 }
166                 if (envlen > buflen)
167                         free(buf);
168                 else
169                         break;
170         }
171
172         for (bp = buf; *bp != '\0'; bp += strlen(bp) + 1) {
173                 if (hflag) {
174                         if (strncmp(bp, "hint.", 5) != 0)
175                                 continue;
176                 }
177                 cp = strchr(bp, '=');
178                 if (cp == NULL)
179                         continue;
180                 *cp++ = '\0';
181                 if (Nflag)
182                         printf("%s\n", bp);
183                 else
184                         printf("%s=\"%s\"\n", bp, cp);
185                 bp = cp;
186         }
187
188         free(buf);
189         return (0);
190 }
191
192 static int
193 kgetenv(const char *env)
194 {
195         char buf[1024];
196         int ret;
197
198         ret = kenv(KENV_GET, env, buf, sizeof(buf));
199         if (ret == -1)
200                 return (ret);
201         if (vflag)
202                 printf("%s=\"%s\"\n", env, buf);
203         else
204                 printf("%s\n", buf);
205         return (0);
206 }
207
208 static int
209 ksetenv(const char *env, char *val)
210 {
211         int ret;
212
213         ret = kenv(KENV_SET, env, val, strlen(val) + 1);
214         if (ret == 0)
215                 printf("%s=\"%s\"\n", env, val);
216         return (ret);
217 }
218
219 static int
220 kunsetenv(const char *env)
221 {
222         int ret;
223
224         ret = kenv(KENV_UNSET, env, NULL, 0);
225         return (ret);
226 }