2 * The new sysinstall program.
4 * This is probably the last program in the `sysinstall' line - the next
5 * generation being essentially a complete rewrite.
10 * Jordan Hubbard. All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer,
17 * verbatim and that no modifications are made prior to this
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
23 * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include "sysinstall.h"
41 #include <sys/disklabel.h>
43 enum size_units_t { UNIT_BLOCKS, UNIT_KILO, UNIT_MEG, UNIT_SIZE };
46 #define SUBTYPE_FREEBSD 50324
47 #define SUBTYPE_FAT 37218
49 #define SUBTYPE_FREEBSD 165
52 #define SUBTYPE_EFI 239
54 /* Where we start displaying chunk information on the screen */
55 #define CHUNK_START_ROW 5
57 /* Where we keep track of MBR chunks */
58 static struct chunk *chunk_info[16];
59 static int current_chunk;
61 static void diskPartitionNonInteractive(Device *dev);
62 static u_char * bootalloc(char *name, size_t *size);
65 record_chunks(Disk *d)
67 struct chunk *c1 = NULL;
72 msgFatal("No chunk list found for %s!", d->name);
74 for (c1 = d->chunks->part; c1; c1 = c1->next) {
75 if (c1->type == unused && c1->size > last_free) {
82 if (current_chunk >= i)
83 current_chunk = i - 1;
89 print_chunks(Disk *d, int u)
96 szstr = (u == UNIT_MEG ? "MB" : (u == UNIT_KILO ? "KB" : "ST"));
98 for (i = Total = 0; chunk_info[i]; i++)
99 Total += chunk_info[i]->size;
101 if (d->bios_cyl >= 65536 || d->bios_hd > 16 || d->bios_sect >= 256) {
103 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64) {
105 dialog_clear_norefresh();
106 msgConfirm("WARNING: A geometry of %lu/%lu/%lu for %s is incorrect. Using\n"
107 "a more likely geometry. If this geometry is incorrect or you\n"
108 "are unsure as to whether or not it's correct, please consult\n"
109 "the Hardware Guide in the Documentation submenu or use the\n"
110 "(G)eometry command to change it now.\n\n"
111 "Remember: you need to enter whatever your BIOS thinks the\n"
112 "geometry is! For IDE, it's what you were told in the BIOS\n"
113 "setup. For SCSI, it's the translation mode your controller is\n"
114 "using. Do NOT use a ``physical geometry''.",
115 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
116 Sanitize_Bios_Geom(d);
119 mvaddstr(0, 0, "Disk name:\t");
121 attrset(A_REVERSE); addstr(d->name); attrset(A_NORMAL);
122 attrset(A_REVERSE); mvaddstr(0, 55, "FDISK Partition Editor"); attrset(A_NORMAL);
124 "DISK Geometry:\t%lu cyls/%lu heads/%lu sectors = %lu sectors (%luMB)",
125 d->bios_cyl, d->bios_hd, d->bios_sect,
126 d->bios_cyl * d->bios_hd * d->bios_sect,
127 d->bios_cyl * d->bios_hd * d->bios_sect / (1024/512) / 1024);
128 mvprintw(3, 0, "%6s %10s(%s) %10s %8s %6s %10s %8s %8s",
129 "Offset", "Size", szstr, "End", "Name", "PType", "Desc",
131 for (i = 0, row = CHUNK_START_ROW; chunk_info[i]; i++, row++) {
133 default: /* fall thru */
135 sz = chunk_info[i]->size;
138 sz = chunk_info[i]->size / (1024/512);
141 sz = chunk_info[i]->size / (1024/512) / 1024;
144 if (i == current_chunk)
145 attrset(ATTR_SELECTED);
146 mvprintw(row, 0, "%10ld %10lu %10lu %8s %6d %10s %8d\t%-6s",
147 chunk_info[i]->offset, sz,
148 chunk_info[i]->end, chunk_info[i]->name,
150 slice_type_name(chunk_info[i]->type, chunk_info[i]->subtype),
151 chunk_info[i]->subtype, ShowChunkFlags(chunk_info[i]));
152 if (i == current_chunk)
158 print_command_summary()
160 mvprintw(14, 0, "The following commands are supported (in upper or lower case):");
161 mvprintw(16, 0, "A = Use Entire Disk G = set Drive Geometry C = Create Slice F = `DD' mode");
162 mvprintw(17, 0, "D = Delete Slice Z = Toggle Size Units S = Set Bootable | = Wizard m.");
163 mvprintw(18, 0, "T = Change Type U = Undo All Changes Q = Finish");
165 mvprintw(18, 47, "W = Write Changes");
166 mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to select.");
172 getBootMgr(char *dname, u_char **bootipl, size_t *bootipl_size,
173 u_char **bootmenu, size_t *bootmenu_size)
175 static u_char *boot0;
176 static size_t boot0_size;
177 static u_char *boot05;
178 static size_t boot05_size;
184 cp = variable_get(VAR_BOOTMGR);
186 /* Figure out what kind of IPL the user wants */
187 sprintf(str, "Install Boot Manager for drive %s?", dname);
188 MenuIPLType.title = str;
189 i = dmenuOpenSimple(&MenuIPLType, FALSE);
191 if (!strncmp(cp, "boot", 4))
199 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
201 *bootipl_size = boot0_size;
202 if (!boot05) boot05 = bootalloc("boot0.5", &boot05_size);
204 *bootmenu_size = boot05_size;
218 getBootMgr(char *dname, u_char **bootCode, size_t *bootCodeSize)
220 #ifdef __i386__ /* only meaningful on x86 */
221 static u_char *mbr, *boot0;
222 static size_t mbr_size, boot0_size;
227 cp = variable_get(VAR_BOOTMGR);
229 /* Figure out what kind of MBR the user wants */
230 sprintf(str, "Install Boot Manager for drive %s?", dname);
231 MenuMBRType.title = str;
232 i = dmenuOpenSimple(&MenuMBRType, FALSE);
235 if (!strncmp(cp, "boot", 4))
237 else if (!strcmp(cp, "standard"))
245 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
247 *bootCodeSize = boot0_size;
250 if (!mbr) mbr = bootalloc("mbr", &mbr_size);
252 *bootCodeSize = mbr_size;
266 diskGetSelectCount(Device ***devs)
272 cp = variable_get(VAR_DISK);
273 dp = *devs = deviceFind(cp, DEVICE_TYPE_DISK);
274 cnt = deviceCount(dp);
277 for (i = 0, enabled = 0; i < cnt; i++) {
285 diskPartition(Device *dev)
295 size_t bootmenu_size;
300 WINDOW *w = savescr();
301 Disk *d = (Disk *)dev->private;
304 size_unit = UNIT_BLOCKS;
306 keypad(stdscr, TRUE);
308 /* Flush both the dialog and curses library views of the screen
309 since we don't always know who called us */
310 dialog_clear_norefresh(), clear();
313 /* Set up the chunk array */
317 char *val, geometry[80];
319 /* Now print our overall state */
321 print_chunks(d, size_unit);
322 print_command_summary();
324 attrset(title_attr); mvprintw(23, 0, msg); attrset(A_NORMAL);
333 /* Get command character */
335 switch (toupper(key)) {
336 case '\014': /* ^L (redraw) */
341 case '\020': /* ^P */
344 if (current_chunk != 0)
348 case '\016': /* ^N */
353 if (chunk_info[current_chunk + 1])
362 while (chunk_info[current_chunk + 1])
368 systemDisplayHelp("slice");
373 case 'F': /* Undocumented magic Dangerously Dedicated mode */
374 #if defined(__alpha__) || defined(__sparc64__)
376 #else /* The rest is only relevant on x86 */
377 cp = variable_get(VAR_DEDICATE_DISK);
378 if (cp && !strcasecmp(cp, "always"))
380 else if (toupper(key) == 'A')
383 rv = msgYesNo("Do you want to do this with a true partition entry\n"
384 "so as to remain cooperative with any future possible\n"
385 "operating systems on the drive(s)?\n"
386 "(See also the section about ``dangerously dedicated''\n"
387 "disks in the FreeBSD FAQ.)");
393 variable_set2(DISK_PARTITIONED, "yes", 0);
399 if (chunk_info[current_chunk]->type != unused)
400 msg = "Slice in use, delete it first or move to an unused one.";
402 char *val, tmp[20], name[16], *cp;
404 chunk_e partitiontype;
406 snprintf(name, sizeof (name), "%s", "FreeBSD");
407 val = msgGetInput(name,
408 "Please specify the name for new FreeBSD slice.");
410 strncpy(name, val, sizeof (name));
414 snprintf(tmp, 20, "%lu", chunk_info[current_chunk]->size);
415 val = msgGetInput(tmp, "Please specify the size for new FreeBSD slice in blocks\n"
416 "or append a trailing `M' for megabytes (e.g. 20M).");
417 if (val && (size = strtol(val, &cp, 0)) > 0) {
418 if (*cp && toupper(*cp) == 'M')
420 else if (*cp && toupper(*cp) == 'G')
422 sprintf(tmp, "%d", SUBTYPE_FREEBSD);
424 val = msgGetInput(tmp, "Enter type of partition to create:\n\n"
425 "Pressing Enter will choose the default, a native FreeBSD\n"
426 "slice (type 50324). You can choose other types, 37218 for a\n"
427 "DOS partition, for example.\n\n"
428 "Note: If you choose a non-FreeBSD partition type, it will not\n"
429 "be formatted or otherwise prepared, it will simply reserve space\n"
430 "for you to use another tool, such as DOS FORMAT, to later format\n"
431 "and use the partition.");
433 val = msgGetInput(tmp, "Enter type of partition to create:\n\n"
434 "Pressing Enter will choose the default, a native FreeBSD\n"
435 "slice (type 165). You can choose other types, 6 for a\n"
436 "DOS partition or 131 for a Linux partition, for example.\n\n"
437 "Note: If you choose a non-FreeBSD partition type, it will not\n"
438 "be formatted or otherwise prepared, it will simply reserve space\n"
439 "for you to use another tool, such as DOS FORMAT, to later format\n"
440 "and use the partition.");
442 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
443 if (subtype == SUBTYPE_FREEBSD)
444 partitiontype = freebsd;
445 else if (subtype == SUBTYPE_FAT)
447 else if (subtype == SUBTYPE_EFI)
450 partitiontype = unknown;
451 #if defined(__alpha__) || defined(__sparc64__)
452 if (partitiontype == freebsd && size == chunk_info[current_chunk]->size)
456 Create_Chunk(d, chunk_info[current_chunk]->offset, size, partitiontype, subtype,
457 (chunk_info[current_chunk]->flags & CHUNK_ALIGN), name);
458 variable_set2(DISK_PARTITIONED, "yes", 0);
468 if (chunk_info[current_chunk]->type == unused)
469 msg = "Slice is already unused!";
471 Delete_Chunk(d, chunk_info[current_chunk]);
472 variable_set2(DISK_PARTITIONED, "yes", 0);
478 if (chunk_info[current_chunk]->type == unused)
479 msg = "Slice is currently unused (use create instead)";
483 chunk_e partitiontype;
485 sprintf(tmp, "%d", SUBTYPE_FREEBSD);
487 val = msgGetInput(tmp, "New partition type:\n\n"
488 "Pressing Enter will choose the default, a native FreeBSD\n"
489 "slice (type 50324). Other popular values are 37218 for\n"
490 "DOS FAT partition.\n\n"
491 "Note: If you choose a non-FreeBSD partition type, it will not\n"
492 "be formatted or otherwise prepared, it will simply reserve space\n"
493 "for you to use another tool, such as DOS format, to later format\n"
494 "and actually use the partition.");
496 val = msgGetInput(tmp, "New partition type:\n\n"
497 "Pressing Enter will choose the default, a native FreeBSD\n"
498 "slice (type 165). Other popular values are 6 for\n"
499 "DOS FAT partition, 131 for a Linux ext2fs partition or\n"
500 "130 for a Linux swap partition.\n\n"
501 "Note: If you choose a non-FreeBSD partition type, it will not\n"
502 "be formatted or otherwise prepared, it will simply reserve space\n"
503 "for you to use another tool, such as DOS format, to later format\n"
504 "and actually use the partition.");
506 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
507 if (subtype == SUBTYPE_FREEBSD)
508 partitiontype = freebsd;
509 else if (subtype == SUBTYPE_FAT)
511 else if (subtype == SUBTYPE_EFI)
514 partitiontype = unknown;
515 chunk_info[current_chunk]->type = partitiontype;
516 chunk_info[current_chunk]->subtype = subtype;
522 snprintf(geometry, 80, "%lu/%lu/%lu", d->bios_cyl, d->bios_hd, d->bios_sect);
523 val = msgGetInput(geometry, "Please specify the new geometry in cyl/hd/sect format.\n"
524 "Don't forget to use the two slash (/) separator characters!\n"
525 "It's not possible to parse the field without them.");
528 nc = strtol(val, &val, 0);
529 nh = strtol(val + 1, &val, 0);
530 ns = strtol(val + 1, 0, 0);
531 Set_Bios_Geom(d, nc, nh, ns);
538 chunk_info[current_chunk]->flags |= CHUNK_ACTIVE;
542 if (!variable_cmp(DISK_LABELLED, "written")) {
543 msgConfirm("You've already written this information out - you\n"
546 else if (!msgNoYes("Are you SURE you want to Undo everything?")) {
549 sstrncpy(cp, d->name, sizeof cp);
550 Free_Disk(dev->private);
553 msgConfirm("Can't reopen disk %s! Internal state is probably corrupted", cp);
555 variable_unset(DISK_PARTITIONED);
556 variable_unset(DISK_LABELLED);
564 if (!msgNoYes("WARNING: This should only be used when modifying an EXISTING\n"
565 "installation. If you are installing FreeBSD for the first time\n"
566 "then you should simply type Q when you're finished here and your\n"
567 "changes will be committed in one batch automatically at the end of\n"
568 "these questions. If you're adding a disk, you should NOT write\n"
569 "from this screen, you should do it from the label editor.\n\n"
570 "Are you absolutely sure you want to do this now?")) {
571 variable_set2(DISK_PARTITIONED, "yes", 0);
575 * Don't trash the IPL if the first (and therefore only) chunk
576 * is marked for a truly dedicated disk (i.e., the disklabel
577 * starts at sector 0), even in cases where the user has
578 * requested a FreeBSD Boot Manager -- both would be fatal in
582 * Don't offer to update the IPL on this disk if the first
583 * "real" chunk looks like a FreeBSD "all disk" partition,
584 * or the disk is entirely FreeBSD.
586 if ((d->chunks->part->type != freebsd) ||
587 (d->chunks->part->offset > 1))
588 getBootMgr(d->name, &bootipl, &bootipl_size,
589 &bootmenu, &bootmenu_size);
596 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
599 * Don't trash the MBR if the first (and therefore only) chunk
600 * is marked for a truly dedicated disk (i.e., the disklabel
601 * starts at sector 0), even in cases where the user has
602 * requested booteasy or a "standard" MBR -- both would be
603 * fatal in this case.
606 * Don't offer to update the MBR on this disk if the first
607 * "real" chunk looks like a FreeBSD "all disk" partition,
608 * or the disk is entirely FreeBSD.
610 if ((d->chunks->part->type != freebsd) ||
611 (d->chunks->part->offset > 1))
612 getBootMgr(d->name, &mbrContents, &mbrSize);
617 Set_Boot_Mgr(d, mbrContents, mbrSize);
620 if (DITEM_STATUS(diskPartitionWrite(NULL)) != DITEM_SUCCESS)
621 msgConfirm("Disk partition write returned an error status!");
623 msgConfirm("Wrote FDISK partition information out successfully.");
629 if (!msgNoYes("Are you SURE you want to go into Wizard mode?\n"
630 "No seat belts whatsoever are provided!")) {
634 variable_set2(DISK_PARTITIONED, "yes", 0);
638 msg = "Wise choice!";
642 case '\033': /* ESC */
647 * Don't trash the IPL if the first (and therefore only) chunk
648 * is marked for a truly dedicated disk (i.e., the disklabel
649 * starts at sector 0), even in cases where the user has requested
650 * a FreeBSD Boot Manager -- both would be fatal in this case.
653 * Don't offer to update the IPL on this disk if the first "real"
654 * chunk looks like a FreeBSD "all disk" partition, or the disk is
657 if ((d->chunks->part->type != freebsd) ||
658 (d->chunks->part->offset > 1)) {
659 if (variable_cmp(DISK_PARTITIONED, "written")) {
660 getBootMgr(d->name, &bootipl, &bootipl_size,
661 &bootmenu, &bootmenu_size);
662 if (bootipl != NULL && bootmenu != NULL)
663 Set_Boot_Mgr(d, bootipl, bootipl_size,
664 bootmenu, bootmenu_size);
669 * Don't trash the MBR if the first (and therefore only) chunk
670 * is marked for a truly dedicated disk (i.e., the disklabel
671 * starts at sector 0), even in cases where the user has requested
672 * booteasy or a "standard" MBR -- both would be fatal in this case.
675 * Don't offer to update the MBR on this disk if the first "real"
676 * chunk looks like a FreeBSD "all disk" partition, or the disk is
679 if ((d->chunks->part->type != freebsd) ||
680 (d->chunks->part->offset > 1)) {
681 if (variable_cmp(DISK_PARTITIONED, "written")) {
682 getBootMgr(d->name, &mbrContents, &mbrSize);
683 if (mbrContents != NULL)
684 Set_Boot_Mgr(d, mbrContents, mbrSize);
691 size_unit = (size_unit + 1) % UNIT_SIZE;
696 msg = "Type F1 or ? for help";
702 char buf[FILENAME_MAX];
704 use_helpline("Press F1 to read more about disk slices.");
705 use_helpfile(systemHelpFile("partition", buf));
706 if (!variable_get(VAR_NO_WARN))
707 dialog_mesgbox("Disk slicing warning:", p, -1, -1);
714 bootalloc(char *name, size_t *size)
716 char buf[FILENAME_MAX];
719 snprintf(buf, sizeof buf, "/boot/%s", name);
720 if (stat(buf, &sb) != -1) {
723 fd = open(buf, O_RDONLY);
727 cp = malloc(sb.st_size);
728 if (read(fd, cp, sb.st_size) != sb.st_size) {
731 msgDebug("bootalloc: couldn't read %ld bytes from %s\n", (long)sb.st_size, buf);
739 msgDebug("bootalloc: couldn't open %s\n", buf);
742 msgDebug("bootalloc: can't stat %s\n", buf);
747 partitionHook(dialogMenuItem *selected)
749 Device **devs = NULL;
751 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
753 msgConfirm("Unable to find disk %s!", selected->prompt);
754 return DITEM_FAILURE;
756 /* Toggle enabled status? */
757 if (!devs[0]->enabled) {
758 devs[0]->enabled = TRUE;
759 diskPartition(devs[0]);
762 devs[0]->enabled = FALSE;
763 return DITEM_SUCCESS;
767 partitionCheck(dialogMenuItem *selected)
769 Device **devs = NULL;
771 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
772 if (!devs || devs[0]->enabled == FALSE)
778 diskPartitionEditor(dialogMenuItem *self)
784 cnt = diskGetSelectCount(&devs);
785 devcnt = deviceCount(devs);
787 msgConfirm("No disks found! Please verify that your disk controller is being\n"
788 "properly probed at boot time. See the Hardware Guide on the\n"
789 "Documentation menu for clues on diagnosing this type of problem.");
790 return DITEM_FAILURE;
793 /* Some are already selected */
794 for (i = 0; i < devcnt; i++) {
795 if (devs[i]->enabled) {
796 if (variable_get(VAR_NONINTERACTIVE) &&
797 !variable_get(VAR_DISKINTERACTIVE))
798 diskPartitionNonInteractive(devs[i]);
800 diskPartition(devs[i]);
805 /* No disks are selected, fall-back case now */
807 devs[0]->enabled = TRUE;
808 if (variable_get(VAR_NONINTERACTIVE) &&
809 !variable_get(VAR_DISKINTERACTIVE))
810 diskPartitionNonInteractive(devs[0]);
812 diskPartition(devs[0]);
813 return DITEM_SUCCESS;
816 menu = deviceCreateMenu(&MenuDiskDevices, DEVICE_TYPE_DISK, partitionHook, partitionCheck);
818 msgConfirm("No devices suitable for installation found!\n\n"
819 "Please verify that your disk controller (and attached drives)\n"
820 "were detected properly. This can be done by pressing the\n"
821 "[Scroll Lock] key and using the Arrow keys to move back to\n"
822 "the boot messages. Press [Scroll Lock] again to return.");
823 return DITEM_FAILURE;
826 i = dmenuOpenSimple(menu, FALSE) ? DITEM_SUCCESS : DITEM_FAILURE;
832 return DITEM_SUCCESS;
836 diskPartitionWrite(dialogMenuItem *self)
841 if (!variable_cmp(DISK_PARTITIONED, "written"))
842 return DITEM_SUCCESS;
844 devs = deviceFind(NULL, DEVICE_TYPE_DISK);
846 msgConfirm("Unable to find any disks to write to??");
847 return DITEM_FAILURE;
850 msgDebug("diskPartitionWrite: Examining %d devices\n", deviceCount(devs));
851 for (i = 0; devs[i]; i++) {
852 Disk *d = (Disk *)devs[i]->private;
853 static u_char *boot1;
854 #if defined(__i386__) || defined(__ia64__)
855 static u_char *boot2;
858 if (!devs[i]->enabled)
861 #if defined(__i386__) || defined(__ia64__)
862 if (!boot1) boot1 = bootalloc("boot1", NULL);
863 if (!boot2) boot2 = bootalloc("boot2", NULL);
864 Set_Boot_Blocks(d, boot1, boot2);
866 if (!boot1) boot1 = bootalloc("boot1", NULL);
867 Set_Boot_Blocks(d, boot1, NULL);
870 msgNotify("Writing partition information to drive %s", d->name);
871 if (!Fake && Write_Disk(d)) {
872 msgConfirm("ERROR: Unable to write data to disk %s!", d->name);
873 return DITEM_FAILURE;
876 /* Now it's not "yes", but "written" */
877 variable_set2(DISK_PARTITIONED, "written", 0);
878 return DITEM_SUCCESS | DITEM_RESTORE;
881 /* Partition a disk based wholly on which variables are set */
883 diskPartitionNonInteractive(Device *dev)
886 int i, sz, all_disk = 0;
891 size_t bootmenu_size;
896 Disk *d = (Disk *)dev->private;
899 cp = variable_get(VAR_GEOMETRY);
901 msgDebug("Setting geometry from script to: %s\n", cp);
902 d->bios_cyl = strtol(cp, &cp, 0);
903 d->bios_hd = strtol(cp + 1, &cp, 0);
904 d->bios_sect = strtol(cp + 1, 0, 0);
907 cp = variable_get(VAR_PARTITION);
909 if (!strcmp(cp, "free")) {
910 /* Do free disk space case */
911 for (i = 0; chunk_info[i]; i++) {
912 /* If a chunk is at least 10MB in size, use it. */
913 if (chunk_info[i]->type == unused && chunk_info[i]->size > (10 * ONE_MEG)) {
914 Create_Chunk(d, chunk_info[i]->offset, chunk_info[i]->size,
916 (chunk_info[i]->flags & CHUNK_ALIGN),
918 variable_set2(DISK_PARTITIONED, "yes", 0);
922 if (!chunk_info[i]) {
923 msgConfirm("Unable to find any free space on this disk!");
927 else if (!strcmp(cp, "all")) {
928 /* Do all disk space case */
929 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
931 All_FreeBSD(d, FALSE);
933 else if (!strcmp(cp, "exclusive")) {
934 /* Do really-all-the-disk-space case */
935 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
937 All_FreeBSD(d, all_disk = TRUE);
939 else if ((sz = strtol(cp, &cp, 0))) {
940 /* Look for sz bytes free */
941 if (*cp && toupper(*cp) == 'M')
943 else if (*cp && toupper(*cp) == 'G')
945 for (i = 0; chunk_info[i]; i++) {
946 /* If a chunk is at least sz MB, use it. */
947 if (chunk_info[i]->type == unused && chunk_info[i]->size >= sz) {
948 Create_Chunk(d, chunk_info[i]->offset, sz, freebsd, 3,
949 (chunk_info[i]->flags & CHUNK_ALIGN),
951 variable_set2(DISK_PARTITIONED, "yes", 0);
955 if (!chunk_info[i]) {
956 msgConfirm("Unable to find %d free blocks on this disk!", sz);
960 else if (!strcmp(cp, "existing")) {
961 /* Do existing FreeBSD case */
962 for (i = 0; chunk_info[i]; i++) {
963 if (chunk_info[i]->type == freebsd)
966 if (!chunk_info[i]) {
967 msgConfirm("Unable to find any existing FreeBSD partitions on this disk!");
972 msgConfirm("`%s' is an invalid value for %s - is config file valid?", cp, VAR_PARTITION);
977 getBootMgr(d->name, &bootipl, &bootipl_size,
978 &bootmenu, &bootmenu_size);
979 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
981 getBootMgr(d->name, &mbrContents, &mbrSize);
982 Set_Boot_Mgr(d, mbrContents, mbrSize);
985 variable_set2(DISK_PARTITIONED, "yes", 0);