Commit | Line | Data |
---|---|---|
337ad0df DH |
1 | /* |
2 | * Copyright (c)2004 The DragonFly Project. All rights reserved. | |
21c1c48a | 3 | * |
337ad0df DH |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions | |
6 | * are met: | |
21c1c48a | 7 | * |
337ad0df DH |
8 | * Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. | |
21c1c48a | 10 | * |
337ad0df DH |
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. | |
21c1c48a | 15 | * |
337ad0df DH |
16 | * Neither the name of the DragonFly Project nor the names of its |
17 | * contributors may be used to endorse or promote products derived | |
21c1c48a SW |
18 | * from this software without specific prior written permission. |
19 | * | |
337ad0df DH |
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 | |
21c1c48a | 31 | * OF THE POSSIBILITY OF SUCH DAMAGE. |
337ad0df DH |
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 | ||
8e693f3b SW |
40 | #include <sys/diskmbr.h> |
41 | ||
337ad0df | 42 | #include <stdlib.h> |
a07abcb9 | 43 | #include <unistd.h> |
337ad0df DH |
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 | ||
bc3d4063 SW |
53 | #include "libaura/mem.h" |
54 | #include "libaura/fspred.h" | |
337ad0df | 55 | |
bc3d4063 SW |
56 | #include "libdfui/dfui.h" |
57 | #include "libdfui/system.h" | |
337ad0df | 58 | |
bc3d4063 SW |
59 | #include "libinstaller/commands.h" |
60 | #include "libinstaller/diskutil.h" | |
61 | #include "libinstaller/functions.h" | |
62 | #include "libinstaller/uiutil.h" | |
337ad0df DH |
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 | |
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 | |
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 | |
7b1aa074 | 187 | fn_format_disk_mbr(struct i_fn_args *a) |
337ad0df DH |
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(); | |
21c1c48a | 208 | |
8afa51ff SW |
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))); | |
53068545 SW |
213 | command_add(cmds, "%s%s -BI %s", |
214 | a->os_root, cmd_name(a, "FDISK"), | |
f59b7dfa | 215 | disk_get_device_name(storage_get_selected_disk(a->s))); |
337ad0df | 216 | |
337ad0df DH |
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 | } | |
337ad0df DH |
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 | ||
7b1aa074 SW |
275 | void |
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 | ||
337ad0df DH |
377 | /* |
378 | * Wipes the start of the selected disk. | |
379 | */ | |
380 | void | |
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, | |
51871435 | 406 | "%s%s if=/dev/zero of=/dev/%s bs=32k count=16", |
337ad0df | 407 | a->os_root, cmd_name(a, "DD"), |
f59b7dfa | 408 | disk_get_device_name(storage_get_selected_disk(a->s))); |
337ad0df DH |
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 | |
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(); | |
51871435 | 449 | command_add(cmds, "%s%s if=/dev/zero of=/dev/%s bs=32k count=16", |
337ad0df | 450 | a->os_root, cmd_name(a, "DD"), |
f59b7dfa | 451 | slice_get_device_name(storage_get_selected_slice(a->s))); |
337ad0df DH |
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 | |
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."), | |
59b733d3 | 486 | disk)) { |
337ad0df DH |
487 | case 1: |
488 | cmds = commands_new(); | |
489 | command_add(cmds, | |
51871435 | 490 | "%s%s | %s%s -B /dev/%s", |
337ad0df DH |
491 | a->os_root, cmd_name(a, "YES"), |
492 | a->os_root, cmd_name(a, "FDISK"), | |
51871435 | 493 | disk); |
337ad0df DH |
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 | |
e75c9034 | 510 | fn_install_bootblocks(struct i_fn_args *a, const char *device) |
337ad0df DH |
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", | |
21c1c48a | 549 | |
337ad0df | 550 | "a", "ok", _("Accept and Install Bootblocks"), "", "", |
21c1c48a | 551 | "a", "cancel", a->cancel_desc, "", "", |
337ad0df DH |
552 | "p", "accelerator", "ESC", |
553 | ||
554 | NULL | |
555 | ); | |
556 | ||
557 | dfui_form_set_multiple(f, 1); | |
558 | ||
e75c9034 | 559 | if (device != NULL) { |
337ad0df | 560 | ds = dfui_dataset_new(); |
e75c9034 | 561 | dfui_dataset_celldata_add(ds, "disk", device); |
337ad0df | 562 | dfui_dataset_celldata_add(ds, "boot0cfg", "Y"); |
341279be | 563 | dfui_dataset_celldata_add(ds, "packet", "Y"); |
337ad0df | 564 | dfui_form_dataset_add(f, ds); |
e75c9034 SW |
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 | } | |
337ad0df DH |
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) { | |
9771f11c | 590 | cmd = command_add(cmds, "%s%s -B -o %spacket %s", |
337ad0df | 591 | a->os_root, cmd_name(a, "BOOT0CFG"), |
341279be | 592 | strcasecmp(packet, "Y") == 0 ? "" : "no", |
337ad0df DH |
593 | disk); |
594 | command_set_failure_mode(cmd, COMMAND_FAILURE_WARN); | |
9462167a | 595 | command_set_tag(cmd, "%s", disk); |
337ad0df DH |
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); | |
9462167a | 600 | command_set_tag(cmd, "%s", disk); |
337ad0df DH |
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 | |
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 | |
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"), | |
9462167a | 669 | "%s", msg_buf[0])) { |
337ad0df DH |
670 | case 1: |
671 | cmds = commands_new(); | |
672 | command_add(cmds, "%s%s -c %sboot/cdboot.flp.bz2 | " | |
51871435 | 673 | "%s%s of=/dev/fd0 bs=32k", |
337ad0df DH |
674 | a->os_root, cmd_name(a, "BUNZIP2"), |
675 | a->os_root, | |
51871435 | 676 | a->os_root, cmd_name(a, "DD")); |
337ad0df DH |
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 | ||
337ad0df DH |
689 | /**** NON-fn_ FUNCTIONS ***/ |
690 | ||
691 | int | |
692 | format_slice(struct i_fn_args *a) | |
693 | { | |
694 | struct commands *cmds; | |
a096577d | 695 | struct command *cmd; |
337ad0df DH |
696 | int result; |
697 | int cyl, hd, sec; | |
698 | ||
699 | cmds = commands_new(); | |
700 | ||
337ad0df DH |
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 | ||
83c251b0 AHJ |
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 | ||
337ad0df | 714 | /* |
7d89978d | 715 | * Set the slice's sysid to 108. |
337ad0df DH |
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)), | |
8e693f3b | 725 | DOSPTYP_DFLYBSD, |
337ad0df DH |
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 | */ | |
a096577d | 743 | cmd = command_add(cmds, "%s%s -v -f %snew.fdisk %s", |
337ad0df | 744 | a->os_root, cmd_name(a, "FDISK"), a->tmp, |
f59b7dfa | 745 | disk_get_device_name(storage_get_selected_disk(a->s))); |
a096577d SW |
746 | if (slice_get_size(storage_get_selected_slice(a->s)) == 0xFFFFFFFFU) |
747 | command_set_failure_mode(cmd, COMMAND_FAILURE_IGNORE); | |
337ad0df | 748 | |
337ad0df DH |
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 | } |