121c1c48aSSascha Wildner /* 221c1c48aSSascha Wildner * Copyright (c)2004 The DragonFly Project. All rights reserved. 321c1c48aSSascha Wildner * 421c1c48aSSascha Wildner * Redistribution and use in source and binary forms, with or without 521c1c48aSSascha Wildner * modification, are permitted provided that the following conditions 621c1c48aSSascha Wildner * are met: 721c1c48aSSascha Wildner * 821c1c48aSSascha Wildner * Redistributions of source code must retain the above copyright 921c1c48aSSascha Wildner * notice, this list of conditions and the following disclaimer. 1021c1c48aSSascha Wildner * 1121c1c48aSSascha Wildner * Redistributions in binary form must reproduce the above copyright 1221c1c48aSSascha Wildner * notice, this list of conditions and the following disclaimer in 1321c1c48aSSascha Wildner * the documentation and/or other materials provided with the 1421c1c48aSSascha Wildner * distribution. 1521c1c48aSSascha Wildner * 1621c1c48aSSascha Wildner * Neither the name of the DragonFly Project nor the names of its 1721c1c48aSSascha Wildner * contributors may be used to endorse or promote products derived 1821c1c48aSSascha Wildner * from this software without specific prior written permission. 1921c1c48aSSascha Wildner * 2021c1c48aSSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2121c1c48aSSascha Wildner * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2221c1c48aSSascha Wildner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 2321c1c48aSSascha Wildner * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 2421c1c48aSSascha Wildner * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 2521c1c48aSSascha Wildner * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 2621c1c48aSSascha Wildner * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 2721c1c48aSSascha Wildner * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2821c1c48aSSascha Wildner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 2921c1c48aSSascha Wildner * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3021c1c48aSSascha Wildner * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 3121c1c48aSSascha Wildner * OF THE POSSIBILITY OF SUCH DAMAGE. 3221c1c48aSSascha Wildner */ 3321c1c48aSSascha Wildner 3421c1c48aSSascha Wildner /* 3521c1c48aSSascha Wildner * fn_disk.c 3621c1c48aSSascha Wildner * Disk functions for installer. 3721c1c48aSSascha Wildner * $Id: fn_disk.c,v 1.40 2005/03/13 01:53:58 cpressey Exp $ 3821c1c48aSSascha Wildner */ 3921c1c48aSSascha Wildner 4021c1c48aSSascha Wildner #include <stdlib.h> 4121c1c48aSSascha Wildner #include <string.h> 4221c1c48aSSascha Wildner 4321c1c48aSSascha Wildner #ifdef ENABLE_NLS 4421c1c48aSSascha Wildner #include <libintl.h> 4521c1c48aSSascha Wildner #define _(String) gettext (String) 4621c1c48aSSascha Wildner #else 4721c1c48aSSascha Wildner #define _(String) (String) 4821c1c48aSSascha Wildner #endif 4921c1c48aSSascha Wildner 5021c1c48aSSascha Wildner #include "libaura/mem.h" 5121c1c48aSSascha Wildner #include "libaura/fspred.h" 5221c1c48aSSascha Wildner 5321c1c48aSSascha Wildner #include "libdfui/dfui.h" 5421c1c48aSSascha Wildner #include "libdfui/system.h" 5521c1c48aSSascha Wildner 5621c1c48aSSascha Wildner #include "libinstaller/commands.h" 5721c1c48aSSascha Wildner #include "libinstaller/diskutil.h" 5821c1c48aSSascha Wildner #include "libinstaller/functions.h" 5921c1c48aSSascha Wildner #include "libinstaller/uiutil.h" 6021c1c48aSSascha Wildner 6121c1c48aSSascha Wildner #include "fn.h" 6221c1c48aSSascha Wildner #include "pathnames.h" 6321c1c48aSSascha Wildner 6421c1c48aSSascha Wildner /*** DISK-RELATED FUNCTIONS ***/ 6521c1c48aSSascha Wildner 6621c1c48aSSascha Wildner /* 6721c1c48aSSascha Wildner * Ask the user which physical disk they want. 6821c1c48aSSascha Wildner * Changes ss->selected_disk if successful. 6921c1c48aSSascha Wildner */ 7021c1c48aSSascha Wildner void 7121c1c48aSSascha Wildner fn_select_disk(struct i_fn_args *a) 7221c1c48aSSascha Wildner { 7321c1c48aSSascha Wildner struct dfui_form *f; 7421c1c48aSSascha Wildner struct dfui_action *k; 7521c1c48aSSascha Wildner struct dfui_response *r; 7621c1c48aSSascha Wildner struct disk *d; 7721c1c48aSSascha Wildner 7821c1c48aSSascha Wildner f = dfui_form_create( 7921c1c48aSSascha Wildner "select_disk", 8021c1c48aSSascha Wildner _("Select Disk"), 8121c1c48aSSascha Wildner a->short_desc, 8221c1c48aSSascha Wildner "", 8321c1c48aSSascha Wildner 8421c1c48aSSascha Wildner "p", "role", "menu", 8521c1c48aSSascha Wildner "p", "special", "dfinstaller_select_disk", 8621c1c48aSSascha Wildner 8721c1c48aSSascha Wildner NULL 8821c1c48aSSascha Wildner ); 8921c1c48aSSascha Wildner 9021c1c48aSSascha Wildner for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) { 9121c1c48aSSascha Wildner dfui_form_action_add(f, disk_get_device_name(d), 9221c1c48aSSascha Wildner dfui_info_new(disk_get_desc(d), "", "")); 9321c1c48aSSascha Wildner } 9421c1c48aSSascha Wildner 9521c1c48aSSascha Wildner k = dfui_form_action_add(f, "cancel", 9621c1c48aSSascha Wildner dfui_info_new(a->cancel_desc, "", "")); 9721c1c48aSSascha Wildner dfui_action_property_set(k, "accelerator", "ESC"); 9821c1c48aSSascha Wildner 9921c1c48aSSascha Wildner if (!dfui_be_present(a->c, f, &r)) 10021c1c48aSSascha Wildner abort_backend(); 10121c1c48aSSascha Wildner 10221c1c48aSSascha Wildner if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 10321c1c48aSSascha Wildner a->result = 0; 10421c1c48aSSascha Wildner } else { 10521c1c48aSSascha Wildner d = disk_find(a->s, dfui_response_get_action_id(r)); 10621c1c48aSSascha Wildner if (d == NULL) { 10721c1c48aSSascha Wildner inform(a->c, _("Internal error - response from frontend " 10821c1c48aSSascha Wildner "should be a valid device name.")); 10921c1c48aSSascha Wildner a->result = 0; 11021c1c48aSSascha Wildner } else { 11121c1c48aSSascha Wildner storage_set_selected_disk(a->s, d); 11221c1c48aSSascha Wildner a->result = 1; 11321c1c48aSSascha Wildner } 11421c1c48aSSascha Wildner } 11521c1c48aSSascha Wildner 11621c1c48aSSascha Wildner dfui_form_free(f); 11721c1c48aSSascha Wildner dfui_response_free(r); 11821c1c48aSSascha Wildner } 11921c1c48aSSascha Wildner 12021c1c48aSSascha Wildner /* 12121c1c48aSSascha Wildner * Ask the user which slice on a the selected disk they want. 12221c1c48aSSascha Wildner * Changes ss->selected_slice. 12321c1c48aSSascha Wildner */ 12421c1c48aSSascha Wildner void 12521c1c48aSSascha Wildner fn_select_slice(struct i_fn_args *a) 12621c1c48aSSascha Wildner { 12721c1c48aSSascha Wildner struct dfui_form *f; 12821c1c48aSSascha Wildner struct dfui_action *k; 12921c1c48aSSascha Wildner struct dfui_response *r; 13021c1c48aSSascha Wildner struct slice *s; 13121c1c48aSSascha Wildner char string[16]; 13221c1c48aSSascha Wildner 13321c1c48aSSascha Wildner f = dfui_form_create( 13421c1c48aSSascha Wildner "select_slice", 13521c1c48aSSascha Wildner _("Select Primary Partition"), 13621c1c48aSSascha Wildner a->short_desc, 13721c1c48aSSascha Wildner "", 13821c1c48aSSascha Wildner 13921c1c48aSSascha Wildner "p", "role", "menu", 14021c1c48aSSascha Wildner "p", "special", "dfinstaller_select_slice", 14121c1c48aSSascha Wildner 14221c1c48aSSascha Wildner NULL 14321c1c48aSSascha Wildner ); 14421c1c48aSSascha Wildner 14521c1c48aSSascha Wildner for (s = disk_slice_first(storage_get_selected_disk(a->s)); 14621c1c48aSSascha Wildner s != NULL; s = slice_next(s)) { 14721c1c48aSSascha Wildner snprintf(string, 16, "%d", slice_get_number(s)); 14821c1c48aSSascha Wildner dfui_form_action_add(f, string, 14921c1c48aSSascha Wildner dfui_info_new(slice_get_desc(s), "", "")); 15021c1c48aSSascha Wildner } 15121c1c48aSSascha Wildner 15221c1c48aSSascha Wildner k = dfui_form_action_add(f, "cancel", 15321c1c48aSSascha Wildner dfui_info_new(a->cancel_desc, "", "")); 15421c1c48aSSascha Wildner dfui_action_property_set(k, "accelerator", "ESC"); 15521c1c48aSSascha Wildner 15621c1c48aSSascha Wildner if (!dfui_be_present(a->c, f, &r)) 15721c1c48aSSascha Wildner abort_backend(); 15821c1c48aSSascha Wildner 15921c1c48aSSascha Wildner if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) { 16021c1c48aSSascha Wildner a->result = 0; 16121c1c48aSSascha Wildner } else { 16221c1c48aSSascha Wildner s = slice_find(storage_get_selected_disk(a->s), 16321c1c48aSSascha Wildner atoi(dfui_response_get_action_id(r))); 16421c1c48aSSascha Wildner if (s == NULL) { 16521c1c48aSSascha Wildner inform(a->c, _("Internal error - response from frontend " 16621c1c48aSSascha Wildner "should be a valid slice number.")); 16721c1c48aSSascha Wildner a->result = 0; 16821c1c48aSSascha Wildner } else { 16921c1c48aSSascha Wildner storage_set_selected_slice(a->s, s); 17021c1c48aSSascha Wildner a->result = 1; 17121c1c48aSSascha Wildner } 17221c1c48aSSascha Wildner } 17321c1c48aSSascha Wildner 17421c1c48aSSascha Wildner dfui_form_free(f); 17521c1c48aSSascha Wildner dfui_response_free(r); 17621c1c48aSSascha Wildner } 17721c1c48aSSascha Wildner 17821c1c48aSSascha Wildner /* 17921c1c48aSSascha Wildner * If ss->selected_disk == NULL, user will be asked for which disk. 18021c1c48aSSascha Wildner * Returns 1 if disk was formatted, 0 if it wasn't. 18121c1c48aSSascha Wildner * If it was, ss->selected_disk and ss->selected_slice are set to it. 18221c1c48aSSascha Wildner */ 18321c1c48aSSascha Wildner void 18421c1c48aSSascha Wildner fn_format_disk(struct i_fn_args *a) 18521c1c48aSSascha Wildner { 18621c1c48aSSascha Wildner struct commands *cmds; 18721c1c48aSSascha Wildner char *selected_disk_string; 18821c1c48aSSascha Wildner 18921c1c48aSSascha Wildner if (storage_get_selected_disk(a->s) == NULL) { 19021c1c48aSSascha Wildner a->short_desc = _("Select a disk to format."); 19121c1c48aSSascha Wildner a->cancel_desc = _("Return to Utilities Menu"); 19221c1c48aSSascha Wildner fn_select_disk(a); 19321c1c48aSSascha Wildner if (!a->result || storage_get_selected_disk(a->s) == NULL) { 19421c1c48aSSascha Wildner a->result = 0; 19521c1c48aSSascha Wildner return; 19621c1c48aSSascha Wildner } 19721c1c48aSSascha Wildner } 19821c1c48aSSascha Wildner 19921c1c48aSSascha Wildner if (confirm_dangerous_action(a->c, 20021c1c48aSSascha Wildner _("WARNING! ALL data in ALL partitions on the disk\n\n" 20121c1c48aSSascha Wildner "%s\n\nwill be IRREVOCABLY ERASED!\n\nAre you ABSOLUTELY " 20221c1c48aSSascha Wildner "SURE you wish to take this action? This is your " 20321c1c48aSSascha Wildner "LAST CHANCE to cancel!"), disk_get_desc(storage_get_selected_disk(a->s)))) { 20421c1c48aSSascha Wildner cmds = commands_new(); 20521c1c48aSSascha Wildner 20621c1c48aSSascha Wildner command_add(cmds, "%s%s -BI %s", 20721c1c48aSSascha Wildner a->os_root, cmd_name(a, "FDISK"), 208f59b7dfaSSascha Wildner disk_get_device_name(storage_get_selected_disk(a->s))); 20921c1c48aSSascha Wildner 21021c1c48aSSascha Wildner if (!commands_execute(a, cmds)) { 21121c1c48aSSascha Wildner inform(a->c, _("The disk\n\n%s\n\nwas " 21221c1c48aSSascha Wildner "not correctly formatted, and may " 21321c1c48aSSascha Wildner "now be in an inconsistent state. " 21421c1c48aSSascha Wildner "We recommend re-formatting it " 21521c1c48aSSascha Wildner "before attempting to install " 21621c1c48aSSascha Wildner "%s on it."), 21721c1c48aSSascha Wildner disk_get_desc(storage_get_selected_disk(a->s)), 21821c1c48aSSascha Wildner OPERATING_SYSTEM_NAME); 21921c1c48aSSascha Wildner commands_free(cmds); 22021c1c48aSSascha Wildner a->result = 0; 22121c1c48aSSascha Wildner return; 22221c1c48aSSascha Wildner } 22321c1c48aSSascha Wildner commands_free(cmds); 22421c1c48aSSascha Wildner 22521c1c48aSSascha Wildner /* 22621c1c48aSSascha Wildner * Since one of the disks has now changed, we must 22721c1c48aSSascha Wildner * refresh our view of them and re-select the disk 22821c1c48aSSascha Wildner * since the selected_disk pointer will be invalidated. 22921c1c48aSSascha Wildner */ 23021c1c48aSSascha Wildner selected_disk_string = aura_strdup( 23121c1c48aSSascha Wildner disk_get_device_name(storage_get_selected_disk(a->s))); 23221c1c48aSSascha Wildner if (!survey_storage(a)) { 23321c1c48aSSascha Wildner inform(a->c, _("Errors occurred while probing " 23421c1c48aSSascha Wildner "the system for its storage capabilities.")); 23521c1c48aSSascha Wildner } 23621c1c48aSSascha Wildner storage_set_selected_disk(a->s, disk_find(a->s, selected_disk_string)); 23721c1c48aSSascha Wildner free(selected_disk_string); 23821c1c48aSSascha Wildner 23921c1c48aSSascha Wildner /* 24021c1c48aSSascha Wildner * Note that we formatted this disk and that we want 24121c1c48aSSascha Wildner * to use the first (and only) slice of it. 24221c1c48aSSascha Wildner */ 24321c1c48aSSascha Wildner disk_set_formatted(storage_get_selected_disk(a->s), 1); 24421c1c48aSSascha Wildner storage_set_selected_slice(a->s, disk_slice_first(storage_get_selected_disk(a->s))); 24521c1c48aSSascha Wildner 24621c1c48aSSascha Wildner if (!format_slice(a)) { 24721c1c48aSSascha Wildner inform(a->c, _("The sole primary partition of " 24821c1c48aSSascha Wildner "the disk\n\n%s\n\nwas " 24921c1c48aSSascha Wildner "not correctly formatted, and may " 25021c1c48aSSascha Wildner "now be in an inconsistent state. " 25121c1c48aSSascha Wildner "We recommend re-formatting the " 25221c1c48aSSascha Wildner "disk before attempting to install " 25321c1c48aSSascha Wildner "%s on it."), 25421c1c48aSSascha Wildner disk_get_desc(storage_get_selected_disk(a->s)), 25521c1c48aSSascha Wildner OPERATING_SYSTEM_NAME); 25621c1c48aSSascha Wildner a->result = 0; 25721c1c48aSSascha Wildner return; 25821c1c48aSSascha Wildner } 25921c1c48aSSascha Wildner 26021c1c48aSSascha Wildner inform(a->c, _("The disk\n\n%s\n\nwas formatted."), 26121c1c48aSSascha Wildner disk_get_desc(storage_get_selected_disk(a->s))); 26221c1c48aSSascha Wildner a->result = 1; 26321c1c48aSSascha Wildner } else { 26421c1c48aSSascha Wildner inform(a->c, _("Action cancelled - no disks were formatted.")); 26521c1c48aSSascha Wildner a->result = 0; 26621c1c48aSSascha Wildner } 26721c1c48aSSascha Wildner } 26821c1c48aSSascha Wildner 26921c1c48aSSascha Wildner /* 27021c1c48aSSascha Wildner * Wipes the start of the selected disk. 27121c1c48aSSascha Wildner */ 27221c1c48aSSascha Wildner void 27321c1c48aSSascha Wildner fn_wipe_start_of_disk(struct i_fn_args *a) 27421c1c48aSSascha Wildner { 27521c1c48aSSascha Wildner struct commands *cmds; 27621c1c48aSSascha Wildner 27721c1c48aSSascha Wildner a->short_desc = _("If you are having problems formatting a disk, " 27821c1c48aSSascha Wildner "it may be because of junk that has accumulated " 27921c1c48aSSascha Wildner "in the boot block and the partition table. " 28021c1c48aSSascha Wildner "A cure for this is to wipe out everything on " 28121c1c48aSSascha Wildner "the first few sectors of the disk. However, this " 28221c1c48aSSascha Wildner "is a rather drastic action to take, so it is not " 28321c1c48aSSascha Wildner "recommended unless you are otherwise " 28421c1c48aSSascha Wildner "encountering problems."); 28521c1c48aSSascha Wildner a->cancel_desc = _("Return to Utilities Menu"); 28621c1c48aSSascha Wildner fn_select_disk(a); 28721c1c48aSSascha Wildner if (!a->result) 28821c1c48aSSascha Wildner return; 28921c1c48aSSascha Wildner 29021c1c48aSSascha Wildner /* XXX check to make sure no slices on this disk are mounted first? */ 29121c1c48aSSascha Wildner if (storage_get_selected_disk(a->s) != NULL && confirm_dangerous_action(a->c, 29221c1c48aSSascha Wildner _("WARNING! ALL data in ALL partitions on the disk\n\n" 29321c1c48aSSascha Wildner "%s\n\nwill be IRREVOCABLY ERASED!\n\nAre you ABSOLUTELY " 29421c1c48aSSascha Wildner "SURE you wish to take this action? This is your " 29521c1c48aSSascha Wildner "LAST CHANCE to cancel!"), disk_get_desc(storage_get_selected_disk(a->s)))) { 29621c1c48aSSascha Wildner cmds = commands_new(); 29721c1c48aSSascha Wildner command_add(cmds, 29821c1c48aSSascha Wildner "%s%s if=%sdev/zero of=%sdev/%s bs=32k count=16", 29921c1c48aSSascha Wildner a->os_root, cmd_name(a, "DD"), 30021c1c48aSSascha Wildner a->os_root, a->os_root, 301f59b7dfaSSascha Wildner disk_get_device_name(storage_get_selected_disk(a->s))); 30221c1c48aSSascha Wildner if (commands_execute(a, cmds)) { 30321c1c48aSSascha Wildner inform(a->c, _("Start of disk was successfully wiped.")); 30421c1c48aSSascha Wildner } else { 30521c1c48aSSascha Wildner inform(a->c, _("Some errors occurred. " 30621c1c48aSSascha Wildner "Start of disk was not successfully wiped.")); 30721c1c48aSSascha Wildner } 30821c1c48aSSascha Wildner commands_free(cmds); 30921c1c48aSSascha Wildner } 31021c1c48aSSascha Wildner } 31121c1c48aSSascha Wildner 31221c1c48aSSascha Wildner /* 31321c1c48aSSascha Wildner * Wipes the start of the selected slice. 31421c1c48aSSascha Wildner */ 31521c1c48aSSascha Wildner void 31621c1c48aSSascha Wildner fn_wipe_start_of_slice(struct i_fn_args *a) 31721c1c48aSSascha Wildner { 31821c1c48aSSascha Wildner struct commands *cmds; 31921c1c48aSSascha Wildner 32021c1c48aSSascha Wildner a->short_desc = 32121c1c48aSSascha Wildner _("If you are having problems formatting a primary partition, " 32221c1c48aSSascha Wildner "it may be because of junk that has accumulated in the " 32321c1c48aSSascha Wildner "partition's `disklabel'. A cure for this is to wipe out " 32421c1c48aSSascha Wildner "everything on the first few sectors of the primary partition. " 32521c1c48aSSascha Wildner "However, this is a rather drastic action to take, so it is not " 32621c1c48aSSascha Wildner "recommended unless you are otherwise encountering problems."); 32721c1c48aSSascha Wildner a->cancel_desc = _("Return to Utilities Menu"); 32821c1c48aSSascha Wildner fn_select_slice(a); 32921c1c48aSSascha Wildner if (!a->result) 33021c1c48aSSascha Wildner return; 33121c1c48aSSascha Wildner 33221c1c48aSSascha Wildner if (confirm_dangerous_action(a->c, 33321c1c48aSSascha Wildner _("WARNING! ALL data in primary partition #%d,\n\n%s\n\non the " 33421c1c48aSSascha Wildner "disk\n\n%s\n\n will be IRREVOCABLY ERASED!\n\nAre you " 33521c1c48aSSascha Wildner "ABSOLUTELY SURE you wish to take this action? This is " 33621c1c48aSSascha Wildner "your LAST CHANCE to cancel!"), 33721c1c48aSSascha Wildner slice_get_number(storage_get_selected_slice(a->s)), 33821c1c48aSSascha Wildner slice_get_desc(storage_get_selected_slice(a->s)), 33921c1c48aSSascha Wildner disk_get_desc(storage_get_selected_disk(a->s)))) { 34021c1c48aSSascha Wildner /* XXX check to make sure this slice is not mounted first */ 34121c1c48aSSascha Wildner cmds = commands_new(); 34221c1c48aSSascha Wildner command_add(cmds, "%s%s if=%sdev/zero of=%sdev/%s bs=32k count=16", 34321c1c48aSSascha Wildner a->os_root, cmd_name(a, "DD"), 34421c1c48aSSascha Wildner a->os_root, a->os_root, 345f59b7dfaSSascha Wildner slice_get_device_name(storage_get_selected_slice(a->s))); 34621c1c48aSSascha Wildner if (commands_execute(a, cmds)) { 34721c1c48aSSascha Wildner inform(a->c, _("Start of primary partition was successfully wiped.")); 34821c1c48aSSascha Wildner } else { 34921c1c48aSSascha Wildner inform(a->c, _("Some errors occurred. " 35021c1c48aSSascha Wildner "Start of primary partition was not successfully wiped.")); 35121c1c48aSSascha Wildner } 35221c1c48aSSascha Wildner commands_free(cmds); 35321c1c48aSSascha Wildner } 35421c1c48aSSascha Wildner } 35521c1c48aSSascha Wildner 35621c1c48aSSascha Wildner static void 35721c1c48aSSascha Wildner ask_to_wipe_boot_sector(struct i_fn_args *a, struct commands *fcmds) 35821c1c48aSSascha Wildner { 35921c1c48aSSascha Wildner struct commands *cmds; 36021c1c48aSSascha Wildner struct command *cmd; 36121c1c48aSSascha Wildner char *disk; 36221c1c48aSSascha Wildner 36321c1c48aSSascha Wildner for (cmd = command_get_first(fcmds); cmd != NULL; 36421c1c48aSSascha Wildner cmd = command_get_next(cmd)) { 36521c1c48aSSascha Wildner disk = command_get_tag(cmd); 36621c1c48aSSascha Wildner if (disk != NULL && 36721c1c48aSSascha Wildner command_get_result(cmd) > 0 && 36821c1c48aSSascha Wildner command_get_result(cmd) < 256) { 36921c1c48aSSascha Wildner switch (dfui_be_present_dialog(a->c, 37021c1c48aSSascha Wildner _("Bootblock Install Failed"), 37121c1c48aSSascha Wildner _("Re-Initialize Bootblock|Cancel"), 37221c1c48aSSascha Wildner _("Warning: bootblocks were not successfully " 37321c1c48aSSascha Wildner "installed on the disk `%s'. This may be " 37421c1c48aSSascha Wildner "because the disk is new and not yet " 37521c1c48aSSascha Wildner "formatted. If this is the case, it might " 37621c1c48aSSascha Wildner "help to re-initialize the boot sector, " 37721c1c48aSSascha Wildner "then try installing the bootblock again. " 37821c1c48aSSascha Wildner "Note that this should not affect the " 37921c1c48aSSascha Wildner "partition table of the disk."), 38059b733d3SSascha Wildner disk)) { 38121c1c48aSSascha Wildner case 1: 38221c1c48aSSascha Wildner cmds = commands_new(); 38321c1c48aSSascha Wildner command_add(cmds, 38421c1c48aSSascha Wildner "%s%s | %s%s -B %sdev/%s", 38521c1c48aSSascha Wildner a->os_root, cmd_name(a, "YES"), 38621c1c48aSSascha Wildner a->os_root, cmd_name(a, "FDISK"), 38721c1c48aSSascha Wildner a->os_root, disk); 38821c1c48aSSascha Wildner if (commands_execute(a, cmds)) { 38921c1c48aSSascha Wildner inform(a->c, _("Boot sector successfully initialized.")); 39021c1c48aSSascha Wildner } else { 39121c1c48aSSascha Wildner inform(a->c, _("Some errors occurred. " 39221c1c48aSSascha Wildner "Boot sector was not successfully initialized.")); 39321c1c48aSSascha Wildner } 39421c1c48aSSascha Wildner commands_free(cmds); 39521c1c48aSSascha Wildner break; 39621c1c48aSSascha Wildner default: 39721c1c48aSSascha Wildner break; 39821c1c48aSSascha Wildner } 39921c1c48aSSascha Wildner } 40021c1c48aSSascha Wildner } 40121c1c48aSSascha Wildner } 40221c1c48aSSascha Wildner 40321c1c48aSSascha Wildner void 404e75c9034SSascha Wildner fn_install_bootblocks(struct i_fn_args *a, const char *device) 40521c1c48aSSascha Wildner { 40621c1c48aSSascha Wildner struct dfui_form *f; 40721c1c48aSSascha Wildner struct dfui_response *r; 40821c1c48aSSascha Wildner struct dfui_dataset *ds; 40921c1c48aSSascha Wildner struct disk *d; 41021c1c48aSSascha Wildner struct commands *cmds; 41121c1c48aSSascha Wildner struct command *cmd; 41221c1c48aSSascha Wildner char disk[64], boot0cfg[32], packet[32]; 41321c1c48aSSascha Wildner char msg_buf[1][1024]; 41421c1c48aSSascha Wildner 41521c1c48aSSascha Wildner snprintf(msg_buf[0], sizeof(msg_buf[0]), 41621c1c48aSSascha Wildner "'Packet Mode' refers to using newer BIOS calls to boot " 41721c1c48aSSascha Wildner "from a partition of the disk. It is generally not " 41821c1c48aSSascha Wildner "required unless:\n\n" 41921c1c48aSSascha Wildner "- your BIOS does not support legacy mode; or\n" 42021c1c48aSSascha Wildner "- your %s primary partition resides on a " 42121c1c48aSSascha Wildner "cylinder of the disk beyond cylinder 1024; or\n" 42221c1c48aSSascha Wildner "- you just can't get it to boot without it.", 42321c1c48aSSascha Wildner OPERATING_SYSTEM_NAME); 42421c1c48aSSascha Wildner 42521c1c48aSSascha Wildner f = dfui_form_create( 42621c1c48aSSascha Wildner "install_bootstrap", 42721c1c48aSSascha Wildner _("Install Bootblock(s)"), 42821c1c48aSSascha Wildner a->short_desc, 42921c1c48aSSascha Wildner 43021c1c48aSSascha Wildner msg_buf[0], 43121c1c48aSSascha Wildner 43221c1c48aSSascha Wildner "p", "special", "dfinstaller_install_bootstrap", 43321c1c48aSSascha Wildner 43421c1c48aSSascha Wildner "f", "disk", _("Disk Drive"), 43521c1c48aSSascha Wildner _("The disk on which you wish to install a bootblock"), "", 43621c1c48aSSascha Wildner "p", "editable", "false", 43721c1c48aSSascha Wildner "f", "boot0cfg", _("Install Bootblock?"), 43821c1c48aSSascha Wildner _("Install a bootblock on this disk"), "", 43921c1c48aSSascha Wildner "p", "control", "checkbox", 44021c1c48aSSascha Wildner "f", "packet", _("Packet Mode?"), 44121c1c48aSSascha Wildner _("Select this to use 'packet mode' to boot the disk"), "", 44221c1c48aSSascha Wildner "p", "control", "checkbox", 44321c1c48aSSascha Wildner 44421c1c48aSSascha Wildner "a", "ok", _("Accept and Install Bootblocks"), "", "", 44521c1c48aSSascha Wildner "a", "cancel", a->cancel_desc, "", "", 44621c1c48aSSascha Wildner "p", "accelerator", "ESC", 44721c1c48aSSascha Wildner 44821c1c48aSSascha Wildner NULL 44921c1c48aSSascha Wildner ); 45021c1c48aSSascha Wildner 45121c1c48aSSascha Wildner dfui_form_set_multiple(f, 1); 45221c1c48aSSascha Wildner 453e75c9034SSascha Wildner if (device != NULL) { 45421c1c48aSSascha Wildner ds = dfui_dataset_new(); 455e75c9034SSascha Wildner dfui_dataset_celldata_add(ds, "disk", device); 45621c1c48aSSascha Wildner dfui_dataset_celldata_add(ds, "boot0cfg", "Y"); 45721c1c48aSSascha Wildner dfui_dataset_celldata_add(ds, "packet", "Y"); 45821c1c48aSSascha Wildner dfui_form_dataset_add(f, ds); 459e75c9034SSascha Wildner } else { 460e75c9034SSascha Wildner for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) { 461e75c9034SSascha Wildner ds = dfui_dataset_new(); 462e75c9034SSascha Wildner dfui_dataset_celldata_add(ds, "disk", 463e75c9034SSascha Wildner disk_get_device_name(d)); 464e75c9034SSascha Wildner dfui_dataset_celldata_add(ds, "boot0cfg", "Y"); 465e75c9034SSascha Wildner dfui_dataset_celldata_add(ds, "packet", "Y"); 466e75c9034SSascha Wildner dfui_form_dataset_add(f, ds); 467e75c9034SSascha Wildner } 46821c1c48aSSascha Wildner } 46921c1c48aSSascha Wildner 47021c1c48aSSascha Wildner if (!dfui_be_present(a->c, f, &r)) 47121c1c48aSSascha Wildner abort_backend(); 47221c1c48aSSascha Wildner 47321c1c48aSSascha Wildner a->result = 0; 47421c1c48aSSascha Wildner if (strcmp(dfui_response_get_action_id(r), "ok") == 0) { 47521c1c48aSSascha Wildner cmds = commands_new(); 47621c1c48aSSascha Wildner 47721c1c48aSSascha Wildner for (ds = dfui_response_dataset_get_first(r); ds != NULL; 47821c1c48aSSascha Wildner ds = dfui_dataset_get_next(ds)) { 47921c1c48aSSascha Wildner strlcpy(disk, dfui_dataset_get_value(ds, "disk"), 64); 48021c1c48aSSascha Wildner strlcpy(boot0cfg, dfui_dataset_get_value(ds, "boot0cfg"), 32); 48121c1c48aSSascha Wildner strlcpy(packet, dfui_dataset_get_value(ds, "packet"), 32); 48221c1c48aSSascha Wildner 48321c1c48aSSascha Wildner if (strcasecmp(boot0cfg, "Y") == 0) { 48421c1c48aSSascha Wildner cmd = command_add(cmds, "%s%s -B -o %spacket %s", 48521c1c48aSSascha Wildner a->os_root, cmd_name(a, "BOOT0CFG"), 48621c1c48aSSascha Wildner strcasecmp(packet, "Y") == 0 ? "" : "no", 48721c1c48aSSascha Wildner disk); 48821c1c48aSSascha Wildner command_set_failure_mode(cmd, COMMAND_FAILURE_WARN); 48921c1c48aSSascha Wildner command_set_tag(cmd, disk); 49021c1c48aSSascha Wildner cmd = command_add(cmds, "%s%s -v %s", 49121c1c48aSSascha Wildner a->os_root, cmd_name(a, "BOOT0CFG"), 49221c1c48aSSascha Wildner disk); 49321c1c48aSSascha Wildner command_set_failure_mode(cmd, COMMAND_FAILURE_WARN); 49421c1c48aSSascha Wildner command_set_tag(cmd, disk); 49521c1c48aSSascha Wildner } 49621c1c48aSSascha Wildner } 49721c1c48aSSascha Wildner 49821c1c48aSSascha Wildner if (!commands_execute(a, cmds)) { 49921c1c48aSSascha Wildner ask_to_wipe_boot_sector(a, cmds); 50021c1c48aSSascha Wildner } else { 50121c1c48aSSascha Wildner inform(a->c, _("Bootblocks were successfully installed!")); 50221c1c48aSSascha Wildner a->result = 1; 50321c1c48aSSascha Wildner } 50421c1c48aSSascha Wildner commands_free(cmds); 50521c1c48aSSascha Wildner } 50621c1c48aSSascha Wildner 50721c1c48aSSascha Wildner dfui_form_free(f); 50821c1c48aSSascha Wildner dfui_response_free(r); 50921c1c48aSSascha Wildner } 51021c1c48aSSascha Wildner 51121c1c48aSSascha Wildner void 51221c1c48aSSascha Wildner fn_format_msdos_floppy(struct i_fn_args *a) 51321c1c48aSSascha Wildner { 51421c1c48aSSascha Wildner struct commands *cmds; 51521c1c48aSSascha Wildner 51621c1c48aSSascha Wildner switch (dfui_be_present_dialog(a->c, _("Format MSDOS Floppy"), 51721c1c48aSSascha Wildner _("Format Floppy|Return to Utilities Menu"), 51821c1c48aSSascha Wildner _("Please insert the floppy to be formatted " 51921c1c48aSSascha Wildner "in unit 0 (``drive A:'')."))) { 52021c1c48aSSascha Wildner case 1: 52121c1c48aSSascha Wildner cmds = commands_new(); 52221c1c48aSSascha Wildner command_add(cmds, "%s%s -y -f 1440 /dev/fd0", 52321c1c48aSSascha Wildner a->os_root, cmd_name(a, "FDFORMAT")); 52421c1c48aSSascha Wildner command_add(cmds, "%s%s -f 1440 fd0", 52521c1c48aSSascha Wildner a->os_root, cmd_name(a, "NEWFS_MSDOS")); 52621c1c48aSSascha Wildner if (commands_execute(a, cmds)) 52721c1c48aSSascha Wildner inform(a->c, _("Floppy successfully formatted!")); 52821c1c48aSSascha Wildner else 52921c1c48aSSascha Wildner inform(a->c, _("Floppy was not successfully formatted.")); 53021c1c48aSSascha Wildner break; 53121c1c48aSSascha Wildner case 2: 53221c1c48aSSascha Wildner return; 53321c1c48aSSascha Wildner default: 53421c1c48aSSascha Wildner abort_backend(); 53521c1c48aSSascha Wildner } 53621c1c48aSSascha Wildner } 53721c1c48aSSascha Wildner 53821c1c48aSSascha Wildner void 53921c1c48aSSascha Wildner fn_create_cdboot_floppy(struct i_fn_args *a) 54021c1c48aSSascha Wildner { 54121c1c48aSSascha Wildner struct commands *cmds; 54221c1c48aSSascha Wildner char msg_buf[1][1024]; 54321c1c48aSSascha Wildner 54421c1c48aSSascha Wildner snprintf(msg_buf[0], sizeof(msg_buf[0]), 54521c1c48aSSascha Wildner "%s cannot be installed from a floppy; " 54621c1c48aSSascha Wildner "it must be installed from a booted CD-ROM. " 54721c1c48aSSascha Wildner "However, many older systems do not support booting " 54821c1c48aSSascha Wildner "from a CD-ROM. For these systems, a boot disk can be " 54921c1c48aSSascha Wildner "created. This boot disk contains the Smart Boot " 55021c1c48aSSascha Wildner "Manager program, which can boot a CD-ROM even " 55121c1c48aSSascha Wildner "on systems with BIOSes which do not support booting " 55221c1c48aSSascha Wildner "from the CD-ROM.\n\n" 55321c1c48aSSascha Wildner "Smart Boot Manager is not a part of %s; " 55421c1c48aSSascha Wildner "the Smart Boot Manager project can be found here:\n\n" 55521c1c48aSSascha Wildner "http://btmgr.sourceforge.net/\n\n" 55621c1c48aSSascha Wildner "To create a CDBoot floppy, insert a blank floppy " 55721c1c48aSSascha Wildner "in unit 0 (``drive A:'') before proceeding." 55821c1c48aSSascha Wildner "", 55921c1c48aSSascha Wildner OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME); 56021c1c48aSSascha Wildner 56121c1c48aSSascha Wildner switch (dfui_be_present_dialog(a->c, _("Create CDBoot Floppy"), 56221c1c48aSSascha Wildner _("Create CDBoot Floppy|Return to Utilities Menu"), 56321c1c48aSSascha Wildner msg_buf[0])) { 56421c1c48aSSascha Wildner case 1: 56521c1c48aSSascha Wildner cmds = commands_new(); 56621c1c48aSSascha Wildner command_add(cmds, "%s%s -c %sboot/cdboot.flp.bz2 | " 56721c1c48aSSascha Wildner "%s%s of=%sdev/fd0 bs=32k", 56821c1c48aSSascha Wildner a->os_root, cmd_name(a, "BUNZIP2"), 56921c1c48aSSascha Wildner a->os_root, 57021c1c48aSSascha Wildner a->os_root, cmd_name(a, "DD"), 57121c1c48aSSascha Wildner a->os_root); 57221c1c48aSSascha Wildner if (commands_execute(a, cmds)) 57321c1c48aSSascha Wildner inform(a->c, _("CDBoot floppy successfully created!")); 57421c1c48aSSascha Wildner else 57521c1c48aSSascha Wildner inform(a->c, _("CDBoot floppy was not successfully created.")); 57621c1c48aSSascha Wildner break; 57721c1c48aSSascha Wildner case 2: 57821c1c48aSSascha Wildner return; 57921c1c48aSSascha Wildner default: 58021c1c48aSSascha Wildner abort_backend(); 58121c1c48aSSascha Wildner } 58221c1c48aSSascha Wildner } 58321c1c48aSSascha Wildner 58421c1c48aSSascha Wildner /**** NON-fn_ FUNCTIONS ***/ 58521c1c48aSSascha Wildner 58621c1c48aSSascha Wildner int 58721c1c48aSSascha Wildner format_slice(struct i_fn_args *a) 58821c1c48aSSascha Wildner { 58921c1c48aSSascha Wildner struct commands *cmds; 590*a096577dSSascha Wildner struct command *cmd; 59121c1c48aSSascha Wildner int result; 59221c1c48aSSascha Wildner int cyl, hd, sec; 59321c1c48aSSascha Wildner 59421c1c48aSSascha Wildner cmds = commands_new(); 59521c1c48aSSascha Wildner 59621c1c48aSSascha Wildner /* 59721c1c48aSSascha Wildner * The information in a->s NEEDS to be accurate here! 59821c1c48aSSascha Wildner * Presumably we just did a survey_storage() recently. 59921c1c48aSSascha Wildner * XXX should we do another one here anyway just to be paranoid? 60021c1c48aSSascha Wildner */ 60121c1c48aSSascha Wildner 60221c1c48aSSascha Wildner /* 60321c1c48aSSascha Wildner * Set the slice's sysid to 165. 60421c1c48aSSascha Wildner */ 60521c1c48aSSascha Wildner disk_get_geometry(storage_get_selected_disk(a->s), &cyl, &hd, &sec); 60621c1c48aSSascha Wildner command_add(cmds, "%s%s 'g c%d h%d s%d' >%snew.fdisk", 60721c1c48aSSascha Wildner a->os_root, cmd_name(a, "ECHO"), 60821c1c48aSSascha Wildner cyl, hd, sec, 60921c1c48aSSascha Wildner a->tmp); 61021c1c48aSSascha Wildner command_add(cmds, "%s%s 'p %d %d %lu %lu' >>%snew.fdisk", 61121c1c48aSSascha Wildner a->os_root, cmd_name(a, "ECHO"), 61221c1c48aSSascha Wildner slice_get_number(storage_get_selected_slice(a->s)), 61321c1c48aSSascha Wildner 165, 61421c1c48aSSascha Wildner slice_get_start(storage_get_selected_slice(a->s)), 61521c1c48aSSascha Wildner slice_get_size(storage_get_selected_slice(a->s)), 61621c1c48aSSascha Wildner a->tmp); 61721c1c48aSSascha Wildner if (slice_get_flags(storage_get_selected_slice(a->s)) & 0x80) { 61821c1c48aSSascha Wildner command_add(cmds, "%s%s 'a %d' >>%snew.fdisk", 61921c1c48aSSascha Wildner a->os_root, cmd_name(a, "ECHO"), 62021c1c48aSSascha Wildner slice_get_number(storage_get_selected_slice(a->s)), 62121c1c48aSSascha Wildner a->tmp); 62221c1c48aSSascha Wildner } 62321c1c48aSSascha Wildner 62421c1c48aSSascha Wildner command_add(cmds, "%s%s %snew.fdisk", 62521c1c48aSSascha Wildner a->os_root, cmd_name(a, "CAT"), a->tmp); 62621c1c48aSSascha Wildner temp_file_add(a, "new.fdisk"); 62721c1c48aSSascha Wildner 62821c1c48aSSascha Wildner /* 62921c1c48aSSascha Wildner * Execute the fdisk script. 63021c1c48aSSascha Wildner */ 631*a096577dSSascha Wildner cmd = command_add(cmds, "%s%s -v -f %snew.fdisk %s", 63221c1c48aSSascha Wildner a->os_root, cmd_name(a, "FDISK"), a->tmp, 633f59b7dfaSSascha Wildner disk_get_device_name(storage_get_selected_disk(a->s))); 634*a096577dSSascha Wildner if (slice_get_size(storage_get_selected_slice(a->s)) == 0xFFFFFFFFU) 635*a096577dSSascha Wildner command_set_failure_mode(cmd, COMMAND_FAILURE_IGNORE); 63621c1c48aSSascha Wildner 63721c1c48aSSascha Wildner /* 63821c1c48aSSascha Wildner * If there is an old 'virgin' disklabel hanging around 63921c1c48aSSascha Wildner * in the temp dir, get rid of it. This won't happen 64021c1c48aSSascha Wildner * from a real CD, but might happen with '-o' installs. 64121c1c48aSSascha Wildner */ 64221c1c48aSSascha Wildner command_add(cmds, "%s%s -f %sinstall.disklabel.%s", 64321c1c48aSSascha Wildner a->os_root, cmd_name(a, "RM"), 64421c1c48aSSascha Wildner a->tmp, 64521c1c48aSSascha Wildner slice_get_device_name(storage_get_selected_slice(a->s))); 64621c1c48aSSascha Wildner 64721c1c48aSSascha Wildner result = commands_execute(a, cmds); 64821c1c48aSSascha Wildner 64921c1c48aSSascha Wildner commands_free(cmds); 65021c1c48aSSascha Wildner 65121c1c48aSSascha Wildner return(result); 65221c1c48aSSascha Wildner } 653