]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - usr.sbin/sysinstall/options.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / usr.sbin / sysinstall / options.c
1 /*
2  * The new sysinstall program.
3  *
4  * This is probably the last attempt in the `sysinstall' line, the next
5  * generation being slated for what's essentially a complete rewrite.
6  *
7  * $FreeBSD$
8  *
9  * Copyright (c) 1995
10  *      Jordan Hubbard.  All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
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
18  *    point in the file.
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.
22  *
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
33  * SUCH DAMAGE.
34  *
35  */
36
37 #include "sysinstall.h"
38 #include <ctype.h>
39 #include <curses.h>
40 #include <term.h>
41
42 int fixitTtyWhich(dialogMenuItem *);
43
44 static char *
45 varCheck(Option *opt)
46 {
47     char *cp = NULL;
48
49     if (opt->aux)
50         cp = variable_get((char *)opt->aux);
51     if (!cp)
52         return "NO";
53     return cp;
54 }
55
56 /* Show our little logo */
57 static char *
58 resetLogo(Option *opt)
59 {
60     return "[RESET!]";
61 }
62
63 static char *
64 mediaCheck(Option *opt)
65 {
66     if (mediaDevice) {
67         switch(mediaDevice->type) {
68         case DEVICE_TYPE_UFS:
69         case DEVICE_TYPE_DISK:
70             return "File system";
71
72         case DEVICE_TYPE_FLOPPY:
73             return "Floppy";
74
75         case DEVICE_TYPE_FTP:
76             return "FTP";
77
78         case DEVICE_TYPE_CDROM:
79             return "CDROM";
80
81         case DEVICE_TYPE_USB:
82             return "USB";
83
84         case DEVICE_TYPE_DOS:
85             return "DOS";
86
87         case DEVICE_TYPE_NFS:
88             return "NFS";
89
90         case DEVICE_TYPE_NONE:
91         case DEVICE_TYPE_NETWORK:
92         case DEVICE_TYPE_ANY:
93         default:
94             return "<unknown>";
95         }
96     }
97     return "<not yet set>";
98 }
99
100 #define NEWFS_PROMPT    "Please enter newfs(8) parameters:"
101 #define RELNAME_PROMPT  "Please specify the release you wish to load or\n\"any\" for a generic release install:"
102 #define BPKG_PROMPT     "Please specify the name of the HTML browser package:"
103 #define BBIN_PROMPT     "Please specify a full pathname to the HTML browser binary:"
104 #define EDITOR_PROMPT   "Please specify the name of the text editor you wish to use:"
105 #define PKG_PROMPT      "Please specify a temporary directory with lots of free space:"
106 #define INSTROOT_PROMPT "Please specify a root directory if installing somewhere other than /"
107 #define TIMEOUT_PROMPT  "Please specify the number of seconds to wait for slow media:"
108
109 static Option Options[] = {
110 { "NFS Secure",         "NFS server talks only on a secure port",
111       OPT_IS_VAR,       NULL,                   VAR_NFS_SECURE,         varCheck        },
112 { "NFS Slow",           "User is using a slow PC or ethernet card",
113       OPT_IS_VAR,       NULL,                   VAR_SLOW_ETHER,         varCheck        },
114 { "NFS TCP",            "Use TCP protocol for NFS",
115       OPT_IS_VAR,       NULL,                   VAR_NFS_TCP,            varCheck        },
116 { "NFS version 3",      "Use NFS version 3",
117       OPT_IS_VAR,       NULL,                   VAR_NFS_V3,             varCheck        },
118 { "Debugging",          "Emit extra debugging output on VTY2 (ALT-F2)",
119       OPT_IS_VAR,       NULL,                   VAR_DEBUG,              varCheck        },
120 { "No Warnings",        "Don't Warn the user when a setting seems incorrect",
121       OPT_IS_VAR,       NULL,                   VAR_NO_WARN,            varCheck        },
122 { "Yes to All",         "Assume \"Yes\" answers to all non-critical dialogs",
123       OPT_IS_VAR,       NULL,                   VAR_NO_CONFIRM,         varCheck        },
124 { "DHCP",               "Attempt automatic DHCP configuration of interfaces",
125       OPT_IS_VAR,       NULL,                   VAR_TRY_DHCP,           varCheck        },
126 { "IPv6",               "Attempt IPv6 configuration of interfaces",
127       OPT_IS_VAR,       NULL,                   VAR_TRY_RTSOL,          varCheck        },
128 { "FTP username",       "Username and password to use instead of anonymous",
129       OPT_IS_FUNC,      mediaSetFTPUserPass,    VAR_FTP_USER,           varCheck        },
130 { "Editor",             "Which text editor to use during installation",
131       OPT_IS_VAR,       EDITOR_PROMPT,          VAR_EDITOR,             varCheck        },
132 { "Extract Detail",     "How verbosely to display file name information during extractions",
133       OPT_IS_FUNC,      mediaSetCPIOVerbosity,  VAR_CPIO_VERBOSITY,     varCheck        },
134 { "Release Name",       "Which release to attempt to load from installation media",
135       OPT_IS_VAR,       RELNAME_PROMPT,         VAR_RELNAME,            varCheck        },
136 { "Install Root",       "Which directory to unpack distributions or packages relative to",
137       OPT_IS_VAR,       INSTROOT_PROMPT,        VAR_INSTALL_ROOT,       varCheck        },
138 { "Browser package",    "This is the browser package that will be used for viewing HTML docs",
139       OPT_IS_VAR,       BPKG_PROMPT,            VAR_BROWSER_PACKAGE,    varCheck        },
140 { "Browser Exec",       "This is the path to the main binary of the browser package",
141       OPT_IS_VAR,       BBIN_PROMPT,            VAR_BROWSER_BINARY,     varCheck        },
142 { "Media Type",         "The current installation media type.",
143       OPT_IS_FUNC,      mediaGetType,           VAR_MEDIA_TYPE,         mediaCheck      },
144 { "Media Timeout",      "Timeout value in seconds for slow media.",
145       OPT_IS_VAR,       TIMEOUT_PROMPT,         VAR_MEDIA_TIMEOUT,      varCheck        },
146 { "Package Temp",       "The directory where package temporary files should go",
147       OPT_IS_VAR,       PKG_PROMPT,             VAR_PKG_TMPDIR,         varCheck        },
148 { "Newfs Args",         "Default parameters for newfs(8)",
149       OPT_IS_VAR,       NEWFS_PROMPT,           VAR_NEWFS_ARGS,         varCheck        },
150 { "Fixit Console",      "Which tty to use for the Fixit action.",
151       OPT_IS_FUNC,      fixitTtyWhich,          VAR_FIXIT_TTY,          varCheck        },
152 { "Re-scan Devices",    "Re-run sysinstall's initial device probe",
153       OPT_IS_FUNC,      deviceRescan,           NULL,                   NULL            },
154 { "Use Defaults",       "Reset all values to startup defaults",
155       OPT_IS_FUNC,      installVarDefaults,     NULL,                   resetLogo       },
156 { NULL, NULL, 0, NULL, NULL, NULL },
157 };
158
159 #define OPT_START_ROW   4
160 #define OPT_END_ROW     19
161 #define OPT_NAME_COL    0
162 #define OPT_VALUE_COL   16
163 #define GROUP_OFFSET    40
164
165 static char *
166 value_of(Option opt)
167 {
168     static char ival[40];
169
170     switch (opt.type) {
171     case OPT_IS_STRING:
172         return (char *)opt.data;
173
174     case OPT_IS_INT:
175         sprintf(ival, "%lu", (long)opt.data);
176         return ival;
177
178     case OPT_IS_FUNC:
179     case OPT_IS_VAR:
180         if (opt.check)
181             return opt.check(&opt);
182         else
183             return "<*>";
184     }
185     return "<unknown>";
186 }
187
188 static int
189 fire(Option opt)
190 {
191     int status = 0;
192
193     if (opt.type == OPT_IS_FUNC) {
194         int (*cp)(char *) = opt.data, rcode;
195
196         rcode = cp(NULL);
197         status = 1;
198     }
199     else if (opt.type == OPT_IS_VAR) {
200         if (opt.data) {
201             (void)variable_get_value(opt.aux, opt.data, -1);
202             status = 1;
203         }
204         else if (variable_get(opt.aux)) {
205             if (!variable_cmp(opt.aux, "YES"))
206                 variable_set2(opt.aux, "NO", -1);
207             else
208                 variable_set2(opt.aux, "YES", -1);
209         }
210         else
211             variable_set2(opt.aux, "YES", 0);
212     }
213     if (opt.check)
214         opt.check(&opt);
215     refresh();
216     return status;
217 }
218
219 int
220 optionsEditor(dialogMenuItem *self)
221 {
222     int i, optcol, optrow, key;
223     static int currOpt = 0;
224     WINDOW *w = savescr();
225     
226     dialog_clear();
227     clear();
228
229     while (1) {
230         /* Whap up the header */
231         attrset(A_REVERSE); mvaddstr(0, 0, "Options Editor"); attrset(A_NORMAL);
232         for (i = 0; i < 2; i++) {
233             mvaddstr(OPT_START_ROW - 2, OPT_NAME_COL + (i * GROUP_OFFSET), "Name");
234             mvaddstr(OPT_START_ROW - 1, OPT_NAME_COL + (i * GROUP_OFFSET), "----");
235
236             mvaddstr(OPT_START_ROW - 2, OPT_VALUE_COL + (i * GROUP_OFFSET), "Value");
237             mvaddstr(OPT_START_ROW - 1, OPT_VALUE_COL + (i * GROUP_OFFSET), "-----");
238         }
239         /* And the footer */
240         mvprintw(OPT_END_ROW + 1, 0, "Use SPACE to select/toggle an option, arrow keys to move,");
241         mvprintw(OPT_END_ROW + 2, 0, "? or F1 for more help.  When you're done, type Q to Quit.");
242
243         optrow = OPT_START_ROW;
244         optcol = OPT_NAME_COL;
245         for (i = 0; Options[i].name; i++) {
246             /* Names are painted somewhat gratuitously each time, but it's easier this way */
247             mvprintw(optrow, OPT_NAME_COL + optcol, Options[i].name);
248             if (currOpt == i)
249                 attrset(ATTR_SELECTED);
250             mvprintw(optrow++, OPT_VALUE_COL + optcol, value_of(Options[i]));
251             if (currOpt == i)
252                 attrset(A_NORMAL);
253             if (optrow == OPT_END_ROW) {
254                 optrow = OPT_START_ROW;
255                 optcol += GROUP_OFFSET;
256             }
257             clrtoeol();
258         }
259         attrset(ATTR_TITLE);
260         mvaddstr(OPT_END_ROW + 4, 0, Options[currOpt].desc);
261         attrset(A_NORMAL);
262         clrtoeol();
263         move(0, 14);
264         refresh();
265
266         /* Start the edit loop */
267         key = toupper(getch());
268         switch (key) {
269         case KEY_F(1):
270         case '?':
271             systemDisplayHelp("options");
272             clear();
273             break;
274
275         case '\020':    /* ^P */
276         case KEY_UP:
277             if (currOpt)
278                 --currOpt;
279             else
280                 for (currOpt = 0; Options[currOpt + 1].name; currOpt++);
281             continue;
282
283         case '\016':    /* ^N */
284         case KEY_DOWN:
285             if (Options[currOpt + 1].name)
286                 ++currOpt;
287             else
288                 currOpt = 0;
289             continue;
290
291         case KEY_HOME:
292             currOpt = 0;
293             continue;
294
295         case KEY_END:
296             while (Options[currOpt + 1].name)
297                 ++currOpt;
298             continue;
299
300         case ' ':
301             if (fire(Options[currOpt]))
302                 clear();
303             continue;
304
305         case '\033':    /* ESC */
306         case 'Q':
307             clear();
308             dialog_clear();
309             restorescr(w);
310             return DITEM_SUCCESS | DITEM_CONTINUE;
311
312         default:
313             beep();
314         }
315     }
316     /* NOTREACHED */
317     return DITEM_SUCCESS;
318 }
319
320 int
321 fixitTtyWhich(dialogMenuItem *self)
322 {
323     char *cp = variable_get(VAR_FIXIT_TTY);
324
325     if (!cp) {
326         msgConfirm("The Fix-it TTY setting is not set to anything!");
327         return DITEM_FAILURE;
328     }
329     else {
330         if (!strcmp(cp, "standard"))
331             variable_set2(VAR_FIXIT_TTY, "serial", 0);
332         else /* must be "serial" - wrap around */
333             variable_set2(VAR_FIXIT_TTY, "standard", 0);
334     }
335     return DITEM_SUCCESS;
336 }