remove unmatched endif
[dragonfly.git] / release / 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: src/release/sysinstall/options.c,v 1.70.2.5 2001/09/27 07:38:49 murray Exp $
8  * $DragonFly: src/release/sysinstall/Attic/options.c,v 1.2 2003/06/17 04:27:21 dillon Exp $
9  *
10  * Copyright (c) 1995
11  *      Jordan Hubbard.  All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer,
18  *    verbatim and that no modifications are made prior to this
19  *    point in the file.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  *
24  * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  */
37
38 #include "sysinstall.h"
39 #include <ctype.h>
40 #include <curses.h>
41 #include <term.h>
42
43 int fixitTtyWhich(dialogMenuItem *);
44
45 static char *
46 varCheck(Option opt)
47 {
48     char *cp = NULL;
49
50     if (opt.aux)
51         cp = variable_get((char *)opt.aux);
52     if (!cp)
53         return "NO";
54     return cp;
55 }
56
57 /* Show our little logo */
58 static char *
59 resetLogo(char *str)
60 {
61     return "[RESET!]";
62 }
63
64 static char *
65 mediaCheck(Option opt)
66 {
67     if (mediaDevice) {
68         switch(mediaDevice->type) {
69         case DEVICE_TYPE_UFS:
70         case DEVICE_TYPE_DISK:
71             return "File system";
72
73         case DEVICE_TYPE_FLOPPY:
74             return "Floppy";
75
76         case DEVICE_TYPE_FTP:
77             return "FTP";
78
79         case DEVICE_TYPE_CDROM:
80             return "CDROM";
81
82         case DEVICE_TYPE_TAPE:
83             return "Tape";
84
85         case DEVICE_TYPE_DOS:
86             return "DOS";
87
88         case DEVICE_TYPE_NFS:
89             return "NFS";
90
91         case DEVICE_TYPE_NONE:
92         case DEVICE_TYPE_NETWORK:
93         case DEVICE_TYPE_ANY:
94         default:
95             return "<unknown>";
96         }
97     }
98     return "<not yet set>";
99 }
100
101 #define TAPE_PROMPT     "Please enter the tape block size in 512 byte blocks:"
102 #define NEWFS_PROMPT    "Please enter newfs(8) parameters:"
103 #define RELNAME_PROMPT  "Please specify the release you wish to load or\n\"any\" for a generic release install:"
104 #define BPKG_PROMPT     "Please specify the name of the HTML browser package:"
105 #define BBIN_PROMPT     "Please specify a full pathname to the HTML browser binary:"
106 #define EDITOR_PROMPT   "Please specify the name of the text editor you wish to use:"
107 #define PKG_PROMPT      "Please specify a temporary directory with lots of free space:"
108 #define INSTROOT_PROMPT "Please specify a root directory if installing somewhere other than /"
109 #define TIMEOUT_PROMPT  "Please specify the number of seconds to wait for slow media:"
110
111 static Option Options[] = {
112 { "NFS Secure",         "NFS server talks only on a secure port",
113       OPT_IS_VAR,       NULL,                   VAR_NFS_SECURE,         varCheck        },
114 { "NFS Slow",           "User is using a slow PC or ethernet card",
115       OPT_IS_VAR,       NULL,                   VAR_SLOW_ETHER,         varCheck        },
116 { "Debugging",          "Emit extra debugging output on VTY2 (ALT-F2)",
117       OPT_IS_VAR,       NULL,                   VAR_DEBUG,              varCheck        },
118 { "No Warnings",        "Don't Warn the user when a setting seems incorrect",
119       OPT_IS_VAR,       NULL,                   VAR_NO_WARN,            varCheck        },
120 { "Yes to All",         "Assume \"Yes\" answers to all non-critical dialogs",
121       OPT_IS_VAR,       NULL,                   VAR_NO_CONFIRM,         varCheck        },
122 { "DHCP",               "Attempt automatic DHCP configuration of interfaces",
123       OPT_IS_VAR,       NULL,                   VAR_TRY_DHCP,           varCheck        },
124 { "IPv6",               "Attempt IPv6 configuration of interfaces",
125       OPT_IS_VAR,       NULL,                   VAR_TRY_RTSOL,          varCheck        },
126 { "FTP username",       "Username and password to use instead of anonymous",
127       OPT_IS_FUNC,      mediaSetFTPUserPass,    VAR_FTP_USER,           varCheck        },
128 { "Editor",             "Which text editor to use during installation",
129       OPT_IS_VAR,       EDITOR_PROMPT,          VAR_EDITOR,             varCheck        },
130 { "Tape Blocksize",     "Tape media block size in 512 byte blocks",
131       OPT_IS_VAR,       TAPE_PROMPT,            VAR_TAPE_BLOCKSIZE,     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 { "Config save",        "Whether or not to save installation kernel config changes",
153       OPT_IS_VAR,       NULL,                   VAR_KGET,               varCheck        },
154 { "Re-scan Devices",    "Re-run sysinstall's initial device probe",
155       OPT_IS_FUNC,      deviceRescan },
156 { "Use Defaults",       "Reset all values to startup defaults",
157       OPT_IS_FUNC,      installVarDefaults,     0,                      resetLogo       },
158 { NULL },
159 };
160
161 #define OPT_START_ROW   4
162 #define OPT_END_ROW     19
163 #define OPT_NAME_COL    0
164 #define OPT_VALUE_COL   16
165 #define GROUP_OFFSET    40
166
167 static char *
168 value_of(Option opt)
169 {
170     static char ival[40];
171
172     switch (opt.type) {
173     case OPT_IS_STRING:
174         return (char *)opt.data;
175
176     case OPT_IS_INT:
177         sprintf(ival, "%lu", (long)opt.data);
178         return ival;
179
180     case OPT_IS_FUNC:
181     case OPT_IS_VAR:
182         if (opt.check)
183             return opt.check(opt);
184         else
185             return "<*>";
186     }
187     return "<unknown>";
188 }
189
190 static int
191 fire(Option opt)
192 {
193     int status = 0;
194
195     if (opt.type == OPT_IS_FUNC) {
196         int (*cp)(char *) = opt.data, rcode;
197
198         rcode = cp(NULL);
199         status = 1;
200     }
201     else if (opt.type == OPT_IS_VAR) {
202         if (opt.data) {
203             (void)variable_get_value(opt.aux, opt.data, -1);
204             status = 1;
205         }
206         else if (variable_get(opt.aux)) {
207             if (!variable_cmp(opt.aux, "YES"))
208                 variable_set2(opt.aux, "NO", -1);
209             else
210                 variable_set2(opt.aux, "YES", -1);
211         }
212         else
213             variable_set2(opt.aux, "YES", 0);
214     }
215     if (opt.check)
216         opt.check(opt);
217     refresh();
218     return status;
219 }
220
221 int
222 optionsEditor(dialogMenuItem *self)
223 {
224     int i, optcol, optrow, key;
225     static int currOpt = 0;
226     WINDOW *w = savescr();
227     
228     dialog_clear();
229     clear();
230
231     while (1) {
232         /* Whap up the header */
233         attrset(A_REVERSE); mvaddstr(0, 0, "Options Editor"); attrset(A_NORMAL);
234         for (i = 0; i < 2; i++) {
235             mvaddstr(OPT_START_ROW - 2, OPT_NAME_COL + (i * GROUP_OFFSET), "Name");
236             mvaddstr(OPT_START_ROW - 1, OPT_NAME_COL + (i * GROUP_OFFSET), "----");
237
238             mvaddstr(OPT_START_ROW - 2, OPT_VALUE_COL + (i * GROUP_OFFSET), "Value");
239             mvaddstr(OPT_START_ROW - 1, OPT_VALUE_COL + (i * GROUP_OFFSET), "-----");
240         }
241         /* And the footer */
242         mvprintw(OPT_END_ROW + 1, 0, "Use SPACE to select/toggle an option, arrow keys to move,");
243         mvprintw(OPT_END_ROW + 2, 0, "? or F1 for more help.  When you're done, type Q to Quit.");
244
245         optrow = OPT_START_ROW;
246         optcol = OPT_NAME_COL;
247         for (i = 0; Options[i].name; i++) {
248             /* Names are painted somewhat gratuitously each time, but it's easier this way */
249             mvprintw(optrow, OPT_NAME_COL + optcol, Options[i].name);
250             if (currOpt == i)
251                 attrset(ATTR_SELECTED);
252             mvprintw(optrow++, OPT_VALUE_COL + optcol, value_of(Options[i]));
253             if (currOpt == i)
254                 attrset(A_NORMAL);
255             if (optrow == OPT_END_ROW) {
256                 optrow = OPT_START_ROW;
257                 optcol += GROUP_OFFSET;
258             }
259             clrtoeol();
260         }
261         attrset(ATTR_TITLE);
262         mvaddstr(OPT_END_ROW + 4, 0, Options[currOpt].desc);
263         attrset(A_NORMAL);
264         clrtoeol();
265         move(0, 14);
266         refresh();
267
268         /* Start the edit loop */
269         key = toupper(getch());
270         switch (key) {
271         case KEY_F(1):
272         case '?':
273             systemDisplayHelp("options");
274             clear();
275             break;
276
277         case '\020':    /* ^P */
278         case KEY_UP:
279             if (currOpt)
280                 --currOpt;
281             else
282                 for (currOpt = 0; Options[currOpt + 1].name; currOpt++);
283             continue;
284
285         case '\016':    /* ^N */
286         case KEY_DOWN:
287             if (Options[currOpt + 1].name)
288                 ++currOpt;
289             else
290                 currOpt = 0;
291             continue;
292
293         case KEY_HOME:
294             currOpt = 0;
295             continue;
296
297         case KEY_END:
298             while (Options[currOpt + 1].name)
299                 ++currOpt;
300             continue;
301
302         case ' ':
303             if (fire(Options[currOpt]))
304                 clear();
305             continue;
306
307         case '\033':    /* ESC */
308         case 'Q':
309             clear();
310             dialog_clear();
311             restorescr(w);
312             return DITEM_SUCCESS;
313
314         default:
315             beep();
316         }
317     }
318     /* NOTREACHED */
319     return DITEM_SUCCESS;
320 }
321
322 int
323 fixitTtyWhich(dialogMenuItem *self)
324 {
325     char *cp = variable_get(VAR_FIXIT_TTY);
326
327     if (!cp) {
328         msgConfirm("The Fix-it TTY setting is not set to anything!");
329         return DITEM_FAILURE;
330     }
331     else {
332         if (!strcmp(cp, "standard"))
333             variable_set2(VAR_FIXIT_TTY, "serial", 0);
334         else /* must be "serial" - wrap around */
335             variable_set2(VAR_FIXIT_TTY, "standard", 0);
336     }
337     return DITEM_SUCCESS;
338 }