install.c revision 8576
141142Sobrien/* 238494Sobrien * The new sysinstall program. 338494Sobrien * 438494Sobrien * This is probably the last program in the `sysinstall' line - the next 538494Sobrien * generation being essentially a complete rewrite. 638494Sobrien * 738494Sobrien * $Id: install.c,v 1.18 1995/05/16 11:37:14 jkh Exp $ 838494Sobrien * 938494Sobrien * Copyright (c) 1995 1038494Sobrien * Jordan Hubbard. All rights reserved. 1138494Sobrien * 1238494Sobrien * Redistribution and use in source and binary forms, with or without 1338494Sobrien * modification, are permitted provided that the following conditions 1438494Sobrien * are met: 1538494Sobrien * 1. Redistributions of source code must retain the above copyright 1638494Sobrien * notice, this list of conditions and the following disclaimer, 1738494Sobrien * verbatim and that no modifications are made prior to this 1838494Sobrien * point in the file. 1938494Sobrien * 2. Redistributions in binary form must reproduce the above copyright 2038494Sobrien * notice, this list of conditions and the following disclaimer in the 2138494Sobrien * documentation and/or other materials provided with the distribution. 2238494Sobrien * 3. All advertising materials mentioning features or use of this software 2338494Sobrien * must display the following acknowledgement: 2438494Sobrien * This product includes software developed by Jordan Hubbard 2538494Sobrien * for the FreeBSD Project. 2638494Sobrien * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to 2738494Sobrien * endorse or promote products derived from this software without specific 2838494Sobrien * prior written permission. 2938494Sobrien * 3038494Sobrien * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND 3138494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 3238494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3338494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE 3438494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3538494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3638494Sobrien * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) 3738494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3838494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3938494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 4038494Sobrien * SUCH DAMAGE. 4138494Sobrien * 4238494Sobrien */ 4338494Sobrien 4438494Sobrien#include "sysinstall.h" 4538494Sobrien#include <sys/disklabel.h> 4638494Sobrien#include <sys/errno.h> 4738494Sobrien#include <sys/fcntl.h> 4838494Sobrien#include <unistd.h> 4938494Sobrien 5038494SobrienBoolean SystemWasInstalled; 5138494Sobrien 5238494Sobrienstatic void make_filesystems(void); 5338494Sobrienstatic void cpio_extract(void); 5438494Sobrienstatic void install_configuration_files(void); 5538494Sobrienstatic void do_final_setup(void); 5638494Sobrien 5738494Sobrienint 5838494SobrieninstallCommit(char *str) 5938494Sobrien{ 6038494Sobrien extern u_char boot1[], boot2[]; 6138494Sobrien extern u_char mbr[], bteasy17[]; 6238494Sobrien u_char *mbrContents; 6338494Sobrien Device **devs; 6438494Sobrien int i; 6538494Sobrien 6638494Sobrien if (!getenv(DISK_PARTITIONED)) { 6738494Sobrien msgConfirm("You need to partition your disk before you can proceed with\nthe installation."); 6838494Sobrien 6938494Sobrien return 0; 7038494Sobrien } 7138494Sobrien if (!getenv(DISK_LABELLED)) { 7238494Sobrien msgConfirm("You need to assign disk labels before you can proceed with\nthe installation."); 7338494Sobrien return 0; 7438494Sobrien } 7538494Sobrien if (!Dists) { 7638494Sobrien msgConfirm("You haven't told me what distributions to load yet!\nPlease select a distribution from the Distributions menu."); 7738494Sobrien return 0; 7838494Sobrien } 7938494Sobrien if (!mediaVerify()) 8038494Sobrien return 0; 8138494Sobrien 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!")) 8238494Sobrien return 0; 8338494Sobrien 8438494Sobrien mbrContents = NULL; 8538494Sobrien 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.")) 8638494Sobrien mbrContents = bteasy17; 8738494Sobrien else if (!msgYesNo("Would you like to remove an existing boot manager?")) 8838494Sobrien mbrContents = mbr; 8938494Sobrien devs = deviceFind(NULL, DEVICE_TYPE_DISK); 9038494Sobrien for (i = 0; devs[i]; i++) { 9138494Sobrien Disk *d = (Disk *)devs[i]->private; 9238494Sobrien 9338494Sobrien if (mbrContents) { 9438494Sobrien Set_Boot_Mgr(d, mbrContents); 9538494Sobrien mbrContents = NULL; 9638494Sobrien } 9738494Sobrien Set_Boot_Blocks(d, boot1, boot2); 9838494Sobrien msgNotify("Writing partition information to drive %s", d->name); 9938494Sobrien Write_Disk(d); 10038494Sobrien } 10138494Sobrien make_filesystems(); 10238494Sobrien cpio_extract(); 10338494Sobrien install_configuration_files(); 10438494Sobrien do_final_setup(); 10538494Sobrien return 1; 10638494Sobrien} 10738494Sobrien 10838494Sobrien/* Go newfs and/or mount all the filesystems we've been asked to */ 10941142Sobrienstatic void 11038494Sobrienmake_filesystems(void) 11138494Sobrien{ 11238494Sobrien int i; 11338494Sobrien Disk *disk; 11438494Sobrien Chunk *c1, *c2; 11538494Sobrien Device **devs; 11638494Sobrien 11738494Sobrien command_clear(); 11838494Sobrien devs = deviceFind(NULL, DEVICE_TYPE_DISK); 11938494Sobrien 12038494Sobrien /* First look for the root device and mount it */ 12138494Sobrien for (i = 0; devs[i]; i++) { 12238494Sobrien disk = (Disk *)devs[i]->private; 12338494Sobrien if (!disk->chunks) 12438494Sobrien msgFatal("No chunk list found for %s!", disk->name); 12541142Sobrien c1 = disk->chunks->part; 12638494Sobrien while (c1) { 12738494Sobrien if (c1->type == freebsd) { 12838494Sobrien for (c2 = c1->part; c2; c2 = c2->next) { 12938494Sobrien if (c2->type == part && c2->subtype != FS_SWAP && 13038494Sobrien c2->private && c2->flags & CHUNK_IS_ROOT) { 13138494Sobrien char dname[40]; 13238494Sobrien PartInfo *p = (PartInfo *)c2->private; 13338494Sobrien 13438494Sobrien if (strcmp(p->mountpoint, "/")) 13538494Sobrien continue; 13641142Sobrien sprintf(dname, "/dev/%sa", disk->name); 13738494Sobrien if (p->newfs) { 13838494Sobrien msgDebug("newfs %s", dname); 13938494Sobrien if (vsystem("newfs %s", dname)) { 14038494Sobrien msgConfirm("Unable to make new root filesystem!"); 14138494Sobrien return; 14238494Sobrien } 14338494Sobrien } 14438494Sobrien else 14538494Sobrien 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."); 14638494Sobrien if (Mount(dname, NULL)) { 14738494Sobrien msgConfirm("Unable to mount the root file system! Giving up."); 14838494Sobrien return; 14938494Sobrien } 15038494Sobrien else 15138494Sobrien break; 15238494Sobrien } 15338494Sobrien } 15438494Sobrien } 15538494Sobrien } 15638494Sobrien } 15738494Sobrien 15838494Sobrien /* Now buzz through the rest of the devices and mount them too */ 15938494Sobrien for (i = 0; devs[i]; i++) { 16038494Sobrien disk = (Disk *)devs[i]->private; 16138494Sobrien if (!disk->chunks) 16238494Sobrien msgFatal("No chunk list found for %s!", disk->name); 16338494Sobrien 16438494Sobrien /* Make the proper device mount points in /mnt/dev */ 16538494Sobrien MakeDevDisk(disk, "/mnt/dev"); 16641142Sobrien 16741142Sobrien /* Now make all the other devices the first time around */ 16838494Sobrien if (i == 0) { 16938494Sobrien extern int makedevs(void); 17038494Sobrien 17138494Sobrien chdir("/mnt"); 17238494Sobrien if (makedevs()) { 17338494Sobrien if (msgYesNo("Failed to make some of the devices in /mnt! Continue?")) 17438494Sobrien return; 17538494Sobrien } 17638494Sobrien chdir("/"); 17738494Sobrien } 17838494Sobrien 17938494Sobrien for (c1 = disk->chunks->part; c1; c1 = c1->next) { 18038494Sobrien if (c1->type == freebsd) { 18138494Sobrien for (c2 = c1->part; c2; c2 = c2->next) { 18238494Sobrien if (c2->type == part && c2->subtype != FS_SWAP && c2->private) { 18338494Sobrien PartInfo *tmp = (PartInfo *)c2->private; 18438494Sobrien 18538494Sobrien if (!strcmp(tmp->mountpoint, "/")) 18638494Sobrien continue; 18738494Sobrien 18838494Sobrien if (tmp->newfs) 18938494Sobrien command_shell_add(tmp->mountpoint, 19038494Sobrien "%s %s", tmp->newfs_cmd, c2->name); 19138494Sobrien command_func_add(tmp->mountpoint, Mount, c2->name); 19238494Sobrien } 19338494Sobrien } 19438494Sobrien } 19538494Sobrien } 19638494Sobrien } 19738494Sobrien command_sort(); 19838494Sobrien command_execute(); 19938494Sobrien} 20038494Sobrien 20138494Sobrienstatic void 20238494Sobriencpio_extract(void) 20338494Sobrien{ 20438494Sobrien int i, j, zpid, cpid, pfd[2]; 20538494Sobrien extern int wait(int *status); 20638494Sobrien 20738494Sobrien while (CpioFD == -1) { 20838494Sobrien msgConfirm("Please Insert CPIO floppy in floppy drive 0"); 20938494Sobrien CpioFD = open("/dev/rfd0", O_RDONLY); 21038494Sobrien } 21138494Sobrien msgNotify("Extracting contents of CPIO floppy..."); 21238494Sobrien pipe(pfd); 21338494Sobrien zpid = fork(); 21438494Sobrien if (!zpid) { 21538494Sobrien close(0); dup(CpioFD); close(CpioFD); 21638494Sobrien close(1); dup(pfd[1]); close(pfd[1]); 21738494Sobrien close(pfd[0]); 21838494Sobrien i = execl("/stand/gunzip", "/stand/gunzip", 0); 21938494Sobrien msgDebug("/stand/gunzip command returns %d status\n", i); 22038494Sobrien exit(i); 22138494Sobrien } 22238494Sobrien cpid = fork(); 22338494Sobrien if (!cpid) { 22438494Sobrien close(0); dup(pfd[0]); close(pfd[0]); 22538494Sobrien close(CpioFD); 22638494Sobrien close(pfd[1]); 22738494Sobrien close(1); open("/dev/null", O_WRONLY); 22838494Sobrien i = execl("/stand/cpio", "/stand/cpio", "-iduvm", 0); 22938494Sobrien msgDebug("/stand/cpio command returns %d status\n", i); 23038494Sobrien exit(i); 23138494Sobrien } 23238494Sobrien close(pfd[0]); 23338494Sobrien close(pfd[1]); 23438494Sobrien close(CpioFD); 23538494Sobrien i = wait(&j); 23638494Sobrien if (i < 0 || j) 23738494Sobrien msgFatal("Pid %d, status %d, cpio=%d, gunzip=%d.\nerror:%s", 23838494Sobrien i, j, cpid, zpid, strerror(errno)); 23938494Sobrien i = wait(&j); 24038494Sobrien if (i < 0 || j) 24138494Sobrien msgFatal("Pid %d, status %d, cpio=%d, gunzip=%d.\nerror:%s", 24238494Sobrien i, j, cpid, zpid, strerror(errno)); 24338494Sobrien} 24438494Sobrien 24538494Sobrienstatic void 24638494Sobrieninstall_configuration_files(void) 24738494Sobrien{ 24838494Sobrien} 24938494Sobrien 25038494Sobrienstatic void 25138494Sobriendo_final_setup(void) 25238494Sobrien{ 25338494Sobrien} 25438494Sobrien