diff options
author | jkh <jkh@FreeBSD.org> | 1997-09-16 18:57:18 +0000 |
---|---|---|
committer | jkh <jkh@FreeBSD.org> | 1997-09-16 18:57:18 +0000 |
commit | cb8ec218f6b133ea876489d516e711e96a6cbc0b (patch) | |
tree | 177d26a861d654de0819973d2caa3300e0f6fe9b /release | |
parent | c65e27777ea7d253329b9e7b655fed623cc253fa (diff) | |
download | FreeBSD-src-cb8ec218f6b133ea876489d516e711e96a6cbc0b.zip FreeBSD-src-cb8ec218f6b133ea876489d516e711e96a6cbc0b.tar.gz |
Much better dispatch code and scripting support.
Submitted by: pst
Diffstat (limited to 'release')
-rw-r--r-- | release/sysinstall/Makefile | 4 | ||||
-rw-r--r-- | release/sysinstall/dispatch.c | 285 | ||||
-rw-r--r-- | release/sysinstall/main.c | 22 | ||||
-rw-r--r-- | release/sysinstall/menus.c | 6 | ||||
-rw-r--r-- | release/sysinstall/sysinstall.h | 10 | ||||
-rw-r--r-- | release/sysinstall/variable_load.c | 145 |
6 files changed, 253 insertions, 219 deletions
diff --git a/release/sysinstall/Makefile b/release/sysinstall/Makefile index 4381f9e..f32f361 100644 --- a/release/sysinstall/Makefile +++ b/release/sysinstall/Makefile @@ -21,10 +21,6 @@ CFLAGS+= -I${.CURDIR}/../../sys CFLAGS+= -DUC_PRIVATE -DKERN_NO_SYMBOLS -DSAVE_USERCONFIG #CFLAGS+= -DUSE_XIG_ENVIRONMENT -.if defined(LOAD_CONFIG_FILE) -CFLAGS+= -DLOAD_CONFIG_FILE=\"${LOAD_CONFIG_FILE}\" -.endif - DPADD= ${LIBDIALOG} ${LIBNCURSES} ${LIBMYTINFO} ${LIBUTIL} ${LIBDISK} ${LIBFTPIO} LDADD= -ldialog -lncurses -lmytinfo -lutil -ldisk -lftpio diff --git a/release/sysinstall/dispatch.c b/release/sysinstall/dispatch.c index fc0f72d..181ccd5 100644 --- a/release/sysinstall/dispatch.c +++ b/release/sysinstall/dispatch.c @@ -4,7 +4,7 @@ * This is probably the last program in the `sysinstall' line - the next * generation being essentially a complete rewrite. * - * $Id: dispatch.c,v 1.21 1997/08/11 13:08:18 jkh Exp $ + * $Id: dispatch.c,v 1.22 1997/09/08 11:09:08 jkh Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. @@ -36,10 +36,14 @@ #include "sysinstall.h" #include <ctype.h> +#include <errno.h> +#include <sys/signal.h> +#include <sys/fcntl.h> -static int _shutdown(dialogMenuItem *unused); -static int _systemExecute(dialogMenuItem *unused); -static int _loadConfig(dialogMenuItem *unused); +#include "list.h" + +static int dispatch_shutdown(dialogMenuItem *unused); +static int dispatch_systemExecute(dialogMenuItem *unused); static struct _word { char *name; @@ -83,7 +87,7 @@ static struct _word { { "installFixitFloppy", installFixitFloppy }, { "installFilesystems", installFilesystems }, { "installVarDefaults", installVarDefaults }, - { "loadConfig", _loadConfig }, + { "loadConfig", dispatch_load_file }, { "mediaSetCDROM", mediaSetCDROM }, { "mediaSetFloppy", mediaSetFloppy }, { "mediaSetDOS", mediaSetDOS }, @@ -101,37 +105,73 @@ static struct _word { { "packageAdd", packageAdd }, { "addGroup", userAddGroup }, { "addUser", userAddUser }, - { "shutdown", _shutdown }, - { "system", _systemExecute }, + { "shutdown", dispatch_shutdown }, + { "system", dispatch_systemExecute }, { NULL, NULL }, }; -static int -call_possible_resword(char *name, dialogMenuItem *value, int *status) +/* + * Helper routines for buffering data. + * + * We read an entire configuration into memory before executing it + * so that we are truely standalone and can do things like nuke the + * file or disk we're working on. + */ + +typedef struct command_buffer_ { + qelement queue; + char * string; +} command_buffer; + +static void +dispatch_free_command(command_buffer *item) { - int i, rval; + REMQUE(item); + free(item->string); + free(item); +} - rval = 0; - for (i = 0; resWords[i].name; i++) { - if (!strcmp(name, resWords[i].name)) { - *status = resWords[i].handler(value); - rval = 1; - break; - } +static void +dispatch_free_all(qelement *head) +{ + command_buffer *item; + + while (!EMPTYQUE(*head)) { + item = (command_buffer *) head->q_forw; + dispatch_free_command(item); } - return rval; } +static command_buffer * +dispatch_add_command(qelement *head, char *string) +{ + command_buffer *new; + + new = malloc(sizeof(command_buffer)); + + if (!new) + return NULL; + + new->string = strdup(string); + INSQUEUE(new, head->q_back); + + return new; +} + +/* + * Command processing + */ + /* Just convenience */ static int -_shutdown(dialogMenuItem *unused) +dispatch_shutdown(dialogMenuItem *unused) { systemShutdown(0); return DITEM_FAILURE; } static int -_systemExecute(dialogMenuItem *unused) +dispatch_systemExecute(dialogMenuItem *unused) { char *cmd = variable_get("command"); @@ -143,32 +183,19 @@ _systemExecute(dialogMenuItem *unused) } static int -_loadConfig(dialogMenuItem *unused) +call_possible_resword(char *name, dialogMenuItem *value, int *status) { - FILE *fp; - char *cp, buf[BUFSIZ]; - int i = DITEM_SUCCESS; - - cp = variable_get("file"); - if ((!cp || (fp = fopen(cp, "r")) == NULL) && - (fp = fopen("install.cfg", "r")) == NULL && - (fp = fopen("/stand/install.cfg", "r")) == NULL && - (fp = fopen("/tmp/install.cfg", "r")) == NULL) { - msgConfirm("Unable to locate an install.cfg file in $CWD, /stand or /tmp."); - i = DITEM_FAILURE; - } - else { - variable_set2(VAR_NONINTERACTIVE, "YES"); - while (fgets(buf, sizeof buf, fp)) { - if ((i = DITEM_STATUS(dispatchCommand(buf))) != DITEM_SUCCESS) { - msgDebug("Command `%s' failed - rest of script aborted.\n", buf); - break; - } + int i, rval; + + rval = 0; + for (i = 0; resWords[i].name; i++) { + if (!strcmp(name, resWords[i].name)) { + *status = resWords[i].handler(value); + rval = 1; + break; } } - fclose(fp); - variable_unset(VAR_NONINTERACTIVE); - return i; + return rval; } /* For a given string, call it or spit out an undefined command diagnostic */ @@ -194,7 +221,8 @@ dispatchCommand(char *str) i = DITEM_SUCCESS; } else { - /* A command might be a pathname if it's encoded in argv[0], which we also support */ + /* A command might be a pathname if it's encoded in argv[0], which + we also support */ if ((cp = rindex(str, '/')) != NULL) str = cp + 1; if (isDebug()) @@ -206,3 +234,172 @@ dispatchCommand(char *str) } return i; } + + +/* + * File processing + */ + +static qelement * +dispatch_load_fp(FILE *fp) +{ + qelement *head; + char buf[BUFSIZ], *cp; + + head = malloc(sizeof(qelement)); + + if (!head) + return NULL; + + INITQUE(*head); + + while (fgets(buf, sizeof buf, fp)) { + + if ((cp = strchr(buf, '\n')) != NULL) + *cp = '\0'; + if (*buf == '\0' || *buf == '#') + continue; + + if (!dispatch_add_command(head, buf)) + return NULL; + } + + return head; +} + +static int +dispatch_execute(qelement *head) +{ + int result = DITEM_SUCCESS; + command_buffer *item; + + if (!head) + return result | DITEM_FAILURE; + + /* Hint to others that we're running from a script, should they care */ + variable_set2(VAR_NONINTERACTIVE, "YES"); + + while (!EMPTYQUE(*head)) { + item = (command_buffer *) head->q_forw; + + if (DITEM_STATUS(dispatchCommand(item->string)) != DITEM_SUCCESS) { + /* + * Allow a user to prefix a command with "noError" to cause + * us to ignore any errors for that one command. + */ + if (variable_get(VAR_NO_ERROR)) + variable_unset(VAR_NO_ERROR); + else { + msgConfirm("Command `%s' failed - rest of script aborted.\n", + item->string); + result |= DITEM_FAILURE; + break; + } + } + dispatch_free_command(item); + } + + dispatch_free_all(head); + + variable_unset(VAR_NONINTERACTIVE); + + return result; +} + +int +dispatch_load_file_int(int quiet) +{ + FILE *fp; + char *cp; + int i; + qelement *list; + + static const char *names[] = { + "install.cfg", + "/stand/install.cfg", + "/tmp/install.cfg", + NULL + }; + + fp = NULL; + cp = variable_get(VAR_CONFIG_FILE); + if (!cp) { + for (i = 0; names[i]; i++) + if ((fp = fopen(names[i], "r")) != NULL) + break; + } else + fp = fopen(cp, "r"); + + if (!fp) { + if (!quiet) + msgConfirm("Unable to open %s: %s", cp, strerror(errno)); + return DITEM_FAILURE; + } + + list = dispatch_load_fp(fp); + fclose(fp); + + return dispatch_execute(list); +} + +int +dispatch_load_file(dialogMenuItem *self) +{ + return dispatch_load_file_int(FALSE); +} + +int +dispatch_load_floppy(dialogMenuItem *self) +{ + int what = DITEM_RESTORE | DITEM_SUCCESS; + extern char *distWanted; + char *cp; + FILE *fp; + qelement *list; + + mediaClose(); + dialog_clear_norefresh(); + + cp = variable_get_value(VAR_INSTALL_CFG, + "Specify the name of a configuration file\n" + "residing on a MSDOS or UFS floppy."); + if (!cp || !*cp) { + variable_unset(VAR_INSTALL_CFG); + what |= DITEM_FAILURE; + return what; + } + + distWanted = cp; + /* Try to open the floppy drive */ + if (DITEM_STATUS(mediaSetFloppy(NULL)) == DITEM_FAILURE) { + msgConfirm("Unable to set media device to floppy."); + what |= DITEM_FAILURE; + mediaClose(); + return what; + } + + if (!mediaDevice->init(mediaDevice)) { + msgConfirm("Unable to mount floppy filesystem."); + what |= DITEM_FAILURE; + mediaClose(); + return what; + } + + fp = mediaDevice->get(mediaDevice, cp, TRUE); + if (fp) { + list = dispatch_load_fp(fp); + fclose(fp); + mediaClose(); + + what |= dispatch_execute(list); + } + else { + msgConfirm("Configuration file '%s' not found.", cp); + variable_unset(VAR_INSTALL_CFG); + what |= DITEM_FAILURE; + mediaClose(); + } + + return what; +} + diff --git a/release/sysinstall/main.c b/release/sysinstall/main.c index e1672d0..d6d2726 100644 --- a/release/sysinstall/main.c +++ b/release/sysinstall/main.c @@ -4,7 +4,7 @@ * This is probably the last attempt in the `sysinstall' line, the next * generation being slated for what's essentially a complete rewrite. * - * $Id: main.c,v 1.45 1997/04/20 16:46:31 jkh Exp $ + * $Id: main.c,v 1.46 1997/06/05 09:47:58 jkh Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. @@ -104,24 +104,8 @@ main(int argc, char **argv) if (argc > start_arg) systemShutdown(0); } - else { - FILE *fp; - char buf[BUFSIZ]; - - fp = fopen("install.cfg", "r"); - if (fp) { - msgNotify("Loading pre-configuration file"); - variable_set2(VAR_NONINTERACTIVE, "YES"); - while (fgets(buf, sizeof buf, fp)) { - if (DITEM_STATUS(dispatchCommand(buf)) != DITEM_SUCCESS) { - msgDebug("Command `%s' failed - rest of script aborted.\n", buf); - break; - } - } - fclose(fp); - variable_unset(VAR_NONINTERACTIVE); - } - } + else + dispatch_load_file_int(TRUE); status = setjmp(BailOut); if (status) { diff --git a/release/sysinstall/menus.c b/release/sysinstall/menus.c index 102db59..8234f3f 100644 --- a/release/sysinstall/menus.c +++ b/release/sysinstall/menus.c @@ -4,7 +4,7 @@ * This is probably the last program in the `sysinstall' line - the next * generation being essentially a complete rewrite. * - * $Id: menus.c,v 1.141 1997/07/16 05:22:41 jkh Exp $ + * $Id: menus.c,v 1.142 1997/09/10 10:15:39 jkh Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. @@ -221,7 +221,7 @@ DMenu MenuIndex = { { "Commit", "Commit any pending actions (dangerous!)", NULL, installCustomCommit }, { "Console settings", "Customize system console behavior.", NULL, dmenuSubmenu, NULL, &MenuSyscons }, { "Configure", "The system configuration menu.", NULL, dmenuSubmenu, NULL, &MenuConfigure }, - { "Defaults, Load", "Load default settings.", NULL, variableLoad }, + { "Defaults, Load", "Load default settings.", NULL, dispatch_load_floppy }, { "Device, Mouse", "The mouse configuration menu.", NULL, dmenuSubmenu, NULL, &MenuMouse }, { "Dists, All", "Root of the distribution tree.", NULL, dmenuSubmenu, NULL, &MenuDistributions }, { "Dists, Basic", "Basic FreeBSD distribution menu.", NULL, dmenuSubmenu, NULL, &MenuSubDistributions }, @@ -314,7 +314,7 @@ DMenu MenuInitial = { { "8 Fixit", "Enter repair mode with CDROM/floppy or start shell", NULL, dmenuSubmenu, NULL, &MenuFixit }, { "9 Upgrade", "Upgrade an existing system", NULL, installUpgrade }, { "c Configure", "Do post-install configuration of FreeBSD", NULL, dmenuSubmenu, NULL, &MenuConfigure }, - { "l Load Config","Load default install configuration", NULL, variableLoad }, + { "l Load Config","Load default install configuration", NULL, dispatch_load_floppy }, { "0 Index", "Glossary of functions", NULL, dmenuSubmenu, NULL, &MenuIndex }, { NULL } }, }; diff --git a/release/sysinstall/sysinstall.h b/release/sysinstall/sysinstall.h index d190a28..0b77928 100644 --- a/release/sysinstall/sysinstall.h +++ b/release/sysinstall/sysinstall.h @@ -4,7 +4,7 @@ * This is probably the last attempt in the `sysinstall' line, the next * generation being slated to essentially a complete rewrite. * - * $Id: sysinstall.h,v 1.138 1997/07/16 05:22:42 jkh Exp $ + * $Id: sysinstall.h,v 1.139 1997/07/31 11:08:41 jkh Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. @@ -106,6 +106,7 @@ #define VAR_DOMAINNAME "domainname" #define VAR_EDITOR "editor" #define VAR_EXTRAS "ifconfig_" +#define VAR_CONFIG_FILE "configFile" #define VAR_FTP_DIR "ftpDirectory" #define VAR_FTP_PASS "ftpPass" #define VAR_FTP_PATH "ftp" @@ -459,6 +460,10 @@ extern void diskPartition(Device *dev, Disk *d); /* dispatch.c */ extern int dispatchCommand(char *command); +extern int dispatch_load_floppy(dialogMenuItem *self); +extern int dispatch_load_file_int(int); +extern int dispatch_load_file(dialogMenuItem *self); + /* dist.c */ extern int distReset(dialogMenuItem *self); @@ -705,9 +710,6 @@ extern void variable_unset(char *var); extern char *variable_get_value(char *var, char *prompt); extern int variable_check(char *data); -/* variable_load.c */ -extern int variableLoad(dialogMenuItem *self); - /* wizard.c */ extern void slice_wizard(Disk *d); diff --git a/release/sysinstall/variable_load.c b/release/sysinstall/variable_load.c deleted file mode 100644 index 16b871c..0000000 --- a/release/sysinstall/variable_load.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * The new sysinstall program. - * - * This is probably the last attempt in the `sysinstall' line, the next - * generation being slated for what's essentially a complete rewrite. - * - * $Id: variable_load.c,v 1.8 1997/06/13 09:37:25 jkh Exp $ - * - * Copyright (c) 1997 - * Paul Traina. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * verbatim and that no modifications are made prior to this - * point in the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY PAUL TRAINA ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL PAUL TRAINA OR HIS KILLER RATS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include "sysinstall.h" -#include <sys/signal.h> -#include <sys/fcntl.h> - -/* Add a string to a string list */ -static char ** -string_add(char **list, char *str, int *curr, int *max) -{ - - if (*curr == *max) { - *max += 20; - list = (char **)realloc(list, sizeof(char *) * *max); - } - list[(*curr)++] = strdup(str); - return list; -} - -/* Toss the strings out */ -static void -strings_free(char **list, int *curr, int *max) -{ - int i; - - for (i = 0; i < *curr; i++) - free(list[i]); - free(list); - *curr = *max = 0; -} - -int -variableLoad(dialogMenuItem *self) -{ - int what = DITEM_RESTORE | DITEM_SUCCESS; - char buf[BUFSIZ]; - extern char *distWanted; - char *cp; - FILE *fp; - int i, curr, max; - char **list; - - mediaClose(); - dialog_clear_norefresh(); - - cp = variable_get_value(VAR_INSTALL_CFG, - "Specify the name of a configuration file\n" - "residing on a MSDOS or UFS floppy."); - if (!cp || !*cp) { - variable_unset(VAR_INSTALL_CFG); - what |= DITEM_FAILURE; - return what; - } - - distWanted = cp; - /* Try to open the floppy drive */ - if (DITEM_STATUS(mediaSetFloppy(NULL)) == DITEM_FAILURE) { - msgConfirm("Unable to set media device to floppy."); - what |= DITEM_FAILURE; - mediaClose(); - return what; - } - - if (!mediaDevice->init(mediaDevice)) { - msgConfirm("Unable to mount floppy filesystem."); - what |= DITEM_FAILURE; - mediaClose(); - return what; - } - - fp = mediaDevice->get(mediaDevice, cp, TRUE); - if (fp) { - /* Hint to others that we're running from a script, should they care */ - variable_set2(VAR_NONINTERACTIVE, "YES"); - - /* Now suck in the lot to execute later */ - curr = max = 0; - list = NULL; - while (fgets(buf, sizeof buf, fp)) { - if ((cp = strchr(buf, '\n')) != NULL) - *cp = '\0'; - if (*buf == '\0' || *buf == '#') - continue; - list = string_add(list, buf, &curr, &max); - } - fclose(fp); - mediaClose(); - - for (i = 0; i < curr; i++) { - if (DITEM_STATUS(dispatchCommand(list[i])) != DITEM_SUCCESS) { - if (variable_get(VAR_NO_ERROR)) - variable_unset(VAR_NO_ERROR); - else { - msgConfirm("Command `%s' failed - rest of script aborted.\n", buf); - what |= DITEM_FAILURE; - break; - } - } - } - strings_free(list, &curr, &max); - } - else { - msgConfirm("Configuration file '%s' not found.", cp); - variable_unset(VAR_INSTALL_CFG); - what |= DITEM_FAILURE; - mediaClose(); - } - - variable_unset(VAR_NONINTERACTIVE); - return what; -} |