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