2 * The new sysinstall program.
4 * This is probably the last attempt in the `sysinstall' line, the next
5 * generation being slated for what's essentially a complete rewrite.
10 * Jordan Hubbard. All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer,
17 * verbatim and that no modifications are made prior to this
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
23 * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include "sysinstall.h"
38 #include <sys/param.h>
43 static Boolean exited;
46 dmenuDisplayFile(dialogMenuItem *tmp)
48 systemDisplayHelp((char *)tmp->data);
53 dmenuSubmenu(dialogMenuItem *tmp)
55 return (dmenuOpenSimple((DMenu *)(tmp->data), FALSE) ? DITEM_SUCCESS : DITEM_FAILURE);
59 dmenuSystemCommand(dialogMenuItem *self)
61 WINDOW *w = NULL; /* Keep lint happy */
63 /* If aux is set, the command is known not to produce any screen-spoiling output */
66 systemExecute((char *)self->data);
73 dmenuSystemCommandBox(dialogMenuItem *tmp)
75 WINDOW *w = savescr();
78 use_helpline("Select OK to dismiss this dialog");
79 dialog_prgbox(tmp->title, (char *)tmp->data, 22, 76, 1, 1);
85 dmenuExit(dialogMenuItem *tmp)
88 return DITEM_LEAVE_MENU;
92 dmenuSetVariable(dialogMenuItem *tmp)
94 variable_set((char *)tmp->data, *((char *)tmp->data) != '_');
99 dmenuSetVariables(dialogMenuItem *tmp)
102 char *copy = strdup((char *)tmp->data);
104 for (cp1 = copy; cp1 != NULL;) {
105 cp2 = index(cp1, ',');
106 if (cp2 != NULL) *cp2++ = '\0';
107 variable_set(cp1, *cp1 != '_');
111 return DITEM_SUCCESS;
115 dmenuSetCountryVariable(dialogMenuItem *tmp)
117 variable_set((char *)tmp->data, FALSE);
119 /* Don't prompt the user for a keymap if they're using the default locale. */
120 if (!strcmp(variable_get(VAR_COUNTRY), DEFAULT_COUNTRY))
121 return DITEM_SUCCESS;
123 return keymapMenuSelect(tmp);
125 return DITEM_SUCCESS;
130 dmenuSetKmapVariable(dialogMenuItem *tmp)
135 variable_set((char *)tmp->data, TRUE);
136 lang = variable_get(VAR_KEYMAP);
139 err = loadKeymap(lang);
141 msgConfirm("No appropriate keyboard map found, sorry.");
143 msgConfirm("Error installing keyboard map, errno = %d.", errno);
145 return DITEM_SUCCESS;
149 dmenuToggleVariable(dialogMenuItem *tmp)
154 if (!(var = strdup((char *)tmp->data))) {
155 msgConfirm("Incorrect data field for `%s'!", tmp->title);
156 return DITEM_FAILURE;
158 if (!(cp = index(var, '='))) {
159 msgConfirm("Data field for %s is not in var=value format!", tmp->title);
160 return DITEM_FAILURE;
162 status = variable_check(var);
164 variable_set2(var, status ? "NO" : "YES", *var != '_');
166 return DITEM_SUCCESS;
170 dmenuISetVariable(dialogMenuItem *tmp)
174 if (!(var = strdup((char *)tmp->data))) {
175 msgConfirm("Incorrect data field for `%s'!", tmp->title);
176 return DITEM_FAILURE;
178 if ((p = index(var, '=')) != NULL)
180 ans = msgGetInput(variable_get(var), tmp->title, 1);
183 return DITEM_FAILURE;
187 variable_set2(var, ans, *var != '_');
189 return DITEM_SUCCESS;
193 dmenuSetFlag(dialogMenuItem *tmp)
195 if (*((unsigned int *)tmp->data) & tmp->aux)
196 *((unsigned int *)tmp->data) &= ~tmp->aux;
198 *((unsigned int *)tmp->data) |= tmp->aux;
199 return DITEM_SUCCESS;
203 dmenuSetValue(dialogMenuItem *tmp)
205 *((unsigned int *)tmp->data) = tmp->aux;
206 return DITEM_SUCCESS;
209 /* Traverse menu but give user no control over positioning */
211 dmenuOpenSimple(DMenu *menu, Boolean buttons)
213 int choice, scroll, curr, max;
215 choice = scroll = curr = max = 0;
216 return dmenuOpen(menu, &choice, &scroll, &curr, &max, buttons);
219 /* Work functions for the state hook */
221 dmenuFlagCheck(dialogMenuItem *item)
223 return (*((unsigned int *)item->data) & item->aux);
227 dmenuVarCheck(dialogMenuItem *item)
231 w = (char *)item->aux;
233 w = (char *)item->data;
234 return variable_check(w);
238 dmenuVarsCheck(dialogMenuItem *item)
244 w = (char *)item->aux;
246 w = (char *)item->data;
253 for (cp1 = copy; cp1 != NULL;) {
255 cp2 = index(cp1, ',');
258 res = res && variable_check(cp1);
266 dmenuRadioCheck(dialogMenuItem *item)
268 return (*((int *)item->data) == item->aux);
272 menu_height(DMenu *menu, int n)
279 max += StatusLine - 24;
280 for (t = menu->prompt; *t; t++) {
284 return n > max ? max : n;
287 /* Find a menu item that matches any field. */
289 dmenuFindItem(DMenu *menu, const char *prompt, const char *title, void *data)
291 dialogMenuItem *items = menu->items;
294 for (i = 0; items[i].prompt; ++i)
295 if ((prompt && !strcmp(items[i].prompt, prompt)) ||
296 (title && !strcmp(items[i].title, title)) ||
297 (data && items[i].data == data))
303 /* Set the default item for a menu by index and scroll to it. */
305 dmenuSetDefaultIndex(DMenu *menu, int *choice, int *scroll, int *curr, int *max)
312 for (nitem = 0; menu->items[nitem].prompt; ++nitem);
314 height = menu_height(menu, nitem);
315 if (*choice > height)
317 *scroll = MIN(nitem - height, *choice);
318 *choice = *choice - *scroll;
324 /* Set the default menu item that matches any field and scroll to it. */
326 dmenuSetDefaultItem(DMenu *menu, const char *prompt, const char *title, void *data,
327 int *choice, int *scroll, int *curr, int *max)
329 if ((*choice = dmenuFindItem(menu, prompt, title, data)) != -1)
331 dmenuSetDefaultIndex(menu, choice, scroll, curr, max);
336 *choice = *scroll = *curr = *max = 0;
341 /* Traverse over an internal menu */
343 dmenuOpen(DMenu *menu, int *choice, int *scroll, int *curr, int *max, Boolean buttons)
346 dialogMenuItem *items;
351 /* Count up all the items */
352 for (n = 0; items[n].title; n++);
355 char buf[FILENAME_MAX];
356 WINDOW *w = savescr();
358 /* Any helpful hints, put 'em up! */
359 use_helpline(menu->helpline);
360 use_helpfile(systemHelpFile(menu->helpfile, buf));
361 dialog_clear_norefresh();
362 /* Pop up that dialog! */
363 if (menu->type & DMENU_NORMAL_TYPE)
364 rval = dialog_menu((u_char *)menu->title, (u_char *)menu->prompt,
365 -1, -1, menu_height(menu, n), -n, items,
366 (char *)(uintptr_t)buttons, choice, scroll);
368 else if (menu->type & DMENU_RADIO_TYPE)
369 rval = dialog_radiolist((u_char *)menu->title,
370 (u_char *)menu->prompt, -1, -1, menu_height(menu, n), -n,
371 items, (char *)(uintptr_t)buttons);
373 else if (menu->type & DMENU_CHECKLIST_TYPE)
374 rval = dialog_checklist((u_char *)menu->title,
375 (u_char *)menu->prompt, -1, -1, menu_height(menu, n), -n,
376 items, (char *)(uintptr_t)buttons);
378 msgFatal("Menu: `%s' is of an unknown type\n", menu->title);
388 else if (menu->type & DMENU_SELECTION_RETURNS) {