xref: /dragonfly/usr.sbin/installer/dfuibe_installer/fn_disk.c (revision 8e693f3b9a243606ce03418ba2304cd3f0691aa3)
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 <sys/diskmbr.h>
41 
42 #include <stdlib.h>
43 #include <unistd.h>
44 #include <string.h>
45 
46 #ifdef ENABLE_NLS
47 #include <libintl.h>
48 #define _(String) gettext (String)
49 #else
50 #define _(String) (String)
51 #endif
52 
53 #include "libaura/mem.h"
54 #include "libaura/fspred.h"
55 
56 #include "libdfui/dfui.h"
57 #include "libdfui/system.h"
58 
59 #include "libinstaller/commands.h"
60 #include "libinstaller/diskutil.h"
61 #include "libinstaller/functions.h"
62 #include "libinstaller/uiutil.h"
63 
64 #include "fn.h"
65 #include "pathnames.h"
66 
67 /*** DISK-RELATED FUNCTIONS ***/
68 
69 /*
70  * Ask the user which physical disk they want.
71  * Changes ss->selected_disk if successful.
72  */
73 void
fn_select_disk(struct i_fn_args * a)74 fn_select_disk(struct i_fn_args *a)
75 {
76           struct dfui_form *f;
77           struct dfui_action *k;
78           struct dfui_response *r;
79           struct disk *d;
80 
81           f = dfui_form_create(
82               "select_disk",
83               _("Select Disk"),
84               a->short_desc,
85               "",
86 
87               "p", "role",  "menu",
88               "p", "special", "dfinstaller_select_disk",
89 
90               NULL
91           );
92 
93           for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) {
94                     dfui_form_action_add(f, disk_get_device_name(d),
95                         dfui_info_new(disk_get_desc(d), "", ""));
96           }
97 
98           k = dfui_form_action_add(f, "cancel",
99               dfui_info_new(a->cancel_desc, "", ""));
100           dfui_action_property_set(k, "accelerator", "ESC");
101 
102           if (!dfui_be_present(a->c, f, &r))
103                     abort_backend();
104 
105           if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
106                     a->result = 0;
107           } else {
108                     d = disk_find(a->s, dfui_response_get_action_id(r));
109                     if (d == NULL) {
110                               inform(a->c, _("Internal error - response from frontend "
111                                   "should be a valid device name."));
112                               a->result = 0;
113                     } else {
114                               storage_set_selected_disk(a->s, d);
115                               a->result = 1;
116                     }
117           }
118 
119           dfui_form_free(f);
120           dfui_response_free(r);
121 }
122 
123 /*
124  * Ask the user which slice on a the selected disk they want.
125  * Changes ss->selected_slice.
126  */
127 void
fn_select_slice(struct i_fn_args * a)128 fn_select_slice(struct i_fn_args *a)
129 {
130           struct dfui_form *f;
131           struct dfui_action *k;
132           struct dfui_response *r;
133           struct slice *s;
134           char string[16];
135 
136           f = dfui_form_create(
137               "select_slice",
138               _("Select Primary Partition"),
139               a->short_desc,
140               "",
141 
142               "p", "role", "menu",
143               "p", "special", "dfinstaller_select_slice",
144 
145               NULL
146           );
147 
148           for (s = disk_slice_first(storage_get_selected_disk(a->s));
149                s != NULL; s = slice_next(s)) {
150                     snprintf(string, 16, "%d", slice_get_number(s));
151                     dfui_form_action_add(f, string,
152                         dfui_info_new(slice_get_desc(s), "", ""));
153           }
154 
155           k = dfui_form_action_add(f, "cancel",
156               dfui_info_new(a->cancel_desc, "", ""));
157           dfui_action_property_set(k, "accelerator", "ESC");
158 
159           if (!dfui_be_present(a->c, f, &r))
160                     abort_backend();
161 
162           if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
163                     a->result = 0;
164           } else {
165                     s = slice_find(storage_get_selected_disk(a->s),
166                         atoi(dfui_response_get_action_id(r)));
167                     if (s == NULL) {
168                               inform(a->c, _("Internal error - response from frontend "
169                                   "should be a valid slice number."));
170                               a->result = 0;
171                     } else {
172                               storage_set_selected_slice(a->s, s);
173                               a->result = 1;
174                     }
175           }
176 
177           dfui_form_free(f);
178           dfui_response_free(r);
179 }
180 
181 /*
182  * If ss->selected_disk == NULL, user will be asked for which disk.
183  * Returns 1 if disk was formatted, 0 if it wasn't.
184  * If it was, ss->selected_disk and ss->selected_slice are set to it.
185  */
186 void
fn_format_disk_mbr(struct i_fn_args * a)187 fn_format_disk_mbr(struct i_fn_args *a)
188 {
189           struct commands *cmds;
190           char *selected_disk_string;
191 
192           if (storage_get_selected_disk(a->s) == NULL) {
193                     a->short_desc = _("Select a disk to format.");
194                     a->cancel_desc = _("Return to Utilities Menu");
195                     fn_select_disk(a);
196                     if (!a->result || storage_get_selected_disk(a->s) == NULL) {
197                               a->result = 0;
198                               return;
199                     }
200           }
201 
202           if (confirm_dangerous_action(a->c,
203               _("WARNING!  ALL data in ALL partitions on the disk\n\n"
204               "%s\n\nwill be IRREVOCABLY ERASED!\n\nAre you ABSOLUTELY "
205               "SURE you wish to take this action?  This is your "
206               "LAST CHANCE to cancel!"), disk_get_desc(storage_get_selected_disk(a->s)))) {
207                     cmds = commands_new();
208 
209                     command_add(cmds,
210                         "%s%s if=/dev/zero of=/dev/%s bs=32k count=16",
211                         a->os_root, cmd_name(a, "DD"),
212                         disk_get_device_name(storage_get_selected_disk(a->s)));
213                     command_add(cmds, "%s%s -BI %s",
214                         a->os_root, cmd_name(a, "FDISK"),
215                         disk_get_device_name(storage_get_selected_disk(a->s)));
216 
217                     if (!commands_execute(a, cmds)) {
218                               inform(a->c, _("The disk\n\n%s\n\nwas "
219                                   "not correctly formatted, and may "
220                                   "now be in an inconsistent state. "
221                                   "We recommend re-formatting it "
222                                   "before attempting to install "
223                                   "%s on it."),
224                                   disk_get_desc(storage_get_selected_disk(a->s)),
225                                   OPERATING_SYSTEM_NAME);
226                               commands_free(cmds);
227                               a->result = 0;
228                               return;
229                     }
230                     commands_free(cmds);
231 
232                     /*
233                      * Since one of the disks has now changed, we must
234                      * refresh our view of them and re-select the disk
235                      * since the selected_disk pointer will be invalidated.
236                      */
237                     selected_disk_string = aura_strdup(
238                         disk_get_device_name(storage_get_selected_disk(a->s)));
239                     if (!survey_storage(a)) {
240                               inform(a->c, _("Errors occurred while probing "
241                                   "the system for its storage capabilities."));
242                     }
243                     storage_set_selected_disk(a->s, disk_find(a->s, selected_disk_string));
244                     free(selected_disk_string);
245 
246                     /*
247                      * Note that we formatted this disk and that we want
248                      * to use the first (and only) slice of it.
249                      */
250                     disk_set_formatted(storage_get_selected_disk(a->s), 1);
251                     storage_set_selected_slice(a->s, disk_slice_first(storage_get_selected_disk(a->s)));
252 
253                     if (!format_slice(a)) {
254                               inform(a->c, _("The sole primary partition of "
255                                   "the disk\n\n%s\n\nwas "
256                                   "not correctly formatted, and may "
257                                   "now be in an inconsistent state. "
258                                   "We recommend re-formatting the "
259                                   "disk before attempting to install "
260                                   "%s on it."),
261                                   disk_get_desc(storage_get_selected_disk(a->s)),
262                                   OPERATING_SYSTEM_NAME);
263                               a->result = 0;
264                               return;
265                     }
266                     inform(a->c, _("The disk\n\n%s\n\nwas formatted."),
267                         disk_get_desc(storage_get_selected_disk(a->s)));
268                     a->result = 1;
269           } else {
270                     inform(a->c, _("Action cancelled - no disks were formatted."));
271                     a->result = 0;
272           }
273 }
274 
275 void
fn_format_disk_uefi(struct i_fn_args * a)276 fn_format_disk_uefi(struct i_fn_args *a)
277 {
278           struct commands *cmds;
279           char *selected_disk_string;
280 
281           if (storage_get_selected_disk(a->s) == NULL) {
282                     a->short_desc = _("Select a disk to format.");
283                     a->cancel_desc = _("Return to Utilities Menu");
284                     fn_select_disk(a);
285                     if (!a->result || storage_get_selected_disk(a->s) == NULL) {
286                               a->result = 0;
287                               return;
288                     }
289           }
290 
291           if (confirm_dangerous_action(a->c,
292               _("WARNING!  ALL data in ALL partitions on the disk\n\n"
293               "%s\n\nwill be IRREVOCABLY ERASED!\n\nAre you ABSOLUTELY "
294               "SURE you wish to take this action?  This is your "
295               "LAST CHANCE to cancel!"), disk_get_desc(storage_get_selected_disk(a->s)))) {
296                     cmds = commands_new();
297 
298                     command_add(cmds,
299                         "%s%s if=/dev/zero of=/dev/%s bs=32k count=16",
300                         a->os_root, cmd_name(a, "DD"),
301                         disk_get_device_name(storage_get_selected_disk(a->s)));
302                     command_add(cmds, "%s%s destroy %s",
303                         a->os_root, cmd_name(a, "GPT"),
304                         disk_get_device_name(storage_get_selected_disk(a->s)));
305                     command_add(cmds, "%s%s create -f %s",
306                         a->os_root, cmd_name(a, "GPT"),
307                         disk_get_device_name(storage_get_selected_disk(a->s)));
308                     command_add(cmds, "%s%s add -i 0 -s 262144 -t efi %s",
309                         a->os_root, cmd_name(a, "GPT"),
310                         disk_get_device_name(storage_get_selected_disk(a->s)));
311                     command_add(cmds, "%s%s add -i 1 -t dragonfly %s",
312                         a->os_root, cmd_name(a, "GPT"),
313                         disk_get_device_name(storage_get_selected_disk(a->s)));
314                     command_add(cmds, "%s%s -F 32 -c 2 -L EFI -m 0xf8 %ss0",
315                         a->os_root, cmd_name(a, "NEWFS_MSDOS"),
316                         disk_get_device_name(storage_get_selected_disk(a->s)));
317                     command_add(cmds, "%s%s /dev/%ss0 %smnt",
318                         a->os_root, cmd_name(a, "MOUNT_MSDOS"),
319                         disk_get_device_name(storage_get_selected_disk(a->s)),
320                         a->os_root);
321                     command_add(cmds, "%s%s -p %smnt/EFI/BOOT",
322                         a->os_root, cmd_name(a, "MKDIR"), a->os_root);
323                     command_add(cmds,
324                         "%s%s %s/boot/boot1.efi %smnt/EFI/BOOT/BOOTX64.EFI",
325                         a->os_root, cmd_name(a, "CP"),
326                         a->os_root, a->os_root);
327                     command_add(cmds, "%s%s %smnt",
328                         a->os_root, cmd_name(a, "UMOUNT"), a->os_root);
329 
330                     if (!commands_execute(a, cmds)) {
331                               inform(a->c, _("The disk\n\n%s\n\nwas "
332                                   "not correctly formatted, and may "
333                                   "now be in an inconsistent state. "
334                                   "We recommend re-formatting it "
335                                   "before attempting to install "
336                                   "%s on it."),
337                                   disk_get_desc(storage_get_selected_disk(a->s)),
338                                   OPERATING_SYSTEM_NAME);
339                               commands_free(cmds);
340                               a->result = 0;
341                               return;
342                     }
343                     commands_free(cmds);
344 
345                     /*
346                      * Since one of the disks has now changed, we must
347                      * refresh our view of them and re-select the disk
348                      * since the selected_disk pointer will be invalidated.
349                      */
350                     selected_disk_string = aura_strdup(
351                         disk_get_device_name(storage_get_selected_disk(a->s)));
352                     if (!survey_storage(a)) {
353                               inform(a->c, _("Errors occurred while probing "
354                                   "the system for its storage capabilities."));
355                     }
356                     storage_set_selected_disk(a->s,
357                         disk_find(a->s, selected_disk_string));
358                     free(selected_disk_string);
359 
360                     /*
361                      * Note that we formatted this disk and that we want
362                      * to use the first (and only) slice of it.
363                      */
364                     disk_set_formatted(storage_get_selected_disk(a->s), 1);
365                     storage_set_selected_slice(a->s,
366                         disk_slice_first(storage_get_selected_disk(a->s)));
367 
368                     inform(a->c, _("The disk\n\n%s\n\nwas formatted."),
369                         disk_get_desc(storage_get_selected_disk(a->s)));
370                     a->result = 1;
371           } else {
372                     inform(a->c, _("Action cancelled - no disks were formatted."));
373                     a->result = 0;
374           }
375 }
376 
377 /*
378  * Wipes the start of the selected disk.
379  */
380 void
fn_wipe_start_of_disk(struct i_fn_args * a)381 fn_wipe_start_of_disk(struct i_fn_args *a)
382 {
383           struct commands *cmds;
384 
385           a->short_desc = _("If you are having problems formatting a disk, "
386               "it may be because of junk that has accumulated "
387               "in the boot block and the partition table. "
388               "A cure for this is to wipe out everything on "
389               "the first few sectors of the disk.  However, this "
390               "is a rather drastic action to take, so it is not "
391               "recommended unless you are otherwise "
392               "encountering problems.");
393           a->cancel_desc = _("Return to Utilities Menu");
394           fn_select_disk(a);
395           if (!a->result)
396                     return;
397 
398           /* XXX check to make sure no slices on this disk are mounted first? */
399           if (storage_get_selected_disk(a->s) != NULL && confirm_dangerous_action(a->c,
400               _("WARNING!  ALL data in ALL partitions on the disk\n\n"
401               "%s\n\nwill be IRREVOCABLY ERASED!\n\nAre you ABSOLUTELY "
402               "SURE you wish to take this action?  This is your "
403               "LAST CHANCE to cancel!"), disk_get_desc(storage_get_selected_disk(a->s)))) {
404                     cmds = commands_new();
405                     command_add(cmds,
406                         "%s%s if=/dev/zero of=/dev/%s bs=32k count=16",
407                         a->os_root, cmd_name(a, "DD"),
408                         disk_get_device_name(storage_get_selected_disk(a->s)));
409                     if (commands_execute(a, cmds)) {
410                               inform(a->c, _("Start of disk was successfully wiped."));
411                     } else {
412                               inform(a->c, _("Some errors occurred. "
413                                   "Start of disk was not successfully wiped."));
414                     }
415                     commands_free(cmds);
416           }
417 }
418 
419 /*
420  * Wipes the start of the selected slice.
421  */
422 void
fn_wipe_start_of_slice(struct i_fn_args * a)423 fn_wipe_start_of_slice(struct i_fn_args *a)
424 {
425           struct commands *cmds;
426 
427           a->short_desc =
428             _("If you are having problems formatting a primary partition, "
429               "it may be because of junk that has accumulated in the "
430               "partition's `disklabel'. A cure for this is to wipe out "
431               "everything on the first few sectors of the primary partition. "
432               "However, this is a rather drastic action to take, so it is not "
433               "recommended unless you are otherwise encountering problems.");
434           a->cancel_desc = _("Return to Utilities Menu");
435           fn_select_slice(a);
436           if (!a->result)
437                     return;
438 
439           if (confirm_dangerous_action(a->c,
440               _("WARNING!  ALL data in primary partition #%d,\n\n%s\n\non the "
441               "disk\n\n%s\n\n will be IRREVOCABLY ERASED!\n\nAre you "
442               "ABSOLUTELY SURE you wish to take this action?  This is "
443               "your LAST CHANCE to cancel!"),
444               slice_get_number(storage_get_selected_slice(a->s)),
445               slice_get_desc(storage_get_selected_slice(a->s)),
446               disk_get_desc(storage_get_selected_disk(a->s)))) {
447                     /* XXX check to make sure this slice is not mounted first */
448                     cmds = commands_new();
449                     command_add(cmds, "%s%s if=/dev/zero of=/dev/%s bs=32k count=16",
450                         a->os_root, cmd_name(a, "DD"),
451                         slice_get_device_name(storage_get_selected_slice(a->s)));
452                     if (commands_execute(a, cmds)) {
453                               inform(a->c, _("Start of primary partition was successfully wiped."));
454                     } else {
455                               inform(a->c, _("Some errors occurred. "
456                                   "Start of primary partition was not successfully wiped."));
457                     }
458                     commands_free(cmds);
459           }
460 }
461 
462 static void
ask_to_wipe_boot_sector(struct i_fn_args * a,struct commands * fcmds)463 ask_to_wipe_boot_sector(struct i_fn_args *a, struct commands *fcmds)
464 {
465           struct commands *cmds;
466           struct command *cmd;
467           char *disk;
468 
469           for (cmd = command_get_first(fcmds); cmd != NULL;
470                cmd = command_get_next(cmd)) {
471                     disk = command_get_tag(cmd);
472                     if (disk != NULL &&
473                         command_get_result(cmd) > 0 &&
474                         command_get_result(cmd) < 256) {
475                               switch (dfui_be_present_dialog(a->c,
476                                   _("Bootblock Install Failed"),
477                                   _("Re-Initialize Bootblock|Cancel"),
478                                   _("Warning: bootblocks were not successfully "
479                                   "installed on the disk `%s'. This may be "
480                                   "because the disk is new and not yet "
481                                   "formatted. If this is the case, it might "
482                                   "help to re-initialize the boot sector, "
483                                   "then try installing the bootblock again. "
484                                   "Note that this should not affect the "
485                                   "partition table of the disk."),
486                                   disk)) {
487                               case 1:
488                                         cmds = commands_new();
489                                         command_add(cmds,
490                                             "%s%s | %s%s -B /dev/%s",
491                                             a->os_root, cmd_name(a, "YES"),
492                                             a->os_root, cmd_name(a, "FDISK"),
493                                             disk);
494                                         if (commands_execute(a, cmds)) {
495                                                   inform(a->c, _("Boot sector successfully initialized."));
496                                         } else {
497                                                   inform(a->c, _("Some errors occurred. "
498                                                       "Boot sector was not successfully initialized."));
499                                         }
500                                         commands_free(cmds);
501                                         break;
502                               default:
503                                         break;
504                               }
505                     }
506           }
507 }
508 
509 void
fn_install_bootblocks(struct i_fn_args * a,const char * device)510 fn_install_bootblocks(struct i_fn_args *a, const char *device)
511 {
512           struct dfui_form *f;
513           struct dfui_response *r;
514           struct dfui_dataset *ds;
515           struct disk *d;
516           struct commands *cmds;
517           struct command *cmd;
518           char disk[64], boot0cfg[32], packet[32];
519           char msg_buf[1][1024];
520 
521           snprintf(msg_buf[0], sizeof(msg_buf[0]),
522               "'Packet Mode' refers to using newer BIOS calls to boot "
523               "from a partition of the disk.  It is generally not "
524               "required unless:\n\n"
525               "- your BIOS does not support legacy mode; or\n"
526               "- your %s primary partition resides on a "
527               "cylinder of the disk beyond cylinder 1024; or\n"
528               "- you just can't get it to boot without it.",
529               OPERATING_SYSTEM_NAME);
530 
531           f = dfui_form_create(
532               "install_bootstrap",
533               _("Install Bootblock(s)"),
534               a->short_desc,
535 
536               msg_buf[0],
537 
538               "p", "special", "dfinstaller_install_bootstrap",
539 
540               "f", "disk", _("Disk Drive"),
541               _("The disk on which you wish to install a bootblock"), "",
542               "p", "editable", "false",
543               "f", "boot0cfg", _("Install Bootblock?"),
544               _("Install a bootblock on this disk"), "",
545               "p", "control", "checkbox",
546               "f", "packet", _("Packet Mode?"),
547               _("Select this to use 'packet mode' to boot the disk"), "",
548               "p", "control", "checkbox",
549 
550               "a", "ok", _("Accept and Install Bootblocks"), "", "",
551               "a", "cancel", a->cancel_desc, "", "",
552               "p", "accelerator", "ESC",
553 
554               NULL
555           );
556 
557           dfui_form_set_multiple(f, 1);
558 
559           if (device != NULL) {
560                     ds = dfui_dataset_new();
561                     dfui_dataset_celldata_add(ds, "disk", device);
562                     dfui_dataset_celldata_add(ds, "boot0cfg", "Y");
563                     dfui_dataset_celldata_add(ds, "packet", "Y");
564                     dfui_form_dataset_add(f, ds);
565           } else {
566                     for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d)) {
567                               ds = dfui_dataset_new();
568                               dfui_dataset_celldata_add(ds, "disk",
569                                   disk_get_device_name(d));
570                               dfui_dataset_celldata_add(ds, "boot0cfg", "Y");
571                               dfui_dataset_celldata_add(ds, "packet", "Y");
572                               dfui_form_dataset_add(f, ds);
573                     }
574           }
575 
576           if (!dfui_be_present(a->c, f, &r))
577                     abort_backend();
578 
579           a->result = 0;
580           if (strcmp(dfui_response_get_action_id(r), "ok") == 0) {
581                     cmds = commands_new();
582 
583                     for (ds = dfui_response_dataset_get_first(r); ds != NULL;
584                          ds = dfui_dataset_get_next(ds)) {
585                               strlcpy(disk, dfui_dataset_get_value(ds, "disk"), 64);
586                               strlcpy(boot0cfg, dfui_dataset_get_value(ds, "boot0cfg"), 32);
587                               strlcpy(packet, dfui_dataset_get_value(ds, "packet"), 32);
588 
589                               if (strcasecmp(boot0cfg, "Y") == 0) {
590                                         cmd = command_add(cmds, "%s%s -B -o %spacket %s",
591                                             a->os_root, cmd_name(a, "BOOT0CFG"),
592                                             strcasecmp(packet, "Y") == 0 ? "" : "no",
593                                             disk);
594                                         command_set_failure_mode(cmd, COMMAND_FAILURE_WARN);
595                                         command_set_tag(cmd, "%s", disk);
596                                         cmd = command_add(cmds, "%s%s -v %s",
597                                             a->os_root, cmd_name(a, "BOOT0CFG"),
598                                             disk);
599                                         command_set_failure_mode(cmd, COMMAND_FAILURE_WARN);
600                                         command_set_tag(cmd, "%s", disk);
601                               }
602                     }
603 
604                     if (!commands_execute(a, cmds)) {
605                               ask_to_wipe_boot_sector(a, cmds);
606                     } else {
607                               inform(a->c, _("Bootblocks were successfully installed!"));
608                               a->result = 1;
609                     }
610                     commands_free(cmds);
611           }
612 
613           dfui_form_free(f);
614           dfui_response_free(r);
615 }
616 
617 void
fn_format_msdos_floppy(struct i_fn_args * a)618 fn_format_msdos_floppy(struct i_fn_args *a)
619 {
620           struct commands *cmds;
621 
622           switch (dfui_be_present_dialog(a->c, _("Format MSDOS Floppy"),
623               _("Format Floppy|Return to Utilities Menu"),
624               _("Please insert the floppy to be formatted "
625               "in unit 0 (``drive A:'')."))) {
626           case 1:
627                     cmds = commands_new();
628                     command_add(cmds, "%s%s -y -f 1440 /dev/fd0",
629                         a->os_root, cmd_name(a, "FDFORMAT"));
630                     command_add(cmds, "%s%s -f 1440 fd0",
631                         a->os_root, cmd_name(a, "NEWFS_MSDOS"));
632                     if (commands_execute(a, cmds))
633                               inform(a->c, _("Floppy successfully formatted!"));
634                     else
635                               inform(a->c, _("Floppy was not successfully formatted."));
636                     break;
637           case 2:
638                     return;
639           default:
640                     abort_backend();
641           }
642 }
643 
644 void
fn_create_cdboot_floppy(struct i_fn_args * a)645 fn_create_cdboot_floppy(struct i_fn_args *a)
646 {
647           struct commands *cmds;
648           char msg_buf[1][1024];
649 
650           snprintf(msg_buf[0], sizeof(msg_buf[0]),
651               "%s cannot be installed from a floppy; "
652               "it must be installed from a booted CD-ROM. "
653               "However, many older systems do not support booting "
654               "from a CD-ROM. For these systems, a boot disk can be "
655               "created. This boot disk contains the Smart Boot "
656               "Manager program, which can boot a CD-ROM even "
657               "on systems with BIOSes which do not support booting "
658               "from the CD-ROM.\n\n"
659               "Smart Boot Manager is not a part of %s; "
660               "the Smart Boot Manager project can be found here:\n\n"
661               "http://btmgr.sourceforge.net/\n\n"
662               "To create a CDBoot floppy, insert a blank floppy "
663               "in unit 0 (``drive A:'') before proceeding."
664               "",
665               OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME);
666 
667           switch (dfui_be_present_dialog(a->c, _("Create CDBoot Floppy"),
668               _("Create CDBoot Floppy|Return to Utilities Menu"),
669               "%s", msg_buf[0])) {
670           case 1:
671                     cmds = commands_new();
672                     command_add(cmds, "%s%s -c %sboot/cdboot.flp.bz2 | "
673                         "%s%s of=/dev/fd0 bs=32k",
674                         a->os_root, cmd_name(a, "BUNZIP2"),
675                         a->os_root,
676                         a->os_root, cmd_name(a, "DD"));
677                     if (commands_execute(a, cmds))
678                               inform(a->c, _("CDBoot floppy successfully created!"));
679                     else
680                               inform(a->c, _("CDBoot floppy was not successfully created."));
681                     break;
682           case 2:
683                     return;
684           default:
685                     abort_backend();
686           }
687 }
688 
689 /**** NON-fn_ FUNCTIONS ***/
690 
691 int
format_slice(struct i_fn_args * a)692 format_slice(struct i_fn_args *a)
693 {
694           struct commands *cmds;
695           struct command *cmd;
696           int result;
697           int cyl, hd, sec;
698 
699           cmds = commands_new();
700 
701           /*
702            * The information in a->s NEEDS to be accurate here!
703            * Presumably we just did a survey_storage() recently.
704            * XXX should we do another one here anyway just to be paranoid?
705            */
706 
707           /*
708            * Make sure the survey did get disk info correctly or fail
709            */
710           if ((storage_get_selected_disk(a->s) == NULL) ||
711               (storage_get_selected_slice(a->s) == NULL))
712                     return 0;
713 
714           /*
715            * Set the slice's sysid to 108.
716            */
717           disk_get_geometry(storage_get_selected_disk(a->s), &cyl, &hd, &sec);
718           command_add(cmds, "%s%s 'g c%d h%d s%d' >%snew.fdisk",
719               a->os_root, cmd_name(a, "ECHO"),
720               cyl, hd, sec,
721               a->tmp);
722           command_add(cmds, "%s%s 'p %d %d %lu %lu' >>%snew.fdisk",
723               a->os_root, cmd_name(a, "ECHO"),
724               slice_get_number(storage_get_selected_slice(a->s)),
725               DOSPTYP_DFLYBSD,
726               slice_get_start(storage_get_selected_slice(a->s)),
727               slice_get_size(storage_get_selected_slice(a->s)),
728               a->tmp);
729           if (slice_get_flags(storage_get_selected_slice(a->s)) & 0x80) {
730                     command_add(cmds, "%s%s 'a %d' >>%snew.fdisk",
731                         a->os_root, cmd_name(a, "ECHO"),
732                         slice_get_number(storage_get_selected_slice(a->s)),
733                         a->tmp);
734           }
735 
736           command_add(cmds, "%s%s %snew.fdisk",
737               a->os_root, cmd_name(a, "CAT"), a->tmp);
738           temp_file_add(a, "new.fdisk");
739 
740           /*
741            * Execute the fdisk script.
742            */
743           cmd = command_add(cmds, "%s%s -v -f %snew.fdisk %s",
744               a->os_root, cmd_name(a, "FDISK"), a->tmp,
745               disk_get_device_name(storage_get_selected_disk(a->s)));
746           if (slice_get_size(storage_get_selected_slice(a->s)) == 0xFFFFFFFFU)
747                     command_set_failure_mode(cmd, COMMAND_FAILURE_IGNORE);
748 
749           /*
750            * If there is an old 'virgin' disklabel hanging around
751            * in the temp dir, get rid of it.  This won't happen
752            * from a real CD, but might happen with '-o' installs.
753            */
754           command_add(cmds, "%s%s -f %sinstall.disklabel.%s",
755               a->os_root, cmd_name(a, "RM"),
756               a->tmp,
757               slice_get_device_name(storage_get_selected_slice(a->s)));
758 
759           result = commands_execute(a, cmds);
760 
761           commands_free(cmds);
762 
763           return(result);
764 }
765