install.c revision 8589
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.20 1995/05/17 16:16:08 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->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 -v -s /mnt/dev/%s", c1->name);
117		if (ret)
118		    msgConfirm("Bad144 scan on %s returned status of %d!", c1->name, ret);
119		/* XXX do something else XXX */
120	    }
121	}
122    }
123    make_filesystems();
124    cpio_extract();
125    distExtractAll();
126    install_configuration_files();
127    do_final_setup();
128    return 1;
129}
130
131/* Go newfs and/or mount all the filesystems we've been asked to */
132static void
133make_filesystems(void)
134{
135    int i;
136    Disk *disk;
137    Chunk *c1, *c2;
138    Device **devs;
139
140    command_clear();
141    devs = deviceFind(NULL, DEVICE_TYPE_DISK);
142
143    /* First look for the root device and mount it */
144    for (i = 0; devs[i]; i++) {
145	disk = (Disk *)devs[i]->private;
146	if (!disk->chunks)
147	    msgFatal("No chunk list found for %s!", disk->name);
148	c1 = disk->chunks->part;
149	while (c1) {
150	    if (c1->type == freebsd) {
151		for (c2 = c1->part; c2; c2 = c2->next) {
152		    if (c2->type == part && c2->subtype != FS_SWAP &&
153			c2->private && c2->flags & CHUNK_IS_ROOT) {
154			char dname[40];
155			PartInfo *p = (PartInfo *)c2->private;
156
157			if (strcmp(p->mountpoint, "/"))
158			    continue;
159			sprintf(dname, "/dev/%sa", disk->name);
160			if (p->newfs) {
161			    int i;
162
163			    msgNotify("Making a new root filesystem on %s", dname);
164			    i = vsystem("newfs %s", dname);
165			    if (i) {
166				msgConfirm("Unable to make new root filesystem!  Command returned status %d", i);
167				return;
168			    }
169			}
170			else
171			    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.");
172			if (Mount(dname, NULL)) {
173			    msgConfirm("Unable to mount the root file system!  Giving up.");
174			    return;
175			}
176			else {
177			    extern int makedevs(void);
178
179			    chdir("/mnt");
180			    if (makedevs())
181				msgConfirm("Failed to make some of the devices in /mnt!");
182			    chdir("/");
183			    break;
184			}
185		    }
186		}
187	    }
188	}
189    }
190
191    /* Now buzz through the rest of the partitions and mount them too */
192    for (i = 0; devs[i]; i++) {
193	disk = (Disk *)devs[i]->private;
194	if (!disk->chunks)
195	    msgFatal("No chunk list found for %s!", disk->name);
196
197	/* Make the proper device mount points in /mnt/dev */
198	MakeDevDisk(disk, "/mnt/dev");
199
200	for (c1 = disk->chunks->part; c1; c1 = c1->next) {
201	    if (c1->type == freebsd) {
202		for (c2 = c1->part; c2; c2 = c2->next) {
203		    if (c2->type == part && c2->subtype != FS_SWAP && c2->private) {
204			PartInfo *tmp = (PartInfo *)c2->private;
205
206			if (!strcmp(tmp->mountpoint, "/"))
207			    continue;
208
209			if (tmp->newfs)
210			    command_shell_add(tmp->mountpoint,
211					      "%s %s", tmp->newfs_cmd, c2->name);
212			command_func_add(tmp->mountpoint, Mount, c2->name);
213		    }
214		}
215	    }
216	}
217    }
218    command_sort();
219    command_execute();
220}
221
222static void
223cpio_extract(void)
224{
225    int i, j, zpid, cpid, pfd[2];
226    extern int wait(int *status);
227
228    while (CpioFD == -1) {
229	msgConfirm("Please Insert CPIO floppy in floppy drive 0");
230	CpioFD = open("/dev/rfd0", O_RDONLY);
231    }
232    msgNotify("Extracting contents of CPIO floppy...");
233    pipe(pfd);
234    zpid = fork();
235    if (!zpid) {
236	close(0); dup(CpioFD); close(CpioFD);
237	close(1); dup(pfd[1]); close(pfd[1]);
238	close(pfd[0]);
239	i = execl("/stand/gunzip", "/stand/gunzip", 0);
240	msgDebug("/stand/gunzip command returns %d status\n", i);
241	exit(i);
242    }
243    cpid = fork();
244    if (!cpid) {
245	close(0); dup(pfd[0]); close(pfd[0]);
246	close(CpioFD);
247	close(pfd[1]);
248	close(1); open("/dev/null", O_WRONLY);
249	i = execl("/stand/cpio", "/stand/cpio", "-iduvm", 0);
250	msgDebug("/stand/cpio command returns %d status\n", i);
251	exit(i);
252    }
253    close(pfd[0]);
254    close(pfd[1]);
255    close(CpioFD);
256    i = wait(&j);
257    if (i < 0 || j)
258	msgFatal("Pid %d, status %d, cpio=%d, gunzip=%d.\nerror:%s",
259		 i, j, cpid, zpid, strerror(errno));
260    i = wait(&j);
261    if (i < 0 || j)
262	msgFatal("Pid %d, status %d, cpio=%d, gunzip=%d.\nerror:%s",
263		 i, j, cpid, zpid, strerror(errno));
264}
265
266static void
267install_configuration_files(void)
268{
269}
270
271static void
272do_final_setup(void)
273{
274}
275