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