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