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