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