install.c revision 8596
1/*
2 * The new sysinstall program.
3 *
4 * This is probably the last program in the `sysinstall' line - the next
5 * generation being essentially a complete rewrite.
6 *
7 * $Id: install.c,v 1.22 1995/05/18 10:43:51 jkh Exp $
8 *
9 * Copyright (c) 1995
10 *	Jordan Hubbard.  All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer,
17 *    verbatim and that no modifications are made prior to this
18 *    point in the file.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 *    notice, this list of conditions and the following disclaimer in the
21 *    documentation and/or other materials provided with the distribution.
22 * 3. All advertising materials mentioning features or use of this software
23 *    must display the following acknowledgement:
24 *	This product includes software developed by Jordan Hubbard
25 *	for the FreeBSD Project.
26 * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to
27 *    endorse or promote products derived from this software without specific
28 *    prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED.  IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36 * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * SUCH DAMAGE.
41 *
42 */
43
44#include "sysinstall.h"
45#include <sys/disklabel.h>
46#include <sys/errno.h>
47#include <sys/fcntl.h>
48#include <unistd.h>
49
50Boolean SystemWasInstalled;
51
52static void	make_filesystems(void);
53static void	cpio_extract(void);
54static void	install_configuration_files(void);
55static void	do_final_setup(void);
56
57static Boolean
58preInstallCheck(void)
59{
60    if (!getenv(DISK_PARTITIONED)) {
61	msgConfirm("You need to partition your disk before you can proceed with\nthe installation.");
62
63	return FALSE;
64    }
65    if (!getenv(DISK_LABELLED)) {
66	msgConfirm("You need to assign disk labels before you can proceed with\nthe installation.");
67	return FALSE;
68    }
69    if (!Dists) {
70	msgConfirm("You haven't told me what distributions to load yet!\nPlease select a distribution from the Distributions menu.");
71	return FALSE;
72    }
73    if (!mediaVerify())
74	return FALSE;
75    return TRUE;
76}
77
78int
79installCommit(char *str)
80{
81    extern u_char boot1[], boot2[];
82    extern u_char mbr[], bteasy17[];
83    u_char *mbrContents;
84    Device **devs;
85    int i;
86
87    /* If things aren't kosher, or we refuse to proceed, bail. */
88    if (!preInstallCheck()
89	|| 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!"))
90	return 0;
91
92    mbrContents = NULL;
93    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."))
94	mbrContents = bteasy17;
95    else if (!msgYesNo("Would you like to remove an existing boot manager?"))
96	mbrContents = mbr;
97    devs = deviceFind(NULL, DEVICE_TYPE_DISK);
98    for (i = 0; devs[i]; i++) {
99	Disk *d = (Disk *)devs[i]->private;
100	Chunk *c1;
101
102	if (mbrContents) {
103	    Set_Boot_Mgr(d, mbrContents);
104	    mbrContents = NULL;
105	}
106	Set_Boot_Blocks(d, boot1, boot2);
107	msgNotify("Writing partition information to drive %s", d->name);
108	Write_Disk(d);
109
110	/* Now scan for bad blocks, if necessary */
111	for (c1 = d->chunks; c1; c1 = c1->next) {
112	    if (c1->flags & CHUNK_BAD144) {
113		int ret;
114
115		msgNotify("Running bad block scan on partition %s", c1->name);
116		ret = vsystem("bad144 /mnt/dev/%s 1234", c1->name);
117		if (ret)
118		    msgConfirm("Bad144 init on %s returned status of %d!", c1->name, ret);
119		ret = vsystem("bad144 -v -s /mnt/dev/%s", c1->name);
120		if (ret)
121		    msgConfirm("Bad144 scan on %s returned status of %d!", c1->name, ret);
122	    }
123	}
124    }
125    make_filesystems();
126    cpio_extract();
127    distExtractAll();
128    install_configuration_files();
129    do_final_setup();
130    return 1;
131}
132
133/* Go newfs and/or mount all the filesystems we've been asked to */
134static void
135make_filesystems(void)
136{
137    int i;
138    Disk *disk;
139    Chunk *c1, *c2;
140    Device **devs;
141
142    command_clear();
143    devs = deviceFind(NULL, DEVICE_TYPE_DISK);
144
145    /* First look for the root device and mount it */
146    for (i = 0; devs[i]; i++) {
147	disk = (Disk *)devs[i]->private;
148	if (!disk->chunks)
149	    msgFatal("No chunk list found for %s!", disk->name);
150	c1 = disk->chunks->part;
151	while (c1) {
152	    if (c1->type == freebsd) {
153		for (c2 = c1->part; c2; c2 = c2->next) {
154		    if (c2->type == part && c2->subtype != FS_SWAP &&
155			c2->private && c2->flags & CHUNK_IS_ROOT) {
156			char dname[40];
157			PartInfo *p = (PartInfo *)c2->private;
158
159			if (strcmp(p->mountpoint, "/"))
160			    continue;
161			sprintf(dname, "/dev/%sa", disk->name);
162			if (p->newfs) {
163			    int i;
164
165			    msgNotify("Making a new root filesystem on %s", dname);
166			    i = vsystem("newfs %s", dname);
167			    if (i) {
168				msgConfirm("Unable to make new root filesystem!  Command returned status %d", i);
169				return;
170			    }
171			}
172			else
173			    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.");
174			if (Mount(dname, NULL)) {
175			    msgConfirm("Unable to mount the root file system!  Giving up.");
176			    return;
177			}
178			else {
179			    extern int makedevs(void);
180
181			    chdir("/mnt");
182			    if (makedevs())
183				msgConfirm("Failed to make some of the devices in /mnt!");
184			    chdir("/");
185			    break;
186			}
187		    }
188		}
189	    }
190	}
191    }
192
193    /* Now buzz through the rest of the partitions and mount them too */
194    for (i = 0; devs[i]; i++) {
195	disk = (Disk *)devs[i]->private;
196	if (!disk->chunks)
197	    msgFatal("No chunk list found for %s!", disk->name);
198
199	/* Make the proper device mount points in /mnt/dev */
200	MakeDevDisk(disk, "/mnt/dev");
201
202	for (c1 = disk->chunks->part; c1; c1 = c1->next) {
203	    if (c1->type == freebsd) {
204		for (c2 = c1->part; c2; c2 = c2->next) {
205		    if (c2->type == part && c2->subtype != FS_SWAP && c2->private) {
206			PartInfo *tmp = (PartInfo *)c2->private;
207
208			if (!strcmp(tmp->mountpoint, "/"))
209			    continue;
210
211			if (tmp->newfs)
212			    command_shell_add(tmp->mountpoint,
213					      "%s %s", tmp->newfs_cmd, c2->name);
214			command_func_add(tmp->mountpoint, Mount, c2->name);
215		    }
216		}
217	    }
218	}
219    }
220    command_sort();
221    command_execute();
222}
223
224static void
225cpio_extract(void)
226{
227    int i, j, zpid, cpid, pfd[2];
228    extern int wait(int *status);
229
230    while (CpioFD == -1) {
231	msgConfirm("Please Insert CPIO floppy in floppy drive 0");
232	CpioFD = open("/dev/rfd0", O_RDONLY);
233    }
234    msgNotify("Extracting contents of CPIO floppy...");
235    pipe(pfd);
236    zpid = fork();
237    if (!zpid) {
238	close(0); dup(CpioFD); close(CpioFD);
239	close(1); dup(pfd[1]); close(pfd[1]);
240	close(pfd[0]);
241	i = execl("/stand/gunzip", "/stand/gunzip", 0);
242	msgDebug("/stand/gunzip command returns %d status\n", i);
243	exit(i);
244    }
245    cpid = fork();
246    if (!cpid) {
247	close(0); dup(pfd[0]); close(pfd[0]);
248	close(CpioFD);
249	close(pfd[1]);
250	close(1); open("/dev/null", O_WRONLY);
251	i = execl("/stand/cpio", "/stand/cpio", "-iduvm", 0);
252	msgDebug("/stand/cpio command returns %d status\n", i);
253	exit(i);
254    }
255    close(pfd[0]);
256    close(pfd[1]);
257    close(CpioFD);
258    i = wait(&j);
259    if (i < 0 || j)
260	msgFatal("Pid %d, status %d, cpio=%d, gunzip=%d.\nerror:%s",
261		 i, j, cpid, zpid, strerror(errno));
262    i = wait(&j);
263    if (i < 0 || j)
264	msgFatal("Pid %d, status %d, cpio=%d, gunzip=%d.\nerror:%s",
265		 i, j, cpid, zpid, strerror(errno));
266}
267
268static void
269install_configuration_files(void)
270{
271}
272
273static void
274do_final_setup(void)
275{
276}
277