install.c revision 87581
1139825Simp/* 245386Swpaul * The new sysinstall program. 345386Swpaul * 445386Swpaul * This is probably the last program in the `sysinstall' line - the next 545386Swpaul * generation being essentially a complete rewrite. 645386Swpaul * 745386Swpaul * $FreeBSD: head/usr.sbin/sade/install.c 87581 2001-12-09 23:40:02Z dillon $ 845386Swpaul * 945386Swpaul * Copyright (c) 1995 1045386Swpaul * Jordan Hubbard. All rights reserved. 1145386Swpaul * 1245386Swpaul * Redistribution and use in source and binary forms, with or without 1345386Swpaul * modification, are permitted provided that the following conditions 1445386Swpaul * are met: 1545386Swpaul * 1. Redistributions of source code must retain the above copyright 1645386Swpaul * notice, this list of conditions and the following disclaimer, 1745386Swpaul * verbatim and that no modifications are made prior to this 1845386Swpaul * point in the file. 1945386Swpaul * 2. Redistributions in binary form must reproduce the above copyright 2045386Swpaul * notice, this list of conditions and the following disclaimer in the 2145386Swpaul * documentation and/or other materials provided with the distribution. 2245386Swpaul * 2345386Swpaul * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND 2445386Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2545386Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2645386Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE 2745386Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2845386Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2945386Swpaul * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) 3045386Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3145386Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3245386Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3345386Swpaul * SUCH DAMAGE. 3445386Swpaul * 3545386Swpaul */ 3645386Swpaul 37131652Sbms#include "sysinstall.h" 3845386Swpaul#include <ctype.h> 3945386Swpaul#include <sys/disklabel.h> 4045386Swpaul#include <sys/errno.h> 4145386Swpaul#include <sys/ioctl.h> 4245386Swpaul#include <sys/fcntl.h> 4345386Swpaul#include <sys/wait.h> 4445386Swpaul#include <sys/param.h> 4545386Swpaul#define MSDOSFS 4645386Swpaul#include <sys/mount.h> 4745386Swpaul#include <ufs/ufs/ufsmount.h> 4845386Swpaul#include <fs/msdosfs/msdosfsmount.h> 4945386Swpaul#undef MSDOSFS 5045386Swpaul#include <sys/stat.h> 5145386Swpaul#include <sys/sysctl.h> 5245386Swpaul#include <unistd.h> 5345386Swpaul#include <termios.h> 5445386Swpaul 5545386Swpaul/* Hack for rsaref package add, which displays interactive license. 5645386Swpaul * Used by package.c 5745386Swpaul */ 5845386Swpaulint _interactiveHack; 5945386Swpaulint FixItMode = 0; 6045386Swpaul 6145386Swpaulstatic void create_termcap(void); 6245386Swpaulstatic void fixit_common(void); 6345386Swpaul 6445386Swpaul#define TERMCAP_FILE "/usr/share/misc/termcap" 6545386Swpaul 6645386Swpaulstatic void installConfigure(void); 6745386Swpaul 6845386SwpaulBoolean 6945386SwpaulcheckLabels(Boolean whinge, Chunk **rdev, Chunk **sdev, Chunk **udev, Chunk **vdev, Chunk **tdev, Chunk **hdev) 7045386Swpaul{ 7145386Swpaul Device **devs; 7245386Swpaul Boolean status; 7345386Swpaul Disk *disk; 7445386Swpaul Chunk *c1, *c2, *rootdev, *swapdev, *usrdev, *vardev, *tmpdev, *homedev; 7545386Swpaul int i; 7645386Swpaul 7745386Swpaul /* Don't allow whinging if noWarn is set */ 7845386Swpaul if (variable_get(VAR_NO_WARN)) 79113038Sobrien whinge = FALSE; 80113038Sobrien 81113038Sobrien status = TRUE; 8298849Sken if (rdev) 8398849Sken *rdev = NULL; 8445386Swpaul if (sdev) 8545386Swpaul *sdev = NULL; 8645386Swpaul if (udev) 8745386Swpaul *udev = NULL; 8845386Swpaul if (vdev) 8945386Swpaul *vdev = NULL; 90129878Sphk if (tdev) 9145386Swpaul *tdev = NULL; 9245386Swpaul if (hdev) 9398849Sken *hdev = NULL; 9445386Swpaul rootdev = swapdev = usrdev = vardev = tmpdev = homedev = NULL; 9545386Swpaul 9645386Swpaul /* We don't need to worry about root/usr/swap if we're already multiuser */ 9745386Swpaul if (!RunningAsInit) 9845386Swpaul return status; 9945386Swpaul 10083115Sbrooks devs = deviceFind(NULL, DEVICE_TYPE_DISK); 10183115Sbrooks /* First verify that we have a root device */ 10245386Swpaul for (i = 0; devs[i]; i++) { 10345386Swpaul if (!devs[i]->enabled) 10445386Swpaul continue; 10545386Swpaul disk = (Disk *)devs[i]->private; 10645386Swpaul msgDebug("Scanning disk %s for root filesystem\n", disk->name); 10745386Swpaul if (!disk->chunks) 10845386Swpaul msgFatal("No chunk list found for %s!", disk->name); 109131655Sbms for (c1 = disk->chunks->part; c1; c1 = c1->next) { 110131655Sbms if (c1->type == freebsd) { 11145386Swpaul for (c2 = c1->part; c2; c2 = c2->next) { 11249011Swpaul if (c2->type == part && c2->subtype != FS_SWAP && c2->private_data) { 11349011Swpaul if (!strcmp(((PartInfo *)c2->private_data)->mountpoint, "/")) { 11449011Swpaul if (rootdev) { 11545386Swpaul if (whinge) 11698849Sken msgConfirm("WARNING: You have more than one root device set?!\n" 11798849Sken "Using the first one found."); 11898849Sken continue; 11998849Sken } 12098849Sken else { 12198849Sken rootdev = c2; 122138424Salc if (isDebug()) 12398849Sken msgDebug("Found rootdev at %s!\n", rootdev->name); 12498849Sken } 12598849Sken } 12698849Sken else if (!strcmp(((PartInfo *)c2->private_data)->mountpoint, "/usr")) { 12798849Sken if (usrdev) { 12898849Sken if (whinge) 12998849Sken msgConfirm("WARNING: You have more than one /usr filesystem.\n" 13098849Sken "Using the first one found."); 13198849Sken continue; 13298849Sken } 13398849Sken else { 13498849Sken usrdev = c2; 13598849Sken if (isDebug()) 136119288Simp msgDebug("Found usrdev at %s!\n", usrdev->name); 137119288Simp } 13845386Swpaul } 13998849Sken else if (!strcmp(((PartInfo *)c2->private_data)->mountpoint, "/var")) { 14045386Swpaul if (vardev) { 14145386Swpaul if (whinge) 14245386Swpaul msgConfirm("WARNING: You have more than one /var filesystem.\n" 14345386Swpaul "Using the first one found."); 14458698Sjlemon continue; 14598849Sken } 14698849Sken else { 14798849Sken vardev = c2; 14898849Sken if (isDebug()) 14998849Sken msgDebug("Found vardev at %s!\n", vardev->name); 15098849Sken } 15198849Sken } else if (!strcmp(((PartInfo *)c2->private_data)->mountpoint, "/tmp")) { 15245386Swpaul if (tmpdev) { 15398849Sken if (whinge) 15498849Sken msgConfirm("WARNING: You have more than one /tmp filesystem.\n" 15598849Sken "Using the first one found."); 15698849Sken continue; 15798849Sken } 15898849Sken else { 15998849Sken tmpdev = c2; 16098849Sken if (isDebug()) 16145386Swpaul msgDebug("Found tmpdev at %s!\n", tmpdev->name); 16245386Swpaul } 16345386Swpaul } else if (!strcmp(((PartInfo *)c2->private_data)->mountpoint, "/home")) { 16445386Swpaul if (homedev) { 16545386Swpaul if (whinge) 16645386Swpaul msgConfirm("WARNING: You have more than one /home filesystem.\n" 16763702Swpaul "Using the first one found."); 16863699Swpaul continue; 16963702Swpaul } 17045386Swpaul else { 17145386Swpaul homedev = c2; 17245386Swpaul if (isDebug()) 17364139Swpaul msgDebug("Found homedev at %s!\n", homedev->name); 17464139Swpaul } 17564139Swpaul } 17645386Swpaul } 17745386Swpaul } 17856206Swpaul } 17956206Swpaul } 18045386Swpaul } 18145386Swpaul 18245386Swpaul /* Now check for swap devices */ 18398849Sken for (i = 0; devs[i]; i++) { 18498849Sken if (!devs[i]->enabled) 18598849Sken continue; 18698849Sken disk = (Disk *)devs[i]->private; 18798849Sken msgDebug("Scanning disk %s for swap partitions\n", disk->name); 18898849Sken if (!disk->chunks) 189126080Sphk msgFatal("No chunk list found for %s!", disk->name); 190126080Sphk for (c1 = disk->chunks->part; c1; c1 = c1->next) { 191111815Sphk if (c1->type == freebsd) { 192111815Sphk for (c2 = c1->part; c2; c2 = c2->next) { 193111815Sphk if (c2->type == part && c2->subtype == FS_SWAP && !swapdev) { 194111815Sphk swapdev = c2; 19598849Sken if (isDebug()) 19698849Sken msgDebug("Found swapdev at %s!\n", swapdev->name); 197142407Simp break; 198142407Simp } 199142407Simp } 200142407Simp } 201142407Simp } 20245386Swpaul } 203142407Simp 204142407Simp /* Copy our values over */ 20545386Swpaul if (rdev) 206142407Simp *rdev = rootdev; 207142407Simp if (sdev) 208142407Simp *sdev = swapdev; 209142407Simp if (udev) 210142407Simp *udev = usrdev; 211142407Simp if (vdev) 212142407Simp *vdev = vardev; 213142407Simp if (tdev) 214142407Simp *tdev = tmpdev; 215142407Simp if (hdev) 21645386Swpaul *hdev = homedev; 217142407Simp 218142407Simp if (!rootdev && whinge) { 219142407Simp msgConfirm("No root device found - you must label a partition as /\n" 22045386Swpaul "in the label editor."); 221142407Simp status = FALSE; 222142407Simp } 223142407Simp if (!swapdev && whinge) { 22445386Swpaul msgConfirm("No swap devices found - you must create at least one\n" 225142407Simp "swap partition."); 226142407Simp status = FALSE; 227142407Simp } 228142407Simp return status; 229142407Simp} 230142407Simp 231142407Simpstatic int 232142407SimpinstallInitial(void) 233142407Simp{ 23498849Sken static Boolean alreadyDone = FALSE; 235142407Simp int status = DITEM_SUCCESS; 236142407Simp 237142407Simp if (alreadyDone) 23898849Sken return DITEM_SUCCESS; 239142407Simp 240142407Simp if (!variable_get(DISK_LABELLED)) { 241142407Simp msgConfirm("You need to assign disk labels before you can proceed with\n" 242142407Simp "the installation."); 243142407Simp return DITEM_FAILURE; 244142407Simp } 245142407Simp /* If it's labelled, assume it's also partitioned */ 246142407Simp if (!variable_get(DISK_PARTITIONED)) 247142407Simp variable_set2(DISK_PARTITIONED, "yes", 0); 248142407Simp 249142407Simp /* If we refuse to proceed, bail. */ 25045386Swpaul dialog_clear_norefresh(); 251142407Simp if (!variable_get(VAR_NO_WARN)) { 252142407Simp if (msgYesNo( 253142407Simp "Last Chance! Are you SURE you want continue the installation?\n\n" 25445386Swpaul "If you're running this on a disk with data you wish to save\n" 25598849Sken "then WE STRONGLY ENCOURAGE YOU TO MAKE PROPER BACKUPS before\n" 25699013Speter "proceeding!\n\n" 25799013Speter "We can take no responsibility for lost disk contents!") != 0) 25898849Sken return DITEM_FAILURE; 25998849Sken } 26049011Swpaul 26149011Swpaul if (DITEM_STATUS(diskLabelCommit(NULL)) != DITEM_SUCCESS) { 26249011Swpaul msgConfirm("Couldn't make filesystems properly. Aborting."); 26349011Swpaul return DITEM_FAILURE; 26449011Swpaul } 26549011Swpaul 26649011Swpaul if (!copySelf()) { 26749011Swpaul msgConfirm("installInitial: Couldn't clone the boot floppy onto the\n" 26849011Swpaul "root file system. Aborting!"); 26949011Swpaul return DITEM_FAILURE; 27051455Swpaul } 27149011Swpaul 27249011Swpaul if (!Restarting && chroot("/mnt") == -1) { 27349011Swpaul msgConfirm("installInitial: Unable to chroot to %s - this is bad!", 27449011Swpaul "/mnt"); 27549011Swpaul return DITEM_FAILURE; 27649011Swpaul } 277113506Smdodd 278113506Smdodd chdir("/"); 279113506Smdodd variable_set2(RUNNING_ON_ROOT, "yes", 0); 28049011Swpaul 28145386Swpaul /* Configure various files in /etc */ 28245386Swpaul if (DITEM_STATUS(configResolv(NULL)) == DITEM_FAILURE) 28345386Swpaul status = DITEM_FAILURE; 28445386Swpaul if (DITEM_STATUS(configFstab(NULL)) == DITEM_FAILURE) 28545386Swpaul status = DITEM_FAILURE; 28645386Swpaul 28745386Swpaul /* stick a helpful shell over on the 4th VTY */ 28845386Swpaul if (!variable_get(VAR_NO_HOLOSHELL)) 28945386Swpaul systemCreateHoloshell(); 29045386Swpaul 29145386Swpaul alreadyDone = TRUE; 29245386Swpaul return status; 29345386Swpaul} 29445386Swpaul 29545386Swpaulint 29645386SwpaulinstallFixitHoloShell(dialogMenuItem *self) 29745386Swpaul{ 29845386Swpaul FixItMode = 1; 29945386Swpaul systemCreateHoloshell(); 30045386Swpaul return DITEM_SUCCESS; 30145386Swpaul FixItMode = 0; 30245386Swpaul} 30345386Swpaul 30445386Swpaulint 30545386SwpaulinstallFixitCDROM(dialogMenuItem *self) 30645386Swpaul{ 30745386Swpaul struct stat sb; 30845386Swpaul 30945386Swpaul if (!RunningAsInit) 31045386Swpaul return DITEM_SUCCESS; 31145386Swpaul 31245386Swpaul variable_set2(SYSTEM_STATE, "fixit", 0); 31345386Swpaul (void)unlink("/mnt2"); 31445386Swpaul (void)rmdir("/mnt2"); 31545386Swpaul 31645386Swpaul while (1) { 31745386Swpaul msgConfirm("Please insert a FreeBSD live filesystem CD/DVD and press return"); 31845386Swpaul if (DITEM_STATUS(mediaSetCDROM(NULL)) != DITEM_SUCCESS 31945386Swpaul || !DEVICE_INIT(mediaDevice)) { 32045386Swpaul /* If we can't initialize it, it's probably not a FreeBSD CDROM so punt on it */ 32145386Swpaul mediaClose(); 322131654Sbms if (msgYesNo("Unable to mount the disc - do you want to try again?") != 0) 32345386Swpaul return DITEM_FAILURE; 32445386Swpaul } 32545386Swpaul else 32645386Swpaul break; 32745386Swpaul } 32845386Swpaul 32945386Swpaul /* Since the fixit code expects everything to be in /mnt2, and the CDROM mounting stuff /dist, do 33045386Swpaul * a little kludge dance here.. 33145386Swpaul */ 33245386Swpaul if (symlink("/dist", "/mnt2")) { 33345386Swpaul msgConfirm("Unable to symlink /mnt2 to the disc mount point. Please report this\n" 33445386Swpaul "unexpected failure to freebsd-bugs@FreeBSD.org."); 33545386Swpaul return DITEM_FAILURE; 33645386Swpaul } 33745386Swpaul 33845386Swpaul /* 33945386Swpaul * If /tmp points to /mnt2/tmp from a previous fixit floppy session, it's 34045386Swpaul * not very good for us if we point it to the CDROM now. Rather make it 34145386Swpaul * a directory in the root MFS then. Experienced admins will still be 34245386Swpaul * able to mount their disk's /tmp over this if they need. 34345386Swpaul */ 34445386Swpaul if (lstat("/tmp", &sb) == 0 && (sb.st_mode & S_IFMT) == S_IFLNK) 34545386Swpaul (void)unlink("/tmp"); 346131654Sbms Mkdir("/tmp"); 34745386Swpaul 34845386Swpaul /* 34945386Swpaul * Since setuid binaries ignore LD_LIBRARY_PATH, we indeed need the 35045386Swpaul * ld.so.hints file. Fortunately, it's fairly small (~ 3 KB). 35145386Swpaul */ 35245386Swpaul if (!file_readable("/var/run/ld.so.hints")) { 35345386Swpaul Mkdir("/var/run"); 35445386Swpaul if (vsystem("/mnt2/sbin/ldconfig -s /mnt2/usr/lib")) { 355131654Sbms msgConfirm("Warning: ldconfig could not create the ld.so hints file.\n" 35645386Swpaul "Dynamic executables from the disc likely won't work."); 35745386Swpaul } 35845386Swpaul } 35945386Swpaul 36045386Swpaul /* Yet more iggly hardcoded pathnames. */ 36145386Swpaul Mkdir("/usr/libexec"); 36245386Swpaul if (!file_readable("/usr/libexec/ld.so") && file_readable("/mnt2/usr/libexec/ld.so")) { 363131654Sbms if (symlink("/mnt2/usr/libexec/ld.so", "/usr/libexec/ld.so")) 36445386Swpaul msgDebug("Couldn't link to ld.so - not necessarily a problem for ELF\n"); 36545386Swpaul } 36645386Swpaul if (!file_readable("/usr/libexec/ld-elf.so.1")) { 36745386Swpaul if (symlink("/mnt2/usr/libexec/ld-elf.so.1", "/usr/libexec/ld-elf.so.1")) { 36845386Swpaul msgConfirm("Warning: could not create the symlink for ld-elf.so.1\n" 36945386Swpaul "Dynamic executables from the disc likely won't work."); 37045386Swpaul } 37145386Swpaul } 37245386Swpaul /* optional nicety */ 37345386Swpaul if (!file_readable("/usr/bin/vi")) 374131654Sbms symlink("/mnt2/usr/bin/vi", "/usr/bin/vi"); 37545386Swpaul fixit_common(); 37645386Swpaul mediaClose(); 37745386Swpaul msgConfirm("Please remove the FreeBSD fixit CDROM now."); 37845386Swpaul return DITEM_SUCCESS; 37945386Swpaul} 38045386Swpaul 38145386Swpaulint 38245386SwpaulinstallFixitFloppy(dialogMenuItem *self) 38345386Swpaul{ 38445386Swpaul struct ufs_args args; 38545386Swpaul extern char *distWanted; 38645386Swpaul 38745386Swpaul if (!RunningAsInit) 38845386Swpaul return DITEM_SUCCESS; 38945386Swpaul 39045386Swpaul /* Try to open the floppy drive */ 39145386Swpaul if (DITEM_STATUS(mediaSetFloppy(NULL)) == DITEM_FAILURE || !mediaDevice) { 39245386Swpaul msgConfirm("Unable to set media device to floppy."); 39345386Swpaul mediaClose(); 39445386Swpaul return DITEM_FAILURE; 39545386Swpaul } 39645386Swpaul 39745386Swpaul memset(&args, 0, sizeof(args)); 398131654Sbms args.fspec = mediaDevice->devname; 39945386Swpaul mediaDevice->private = "/mnt2"; 40045386Swpaul distWanted = NULL; 40145386Swpaul Mkdir("/mnt2"); 40245386Swpaul 40345386Swpaul variable_set2(SYSTEM_STATE, "fixit", 0); 404102336Salfred 405102336Salfred while (1) { 40645386Swpaul if (!DEVICE_INIT(mediaDevice)) { 40745386Swpaul if (msgYesNo("The attempt to mount the fixit floppy failed, bad floppy\n" 40845386Swpaul "or unclean filesystem. Do you want to try again?")) 40945386Swpaul return DITEM_FAILURE; 41045386Swpaul } 41145386Swpaul else 41245386Swpaul break; 41345386Swpaul } 41445386Swpaul if (!directory_exists("/tmp")) 41545386Swpaul (void)symlink("/mnt2/tmp", "/tmp"); 41645386Swpaul fixit_common(); 41745386Swpaul mediaClose(); 41845386Swpaul msgConfirm("Please remove the fixit floppy now."); 41945386Swpaul return DITEM_SUCCESS; 42045386Swpaul} 421131654Sbms 42245386Swpaul/* 42345386Swpaul * The common code for both fixit variants. 42445386Swpaul */ 42545386Swpaulstatic void 42645386Swpaulfixit_common(void) 42745386Swpaul{ 428102336Salfred pid_t child; 429102336Salfred int waitstatus; 43045386Swpaul 43145386Swpaul if (!directory_exists("/var/tmp/vi.recover")) { 43245386Swpaul if (DITEM_STATUS(Mkdir("/var/tmp/vi.recover")) != DITEM_SUCCESS) { 43345386Swpaul msgConfirm("Warning: Was unable to create a /var/tmp/vi.recover directory.\n" 43445386Swpaul "vi will kvetch and moan about it as a result but should still\n" 43545386Swpaul "be essentially usable."); 43645386Swpaul } 43745386Swpaul } 43845386Swpaul if (!directory_exists("/bin")) 43949133Swpaul (void)Mkdir("/bin"); 44045386Swpaul (void)symlink("/stand/sh", "/bin/sh"); 44145386Swpaul /* Link the /etc/ files */ 442131654Sbms if (DITEM_STATUS(Mkdir("/etc")) != DITEM_SUCCESS) 44345386Swpaul msgConfirm("Unable to create an /etc directory! Things are weird on this floppy.."); 44445386Swpaul else if ((symlink("/mnt2/etc/spwd.db", "/etc/spwd.db") == -1 && errno != EEXIST) || 44545386Swpaul (symlink("/mnt2/etc/protocols", "/etc/protocols") == -1 && errno != EEXIST) || 44645386Swpaul (symlink("/mnt2/etc/services", "/etc/services") == -1 && errno != EEXIST)) 44745386Swpaul msgConfirm("Couldn't symlink the /etc/ files! I'm not sure I like this.."); 44845386Swpaul if (!file_readable(TERMCAP_FILE)) 44945386Swpaul create_termcap(); 45045386Swpaul if (strcmp(variable_get(VAR_FIXIT_TTY), "serial") == 0) 45145386Swpaul systemSuspendDialog(); /* must be before the fork() */ 45245386Swpaul if (!(child = fork())) { 45345386Swpaul int i, fd; 45445386Swpaul struct termios foo; 45545386Swpaul extern int login_tty(int); 45645386Swpaul 45745386Swpaul ioctl(0, TIOCNOTTY, NULL); 45845386Swpaul for (i = getdtablesize(); i >= 0; --i) 45945386Swpaul close(i); 46045386Swpaul 46198849Sken if (strcmp(variable_get(VAR_FIXIT_TTY), "serial") == 0) 46298849Sken fd = open("/dev/console", O_RDWR); 46398849Sken else 46498849Sken fd = open("/dev/ttyv3", O_RDWR); 46598849Sken ioctl(0, TIOCSCTTY, &fd); 46698849Sken dup2(0, 1); 46798849Sken dup2(0, 2); 46898849Sken DebugFD = 2; 46998849Sken if (login_tty(fd) == -1) 47098849Sken msgDebug("fixit: I can't set the controlling terminal.\n"); 47198849Sken 47298849Sken signal(SIGTTOU, SIG_IGN); 47398849Sken if (tcgetattr(0, &foo) != -1) { 47498849Sken foo.c_cc[VERASE] = '\010'; 47598849Sken if (tcsetattr(0, TCSANOW, &foo) == -1) 47698849Sken msgDebug("fixit shell: Unable to set erase character.\n"); 47798849Sken } 47898849Sken else 47998849Sken msgDebug("fixit shell: Unable to get terminal attributes!\n"); 48098849Sken setenv("PATH", "/bin:/sbin:/usr/bin:/usr/sbin:/stand:" 48198849Sken "/mnt2/stand:/mnt2/bin:/mnt2/sbin:/mnt2/usr/bin:/mnt2/usr/sbin", 1); 48298849Sken setenv("MAKEDEVPATH", "/sbin:/bin:/stand:" 48398849Sken "/mnt2/sbin:/mnt2/bin:/mnt2/stand", 1); 48498849Sken if (strcmp(variable_get(VAR_FIXIT_TTY), "serial") == 0) { 485131654Sbms printf("Waiting for fixit shell to exit.\n" 48698849Sken "When you are done, type ``exit'' to exit\n" 48798849Sken "the fixit shell and be returned here.\n\n"); 48898849Sken fflush(stdout); 48998849Sken } 49098849Sken 49198849Sken /* use the .profile from the fixit medium */ 49298849Sken setenv("HOME", "/mnt2", 1); 49398849Sken chdir("/mnt2"); 49498849Sken execlp("sh", "-sh", (char *)0); 49598849Sken msgDebug("fixit shell: Failed to execute shell!\n"); 49698849Sken _exit(1);; 49798849Sken } 49898849Sken else { 49998849Sken if (strcmp(variable_get(VAR_FIXIT_TTY), "standard") == 0) { 50098849Sken dialog_clear_norefresh(); 50198849Sken msgNotify("Waiting for fixit shell to exit. Go to VTY4 now by\n" 50298849Sken "typing ALT-F4. When you are done, type ``exit'' to exit\n" 50398849Sken "the fixit shell and be returned here\n."); 50498849Sken } 50598849Sken (void)waitpid(child, &waitstatus, 0); 50698849Sken if (strcmp(variable_get(VAR_FIXIT_TTY), "serial") == 0) 50798849Sken systemResumeDialog(); 50898849Sken } 50998849Sken dialog_clear(); 51098849Sken} 51198849Sken 51298849Sken 51398849Skenint 51498849SkeninstallExpress(dialogMenuItem *self) 51598849Sken{ 51698849Sken int i; 51798849Sken 51898849Sken dialog_clear_norefresh(); 51998849Sken variable_set2(SYSTEM_STATE, "express", 0); 52098849Sken#ifndef __alpha__ 52198849Sken if (DITEM_STATUS((i = diskPartitionEditor(self))) == DITEM_FAILURE) 52298849Sken return i; 523131654Sbms#endif 52498849Sken 52598849Sken if (DITEM_STATUS((i = diskLabelEditor(self))) == DITEM_FAILURE) 52698849Sken return i; 52798849Sken 52898849Sken if (DITEM_STATUS((i = installCommit(self))) == DITEM_SUCCESS) { 52998849Sken i |= DITEM_LEAVE_MENU; 53098849Sken /* Set default security level */ 53198849Sken configSecurityModerate(NULL); 53298849Sken 53398849Sken /* Give user the option of one last configuration spree */ 53498849Sken installConfigure(); 53598849Sken } 53698849Sken return i; 53798849Sken} 53898849Sken 53998849Sken/* Standard mode installation */ 54098849Skenint 54198849SkeninstallStandard(dialogMenuItem *self) 54298849Sken{ 54398849Sken int i, tries = 0; 54498849Sken Device **devs; 54598849Sken 54698849Sken variable_set2(SYSTEM_STATE, "standard", 0); 54798849Sken dialog_clear_norefresh(); 54898849Sken#ifndef __alpha__ 54998849Sken msgConfirm("In the next menu, you will need to set up a DOS-style (\"fdisk\") partitioning\n" 55098849Sken "scheme for your hard disk. If you simply wish to devote all disk space\n" 55198849Sken "to FreeBSD (overwriting anything else that might be on the disk(s) selected)\n" 55298849Sken "then use the (A)ll command to select the default partitioning scheme followed\n" 55398849Sken "by a (Q)uit. If you wish to allocate only free space to FreeBSD, move to a\n" 55498849Sken "partition marked \"unused\" and use the (C)reate command."); 55598849Sken 55698849Skennodisks: 55798849Sken if (DITEM_STATUS(diskPartitionEditor(self)) == DITEM_FAILURE) 55898849Sken return DITEM_FAILURE; 55998849Sken 56098849Sken if (diskGetSelectCount(&devs) <= 0 && tries < 3) { 56198849Sken msgConfirm("You need to select some disks to operate on! Be sure to use SPACE\n" 56298849Sken "instead of RETURN in the disk selection menu when selecting a disk."); 56398849Sken ++tries; 56498849Sken goto nodisks; 56598849Sken } 56698849Sken#endif 56798849Sken 56898849Sken#ifdef __alpha__ 56998849Sken msgConfirm("Now you need to create BSD partitions on the disk which you are\n" 57098849Sken "installing to. If you have a reasonable amount of disk space (200MB or more)\n" 57198849Sken "and don't have any special requirements, simply use the (A)uto command to\n" 57298849Sken "allocate space automatically. If you have more specific needs or just don't\n" 57398849Sken "care for the layout chosen by (A)uto, press F1 for more information on\n" 57498849Sken "manual layout."); 57598849Sken#else 57698849Sken msgConfirm("Now you need to create BSD partitions inside of the fdisk partition(s)\n" 57798849Sken "just created. If you have a reasonable amount of disk space (200MB or more)\n" 57898849Sken "and don't have any special requirements, simply use the (A)uto command to\n" 57998849Sken "allocate space automatically. If you have more specific needs or just don't\n" 58098849Sken "care for the layout chosen by (A)uto, press F1 for more information on\n" 58198849Sken "manual layout."); 58298849Sken#endif 58398849Sken 58498849Sken if (DITEM_STATUS(diskLabelEditor(self)) == DITEM_FAILURE) 58598849Sken return DITEM_FAILURE; 58698849Sken 58798849Sken if (DITEM_STATUS((i = installCommit(self))) == DITEM_FAILURE) { 58898849Sken dialog_clear(); 58998849Sken msgConfirm("Installation completed with some errors. You may wish to\n" 59098849Sken "scroll through the debugging messages on VTY1 with the\n" 59198849Sken "scroll-lock feature. You can also choose \"No\" at the next\n" 59298849Sken "prompt and go back into the installation menus to try and retry\n" 59398849Sken "whichever operations have failed."); 59498849Sken return i; 59598849Sken 59698849Sken } 59798849Sken else { 59898849Sken dialog_clear(); 59998849Sken msgConfirm("Congratulations! You now have FreeBSD installed on your system.\n\n" 60098849Sken "We will now move on to the final configuration questions.\n" 60198849Sken "For any option you do not wish to configure, simply select\n" 60298849Sken "No.\n\n" 60398849Sken "If you wish to re-enter this utility after the system is up, you\n" 60498849Sken "may do so by typing: /usr/sbin/sysinstall."); 60598849Sken } 60698849Sken if (mediaDevice->type != DEVICE_TYPE_FTP && mediaDevice->type != DEVICE_TYPE_NFS) { 60798849Sken if (!msgYesNo("Would you like to configure any Ethernet or SLIP/PPP network devices?")) { 60898849Sken Device *tmp = tcpDeviceSelect(); 60998849Sken 61098849Sken if (tmp && !((DevInfo *)tmp->private)->use_dhcp && !msgYesNo("Would you like to bring the %s interface up right now?", tmp->name)) 61198849Sken if (!DEVICE_INIT(tmp)) 61298849Sken msgConfirm("Initialization of %s device failed.", tmp->name); 61398849Sken } 61498849Sken dialog_clear_norefresh(); 61598849Sken } 61698849Sken 61798849Sken if (!msgNoYes("Do you want this machine to function as a network gateway?")) 61898849Sken variable_set2("gateway_enable", "YES", 1); 61998849Sken 62098849Sken dialog_clear_norefresh(); 62198849Sken if (!msgNoYes("Do you want to configure inetd and the network services that it provides?")) 62298849Sken configInetd(self); 62398849Sken 62498849Sken dialog_clear_norefresh(); 62598849Sken if (!msgNoYes("Do you want to have anonymous FTP access to this machine?")) 62698849Sken configAnonFTP(self); 62798849Sken 62898849Sken dialog_clear_norefresh(); 62998849Sken if (!msgNoYes("Do you want to configure this machine as an NFS server?")) 63098849Sken configNFSServer(self); 63198849Sken 63298849Sken dialog_clear_norefresh(); 63398849Sken if (!msgNoYes("Do you want to configure this machine as an NFS client?")) 63498849Sken variable_set2("nfs_client_enable", "YES", 1); 63598849Sken 63698849Sken if (!msgNoYes("Do you want to select a default security profile for\n" 63798849Sken "this host (select No for \"moderate\" security)?")) 63898849Sken configSecurityProfile(self); 63998849Sken else 64098849Sken configSecurityModerate(self); 64198849Sken 64298849Sken dialog_clear_norefresh(); 64398849Sken if (!msgNoYes("Would you like to customize your system console settings?")) 64498849Sken dmenuOpenSimple(&MenuSyscons, FALSE); 64598849Sken 64698849Sken dialog_clear_norefresh(); 64798849Sken if (!msgYesNo("Would you like to set this machine's time zone now?")) 64898849Sken systemExecute("tzsetup"); 64998849Sken 65098849Sken#ifdef __i386__ 65198849Sken dialog_clear_norefresh(); 65298849Sken if (!msgYesNo("Would you like to enable Linux binary compatibility?")) 653131654Sbms (void)configLinux(self); 65498849Sken#endif 65598849Sken 65698849Sken dialog_clear_norefresh(); 65798849Sken if (msgNoYes("Does this system have a USB mouse attached to it?")) 65898849Sken dmenuOpenSimple(&MenuMouse, FALSE); 65998849Sken 66098849Sken /* Now would be a good time to checkpoint the configuration data */ 66198849Sken configRC_conf(); 66298849Sken sync(); 66398849Sken 66498849Sken if (directory_exists("/usr/X11R6")) { 66598849Sken dialog_clear_norefresh(); 66698849Sken if (!msgYesNo("Would you like to configure your X server at this time?")) 66798849Sken (void)configXSetup(self); 66898849Sken } 66998849Sken 67098849Sken dialog_clear_norefresh(); 67198849Sken if (!msgYesNo("The FreeBSD package collection is a collection of thousands of ready-to-run\n" 67298849Sken "applications, from text editors to games to WEB servers and more. Would you\n" 67398849Sken "like to browse the collection now?")) { 67498849Sken (void)configPackages(self); 67598849Sken } 676131654Sbms 67798849Sken if (!msgYesNo("Would you like to add any initial user accounts to the system?\n" 67898849Sken "Adding at least one account for yourself at this stage is suggested\n" 67998849Sken "since working as the \"root\" user is dangerous (it is easy to do\n" 68098849Sken "things which adversely affect the entire system).")) 68198849Sken (void)configUsers(self); 682131654Sbms 68398849Sken msgConfirm("Now you must set the system manager's password.\n" 68498849Sken "This is the password you'll use to log in as \"root\"."); 68598849Sken if (!systemExecute("passwd root")) 68698849Sken variable_set2("root_password", "YES", 0); 68798849Sken 68898849Sken /* XXX Put whatever other nice configuration questions you'd like to ask the user here XXX */ 68998849Sken 69098849Sken /* Give user the option of one last configuration spree */ 69198849Sken dialog_clear_norefresh(); 69298849Sken installConfigure(); 69398849Sken return DITEM_LEAVE_MENU; 69498849Sken} 69598849Sken 69698849Sken/* The version of commit we call from the Install Custom menu */ 69798849Skenint 69898849SkeninstallCustomCommit(dialogMenuItem *self) 69998849Sken{ 70098849Sken int i; 70198849Sken 70298849Sken i = installCommit(self); 70398849Sken if (DITEM_STATUS(i) == DITEM_SUCCESS) { 70498849Sken /* Set default security level */ 70598849Sken configSecurityModerate(NULL); 70698849Sken 707131652Sbms /* Give user the option of one last configuration spree */ 70898849Sken installConfigure(); 70998849Sken return i; 71098849Sken } 71198849Sken else 71298849Sken msgConfirm("The commit operation completed with errors. Not\n" 71398849Sken "updating /etc files."); 71498849Sken return i; 71598849Sken} 71698849Sken 71798849Sken/* 71898849Sken * What happens when we finally decide to going ahead with the installation. 71998849Sken * 72098849Sken * This is broken into multiple stages so that the user can do a full 72198849Sken * installation but come back here again to load more distributions, 72298849Sken * perhaps from a different media type. This would allow, for 72398849Sken * example, the user to load the majority of the system from CDROM and 72498849Sken * then use ftp to load just the CRYPTO dist. 72598849Sken */ 72698849Skenint 72798849SkeninstallCommit(dialogMenuItem *self) 72898849Sken{ 72998849Sken int i; 73098849Sken char *str; 73198849Sken 73298849Sken dialog_clear_norefresh(); 73398849Sken if (!Dists) 73498849Sken distConfig(NULL); 73598849Sken 73698849Sken if (!Dists) { 73798849Sken (void)dmenuOpenSimple(&MenuDistributions, FALSE); 73898849Sken /* select reasonable defaults if necessary */ 73998849Sken if (!Dists) 74098849Sken Dists = _DIST_USER; 74198849Sken } 74298849Sken 74398849Sken if (!mediaVerify()) 74498849Sken return DITEM_FAILURE; 74598849Sken 74698849Sken str = variable_get(SYSTEM_STATE); 74798849Sken if (isDebug()) 74898849Sken msgDebug("installCommit: System state is `%s'\n", str); 74998849Sken 75098849Sken /* Installation stuff we wouldn't do to a running system */ 75198849Sken if (RunningAsInit && DITEM_STATUS((i = installInitial())) == DITEM_FAILURE) 75298849Sken return i; 753131654Sbms 75498849Skentry_media: 75598849Sken if (!DEVICE_INIT(mediaDevice)) { 75698849Sken if (!msgYesNo("Unable to initialize selected media. Would you like to\n" 75798849Sken "adjust your media configuration and try again?")) { 75898849Sken mediaDevice = NULL; 75998849Sken if (!mediaVerify()) 76098849Sken return DITEM_FAILURE; 76198849Sken else 76298849Sken goto try_media; 76398849Sken } 76498849Sken else 76598849Sken return DITEM_FAILURE; 76698849Sken } 76798849Sken 768106627Sjhb /* Now go get it all */ 76998849Sken i = distExtractAll(self); 770131654Sbms 77198849Sken /* When running as init, *now* it's safe to grab the rc.foo vars */ 77298849Sken installEnvironment(); 77398849Sken 77498849Sken variable_set2(SYSTEM_STATE, DITEM_STATUS(i) == DITEM_FAILURE ? "error-install" : "full-install", 0); 77598849Sken 77698849Sken return i; 77798849Sken} 77898849Sken 77998849Skenstatic void 78098849SkeninstallConfigure(void) 78198849Sken{ 78298849Sken /* Final menu of last resort */ 78398849Sken if (!msgNoYes("Visit the general configuration menu for a chance to set\n" 78498849Sken "any last options?")) 78598849Sken dmenuOpenSimple(&MenuConfigure, FALSE); 78698849Sken configRC_conf(); 78798849Sken sync(); 78898849Sken} 78998849Sken 790131654Sbmsint 79198849SkeninstallFixupBin(dialogMenuItem *self) 79298849Sken{ 79345386Swpaul Device **devs; 79445386Swpaul char *cp; 79545386Swpaul int i; 79645386Swpaul FILE *fp; 79745386Swpaul int kstat = 1; 798102336Salfred 799102336Salfred /* All of this is done only as init, just to be safe */ 80045386Swpaul if (RunningAsInit) { 80145386Swpaul#ifdef __i386__ 802131654Sbms if ((fp = fopen("/boot/loader.conf", "a")) != NULL) { 80345386Swpaul if (!kstat || !OnVTY) 80445386Swpaul fprintf(fp, "# -- sysinstall generated deltas -- #\n"); 80545386Swpaul if (!kstat) 80645386Swpaul fprintf(fp, "userconfig_script_load=\"YES\"\n"); 80745386Swpaul if (!OnVTY) 80845386Swpaul fprintf(fp, "console=\"comconsole\"\n"); 80945386Swpaul fclose(fp); 81045386Swpaul } 81145386Swpaul#endif 81245386Swpaul /* BOGON #1: Resurrect /dev after bin distribution screws it up */ 81345386Swpaul dialog_clear_norefresh(); 81445386Swpaul msgNotify("Remaking all devices.. Please wait!"); 81545386Swpaul if (vsystem("cd /dev; sh MAKEDEV all")) { 81645386Swpaul msgConfirm("MAKEDEV returned non-zero status"); 81745386Swpaul return DITEM_FAILURE | DITEM_RESTORE; 81845386Swpaul } 81945386Swpaul 82045386Swpaul dialog_clear_norefresh(); 82145386Swpaul msgNotify("Resurrecting /dev entries for slices.."); 82245386Swpaul devs = deviceFind(NULL, DEVICE_TYPE_DISK); 82345386Swpaul if (!devs) 82445386Swpaul msgFatal("Couldn't get a disk device list!"); 82545386Swpaul 82645386Swpaul /* Resurrect the slices that the former clobbered */ 82745386Swpaul for (i = 0; devs[i]; i++) { 82845386Swpaul Disk *disk = (Disk *)devs[i]->private; 82945386Swpaul Chunk *c1; 83045386Swpaul 83145386Swpaul if (!devs[i]->enabled) 83245386Swpaul continue; 83345386Swpaul if (!disk->chunks) 83445386Swpaul msgFatal("No chunk list found for %s!", disk->name); 83545386Swpaul for (c1 = disk->chunks->part; c1; c1 = c1->next) { 83645386Swpaul if (c1->type == freebsd) { 83745386Swpaul dialog_clear_norefresh(); 83845386Swpaul msgNotify("Making slice entries for %s", c1->name); 83945386Swpaul if (vsystem("cd /dev; sh MAKEDEV %sh", c1->name)) { 84045386Swpaul msgConfirm("Unable to make slice entries for %s!", c1->name); 84145386Swpaul return DITEM_FAILURE | DITEM_RESTORE; 84245386Swpaul } 84345386Swpaul } 84445386Swpaul } 84545386Swpaul } 84645386Swpaul 84745386Swpaul /* BOGON #2: We leave /etc in a bad state */ 84845386Swpaul chmod("/etc", 0755); 84945386Swpaul 85045386Swpaul /* BOGON #3: No /var/db/mountdtab complains */ 85145386Swpaul Mkdir("/var/db"); 85245386Swpaul creat("/var/db/mountdtab", 0644); 85345386Swpaul 85445386Swpaul /* BOGON #4: /compat created by default in root fs */ 855102336Salfred Mkdir("/usr/compat"); 856102336Salfred vsystem("ln -s usr/compat /compat"); 85745386Swpaul 85845386Swpaul /* BOGON #5: aliases database not build for bin */ 85945386Swpaul vsystem("newaliases"); 86045386Swpaul 86145386Swpaul /* Now run all the mtree stuff to fix things up */ 86245386Swpaul vsystem("mtree -deU -f /etc/mtree/BSD.root.dist -p /"); 86345386Swpaul vsystem("mtree -deU -f /etc/mtree/BSD.var.dist -p /var"); 86445386Swpaul vsystem("mtree -deU -f /etc/mtree/BSD.usr.dist -p /usr"); 86545386Swpaul 86645386Swpaul /* Do all the last ugly work-arounds here */ 86745386Swpaul } 86845386Swpaul return DITEM_SUCCESS | DITEM_RESTORE; 86945386Swpaul} 87045386Swpaul 87145386Swpaul/* Fix side-effects from the the XFree86 installation */ 87245386Swpaulint 87345386SwpaulinstallFixupXFree(dialogMenuItem *self) 87445386Swpaul{ 87545386Swpaul /* BOGON #1: XFree86 requires various specialized fixups */ 876102336Salfred if (directory_exists("/usr/X11R6")) { 877102336Salfred dialog_clear_norefresh(); 87845386Swpaul msgNotify("Fixing permissions in XFree86 tree.."); 87945386Swpaul vsystem("chmod -R a+r /usr/X11R6"); 88045386Swpaul vsystem("find /usr/X11R6 -type d | xargs chmod a+x"); 88145386Swpaul 88245386Swpaul /* Also do bogus minimal package registration so ports don't whine */ 88345386Swpaul if (file_readable("/usr/X11R6/lib/X11/pkgreg.tar.gz")) { 88445386Swpaul dialog_clear_norefresh(); 88545386Swpaul msgNotify("Installing package metainfo.."); 88645386Swpaul vsystem("tar xpzf /usr/X11R6/lib/X11/pkgreg.tar.gz -C / && rm /usr/X11R6/lib/X11/pkgreg.tar.gz"); 88745386Swpaul } 88845386Swpaul } 88945386Swpaul return DITEM_SUCCESS | DITEM_RESTORE; 89045386Swpaul} 89145386Swpaul 89245386Swpaul/* Go newfs and/or mount all the filesystems we've been asked to */ 89345386Swpaulint 89445386SwpaulinstallFilesystems(dialogMenuItem *self) 89545386Swpaul{ 89645386Swpaul int i, mountfailed; 89745386Swpaul Disk *disk; 89845386Swpaul Chunk *c1, *c2, *rootdev, *swapdev; 89945386Swpaul Device **devs; 90045386Swpaul PartInfo *root; 90145386Swpaul char dname[80]; 90245386Swpaul extern int MakeDevChunk(Chunk *c, char *n); 90345386Swpaul Boolean upgrade = FALSE; 904102336Salfred 905102336Salfred /* If we've already done this, bail out */ 90645386Swpaul if (!variable_cmp(DISK_LABELLED, "written")) 90745386Swpaul return DITEM_SUCCESS; 90845386Swpaul 90945386Swpaul upgrade = !variable_cmp(SYSTEM_STATE, "upgrade"); 91045386Swpaul if (!checkLabels(TRUE, &rootdev, &swapdev, NULL, NULL, NULL, NULL)) 91145386Swpaul return DITEM_FAILURE; 91245386Swpaul 91345386Swpaul if (rootdev) 91445386Swpaul root = (PartInfo *)rootdev->private_data; 915131654Sbms else 91645386Swpaul root = NULL; 91745386Swpaul 91845386Swpaul command_clear(); 91945386Swpaul if (swapdev && RunningAsInit) { 92045386Swpaul /* As the very first thing, try to get ourselves some swap space */ 92145386Swpaul sprintf(dname, "/dev/%s", swapdev->name); 92245386Swpaul if (!Fake && (!MakeDevChunk(swapdev, "/dev") || !file_readable(dname))) { 92345386Swpaul msgConfirm("Unable to make device node for %s in /dev!\n" 92445386Swpaul "The creation of filesystems will be aborted.", dname); 92545386Swpaul return DITEM_FAILURE; 92645386Swpaul } 92745386Swpaul 92845386Swpaul if (!Fake) { 92945386Swpaul if (!swapon(dname)) { 93045386Swpaul dialog_clear_norefresh(); 93145386Swpaul msgNotify("Added %s as initial swap device", dname); 93245386Swpaul } 93345386Swpaul else { 93445386Swpaul msgConfirm("WARNING! Unable to swap to %s: %s\n" 93545386Swpaul "This may cause the installation to fail at some point\n" 93645386Swpaul "if you don't have a lot of memory.", dname, strerror(errno)); 93745386Swpaul } 93845386Swpaul } 93945386Swpaul } 94045386Swpaul 94145386Swpaul if (rootdev && RunningAsInit) { 94245386Swpaul /* Next, create and/or mount the root device */ 94345386Swpaul sprintf(dname, "/dev/%s", rootdev->name); 94445386Swpaul if (!Fake && (!MakeDevChunk(rootdev, "/dev") || !file_readable(dname))) { 94545386Swpaul msgConfirm("Unable to make device node for %s in /dev!\n" 94645386Swpaul "The creation of filesystems will be aborted.", dname); 94745386Swpaul return DITEM_FAILURE | DITEM_RESTORE; 94845386Swpaul } 94945386Swpaul if (strcmp(root->mountpoint, "/")) 95045386Swpaul msgConfirm("Warning: %s is marked as a root partition but is mounted on %s", rootdev->name, root->mountpoint); 95145386Swpaul 95245386Swpaul if (root->newfs && (!upgrade || !msgNoYes("You are upgrading - are you SURE you want to newfs the root partition?"))) { 95345386Swpaul int i; 95498849Sken 95598849Sken dialog_clear_norefresh(); 95645386Swpaul msgNotify("Making a new root filesystem on %s", dname); 95745386Swpaul i = vsystem("%s %s", root->newfs_cmd, dname); 95845386Swpaul if (i) { 95945386Swpaul msgConfirm("Unable to make new root filesystem on %s!\n" 96045386Swpaul "Command returned status %d", dname, i); 96145386Swpaul return DITEM_FAILURE | DITEM_RESTORE; 96245386Swpaul } 96345386Swpaul } 96445386Swpaul else { 96545386Swpaul if (!upgrade) { 96645386Swpaul msgConfirm("Warning: Using existing root partition. It will be assumed\n" 96745386Swpaul "that you have the appropriate device entries already in /dev."); 96845386Swpaul } 96945386Swpaul dialog_clear_norefresh(); 97045386Swpaul msgNotify("Checking integrity of existing %s filesystem.", dname); 97145386Swpaul i = vsystem("fsck_ffs -y %s", dname); 97245386Swpaul if (i) 97345386Swpaul msgConfirm("Warning: fsck returned status of %d for %s.\n" 97445386Swpaul "This partition may be unsafe to use.", i, dname); 97545386Swpaul } 97645386Swpaul if (root->soft) { 97745386Swpaul i = vsystem("tunefs -n enable %s", dname); 97845386Swpaul if (i) 979102336Salfred msgConfirm("Warning: Unable to enable softupdates for root filesystem on %s", dname); 980102336Salfred } 98145386Swpaul 98245386Swpaul /* Switch to block device */ 98345386Swpaul sprintf(dname, "/dev/%s", rootdev->name); 98445386Swpaul if (Mount("/mnt", dname)) { 98545386Swpaul msgConfirm("Unable to mount the root file system on %s! Giving up.", dname); 98645386Swpaul return DITEM_FAILURE | DITEM_RESTORE; 98745386Swpaul } 98845386Swpaul 98950548Sbde /* Mount devfs for other partitions to mount */ 99045386Swpaul Mkdir("/mnt/dev"); 99145386Swpaul if (!Fake) 99245386Swpaul mountfailed = mount("devfs", "/mnt/dev", 0, NULL); 993131654Sbms 99445386Swpaul if (mountfailed) { 99545386Swpaul dialog_clear_norefresh(); 99645386Swpaul msgNotify("Copying initial device files.."); 99745386Swpaul /* Copy the boot floppy's dev files */ 99845386Swpaul if ((root->newfs || upgrade) && vsystem("find -x /dev | cpio %s -pdum /mnt", cpioVerbosity())) { 99945386Swpaul msgConfirm("Couldn't clone the /dev files!"); 100045386Swpaul return DITEM_FAILURE | DITEM_RESTORE; 100167405Sbmilekic } 100245386Swpaul } 100345386Swpaul } 100445386Swpaul 100567405Sbmilekic /* Now buzz through the rest of the partitions and mount them too */ 100667405Sbmilekic devs = deviceFind(NULL, DEVICE_TYPE_DISK); 1007131652Sbms for (i = 0; devs[i]; i++) { 100845386Swpaul if (!devs[i]->enabled) 100945386Swpaul continue; 101062793Sgallatin 101162793Sgallatin disk = (Disk *)devs[i]->private; 101245386Swpaul if (!disk->chunks) { 101345386Swpaul msgConfirm("No chunk list found for %s!", disk->name); 101445386Swpaul return DITEM_FAILURE | DITEM_RESTORE; 1015131654Sbms } 101645386Swpaul if (mountfailed) { 101745386Swpaul if (RunningAsInit && root && (root->newfs || upgrade)) { 101845386Swpaul Mkdir("/mnt/dev"); 101945386Swpaul if (!Fake) 102045386Swpaul MakeDevDisk(disk, "/mnt/dev"); 1021131654Sbms } 102245386Swpaul else if (!RunningAsInit && !Fake) 102345386Swpaul MakeDevDisk(disk, "/dev"); 102445386Swpaul } 102545386Swpaul 102645386Swpaul for (c1 = disk->chunks->part; c1; c1 = c1->next) { 102745386Swpaul if (c1->type == freebsd) { 102845386Swpaul for (c2 = c1->part; c2; c2 = c2->next) { 102945386Swpaul if (c2->type == part && c2->subtype != FS_SWAP && c2->private_data) { 1030131655Sbms PartInfo *tmp = (PartInfo *)c2->private_data; 1031131652Sbms 103245386Swpaul /* Already did root */ 1033131652Sbms if (c2 == rootdev) 103445386Swpaul continue; 103545386Swpaul 1036131654Sbms if (tmp->newfs && (!upgrade || !msgNoYes("You are upgrading - are you SURE you want to newfs /dev/%s?", c2->name))) 103745386Swpaul command_shell_add(tmp->mountpoint, "%s %s/dev/%s", tmp->newfs_cmd, RunningAsInit ? "/mnt" : "", c2->name); 103845386Swpaul else 103945386Swpaul command_shell_add(tmp->mountpoint, "fsck_ffs -y %s/dev/%s", RunningAsInit ? "/mnt" : "", c2->name); 104045386Swpaul if (tmp->soft) 1041131654Sbms command_shell_add(tmp->mountpoint, "tunefs -n enable %s/dev/%s", RunningAsInit ? "/mnt" : "", c2->name); 104245386Swpaul command_func_add(tmp->mountpoint, Mount, c2->name); 104345386Swpaul } 104445386Swpaul else if (c2->type == part && c2->subtype == FS_SWAP) { 104545386Swpaul char fname[80]; 104645386Swpaul int i; 1047102336Salfred 1048102336Salfred if (c2 == swapdev) 104999058Salfred continue; 105064837Sdwmalone sprintf(fname, "%s/dev/%s", RunningAsInit ? "/mnt" : "", c2->name); 105145386Swpaul i = (Fake || swapon(fname)); 105245386Swpaul if (!i) { 1053131655Sbms dialog_clear_norefresh(); 1054131655Sbms msgNotify("Added %s as an additional swap device", fname); 105545386Swpaul } 105645386Swpaul else { 105767405Sbmilekic msgConfirm("Unable to add %s as a swap device: %s", fname, strerror(errno)); 105845386Swpaul } 105945386Swpaul } 106067405Sbmilekic } 106145386Swpaul } 106245386Swpaul else if (c1->type == fat && c1->private_data && (root->newfs || upgrade)) { 106367405Sbmilekic char name[FILENAME_MAX]; 106445386Swpaul 106545386Swpaul sprintf(name, "%s/%s", RunningAsInit ? "/mnt" : "", ((PartInfo *)c1->private_data)->mountpoint); 106645386Swpaul Mkdir(name); 106745386Swpaul } 106845386Swpaul } 106964837Sdwmalone } 107064837Sdwmalone 107164837Sdwmalone command_sort(); 107264837Sdwmalone command_execute(); 107364837Sdwmalone if (!mountfailed && !Fake) 107464837Sdwmalone unmount("/mnt/dev", MNT_FORCE); 107545386Swpaul dialog_clear_norefresh(); 107645386Swpaul return DITEM_SUCCESS | DITEM_RESTORE; 107798849Sken} 107845386Swpaul 107945386Swpaulstatic char * 108045386SwpaulgetRelname(void) 108145386Swpaul{ 1082102336Salfred static char buf[64]; 1083102336Salfred size_t sz = (sizeof buf) - 1; 108445386Swpaul 108545386Swpaul if (sysctlbyname("kern.osrelease", buf, &sz, NULL, 0) != -1) { 108645386Swpaul buf[sz] = '\0'; 108745386Swpaul return buf; 108845386Swpaul } 108945386Swpaul else 109045386Swpaul return "<unknown>"; 109149036Swpaul} 1092111119Simp 109387846Sluigi/* Initialize various user-settable values to their defaults */ 1094131654Sbmsint 109545386SwpaulinstallVarDefaults(dialogMenuItem *self) 1096111119Simp{ 109745386Swpaul char *cp; 109845386Swpaul 1099131654Sbms /* Set default startup options */ 110045386Swpaul variable_set2(VAR_RELNAME, getRelname(), 0); 110149036Swpaul variable_set2(VAR_CPIO_VERBOSITY, "high", 0); 110249036Swpaul variable_set2(VAR_TAPE_BLOCKSIZE, DEFAULT_TAPE_BLOCKSIZE, 0); 110349036Swpaul variable_set2(VAR_INSTALL_ROOT, "/", 0); 110449036Swpaul variable_set2(VAR_INSTALL_CFG, "install.cfg", 0); 110549036Swpaul cp = getenv("EDITOR"); 110645386Swpaul if (!cp) 110745386Swpaul cp = "/usr/bin/ee"; 110848597Swpaul variable_set2(VAR_EDITOR, cp, 0); 110945386Swpaul variable_set2(VAR_FTP_USER, "ftp", 0); 111045386Swpaul variable_set2(VAR_BROWSER_PACKAGE, "links", 0); 111145386Swpaul variable_set2(VAR_BROWSER_BINARY, "/usr/local/bin/links", 0); 111245386Swpaul variable_set2(VAR_FTP_STATE, "passive", 0); 111345386Swpaul variable_set2(VAR_NFS_SECURE, "NO", -1); 1114147256Sbrooks if (OnVTY) 111558698Sjlemon variable_set2(VAR_FIXIT_TTY, "standard", 0); 111649036Swpaul else 111745386Swpaul variable_set2(VAR_FIXIT_TTY, "serial", 0); 111845386Swpaul variable_set2(VAR_PKG_TMPDIR, "/usr/tmp", 0); 1119131654Sbms variable_set2(VAR_MEDIA_TIMEOUT, itoa(MEDIA_TIMEOUT), 0); 112045386Swpaul if (getpid() != 1) 112145386Swpaul variable_set2(SYSTEM_STATE, "update", 0); 112245386Swpaul else 112345386Swpaul variable_set2(SYSTEM_STATE, "init", 0); 112445386Swpaul variable_set2(VAR_NEWFS_ARGS, "-b 8192 -f 1024", 0); 112545386Swpaul variable_set2(VAR_CONSTERM, "NO", 0); 1126102336Salfred return DITEM_SUCCESS; 1127102336Salfred} 112845386Swpaul 112945386Swpaul/* Load the environment up from various system configuration files */ 113045386Swpaulvoid 113145386SwpaulinstallEnvironment(void) 113245386Swpaul{ 113345386Swpaul configEnvironmentRC_conf(); 113445386Swpaul if (file_readable("/etc/resolv.conf")) 113549036Swpaul configEnvironmentResolv("/etc/resolv.conf"); 1136111119Simp} 113745386Swpaul 1138131654Sbms/* Copy the boot floppy contents into /stand */ 113945386SwpaulBoolean 114049036SwpaulcopySelf(void) 114149036Swpaul{ 114249036Swpaul int i; 114349036Swpaul 114449036Swpaul if (file_readable("/boot.help")) 114545386Swpaul vsystem("cp /boot.help /mnt"); 114649036Swpaul msgWeHaveOutput("Copying the boot floppy to /stand on root filesystem"); 114748597Swpaul i = vsystem("find -x /stand | cpio %s -pdum /mnt", cpioVerbosity()); 114845386Swpaul if (i) { 114945386Swpaul msgConfirm("Copy returned error status of %d!", i); 115045386Swpaul return FALSE; 115145386Swpaul } 115245386Swpaul 1153147256Sbrooks /* Copy the /etc files into their rightful place */ 115458698Sjlemon if (vsystem("cd /mnt/stand; find etc | cpio %s -pdum /mnt", cpioVerbosity())) { 115549036Swpaul msgConfirm("Couldn't copy up the /etc files!"); 115645386Swpaul return TRUE; 115745386Swpaul } 1158131654Sbms return TRUE; 115945386Swpaul} 116045386Swpaul 116198849Skenstatic void 116298849Skencreate_termcap(void) 116345386Swpaul{ 116445386Swpaul FILE *fp; 116545386Swpaul 116645386Swpaul const char *caps[] = { 1167102336Salfred termcap_vt100, termcap_cons25, termcap_cons25_m, termcap_cons25r, 1168102336Salfred termcap_cons25r_m, termcap_cons25l1, termcap_cons25l1_m, 116945386Swpaul termcap_xterm, NULL, 117045386Swpaul }; 117145386Swpaul const char **cp; 117245386Swpaul 117345386Swpaul if (!file_readable(TERMCAP_FILE)) { 117445386Swpaul Mkdir("/usr/share/misc"); 117545386Swpaul fp = fopen(TERMCAP_FILE, "w"); 117649036Swpaul if (!fp) { 117745386Swpaul msgConfirm("Unable to initialize termcap file. Some screen-oriented\nutilities may not work."); 117845386Swpaul return; 117945386Swpaul } 1180111119Simp cp = caps; 118145386Swpaul while (*cp) 1182131654Sbms fprintf(fp, "%s\n", *(cp++)); 118345386Swpaul fclose(fp); 118445386Swpaul } 118545386Swpaul} 118645386Swpaul