111568Sjkh/* 211568Sjkh * The new sysinstall program. 311568Sjkh * 411568Sjkh * This is probably the last program in the `sysinstall' line - the next 511568Sjkh * generation being essentially a complete rewrite. 611568Sjkh * 750479Speter * $FreeBSD$ 811568Sjkh * 911568Sjkh * Copyright (c) 1995 1011568Sjkh * Jordan Hubbard. All rights reserved. 1111568Sjkh * 1211568Sjkh * Redistribution and use in source and binary forms, with or without 1311568Sjkh * modification, are permitted provided that the following conditions 1411568Sjkh * are met: 1511568Sjkh * 1. Redistributions of source code must retain the above copyright 1611568Sjkh * notice, this list of conditions and the following disclaimer, 1711568Sjkh * verbatim and that no modifications are made prior to this 1811568Sjkh * point in the file. 1911568Sjkh * 2. Redistributions in binary form must reproduce the above copyright 2011568Sjkh * notice, this list of conditions and the following disclaimer in the 2111568Sjkh * documentation and/or other materials provided with the distribution. 2211568Sjkh * 2311568Sjkh * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND 2411568Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2511568Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2611568Sjkh * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE 2711568Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2811568Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2911568Sjkh * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) 3011568Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3111568Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3211568Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3311568Sjkh * SUCH DAMAGE. 3411568Sjkh * 3511568Sjkh */ 3611568Sjkh 3711568Sjkh#include "sysinstall.h" 3811568Sjkh#include <sys/disklabel.h> 3911568Sjkh#include <sys/errno.h> 4011568Sjkh#include <sys/ioctl.h> 4111568Sjkh#include <sys/fcntl.h> 4211568Sjkh#include <sys/wait.h> 4311568Sjkh#include <sys/param.h> 4411568Sjkh#include <sys/stat.h> 4511568Sjkh#include <unistd.h> 4611568Sjkh#include <sys/mount.h> 4711568Sjkh 4829222Sjkhstatic int installUpgradeNonInteractive(dialogMenuItem *self); 4929222Sjkh 5011568Sjkhtypedef struct _hitList { 5111568Sjkh enum { JUST_COPY, CALL_HANDLER } action ; 5211568Sjkh char *name; 5311568Sjkh Boolean optional; 5411568Sjkh void (*handler)(struct _hitList *self); 5511568Sjkh} HitList; 5611568Sjkh 5711568Sjkh/* These are the only meaningful files I know about */ 5811568Sjkhstatic HitList etc_files [] = { 5911568Sjkh { JUST_COPY, "Xaccel.ini", TRUE, NULL }, 6098079Sobrien { JUST_COPY, "X11", TRUE, NULL }, 6111568Sjkh { JUST_COPY, "adduser.conf", TRUE, NULL }, 6211568Sjkh { JUST_COPY, "aliases", TRUE, NULL }, 6311568Sjkh { JUST_COPY, "aliases.db", TRUE, NULL }, 6411568Sjkh { JUST_COPY, "amd.map", TRUE, NULL }, 6543949Sjkh { JUST_COPY, "auth.conf", TRUE, NULL }, 6611568Sjkh { JUST_COPY, "crontab", TRUE, NULL }, 6711568Sjkh { JUST_COPY, "csh.cshrc", TRUE, NULL }, 6811568Sjkh { JUST_COPY, "csh.login", TRUE, NULL }, 6911568Sjkh { JUST_COPY, "csh.logout", TRUE, NULL }, 7043949Sjkh { JUST_COPY, "cvsupfile", TRUE, NULL }, 71159113Sceri { JUST_COPY, "devfs.conf", TRUE, NULL }, 7282680Sjkh { JUST_COPY, "dhclient.conf", TRUE, NULL }, 7311568Sjkh { JUST_COPY, "disktab", TRUE, NULL }, 7443949Sjkh { JUST_COPY, "dumpdates", TRUE, NULL }, 7511568Sjkh { JUST_COPY, "exports", TRUE, NULL }, 7611568Sjkh { JUST_COPY, "fbtab", TRUE, NULL }, 7721726Sjkh { JUST_COPY, "fstab", FALSE, NULL }, 7811568Sjkh { JUST_COPY, "ftpusers", TRUE, NULL }, 7924548Sjkh { JUST_COPY, "gettytab", TRUE, NULL }, 8011568Sjkh { JUST_COPY, "gnats", TRUE, NULL }, 8111568Sjkh { JUST_COPY, "group", FALSE, NULL }, 8211568Sjkh { JUST_COPY, "hosts", TRUE, NULL }, 8382680Sjkh { JUST_COPY, "hosts.allow", TRUE, NULL }, 8411568Sjkh { JUST_COPY, "hosts.equiv", TRUE, NULL }, 8511568Sjkh { JUST_COPY, "hosts.lpd", TRUE, NULL }, 8621726Sjkh { JUST_COPY, "inetd.conf", TRUE, NULL }, 8711568Sjkh { JUST_COPY, "localtime", TRUE, NULL }, 8811568Sjkh { JUST_COPY, "login.access", TRUE, NULL }, 8943949Sjkh { JUST_COPY, "login.conf", TRUE, NULL }, 9072787Sjkh { JUST_COPY, "mail", TRUE, NULL }, 9111568Sjkh { JUST_COPY, "mail.rc", TRUE, NULL }, 92159113Sceri { JUST_COPY, "mac.conf", TRUE, NULL }, 9311568Sjkh { JUST_COPY, "make.conf", TRUE, NULL }, 9411568Sjkh { JUST_COPY, "manpath.config", TRUE, NULL }, 9543949Sjkh { JUST_COPY, "master.passwd", FALSE, NULL }, 96159113Sceri { JUST_COPY, "mergemaster.rc", TRUE, NULL }, 9711568Sjkh { JUST_COPY, "motd", TRUE, NULL }, 9811568Sjkh { JUST_COPY, "namedb", TRUE, NULL }, 9911568Sjkh { JUST_COPY, "networks", TRUE, NULL }, 10036320Ssteve { JUST_COPY, "newsyslog.conf", TRUE, NULL }, 10188515Ssheldonh { JUST_COPY, "nsmb.conf", TRUE, NULL }, 10265532Snectar { JUST_COPY, "nsswitch.conf", TRUE, NULL }, 103159113Sceri { JUST_COPY, "ntp.conf", TRUE, NULL }, 10443949Sjkh { JUST_COPY, "pam.conf", TRUE, NULL }, 10543949Sjkh { JUST_COPY, "passwd", TRUE, NULL }, 10643949Sjkh { JUST_COPY, "periodic", TRUE, NULL }, 107159113Sceri { JUST_COPY, "pf.conf", TRUE, NULL }, 108159113Sceri { JUST_COPY, "portsnap.conf", TRUE, NULL }, 10911568Sjkh { JUST_COPY, "ppp", TRUE, NULL }, 11011568Sjkh { JUST_COPY, "printcap", TRUE, NULL }, 11111568Sjkh { JUST_COPY, "profile", TRUE, NULL }, 112159113Sceri { JUST_COPY, "protocols", TRUE, NULL }, 11311568Sjkh { JUST_COPY, "pwd.db", TRUE, NULL }, 11411568Sjkh { JUST_COPY, "rc.local", TRUE, NULL }, 11544890Sjkh { JUST_COPY, "rc.firewall", TRUE, NULL }, 11643949Sjkh { JUST_COPY, "rc.conf.local", TRUE, NULL }, 11711568Sjkh { JUST_COPY, "remote", TRUE, NULL }, 11811568Sjkh { JUST_COPY, "resolv.conf", TRUE, NULL }, 11911568Sjkh { JUST_COPY, "rmt", TRUE, NULL }, 12011568Sjkh { JUST_COPY, "sendmail.cf", TRUE, NULL }, 12143949Sjkh { JUST_COPY, "sendmail.cw", TRUE, NULL }, 12221726Sjkh { JUST_COPY, "services", TRUE, NULL }, 12311568Sjkh { JUST_COPY, "shells", TRUE, NULL }, 12411568Sjkh { JUST_COPY, "skeykeys", TRUE, NULL }, 125159113Sceri { JUST_COPY, "snmpd.config", TRUE, NULL }, 12611568Sjkh { JUST_COPY, "spwd.db", TRUE, NULL }, 127159113Sceri { JUST_COPY, "src.conf", TRUE, NULL }, 12874730Sjkh { JUST_COPY, "ssh", TRUE, NULL }, 129152993Sphilip { JUST_COPY, "sysctl.conf", TRUE, NULL }, 13011568Sjkh { JUST_COPY, "syslog.conf", TRUE, NULL }, 13111568Sjkh { JUST_COPY, "ttys", TRUE, NULL }, 132156123Sjhb { 0, NULL, FALSE, NULL }, 13311568Sjkh}; 13411568Sjkh 135156123Sjhbstatic void 13611568SjkhtraverseHitlist(HitList *h) 13711568Sjkh{ 13821728Sjkh system("rm -rf /etc/upgrade"); 13921728Sjkh Mkdir("/etc/upgrade"); 14011568Sjkh while (h->name) { 14111568Sjkh if (!file_readable(h->name)) { 14215355Sjkh if (!h->optional) 14311568Sjkh msgConfirm("Unable to find an old /etc/%s file! That is decidedly non-standard and\n" 14421720Sjkh "your upgraded system may function a little strangely as a result.", h->name); 14511568Sjkh } 14611568Sjkh else { 14711568Sjkh if (h->action == JUST_COPY) { 14821726Sjkh /* Move the just-loaded copy aside */ 14921728Sjkh vsystem("mv /etc/%s /etc/upgrade/%s", h->name, h->name); 15011568Sjkh 15111568Sjkh /* Copy the old one into its place */ 15211568Sjkh msgNotify("Resurrecting %s..", h->name); 15311568Sjkh /* Do this with tar so that symlinks and such are preserved */ 15415355Sjkh if (vsystem("tar cf - %s | tar xpf - -C /etc", h->name)) 15511568Sjkh msgConfirm("Unable to resurrect your old /etc/%s! Hmmmm.", h->name); 15611568Sjkh } 15711568Sjkh else /* call handler */ 15811568Sjkh h->handler(h); 15911568Sjkh } 16011568Sjkh ++h; 16111568Sjkh } 16211568Sjkh} 16316975Sjkh 16411568Sjkhint 16515091SjkhinstallUpgrade(dialogMenuItem *self) 16611568Sjkh{ 16730345Sjkh char saved_etc[FILENAME_MAX]; 16811568Sjkh Boolean extractingBin = TRUE; 16911568Sjkh 17029222Sjkh if (variable_get(VAR_NONINTERACTIVE)) 17129222Sjkh return installUpgradeNonInteractive(self); 17229222Sjkh 17343685Sjkh variable_set2(SYSTEM_STATE, "upgrade", 0); 17457509Sjkh dialog_clear(); 17511752Sjkh 17683020Sbmah if (msgYesNo("Before beginning a binary upgrade, please review the upgrade instructions,\n" 17783020Sbmah "which are located in the \"Install\" document under the main documentation\n" 17883020Sbmah "menu. Given that you have read these instructions and understand the risks\n" 17983020Sbmah "and precautions involved, are you sure that you want to proceed with\n" 18083020Sbmah "this upgrade?") != 0) 18154587Sjkh return DITEM_FAILURE; 18211752Sjkh 18311568Sjkh if (!Dists) { 18430345Sjkh msgConfirm("First, you must select some distribution components. The upgrade procedure\n" 18530345Sjkh "will only upgrade the distributions you select in the next set of menus."); 18621710Sjkh if (!dmenuOpenSimple(&MenuDistributions, FALSE) || !Dists) 18754587Sjkh return DITEM_FAILURE; 18811568Sjkh } 18995327Sobrien else if (!(Dists & DIST_BASE)) { /* No base selected? Not much of an upgrade.. */ 19095327Sobrien if (msgYesNo("You didn't select the base distribution as one of the distributons to load.\n" 19120518Sjkh "This one is pretty vital to a successful upgrade. Are you SURE you don't\n" 19295327Sobrien "want to select the base distribution? Chose No to bring up the Distributions\n" 19330345Sjkh "menu again.") != 0) { 19417164Sjkh if (!dmenuOpenSimple(&MenuDistributions, FALSE)) 19554587Sjkh return DITEM_FAILURE; 19611568Sjkh } 19711568Sjkh } 19811568Sjkh 19911568Sjkh /* Still?! OK! They must know what they're doing.. */ 20095327Sobrien if (!(Dists & DIST_BASE)) 20111568Sjkh extractingBin = FALSE; 20211568Sjkh 20317164Sjkh if (RunningAsInit) { 20417164Sjkh Device **devs; 20517164Sjkh int i, cnt; 20617164Sjkh char *cp; 20711568Sjkh 20817164Sjkh cp = variable_get(VAR_DISK); 20917164Sjkh devs = deviceFind(cp, DEVICE_TYPE_DISK); 21017164Sjkh cnt = deviceCount(devs); 21117164Sjkh if (!cnt) { 21217164Sjkh msgConfirm("No disks found! Please verify that your disk controller is being\n" 21317164Sjkh "properly probed at boot time. See the Hardware Guide on the\n" 21417164Sjkh "Documentation menu for clues on diagnosing this type of problem."); 21557509Sjkh return DITEM_FAILURE | DITEM_RESTORE; 21617164Sjkh } 21717164Sjkh else { 21834733Sjkh /* Enable all the drives before we start */ 21917164Sjkh for (i = 0; i < cnt; i++) 22017164Sjkh devs[i]->enabled = TRUE; 22117164Sjkh } 22211568Sjkh 22317164Sjkh msgConfirm("OK. First, we're going to go to the disk label editor. In this editor\n" 22421726Sjkh "you will be expected to Mount any partitions you're interested in\n" 22517164Sjkh "upgrading. DO NOT set the Newfs flag to Y on anything in the label editor\n" 22617164Sjkh "unless you're absolutely sure you know what you're doing! In this\n" 22717164Sjkh "instance, you'll be using the label editor as little more than a fancy\n" 22821726Sjkh "screen-oriented partition mounting tool.\n\n" 22917164Sjkh "Once you're done in the label editor, press Q to return here for the next\n" 23017164Sjkh "step."); 23117164Sjkh 23217164Sjkh if (DITEM_STATUS(diskLabelEditor(self)) == DITEM_FAILURE) { 23320518Sjkh msgConfirm("The disk label editor returned an error status. Upgrade operation\n" 23417164Sjkh "aborted."); 23557509Sjkh return DITEM_FAILURE | DITEM_RESTORE; 23617164Sjkh } 23717164Sjkh 23817164Sjkh /* Don't write out MBR info */ 23943685Sjkh variable_set2(DISK_PARTITIONED, "written", 0); 24017164Sjkh if (DITEM_STATUS(diskLabelCommit(self)) == DITEM_FAILURE) { 24117164Sjkh msgConfirm("Not all file systems were properly mounted. Upgrade operation\n" 24217164Sjkh "aborted."); 24317164Sjkh variable_unset(DISK_PARTITIONED); 24457509Sjkh return DITEM_FAILURE | DITEM_RESTORE; 24517164Sjkh } 24611568Sjkh 24722072Sjkh msgNotify("Updating /stand on root filesystem"); 24822072Sjkh (void)vsystem("find -x /stand | cpio %s -pdum /mnt", cpioVerbosity()); 24922072Sjkh 25021713Sjkh if (DITEM_STATUS(chroot("/mnt")) == DITEM_FAILURE) { 25121713Sjkh msgConfirm("Unable to chroot to /mnt - something is wrong with the\n" 25221713Sjkh "root partition or the way it's mounted if this doesn't work."); 25321713Sjkh variable_unset(DISK_PARTITIONED); 25457509Sjkh return DITEM_FAILURE | DITEM_RESTORE; 25521713Sjkh } 25621713Sjkh chdir("/"); 25734811Sjkh installEnvironment(); 25821713Sjkh systemCreateHoloshell(); 25911568Sjkh } 26012127Sjkh 26130345Sjkh saved_etc[0] = '\0'; 26245402Sjkh 263165706Sceri /* Don't allow sources to be upgraded if we have src already */ 26445402Sjkh if (directory_exists("/usr/src/") && (Dists & DIST_SRC)) { 26545402Sjkh Dists &= ~DIST_SRC; 26668730Sjkh SrcDists = 0; 26745402Sjkh msgConfirm("Warning: /usr/src exists and sources were selected as upgrade\n" 26845402Sjkh "targets. Unfortunately, this is not the way to upgrade your\n" 26945402Sjkh "sources - please use CTM or CVSup or some other method which\n" 27045402Sjkh "handles ``deletion events'', unlike this particular feature.\n\n" 27145402Sjkh "Your existing /usr/src will not be affected by this upgrade.\n"); 27245402Sjkh } 27345402Sjkh 27411568Sjkh if (extractingBin) { 27530345Sjkh while (!*saved_etc) { 27693595Sobrien char *cp = msgGetInput("/var/tmp/etc", "Under which directory do you wish to save your current /etc?"); 27730345Sjkh 27830345Sjkh if (!cp || !*cp || Mkdir(cp)) { 27911568Sjkh if (msgYesNo("Directory was not specified, was invalid or user selected Cancel.\n\n" 28011568Sjkh "Doing an upgrade without first backing up your /etc directory is a very\n" 28118830Sjkh "bad idea! Do you want to go back and specify the save directory again?") != 0) 28211568Sjkh break; 28311568Sjkh } 28430345Sjkh else { 28530345Sjkh SAFE_STRCPY(saved_etc, cp); 28630345Sjkh } 28711568Sjkh } 28811568Sjkh 28930345Sjkh if (saved_etc[0]) { 29011568Sjkh msgNotify("Preserving /etc directory.."); 29130018Sjkh if (vsystem("tar -cBpf - -C /etc . | tar --unlink -xBpf - -C %s", saved_etc)) 29216975Sjkh if (msgYesNo("Unable to backup your /etc into %s.\n" 29320208Sjkh "Do you want to continue anyway?", saved_etc) != 0) 29454587Sjkh return DITEM_FAILURE; 29546994Sjkh msgNotify("Preserving /root directory.."); 29646994Sjkh vsystem("tar -cBpf - -C / root | tar --unlink -xBpf - -C %s", saved_etc); 29711568Sjkh } 29830832Sjkh 29930832Sjkh msgNotify("chflags'ing old binaries - please wait."); 300164170Sceri (void)vsystem("chflags -R noschg /bin /sbin /lib /libexec /usr/bin /usr/sbin /usr/lib /usr/libexec /var/empty /boot/kernel*"); 30130832Sjkh 302159112Sceri if (directory_exists("/boot/kernel")) { 303165720Sceri if (directory_exists("/boot/kernel.prev")) { 304165720Sceri msgNotify("Removing /boot/kernel.prev"); 305165720Sceri if (system("rm -fr /boot/kernel.prev")) { 306165720Sceri msgConfirm("NOTICE: I'm trying to back up /boot/kernel to\n" 307165720Sceri "/boot/kernel.prev, but /boot/kernel.prev exists and I\n" 308165720Sceri "can't remove it. This means that the backup will, in\n" 309165720Sceri "all probability, fail."); 310165720Sceri } 311165720Sceri } 312159112Sceri msgNotify("Moving old kernel to /boot/kernel.prev"); 313159112Sceri if (system("mv /boot/kernel /boot/kernel.prev")) { 31411568Sjkh if (!msgYesNo("Hmmm! I couldn't move the old kernel over! Do you want to\n" 31511752Sjkh "treat this as a big problem and abort the upgrade? Due to the\n" 31611752Sjkh "way that this upgrade process works, you will have to reboot\n" 31715788Sjkh "and start over from the beginning. Select Yes to reboot now")) 31815788Sjkh systemShutdown(1); 31911673Sjkh } 32034733Sjkh else 321159112Sceri msgConfirm("NOTICE: Your old kernel is in /boot/kernel.prev should this\n" 322159112Sceri "upgrade fail for any reason and you need to boot your old\n" 323159112Sceri "kernel."); 32411568Sjkh } 32511568Sjkh } 32611752Sjkh 32730018Sjkhmedia: 32830345Sjkh /* We do this very late, but we unfortunately need to back up /etc first */ 32930018Sjkh if (!mediaVerify()) 33054587Sjkh return DITEM_FAILURE; 33130018Sjkh 33279065Sdd if (!DEVICE_INIT(mediaDevice)) { 33330018Sjkh if (!msgYesNo("Couldn't initialize the media. Would you like\n" 33430018Sjkh "to adjust your media selection and try again?")) { 33530018Sjkh mediaDevice = NULL; 33630018Sjkh goto media; 33730018Sjkh } 33830018Sjkh else 33957509Sjkh return DITEM_FAILURE | DITEM_REDRAW | DITEM_RESTORE; 34030018Sjkh } 34130018Sjkh 342164172Sceri msgNotify("Beginning extraction of distributions."); 34315419Sjkh if (DITEM_STATUS(distExtractAll(self)) == DITEM_FAILURE) { 34495327Sobrien msgConfirm("Hmmmm. We couldn't even extract the base distribution. This upgrade\n" 34521710Sjkh "should be considered a failure and started from the beginning, sorry!\n" 34621710Sjkh "The system will reboot now."); 34721710Sjkh dialog_clear(); 34821710Sjkh systemShutdown(1); 34921710Sjkh } 35021726Sjkh else if (Dists) { 35195327Sobrien if (!extractingBin || !(Dists & DIST_BASE)) { 35221726Sjkh msgNotify("The extraction process seems to have had some problems, but we got most\n" 35321710Sjkh "of the essentials. We'll treat this as a warning since it may have been\n" 35421710Sjkh "only non-essential distributions which failed to load."); 35521710Sjkh } 35621710Sjkh else { 35795327Sobrien msgConfirm("Hmmmm. We couldn't even extract the base distribution. This upgrade\n" 35811752Sjkh "should be considered a failure and started from the beginning, sorry!\n" 35911752Sjkh "The system will reboot now."); 36015355Sjkh dialog_clear(); 36115788Sjkh systemShutdown(1); 36211568Sjkh } 36311568Sjkh } 36411568Sjkh 36544036Sjkh if (extractingBin) 366170320Sdelphij vsystem("disklabel -B `awk '$2~/\\/$/ {print substr($1, 6, 5)}' /etc/fstab`"); 36721728Sjkh msgNotify("First stage of upgrade completed successfully!\n\n" 36812025Sjkh "Next comes stage 2, where we attempt to resurrect your /etc\n" 36912025Sjkh "directory!"); 37012025Sjkh 371209069Srandi if (chdir(saved_etc)) { 37211568Sjkh msgConfirm("Unable to go to your saved /etc directory in %s?! Argh!\n" 37311568Sjkh "Something went seriously wrong! It's quite possible that\n" 37411568Sjkh "your former /etc is toast. I hope you didn't have any\n" 37521720Sjkh "important customizations you wanted to keep in there.. :(", saved_etc); 37611568Sjkh } 37711752Sjkh else { 37811752Sjkh /* Now try to resurrect the /etc files */ 37911752Sjkh traverseHitlist(etc_files); 38046994Sjkh /* Resurrect the root dotfiles */ 38146994Sjkh vsystem("tar -cBpf - root | tar -xBpf - -C / && rm -rf root"); 38211752Sjkh } 38311568Sjkh 38434867Sjkh msgConfirm("Upgrade completed! All of your old /etc files have been restored.\n" 38534867Sjkh "For your reference, the new /etc files are in /etc/upgrade/ in case\n" 38634867Sjkh "you wish to upgrade these files by hand (though that should not be\n" 38734867Sjkh "strictly necessary). If your root partition is specified in /etc/fstab\n" 38834867Sjkh "using the old \"compatibility\" slice, you may also wish to update it to\n" 38934867Sjkh "use a fully qualified slice name in order to avoid warnings on startup.\n\n" 39034867Sjkh "When you're ready to reboot into the new system, simply exit the installation."); 39157509Sjkh return DITEM_SUCCESS | DITEM_REDRAW | DITEM_RESTORE; 39211568Sjkh} 39329222Sjkh 39429222Sjkhstatic int 39529222SjkhinstallUpgradeNonInteractive(dialogMenuItem *self) 39629222Sjkh{ 39729222Sjkh char *saved_etc; 39829222Sjkh Boolean extractingBin = TRUE; 39929222Sjkh 40043685Sjkh variable_set2(SYSTEM_STATE, "upgrade", 0); 40129222Sjkh 40229222Sjkh /* Make sure at least BIN is selected */ 40395327Sobrien Dists |= DIST_BASE; 40429222Sjkh 40529222Sjkh if (RunningAsInit) { 40629222Sjkh Device **devs; 40729222Sjkh int i, cnt; 40829222Sjkh char *cp; 40929222Sjkh 41029222Sjkh cp = variable_get(VAR_DISK); 41129222Sjkh devs = deviceFind(cp, DEVICE_TYPE_DISK); 41229222Sjkh cnt = deviceCount(devs); 41329222Sjkh if (!cnt) { 41429222Sjkh msgConfirm("No disks found! Please verify that your disk controller is being\n" 41529222Sjkh "properly probed at boot time. See the Hardware Guide on the\n" 41629222Sjkh "Documentation menu for clues on diagnosing this type of problem."); 41729222Sjkh return DITEM_FAILURE; 41829222Sjkh } 41929222Sjkh else { 420164084Sceri /* Enable all the drives before we start */ 42129222Sjkh for (i = 0; i < cnt; i++) 42229222Sjkh devs[i]->enabled = TRUE; 42329222Sjkh } 42429222Sjkh 42529222Sjkh msgConfirm("OK. First, we're going to go to the disk label editor. In this editor\n" 42629222Sjkh "you will be expected to Mount any partitions you're interested in\n" 42729222Sjkh "upgrading. DO NOT set the Newfs flag to Y on anything in the label editor\n" 42829222Sjkh "unless you're absolutely sure you know what you're doing! In this\n" 42929222Sjkh "instance, you'll be using the label editor as little more than a fancy\n" 43029222Sjkh "screen-oriented partition mounting tool.\n\n" 43129222Sjkh "Once you're done in the label editor, press Q to return here for the next\n" 43229222Sjkh "step."); 43329222Sjkh 43429222Sjkh if (DITEM_STATUS(diskLabelEditor(self)) == DITEM_FAILURE) { 43529222Sjkh msgConfirm("The disk label editor returned an error status. Upgrade operation\n" 43629222Sjkh "aborted."); 43754587Sjkh return DITEM_FAILURE; 43829222Sjkh } 43929222Sjkh 44029222Sjkh /* Don't write out MBR info */ 44143685Sjkh variable_set2(DISK_PARTITIONED, "written", 0); 44229222Sjkh if (DITEM_STATUS(diskLabelCommit(self)) == DITEM_FAILURE) { 44329222Sjkh msgConfirm("Not all file systems were properly mounted. Upgrade operation\n" 44429222Sjkh "aborted."); 44529222Sjkh variable_unset(DISK_PARTITIONED); 44654587Sjkh return DITEM_FAILURE; 44729222Sjkh } 44829222Sjkh 44929222Sjkh if (extractingBin) { 45029222Sjkh msgNotify("chflags'ing old binaries - please wait."); 45129222Sjkh (void)vsystem("chflags -R noschg /mnt/"); 45229222Sjkh } 45329222Sjkh msgNotify("Updating /stand on root filesystem"); 45429222Sjkh (void)vsystem("find -x /stand | cpio %s -pdum /mnt", cpioVerbosity()); 45529222Sjkh 45629222Sjkh if (DITEM_STATUS(chroot("/mnt")) == DITEM_FAILURE) { 45729222Sjkh msgConfirm("Unable to chroot to /mnt - something is wrong with the\n" 45829222Sjkh "root partition or the way it's mounted if this doesn't work."); 45929222Sjkh variable_unset(DISK_PARTITIONED); 46054587Sjkh return DITEM_FAILURE; 46129222Sjkh } 46229222Sjkh chdir("/"); 46329222Sjkh systemCreateHoloshell(); 46429222Sjkh } 46529222Sjkh 46679065Sdd if (!mediaVerify() || !DEVICE_INIT(mediaDevice)) { 46729222Sjkh msgNotify("Upgrade: Couldn't initialize media."); 46854587Sjkh return DITEM_FAILURE; 46929222Sjkh } 47029222Sjkh 47193595Sobrien saved_etc = "/var/tmp/etc"; 47229222Sjkh Mkdir(saved_etc); 47329222Sjkh msgNotify("Preserving /etc directory.."); 47429222Sjkh if (vsystem("tar -cpBf - -C /etc . | tar -xpBf - -C %s", saved_etc)) { 47529222Sjkh msgNotify("Unable to backup your /etc into %s.", saved_etc); 47654587Sjkh return DITEM_FAILURE; 47729222Sjkh } 47829222Sjkh 479164171Sceri /* 480164171Sceri * Back up the old kernel, leaving it in place in case we 481164171Sceri * crash and reboot. 482164171Sceri */ 483164171Sceri if (directory_exists("/boot/kernel")) { 484165720Sceri if (directory_exists("/boot/kernel.prev")) { 485165720Sceri msgNotify("Removing /boot/kernel.prev"); 486165720Sceri if (system("rm -fr /boot/kernel.prev")) { 487165720Sceri msgConfirm("NOTICE: I'm trying to back up /boot/kernel to\n" 488165720Sceri "/boot/kernel.prev, but /boot/kernel.prev exists and I\n" 489165720Sceri "can't remove it. This means that the backup will, in\n" 490165720Sceri "all probability, fail."); 491165720Sceri } 492165720Sceri } 493164171Sceri msgNotify("Copying old kernel to /boot/kernel.prev"); 494164171Sceri vsystem("cp -Rp /boot/kernel /boot/kernel.prev"); 495164171Sceri } 49629222Sjkh 497164172Sceri msgNotify("Beginning extraction of distributions."); 49829222Sjkh if (DITEM_STATUS(distExtractAll(self)) == DITEM_FAILURE) { 49995327Sobrien msgConfirm("Hmmmm. We couldn't even extract the base distribution. This upgrade\n" 50029222Sjkh "should be considered a failure and started from the beginning, sorry!\n" 50129222Sjkh "The system will reboot now."); 50229222Sjkh dialog_clear(); 50329222Sjkh systemShutdown(1); 50429222Sjkh } 50529222Sjkh else if (Dists) { 50695327Sobrien if (!(Dists & DIST_BASE)) { 50729222Sjkh msgNotify("The extraction process seems to have had some problems, but we got most\n" 50829222Sjkh "of the essentials. We'll treat this as a warning since it may have been\n" 50929222Sjkh "only non-essential distributions which failed to upgrade."); 51029222Sjkh } 51129222Sjkh else { 51295327Sobrien msgConfirm("Hmmmm. We couldn't even extract the base distribution. This upgrade\n" 51329222Sjkh "should be considered a failure and started from the beginning, sorry!\n" 51429222Sjkh "The system will reboot now."); 51529222Sjkh dialog_clear(); 51629222Sjkh systemShutdown(1); 51729222Sjkh } 51829222Sjkh } 51929222Sjkh 52029222Sjkh msgNotify("First stage of upgrade completed successfully."); 52129222Sjkh if (vsystem("tar -cpBf - -C %s . | tar --unlink -xpBf - -C /etc", saved_etc)) { 52229222Sjkh msgNotify("Unable to resurrect your old /etc!"); 52354587Sjkh return DITEM_FAILURE; 52429222Sjkh } 52529222Sjkh return DITEM_SUCCESS | DITEM_REDRAW; 52629222Sjkh} 527