xref: /dflybsd-src/usr.sbin/installer/dfuibe_installer/fn_disk.c (revision 8e693f3b9a243606ce03418ba2304cd3f0691aa3)
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 
40*8e693f3bSSascha Wildner #include <sys/diskmbr.h>
41*8e693f3bSSascha Wildner 
4221c1c48aSSascha Wildner #include <stdlib.h>
43a07abcb9SMatthew Dillon #include <unistd.h>
4421c1c48aSSascha Wildner #include <string.h>
4521c1c48aSSascha Wildner 
4621c1c48aSSascha Wildner #ifdef ENABLE_NLS
4721c1c48aSSascha Wildner #include <libintl.h>
4821c1c48aSSascha Wildner #define _(String) gettext (String)
4921c1c48aSSascha Wildner #else
5021c1c48aSSascha Wildner #define _(String) (String)
5121c1c48aSSascha Wildner #endif
5221c1c48aSSascha Wildner 
5321c1c48aSSascha Wildner #include "libaura/mem.h"
5421c1c48aSSascha Wildner #include "libaura/fspred.h"
5521c1c48aSSascha Wildner 
5621c1c48aSSascha Wildner #include "libdfui/dfui.h"
5721c1c48aSSascha Wildner #include "libdfui/system.h"
5821c1c48aSSascha Wildner 
5921c1c48aSSascha Wildner #include "libinstaller/commands.h"
6021c1c48aSSascha Wildner #include "libinstaller/diskutil.h"
6121c1c48aSSascha Wildner #include "libinstaller/functions.h"
6221c1c48aSSascha Wildner #include "libinstaller/uiutil.h"
6321c1c48aSSascha Wildner 
6421c1c48aSSascha Wildner #include "fn.h"
6521c1c48aSSascha Wildner #include "pathnames.h"
6621c1c48aSSascha Wildner 
6721c1c48aSSascha Wildner /*** DISK-RELATED FUNCTIONS ***/
6821c1c48aSSascha Wildner 
6921c1c48aSSascha Wildner /*
7021c1c48aSSascha Wildner  * Ask the user which physical disk they want.
7121c1c48aSSascha Wildner  * Changes ss->selected_disk if successful.
7221c1c48aSSascha Wildner  */
7321c1c48aSSascha Wildner void
fn_select_disk(struct i_fn_args * a)7421c1c48aSSascha Wildner fn_select_disk(struct i_fn_args *a)
7521c1c48aSSascha Wildner {
7621c1c48aSSascha Wildner 	struct dfui_form *f;
7721c1c48aSSascha Wildner 	struct dfui_action *k;
7821c1c48aSSascha Wildner 	struct dfui_response *r;
7921c1c48aSSascha Wildner 	struct disk *d;
8021c1c48aSSascha Wildner 
8121c1c48aSSascha Wildner 	f = dfui_form_create(
8221c1c48aSSascha Wildner 	    "select_disk",
8321c1c48aSSascha Wildner 	    _("Select Disk"),
8421c1c48aSSascha Wildner 	    a->short_desc,
8521c1c48aSSascha Wildner 	    "",
8621c1c48aSSascha Wildner 
8721c1c48aSSascha Wildner 	    "p", "role",  "menu",
8821c1c48aSSascha Wildner 	    "p", "special", "dfinstaller_select_disk",
8921c1c48aSSascha Wildner 
9021c1c48aSSascha Wildner 	    NULL
9121c1c48aSSascha Wildner 	);
9221c1c48aSSascha Wildner 
9321c1c48aSSascha Wildner 	for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) {
9421c1c48aSSascha Wildner 		dfui_form_action_add(f, disk_get_device_name(d),
9521c1c48aSSascha Wildner 		    dfui_info_new(disk_get_desc(d), "", ""));
9621c1c48aSSascha Wildner 	}
9721c1c48aSSascha Wildner 
9821c1c48aSSascha Wildner 	k = dfui_form_action_add(f, "cancel",
9921c1c48aSSascha Wildner 	    dfui_info_new(a->cancel_desc, "", ""));
10021c1c48aSSascha Wildner 	dfui_action_property_set(k, "accelerator", "ESC");
10121c1c48aSSascha Wildner 
10221c1c48aSSascha Wildner 	if (!dfui_be_present(a->c, f, &r))
10321c1c48aSSascha Wildner 		abort_backend();
10421c1c48aSSascha Wildner 
10521c1c48aSSascha Wildner 	if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
10621c1c48aSSascha Wildner 		a->result = 0;
10721c1c48aSSascha Wildner 	} else {
10821c1c48aSSascha Wildner 		d = disk_find(a->s, dfui_response_get_action_id(r));
10921c1c48aSSascha Wildner 		if (d == NULL) {
11021c1c48aSSascha Wildner 			inform(a->c, _("Internal error - response from frontend "
11121c1c48aSSascha Wildner 			    "should be a valid device name."));
11221c1c48aSSascha Wildner 			a->result = 0;
11321c1c48aSSascha Wildner 		} else {
11421c1c48aSSascha Wildner 			storage_set_selected_disk(a->s, d);
11521c1c48aSSascha Wildner 			a->result = 1;
11621c1c48aSSascha Wildner 		}
11721c1c48aSSascha Wildner 	}
11821c1c48aSSascha Wildner 
11921c1c48aSSascha Wildner 	dfui_form_free(f);
12021c1c48aSSascha Wildner 	dfui_response_free(r);
12121c1c48aSSascha Wildner }
12221c1c48aSSascha Wildner 
12321c1c48aSSascha Wildner /*
12421c1c48aSSascha Wildner  * Ask the user which slice on a the selected disk they want.
12521c1c48aSSascha Wildner  * Changes ss->selected_slice.
12621c1c48aSSascha Wildner  */
12721c1c48aSSascha Wildner void
fn_select_slice(struct i_fn_args * a)12821c1c48aSSascha Wildner fn_select_slice(struct i_fn_args *a)
12921c1c48aSSascha Wildner {
13021c1c48aSSascha Wildner 	struct dfui_form *f;
13121c1c48aSSascha Wildner 	struct dfui_action *k;
13221c1c48aSSascha Wildner 	struct dfui_response *r;
13321c1c48aSSascha Wildner 	struct slice *s;
13421c1c48aSSascha Wildner 	char string[16];
13521c1c48aSSascha Wildner 
13621c1c48aSSascha Wildner 	f = dfui_form_create(
13721c1c48aSSascha Wildner 	    "select_slice",
13821c1c48aSSascha Wildner 	    _("Select Primary Partition"),
13921c1c48aSSascha Wildner 	    a->short_desc,
14021c1c48aSSascha Wildner 	    "",
14121c1c48aSSascha Wildner 
14221c1c48aSSascha Wildner 	    "p", "role", "menu",
14321c1c48aSSascha Wildner 	    "p", "special", "dfinstaller_select_slice",
14421c1c48aSSascha Wildner 
14521c1c48aSSascha Wildner 	    NULL
14621c1c48aSSascha Wildner 	);
14721c1c48aSSascha Wildner 
14821c1c48aSSascha Wildner 	for (s = disk_slice_first(storage_get_selected_disk(a->s));
14921c1c48aSSascha Wildner 	     s != NULL; s = slice_next(s)) {
15021c1c48aSSascha Wildner 		snprintf(string, 16, "%d", slice_get_number(s));
15121c1c48aSSascha Wildner 		dfui_form_action_add(f, string,
15221c1c48aSSascha Wildner 		    dfui_info_new(slice_get_desc(s), "", ""));
15321c1c48aSSascha Wildner 	}
15421c1c48aSSascha Wildner 
15521c1c48aSSascha Wildner 	k = dfui_form_action_add(f, "cancel",
15621c1c48aSSascha Wildner 	    dfui_info_new(a->cancel_desc, "", ""));
15721c1c48aSSascha Wildner 	dfui_action_property_set(k, "accelerator", "ESC");
15821c1c48aSSascha Wildner 
15921c1c48aSSascha Wildner 	if (!dfui_be_present(a->c, f, &r))
16021c1c48aSSascha Wildner 		abort_backend();
16121c1c48aSSascha Wildner 
16221c1c48aSSascha Wildner 	if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
16321c1c48aSSascha Wildner 		a->result = 0;
16421c1c48aSSascha Wildner 	} else {
16521c1c48aSSascha Wildner 		s = slice_find(storage_get_selected_disk(a->s),
16621c1c48aSSascha Wildner 		    atoi(dfui_response_get_action_id(r)));
16721c1c48aSSascha Wildner 		if (s == NULL) {
16821c1c48aSSascha Wildner 			inform(a->c, _("Internal error - response from frontend "
16921c1c48aSSascha Wildner 			    "should be a valid slice number."));
17021c1c48aSSascha Wildner 			a->result = 0;
17121c1c48aSSascha Wildner 		} else {
17221c1c48aSSascha Wildner 			storage_set_selected_slice(a->s, s);
17321c1c48aSSascha Wildner 			a->result = 1;
17421c1c48aSSascha Wildner 		}
17521c1c48aSSascha Wildner 	}
17621c1c48aSSascha Wildner 
17721c1c48aSSascha Wildner 	dfui_form_free(f);
17821c1c48aSSascha Wildner 	dfui_response_free(r);
17921c1c48aSSascha Wildner }
18021c1c48aSSascha Wildner 
18121c1c48aSSascha Wildner /*
18221c1c48aSSascha Wildner  * If ss->selected_disk == NULL, user will be asked for which disk.
18321c1c48aSSascha Wildner  * Returns 1 if disk was formatted, 0 if it wasn't.
18421c1c48aSSascha Wildner  * If it was, ss->selected_disk and ss->selected_slice are set to it.
18521c1c48aSSascha Wildner  */
18621c1c48aSSascha Wildner void
fn_format_disk_mbr(struct i_fn_args * a)1877b1aa074SSascha Wildner fn_format_disk_mbr(struct i_fn_args *a)
18821c1c48aSSascha Wildner {
18921c1c48aSSascha Wildner 	struct commands *cmds;
19021c1c48aSSascha Wildner 	char *selected_disk_string;
19121c1c48aSSascha Wildner 
19221c1c48aSSascha Wildner 	if (storage_get_selected_disk(a->s) == NULL) {
19321c1c48aSSascha Wildner 		a->short_desc = _("Select a disk to format.");
19421c1c48aSSascha Wildner 		a->cancel_desc = _("Return to Utilities Menu");
19521c1c48aSSascha Wildner 		fn_select_disk(a);
19621c1c48aSSascha Wildner 		if (!a->result || storage_get_selected_disk(a->s) == NULL) {
19721c1c48aSSascha Wildner 			a->result = 0;
19821c1c48aSSascha Wildner 			return;
19921c1c48aSSascha Wildner 		}
20021c1c48aSSascha Wildner 	}
20121c1c48aSSascha Wildner 
20221c1c48aSSascha Wildner 	if (confirm_dangerous_action(a->c,
20321c1c48aSSascha Wildner 	    _("WARNING!  ALL data in ALL partitions on the disk\n\n"
20421c1c48aSSascha Wildner 	    "%s\n\nwill be IRREVOCABLY ERASED!\n\nAre you ABSOLUTELY "
20521c1c48aSSascha Wildner 	    "SURE you wish to take this action?  This is your "
20621c1c48aSSascha Wildner 	    "LAST CHANCE to cancel!"), disk_get_desc(storage_get_selected_disk(a->s)))) {
20721c1c48aSSascha Wildner 		cmds = commands_new();
20821c1c48aSSascha Wildner 
2098afa51ffSSascha Wildner 		command_add(cmds,
2108afa51ffSSascha Wildner 		    "%s%s if=/dev/zero of=/dev/%s bs=32k count=16",
2118afa51ffSSascha Wildner 		    a->os_root, cmd_name(a, "DD"),
2128afa51ffSSascha Wildner 		    disk_get_device_name(storage_get_selected_disk(a->s)));
21321c1c48aSSascha Wildner 		command_add(cmds, "%s%s -BI %s",
21421c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "FDISK"),
215f59b7dfaSSascha Wildner 		    disk_get_device_name(storage_get_selected_disk(a->s)));
21621c1c48aSSascha Wildner 
21721c1c48aSSascha Wildner 		if (!commands_execute(a, cmds)) {
21821c1c48aSSascha Wildner 			inform(a->c, _("The disk\n\n%s\n\nwas "
21921c1c48aSSascha Wildner 			    "not correctly formatted, and may "
22021c1c48aSSascha Wildner 			    "now be in an inconsistent state. "
22121c1c48aSSascha Wildner 			    "We recommend re-formatting it "
22221c1c48aSSascha Wildner 			    "before attempting to install "
22321c1c48aSSascha Wildner 			    "%s on it."),
22421c1c48aSSascha Wildner 			    disk_get_desc(storage_get_selected_disk(a->s)),
22521c1c48aSSascha Wildner 			    OPERATING_SYSTEM_NAME);
22621c1c48aSSascha Wildner 			commands_free(cmds);
22721c1c48aSSascha Wildner 			a->result = 0;
22821c1c48aSSascha Wildner 			return;
22921c1c48aSSascha Wildner 		}
23021c1c48aSSascha Wildner 		commands_free(cmds);
23121c1c48aSSascha Wildner 
23221c1c48aSSascha Wildner 		/*
23321c1c48aSSascha Wildner 		 * Since one of the disks has now changed, we must
23421c1c48aSSascha Wildner 		 * refresh our view of them and re-select the disk
23521c1c48aSSascha Wildner 		 * since the selected_disk pointer will be invalidated.
23621c1c48aSSascha Wildner 		 */
23721c1c48aSSascha Wildner 		selected_disk_string = aura_strdup(
23821c1c48aSSascha Wildner 		    disk_get_device_name(storage_get_selected_disk(a->s)));
23921c1c48aSSascha Wildner 		if (!survey_storage(a)) {
24021c1c48aSSascha Wildner 			inform(a->c, _("Errors occurred while probing "
24121c1c48aSSascha Wildner 			    "the system for its storage capabilities."));
24221c1c48aSSascha Wildner 		}
24321c1c48aSSascha Wildner 		storage_set_selected_disk(a->s, disk_find(a->s, selected_disk_string));
24421c1c48aSSascha Wildner 		free(selected_disk_string);
24521c1c48aSSascha Wildner 
24621c1c48aSSascha Wildner 		/*
24721c1c48aSSascha Wildner 		 * Note that we formatted this disk and that we want
24821c1c48aSSascha Wildner 		 * to use the first (and only) slice of it.
24921c1c48aSSascha Wildner 		 */
25021c1c48aSSascha Wildner 		disk_set_formatted(storage_get_selected_disk(a->s), 1);
25121c1c48aSSascha Wildner 		storage_set_selected_slice(a->s, disk_slice_first(storage_get_selected_disk(a->s)));
25221c1c48aSSascha Wildner 
25321c1c48aSSascha Wildner 		if (!format_slice(a)) {
25421c1c48aSSascha Wildner 			inform(a->c, _("The sole primary partition of "
25521c1c48aSSascha Wildner 			    "the disk\n\n%s\n\nwas "
25621c1c48aSSascha Wildner 			    "not correctly formatted, and may "
25721c1c48aSSascha Wildner 			    "now be in an inconsistent state. "
25821c1c48aSSascha Wildner 			    "We recommend re-formatting the "
25921c1c48aSSascha Wildner 			    "disk before attempting to install "
26021c1c48aSSascha Wildner 			    "%s on it."),
26121c1c48aSSascha Wildner 			    disk_get_desc(storage_get_selected_disk(a->s)),
26221c1c48aSSascha Wildner 			    OPERATING_SYSTEM_NAME);
26321c1c48aSSascha Wildner 			a->result = 0;
26421c1c48aSSascha Wildner 			return;
26521c1c48aSSascha Wildner 		}
26621c1c48aSSascha Wildner 		inform(a->c, _("The disk\n\n%s\n\nwas formatted."),
26721c1c48aSSascha Wildner 		    disk_get_desc(storage_get_selected_disk(a->s)));
26821c1c48aSSascha Wildner 		a->result = 1;
26921c1c48aSSascha Wildner 	} else {
27021c1c48aSSascha Wildner 		inform(a->c, _("Action cancelled - no disks were formatted."));
27121c1c48aSSascha Wildner 		a->result = 0;
27221c1c48aSSascha Wildner 	}
27321c1c48aSSascha Wildner }
27421c1c48aSSascha Wildner 
2757b1aa074SSascha Wildner void
fn_format_disk_uefi(struct i_fn_args * a)2767b1aa074SSascha Wildner fn_format_disk_uefi(struct i_fn_args *a)
2777b1aa074SSascha Wildner {
2787b1aa074SSascha Wildner 	struct commands *cmds;
2797b1aa074SSascha Wildner 	char *selected_disk_string;
2807b1aa074SSascha Wildner 
2817b1aa074SSascha Wildner 	if (storage_get_selected_disk(a->s) == NULL) {
2827b1aa074SSascha Wildner 		a->short_desc = _("Select a disk to format.");
2837b1aa074SSascha Wildner 		a->cancel_desc = _("Return to Utilities Menu");
2847b1aa074SSascha Wildner 		fn_select_disk(a);
2857b1aa074SSascha Wildner 		if (!a->result || storage_get_selected_disk(a->s) == NULL) {
2867b1aa074SSascha Wildner 			a->result = 0;
2877b1aa074SSascha Wildner 			return;
2887b1aa074SSascha Wildner 		}
2897b1aa074SSascha Wildner 	}
2907b1aa074SSascha Wildner 
2917b1aa074SSascha Wildner 	if (confirm_dangerous_action(a->c,
2927b1aa074SSascha Wildner 	    _("WARNING!  ALL data in ALL partitions on the disk\n\n"
2937b1aa074SSascha Wildner 	    "%s\n\nwill be IRREVOCABLY ERASED!\n\nAre you ABSOLUTELY "
2947b1aa074SSascha Wildner 	    "SURE you wish to take this action?  This is your "
2957b1aa074SSascha Wildner 	    "LAST CHANCE to cancel!"), disk_get_desc(storage_get_selected_disk(a->s)))) {
2967b1aa074SSascha Wildner 		cmds = commands_new();
2977b1aa074SSascha Wildner 
2987b1aa074SSascha Wildner 		command_add(cmds,
2997b1aa074SSascha Wildner 		    "%s%s if=/dev/zero of=/dev/%s bs=32k count=16",
3007b1aa074SSascha Wildner 		    a->os_root, cmd_name(a, "DD"),
3017b1aa074SSascha Wildner 		    disk_get_device_name(storage_get_selected_disk(a->s)));
3027b1aa074SSascha Wildner 		command_add(cmds, "%s%s destroy %s",
3037b1aa074SSascha Wildner 		    a->os_root, cmd_name(a, "GPT"),
3047b1aa074SSascha Wildner 		    disk_get_device_name(storage_get_selected_disk(a->s)));
3057b1aa074SSascha Wildner 		command_add(cmds, "%s%s create -f %s",
3067b1aa074SSascha Wildner 		    a->os_root, cmd_name(a, "GPT"),
3077b1aa074SSascha Wildner 		    disk_get_device_name(storage_get_selected_disk(a->s)));
3087b1aa074SSascha Wildner 		command_add(cmds, "%s%s add -i 0 -s 262144 -t efi %s",
3097b1aa074SSascha Wildner 		    a->os_root, cmd_name(a, "GPT"),
3107b1aa074SSascha Wildner 		    disk_get_device_name(storage_get_selected_disk(a->s)));
3117b1aa074SSascha Wildner 		command_add(cmds, "%s%s add -i 1 -t dragonfly %s",
3127b1aa074SSascha Wildner 		    a->os_root, cmd_name(a, "GPT"),
3137b1aa074SSascha Wildner 		    disk_get_device_name(storage_get_selected_disk(a->s)));
3147b1aa074SSascha Wildner 		command_add(cmds, "%s%s -F 32 -c 2 -L EFI -m 0xf8 %ss0",
3157b1aa074SSascha Wildner 		    a->os_root, cmd_name(a, "NEWFS_MSDOS"),
3167b1aa074SSascha Wildner 		    disk_get_device_name(storage_get_selected_disk(a->s)));
3177b1aa074SSascha Wildner 		command_add(cmds, "%s%s /dev/%ss0 %smnt",
3187b1aa074SSascha Wildner 		    a->os_root, cmd_name(a, "MOUNT_MSDOS"),
3197b1aa074SSascha Wildner 		    disk_get_device_name(storage_get_selected_disk(a->s)),
3207b1aa074SSascha Wildner 		    a->os_root);
3217b1aa074SSascha Wildner 		command_add(cmds, "%s%s -p %smnt/EFI/BOOT",
3227b1aa074SSascha Wildner 		    a->os_root, cmd_name(a, "MKDIR"), a->os_root);
3237b1aa074SSascha Wildner 		command_add(cmds,
3247b1aa074SSascha Wildner 		    "%s%s %s/boot/boot1.efi %smnt/EFI/BOOT/BOOTX64.EFI",
3257b1aa074SSascha Wildner 		    a->os_root, cmd_name(a, "CP"),
3267b1aa074SSascha Wildner 		    a->os_root, a->os_root);
3277b1aa074SSascha Wildner 		command_add(cmds, "%s%s %smnt",
3287b1aa074SSascha Wildner 		    a->os_root, cmd_name(a, "UMOUNT"), a->os_root);
3297b1aa074SSascha Wildner 
3307b1aa074SSascha Wildner 		if (!commands_execute(a, cmds)) {
3317b1aa074SSascha Wildner 			inform(a->c, _("The disk\n\n%s\n\nwas "
3327b1aa074SSascha Wildner 			    "not correctly formatted, and may "
3337b1aa074SSascha Wildner 			    "now be in an inconsistent state. "
3347b1aa074SSascha Wildner 			    "We recommend re-formatting it "
3357b1aa074SSascha Wildner 			    "before attempting to install "
3367b1aa074SSascha Wildner 			    "%s on it."),
3377b1aa074SSascha Wildner 			    disk_get_desc(storage_get_selected_disk(a->s)),
3387b1aa074SSascha Wildner 			    OPERATING_SYSTEM_NAME);
3397b1aa074SSascha Wildner 			commands_free(cmds);
3407b1aa074SSascha Wildner 			a->result = 0;
3417b1aa074SSascha Wildner 			return;
3427b1aa074SSascha Wildner 		}
3437b1aa074SSascha Wildner 		commands_free(cmds);
3447b1aa074SSascha Wildner 
3457b1aa074SSascha Wildner 		/*
3467b1aa074SSascha Wildner 		 * Since one of the disks has now changed, we must
3477b1aa074SSascha Wildner 		 * refresh our view of them and re-select the disk
3487b1aa074SSascha Wildner 		 * since the selected_disk pointer will be invalidated.
3497b1aa074SSascha Wildner 		 */
3507b1aa074SSascha Wildner 		selected_disk_string = aura_strdup(
3517b1aa074SSascha Wildner 		    disk_get_device_name(storage_get_selected_disk(a->s)));
3527b1aa074SSascha Wildner 		if (!survey_storage(a)) {
3537b1aa074SSascha Wildner 			inform(a->c, _("Errors occurred while probing "
3547b1aa074SSascha Wildner 			    "the system for its storage capabilities."));
3557b1aa074SSascha Wildner 		}
3567b1aa074SSascha Wildner 		storage_set_selected_disk(a->s,
3577b1aa074SSascha Wildner 		    disk_find(a->s, selected_disk_string));
3587b1aa074SSascha Wildner 		free(selected_disk_string);
3597b1aa074SSascha Wildner 
3607b1aa074SSascha Wildner 		/*
3617b1aa074SSascha Wildner 		 * Note that we formatted this disk and that we want
3627b1aa074SSascha Wildner 		 * to use the first (and only) slice of it.
3637b1aa074SSascha Wildner 		 */
3647b1aa074SSascha Wildner 		disk_set_formatted(storage_get_selected_disk(a->s), 1);
3657b1aa074SSascha Wildner 		storage_set_selected_slice(a->s,
3667b1aa074SSascha Wildner 		    disk_slice_first(storage_get_selected_disk(a->s)));
3677b1aa074SSascha Wildner 
3687b1aa074SSascha Wildner 		inform(a->c, _("The disk\n\n%s\n\nwas formatted."),
3697b1aa074SSascha Wildner 		    disk_get_desc(storage_get_selected_disk(a->s)));
3707b1aa074SSascha Wildner 		a->result = 1;
3717b1aa074SSascha Wildner 	} else {
3727b1aa074SSascha Wildner 		inform(a->c, _("Action cancelled - no disks were formatted."));
3737b1aa074SSascha Wildner 		a->result = 0;
3747b1aa074SSascha Wildner 	}
3757b1aa074SSascha Wildner }
3767b1aa074SSascha Wildner 
37721c1c48aSSascha Wildner /*
37821c1c48aSSascha Wildner  * Wipes the start of the selected disk.
37921c1c48aSSascha Wildner  */
38021c1c48aSSascha Wildner void
fn_wipe_start_of_disk(struct i_fn_args * a)38121c1c48aSSascha Wildner fn_wipe_start_of_disk(struct i_fn_args *a)
38221c1c48aSSascha Wildner {
38321c1c48aSSascha Wildner 	struct commands *cmds;
38421c1c48aSSascha Wildner 
38521c1c48aSSascha Wildner 	a->short_desc = _("If you are having problems formatting a disk, "
38621c1c48aSSascha Wildner 	    "it may be because of junk that has accumulated "
38721c1c48aSSascha Wildner 	    "in the boot block and the partition table. "
38821c1c48aSSascha Wildner 	    "A cure for this is to wipe out everything on "
38921c1c48aSSascha Wildner 	    "the first few sectors of the disk.  However, this "
39021c1c48aSSascha Wildner 	    "is a rather drastic action to take, so it is not "
39121c1c48aSSascha Wildner 	    "recommended unless you are otherwise "
39221c1c48aSSascha Wildner 	    "encountering problems.");
39321c1c48aSSascha Wildner 	a->cancel_desc = _("Return to Utilities Menu");
39421c1c48aSSascha Wildner 	fn_select_disk(a);
39521c1c48aSSascha Wildner 	if (!a->result)
39621c1c48aSSascha Wildner 		return;
39721c1c48aSSascha Wildner 
39821c1c48aSSascha Wildner 	/* XXX check to make sure no slices on this disk are mounted first? */
39921c1c48aSSascha Wildner 	if (storage_get_selected_disk(a->s) != NULL && confirm_dangerous_action(a->c,
40021c1c48aSSascha Wildner 	    _("WARNING!  ALL data in ALL partitions on the disk\n\n"
40121c1c48aSSascha Wildner 	    "%s\n\nwill be IRREVOCABLY ERASED!\n\nAre you ABSOLUTELY "
40221c1c48aSSascha Wildner 	    "SURE you wish to take this action?  This is your "
40321c1c48aSSascha Wildner 	    "LAST CHANCE to cancel!"), disk_get_desc(storage_get_selected_disk(a->s)))) {
40421c1c48aSSascha Wildner 		cmds = commands_new();
40521c1c48aSSascha Wildner 		command_add(cmds,
40651871435SSascha Wildner 		    "%s%s if=/dev/zero of=/dev/%s bs=32k count=16",
40721c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "DD"),
408f59b7dfaSSascha Wildner 		    disk_get_device_name(storage_get_selected_disk(a->s)));
40921c1c48aSSascha Wildner 		if (commands_execute(a, cmds)) {
41021c1c48aSSascha Wildner 			inform(a->c, _("Start of disk was successfully wiped."));
41121c1c48aSSascha Wildner 		} else {
41221c1c48aSSascha Wildner 			inform(a->c, _("Some errors occurred. "
41321c1c48aSSascha Wildner 			    "Start of disk was not successfully wiped."));
41421c1c48aSSascha Wildner 		}
41521c1c48aSSascha Wildner 		commands_free(cmds);
41621c1c48aSSascha Wildner 	}
41721c1c48aSSascha Wildner }
41821c1c48aSSascha Wildner 
41921c1c48aSSascha Wildner /*
42021c1c48aSSascha Wildner  * Wipes the start of the selected slice.
42121c1c48aSSascha Wildner  */
42221c1c48aSSascha Wildner void
fn_wipe_start_of_slice(struct i_fn_args * a)42321c1c48aSSascha Wildner fn_wipe_start_of_slice(struct i_fn_args *a)
42421c1c48aSSascha Wildner {
42521c1c48aSSascha Wildner 	struct commands *cmds;
42621c1c48aSSascha Wildner 
42721c1c48aSSascha Wildner 	a->short_desc =
42821c1c48aSSascha Wildner 	  _("If you are having problems formatting a primary partition, "
42921c1c48aSSascha Wildner 	    "it may be because of junk that has accumulated in the "
43021c1c48aSSascha Wildner 	    "partition's `disklabel'. A cure for this is to wipe out "
43121c1c48aSSascha Wildner 	    "everything on the first few sectors of the primary partition. "
43221c1c48aSSascha Wildner 	    "However, this is a rather drastic action to take, so it is not "
43321c1c48aSSascha Wildner 	    "recommended unless you are otherwise encountering problems.");
43421c1c48aSSascha Wildner 	a->cancel_desc = _("Return to Utilities Menu");
43521c1c48aSSascha Wildner 	fn_select_slice(a);
43621c1c48aSSascha Wildner 	if (!a->result)
43721c1c48aSSascha Wildner 		return;
43821c1c48aSSascha Wildner 
43921c1c48aSSascha Wildner 	if (confirm_dangerous_action(a->c,
44021c1c48aSSascha Wildner 	    _("WARNING!  ALL data in primary partition #%d,\n\n%s\n\non the "
44121c1c48aSSascha Wildner 	    "disk\n\n%s\n\n will be IRREVOCABLY ERASED!\n\nAre you "
44221c1c48aSSascha Wildner 	    "ABSOLUTELY SURE you wish to take this action?  This is "
44321c1c48aSSascha Wildner 	    "your LAST CHANCE to cancel!"),
44421c1c48aSSascha Wildner 	    slice_get_number(storage_get_selected_slice(a->s)),
44521c1c48aSSascha Wildner 	    slice_get_desc(storage_get_selected_slice(a->s)),
44621c1c48aSSascha Wildner 	    disk_get_desc(storage_get_selected_disk(a->s)))) {
44721c1c48aSSascha Wildner 		/* XXX check to make sure this slice is not mounted first */
44821c1c48aSSascha Wildner 		cmds = commands_new();
44951871435SSascha Wildner 		command_add(cmds, "%s%s if=/dev/zero of=/dev/%s bs=32k count=16",
45021c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "DD"),
451f59b7dfaSSascha Wildner 		    slice_get_device_name(storage_get_selected_slice(a->s)));
45221c1c48aSSascha Wildner 		if (commands_execute(a, cmds)) {
45321c1c48aSSascha Wildner 			inform(a->c, _("Start of primary partition was successfully wiped."));
45421c1c48aSSascha Wildner 		} else {
45521c1c48aSSascha Wildner 			inform(a->c, _("Some errors occurred. "
45621c1c48aSSascha Wildner 			    "Start of primary partition was not successfully wiped."));
45721c1c48aSSascha Wildner 		}
45821c1c48aSSascha Wildner 		commands_free(cmds);
45921c1c48aSSascha Wildner 	}
46021c1c48aSSascha Wildner }
46121c1c48aSSascha Wildner 
46221c1c48aSSascha Wildner static void
ask_to_wipe_boot_sector(struct i_fn_args * a,struct commands * fcmds)46321c1c48aSSascha Wildner ask_to_wipe_boot_sector(struct i_fn_args *a, struct commands *fcmds)
46421c1c48aSSascha Wildner {
46521c1c48aSSascha Wildner 	struct commands *cmds;
46621c1c48aSSascha Wildner 	struct command *cmd;
46721c1c48aSSascha Wildner 	char *disk;
46821c1c48aSSascha Wildner 
46921c1c48aSSascha Wildner 	for (cmd = command_get_first(fcmds); cmd != NULL;
47021c1c48aSSascha Wildner 	     cmd = command_get_next(cmd)) {
47121c1c48aSSascha Wildner 		disk = command_get_tag(cmd);
47221c1c48aSSascha Wildner 		if (disk != NULL &&
47321c1c48aSSascha Wildner 		    command_get_result(cmd) > 0 &&
47421c1c48aSSascha Wildner 		    command_get_result(cmd) < 256) {
47521c1c48aSSascha Wildner 			switch (dfui_be_present_dialog(a->c,
47621c1c48aSSascha Wildner 			    _("Bootblock Install Failed"),
47721c1c48aSSascha Wildner 			    _("Re-Initialize Bootblock|Cancel"),
47821c1c48aSSascha Wildner 			    _("Warning: bootblocks were not successfully "
47921c1c48aSSascha Wildner 			    "installed on the disk `%s'. This may be "
48021c1c48aSSascha Wildner 			    "because the disk is new and not yet "
48121c1c48aSSascha Wildner 			    "formatted. If this is the case, it might "
48221c1c48aSSascha Wildner 			    "help to re-initialize the boot sector, "
48321c1c48aSSascha Wildner 			    "then try installing the bootblock again. "
48421c1c48aSSascha Wildner 			    "Note that this should not affect the "
48521c1c48aSSascha Wildner 			    "partition table of the disk."),
48659b733d3SSascha Wildner 			    disk)) {
48721c1c48aSSascha Wildner 			case 1:
48821c1c48aSSascha Wildner 				cmds = commands_new();
48921c1c48aSSascha Wildner 				command_add(cmds,
49051871435SSascha Wildner 				    "%s%s | %s%s -B /dev/%s",
49121c1c48aSSascha Wildner 				    a->os_root, cmd_name(a, "YES"),
49221c1c48aSSascha Wildner 				    a->os_root, cmd_name(a, "FDISK"),
49351871435SSascha Wildner 				    disk);
49421c1c48aSSascha Wildner 				if (commands_execute(a, cmds)) {
49521c1c48aSSascha Wildner 					inform(a->c, _("Boot sector successfully initialized."));
49621c1c48aSSascha Wildner 				} else {
49721c1c48aSSascha Wildner 					inform(a->c, _("Some errors occurred. "
49821c1c48aSSascha Wildner 					    "Boot sector was not successfully initialized."));
49921c1c48aSSascha Wildner 				}
50021c1c48aSSascha Wildner 				commands_free(cmds);
50121c1c48aSSascha Wildner 				break;
50221c1c48aSSascha Wildner 			default:
50321c1c48aSSascha Wildner 				break;
50421c1c48aSSascha Wildner 			}
50521c1c48aSSascha Wildner 		}
50621c1c48aSSascha Wildner 	}
50721c1c48aSSascha Wildner }
50821c1c48aSSascha Wildner 
50921c1c48aSSascha Wildner void
fn_install_bootblocks(struct i_fn_args * a,const char * device)510e75c9034SSascha Wildner fn_install_bootblocks(struct i_fn_args *a, const char *device)
51121c1c48aSSascha Wildner {
51221c1c48aSSascha Wildner 	struct dfui_form *f;
51321c1c48aSSascha Wildner 	struct dfui_response *r;
51421c1c48aSSascha Wildner 	struct dfui_dataset *ds;
51521c1c48aSSascha Wildner 	struct disk *d;
51621c1c48aSSascha Wildner 	struct commands *cmds;
51721c1c48aSSascha Wildner 	struct command *cmd;
51821c1c48aSSascha Wildner 	char disk[64], boot0cfg[32], packet[32];
51921c1c48aSSascha Wildner 	char msg_buf[1][1024];
52021c1c48aSSascha Wildner 
52121c1c48aSSascha Wildner 	snprintf(msg_buf[0], sizeof(msg_buf[0]),
52221c1c48aSSascha Wildner 	    "'Packet Mode' refers to using newer BIOS calls to boot "
52321c1c48aSSascha Wildner 	    "from a partition of the disk.  It is generally not "
52421c1c48aSSascha Wildner 	    "required unless:\n\n"
52521c1c48aSSascha Wildner 	    "- your BIOS does not support legacy mode; or\n"
52621c1c48aSSascha Wildner 	    "- your %s primary partition resides on a "
52721c1c48aSSascha Wildner 	    "cylinder of the disk beyond cylinder 1024; or\n"
52821c1c48aSSascha Wildner 	    "- you just can't get it to boot without it.",
52921c1c48aSSascha Wildner 	    OPERATING_SYSTEM_NAME);
53021c1c48aSSascha Wildner 
53121c1c48aSSascha Wildner 	f = dfui_form_create(
53221c1c48aSSascha Wildner 	    "install_bootstrap",
53321c1c48aSSascha Wildner 	    _("Install Bootblock(s)"),
53421c1c48aSSascha Wildner 	    a->short_desc,
53521c1c48aSSascha Wildner 
53621c1c48aSSascha Wildner 	    msg_buf[0],
53721c1c48aSSascha Wildner 
53821c1c48aSSascha Wildner 	    "p", "special", "dfinstaller_install_bootstrap",
53921c1c48aSSascha Wildner 
54021c1c48aSSascha Wildner 	    "f", "disk", _("Disk Drive"),
54121c1c48aSSascha Wildner 	    _("The disk on which you wish to install a bootblock"), "",
54221c1c48aSSascha Wildner 	    "p", "editable", "false",
54321c1c48aSSascha Wildner 	    "f", "boot0cfg", _("Install Bootblock?"),
54421c1c48aSSascha Wildner 	    _("Install a bootblock on this disk"), "",
54521c1c48aSSascha Wildner 	    "p", "control", "checkbox",
54621c1c48aSSascha Wildner 	    "f", "packet", _("Packet Mode?"),
54721c1c48aSSascha Wildner 	    _("Select this to use 'packet mode' to boot the disk"), "",
54821c1c48aSSascha Wildner 	    "p", "control", "checkbox",
54921c1c48aSSascha Wildner 
55021c1c48aSSascha Wildner 	    "a", "ok", _("Accept and Install Bootblocks"), "", "",
55121c1c48aSSascha Wildner 	    "a", "cancel", a->cancel_desc, "", "",
55221c1c48aSSascha Wildner 	    "p", "accelerator", "ESC",
55321c1c48aSSascha Wildner 
55421c1c48aSSascha Wildner 	    NULL
55521c1c48aSSascha Wildner 	);
55621c1c48aSSascha Wildner 
55721c1c48aSSascha Wildner 	dfui_form_set_multiple(f, 1);
55821c1c48aSSascha Wildner 
559e75c9034SSascha Wildner 	if (device != NULL) {
56021c1c48aSSascha Wildner 		ds = dfui_dataset_new();
561e75c9034SSascha Wildner 		dfui_dataset_celldata_add(ds, "disk", device);
56221c1c48aSSascha Wildner 		dfui_dataset_celldata_add(ds, "boot0cfg", "Y");
56321c1c48aSSascha Wildner 		dfui_dataset_celldata_add(ds, "packet", "Y");
56421c1c48aSSascha Wildner 		dfui_form_dataset_add(f, ds);
565e75c9034SSascha Wildner 	} else {
566e75c9034SSascha Wildner 		for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) {
567e75c9034SSascha Wildner 			ds = dfui_dataset_new();
568e75c9034SSascha Wildner 			dfui_dataset_celldata_add(ds, "disk",
569e75c9034SSascha Wildner 			    disk_get_device_name(d));
570e75c9034SSascha Wildner 			dfui_dataset_celldata_add(ds, "boot0cfg", "Y");
571e75c9034SSascha Wildner 			dfui_dataset_celldata_add(ds, "packet", "Y");
572e75c9034SSascha Wildner 			dfui_form_dataset_add(f, ds);
573e75c9034SSascha Wildner 		}
57421c1c48aSSascha Wildner 	}
57521c1c48aSSascha Wildner 
57621c1c48aSSascha Wildner 	if (!dfui_be_present(a->c, f, &r))
57721c1c48aSSascha Wildner 		abort_backend();
57821c1c48aSSascha Wildner 
57921c1c48aSSascha Wildner 	a->result = 0;
58021c1c48aSSascha Wildner 	if (strcmp(dfui_response_get_action_id(r), "ok") == 0) {
58121c1c48aSSascha Wildner 		cmds = commands_new();
58221c1c48aSSascha Wildner 
58321c1c48aSSascha Wildner 		for (ds = dfui_response_dataset_get_first(r); ds != NULL;
58421c1c48aSSascha Wildner 		     ds = dfui_dataset_get_next(ds)) {
58521c1c48aSSascha Wildner 			strlcpy(disk, dfui_dataset_get_value(ds, "disk"), 64);
58621c1c48aSSascha Wildner 			strlcpy(boot0cfg, dfui_dataset_get_value(ds, "boot0cfg"), 32);
58721c1c48aSSascha Wildner 			strlcpy(packet, dfui_dataset_get_value(ds, "packet"), 32);
58821c1c48aSSascha Wildner 
58921c1c48aSSascha Wildner 			if (strcasecmp(boot0cfg, "Y") == 0) {
59021c1c48aSSascha Wildner 				cmd = command_add(cmds, "%s%s -B -o %spacket %s",
59121c1c48aSSascha Wildner 				    a->os_root, cmd_name(a, "BOOT0CFG"),
59221c1c48aSSascha Wildner 				    strcasecmp(packet, "Y") == 0 ? "" : "no",
59321c1c48aSSascha Wildner 				    disk);
59421c1c48aSSascha Wildner 				command_set_failure_mode(cmd, COMMAND_FAILURE_WARN);
5959462167aSSascha Wildner 				command_set_tag(cmd, "%s", disk);
59621c1c48aSSascha Wildner 				cmd = command_add(cmds, "%s%s -v %s",
59721c1c48aSSascha Wildner 				    a->os_root, cmd_name(a, "BOOT0CFG"),
59821c1c48aSSascha Wildner 				    disk);
59921c1c48aSSascha Wildner 				command_set_failure_mode(cmd, COMMAND_FAILURE_WARN);
6009462167aSSascha Wildner 				command_set_tag(cmd, "%s", disk);
60121c1c48aSSascha Wildner 			}
60221c1c48aSSascha Wildner 		}
60321c1c48aSSascha Wildner 
60421c1c48aSSascha Wildner 		if (!commands_execute(a, cmds)) {
60521c1c48aSSascha Wildner 			ask_to_wipe_boot_sector(a, cmds);
60621c1c48aSSascha Wildner 		} else {
60721c1c48aSSascha Wildner 			inform(a->c, _("Bootblocks were successfully installed!"));
60821c1c48aSSascha Wildner 			a->result = 1;
60921c1c48aSSascha Wildner 		}
61021c1c48aSSascha Wildner 		commands_free(cmds);
61121c1c48aSSascha Wildner 	}
61221c1c48aSSascha Wildner 
61321c1c48aSSascha Wildner 	dfui_form_free(f);
61421c1c48aSSascha Wildner 	dfui_response_free(r);
61521c1c48aSSascha Wildner }
61621c1c48aSSascha Wildner 
61721c1c48aSSascha Wildner void
fn_format_msdos_floppy(struct i_fn_args * a)61821c1c48aSSascha Wildner fn_format_msdos_floppy(struct i_fn_args *a)
61921c1c48aSSascha Wildner {
62021c1c48aSSascha Wildner 	struct commands *cmds;
62121c1c48aSSascha Wildner 
62221c1c48aSSascha Wildner 	switch (dfui_be_present_dialog(a->c, _("Format MSDOS Floppy"),
62321c1c48aSSascha Wildner 	    _("Format Floppy|Return to Utilities Menu"),
62421c1c48aSSascha Wildner 	    _("Please insert the floppy to be formatted "
62521c1c48aSSascha Wildner 	    "in unit 0 (``drive A:'')."))) {
62621c1c48aSSascha Wildner 	case 1:
62721c1c48aSSascha Wildner 		cmds = commands_new();
62821c1c48aSSascha Wildner 		command_add(cmds, "%s%s -y -f 1440 /dev/fd0",
62921c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "FDFORMAT"));
63021c1c48aSSascha Wildner 		command_add(cmds, "%s%s -f 1440 fd0",
63121c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "NEWFS_MSDOS"));
63221c1c48aSSascha Wildner 		if (commands_execute(a, cmds))
63321c1c48aSSascha Wildner 			inform(a->c, _("Floppy successfully formatted!"));
63421c1c48aSSascha Wildner 		else
63521c1c48aSSascha Wildner 			inform(a->c, _("Floppy was not successfully formatted."));
63621c1c48aSSascha Wildner 		break;
63721c1c48aSSascha Wildner 	case 2:
63821c1c48aSSascha Wildner 		return;
63921c1c48aSSascha Wildner 	default:
64021c1c48aSSascha Wildner 		abort_backend();
64121c1c48aSSascha Wildner 	}
64221c1c48aSSascha Wildner }
64321c1c48aSSascha Wildner 
64421c1c48aSSascha Wildner void
fn_create_cdboot_floppy(struct i_fn_args * a)64521c1c48aSSascha Wildner fn_create_cdboot_floppy(struct i_fn_args *a)
64621c1c48aSSascha Wildner {
64721c1c48aSSascha Wildner 	struct commands *cmds;
64821c1c48aSSascha Wildner 	char msg_buf[1][1024];
64921c1c48aSSascha Wildner 
65021c1c48aSSascha Wildner 	snprintf(msg_buf[0], sizeof(msg_buf[0]),
65121c1c48aSSascha Wildner 	    "%s cannot be installed from a floppy; "
65221c1c48aSSascha Wildner 	    "it must be installed from a booted CD-ROM. "
65321c1c48aSSascha Wildner 	    "However, many older systems do not support booting "
65421c1c48aSSascha Wildner 	    "from a CD-ROM. For these systems, a boot disk can be "
65521c1c48aSSascha Wildner 	    "created. This boot disk contains the Smart Boot "
65621c1c48aSSascha Wildner 	    "Manager program, which can boot a CD-ROM even "
65721c1c48aSSascha Wildner 	    "on systems with BIOSes which do not support booting "
65821c1c48aSSascha Wildner 	    "from the CD-ROM.\n\n"
65921c1c48aSSascha Wildner 	    "Smart Boot Manager is not a part of %s; "
66021c1c48aSSascha Wildner 	    "the Smart Boot Manager project can be found here:\n\n"
66121c1c48aSSascha Wildner 	    "http://btmgr.sourceforge.net/\n\n"
66221c1c48aSSascha Wildner 	    "To create a CDBoot floppy, insert a blank floppy "
66321c1c48aSSascha Wildner 	    "in unit 0 (``drive A:'') before proceeding."
66421c1c48aSSascha Wildner 	    "",
66521c1c48aSSascha Wildner 	    OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME);
66621c1c48aSSascha Wildner 
66721c1c48aSSascha Wildner 	switch (dfui_be_present_dialog(a->c, _("Create CDBoot Floppy"),
66821c1c48aSSascha Wildner 	    _("Create CDBoot Floppy|Return to Utilities Menu"),
6699462167aSSascha Wildner 	    "%s", msg_buf[0])) {
67021c1c48aSSascha Wildner 	case 1:
67121c1c48aSSascha Wildner 		cmds = commands_new();
67221c1c48aSSascha Wildner 		command_add(cmds, "%s%s -c %sboot/cdboot.flp.bz2 | "
67351871435SSascha Wildner 		    "%s%s of=/dev/fd0 bs=32k",
67421c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "BUNZIP2"),
67521c1c48aSSascha Wildner 		    a->os_root,
67651871435SSascha Wildner 		    a->os_root, cmd_name(a, "DD"));
67721c1c48aSSascha Wildner 		if (commands_execute(a, cmds))
67821c1c48aSSascha Wildner 			inform(a->c, _("CDBoot floppy successfully created!"));
67921c1c48aSSascha Wildner 		else
68021c1c48aSSascha Wildner 			inform(a->c, _("CDBoot floppy was not successfully created."));
68121c1c48aSSascha Wildner 		break;
68221c1c48aSSascha Wildner 	case 2:
68321c1c48aSSascha Wildner 		return;
68421c1c48aSSascha Wildner 	default:
68521c1c48aSSascha Wildner 		abort_backend();
68621c1c48aSSascha Wildner 	}
68721c1c48aSSascha Wildner }
68821c1c48aSSascha Wildner 
68921c1c48aSSascha Wildner /**** NON-fn_ FUNCTIONS ***/
69021c1c48aSSascha Wildner 
69121c1c48aSSascha Wildner int
format_slice(struct i_fn_args * a)69221c1c48aSSascha Wildner format_slice(struct i_fn_args *a)
69321c1c48aSSascha Wildner {
69421c1c48aSSascha Wildner 	struct commands *cmds;
695a096577dSSascha Wildner 	struct command *cmd;
69621c1c48aSSascha Wildner 	int result;
69721c1c48aSSascha Wildner 	int cyl, hd, sec;
69821c1c48aSSascha Wildner 
69921c1c48aSSascha Wildner 	cmds = commands_new();
70021c1c48aSSascha Wildner 
70121c1c48aSSascha Wildner 	/*
70221c1c48aSSascha Wildner 	 * The information in a->s NEEDS to be accurate here!
70321c1c48aSSascha Wildner 	 * Presumably we just did a survey_storage() recently.
70421c1c48aSSascha Wildner 	 * XXX should we do another one here anyway just to be paranoid?
70521c1c48aSSascha Wildner 	 */
70621c1c48aSSascha Wildner 
70721c1c48aSSascha Wildner 	/*
70883c251b0SAntonio Huete Jimenez 	 * Make sure the survey did get disk info correctly or fail
70983c251b0SAntonio Huete Jimenez 	 */
71083c251b0SAntonio Huete Jimenez 	if ((storage_get_selected_disk(a->s) == NULL) ||
71183c251b0SAntonio Huete Jimenez 	    (storage_get_selected_slice(a->s) == NULL))
71283c251b0SAntonio Huete Jimenez 		return 0;
71383c251b0SAntonio Huete Jimenez 
71483c251b0SAntonio Huete Jimenez 	/*
7157d89978dSSascha Wildner 	 * Set the slice's sysid to 108.
71621c1c48aSSascha Wildner 	 */
71721c1c48aSSascha Wildner 	disk_get_geometry(storage_get_selected_disk(a->s), &cyl, &hd, &sec);
71821c1c48aSSascha Wildner 	command_add(cmds, "%s%s 'g c%d h%d s%d' >%snew.fdisk",
71921c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "ECHO"),
72021c1c48aSSascha Wildner 	    cyl, hd, sec,
72121c1c48aSSascha Wildner 	    a->tmp);
72221c1c48aSSascha Wildner 	command_add(cmds, "%s%s 'p %d %d %lu %lu' >>%snew.fdisk",
72321c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "ECHO"),
72421c1c48aSSascha Wildner 	    slice_get_number(storage_get_selected_slice(a->s)),
725*8e693f3bSSascha Wildner 	    DOSPTYP_DFLYBSD,
72621c1c48aSSascha Wildner 	    slice_get_start(storage_get_selected_slice(a->s)),
72721c1c48aSSascha Wildner 	    slice_get_size(storage_get_selected_slice(a->s)),
72821c1c48aSSascha Wildner 	    a->tmp);
72921c1c48aSSascha Wildner 	if (slice_get_flags(storage_get_selected_slice(a->s)) & 0x80) {
73021c1c48aSSascha Wildner 		command_add(cmds, "%s%s 'a %d' >>%snew.fdisk",
73121c1c48aSSascha Wildner 		    a->os_root, cmd_name(a, "ECHO"),
73221c1c48aSSascha Wildner 		    slice_get_number(storage_get_selected_slice(a->s)),
73321c1c48aSSascha Wildner 		    a->tmp);
73421c1c48aSSascha Wildner 	}
73521c1c48aSSascha Wildner 
73621c1c48aSSascha Wildner 	command_add(cmds, "%s%s %snew.fdisk",
73721c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "CAT"), a->tmp);
73821c1c48aSSascha Wildner 	temp_file_add(a, "new.fdisk");
73921c1c48aSSascha Wildner 
74021c1c48aSSascha Wildner 	/*
74121c1c48aSSascha Wildner 	 * Execute the fdisk script.
74221c1c48aSSascha Wildner 	 */
743a096577dSSascha Wildner 	cmd = command_add(cmds, "%s%s -v -f %snew.fdisk %s",
74421c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "FDISK"), a->tmp,
745f59b7dfaSSascha Wildner 	    disk_get_device_name(storage_get_selected_disk(a->s)));
746a096577dSSascha Wildner 	if (slice_get_size(storage_get_selected_slice(a->s)) == 0xFFFFFFFFU)
747a096577dSSascha Wildner 		command_set_failure_mode(cmd, COMMAND_FAILURE_IGNORE);
74821c1c48aSSascha Wildner 
74921c1c48aSSascha Wildner 	/*
75021c1c48aSSascha Wildner 	 * If there is an old 'virgin' disklabel hanging around
75121c1c48aSSascha Wildner 	 * in the temp dir, get rid of it.  This won't happen
75221c1c48aSSascha Wildner 	 * from a real CD, but might happen with '-o' installs.
75321c1c48aSSascha Wildner 	 */
75421c1c48aSSascha Wildner 	command_add(cmds, "%s%s -f %sinstall.disklabel.%s",
75521c1c48aSSascha Wildner 	    a->os_root, cmd_name(a, "RM"),
75621c1c48aSSascha Wildner 	    a->tmp,
75721c1c48aSSascha Wildner 	    slice_get_device_name(storage_get_selected_slice(a->s)));
75821c1c48aSSascha Wildner 
75921c1c48aSSascha Wildner 	result = commands_execute(a, cmds);
76021c1c48aSSascha Wildner 
76121c1c48aSSascha Wildner 	commands_free(cmds);
76221c1c48aSSascha Wildner 
76321c1c48aSSascha Wildner 	return(result);
76421c1c48aSSascha Wildner }
765