install.c revision 8654
12340Sbde/* 250476Speter * The new sysinstall program. 31638Srgrimes * 42340Sbde * This is probably the last program in the `sysinstall' line - the next 578347Sobrien * generation being essentially a complete rewrite. 61638Srgrimes * 7209024Simp * $Id: install.c,v 1.39 1995/05/20 16:22:42 jkh Exp $ 8209024Simp * 9209024Simp * Copyright (c) 1995 10215149Sdim * Jordan Hubbard. All rights reserved. 11215149Sdim * 12215149Sdim * Redistribution and use in source and binary forms, with or without 13215149Sdim * modification, are permitted provided that the following conditions 14215149Sdim * are met: 15209024Simp * 1. Redistributions of source code must retain the above copyright 16300438Sian * notice, this list of conditions and the following disclaimer, 17209024Simp * verbatim and that no modifications are made prior to this 18209024Simp * point in the file. 19284345Ssjg * 2. Redistributions in binary form must reproduce the above copyright 20284345Ssjg * notice, this list of conditions and the following disclaimer in the 21284345Ssjg * documentation and/or other materials provided with the distribution. 22290816Ssjg * 3. All advertising materials mentioning features or use of this software 23290956Ssjg * must display the following acknowledgement: 24284345Ssjg * This product includes software developed by Jordan Hubbard 25284345Ssjg * for the FreeBSD Project. 26290816Ssjg * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to 27290956Ssjg * endorse or promote products derived from this software without specific 28290816Ssjg * prior written permission. 29290816Ssjg * 30284345Ssjg * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND 31287932Sbdrewery * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32287932Sbdrewery * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33287932Sbdrewery * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE 34287932Sbdrewery * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35287932Sbdrewery * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 36284598Ssjg * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) 37284598Ssjg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 38287187Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 39287187Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 40287187Simp * SUCH DAMAGE. 41287187Simp * 42284345Ssjg */ 43287924Sbdrewery 44287924Sbdrewery#include "sysinstall.h" 45301886Sbdrewery#include <sys/disklabel.h> 46301886Sbdrewery#include <sys/errno.h> 47301886Sbdrewery#include <sys/fcntl.h> 48301886Sbdrewery#include <sys/wait.h> 49301886Sbdrewery#include <unistd.h> 50290816Ssjg 51287187SimpBoolean SystemWasInstalled; 52301886Sbdrewery 53296118Sbdrewerystatic void make_filesystems(void); 54300526Sbdrewerystatic void copy_self(void); 55301466Sbdrewerystatic void cpio_extract(void); 56301466Sbdrewerystatic void install_configuration_files(void); 57301466Sbdrewerystatic void do_final_setup(void); 58296123Sbdrewery 59296123Sbdrewerystatic Boolean 60296123SbdrewerypreInstallCheck(void) 61296123Sbdrewery{ 62294350Sbdrewery if (!getenv(DISK_PARTITIONED)) { 63296118Sbdrewery msgConfirm("You need to partition your disk before you can proceed with\nthe installation."); 64284345Ssjg 65301466Sbdrewery return FALSE; 66301466Sbdrewery } 67301466Sbdrewery if (!getenv(DISK_LABELLED)) { 68294350Sbdrewery msgConfirm("You need to assign disk labels before you can proceed with\nthe installation."); 69301466Sbdrewery return FALSE; 70296118Sbdrewery } 71296118Sbdrewery if (!Dists) { 72296118Sbdrewery msgConfirm("You haven't told me what distributions to load yet!\nPlease select a distribution from the Distributions menu."); 73301467Sbdrewery return FALSE; 74301467Sbdrewery } 75301467Sbdrewery return TRUE; 76301467Sbdrewery} 77301467Sbdrewery 78302073Sbdrewerystatic void 79302073SbdreweryinstallInitial(void) 80301467Sbdrewery{ 81301467Sbdrewery extern u_char boot1[], boot2[]; 82301467Sbdrewery extern u_char mbr[], bteasy17[]; 83301467Sbdrewery u_char *mbrContents; 84301467Sbdrewery Device **devs; 85301467Sbdrewery int i; 86301467Sbdrewery static Boolean alreadyDone = FALSE; 87301467Sbdrewery 88301467Sbdrewery if (alreadyDone) 89301467Sbdrewery return; 90301467Sbdrewery 91301467Sbdrewery /* If things aren't kosher, or we refuse to proceed, bail. */ 92294349Sbdrewery if (!preInstallCheck() 93301467Sbdrewery || 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!")) 94301467Sbdrewery return; 95301467Sbdrewery 96284345Ssjg mbrContents = NULL; 97284345Ssjg if (!msgYesNo("Would you like to install a boot manager?\n\nThis will allow you to easily select between other operating systems\non the first disk, or boot from a disk other than the first.")) 98291312Sbdrewery mbrContents = bteasy17; 99291312Sbdrewery else if (!msgYesNo("Would you like to remove an existing boot manager?")) 100291312Sbdrewery mbrContents = mbr; 101287187Simp devs = deviceFind(NULL, DEVICE_TYPE_DISK); 102284345Ssjg for (i = 0; devs[i]; i++) { 103287879Sbdrewery Disk *d = (Disk *)devs[i]->private; 104287924Sbdrewery Chunk *c1; 105287924Sbdrewery 106287187Simp if (!devs[i]->enabled) 107287187Simp continue; 10819343Ssteve 10919343Ssteve if (mbrContents) { 11019343Ssteve Set_Boot_Mgr(d, mbrContents); 11119343Ssteve mbrContents = NULL; 11219343Ssteve } 11319343Ssteve Set_Boot_Blocks(d, boot1, boot2); 11419343Ssteve msgNotify("Writing partition information to drive %s", d->name); 11519343Ssteve Write_Disk(d); 116292718Scperciva 117292718Scperciva /* Now scan for bad blocks, if necessary */ 118292718Scperciva for (c1 = d->chunks->part; c1; c1 = c1->next) { 119292718Scperciva if (c1->flags & CHUNK_BAD144) { 12019343Ssteve int ret; 12119343Ssteve 12219343Ssteve msgNotify("Running bad block scan on partition %s", c1->name); 12319343Ssteve ret = vsystem("bad144 -v /dev/r%s 1234", c1->name); 124117173Sru if (ret) 12519343Ssteve msgConfirm("Bad144 init on %s returned status of %d!", c1->name, ret); 1261638Srgrimes ret = vsystem("bad144 -v -s /dev/r%s", c1->name); 1272340Sbde if (ret) 12819343Ssteve msgConfirm("Bad144 scan on %s returned status of %d!", c1->name, ret); 12919343Ssteve } 13019343Ssteve } 131264367Sdes } 13219343Ssteve make_filesystems(); 1332340Sbde copy_self(); 134264367Sdes dialog_clear(); 135264367Sdes cpio_extract(); 136264367Sdes alreadyDone = TRUE; 1371638Srgrimes} 1382340Sbde 1392340Sbdestatic void 140217100SkibinstallFinal(void) 1411638Srgrimes{ 14219343Ssteve static Boolean alreadyDone = FALSE; 14319343Ssteve 144125445Sbde if (alreadyDone) 14519343Ssteve return; 1462340Sbde install_configuration_files(); 147209024Simp do_final_setup(); 148177865Sobrien alreadyDone = TRUE; 149173375Scognet} 150177865Sobrien 15119343Ssteveint 152173850SjbinstallCommit(char *str) 153173850Sjb{ 154173375Scognet installInitial(); 155173850Sjb if (!mediaVerify()) 156202807Ssepotvin return 0; 1571638Srgrimes distExtractAll(); 158281258Smarkj installFinal(); 159281258Smarkj return 0; 160281258Smarkj} 161281258Smarkj 162281258Smarkj/* Go newfs and/or mount all the filesystems we've been asked to */ 163281258Smarkjstatic void 164179184Sjbmake_filesystems(void) 165179184Sjb{ 166179184Sjb int i; 167179184Sjb Disk *disk; 168179184Sjb Chunk *c1, *c2; 169277273Swill Device **devs; 170179184Sjb 171179184Sjb command_clear(); 172179184Sjb devs = deviceFind(NULL, DEVICE_TYPE_DISK); 173179184Sjb 1742419Spaul /* First look for the root device and mount it */ 175204024Smarcel for (i = 0; devs[i]; i++) { 176202807Ssepotvin disk = (Disk *)devs[i]->private; 1771638Srgrimes msgDebug("Scanning disk %s for root filesystem\n", disk->name); 178281258Smarkj if (!disk->chunks) 179281258Smarkj msgFatal("No chunk list found for %s!", disk->name); 1801638Srgrimes for (c1 = disk->chunks->part; c1; c1 = c1->next) { 181125119Sru if (c1->type == freebsd) { 1822340Sbde for (c2 = c1->part; c2; c2 = c2->next) { 1832340Sbde if (c2->type == part && c2->subtype != FS_SWAP && 1842340Sbde c2->private && c2->flags & CHUNK_IS_ROOT) { 1852340Sbde char dname[40]; 1862340Sbde PartInfo *p = (PartInfo *)c2->private; 1872340Sbde 1882340Sbde if (strcmp(p->mountpoint, "/")) { 1892340Sbde msgConfirm("Warning: %s is marked as a root partition but is mounted on %s", c2->name, p->mountpoint); 1902340Sbde continue; 1912340Sbde } 1921638Srgrimes if (p->newfs) { 193289460Sbdrewery int i; 194289460Sbdrewery 195289460Sbdrewery sprintf(dname, "/dev/r%sa", disk->name); 196289460Sbdrewery msgNotify("Making a new root filesystem on %s", dname); 197289460Sbdrewery i = vsystem("newfs %s", dname); 198289460Sbdrewery if (i) { 199133369Sharti msgConfirm("Unable to make new root filesystem! Command returned status %d", i); 200133369Sharti return; 201133369Sharti } 202133369Sharti } 203133369Sharti else 20419343Ssteve 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."); 20519343Ssteve sprintf(dname, "/dev/%sa", disk->name); 20619343Ssteve if (Mount("/mnt", dname)) { 20719343Ssteve msgConfirm("Unable to mount the root file system! Giving up."); 2082340Sbde return; 2092340Sbde } 21019343Ssteve else { 2112340Sbde extern int makedevs(void); 2121638Srgrimes 2135257Sache msgNotify("Making device files"); 2145257Sache if (Mkdir("/mnt/dev", NULL) 2152340Sbde || chdir("/mnt/dev") 2162340Sbde || makedevs()) 2171638Srgrimes msgConfirm("Failed to make some of the devices in /mnt!"); 2182340Sbde if (Mkdir("/mnt/stand", NULL)) 219269114Ssjg msgConfirm("Unable to make /mnt/stand directory!"); 220269114Ssjg chdir("/"); 2211638Srgrimes break; 2222340Sbde } 22392813Sru } 22492491Smarkm } 22592491Smarkm } 226120485Smarkm } 22792491Smarkm } 2281638Srgrimes 2292340Sbde /* Now buzz through the rest of the partitions and mount them too */ 2301638Srgrimes for (i = 0; devs[i]; i++) { 231234575Simp disk = (Disk *)devs[i]->private; 232234575Simp if (!disk->chunks) 233286791Srpaulo msgFatal("No chunk list found for %s!", disk->name); 234234575Simp 23536054Sbde /* Make the proper device mount points in /mnt/dev */ 23636054Sbde MakeDevDisk(disk, "/mnt/dev"); 23736054Sbde 238244236Semaste for (c1 = disk->chunks->part; c1; c1 = c1->next) { 239244236Semaste if (c1->type == freebsd) { 240274503Sandrew for (c2 = c1->part; c2; c2 = c2->next) { 241274503Sandrew if (c2->type == part && c2->subtype != FS_SWAP && c2->private) { 2422340Sbde PartInfo *tmp = (PartInfo *)c2->private; 2432340Sbde 2441638Srgrimes if (!strcmp(tmp->mountpoint, "/")) 2452340Sbde continue; 2462340Sbde 247244366Semaste if (tmp->newfs) 2481638Srgrimes command_shell_add(tmp->mountpoint, 2492340Sbde "%s /mnt/dev/r%s", tmp->newfs_cmd, c2->name); 2502340Sbde command_func_add(tmp->mountpoint, Mount, c2->name); 251272887Sbapt } 252272887Sbapt } 253272887Sbapt } 254272887Sbapt } 2552340Sbde } 25619343Ssteve command_sort(); 25719343Ssteve command_execute(); 25819343Ssteve} 2592340Sbde 26019343Ssteve/* Copy the boot floppy contents into /stand */ 2612340Sbdestatic void 26219343Sstevecopy_self(void) 263129163Sbde{ 26419343Ssteve int i; 26519343Ssteve 26619343Ssteve msgNotify("Copying the boot floppy to /stand on root filesystem"); 26719343Ssteve i = vsystem("find -x / | cpio -pdmv /mnt"); 26819343Ssteve if (i) 26919343Ssteve msgConfirm("Copy returned error status of %d!", i); 27019343Ssteve} 27111613Sbde 27219481Salexstatic void 27319343Sstevecpio_extract(void) 27419343Ssteve{ 27519481Salex int i, j, zpid, cpid, pfd[2]; 27619343Ssteve 27719343Ssteve tryagain: 278211243Swill while (CpioFD == -1) { 27919343Ssteve msgConfirm("Please Insert CPIO floppy in floppy drive 0"); 28019343Ssteve CpioFD = open("/dev/rfd0", O_RDWR); 28119343Ssteve if (CpioFD >= 0) 28219343Ssteve break; 28319343Ssteve msgDebug("Error on open of cpio floppy: %s (%d)\n", strerror(errno), errno); 28419481Salex } 28519343Ssteve j = fork(); 28619343Ssteve if (!j) { 28719481Salex chroot("/mnt"); chdir("/"); 28819343Ssteve msgNotify("Extracting contents of CPIO floppy..."); 28919343Ssteve pipe(pfd); 29019481Salex zpid = fork(); 29119481Salex if (!zpid) { 29239208Sobrien dup2(CpioFD, 0); close(CpioFD); 29319343Ssteve dup2(pfd[1], 1); close(pfd[1]); 29419343Ssteve close(pfd[0]); 29519343Ssteve i = execl("/stand/gunzip", "/stand/gunzip", 0); 29619481Salex msgDebug("/stand/gunzip command returns %d status\n", i); 29719481Salex exit(i); 29839208Sobrien } 29919343Ssteve cpid = fork(); 30019343Ssteve if (!cpid) { 30119343Ssteve dup2(pfd[0], 0); close(pfd[0]); 30219481Salex close(CpioFD); 30319343Ssteve close(pfd[1]); 30419343Ssteve if (DebugFD != -1) { 30519343Ssteve dup2(DebugFD, 1); 30619481Salex dup2(DebugFD, 2); 30719343Ssteve } 30819343Ssteve else { 30919343Ssteve close(1); open("/dev/null", O_WRONLY); 31019481Salex dup2(1, 2); 31119481Salex } 31239208Sobrien i = execl("/stand/cpio", "/stand/cpio", "-iduvm", 0); 31319343Ssteve msgDebug("/stand/cpio command returns %d status\n", i); 31419343Ssteve exit(i); 31519481Salex } 31619481Salex close(pfd[0]); 31739208Sobrien close(pfd[1]); 31819343Ssteve close(CpioFD); 31919343Ssteve 32019343Ssteve i = waitpid(zpid, &j, 0); 32119343Ssteve if (i < 0 || j) { 32219343Ssteve msgConfirm("gunzip returned status of %d, error was: %s (%d)!", j, strerror(errno), errno); 323301284Sbdrewery exit(1); 324296119Sbdrewery } 32511613Sbde i = waitpid(cpid, &j, 0); 32611613Sbde if (i < 0 || j) { 327301284Sbdrewery msgConfirm("cpio returned status of %d, error was: %s (%d)!", j, strerror(errno), errno); 328103713Smarkm exit(2); 329103713Smarkm } 330103713Smarkm exit(0); 331301284Sbdrewery } 332103713Smarkm else 333103713Smarkm i = wait(&j); 334103713Smarkm if (i < 0 || j || access("/mnt/OK", R_OK) == -1) { 335301284Sbdrewery msgConfirm("CPIO floppy did not extract properly! Please verify\nthat your media is correct and try again"); 33677817Sobrien close(CpioFD); 337228137Sfjoe CpioFD = -1; 33877817Sobrien goto tryagain; 339301284Sbdrewery } 340279980Sdim unlink("/mnt/OK"); 341228137Sfjoe} 3421638Srgrimes 343301284Sbdrewerystatic void 34477817Sobrieninstall_configuration_files(void) 34577817Sobrien{ 346301284Sbdrewery} 347279980Sdim 3481844Swollmanstatic void 349301284Sbdrewerydo_final_setup(void) 350279980Sdim{ 351228137Sfjoe} 35236054Sbde