]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - usr.sbin/sade/variable.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / usr.sbin / sade / variable.c
1 /*
2  * $FreeBSD$
3  *
4  * Copyright (c) 1995
5  *      Jordan Hubbard.  All rights reserved.
6  * Copyright (c) 2001 
7  *      Murray Stokely.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer,
14  *    verbatim and that no modifications are made prior to this
15  *    point in the file.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  */
33
34 #include "sade.h"
35
36 /* Routines for dealing with variable lists */
37
38 static void
39 make_variable(char *var, char *value, int dirty)
40 {
41     Variable *vp;
42
43     /* Trim leading and trailing whitespace */
44     var = string_skipwhite(string_prune(var));
45
46     if (!var || !*var)
47         return;
48
49
50     /* Now search to see if it's already in the list */
51     for (vp = VarHead; vp; vp = vp->next) {
52         if (!strcmp(vp->name, var)) {
53             if (vp->dirty && !dirty)
54                 return;
55             setenv(var, value, 1);
56             free(vp->value);
57             vp->value = strdup(value);
58             if (dirty != -1)
59                 vp->dirty = dirty;
60             return;
61         }
62     }
63
64     setenv(var, value, 1);
65     /* No?  Create a new one */
66     vp = (Variable *)safe_malloc(sizeof(Variable));
67     vp->name = strdup(var);
68     vp->value = strdup(value);
69     if (dirty == -1)
70         dirty = 0;
71     vp->dirty = dirty;
72     vp->next = VarHead;
73     VarHead = vp;
74 }
75
76 void
77 variable_set(char *var, int dirty)
78 {
79     char tmp[1024], *cp;
80
81     if (!var)
82         msgFatal("NULL variable name & value passed.");
83     else if (!*var)
84         msgDebug("Warning:  Zero length name & value passed to variable_set()\n");
85     SAFE_STRCPY(tmp, var);
86     if ((cp = index(tmp, '=')) == NULL)
87         msgFatal("Invalid variable format: %s", var);
88     *(cp++) = '\0';
89     make_variable(tmp, string_skipwhite(cp), dirty);
90 }
91
92 void
93 variable_set2(char *var, char *value, int dirty)
94 {
95     if (!var || !value)
96         msgFatal("Null name or value passed to set_variable2(%s) = %s!",
97                 var ? var : "", value ? value : "");
98     else if (!*var || !*value)
99         msgDebug("Warning:  Zero length name or value passed to variable_set2(%s) = %s\n",
100                 var, value);
101     make_variable(var, value, dirty);
102 }
103
104 char *
105 variable_get(char *var)
106 {
107     return getenv(var);
108 }
109
110 int
111 variable_cmp(char *var, char *value)
112 {
113     char *val;
114
115     if ((val = variable_get(var)))
116         return strcmp(val, value);
117     return -1;
118 }
119
120 void
121 variable_unset(char *var)
122 {
123     Variable *vp;
124     char name[512], *cp;
125
126     if ((cp = index(var, '=')) != NULL)
127         sstrncpy(name, var, cp - var);
128     else
129         SAFE_STRCPY(name, var);
130     unsetenv(name);
131     /* Now search to see if it's in our list, if we have one.. */
132     if (!VarHead)
133         return;
134     else if (!VarHead->next && !strcmp(VarHead->name, name)) {
135         safe_free(VarHead->name);
136         safe_free(VarHead->value);
137         free(VarHead);
138         VarHead = NULL;
139     }
140     else {
141         for (vp = VarHead; vp; vp = vp->next) {
142             if (!strcmp(vp->name, name)) {
143                 Variable *save = vp->next;
144
145                 safe_free(vp->name);
146                 safe_free(vp->value);
147                 *vp = *save;
148                 safe_free(save);
149                 break;
150             }
151         }
152     }
153 }
154
155 /* Prompt user for the name of a variable */
156 char *
157 variable_get_value(char *var, char *prompt, int dirty)
158 {
159     char *cp;
160
161     cp = variable_get(var);
162     if (cp && variable_get(VAR_NONINTERACTIVE))
163         return cp;
164     else if ((cp = msgGetInput(cp, "%s", prompt)) != NULL)
165         variable_set2(var, cp, dirty);
166     else
167         cp = NULL;
168     return cp;
169 }
170
171 /* Check if value passed in data (in the form "variable=value") is
172  * valid, and it's status compared to the value of variable stored in
173  * env
174  *
175  * Possible return values :
176  * -3: Invalid line, the data string is NOT set as an env variable
177  * -2: Invalid line, the data string is set as an env variable
178  * -1: Invalid line
179  *  0: Valid line, is NOT equal to env version
180  *  1: Valid line, is equal to env version
181  *  2: Valid line, value empty - e.g. foo=""
182  *  3: Valid line, does not exist in env
183 */
184 int
185 variable_check2(char *data)
186 {
187     char *cp, *cp2, *cp3, tmp[256];
188
189     if (data == NULL)
190         return -1;
191     SAFE_STRCPY(tmp, data);
192     if ((cp = index(tmp, '=')) != NULL) {
193         *(cp++) = '\0';
194         if (*cp == '"') {       /* smash quotes if present */
195             ++cp;
196             if ((cp3 = index(cp, '"')) != NULL)
197                 *cp3 = '\0';
198         }
199         else if ((cp3 = index(cp, ',')) != NULL)
200             *cp3 = '\0';
201         cp2 = variable_get(tmp);
202         if (cp2 != NULL) {
203             if (*cp == '\0')
204                 return 2;
205             else
206                 return strcmp(cp, cp2) == 0 ? 1 : 0;
207         }
208         else
209             return 3;
210     }
211     else
212         return variable_get(tmp) != NULL ? -2 : -3;
213
214
215 /* Check if the value passed in data (in the form "variable=value") is
216    equal to the value of variable stored in env */
217 int
218 variable_check(char *data)
219 {
220     int ret;
221     ret = variable_check2(data);
222
223     switch(ret) {
224     case -2:
225     case 1:
226     case 2:
227         return TRUE;
228         /* NOT REACHED */
229     default:
230         return FALSE;
231     }
232 }
233
234 int
235 dump_variables(dialogMenuItem *unused)
236 {
237     FILE *fp;
238     Variable *vp;
239
240     if (isDebug())
241         msgDebug("Writing %s variables to file..\n", ProgName);
242
243     fp = fopen("/etc/sade.vars", "w");
244     if (!fp) {
245         msgConfirm("Unable to write to /etc/%s.vars: %s",
246                    ProgName, strerror(errno));
247         return DITEM_FAILURE;
248     }
249
250     for (vp = VarHead; vp; vp = vp->next)
251         fprintf(fp, "%s=\"%s\" (%d)\n", vp->name, vp->value, vp->dirty);
252
253     fclose(fp);
254
255     return DITEM_SUCCESS;
256 }
257
258 /* Free all of the variables, useful to really start over as when the
259    user selects "restart" from the interrupt menu. */
260 void
261 free_variables(void)
262 {
263     Variable *vp;
264
265     /* Free the variables from our list, if we have one.. */
266     if (!VarHead)
267         return;
268     else if (!VarHead->next) {
269         unsetenv(VarHead->name);
270         safe_free(VarHead->name);
271         safe_free(VarHead->value);
272         free(VarHead);
273         VarHead = NULL;
274     }
275     else {
276         for (vp = VarHead; vp; ) {
277             Variable *save = vp;
278             unsetenv(vp->name);
279             safe_free(vp->name);
280             safe_free(vp->value);
281             vp = vp->next;
282             safe_free(save);
283         }
284         VarHead = NULL;
285     }
286 }
287
288 /*
289  * Persistent variables.  The variables modified by these functions
290  * are not cleared between invocations of sysinstall.  This is useful
291  * to allow the user to completely restart sysinstall, without having
292  * it load all of the modules again from the installation media which
293  * are still in memory.
294  */
295
296 void
297 pvariable_set(char *var)
298 {
299     char *p;
300     char tmp[1024];
301
302     if (!var)
303         msgFatal("NULL variable name & value passed.");
304     else if (!*var)
305         msgDebug("Warning:  Zero length name & value passed to variable_set()\n");
306     /* Add a trivial namespace to whatever name the caller chooses. */
307     SAFE_STRCPY(tmp, "SYSINSTALL_PVAR");
308     if (index(var, '=') == NULL)
309         msgFatal("Invalid variable format: %s", var);
310     strlcat(tmp, var, 1024); 
311     p = strchr(tmp, '=');
312     *p = '\0';
313     setenv(tmp, p + 1, 1);
314 }
315
316 char *
317 pvariable_get(char *var)
318 {
319     char tmp[1024];
320
321     SAFE_STRCPY(tmp, "SYSINSTALL_PVAR");
322     strlcat(tmp, var, 1024);
323     return getenv(tmp);
324 }