115788Sjkh/* 215788Sjkh * The new sysinstall program. 315788Sjkh * 415788Sjkh * This is probably the last program in the `sysinstall' line - the next 515788Sjkh * generation being essentially a complete rewrite. 615788Sjkh * 750479Speter * $FreeBSD$ 815788Sjkh * 915788Sjkh * Copyright (c) 1995 1015788Sjkh * Jordan Hubbard. All rights reserved. 1115788Sjkh * 1215788Sjkh * Redistribution and use in source and binary forms, with or without 1315788Sjkh * modification, are permitted provided that the following conditions 1415788Sjkh * are met: 1515788Sjkh * 1. Redistributions of source code must retain the above copyright 1615788Sjkh * notice, this list of conditions and the following disclaimer, 1715788Sjkh * verbatim and that no modifications are made prior to this 1815788Sjkh * point in the file. 1915788Sjkh * 2. Redistributions in binary form must reproduce the above copyright 2015788Sjkh * notice, this list of conditions and the following disclaimer in the 2115788Sjkh * documentation and/or other materials provided with the distribution. 2215788Sjkh * 2315788Sjkh * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND 2415788Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2515788Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2615788Sjkh * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE 2715788Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2815788Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2915788Sjkh * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) 3015788Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3115788Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3215788Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3315788Sjkh * SUCH DAMAGE. 3415788Sjkh * 3515788Sjkh */ 3615788Sjkh 3715788Sjkh#include "sysinstall.h" 3815788Sjkh#include <ctype.h> 3929517Sjkh#include <errno.h> 4029517Sjkh#include <sys/signal.h> 4129517Sjkh#include <sys/fcntl.h> 4215788Sjkh 4329517Sjkh#include "list.h" 4429222Sjkh 4529517Sjkhstatic int dispatch_shutdown(dialogMenuItem *unused); 4629517Sjkhstatic int dispatch_systemExecute(dialogMenuItem *unused); 4737735Sjkhstatic int dispatch_msgConfirm(dialogMenuItem *unused); 48154925Sjkimstatic int dispatch_mediaOpen(dialogMenuItem *unused); 4997777Sjhbstatic int dispatch_mediaClose(dialogMenuItem *unused); 50189754Sgrogstatic int cfgModuleFire(dialogMenuItem *self); 5129517Sjkh 5215788Sjkhstatic struct _word { 5315788Sjkh char *name; 5415788Sjkh int (*handler)(dialogMenuItem *self); 5515788Sjkh} resWords[] = { 5615788Sjkh { "configAnonFTP", configAnonFTP }, 5719385Sjkh { "configRouter", configRouter }, 5881023Srwatson { "configInetd", configInetd }, 5915788Sjkh { "configNFSServer", configNFSServer }, 6026456Sjkh { "configNTP", configNTP }, 6126456Sjkh { "configPCNFSD", configPCNFSD }, 6226456Sjkh { "configPackages", configPackages }, 6326456Sjkh { "configUsers", configUsers }, 64107339Sjhb#ifdef WITH_SLICES 6515788Sjkh { "diskPartitionEditor", diskPartitionEditor }, 66107339Sjhb#endif 6715788Sjkh { "diskPartitionWrite", diskPartitionWrite }, 6815788Sjkh { "diskLabelEditor", diskLabelEditor }, 6915788Sjkh { "diskLabelCommit", diskLabelCommit }, 7015788Sjkh { "distReset", distReset }, 7126601Sjkh { "distSetCustom", distSetCustom }, 7253015Sjkh { "distUnsetCustom", distUnsetCustom }, 7315788Sjkh { "distSetDeveloper", distSetDeveloper }, 7415788Sjkh { "distSetKernDeveloper", distSetKernDeveloper }, 7515788Sjkh { "distSetUser", distSetUser }, 7615788Sjkh { "distSetMinimum", distSetMinimum }, 7715788Sjkh { "distSetEverything", distSetEverything }, 7815788Sjkh { "distSetSrc", distSetSrc }, 7915788Sjkh { "distExtractAll", distExtractAll }, 8015788Sjkh { "docBrowser", docBrowser }, 8115788Sjkh { "docShowDocument", docShowDocument }, 8215788Sjkh { "installCommit", installCommit }, 8315788Sjkh { "installExpress", installExpress }, 8457315Sjkh { "installStandard", installStandard }, 85209832Srandi { "installUpgrade", installUpgrade }, 86109434Sjhb { "installFixupBase", installFixupBase }, 8726456Sjkh { "installFixitHoloShell", installFixitHoloShell }, 8826456Sjkh { "installFixitCDROM", installFixitCDROM }, 89195442Scperciva { "installFixitUSB", installFixitUSB }, 9026456Sjkh { "installFixitFloppy", installFixitFloppy }, 9115788Sjkh { "installFilesystems", installFilesystems }, 9226456Sjkh { "installVarDefaults", installVarDefaults }, 9329517Sjkh { "loadConfig", dispatch_load_file }, 9437735Sjkh { "loadFloppyConfig", dispatch_load_floppy }, 95189754Sgrog { "loadCDROMConfig", dispatch_load_cdrom }, 96154925Sjkim { "mediaOpen", dispatch_mediaOpen }, 9797777Sjhb { "mediaClose", dispatch_mediaClose }, 9815788Sjkh { "mediaSetCDROM", mediaSetCDROM }, 9915788Sjkh { "mediaSetFloppy", mediaSetFloppy }, 100194931Scperciva { "mediaSetUSB", mediaSetUSB }, 10115788Sjkh { "mediaSetDOS", mediaSetDOS }, 10215788Sjkh { "mediaSetFTP", mediaSetFTP }, 10315788Sjkh { "mediaSetFTPActive", mediaSetFTPActive }, 10415788Sjkh { "mediaSetFTPPassive", mediaSetFTPPassive }, 10555392Sjkh { "mediaSetHTTP", mediaSetHTTP }, 106248313Sdteske { "mediaSetHTTPDirect", mediaSetHTTPDirect }, 10715788Sjkh { "mediaSetUFS", mediaSetUFS }, 10815788Sjkh { "mediaSetNFS", mediaSetNFS }, 10918619Sjkh { "mediaSetFTPUserPass", mediaSetFTPUserPass }, 11015788Sjkh { "mediaSetCPIOVerbosity", mediaSetCPIOVerbosity }, 11115788Sjkh { "mediaGetType", mediaGetType }, 11237735Sjkh { "msgConfirm", dispatch_msgConfirm }, 11316208Sjkh { "optionsEditor", optionsEditor }, 11426613Sjkh { "packageAdd", packageAdd }, 11520484Sjkh { "addGroup", userAddGroup }, 11620484Sjkh { "addUser", userAddUser }, 11729517Sjkh { "shutdown", dispatch_shutdown }, 11829517Sjkh { "system", dispatch_systemExecute }, 11937735Sjkh { "dumpVariables", dump_variables }, 12037735Sjkh { "tcpMenuSelect", tcpMenuSelect }, 12115788Sjkh { NULL, NULL }, 12215788Sjkh}; 12315788Sjkh 12429517Sjkh/* 12529517Sjkh * Helper routines for buffering data. 12629517Sjkh * 12729517Sjkh * We read an entire configuration into memory before executing it 12829517Sjkh * so that we are truely standalone and can do things like nuke the 12929517Sjkh * file or disk we're working on. 13029517Sjkh */ 13129517Sjkh 13229517Sjkhtypedef struct command_buffer_ { 13329517Sjkh qelement queue; 13429517Sjkh char * string; 13529517Sjkh} command_buffer; 13629517Sjkh 13729517Sjkhstatic void 13829517Sjkhdispatch_free_command(command_buffer *item) 13915788Sjkh{ 140215637Sbrucec if (item != NULL) { 141215637Sbrucec REMQUE(item); 142215637Sbrucec free(item->string); 143215637Sbrucec item->string = NULL; 144215637Sbrucec } 145215637Sbrucec 14629517Sjkh free(item); 14729517Sjkh} 14815788Sjkh 14929517Sjkhstatic void 15029517Sjkhdispatch_free_all(qelement *head) 15129517Sjkh{ 15229517Sjkh command_buffer *item; 15329517Sjkh 15429517Sjkh while (!EMPTYQUE(*head)) { 15529517Sjkh item = (command_buffer *) head->q_forw; 15629517Sjkh dispatch_free_command(item); 15715788Sjkh } 15815788Sjkh} 15915788Sjkh 16029517Sjkhstatic command_buffer * 16129517Sjkhdispatch_add_command(qelement *head, char *string) 16229517Sjkh{ 163215637Sbrucec command_buffer *new = NULL; 16429517Sjkh 16529517Sjkh new = malloc(sizeof(command_buffer)); 16629517Sjkh 167215637Sbrucec if (new != NULL) { 16829517Sjkh 169215637Sbrucec new->string = strdup(string); 17029517Sjkh 171215637Sbrucec /* 172215637Sbrucec * We failed to copy `string'; clean up the allocated 173215637Sbrucec * resources. 174215637Sbrucec */ 175215637Sbrucec if (new->string == NULL) { 176215637Sbrucec free(new); 177215637Sbrucec new = NULL; 178215637Sbrucec } else { 179215637Sbrucec INSQUEUE(new, head->q_back); 180215637Sbrucec } 181215637Sbrucec } 182215637Sbrucec 18329517Sjkh return new; 18429517Sjkh} 185215637Sbrucec 18629517Sjkh/* 18729517Sjkh * Command processing 18829517Sjkh */ 18929517Sjkh 19021764Sjkh/* Just convenience */ 19126795Sjkhstatic int 19229517Sjkhdispatch_shutdown(dialogMenuItem *unused) 19321764Sjkh{ 19421764Sjkh systemShutdown(0); 19521764Sjkh return DITEM_FAILURE; 19621764Sjkh} 19721764Sjkh 19826795Sjkhstatic int 19929517Sjkhdispatch_systemExecute(dialogMenuItem *unused) 20026795Sjkh{ 20129539Spst char *cmd = variable_get(VAR_COMMAND); 20226795Sjkh 20326795Sjkh if (cmd) 20426795Sjkh return systemExecute(cmd) ? DITEM_FAILURE : DITEM_SUCCESS; 20526795Sjkh else 20626795Sjkh msgDebug("_systemExecute: No command passed in `command' variable.\n"); 20726795Sjkh return DITEM_FAILURE; 20826795Sjkh} 20926795Sjkh 21029222Sjkhstatic int 21137735Sjkhdispatch_msgConfirm(dialogMenuItem *unused) 21237735Sjkh{ 21337735Sjkh char *msg = variable_get(VAR_COMMAND); 21437735Sjkh 21537735Sjkh if (msg) { 21679304Skris msgConfirm("%s", msg); 21737735Sjkh return DITEM_SUCCESS; 21837735Sjkh } 21937735Sjkh 22037735Sjkh msgDebug("_msgConfirm: No message passed in `command' variable.\n"); 22137735Sjkh return DITEM_FAILURE; 22237735Sjkh} 22337735Sjkh 22437735Sjkhstatic int 225154925Sjkimdispatch_mediaOpen(dialogMenuItem *unused) 226154925Sjkim{ 227154925Sjkim return mediaOpen(); 228154925Sjkim} 229154925Sjkim 230154925Sjkimstatic int 23197777Sjhbdispatch_mediaClose(dialogMenuItem *unused) 23297777Sjhb{ 23397777Sjhb mediaClose(); 23497777Sjhb return DITEM_SUCCESS; 23597777Sjhb} 23697777Sjhb 23797777Sjhbstatic int 23829517Sjkhcall_possible_resword(char *name, dialogMenuItem *value, int *status) 23929222Sjkh{ 24029517Sjkh int i, rval; 24129222Sjkh 24229517Sjkh rval = 0; 24329517Sjkh for (i = 0; resWords[i].name; i++) { 24429517Sjkh if (!strcmp(name, resWords[i].name)) { 24529517Sjkh *status = resWords[i].handler(value); 24629517Sjkh rval = 1; 24729517Sjkh break; 24829222Sjkh } 24929222Sjkh } 25029517Sjkh return rval; 25129222Sjkh} 25229222Sjkh 25315788Sjkh/* For a given string, call it or spit out an undefined command diagnostic */ 25415788Sjkhint 25515788SjkhdispatchCommand(char *str) 25615788Sjkh{ 25715788Sjkh int i; 25816766Sjkh char *cp; 25915788Sjkh 26015788Sjkh if (!str || !*str) { 26115788Sjkh msgConfirm("Null or zero-length string passed to dispatchCommand"); 26215788Sjkh return DITEM_FAILURE; 26315788Sjkh } 264189754Sgrog 265189754Sgrog /* Fixup DOS abuse */ 266189754Sgrog if ((cp = index(str, '\r')) != NULL) 26721764Sjkh *cp = '\0'; 26821764Sjkh 26926456Sjkh /* If it's got a `=' sign in there, assume it's a variable setting */ 27016766Sjkh if (index(str, '=')) { 27126572Sjkh if (isDebug()) 27226572Sjkh msgDebug("dispatch: setting variable `%s'\n", str); 27343685Sjkh variable_set(str, 0); 27421764Sjkh i = DITEM_SUCCESS; 27515788Sjkh } 27621764Sjkh else { 27729517Sjkh /* A command might be a pathname if it's encoded in argv[0], which 27829517Sjkh we also support */ 27926456Sjkh if ((cp = rindex(str, '/')) != NULL) 28021764Sjkh str = cp + 1; 28126572Sjkh if (isDebug()) 28226572Sjkh msgDebug("dispatch: calling resword `%s'\n", str); 28321764Sjkh if (!call_possible_resword(str, NULL, &i)) { 28426456Sjkh msgNotify("Warning: No such command ``%s''", str); 28521764Sjkh i = DITEM_FAILURE; 28621764Sjkh } 28797778Sjhb /* 28897778Sjhb * Allow a user to prefix a command with "noError" to cause 28997778Sjhb * us to ignore any errors for that one command. 29097778Sjhb */ 29197778Sjhb if (i != DITEM_SUCCESS && variable_get(VAR_NO_ERROR)) 29297778Sjhb i = DITEM_SUCCESS; 29397778Sjhb variable_unset(VAR_NO_ERROR); 29415788Sjkh } 29515788Sjkh return i; 29615788Sjkh} 29729517Sjkh 298215637Sbrucec 29929517Sjkh/* 30029517Sjkh * File processing 30129517Sjkh */ 30229517Sjkh 30329517Sjkhstatic qelement * 30429517Sjkhdispatch_load_fp(FILE *fp) 30529517Sjkh{ 30629517Sjkh qelement *head; 30729517Sjkh char buf[BUFSIZ], *cp; 30829517Sjkh 30929517Sjkh head = malloc(sizeof(qelement)); 31029517Sjkh 31129517Sjkh if (!head) 31229517Sjkh return NULL; 31329517Sjkh 31429517Sjkh INITQUE(*head); 31529517Sjkh 31629517Sjkh while (fgets(buf, sizeof buf, fp)) { 317189754Sgrog /* Fix up DOS abuse */ 318189754Sgrog if ((cp = index(buf, '\r')) != NULL) 31929517Sjkh *cp = '\0'; 320189754Sgrog /* If it's got a new line, trim it */ 321189754Sgrog if ((cp = index(buf, '\n')) != NULL) 322189754Sgrog *cp = '\0'; 32329517Sjkh if (*buf == '\0' || *buf == '#') 32429517Sjkh continue; 32529517Sjkh 32629517Sjkh if (!dispatch_add_command(head, buf)) 32729517Sjkh return NULL; 32829517Sjkh } 32929517Sjkh 33029517Sjkh return head; 33129517Sjkh} 33229517Sjkh 33329517Sjkhstatic int 33429517Sjkhdispatch_execute(qelement *head) 33529517Sjkh{ 33629517Sjkh int result = DITEM_SUCCESS; 33729517Sjkh command_buffer *item; 33837735Sjkh char *old_interactive; 33929517Sjkh 34029517Sjkh if (!head) 34129517Sjkh return result | DITEM_FAILURE; 34229517Sjkh 34337735Sjkh old_interactive = variable_get(VAR_NONINTERACTIVE); 34437735Sjkh if (old_interactive) 34537735Sjkh old_interactive = strdup(old_interactive); /* save copy */ 34637735Sjkh 34729517Sjkh /* Hint to others that we're running from a script, should they care */ 34843685Sjkh variable_set2(VAR_NONINTERACTIVE, "yes", 0); 34929517Sjkh 35029517Sjkh while (!EMPTYQUE(*head)) { 35129517Sjkh item = (command_buffer *) head->q_forw; 352189754Sgrog 35329517Sjkh if (DITEM_STATUS(dispatchCommand(item->string)) != DITEM_SUCCESS) { 35497778Sjhb msgConfirm("Command `%s' failed - rest of script aborted.\n", 35597778Sjhb item->string); 35697778Sjhb result |= DITEM_FAILURE; 35797778Sjhb break; 35829517Sjkh } 35929517Sjkh dispatch_free_command(item); 36029517Sjkh } 36129517Sjkh 36229517Sjkh dispatch_free_all(head); 36329517Sjkh 36437735Sjkh if (!old_interactive) 36537735Sjkh variable_unset(VAR_NONINTERACTIVE); 36637735Sjkh else { 36743685Sjkh variable_set2(VAR_NONINTERACTIVE, old_interactive, 0); 36837735Sjkh free(old_interactive); 36937735Sjkh } 37029517Sjkh 37129517Sjkh return result; 37229517Sjkh} 37329517Sjkh 37429517Sjkhint 37529517Sjkhdispatch_load_file_int(int quiet) 37629517Sjkh{ 37729517Sjkh FILE *fp; 37829517Sjkh char *cp; 37929517Sjkh int i; 38029517Sjkh qelement *list; 38129517Sjkh 38229517Sjkh static const char *names[] = { 38329517Sjkh "install.cfg", 38429517Sjkh "/stand/install.cfg", 38529517Sjkh "/tmp/install.cfg", 38629517Sjkh NULL 38729517Sjkh }; 38829517Sjkh 38929517Sjkh fp = NULL; 39029517Sjkh cp = variable_get(VAR_CONFIG_FILE); 39129517Sjkh if (!cp) { 39229517Sjkh for (i = 0; names[i]; i++) 39329517Sjkh if ((fp = fopen(names[i], "r")) != NULL) 39429517Sjkh break; 39529517Sjkh } else 39629517Sjkh fp = fopen(cp, "r"); 39729517Sjkh 39829517Sjkh if (!fp) { 39929517Sjkh if (!quiet) 40029517Sjkh msgConfirm("Unable to open %s: %s", cp, strerror(errno)); 40129517Sjkh return DITEM_FAILURE; 40229517Sjkh } 40329517Sjkh 40429517Sjkh list = dispatch_load_fp(fp); 40529517Sjkh fclose(fp); 40629517Sjkh 40729517Sjkh return dispatch_execute(list); 40829517Sjkh} 40929517Sjkh 41029517Sjkhint 41129517Sjkhdispatch_load_file(dialogMenuItem *self) 41229517Sjkh{ 41329517Sjkh return dispatch_load_file_int(FALSE); 41429517Sjkh} 41529517Sjkh 41629517Sjkhint 41729517Sjkhdispatch_load_floppy(dialogMenuItem *self) 41829517Sjkh{ 41954587Sjkh int what = DITEM_SUCCESS; 42029517Sjkh extern char *distWanted; 42129517Sjkh char *cp; 42229517Sjkh FILE *fp; 42329517Sjkh qelement *list; 42429517Sjkh 42529517Sjkh mediaClose(); 42629517Sjkh cp = variable_get_value(VAR_INSTALL_CFG, 427189754Sgrog "Specify the name of a configuration file", 0); 42829517Sjkh if (!cp || !*cp) { 42929517Sjkh variable_unset(VAR_INSTALL_CFG); 43029517Sjkh what |= DITEM_FAILURE; 43129517Sjkh return what; 43229517Sjkh } 43329517Sjkh 43429517Sjkh distWanted = cp; 43529517Sjkh /* Try to open the floppy drive */ 43629517Sjkh if (DITEM_STATUS(mediaSetFloppy(NULL)) == DITEM_FAILURE) { 43729517Sjkh msgConfirm("Unable to set media device to floppy."); 43829517Sjkh what |= DITEM_FAILURE; 43929517Sjkh mediaClose(); 44029517Sjkh return what; 44129517Sjkh } 44229517Sjkh 44379065Sdd if (!DEVICE_INIT(mediaDevice)) { 44429517Sjkh msgConfirm("Unable to mount floppy filesystem."); 44529517Sjkh what |= DITEM_FAILURE; 44629517Sjkh mediaClose(); 44729517Sjkh return what; 44829517Sjkh } 44929517Sjkh 45079065Sdd fp = DEVICE_GET(mediaDevice, cp, TRUE); 45129517Sjkh if (fp) { 45229517Sjkh list = dispatch_load_fp(fp); 45329517Sjkh fclose(fp); 45429517Sjkh mediaClose(); 45529517Sjkh 45629517Sjkh what |= dispatch_execute(list); 45729517Sjkh } 45829517Sjkh else { 45937735Sjkh if (!variable_get(VAR_NO_ERROR)) 46037735Sjkh msgConfirm("Configuration file '%s' not found.", cp); 46129517Sjkh variable_unset(VAR_INSTALL_CFG); 46229517Sjkh what |= DITEM_FAILURE; 46329517Sjkh mediaClose(); 46429517Sjkh } 46529517Sjkh return what; 46629517Sjkh} 46729517Sjkh 468189754Sgrogint 469189754Sgrogdispatch_load_cdrom(dialogMenuItem *self) 470189754Sgrog{ 471189754Sgrog int what = DITEM_SUCCESS; 472189754Sgrog extern char *distWanted; 473189754Sgrog char *cp; 474189754Sgrog FILE *fp; 475189754Sgrog qelement *list; 476189754Sgrog 477189754Sgrog mediaClose(); 478189754Sgrog cp = variable_get_value(VAR_INSTALL_CFG, 479189754Sgrog "Specify the name of a configuration file\n" 480189754Sgrog "residing on the CDROM.", 0); 481189754Sgrog if (!cp || !*cp) { 482189754Sgrog variable_unset(VAR_INSTALL_CFG); 483189754Sgrog what |= DITEM_FAILURE; 484189754Sgrog return what; 485189754Sgrog } 486189754Sgrog 487189754Sgrog distWanted = cp; 488189754Sgrog /* Try to open the floppy drive */ 489189754Sgrog if (DITEM_STATUS(mediaSetCDROM(NULL)) == DITEM_FAILURE) { 490189754Sgrog msgConfirm("Unable to set media device to CDROM."); 491189754Sgrog what |= DITEM_FAILURE; 492189754Sgrog mediaClose(); 493189754Sgrog return what; 494189754Sgrog } 495189754Sgrog 496189754Sgrog if (!DEVICE_INIT(mediaDevice)) { 497189754Sgrog msgConfirm("Unable to CDROM filesystem."); 498189754Sgrog what |= DITEM_FAILURE; 499189754Sgrog mediaClose(); 500189754Sgrog return what; 501189754Sgrog } 502189754Sgrog 503189754Sgrog fp = DEVICE_GET(mediaDevice, cp, TRUE); 504189754Sgrog if (fp) { 505189754Sgrog list = dispatch_load_fp(fp); 506189754Sgrog fclose(fp); 507189754Sgrog mediaClose(); 508189754Sgrog 509189754Sgrog what |= dispatch_execute(list); 510189754Sgrog } 511189754Sgrog else { 512189754Sgrog if (!variable_get(VAR_NO_ERROR)) 513189754Sgrog msgConfirm("Configuration file '%s' not found.", cp); 514189754Sgrog variable_unset(VAR_INSTALL_CFG); 515189754Sgrog what |= DITEM_FAILURE; 516189754Sgrog mediaClose(); 517189754Sgrog } 518189754Sgrog return what; 519189754Sgrog} 520189754Sgrog 521189754Sgrog/* 522189754Sgrog * Create a menu based on available disk devices 523189754Sgrog */ 524189754Sgrogint 525189754Sgrogdispatch_load_menu(dialogMenuItem *self) 526189754Sgrog{ 527189754Sgrog DMenu *menu; 528189754Sgrog Device **devlist; 529189754Sgrog char *err; 530189754Sgrog int what, i, j, msize, count; 531194931Scperciva DeviceType dtypes[] = {DEVICE_TYPE_FLOPPY, DEVICE_TYPE_CDROM, 532194931Scperciva DEVICE_TYPE_DOS, DEVICE_TYPE_UFS, DEVICE_TYPE_USB}; 533189754Sgrog 534189754Sgrog fprintf(stderr, "dispatch_load_menu called\n"); 535189754Sgrog 536189754Sgrog msize = sizeof(DMenu) + (sizeof(dialogMenuItem) * 2); 537189754Sgrog count = 0; 538189754Sgrog err = NULL; 539189754Sgrog what = DITEM_SUCCESS; 540189754Sgrog 541189754Sgrog if ((menu = malloc(msize)) == NULL) { 542189754Sgrog err = "Failed to allocate memory for menu"; 543189754Sgrog goto errout; 544189754Sgrog } 545189754Sgrog 546189754Sgrog bcopy(&MenuConfig, menu, sizeof(DMenu)); 547189754Sgrog 548189754Sgrog bzero(&menu->items[count], sizeof(menu->items[0])); 549189754Sgrog menu->items[count].prompt = strdup("X Exit"); 550189754Sgrog menu->items[count].title = strdup("Exit this menu (returning to previous)"); 551189754Sgrog menu->items[count].fire = dmenuExit; 552189754Sgrog count++; 553189754Sgrog 554189754Sgrog for (i = 0; i < sizeof(dtypes) / sizeof(dtypes[0]); i++) { 555189754Sgrog if ((devlist = deviceFind(NULL, dtypes[i])) == NULL) { 556189754Sgrog fprintf(stderr, "No devices found for type %d\n", dtypes[i]); 557189754Sgrog continue; 558189754Sgrog } 559189754Sgrog 560189754Sgrog for (j = 0; devlist[j] != NULL; j++) { 561189754Sgrog fprintf(stderr, "device type %d device name %s\n", dtypes[i], devlist[j]->name); 562189754Sgrog msize += sizeof(dialogMenuItem); 563189754Sgrog if ((menu = realloc(menu, msize)) == NULL) { 564189754Sgrog err = "Failed to allocate memory for menu item"; 565189754Sgrog goto errout; 566189754Sgrog } 567189754Sgrog 568189754Sgrog bzero(&menu->items[count], sizeof(menu->items[0])); 569189754Sgrog menu->items[count].fire = cfgModuleFire; 570189754Sgrog 571189754Sgrog menu->items[count].prompt = strdup(devlist[j]->name); 572189754Sgrog menu->items[count].title = strdup(devlist[j]->description); 573189754Sgrog /* XXX: dialog(3) sucks */ 574189754Sgrog menu->items[count].aux = (long)devlist[j]; 575189754Sgrog count++; 576189754Sgrog } 577189754Sgrog } 578189754Sgrog 579189754Sgrog menu->items[count].prompt = NULL; 580189754Sgrog menu->items[count].title = NULL; 581189754Sgrog 582189754Sgrog dmenuOpenSimple(menu, FALSE); 583189754Sgrog 584189754Sgrog errout: 585189754Sgrog for (i = 0; i < count; i++) { 586189754Sgrog free(menu->items[i].prompt); 587189754Sgrog free(menu->items[i].title); 588189754Sgrog } 589189754Sgrog 590189754Sgrog free(menu); 591189754Sgrog 592189754Sgrog if (err != NULL) { 593189754Sgrog what |= DITEM_FAILURE; 594189754Sgrog if (!variable_get(VAR_NO_ERROR)) 595234737Sdim msgConfirm("%s", err); 596189754Sgrog } 597189754Sgrog 598189754Sgrog return (what); 599189754Sgrog 600189754Sgrog} 601189754Sgrog 602189754Sgrogstatic int 603189754SgrogcfgModuleFire(dialogMenuItem *self) { 604189754Sgrog Device *d; 605189754Sgrog FILE *fp; 606189754Sgrog int what = DITEM_SUCCESS; 607189754Sgrog extern char *distWanted; 608189754Sgrog qelement *list; 609189754Sgrog char *cp; 610189754Sgrog 611189754Sgrog d = (Device *)self->aux; 612189754Sgrog 613189754Sgrog msgDebug("cfgModuleFire: User selected %s (%s)\n", self->prompt, d->devname); 614189754Sgrog 615189754Sgrog mediaClose(); 616189754Sgrog 617189754Sgrog cp = variable_get_value(VAR_INSTALL_CFG, 618189754Sgrog "Specify the name of a configuration file", 0); 619189754Sgrog if (!cp || !*cp) { 620189754Sgrog variable_unset(VAR_INSTALL_CFG); 621189754Sgrog what |= DITEM_FAILURE; 622189754Sgrog return what; 623189754Sgrog } 624189754Sgrog 625189754Sgrog distWanted = cp; 626189754Sgrog 627189754Sgrog mediaDevice = d; 628189754Sgrog if (!DEVICE_INIT(mediaDevice)) { 629189754Sgrog msgConfirm("Unable to mount filesystem."); 630189754Sgrog what |= DITEM_FAILURE; 631189754Sgrog mediaClose(); 632189754Sgrog return what; 633189754Sgrog } 634189754Sgrog msgDebug("getting fp for %s\n", cp); 635189754Sgrog 636189754Sgrog fp = DEVICE_GET(mediaDevice, cp, TRUE); 637189754Sgrog if (fp) { 638189754Sgrog msgDebug("opened OK, processing..\n"); 639189754Sgrog 640189754Sgrog list = dispatch_load_fp(fp); 641189754Sgrog fclose(fp); 642189754Sgrog mediaClose(); 643189754Sgrog 644189754Sgrog what |= dispatch_execute(list); 645189754Sgrog } else { 646189754Sgrog if (!variable_get(VAR_NO_ERROR)) 647189754Sgrog msgConfirm("Configuration file '%s' not found.", cp); 648189754Sgrog variable_unset(VAR_INSTALL_CFG); 649189754Sgrog what |= DITEM_FAILURE; 650189754Sgrog mediaClose(); 651189754Sgrog } 652189754Sgrog 653189754Sgrog return(what); 654189754Sgrog } 655