Index: stable/2.1/release/sysinstall/disks.c =================================================================== --- stable/2.1/release/sysinstall/disks.c (revision 10979) +++ stable/2.1/release/sysinstall/disks.c (revision 10980) @@ -1,448 +1,448 @@ /* * The new sysinstall program. * * This is probably the last program in the `sysinstall' line - the next * generation being essentially a complete rewrite. * - * $Id: disks.c,v 1.31.2.4 1995/09/20 10:43:11 jkh Exp $ + * $Id: disks.c,v 1.31.2.5 1995/09/22 23:35:17 jkh Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * verbatim and that no modifications are made prior to this * point in the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Jordan Hubbard * for the FreeBSD Project. * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include "sysinstall.h" #include #include /* Where we start displaying chunk information on the screen */ #define CHUNK_START_ROW 5 /* Where we keep track of MBR chunks */ static struct chunk *chunk_info[10]; static int current_chunk; static void record_chunks(Disk *d) { struct chunk *c1; int i = 0; int last_free = 0; if (!d->chunks) msgFatal("No chunk list found for %s!", d->name); c1 = d->chunks->part; current_chunk = 0; while (c1) { if (c1->type == unused && c1->size > last_free) { last_free = c1->size; current_chunk = i; } chunk_info[i++] = c1; c1 = c1->next; } chunk_info[i] = NULL; } static void print_chunks(Disk *d) { int row; int i; if ((!d->bios_cyl || d->bios_cyl > 65536) || (!d->bios_hd || d->bios_hd > 256) || (!d->bios_sect || d->bios_sect >= 64)) msgConfirm("WARNING: The detected geometry is incorrect! Please adjust it to\nthe correct values manually with the (G)eometry command. If you are\nunsure about the correct geometry (which may be \"translated\"), please\nconsult the Hardware Guide in the Documentation submenu."); attrset(A_NORMAL); mvaddstr(0, 0, "Disk name:\t"); clrtobot(); attrset(A_REVERSE); addstr(d->name); attrset(A_NORMAL); attrset(A_REVERSE); mvaddstr(0, 55, "FDISK Partition Editor"); attrset(A_NORMAL); mvprintw(1, 0, "BIOS Geometry:\t%lu cyls/%lu heads/%lu sectors", d->bios_cyl, d->bios_hd, d->bios_sect); mvprintw(3, 1, "%10s %10s %10s %8s %8s %8s %8s %8s", "Offset", "Size", "End", "Name", "PType", "Desc", "Subtype", "Flags"); for (i = 0, row = CHUNK_START_ROW; chunk_info[i]; i++, row++) { if (i == current_chunk) attrset(A_REVERSE); mvprintw(row, 2, "%10ld %10lu %10lu %8s %8d %8s %8d\t%-6s", chunk_info[i]->offset, chunk_info[i]->size, chunk_info[i]->end, chunk_info[i]->name, chunk_info[i]->type, chunk_n[chunk_info[i]->type], chunk_info[i]->subtype, ShowChunkFlags(chunk_info[i])); if (i == current_chunk) attrset(A_NORMAL); } } static void print_command_summary() { mvprintw(14, 0, "The following commands are supported (in upper or lower case):"); mvprintw(16, 0, "A = Use Entire Disk B = Bad Block Scan C = Create Partition"); mvprintw(17, 0, "D = Delete Partition G = Set BIOS Geometry S = Set Bootable"); mvprintw(18, 0, "U = Undo All Changes Q = Finish W = Write Changes"); mvprintw(20, 0, "The currently selected partition is displayed in "); attrset(A_REVERSE); addstr("reverse"); attrset(A_NORMAL); addstr(" video."); mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to move."); move(0, 0); } static Disk * diskPartition(Disk *d) { char *p; int key = 0; Boolean chunking; char *msg = NULL; char name[40]; chunking = TRUE; strncpy(name, d->name, 40); keypad(stdscr, TRUE); clear(); record_chunks(d); while (chunking) { print_chunks(d); print_command_summary(); if (msg) { standout(); mvprintw(23, 0, msg); standend(); beep(); msg = NULL; } key = toupper(getch()); switch (key) { case '\014': /* ^L */ clear(); continue; case KEY_UP: case '-': if (current_chunk != 0) --current_chunk; break; case KEY_DOWN: case '+': case '\r': case '\n': if (chunk_info[current_chunk + 1]) ++current_chunk; break; case KEY_HOME: current_chunk = 0; break; case KEY_END: while (chunk_info[current_chunk + 1]) ++current_chunk; break; case KEY_F(1): case '?': systemDisplayFile("slice"); break; case 'A': if(!msgYesNo("Do you want to use the regular way to keep the disk\n" "cooperative with the usual BIOS partitioning schemes?")) All_FreeBSD(d, 0); else { int rv; rv = !msgYesNo("This is dangerous in that it will make the drive absolutely\n" "uncooperative to other potential operating systems on the\n" "same disk. It will rather lead to a totally dedicated disk,\n" "starting at the very first sector, bypassing all BIOS geometry\n" "considerations.\n" "You will run into serious troubles for ST-506 and ESDI drives,\n" "and you might suffer a great pain when applying this to some\n" "IDE drives (e.g. drives running under control of some sort of\n" "a disk manager). SCSI drives are considered less harmful.\n" "Whenever you'll get this disk within the reach of some DOS\n" "\"fdisk\" utility, little red daemons will jump out of your\n" "drive and eat you up!\n\n" "Do you insist on dedicating the entire disk this way?"); if(rv) - msgInfo("You can't say you haven't been warned!"); + msgInfo("Well OK, but you can't say you haven't been warned!"); All_FreeBSD(d, rv); } record_chunks(d); break; case 'B': if (chunk_info[current_chunk]->type != freebsd) msg = "Can only scan for bad blocks in FreeBSD partition."; else if (strncmp(name, "sd", 2) || !msgYesNo("This typically makes sense only for ESDI, IDE or MFM drives.\nAre you sure you want to do this on a SCSI disk?")) if (chunk_info[current_chunk]->flags & CHUNK_BAD144) chunk_info[current_chunk]->flags &= ~CHUNK_BAD144; else chunk_info[current_chunk]->flags |= CHUNK_BAD144; break; case 'C': if (chunk_info[current_chunk]->type != unused) msg = "Partition in use, delete it first or move to an unused one."; else { char *val, tmp[20], *cp; int size; snprintf(tmp, 20, "%d", chunk_info[current_chunk]->size); val = msgGetInput(tmp, "Please specify the size for new FreeBSD partition in blocks, or append\na trailing `M' for megabytes (e.g. 20M)."); if (val && (size = strtol(val, &cp, 0)) > 0) { if (*cp && toupper(*cp) == 'M') size *= 2048; Create_Chunk(d, chunk_info[current_chunk]->offset, size, freebsd, 3, (chunk_info[current_chunk]->flags & CHUNK_ALIGN)); record_chunks(d); } } break; case 'D': if (chunk_info[current_chunk]->type == unused) msg = "Partition is already unused!"; else { Delete_Chunk(d, chunk_info[current_chunk]); record_chunks(d); } break; case 'G': { char *val, geometry[80]; snprintf(geometry, 80, "%lu/%lu/%lu", d->bios_cyl, d->bios_hd, d->bios_sect); val = msgGetInput(geometry, "Please specify the new geometry in cyl/hd/sect format.\nDon't forget to use the two slash (/) separator characters!\nIt's not possible to parse the field without them."); if (val) { d->bios_cyl = strtol(val, &val, 0); d->bios_hd = strtol(val + 1, &val, 0); d->bios_sect = strtol(val + 1, 0, 0); } } break; case 'S': /* Set Bootable */ chunk_info[current_chunk]->flags |= CHUNK_ACTIVE; break; case 'U': Free_Disk(d); d = Open_Disk(name); if (!d) msgFatal("Can't reopen disk %s!", name); record_chunks(d); break; case 'W': if (!msgYesNo("Are you sure you want to write this now? You do also\nhave the option of not modifying the disk until *all*\nconfiguration information has been entered, at which\npoint you can do it all at once. If you're unsure, then\nchoose No at this dialog.")) diskPartitionWrite(NULL); break; case '|': if (!msgYesNo("Are you sure you want to go into Wizard mode?\nNo seat belts whatsoever are provided!")) { dialog_clear(); end_dialog(); DialogActive = FALSE; slice_wizard(d); dialog_clear(); DialogActive = TRUE; record_chunks(d); } else msg = "Wise choice!"; break; case 'Q': chunking = FALSE; break; default: beep(); msg = "Type F1 or ? for help"; break; } } p = CheckRules(d); if (p) { msgConfirm(p); free(p); } dialog_clear(); variable_set2(DISK_PARTITIONED, "yes"); return d; } static int partitionHook(char *str) { Device **devs = NULL; /* Clip garbage off the ends */ string_prune(str); str = string_skipwhite(str); /* Try and open all the disks */ while (str) { char *cp; cp = index(str, '\n'); if (cp) *cp++ = 0; if (!*str) { beep(); return 0; } devs = deviceFind(str, DEVICE_TYPE_DISK); if (!devs) { msgConfirm("Unable to find disk %s!", str); return 0; } else if (devs[1]) msgConfirm("Bizarre multiple match for %s!", str); devs[0]->private = diskPartition((Disk *)devs[0]->private); devs[0]->enabled = TRUE; str = cp; } return devs ? 1 : 0; } int diskPartitionEditor(char *str) { DMenu *menu; Device **devs; int cnt; devs = deviceFind(NULL, DEVICE_TYPE_DISK); cnt = deviceCount(devs); if (!cnt) { msgConfirm("No disks found! Please verify that your disk controller is being\nproperly probed at boot time. See the Hardware Guide on the Documentation menu\nfor clues on diagnosing this type of problem."); return 0; } else if (cnt == 1) { devs[0]->private = diskPartition((Disk *)devs[0]->private); devs[0]->enabled = TRUE; } else { menu = deviceCreateMenu(&MenuDiskDevices, DEVICE_TYPE_DISK, partitionHook); if (!menu) msgConfirm("No devices suitable for installation found!\n\nPlease verify that your disk controller (and attached drives) were detected properly. This can be done by selecting the ``Bootmsg'' option on the main menu and reviewing the boot messages carefully."); else { dmenuOpenSimple(menu); free(menu); } } return 0; } static u_char * getBootMgr(void) { extern u_char mbr[], bteasy17[]; /* Figure out what kind of MBR the user wants */ if (dmenuOpenSimple(&MenuMBRType)) { switch (BootMgr) { case 0: return bteasy17; case 1: return mbr; case 2: default: break; } } return NULL; } int diskPartitionWrite(char *str) { extern u_char boot1[], boot2[]; u_char *mbrContents; Device **devs; int i; mbrContents = getBootMgr(); devs = deviceFind(NULL, DEVICE_TYPE_DISK); if (!devs) { msgConfirm("Unable to find any disks to write to??"); return 0; } for (i = 0; devs[i]; i++) { Chunk *c1; Disk *d = (Disk *)devs[i]->private; if (!devs[i]->enabled) continue; /* Don't trash the MBR if the first (and therefore only) chunk is marked for a truly dedicated disk (i.e., the disklabel starts at sector 0), even in cases where the user has requested booteasy or a "standard" MBR -- both would be fatal in this case. */ if (mbrContents && (d->chunks->part->flags & CHUNK_FORCE_ALL) != CHUNK_FORCE_ALL) { Set_Boot_Mgr(d, mbrContents); mbrContents = NULL; } Set_Boot_Blocks(d, boot1, boot2); msgNotify("Writing partition information to drive %s", d->name); Write_Disk(d); /* Now scan for bad blocks, if necessary */ for (c1 = d->chunks->part; c1; c1 = c1->next) { if (c1->flags & CHUNK_BAD144) { int ret; msgNotify("Running bad block scan on partition %s", c1->name); ret = vsystem("bad144 -v /dev/r%s 1234", c1->name); if (ret) msgConfirm("Bad144 init on %s returned status of %d!", c1->name, ret); ret = vsystem("bad144 -v -s /dev/r%s", c1->name); if (ret) msgConfirm("Bad144 scan on %s returned status of %d!", c1->name, ret); } } } return 0; } Index: stable/2.1/release/sysinstall/install.c =================================================================== --- stable/2.1/release/sysinstall/install.c (revision 10979) +++ stable/2.1/release/sysinstall/install.c (revision 10980) @@ -1,516 +1,518 @@ /* * The new sysinstall program. * * This is probably the last program in the `sysinstall' line - the next * generation being essentially a complete rewrite. * - * $Id: install.c,v 1.71.2.2 1995/09/18 17:00:19 peter Exp $ + * $Id: install.c,v 1.71.2.3 1995/09/22 23:22:20 jkh Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * verbatim and that no modifications are made prior to this * point in the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Jordan Hubbard * for the FreeBSD Project. * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include "sysinstall.h" #include #include #include #include #include #include #include Boolean SystemWasInstalled = FALSE; static Boolean copy_self(void); static Boolean root_extract(void); static Chunk *rootdev; static Boolean checkLabels(void) { Device **devs; Disk *disk; Chunk *c1, *c2, *swapdev, *usrdev; int i; rootdev = swapdev = usrdev = NULL; devs = deviceFind(NULL, DEVICE_TYPE_DISK); /* First verify that we have a root device */ for (i = 0; devs[i]; i++) { if (!devs[i]->enabled) continue; disk = (Disk *)devs[i]->private; msgDebug("Scanning disk %s for root filesystem\n", disk->name); if (!disk->chunks) msgFatal("No chunk list found for %s!", disk->name); for (c1 = disk->chunks->part; c1; c1 = c1->next) { if (c1->type == freebsd) { for (c2 = c1->part; c2; c2 = c2->next) { if (c2->type == part && c2->subtype != FS_SWAP && c2->private) { if (c2->flags & CHUNK_IS_ROOT) { if (rootdev) { msgConfirm("WARNING: You have more than one root device set?!\nUsing the first one found."); continue; } rootdev = c2; } else if (!strcmp(((PartInfo *)c2->private)->mountpoint, "/usr")) { if (usrdev) { msgConfirm("WARNING: You have more than one /usr filesystem.\nUsing the first one found."); continue; } usrdev = c2; } } } } } } /* Now check for swap devices */ for (i = 0; devs[i]; i++) { disk = (Disk *)devs[i]->private; msgDebug("Scanning disk %s for swap partitions\n", disk->name); if (!disk->chunks) msgFatal("No chunk list found for %s!", disk->name); for (c1 = disk->chunks->part; c1; c1 = c1->next) { if (c1->type == freebsd) { for (c2 = c1->part; c2; c2 = c2->next) { if (c2->type == part && c2->subtype == FS_SWAP) { swapdev = c2; break; } } } } } if (!rootdev) { msgConfirm("No root device found - you must label a partition as /\n in the label editor."); return FALSE; } else if (rootdev->name[strlen(rootdev->name) - 1] != 'a') { msgConfirm("Invalid placement of root partition. For now, we only support\nmounting root partitions on \"a\" partitions due to limitations\nin the FreeBSD boot code. Please correct this and\ntry again."); return FALSE; } if (!swapdev) { msgConfirm("No swap devices found - you must create at least one\nswap partition."); return FALSE; } if (!usrdev) msgConfirm("WARNING: No /usr filesystem found. This is not technically\nan error if your root filesystem is big enough (or you later\nintend to get your /usr filesystem over NFS), but it may otherwise\ncause you trouble and is not recommended procedure!"); return TRUE; } static Boolean installInitial(void) { static Boolean alreadyDone = FALSE; if (alreadyDone) return TRUE; if (!getenv(DISK_PARTITIONED)) { msgConfirm("You need to partition your disk before you can proceed with\nthe installation."); return FALSE; } if (!getenv(DISK_LABELLED)) { msgConfirm("You need to assign disk labels before you can proceed with\nthe installation."); return FALSE; } if (!checkLabels()) return FALSE; /* If we refuse to proceed, bail. */ if (msgYesNo("Last Chance! Are you SURE you want continue the installation?\n\nIf you're running this on an existing system, we STRONGLY\nencourage you to make proper backups before proceeding.\nWe take no responsibility for lost disk contents!")) return FALSE; (void)diskPartitionWrite(NULL); if (!installFilesystems()) { msgConfirm("Couldn't make filesystems properly. Aborting."); return FALSE; } if (!copy_self()) { msgConfirm("Couldn't clone the boot floppy onto the root file system.\nAborting."); return FALSE; } dialog_clear(); chroot("/mnt"); chdir("/"); variable_set2(RUNNING_ON_ROOT, "yes"); /* stick a helpful shell over on the 4th VTY */ if (OnVTY && !fork()) { int i, fd; extern int login_tty(int); msgDebug("Starting an emergency holographic shell over on the 4th screen\n"); for (i = 0; i < 64; i++) close(i); fd = open("/dev/ttyv3", O_RDWR); ioctl(0, TIOCSCTTY, &fd); dup2(0, 1); dup2(0, 2); if (login_tty(fd) == -1) { msgNotify("Can't set controlling terminal"); exit(1); } printf("Warning: This shell is chroot()'d to /mnt\n"); execlp("sh", "-sh", 0); exit(1); } alreadyDone = TRUE; return TRUE; } int installExpress(char *str) { msgConfirm("In the next menu, you will need to set up a DOS-style\n" - "partitioning scheme for your hard disk. If you don't\n" - "want to do anything special, just type `A' to use the\n" - "whole disk and then `Q' to quit."); + "(\"fdisk\") partitioning scheme for your hard disk. If you\n" + "don't want to do anything special, just type `A' to use the\n" + "whole disk and then `Q' to quit. If you wish to share\n" + "a disk with multiple operating systems, do NOT use the\n" + "`A' command."); diskPartitionEditor("express"); msgConfirm("Next, you need to lay out BSD partitions inside of the\n" - "DOS-style partition just created. If you don't want to\n" + "fdisk partition just created. If you don't want to\n" "do anything special, just type `A' to use the default\n" "partitioning scheme and then `Q' to quit."); diskLabelEditor("express"); msgConfirm("Now it is time to select an installation subset. There\n" "are many different configurations, ranging from minimal\n" "installation sets to full X developer oriented configs.\n" "You can also select a custom software set if none of the\n" "default configurations are suitable."); while(!Dists) { dmenuOpenSimple(&MenuInstallType); } msgConfirm("Finally, you must specify an installation medium."); dmenuOpenSimple(&MenuMedia); installCommit("express"); dmenuOpenSimple(&MenuConfigure); return 0; } /* * What happens when we select "Commit" in the custom installation menu. * * This is broken into multiple stages so that the user can do a full installation but come * back here again to load more distributions, perhaps from a different media type. * This would allow, for example, the user to load the majority of the system from CDROM * and then use ftp to load just the DES dist. */ int installCommit(char *str) { Device **devs; int i; if (!Dists) { msgConfirm("You haven't told me what distributions to load yet!\nPlease select a distribution from the Distributions menu."); return 0; } if (!mediaVerify()) return 0; if (RunningAsInit && !SystemWasInstalled) { if (!installInitial()) return 0; configFstab(); } if (RunningAsInit && !SystemWasInstalled && !root_extract()) { msgConfirm("Failed to load the ROOT distribution. Please correct\nthis problem and try again."); return 0; } /* If we're about to extract the bin dist again, reset the installed state */ if (Dists & DIST_BIN) SystemWasInstalled = FALSE; (void)distExtractAll(NULL); if (!SystemWasInstalled && access("/kernel", R_OK)) { if (vsystem("ln -f /kernel.GENERIC /kernel")) { msgConfirm("Unable to link /kernel into place!"); return 0; } } /* Resurrect /dev after bin distribution screws it up */ if (RunningAsInit && !SystemWasInstalled) { msgNotify("Remaking all devices.. Please wait!"); if (vsystem("cd /dev; sh MAKEDEV all")) msgConfirm("MAKEDEV returned non-zero status"); msgNotify("Resurrecting /dev entries for slices.."); devs = deviceFind(NULL, DEVICE_TYPE_DISK); if (!devs) msgFatal("Couldn't get a disk device list!"); /* Resurrect the slices that the former clobbered */ for (i = 0; devs[i]; i++) { Disk *disk = (Disk *)devs[i]->private; Chunk *c1; if (!disk->chunks) msgFatal("No chunk list found for %s!", disk->name); for (c1 = disk->chunks->part; c1; c1 = c1->next) { if (c1->type == freebsd) { msgNotify("Making slice entries for %s", c1->name); if (vsystem("cd /dev; sh MAKEDEV %sh", c1->name)) msgConfirm("Unable to make slice entries for %s!", c1->name); } } } } /* XXX Do all the last ugly work-arounds here which we'll try and excise someday right?? XXX */ /* BOGON #1: XFree86 extracting /usr/X11R6 with root-only perms */ if (file_readable("/usr/X11R6")) chmod("/usr/X11R6", 0755); /* BOGON #2: We leave /etc in a bad state */ chmod("/etc", 0755); dialog_clear(); /* We get a NULL value for str if run from installExpress(), in which case we don't want to print the following */ if (str) { if (Dists) msgConfirm("Installation completed with some errors. You may wish\nto scroll through the debugging messages on ALT-F2 with the scroll-lock\nfeature. Press [ENTER] to return to the installation menu."); else msgConfirm("Installation completed successfully, now press [ENTER] to return\nto the main menu. If you have any network devices you have not yet\nconfigured, see the Interface configuration item on the\nConfiguration menu."); } SystemWasInstalled = TRUE; return 0; } /* Go newfs and/or mount all the filesystems we've been asked to */ Boolean installFilesystems(void) { int i; Disk *disk; Chunk *c1, *c2; Device **devs; char dname[40]; PartInfo *p = (PartInfo *)rootdev->private; Boolean RootReadOnly; command_clear(); devs = deviceFind(NULL, DEVICE_TYPE_DISK); /* First, create and mount the root device */ if (strcmp(p->mountpoint, "/")) msgConfirm("Warning: %s is marked as a root partition but is mounted on %s", rootdev->name, p->mountpoint); if (p->newfs) { int i; sprintf(dname, "/dev/r%sa", rootdev->disk->name); msgNotify("Making a new root filesystem on %s", dname); i = vsystem("%s %s", p->newfs_cmd, dname); if (i) { msgConfirm("Unable to make new root filesystem! Command returned status %d", i); return FALSE; } RootReadOnly = FALSE; } else { RootReadOnly = TRUE; msgConfirm("Warning: You have selected a Read-Only root device\nand may be unable to find the appropriate device entries on it\nif it is from an older pre-slice version of FreeBSD."); sprintf(dname, "/dev/r%sa", rootdev->disk->name); msgNotify("Checking integrity of existing %s filesystem", dname); i = vsystem("fsck -y %s", dname); if (i) msgConfirm("Warning: fsck returned status off %d - this partition may be\nunsafe to use.", i); } sprintf(dname, "/dev/%sa", rootdev->disk->name); if (Mount("/mnt", dname)) { msgConfirm("Unable to mount the root file system! Giving up."); return FALSE; } /* Now buzz through the rest of the partitions and mount them too */ for (i = 0; devs[i]; i++) { if (!devs[i]->enabled) continue; disk = (Disk *)devs[i]->private; if (!disk->chunks) { msgConfirm("No chunk list found for %s!", disk->name); return FALSE; } /* Make the proper device mount points in /mnt/dev */ if (!(RootReadOnly && disk == rootdev->disk)) { Mkdir("/mnt/dev", NULL); MakeDevDisk(disk, "/mnt/dev"); } for (c1 = disk->chunks->part; c1; c1 = c1->next) { if (c1->type == freebsd) { for (c2 = c1->part; c2; c2 = c2->next) { if (c2->type == part && c2->subtype != FS_SWAP && c2->private) { PartInfo *tmp = (PartInfo *)c2->private; if (!strcmp(tmp->mountpoint, "/")) continue; if (tmp->newfs) command_shell_add(tmp->mountpoint, "%s /mnt/dev/r%s", tmp->newfs_cmd, c2->name); else command_shell_add(tmp->mountpoint, "fsck -y /mnt/dev/r%s", c2->name); command_func_add(tmp->mountpoint, Mount, c2->name); } else if (c2->type == part && c2->subtype == FS_SWAP) { char fname[80]; int i; sprintf(fname, "/mnt/dev/%s", c2->name); i = swapon(fname); if (!i) msgNotify("Added %s as a swap device", fname); else msgConfirm("Unable to add %s as a swap device: %s", fname, strerror(errno)); } } } else if (c1->type == fat && c1->private && !RootReadOnly) { char name[FILENAME_MAX]; sprintf(name, "/mnt%s", ((PartInfo *)c1->private)->mountpoint); Mkdir(name, NULL); } } } /* Copy the boot floppy's dev files */ if (vsystem("find -x /dev | cpio -pdmV /mnt")) { msgConfirm("Couldn't clone the /dev files!"); return FALSE; } command_sort(); command_execute(); return TRUE; } /* Copy the boot floppy contents into /stand */ static Boolean copy_self(void) { int i; msgWeHaveOutput("Copying the boot floppy to /stand on root filesystem"); i = vsystem("find -x /stand | cpio -pdmV /mnt"); if (i) { msgConfirm("Copy returned error status of %d!", i); return FALSE; } /* Copy the /etc files into their rightful place */ if (vsystem("cd /mnt/stand; find etc | cpio -pdmV /mnt")) { msgConfirm("Couldn't copy up the /etc files!"); return TRUE; } return TRUE; } static Boolean loop_on_root_floppy(void); static Boolean root_extract(void) { int fd; static Boolean alreadyExtracted = FALSE; if (alreadyExtracted) return TRUE; if (mediaDevice) { if (isDebug()) msgDebug("Attempting to extract root image from %s device\n", mediaDevice->description); switch(mediaDevice->type) { case DEVICE_TYPE_FLOPPY: alreadyExtracted = loop_on_root_floppy(); break; default: if (!(*mediaDevice->init)(mediaDevice)) break; fd = (*mediaDevice->get)(mediaDevice, "floppies/root.flp", NULL); if (fd < 0) { msgConfirm("Couldn't get root image from %s!\nWill try to get it from floppy.", mediaDevice->name); (*mediaDevice->shutdown)(mediaDevice); alreadyExtracted = loop_on_root_floppy(); } else { msgNotify("Loading root image from %s", mediaDevice->name); alreadyExtracted = mediaExtractDist("/", fd); (*mediaDevice->close)(mediaDevice, fd); } break; } } else alreadyExtracted = loop_on_root_floppy(); return alreadyExtracted; } static Boolean loop_on_root_floppy(void) { int fd; int status = FALSE; while (1) { fd = getRootFloppy(); if (fd != -1) { msgNotify("Extracting root floppy.."); status = mediaExtractDist("/", fd); close(fd); break; } } return status; }