2 * The new sysinstall program.
4 * This is probably the last program in the `sysinstall' line - the next
5 * generation being essentially a complete rewrite.
7 * $FreeBSD: src/release/sysinstall/dispatch.c,v 1.35.2.7 2002/07/02 21:37:49 jhb Exp $
8 * $DragonFly: src/release/sysinstall/Attic/dispatch.c,v 1.2 2003/06/17 04:27:21 dillon Exp $
11 * Jordan Hubbard. All rights reserved.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
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
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.
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
38 #include "sysinstall.h"
41 #include <sys/signal.h>
42 #include <sys/fcntl.h>
46 static int dispatch_shutdown(dialogMenuItem *unused);
47 static int dispatch_systemExecute(dialogMenuItem *unused);
48 static int dispatch_msgConfirm(dialogMenuItem *unused);
49 static int dispatch_mediaClose(dialogMenuItem *unused);
53 int (*handler)(dialogMenuItem *self);
55 { "configAnonFTP", configAnonFTP },
56 { "configRouter", configRouter },
57 { "configInetd", configInetd },
58 { "configNFSServer", configNFSServer },
59 { "configNTP", configNTP },
60 { "configPCNFSD", configPCNFSD },
61 { "configPackages", configPackages },
62 { "configUsers", configUsers },
63 { "configXSetup", configXSetup },
64 { "configXDesktop", configXDesktop },
65 { "diskPartitionEditor", diskPartitionEditor },
66 { "diskPartitionWrite", diskPartitionWrite },
67 { "diskLabelEditor", diskLabelEditor },
68 { "diskLabelCommit", diskLabelCommit },
69 { "distReset", distReset },
70 { "distSetCustom", distSetCustom },
71 { "distUnsetCustom", distUnsetCustom },
72 { "distSetDeveloper", distSetDeveloper },
73 { "distSetXDeveloper", distSetXDeveloper },
74 { "distSetKernDeveloper", distSetKernDeveloper },
75 { "distSetUser", distSetUser },
76 { "distSetXUser", distSetXUser },
77 { "distSetMinimum", distSetMinimum },
78 { "distSetEverything", distSetEverything },
79 { "distSetSrc", distSetSrc },
80 { "distSetXF86", distSetXF86 },
81 { "distExtractAll", distExtractAll },
82 { "docBrowser", docBrowser },
83 { "docShowDocument", docShowDocument },
84 { "installCommit", installCommit },
85 { "installExpress", installExpress },
86 { "installStandard", installStandard },
87 { "installUpgrade", installUpgrade },
88 { "installFixupBin", installFixupBin },
90 { "installFixupXFree", installFixupXFree },
92 { "installFixitHoloShell", installFixitHoloShell },
93 { "installFixitCDROM", installFixitCDROM },
94 { "installFixitFloppy", installFixitFloppy },
95 { "installFilesystems", installFilesystems },
96 { "installVarDefaults", installVarDefaults },
97 { "loadConfig", dispatch_load_file },
98 { "loadFloppyConfig", dispatch_load_floppy },
99 { "mediaClose", dispatch_mediaClose },
100 { "mediaSetCDROM", mediaSetCDROM },
101 { "mediaSetFloppy", mediaSetFloppy },
102 { "mediaSetDOS", mediaSetDOS },
103 { "mediaSetTape", mediaSetTape },
104 { "mediaSetFTP", mediaSetFTP },
105 { "mediaSetFTPActive", mediaSetFTPActive },
106 { "mediaSetFTPPassive", mediaSetFTPPassive },
107 { "mediaSetHTTP", mediaSetHTTP },
108 { "mediaSetUFS", mediaSetUFS },
109 { "mediaSetNFS", mediaSetNFS },
110 { "mediaSetFTPUserPass", mediaSetFTPUserPass },
111 { "mediaSetCPIOVerbosity", mediaSetCPIOVerbosity },
112 { "mediaGetType", mediaGetType },
113 { "msgConfirm", dispatch_msgConfirm },
114 { "optionsEditor", optionsEditor },
115 { "packageAdd", packageAdd },
116 { "addGroup", userAddGroup },
117 { "addUser", userAddUser },
118 { "shutdown", dispatch_shutdown },
119 { "system", dispatch_systemExecute },
120 { "dumpVariables", dump_variables },
121 { "tcpMenuSelect", tcpMenuSelect },
126 * Helper routines for buffering data.
128 * We read an entire configuration into memory before executing it
129 * so that we are truely standalone and can do things like nuke the
130 * file or disk we're working on.
133 typedef struct command_buffer_ {
139 dispatch_free_command(command_buffer *item)
147 dispatch_free_all(qelement *head)
149 command_buffer *item;
151 while (!EMPTYQUE(*head)) {
152 item = (command_buffer *) head->q_forw;
153 dispatch_free_command(item);
157 static command_buffer *
158 dispatch_add_command(qelement *head, char *string)
162 new = malloc(sizeof(command_buffer));
167 new->string = strdup(string);
168 INSQUEUE(new, head->q_back);
177 /* Just convenience */
179 dispatch_shutdown(dialogMenuItem *unused)
182 return DITEM_FAILURE;
186 dispatch_systemExecute(dialogMenuItem *unused)
188 char *cmd = variable_get(VAR_COMMAND);
191 return systemExecute(cmd) ? DITEM_FAILURE : DITEM_SUCCESS;
193 msgDebug("_systemExecute: No command passed in `command' variable.\n");
194 return DITEM_FAILURE;
198 dispatch_msgConfirm(dialogMenuItem *unused)
200 char *msg = variable_get(VAR_COMMAND);
203 msgConfirm("%s", msg);
204 return DITEM_SUCCESS;
207 msgDebug("_msgConfirm: No message passed in `command' variable.\n");
208 return DITEM_FAILURE;
212 dispatch_mediaClose(dialogMenuItem *unused)
215 return DITEM_SUCCESS;
219 call_possible_resword(char *name, dialogMenuItem *value, int *status)
224 for (i = 0; resWords[i].name; i++) {
225 if (!strcmp(name, resWords[i].name)) {
226 *status = resWords[i].handler(value);
234 /* For a given string, call it or spit out an undefined command diagnostic */
236 dispatchCommand(char *str)
242 msgConfirm("Null or zero-length string passed to dispatchCommand");
243 return DITEM_FAILURE;
245 /* If it's got a newline, trim it */
246 if ((cp = index(str, '\n')) != NULL)
249 /* If it's got a `=' sign in there, assume it's a variable setting */
250 if (index(str, '=')) {
252 msgDebug("dispatch: setting variable `%s'\n", str);
253 variable_set(str, 0);
257 /* A command might be a pathname if it's encoded in argv[0], which
259 if ((cp = rindex(str, '/')) != NULL)
262 msgDebug("dispatch: calling resword `%s'\n", str);
263 if (!call_possible_resword(str, NULL, &i)) {
264 msgNotify("Warning: No such command ``%s''", str);
268 * Allow a user to prefix a command with "noError" to cause
269 * us to ignore any errors for that one command.
271 if (i != DITEM_SUCCESS && variable_get(VAR_NO_ERROR))
273 variable_unset(VAR_NO_ERROR);
284 dispatch_load_fp(FILE *fp)
287 char buf[BUFSIZ], *cp;
289 head = malloc(sizeof(qelement));
296 while (fgets(buf, sizeof buf, fp)) {
298 if ((cp = strchr(buf, '\n')) != NULL)
300 if (*buf == '\0' || *buf == '#')
303 if (!dispatch_add_command(head, buf))
311 dispatch_execute(qelement *head)
313 int result = DITEM_SUCCESS;
314 command_buffer *item;
315 char *old_interactive;
318 return result | DITEM_FAILURE;
320 old_interactive = variable_get(VAR_NONINTERACTIVE);
322 old_interactive = strdup(old_interactive); /* save copy */
324 /* Hint to others that we're running from a script, should they care */
325 variable_set2(VAR_NONINTERACTIVE, "yes", 0);
327 while (!EMPTYQUE(*head)) {
328 item = (command_buffer *) head->q_forw;
330 if (DITEM_STATUS(dispatchCommand(item->string)) != DITEM_SUCCESS) {
331 msgConfirm("Command `%s' failed - rest of script aborted.\n",
333 result |= DITEM_FAILURE;
336 dispatch_free_command(item);
339 dispatch_free_all(head);
341 if (!old_interactive)
342 variable_unset(VAR_NONINTERACTIVE);
344 variable_set2(VAR_NONINTERACTIVE, old_interactive, 0);
345 free(old_interactive);
352 dispatch_load_file_int(int quiet)
359 static const char *names[] = {
361 "/stand/install.cfg",
367 cp = variable_get(VAR_CONFIG_FILE);
369 for (i = 0; names[i]; i++)
370 if ((fp = fopen(names[i], "r")) != NULL)
377 msgConfirm("Unable to open %s: %s", cp, strerror(errno));
378 return DITEM_FAILURE;
381 list = dispatch_load_fp(fp);
384 return dispatch_execute(list);
388 dispatch_load_file(dialogMenuItem *self)
390 return dispatch_load_file_int(FALSE);
394 dispatch_load_floppy(dialogMenuItem *self)
396 int what = DITEM_SUCCESS;
397 extern char *distWanted;
403 cp = variable_get_value(VAR_INSTALL_CFG,
404 "Specify the name of a configuration file\n"
405 "residing on a MSDOS or UFS floppy.", 0);
407 variable_unset(VAR_INSTALL_CFG);
408 what |= DITEM_FAILURE;
413 /* Try to open the floppy drive */
414 if (DITEM_STATUS(mediaSetFloppy(NULL)) == DITEM_FAILURE) {
415 msgConfirm("Unable to set media device to floppy.");
416 what |= DITEM_FAILURE;
421 if (!DEVICE_INIT(mediaDevice)) {
422 msgConfirm("Unable to mount floppy filesystem.");
423 what |= DITEM_FAILURE;
428 fp = DEVICE_GET(mediaDevice, cp, TRUE);
430 list = dispatch_load_fp(fp);
434 what |= dispatch_execute(list);
437 if (!variable_get(VAR_NO_ERROR))
438 msgConfirm("Configuration file '%s' not found.", cp);
439 variable_unset(VAR_INSTALL_CFG);
440 what |= DITEM_FAILURE;