Deleted Added
full compact
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.45 1995/05/21 01:56:01 phk 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 <sys/wait.h>
49#include <unistd.h>
50
51Boolean SystemWasInstalled;
52
53static void make_filesystems(void);
54static void copy_self(void);
55static void cpio_extract(void);
56static void install_configuration_files(void);
57static void do_final_setup(void);
58
59static void
60installInitial(void)
61{
62 extern u_char boot1[], boot2[];
63 extern u_char mbr[], bteasy17[];
64 u_char *mbrContents;
65 Device **devs;
66 int i;
67 static Boolean alreadyDone = FALSE;
68 char *cp;
69
70 if (alreadyDone)
71 return;
72
73 if (!getenv(DISK_PARTITIONED)) {
74 msgConfirm("You need to partition your disk before you can proceed with\nthe installation.");
75 return;
76 }
77 if (!getenv(DISK_LABELLED)) {
78 msgConfirm("You need to assign disk labels before you can proceed with\nthe installation.");
79 return;
80 }
81
82 /* Figure out what kind of MBR the user wants */
83 dmenuOpenSimple(&MenuMBRType);
84 mbrContents = NULL;
85 cp = getenv("bootManager");
86 if (cp) {
87 if (!strcmp(cp, "bteasy"))
88 mbrContents = bteasy17;
89 else if (!strcmp(cp, "mbr"))
90 mbrContents = mbr;
91 }
92
93 /* If we refuse to proceed, bail. */
94 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!"))
95 return;
96
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 (!devs[i]->enabled)
103 continue;
104
105 if (mbrContents) {
106 Set_Boot_Mgr(d, mbrContents);
107 mbrContents = NULL;
108 }
109 Set_Boot_Blocks(d, boot1, boot2);
110 msgNotify("Writing partition information to drive %s", d->name);
111 Write_Disk(d);
112
113 /* Now scan for bad blocks, if necessary */
114 for (c1 = d->chunks->part; c1; c1 = c1->next) {
115 if (c1->flags & CHUNK_BAD144) {
116 int ret;
117
118 msgNotify("Running bad block scan on partition %s", c1->name);
119 ret = vsystem("bad144 -v /dev/r%s 1234", c1->name);
120 if (ret)
121 msgConfirm("Bad144 init on %s returned status of %d!",
122 c1->name, ret);
123 ret = vsystem("bad144 -v -s /dev/r%s", c1->name);
124 if (ret)
125 msgConfirm("Bad144 scan on %s returned status of %d!",
126 c1->name, ret);
127 }
128 }
129 }
130 make_filesystems();
131 copy_self();
132 dialog_clear();
133 chroot("/mnt");
134 chdir("/");
135 cpio_extract();
136 alreadyDone = TRUE;
137}
138
139static void
140installFinal(void)
141{
142 static Boolean alreadyDone = FALSE;
143
144 if (alreadyDone)
145 return;
146 install_configuration_files();
147 do_final_setup();
148 alreadyDone = TRUE;
149}
150
151/*
152 * What happens when we select "GO". This is broken into a 3 stage installation so that
153 * the user can do a full installation but come back here again to load more distributions,
154 * perhaps from a different media type. This would allow, for example, the user to load the
155 * majority of the system from CDROM and then use ftp to load just the DES dist.
156 */
157int
158installCommit(char *str)
159{
160 if (!Dists) {
161 msgConfirm("You haven't told me what distributions to load yet!\nPlease select a distribution from the Distributions menu.");
162 return 0;
163 }
164 if (!mediaVerify())
165 return 0;
166
167 installInitial();
168 distExtractAll();
169 installFinal();
170 return 0;
171}
172
173/* Go newfs and/or mount all the filesystems we've been asked to */
174static void
175make_filesystems(void)
176{
177 int i;
178 Disk *disk;
179 Chunk *c1, *c2;
180 Device **devs;
181
182 command_clear();
183 devs = deviceFind(NULL, DEVICE_TYPE_DISK);
184
185 /* First look for the root device and mount it */
186 for (i = 0; devs[i]; i++) {
187 disk = (Disk *)devs[i]->private;
188 msgDebug("Scanning disk %s for root filesystem\n", disk->name);
189 if (!disk->chunks)
190 msgFatal("No chunk list found for %s!", disk->name);
191 for (c1 = disk->chunks->part; c1; c1 = c1->next) {
192 if (c1->type == freebsd) {
193 for (c2 = c1->part; c2; c2 = c2->next) {
194 if (c2->type == part && c2->subtype != FS_SWAP &&
195 c2->private && c2->flags & CHUNK_IS_ROOT) {
196 char dname[40];
197 PartInfo *p = (PartInfo *)c2->private;
198
199 if (strcmp(p->mountpoint, "/")) {
200 msgConfirm("Warning: %s is marked as a root partition but is mounted on %s", c2->name, p->mountpoint);
201 continue;
202 }
203 if (p->newfs) {
204 int i;
205
206 sprintf(dname, "/dev/r%sa", disk->name);
207 msgNotify("Making a new root filesystem on %s", dname);
208 i = vsystem("%s %s", p->newfs_cmd,dname);
209 if (i) {
210 msgConfirm("Unable to make new root filesystem! Command returned status %d", i);
211 return;
212 }
213 }
214 else
215 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.");
216 sprintf(dname, "/dev/%sa", disk->name);
217 if (Mount("/mnt", dname)) {
218 msgConfirm("Unable to mount the root file system! Giving up.");
219 return;
220 }
221 else {
222 extern int makedevs(void);
223
224 msgNotify("Making device files");
225 if (Mkdir("/mnt/dev", NULL)
226 || chdir("/mnt/dev")
227 || makedevs())
228 msgConfirm("Failed to make some of the devices in /mnt!");
229 if (Mkdir("/mnt/stand", NULL))
230 msgConfirm("Unable to make /mnt/stand directory!");
231 chdir("/");
232 break;
233 }
234 }
235 }
236 }
237 }
238 }
239
240 /* Now buzz through the rest of the partitions and mount them too */
241 for (i = 0; devs[i]; i++) {
242 disk = (Disk *)devs[i]->private;
243 if (!disk->chunks)
244 msgFatal("No chunk list found for %s!", disk->name);
245
246 /* Make the proper device mount points in /mnt/dev */
247 MakeDevDisk(disk, "/mnt/dev");
248
249 for (c1 = disk->chunks->part; c1; c1 = c1->next) {
250 if (c1->type == freebsd) {
251 for (c2 = c1->part; c2; c2 = c2->next) {
252 if (c2->type == part && c2->subtype != FS_SWAP && c2->private) {
253 PartInfo *tmp = (PartInfo *)c2->private;
254
255 if (!strcmp(tmp->mountpoint, "/"))
256 continue;
257
258 if (tmp->newfs)
259 command_shell_add(tmp->mountpoint,
260 "%s /mnt/dev/r%s", tmp->newfs_cmd, c2->name);
261 command_func_add(tmp->mountpoint, Mount, c2->name);
262 }
263 }
264 }
265 }
266 }
267 command_sort();
268 command_execute();
269}
270
271/* Copy the boot floppy contents into /stand */
272static void
273copy_self(void)
274{
275 int i;
276
277 msgNotify("Copying the boot floppy to /stand on root filesystem");
278 i = vsystem("find -x /stand | cpio -pdmv /mnt");
279 if (i)
280 msgConfirm("Copy returned error status of %d!", i);
281}
282
283static void
284cpio_extract(void)
285{
286 int i, j, zpid, cpid, pfd[2];
287
288 tryagain:
289 while (CpioFD == -1) {
290 msgConfirm("Please Insert CPIO floppy in floppy drive 0");
291 CpioFD = open("/dev/rfd0", O_RDWR);
292 if (CpioFD >= 0)
293 break;
294 msgDebug("Error on open of cpio floppy: %s (%d)\n", strerror(errno), errno);
295 }
296 j = fork();
297 if (!j) {
298 chdir("/");
299 msgNotify("Extracting contents of CPIO floppy...");
300 pipe(pfd);
301 zpid = fork();
302 if (!zpid) {
303 dup2(CpioFD, 0); close(CpioFD);
304 dup2(pfd[1], 1); close(pfd[1]);
305 close(pfd[0]);
306 i = execl("/stand/gunzip", "/stand/gunzip", 0);
307 msgDebug("/stand/gunzip command returns %d status\n", i);
308 exit(i);
309 }
310 cpid = fork();
311 if (!cpid) {
312 dup2(pfd[0], 0); close(pfd[0]);
313 close(CpioFD);
314 close(pfd[1]);
315 if (DebugFD != -1) {
316 dup2(DebugFD, 1);
317 dup2(DebugFD, 2);
318 }
319 else {
320 close(1); open("/dev/null", O_WRONLY);
321 dup2(1, 2);
322 }
323 i = execl("/stand/cpio", "/stand/cpio", "-iduvm", 0);
324 msgDebug("/stand/cpio command returns %d status\n", i);
325 exit(i);
326 }
327 close(pfd[0]);
328 close(pfd[1]);
329 close(CpioFD);
330
331 i = waitpid(zpid, &j, 0);
332 if (i < 0 || _WSTATUS(j)) {
333 dialog_clear();
334 msgConfirm("gunzip returned error status of %d!", _WSTATUS(j));
335 exit(1);
336 }
337 i = waitpid(cpid, &j, 0);
338 if (i < 0 || _WSTATUS(j)) {
339 dialog_clear();
340 msgConfirm("cpio returned error status of %d!", _WSTATUS(j));
341 exit(2);
342 }
343 exit(0);
344 }
345 else
346 i = wait(&j);
347 if (i < 0 || _WSTATUS(j) || access("/OK", R_OK) == -1) {
348 dialog_clear();
349 msgConfirm("CPIO floppy did not extract properly! Please verify\nthat your media is correct and try again.");
350 close(CpioFD);
351 CpioFD = -1;
352 goto tryagain;
353 }
354 unlink("/OK");
355}
356
357static void
358install_configuration_files(void)
359{
360}
361
362static void
363do_final_setup(void)
364{
365}