acpi: Select proper one shot timer based on CPUs' C3 state.
[dragonfly.git] / contrib / bsdinstaller-1.1.6 / src / backend / installer / fn_disk.c
1 /*
2  * Copyright (c)2004 The DragonFly Project.  All rights reserved.
3  * 
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 
8  *   Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * 
11  *   Redistributions in binary form must reproduce the above copyright
12  *   notice, this list of conditions and the following disclaimer in
13  *   the documentation and/or other materials provided with the
14  *   distribution.
15  * 
16  *   Neither the name of the DragonFly Project nor the names of its
17  *   contributors may be used to endorse or promote products derived
18  *   from this software without specific prior written permission. 
19  * 
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31  * OF THE POSSIBILITY OF SUCH DAMAGE. 
32  */
33
34 /*
35  * fn_disk.c
36  * Disk functions for installer.
37  * $Id: fn_disk.c,v 1.40 2005/03/13 01:53:58 cpressey Exp $
38  */
39
40 #include <stdlib.h>
41 #include <string.h>
42
43 #ifdef ENABLE_NLS
44 #include <libintl.h>
45 #define _(String) gettext (String)
46 #else
47 #define _(String) (String)
48 #endif
49
50 #include "libaura/mem.h"
51 #include "libaura/fspred.h"
52
53 #include "libdfui/dfui.h"
54 #include "libdfui/system.h"
55
56 #include "libinstaller/commands.h"
57 #include "libinstaller/diskutil.h"
58 #include "libinstaller/functions.h"
59 #include "libinstaller/uiutil.h"
60
61 #include "fn.h"
62 #include "pathnames.h"
63
64 /*** DISK-RELATED FUNCTIONS ***/
65
66 /*
67  * Ask the user which physical disk they want.
68  * Changes ss->selected_disk if successful.
69  */
70 void
71 fn_select_disk(struct i_fn_args *a)
72 {
73         struct dfui_form *f;
74         struct dfui_action *k;
75         struct dfui_response *r;
76         struct disk *d;
77
78         f = dfui_form_create(
79             "select_disk",
80             _("Select Disk"),
81             a->short_desc,
82             "",
83
84             "p", "role",  "menu",
85             "p", "special", "dfinstaller_select_disk",
86
87             NULL
88         );
89
90         for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) {
91                 dfui_form_action_add(f, disk_get_device_name(d),
92                     dfui_info_new(disk_get_desc(d), "", ""));
93         }
94
95         k = dfui_form_action_add(f, "cancel",
96             dfui_info_new(a->cancel_desc, "", ""));
97         dfui_action_property_set(k, "accelerator", "ESC");
98
99         if (!dfui_be_present(a->c, f, &r))
100                 abort_backend();
101
102         if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
103                 a->result = 0;
104         } else {
105                 d = disk_find(a->s, dfui_response_get_action_id(r));
106                 if (d == NULL) {
107                         inform(a->c, _("Internal error - response from frontend "
108                             "should be a valid device name."));
109                         a->result = 0;
110                 } else {
111                         storage_set_selected_disk(a->s, d);
112                         a->result = 1;
113                 }
114         }
115
116         dfui_form_free(f);
117         dfui_response_free(r);
118 }
119
120 /*
121  * Ask the user which slice on a the selected disk they want.
122  * Changes ss->selected_slice.
123  */
124 void
125 fn_select_slice(struct i_fn_args *a)
126 {
127         struct dfui_form *f;
128         struct dfui_action *k;
129         struct dfui_response *r;
130         struct slice *s;
131         char string[16];
132
133         f = dfui_form_create(
134             "select_slice",
135             _("Select Primary Partition"),
136             a->short_desc,
137             "",
138
139             "p", "role", "menu",
140             "p", "special", "dfinstaller_select_slice",
141
142             NULL
143         );
144
145         for (s = disk_slice_first(storage_get_selected_disk(a->s));
146              s != NULL; s = slice_next(s)) {
147                 snprintf(string, 16, "%d", slice_get_number(s));
148                 dfui_form_action_add(f, string,
149                     dfui_info_new(slice_get_desc(s), "", ""));
150         }
151
152         k = dfui_form_action_add(f, "cancel",
153             dfui_info_new(a->cancel_desc, "", ""));
154         dfui_action_property_set(k, "accelerator", "ESC");
155
156         if (!dfui_be_present(a->c, f, &r))
157                 abort_backend();
158
159         if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
160                 a->result = 0;
161         } else {
162                 s = slice_find(storage_get_selected_disk(a->s),
163                     atoi(dfui_response_get_action_id(r)));
164                 if (s == NULL) {
165                         inform(a->c, _("Internal error - response from frontend "
166                             "should be a valid slice number."));
167                         a->result = 0;
168                 } else {
169                         storage_set_selected_slice(a->s, s);
170                         a->result = 1;
171                 }
172         }
173
174         dfui_form_free(f);
175         dfui_response_free(r);
176 }
177
178 /*
179  * If ss->selected_disk == NULL, user will be asked for which disk.
180  * Returns 1 if disk was formatted, 0 if it wasn't.
181  * If it was, ss->selected_disk and ss->selected_slice are set to it.
182  */
183 void
184 fn_format_disk(struct i_fn_args *a)
185 {
186         struct commands *cmds;
187         char *selected_disk_string;
188
189         if (storage_get_selected_disk(a->s) == NULL) {
190                 a->short_desc = _("Select a disk to format.");
191                 a->cancel_desc = _("Return to Utilities Menu");
192                 fn_select_disk(a);
193                 if (!a->result || storage_get_selected_disk(a->s) == NULL) {
194                         a->result = 0;
195                         return;
196                 }
197         }
198
199         if (confirm_dangerous_action(a->c,
200             _("WARNING!  ALL data in ALL partitions on the disk\n\n"
201             "%s\n\nwill be IRREVOCABLY ERASED!\n\nAre you ABSOLUTELY "
202             "SURE you wish to take this action?  This is your "
203             "LAST CHANCE to cancel!"), disk_get_desc(storage_get_selected_disk(a->s)))) {
204                 cmds = commands_new();
205                         
206                 /*
207                  * Create the device node if it does not exist.
208                  */
209                 command_add_ensure_dev(a, cmds,
210                     disk_get_device_name(storage_get_selected_disk(a->s)));
211                 command_add(cmds, "%s%s -BI %s",
212                     a->os_root, cmd_name(a, "FDISK"),
213                     disk_get_raw_device_name(storage_get_selected_disk(a->s)));
214
215                 if (!commands_execute(a, cmds)) {
216                         inform(a->c, _("The disk\n\n%s\n\nwas "
217                             "not correctly formatted, and may "
218                             "now be in an inconsistent state. "
219                             "We recommend re-formatting it "
220                             "before attempting to install "
221                             "%s on it."),
222                             disk_get_desc(storage_get_selected_disk(a->s)),
223                             OPERATING_SYSTEM_NAME);
224                         commands_free(cmds);
225                         a->result = 0;
226                         return;
227                 }
228                 commands_free(cmds);
229
230                 /*
231                  * Since one of the disks has now changed, we must
232                  * refresh our view of them and re-select the disk
233                  * since the selected_disk pointer will be invalidated.
234                  */
235                 selected_disk_string = aura_strdup(
236                     disk_get_device_name(storage_get_selected_disk(a->s)));
237                 if (!survey_storage(a)) {
238                         inform(a->c, _("Errors occurred while probing "
239                             "the system for its storage capabilities."));
240                 }
241                 storage_set_selected_disk(a->s, disk_find(a->s, selected_disk_string));
242                 free(selected_disk_string);
243
244                 /*
245                  * Note that we formatted this disk and that we want
246                  * to use the first (and only) slice of it.
247                  */
248                 disk_set_formatted(storage_get_selected_disk(a->s), 1);
249                 storage_set_selected_slice(a->s, disk_slice_first(storage_get_selected_disk(a->s)));
250
251                 if (!format_slice(a)) {
252                         inform(a->c, _("The sole primary partition of "
253                             "the disk\n\n%s\n\nwas "
254                             "not correctly formatted, and may "
255                             "now be in an inconsistent state. "
256                             "We recommend re-formatting the "
257                             "disk before attempting to install "
258                             "%s on it."),
259                             disk_get_desc(storage_get_selected_disk(a->s)),
260                             OPERATING_SYSTEM_NAME);
261                         a->result = 0;
262                         return;
263                 }
264
265                 inform(a->c, _("The disk\n\n%s\n\nwas formatted."),
266                     disk_get_desc(storage_get_selected_disk(a->s)));
267                 a->result = 1;
268         } else {
269                 inform(a->c, _("Action cancelled - no disks were formatted."));
270                 a->result = 0;
271         }
272 }
273
274 /*
275  * Wipes the start of the selected disk.
276  */
277 void
278 fn_wipe_start_of_disk(struct i_fn_args *a)
279 {
280         struct commands *cmds;
281
282         a->short_desc = _("If you are having problems formatting a disk, "
283             "it may be because of junk that has accumulated "
284             "in the boot block and the partition table. "
285             "A cure for this is to wipe out everything on "
286             "the first few sectors of the disk.  However, this "
287             "is a rather drastic action to take, so it is not "
288             "recommended unless you are otherwise "
289             "encountering problems.");
290         a->cancel_desc = _("Return to Utilities Menu");
291         fn_select_disk(a);
292         if (!a->result)
293                 return;
294
295         /* XXX check to make sure no slices on this disk are mounted first? */
296         if (storage_get_selected_disk(a->s) != NULL && confirm_dangerous_action(a->c,
297             _("WARNING!  ALL data in ALL partitions on the disk\n\n"
298             "%s\n\nwill be IRREVOCABLY ERASED!\n\nAre you ABSOLUTELY "
299             "SURE you wish to take this action?  This is your "
300             "LAST CHANCE to cancel!"), disk_get_desc(storage_get_selected_disk(a->s)))) {
301                 cmds = commands_new();
302                 command_add(cmds,
303                     "%s%s if=%sdev/zero of=%sdev/%s bs=32k count=16",
304                     a->os_root, cmd_name(a, "DD"),
305                     a->os_root, a->os_root,
306                     disk_get_raw_device_name(storage_get_selected_disk(a->s)));
307                 if (commands_execute(a, cmds)) {
308                         inform(a->c, _("Start of disk was successfully wiped."));
309                 } else {
310                         inform(a->c, _("Some errors occurred. "
311                             "Start of disk was not successfully wiped."));
312                 }
313                 commands_free(cmds);
314         }
315 }
316
317 /*
318  * Wipes the start of the selected slice.
319  */
320 void
321 fn_wipe_start_of_slice(struct i_fn_args *a)
322 {
323         struct commands *cmds;
324
325         a->short_desc =
326           _("If you are having problems formatting a primary partition, "
327             "it may be because of junk that has accumulated in the "
328             "partition's `disklabel'. A cure for this is to wipe out "
329             "everything on the first few sectors of the primary partition. "
330             "However, this is a rather drastic action to take, so it is not "
331             "recommended unless you are otherwise encountering problems.");
332         a->cancel_desc = _("Return to Utilities Menu");
333         fn_select_slice(a);
334         if (!a->result)
335                 return;
336
337         if (confirm_dangerous_action(a->c,
338             _("WARNING!  ALL data in primary partition #%d,\n\n%s\n\non the "
339             "disk\n\n%s\n\n will be IRREVOCABLY ERASED!\n\nAre you "
340             "ABSOLUTELY SURE you wish to take this action?  This is "
341             "your LAST CHANCE to cancel!"),
342             slice_get_number(storage_get_selected_slice(a->s)),
343             slice_get_desc(storage_get_selected_slice(a->s)),
344             disk_get_desc(storage_get_selected_disk(a->s)))) {
345                 /* XXX check to make sure this slice is not mounted first */
346                 cmds = commands_new();
347                 command_add(cmds, "%s%s if=%sdev/zero of=%sdev/%s bs=32k count=16",
348                     a->os_root, cmd_name(a, "DD"),
349                     a->os_root, a->os_root,
350                     slice_get_raw_device_name(storage_get_selected_slice(a->s)));
351                 if (commands_execute(a, cmds)) {
352                         inform(a->c, _("Start of primary partition was successfully wiped."));
353                 } else {
354                         inform(a->c, _("Some errors occurred. "
355                             "Start of primary partition was not successfully wiped."));
356                 }
357                 commands_free(cmds);
358         }
359 }
360
361 static void
362 ask_to_wipe_boot_sector(struct i_fn_args *a, struct commands *fcmds)
363 {
364         struct commands *cmds;
365         struct command *cmd;
366         char *disk;
367
368         for (cmd = command_get_first(fcmds); cmd != NULL;
369              cmd = command_get_next(cmd)) {
370                 disk = command_get_tag(cmd);
371                 if (disk != NULL &&
372                     command_get_result(cmd) > 0 &&
373                     command_get_result(cmd) < 256) {
374                         switch (dfui_be_present_dialog(a->c,
375                             _("Bootblock Install Failed"),
376                             _("Re-Initialize Bootblock|Cancel"),
377                             _("Warning: bootblocks were not successfully "
378                             "installed on the disk `%s'. This may be "
379                             "because the disk is new and not yet "
380                             "formatted. If this is the case, it might "
381                             "help to re-initialize the boot sector, "
382                             "then try installing the bootblock again. "
383                             "Note that this should not affect the "
384                             "partition table of the disk."),
385                             disk, disk)) {
386                         case 1:
387                                 cmds = commands_new();
388                                 command_add(cmds,
389                                     "%s%s | %s%s -B %sdev/%s",
390                                     a->os_root, cmd_name(a, "YES"),
391                                     a->os_root, cmd_name(a, "FDISK"),
392                                     a->os_root, disk);
393                                 if (commands_execute(a, cmds)) {
394                                         inform(a->c, _("Boot sector successfully initialized."));
395                                 } else {
396                                         inform(a->c, _("Some errors occurred. "
397                                             "Boot sector was not successfully initialized."));
398                                 }
399                                 commands_free(cmds);
400                                 break;
401                         default:
402                                 break;
403                         }
404                 }
405         }
406 }
407
408 void
409 fn_install_bootblocks(struct i_fn_args *a)
410 {
411         struct dfui_form *f;
412         struct dfui_response *r;
413         struct dfui_dataset *ds;
414         struct disk *d;
415         struct commands *cmds;
416         struct command *cmd;
417         char disk[64], boot0cfg[32], packet[32];
418         char msg_buf[1][1024];
419
420         snprintf(msg_buf[0], sizeof(msg_buf[0]),
421             "'Packet Mode' refers to using newer BIOS calls to boot "
422             "from a partition of the disk.  It is generally not "
423             "required unless:\n\n"
424             "- your BIOS does not support legacy mode; or\n"
425             "- your %s primary partition resides on a "
426             "cylinder of the disk beyond cylinder 1024; or\n"
427             "- you just can't get it to boot without it.",
428             OPERATING_SYSTEM_NAME);
429
430         f = dfui_form_create(
431             "install_bootstrap",
432             _("Install Bootblock(s)"),
433             a->short_desc,
434
435             msg_buf[0],
436
437             "p", "special", "dfinstaller_install_bootstrap",
438
439             "f", "disk", _("Disk Drive"),
440             _("The disk on which you wish to install a bootblock"), "",
441             "p", "editable", "false",
442             "f", "boot0cfg", _("Install Bootblock?"),
443             _("Install a bootblock on this disk"), "",
444             "p", "control", "checkbox",
445             "f", "packet", _("Packet Mode?"),
446             _("Select this to use 'packet mode' to boot the disk"), "",
447             "p", "control", "checkbox",
448         
449             "a", "ok", _("Accept and Install Bootblocks"), "", "",
450             "a", "cancel", a->cancel_desc, "", "", 
451             "p", "accelerator", "ESC",
452
453             NULL
454         );
455
456         dfui_form_set_multiple(f, 1);
457
458         for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) {
459                 ds = dfui_dataset_new();
460                 /* XXX need to see how this is handled in OpenBSD/NetBSD */
461                 dfui_dataset_celldata_add(ds, "disk", disk_get_raw_device_name(d));
462                 dfui_dataset_celldata_add(ds, "boot0cfg", "Y");
463                 dfui_dataset_celldata_add(ds, "packet", "Y");
464                 dfui_form_dataset_add(f, ds);
465         }
466
467         if (!dfui_be_present(a->c, f, &r))
468                 abort_backend();
469
470         a->result = 0;
471         if (strcmp(dfui_response_get_action_id(r), "ok") == 0) {
472                 cmds = commands_new();
473
474                 for (ds = dfui_response_dataset_get_first(r); ds != NULL;
475                      ds = dfui_dataset_get_next(ds)) {
476                         strlcpy(disk, dfui_dataset_get_value(ds, "disk"), 64);
477                         strlcpy(boot0cfg, dfui_dataset_get_value(ds, "boot0cfg"), 32);
478                         strlcpy(packet, dfui_dataset_get_value(ds, "packet"), 32);
479
480                         if (strcasecmp(boot0cfg, "Y") == 0) {
481                                 cmd = command_add(cmds, "%s%s -B -o %spacket %s",
482                                     a->os_root, cmd_name(a, "BOOT0CFG"),
483                                     strcasecmp(packet, "Y") == 0 ? "" : "no",
484                                     disk);
485                                 command_set_failure_mode(cmd, COMMAND_FAILURE_WARN);
486                                 command_set_tag(cmd, disk);
487                                 cmd = command_add(cmds, "%s%s -v %s",
488                                     a->os_root, cmd_name(a, "BOOT0CFG"),
489                                     disk);
490                                 command_set_failure_mode(cmd, COMMAND_FAILURE_WARN);
491                                 command_set_tag(cmd, disk);
492                         }
493                 }
494
495                 if (!commands_execute(a, cmds)) {
496                         ask_to_wipe_boot_sector(a, cmds);
497                 } else {
498                         inform(a->c, _("Bootblocks were successfully installed!"));
499                         a->result = 1;
500                 }
501                 commands_free(cmds);
502         }
503
504         dfui_form_free(f);
505         dfui_response_free(r);
506 }
507
508 void
509 fn_format_msdos_floppy(struct i_fn_args *a)
510 {
511         struct commands *cmds;
512
513         switch (dfui_be_present_dialog(a->c, _("Format MSDOS Floppy"),
514             _("Format Floppy|Return to Utilities Menu"),
515             _("Please insert the floppy to be formatted "
516             "in unit 0 (``drive A:'')."))) {
517         case 1:
518                 cmds = commands_new();
519                 command_add(cmds, "%s%s -y -f 1440 /dev/fd0",
520                     a->os_root, cmd_name(a, "FDFORMAT"));
521                 command_add(cmds, "%s%s -f 1440 fd0",
522                     a->os_root, cmd_name(a, "NEWFS_MSDOS"));
523                 if (commands_execute(a, cmds))
524                         inform(a->c, _("Floppy successfully formatted!"));
525                 else
526                         inform(a->c, _("Floppy was not successfully formatted."));
527                 break;
528         case 2:
529                 return;
530         default:
531                 abort_backend();
532         }
533 }
534
535 void
536 fn_create_cdboot_floppy(struct i_fn_args *a)
537 {
538         struct commands *cmds;
539         char msg_buf[1][1024];
540
541         snprintf(msg_buf[0], sizeof(msg_buf[0]),
542             "%s cannot be installed from a floppy; "
543             "it must be installed from a booted CD-ROM. "
544             "However, many older systems do not support booting "
545             "from a CD-ROM. For these systems, a boot disk can be "
546             "created. This boot disk contains the Smart Boot "
547             "Manager program, which can boot a CD-ROM even "
548             "on systems with BIOSes which do not support booting "
549             "from the CD-ROM.\n\n"
550             "Smart Boot Manager is not a part of %s; "
551             "the Smart Boot Manager project can be found here:\n\n"
552             "http://btmgr.sourceforge.net/\n\n"
553             "To create a CDBoot floppy, insert a blank floppy "
554             "in unit 0 (``drive A:'') before proceeding."
555             "",
556             OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME);
557
558         switch (dfui_be_present_dialog(a->c, _("Create CDBoot Floppy"),
559             _("Create CDBoot Floppy|Return to Utilities Menu"),
560             msg_buf[0])) {
561         case 1:
562                 cmds = commands_new();
563                 command_add(cmds, "%s%s -c %sboot/cdboot.flp.bz2 | "
564                     "%s%s of=%sdev/fd0 bs=32k",
565                     a->os_root, cmd_name(a, "BUNZIP2"),
566                     a->os_root,
567                     a->os_root, cmd_name(a, "DD"),
568                     a->os_root);
569                 if (commands_execute(a, cmds))
570                         inform(a->c, _("CDBoot floppy successfully created!"));
571                 else
572                         inform(a->c, _("CDBoot floppy was not successfully created."));
573                 break;
574         case 2:
575                 return;
576         default:
577                 abort_backend();
578         }
579 }
580
581 void
582 fn_create_memtest86_floppy(struct i_fn_args *a)
583 {
584         struct commands *cmds;
585
586         switch (dfui_be_present_dialog(a->c, _("Create memtest86 Floppy"),
587             "Create memtest86 Floppy|Return to Utilities Menu",
588             "While this installer allows you to test memory "
589             "on-line, the fact that the installer and operating "
590             "system are already loaded means that the memory "
591             "test has certain limits.  For a more thorough "
592             "memory test, you can create a floppy containing "
593             "the memtest86 program, which boots up independently "
594             "of any operating system, allowing it access to "
595             "almost the entire memory of the computer for testing.\n\n"
596             "memtest86 is not a part of %s; "
597             "the memtest86 project can be found here:\n\n"
598             "http://www.memtest86.com/\n\n"
599             "To create a memtest86 floppy, insert a blank floppy "
600             "in unit 0 (``drive A:'') before proceeding."
601             "", OPERATING_SYSTEM_NAME)) {
602         case 1:
603                 cmds = commands_new();
604                 command_add(cmds, "%s%s -c %sboot/memtest86.flp.bz2 | "
605                     "%s%s of=%sdev/fd0 bs=32k",
606                     a->os_root, cmd_name(a, "BUNZIP2"),
607                     a->os_root,
608                     a->os_root, cmd_name(a, "DD"),
609                     a->os_root);
610                 if (commands_execute(a, cmds))
611                         inform(a->c, _("memtest86 floppy successfully created!"));
612                 else
613                         inform(a->c, _("memtest86 floppy was not successfully created."));
614                 break;
615         case 2:
616                 return;
617         default:
618                 abort_backend();
619         }
620 }
621
622 /**** NON-fn_ FUNCTIONS ***/
623
624 int
625 format_slice(struct i_fn_args *a)
626 {
627         struct commands *cmds;
628         int result;
629         int cyl, hd, sec;
630
631         cmds = commands_new();
632
633         /*
634          * Create the device node if it does not exist.
635          */
636         command_add_ensure_dev(a, cmds,
637             slice_get_device_name(storage_get_selected_slice(a->s)));
638
639         /*
640          * The information in a->s NEEDS to be accurate here!
641          * Presumably we just did a survey_storage() recently.
642          * XXX should we do another one here anyway just to be paranoid?
643          */
644
645         /*
646          * Set the slice's sysid to 165.
647          */
648         disk_get_geometry(storage_get_selected_disk(a->s), &cyl, &hd, &sec);
649         command_add(cmds, "%s%s 'g c%d h%d s%d' >%snew.fdisk",
650             a->os_root, cmd_name(a, "ECHO"),
651             cyl, hd, sec,
652             a->tmp);
653         command_add(cmds, "%s%s 'p %d %d %lu %lu' >>%snew.fdisk",
654             a->os_root, cmd_name(a, "ECHO"),
655             slice_get_number(storage_get_selected_slice(a->s)),
656             165,
657             slice_get_start(storage_get_selected_slice(a->s)),
658             slice_get_size(storage_get_selected_slice(a->s)),
659             a->tmp);
660         if (slice_get_flags(storage_get_selected_slice(a->s)) & 0x80) {
661                 command_add(cmds, "%s%s 'a %d' >>%snew.fdisk",
662                     a->os_root, cmd_name(a, "ECHO"),
663                     slice_get_number(storage_get_selected_slice(a->s)),
664                     a->tmp);
665         }
666
667         command_add(cmds, "%s%s %snew.fdisk",
668             a->os_root, cmd_name(a, "CAT"), a->tmp);
669         temp_file_add(a, "new.fdisk");
670
671         /*
672          * Execute the fdisk script.
673          */
674         command_add(cmds, "%s%s -v -f %snew.fdisk %s",
675             a->os_root, cmd_name(a, "FDISK"), a->tmp,
676             disk_get_raw_device_name(storage_get_selected_disk(a->s)));
677
678         /*
679          * If there is an old 'virgin' disklabel hanging around
680          * in the temp dir, get rid of it.  This won't happen
681          * from a real CD, but might happen with '-o' installs.
682          */
683         command_add(cmds, "%s%s -f %sinstall.disklabel.%s",
684             a->os_root, cmd_name(a, "RM"),
685             a->tmp,
686             slice_get_device_name(storage_get_selected_slice(a->s)));
687
688         result = commands_execute(a, cmds);
689
690         commands_free(cmds);
691
692         return(result);
693 }