diff options
author | jkh <jkh@FreeBSD.org> | 1995-10-19 16:15:43 +0000 |
---|---|---|
committer | jkh <jkh@FreeBSD.org> | 1995-10-19 16:15:43 +0000 |
commit | 45cf2943d04dcb0b87c6372e28b812ce8e6dee59 (patch) | |
tree | 54bbe59295f8d126481563d624650bd5a92ba5a9 | |
parent | 26765522cec0d44af5e1e6b0516c0912524a770f (diff) | |
download | FreeBSD-src-45cf2943d04dcb0b87c6372e28b812ce8e6dee59.zip FreeBSD-src-45cf2943d04dcb0b87c6372e28b812ce8e6dee59.tar.gz |
Drat! Forgot the adds..
-rw-r--r-- | release/sysinstall/help/upgrade.hlp | 31 | ||||
-rw-r--r-- | release/sysinstall/installFinal.c | 235 | ||||
-rw-r--r-- | release/sysinstall/installUpgrade.c | 353 | ||||
-rw-r--r-- | usr.sbin/sysinstall/installUpgrade.c | 353 |
4 files changed, 972 insertions, 0 deletions
diff --git a/release/sysinstall/help/upgrade.hlp b/release/sysinstall/help/upgrade.hlp new file mode 100644 index 0000000..8dd99f0 --- /dev/null +++ b/release/sysinstall/help/upgrade.hlp @@ -0,0 +1,31 @@ +Welcome to the 2.0.5 -> 2.1 upgrade procedure! + +It must first be said that this upgrade DOES NOT take a particularly +sophisticated approach to the upgrade problem, it being more a question +of providing what seemed "good enough" at the time. A truly polished +upgrade that deals properly with the broad spectrum of installed 2.0.5 +systems would be nice to have, but until that gets written what you get is +this - the brute-force approach! + +What this upgrade will attempt to do is best summarized thusly: + + 1. fsck and mount all file systems chosen in the label editor. + 2. Ask for a location to preserve your /etc directory into and do so. + 3. Extract all selected distributions on top of your existing system. + 4. Copy certain obvious files back from the preserved /etc, leaving the + rest of the /etc file merge up to the user. + 5. Drop user in a shell so that they may perform that merge before + rebooting into the new system. + +And that's it! This "upgrade" is not going to hold your hand in all +major respects, it's simply provided to make one PART of the upgrade +easier. + +IMPORTANT NOTE: What this upgrade procedure also may do, in fact, is +completely destroy your system (though much more quickly than you +would have been able to destroy it yourself) and it is simply +impossible to guarantee that this procedure's crude form of upgrade +automation will work in all cases. If you do this upgrade without +proper BACKUPS for any important data then you really must like living +life close to the edge, that's all I can say! + diff --git a/release/sysinstall/installFinal.c b/release/sysinstall/installFinal.c new file mode 100644 index 0000000..2f44c9e --- /dev/null +++ b/release/sysinstall/installFinal.c @@ -0,0 +1,235 @@ +/* + * The new sysinstall program. + * + * This is probably the last program in the `sysinstall' line - the next + * generation being essentially a complete rewrite. + * + * $Id: install.c,v 1.71.2.38 1995/10/18 05:01:55 jkh Exp $ + * + * Copyright (c) 1995 + * Jordan Hubbard & Coranth Gryphon. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * verbatim and that no modifications are made prior to this + * point in the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the authors listed above + * for the FreeBSD Project. + * 4. The names of the authors or the FreeBSD project may not be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR THEIR PETS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include "sysinstall.h" +#include <sys/disklabel.h> +#include <sys/errno.h> +#include <sys/ioctl.h> +#include <sys/fcntl.h> +#include <sys/wait.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <unistd.h> +#include <sys/mount.h> + +static DMenu MenuSamba = { + DMENU_MULTIPLE_TYPE | DMENU_SELECTION_RETURNS, + "Samba Services Menu", + "This allows you to configure various aspects of your Samba server.", + NULL, + NULL, +{ { "Homes", "Make home directories available to users.", + DMENU_SET_VARIABLE, "SAMBA_homes=YES", 0, 0, dmenuVarCheck }, + { "Printers", "Allows for sharing of local printers.", + DMENU_SET_VARIABLE, "SAMBA_printers=YES", 0, 0, dmenuVarCheck}, + { "Export Paths", "Specify local directories to make available.", + DMENU_SET_VARIABLE, "SAMBA_export=YES", 0, 0, dmenuVarCheck }, + { NULL } }, +}; + +/* These probably shouldn't be hard-coded, but making them options might prove to be even more confusing! */ +#define FTP_UID 14 +#define FTP_NAME "ftp" +#define FTP_GROUP "operator" +#define FTP_COMMENT "Anonymous FTP Admin" + +#define SMB_CONF "./smb.conf" + +#define APACHE_WEBDIR "/usr/local/www/pages" + +/* Do any final optional hackery */ +int +installFinal(void) +{ + int i, tval; + char tbuf[256]; + char *tptr; + FILE *fptr; + + i = RET_SUCCESS; + + /* Do we want to install and set up gated? */ + if (variable_get("gated")) { + /* Load gated package and maybe even seek to configure or explain it a little */ + } + + /* Set up anonymous FTP access to this machine? */ + if (variable_get("anon_ftp")) { + tptr = msgGetInput("/u", "What directory should the ftp home be in?"); + if (tptr && *tptr && (tptr[0] == '/')) { + int len = strlen(tbuf); + + strcpy(tbuf, tptr); + if (tbuf[len - 1] == '/') + tbuf[len - 1] = '\0'; + + if (vsystem("adduser -uid %d -home %s -shell date -dotdir no -batch %s %s \"%s\" ", + FTP_UID, tbuf, FTP_NAME, FTP_GROUP, FTP_COMMENT)) { + msgConfirm("Unable to create FTP user! Anonymous FTP setup failed."); + i = RET_FAIL; + } + else { + vsystem("mkdir %s/%s/pub", tbuf, FTP_NAME); + vsystem("mkdir %s/%s/upload", tbuf, FTP_NAME); + vsystem("chmod 0777 %s/%s/upload", tbuf, FTP_NAME); + } + } + else { + msgConfirm("Invalid Directory. Anonymous FTP will not be set up."); + } + } + + /* Set this machine up as a web server? */ + if (variable_get("apache_httpd")) { + /* Load and configure the Apache HTTPD web server */ + } + + /* Set this machine up as a Samba server? */ + if (variable_get("samba")) { + if (!dmenuOpenSimple(&MenuSamba)) + i = RET_FAIL; + else { + fptr = fopen("/tmp/smb.conf","w"); + if (fptr) { + strcpy(tbuf,"FreeBSD - Samba %v"); + if (variable_get("SAMBA_string")) { + tptr = msgGetInput("FreeBSD - Samba %%v", "What should this server list as its description?\n" + "Note that the \"%%v\" refers to the samba version number."); + if (tptr && *tptr) + strcpy(tbuf, tptr); + } + + fprintf(fptr, "[global]\n"); + fprintf(fptr, "comment = %s\n", tbuf); + fprintf(fptr, "log file = /var/log/samba.log\n"); + fprintf(fptr, "dont descend = /dev,/proc,/root,/stand\n\n"); + + fprintf(fptr, "printing = bsd\n"); + fprintf(fptr, "map archive = no\n"); + fprintf(fptr, "status = yes\n"); + fprintf(fptr, "public = yes\n"); + fprintf(fptr, "read only = no\n"); + fprintf(fptr, "preserve case = yes\n"); + fprintf(fptr, "strip dot = yes\n"); + fprintf(fptr, "security = share\n"); + fprintf(fptr, "guest ok = yes\n\n"); + + if (variable_get("SAMBA_homes")) { + fprintf(fptr, "[homes]\n"); + fprintf(fptr, "browseable = no\n"); + fprintf(fptr, "comment = User Home Directory\n"); + fprintf(fptr, "create mode = 0775\n"); + fprintf(fptr, "public = no\n\n"); + } + + if (variable_get("SAMBA_printers")) { + fprintf(fptr, "[printers]\n"); + fprintf(fptr, "path = /var/spool\n"); + fprintf(fptr, "comment = Printers\n"); + fprintf(fptr, "create mode = 0700\n"); + fprintf(fptr, "browseable = no\n"); + fprintf(fptr, "printable = yes\n"); + fprintf(fptr, "read only = yes\n"); + fprintf(fptr, "public = no\n\n"); + } + + if (variable_get("SAMBA_export")) { + for (tval = 0; ! tval; tval = msgYesNo("Another?")) { + tptr = msgGetInput(NULL,"What directory to export?"); + if (tptr && *tptr && (tptr[0] == '/')) { + int len = strlen(tbuf); + + strcpy(tbuf, tptr); + if (tbuf[len - 1] == '/') + tbuf[len - 1] = '\0'; + if (directoryExists(tbuf)) { + tptr = msgGetInput(pathBaseName(tbuf), "What do you want to call this share?"); + if (tptr && *tptr) { + fprintf(fptr, "[%s]\npath = %s\n", tptr, tbuf); + tptr = msgGetInput(NULL, "Enter a short description of this share?"); + if (tptr && *tptr) + fprintf(fptr, "comment = %s\n", tptr); + if (msgYesNo("Do you want this share to be read only?")) + fprintf(fptr, "read only = no\n\n"); + else + fprintf(fptr, "read only = yes\n\n"); + } + else { + msgConfirm("Invalid Share Name."); + } + } + else { + msgConfirm("Directory does not exist."); + } + } /* end if (tptr) */ + } /* end for loop */ + } /* end if (SAMBA_export) */ + + fclose(fptr); + vsystem("mv -f /tmp/smb.conf %s", SMB_CONF); + } + else { + msgConfirm("Unable to open temporary smb.conf file.\nSamba must be configured by hand."); + } + } + } + + /* Set this machine up with a PC-NFS authentication server? */ + if (variable_get("pcnfsd")) { + /* Load and configure pcnfsd */ + } + + /* If we're an NFS server, we need an exports file */ + if (variable_get("nfs_server") && !file_readable("/etc/exports")) { + msgConfirm("You have chosen to be an NFS server but have not yet configured\n" + "the /etc/exports file. You must configure this information before\n" + "other hosts will be able to mount file systems from your machine.\n" + "Press [ENTER] now to invoke an editor on /etc/exports"); + vsystem("echo '#The following example exports /usr to 3 machines named after ducks.' > /etc/exports"); + vsystem("echo '#/usr huey louie dewie' >> /etc/exports"); + vsystem("echo >> /etc/exports"); + systemExecute("ee /etc/exports"); + } + return i; +} + diff --git a/release/sysinstall/installUpgrade.c b/release/sysinstall/installUpgrade.c new file mode 100644 index 0000000..15dfddf --- /dev/null +++ b/release/sysinstall/installUpgrade.c @@ -0,0 +1,353 @@ +/* + * The new sysinstall program. + * + * This is probably the last program in the `sysinstall' line - the next + * generation being essentially a complete rewrite. + * + * $Id: install.c,v 1.71.2.38 1995/10/18 05:01:55 jkh Exp $ + * + * Copyright (c) 1995 + * Jordan Hubbard. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * verbatim and that no modifications are made prior to this + * point in the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Jordan Hubbard + * for the FreeBSD Project. + * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include "sysinstall.h" +#include <sys/disklabel.h> +#include <sys/errno.h> +#include <sys/ioctl.h> +#include <sys/fcntl.h> +#include <sys/wait.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <unistd.h> +#include <sys/mount.h> + +typedef struct _hitList { + enum { JUST_COPY, CALL_HANDLER } action ; + char *name; + Boolean optional; + void (*handler)(struct _hitList *self); +} HitList; + +/* cop-out function for files we can't handle */ +static void +doByHand(HitList *h) +{ + msgConfirm("/etc/%s is one of those files that this upgrade procedure just isn't\n" + "smart enough to deal with right now. You'll need to merge the old and\n" + "new versions by hand when the option to do so is later presented.", h->name); +} + +/* These are the only meaningful files I know about */ +static HitList etc_files [] = { + { JUST_COPY, "Xaccel.ini", TRUE, NULL }, + { JUST_COPY, "adduser.conf", TRUE, NULL }, + { JUST_COPY, "aliases", TRUE, NULL }, + { JUST_COPY, "aliases.db", TRUE, NULL }, + { JUST_COPY, "amd.map", TRUE, NULL }, + { JUST_COPY, "crontab", TRUE, NULL }, + { JUST_COPY, "csh.cshrc", TRUE, NULL }, + { JUST_COPY, "csh.login", TRUE, NULL }, + { JUST_COPY, "csh.logout", TRUE, NULL }, + { JUST_COPY, "daily", TRUE, NULL }, + { JUST_COPY, "disktab", TRUE, NULL }, + { JUST_COPY, "dm.conf", TRUE, NULL }, + { JUST_COPY, "exports", TRUE, NULL }, + { JUST_COPY, "fbtab", TRUE, NULL }, + { CALL_HANDLER, "fstab", FALSE, doByHand }, + { JUST_COPY, "ftpusers", TRUE, NULL }, + { JUST_COPY, "gnats", TRUE, NULL }, + { JUST_COPY, "group", FALSE, NULL }, + { JUST_COPY, "host.conf", TRUE, NULL }, + { JUST_COPY, "hosts", TRUE, NULL }, + { JUST_COPY, "hosts.equiv", TRUE, NULL }, + { JUST_COPY, "hosts.lpd", TRUE, NULL }, + { CALL_HANDLER, "inetd.conf", FALSE, doByHand }, + { CALL_HANDLER, "kerberosIV", TRUE, doByHand }, + { JUST_COPY, "localtime", TRUE, NULL }, + { JUST_COPY, "login.access", TRUE, NULL }, + { JUST_COPY, "mail.rc", TRUE, NULL }, + { JUST_COPY, "make.conf", TRUE, NULL }, + { JUST_COPY, "manpath.config", TRUE, NULL }, + { JUST_COPY, "master.passwd", TRUE, NULL }, + { JUST_COPY, "mib.txt", TRUE, NULL }, + { JUST_COPY, "modems", TRUE, NULL }, + { JUST_COPY, "monthly", TRUE, NULL }, + { JUST_COPY, "motd", TRUE, NULL }, + { JUST_COPY, "namedb", TRUE, NULL }, + { CALL_HANDLER, "netstart", FALSE, doByHand }, + { JUST_COPY, "networks", TRUE, NULL }, + { JUST_COPY, "passwd", FALSE, NULL }, + { JUST_COPY, "phones", TRUE, NULL }, + { JUST_COPY, "ppp", TRUE, NULL }, + { JUST_COPY, "printcap", TRUE, NULL }, + { JUST_COPY, "profile", TRUE, NULL }, + { JUST_COPY, "protocols", TRUE, NULL }, + { JUST_COPY, "pwd.db", TRUE, NULL }, + { CALL_HANDLER, "rc", FALSE, doByHand }, + { CALL_HANDLER, "rc.i386", TRUE, doByHand }, + { JUST_COPY, "rc.local", TRUE, NULL }, + { CALL_HANDLER, "rc.serial", TRUE, doByHand }, + { JUST_COPY, "remote", TRUE, NULL }, + { JUST_COPY, "resolv.conf", TRUE, NULL }, + { JUST_COPY, "rmt", TRUE, NULL }, + { JUST_COPY, "security", TRUE, NULL }, + { JUST_COPY, "sendmail.cf", TRUE, NULL }, + { CALL_HANDLER, "services", TRUE, doByHand }, + { JUST_COPY, "shells", TRUE, NULL }, + { JUST_COPY, "skeykeys", TRUE, NULL }, + { JUST_COPY, "spwd.db", TRUE, NULL }, + { JUST_COPY, "supfile", TRUE, NULL }, + { CALL_HANDLER, "sysconfig", FALSE, doByHand }, + { JUST_COPY, "syslog.conf", TRUE, NULL }, + { JUST_COPY, "termcap", TRUE, NULL }, + { JUST_COPY, "ttys", TRUE, NULL }, + { JUST_COPY, "uucp", TRUE, NULL }, + { JUST_COPY, "weekly", TRUE, NULL }, + { 0 }, +}; + +void +traverseHitlist(HitList *h) +{ + while (h->name) { + if (!file_readable(h->name)) { + if (!h->optional) + msgConfirm("Unable to find an old /etc/%s file! That is decidedly non-standard and\n" + "your upgraded system may function a little strangely as a result."); + } + else { + if (h->action == JUST_COPY) { + /* Nuke the just-loaded copy thoroughly */ + vsystem("rm -rf /etc/%s", h->name); + + /* Copy the old one into its place */ + msgNotify("Resurrecting %s..", h->name); + /* Do this with tar so that symlinks and such are preserved */ + if (vsystem("tar cf - %s | tar xpf - -C /etc", h->name)) + msgConfirm("Unable to resurrect your old /etc/%s! Hmmmm.", h->name); + } + else /* call handler */ + h->handler(h); + } + ++h; + } +} + +int +installUpgrade(char *str) +{ + char *saved_etc = NULL; + Boolean extractingBin = TRUE; + int waitstatus; + pid_t child; + + if (!Dists) { + msgConfirm("You haven't specified any distributions yet. The upgrade procedure\n" + "will only upgrade those portions of the system for which a distribution\n" + "has been selected. In the next screen, we'll go to the Distributions\n" + "menu to select those portions of 2.1 you wish to install on top of your\n" + "2.0.5 system."); + if (!dmenuOpenSimple(&MenuDistributions)) + return RET_FAIL; + } + + /* No bin selected? Not much of an upgrade.. */ + if (!(Dists & DIST_BIN)) { + if (msgYesNo("You didn't select the bin distribution as one of the distributons to load.\n" + "This one is pretty vital to a successful 2.1 upgrade. Are you SURE you don't\n" + "want to select the bin distribution? Chose _No_ to bring up the Distributions\n" + "menu.")) { + (void)dmenuOpenSimple(&MenuDistributions); + } + } + + /* Still?! OK! They must know what they're doing.. */ + if (!(Dists & DIST_BIN)) + extractingBin = FALSE; + + systemDisplayHelp("upgrade"); + + if (msgYesNo("Given all that scary stuff you just read, are you sure you want to\n" + "risk it all and proceed with this upgrade?")) + return RET_FAIL; + + msgConfirm("OK. First, we're going to go to the disk label editor. In this editor\n" + "you will be expected to *Mount* any partitions you're interested in\n" + "upgrading. Don't set the Newfs flag to `Y' on anything in the label\n" + "editor unless you're absolutely sure you know what you're doing! In\n" + "this instance, you'll be using the label editor as little more than a\n" + "fancy screen-oriented filesystem mounting utility!\n\n" + "Once you're done in the label editor, press Q to return here for the next\n" + "step.\n"); + + if (diskLabelEditor(NULL) == RET_FAIL) { + msgConfirm("The disk label editor failed to work properly! Upgrade operation\n" + "aborted."); + return RET_FAIL; + } + + if (diskLabelCommit(NULL) == RET_FAIL) { + msgConfirm("Not all file systems were properly mounted. Upgrade operation\n" + "aborted."); + return RET_FAIL; + } + + if (chroot("/mnt") == RET_FAIL) { + msgConfirm("Unable to chroot to /mnt - something is wrong with the\n" + "root partition or the way it's mounted if this doesn't work."); + return RET_FAIL; + } + chdir("/"); + if (extractingBin) { + while (!saved_etc) { + saved_etc = msgGetInput("/usr/tmp/etc", "Under which directory do you wish to save your current /etc?"); + if (!saved_etc || !*saved_etc || Mkdir(saved_etc, NULL)) { + if (msgYesNo("Directory was not specified, was invalid or user selected Cancel.\n\n" + "Doing an upgrade without first backing up your /etc directory is a very\n" + "bad idea! Do you want to go back and specify the save directory again?")) + break; + } + } + + if (saved_etc) { + msgNotify("Preserving /etc directory.."); + if (vsystem("cp -pr /etc/* %s", saved_etc)) { + msgConfirm("Unable to back up /etc directory to %s! Upgrade operation\n" + "aborted.", saved_etc); + return RET_FAIL; + } + } + + if (file_readable("/kernel")) { + msgNotify("Moving old kernel to /kernel.205."); + if (system("chflags noschg /mnt/kernel && mv /mnt/kernel /mnt/kernel.205")) + if (!msgYesNo("Hmmm! I couldn't move the old kernel over! Do you want to\n" + "treat this as a big problem and abort the upgrade?")) + return RET_FAIL; + } + } + msgNotify("Beginning extraction of distributions.."); + if (distExtractAll(NULL) == RET_FAIL) { + if (extractingBin && (Dists & DIST_BIN)) { + msgConfirm("Hmmmm. We couldn't even extract the bin distribution. This upgrade\n" + "should be considered a failure and started from the beginning, sorry!\n"); + return RET_FAIL; + } + msgConfirm("The extraction process seems to have had some problems, but we got most\n" + "of the essentials. We'll treat this as a warning since it may have been\n" + "a non-essential distribution which failed to load."); + } + + if (extractingBin) { + msgNotify("OK, now it's time to go pound on your root a little bit to create all the\n" + "/dev entries and such that a 2.1 system expects to see. I'll also perform a\n" + "few \"fixup\" operations to repair the effects of splatting a bin distribution\n" + "on top of an existing system.."); + if (installFixup() == RET_FAIL) + msgConfirm("Hmmmmm. The fixups don't seem to have been very happy.\n" + "You may wish to examine the system a little more closely when\n" + "it comes time to merge your /etc customizations back."); + } + + if (extractingBin) + configSysconfig(); + + if (installFinal() == RET_FAIL) + msgConfirm("Some of the final configuration stuff evidently failed, but\n" + "the first stage of the upgrade should otherwise be considered\n" + "a success!\n\n" + "Next comes stage 2, where we attempt to resurrect your /etc\n" + "directory!"); + else + msgConfirm("First stage of upgrade completed successfully!\n\n" + "Next comes stage 2, where we attempt to resurrect your /etc\n" + "directory!"); + + if (chdir(saved_etc)) { + msgConfirm("Unable to go to your saved /etc directory in %s?! Argh!\n" + "Something went seriously wrong! It's quite possible that\n" + "your former /etc is toast. I hope you didn't have any\n" + "important customizations you wanted to keep in there.. :(\n"); + return RET_FAIL; + } + + /* Now try to resurrect the /etc files */ + traverseHitlist(etc_files); + + msgConfirm("OK! At this stage, we've resurrected all the /etc files we could\n" + "(and you may have been warned about some that you'll have to merge\n" + "yourself, by hand) and we're going to drop you into a shell to do\n" + "the rest yourself (sorry about this!). Once the system looks good\n" + "to you, exit the shell and reboot the system."); + + chdir("/"); + dialog_clear(); + dialog_update(); + end_dialog(); + DialogActive = FALSE; + + if (!(child = fork())) { + int i, fd; + struct termios foo; + extern int login_tty(int); + + for (i = 0; i < 3; i++) + close(i); + fd = open("/dev/ttyv0", O_RDWR); + ioctl(0, TIOCSCTTY, &fd); + dup2(0, 1); + dup2(0, 2); + if (login_tty(fd) == -1) + msgDebug("Can't set the controlling terminal.\n"); + signal(SIGTTOU, SIG_IGN); + if (tcgetattr(fd, &foo) != -1) { + foo.c_cc[VERASE] = '\010'; + if (tcsetattr(fd, TCSANOW, &foo) == -1) + msgDebug("Unable to set the erase character.\n"); + } + else + msgDebug("Unable to get the terminal attributes!\n"); + printf("Well, good luck! When you're done, type exit to return.\n"); + execlp("sh", "-sh", 0); + msgDebug("Was unable to execute sh for post-upgrade shell!\n"); + exit(1); + } + else + (void)waitpid(child, &waitstatus, 0); + DialogActive = TRUE; + clear(); + dialog_clear(); + dialog_update(); + return RET_SUCCESS; +} diff --git a/usr.sbin/sysinstall/installUpgrade.c b/usr.sbin/sysinstall/installUpgrade.c new file mode 100644 index 0000000..15dfddf --- /dev/null +++ b/usr.sbin/sysinstall/installUpgrade.c @@ -0,0 +1,353 @@ +/* + * The new sysinstall program. + * + * This is probably the last program in the `sysinstall' line - the next + * generation being essentially a complete rewrite. + * + * $Id: install.c,v 1.71.2.38 1995/10/18 05:01:55 jkh Exp $ + * + * Copyright (c) 1995 + * Jordan Hubbard. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * verbatim and that no modifications are made prior to this + * point in the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Jordan Hubbard + * for the FreeBSD Project. + * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include "sysinstall.h" +#include <sys/disklabel.h> +#include <sys/errno.h> +#include <sys/ioctl.h> +#include <sys/fcntl.h> +#include <sys/wait.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <unistd.h> +#include <sys/mount.h> + +typedef struct _hitList { + enum { JUST_COPY, CALL_HANDLER } action ; + char *name; + Boolean optional; + void (*handler)(struct _hitList *self); +} HitList; + +/* cop-out function for files we can't handle */ +static void +doByHand(HitList *h) +{ + msgConfirm("/etc/%s is one of those files that this upgrade procedure just isn't\n" + "smart enough to deal with right now. You'll need to merge the old and\n" + "new versions by hand when the option to do so is later presented.", h->name); +} + +/* These are the only meaningful files I know about */ +static HitList etc_files [] = { + { JUST_COPY, "Xaccel.ini", TRUE, NULL }, + { JUST_COPY, "adduser.conf", TRUE, NULL }, + { JUST_COPY, "aliases", TRUE, NULL }, + { JUST_COPY, "aliases.db", TRUE, NULL }, + { JUST_COPY, "amd.map", TRUE, NULL }, + { JUST_COPY, "crontab", TRUE, NULL }, + { JUST_COPY, "csh.cshrc", TRUE, NULL }, + { JUST_COPY, "csh.login", TRUE, NULL }, + { JUST_COPY, "csh.logout", TRUE, NULL }, + { JUST_COPY, "daily", TRUE, NULL }, + { JUST_COPY, "disktab", TRUE, NULL }, + { JUST_COPY, "dm.conf", TRUE, NULL }, + { JUST_COPY, "exports", TRUE, NULL }, + { JUST_COPY, "fbtab", TRUE, NULL }, + { CALL_HANDLER, "fstab", FALSE, doByHand }, + { JUST_COPY, "ftpusers", TRUE, NULL }, + { JUST_COPY, "gnats", TRUE, NULL }, + { JUST_COPY, "group", FALSE, NULL }, + { JUST_COPY, "host.conf", TRUE, NULL }, + { JUST_COPY, "hosts", TRUE, NULL }, + { JUST_COPY, "hosts.equiv", TRUE, NULL }, + { JUST_COPY, "hosts.lpd", TRUE, NULL }, + { CALL_HANDLER, "inetd.conf", FALSE, doByHand }, + { CALL_HANDLER, "kerberosIV", TRUE, doByHand }, + { JUST_COPY, "localtime", TRUE, NULL }, + { JUST_COPY, "login.access", TRUE, NULL }, + { JUST_COPY, "mail.rc", TRUE, NULL }, + { JUST_COPY, "make.conf", TRUE, NULL }, + { JUST_COPY, "manpath.config", TRUE, NULL }, + { JUST_COPY, "master.passwd", TRUE, NULL }, + { JUST_COPY, "mib.txt", TRUE, NULL }, + { JUST_COPY, "modems", TRUE, NULL }, + { JUST_COPY, "monthly", TRUE, NULL }, + { JUST_COPY, "motd", TRUE, NULL }, + { JUST_COPY, "namedb", TRUE, NULL }, + { CALL_HANDLER, "netstart", FALSE, doByHand }, + { JUST_COPY, "networks", TRUE, NULL }, + { JUST_COPY, "passwd", FALSE, NULL }, + { JUST_COPY, "phones", TRUE, NULL }, + { JUST_COPY, "ppp", TRUE, NULL }, + { JUST_COPY, "printcap", TRUE, NULL }, + { JUST_COPY, "profile", TRUE, NULL }, + { JUST_COPY, "protocols", TRUE, NULL }, + { JUST_COPY, "pwd.db", TRUE, NULL }, + { CALL_HANDLER, "rc", FALSE, doByHand }, + { CALL_HANDLER, "rc.i386", TRUE, doByHand }, + { JUST_COPY, "rc.local", TRUE, NULL }, + { CALL_HANDLER, "rc.serial", TRUE, doByHand }, + { JUST_COPY, "remote", TRUE, NULL }, + { JUST_COPY, "resolv.conf", TRUE, NULL }, + { JUST_COPY, "rmt", TRUE, NULL }, + { JUST_COPY, "security", TRUE, NULL }, + { JUST_COPY, "sendmail.cf", TRUE, NULL }, + { CALL_HANDLER, "services", TRUE, doByHand }, + { JUST_COPY, "shells", TRUE, NULL }, + { JUST_COPY, "skeykeys", TRUE, NULL }, + { JUST_COPY, "spwd.db", TRUE, NULL }, + { JUST_COPY, "supfile", TRUE, NULL }, + { CALL_HANDLER, "sysconfig", FALSE, doByHand }, + { JUST_COPY, "syslog.conf", TRUE, NULL }, + { JUST_COPY, "termcap", TRUE, NULL }, + { JUST_COPY, "ttys", TRUE, NULL }, + { JUST_COPY, "uucp", TRUE, NULL }, + { JUST_COPY, "weekly", TRUE, NULL }, + { 0 }, +}; + +void +traverseHitlist(HitList *h) +{ + while (h->name) { + if (!file_readable(h->name)) { + if (!h->optional) + msgConfirm("Unable to find an old /etc/%s file! That is decidedly non-standard and\n" + "your upgraded system may function a little strangely as a result."); + } + else { + if (h->action == JUST_COPY) { + /* Nuke the just-loaded copy thoroughly */ + vsystem("rm -rf /etc/%s", h->name); + + /* Copy the old one into its place */ + msgNotify("Resurrecting %s..", h->name); + /* Do this with tar so that symlinks and such are preserved */ + if (vsystem("tar cf - %s | tar xpf - -C /etc", h->name)) + msgConfirm("Unable to resurrect your old /etc/%s! Hmmmm.", h->name); + } + else /* call handler */ + h->handler(h); + } + ++h; + } +} + +int +installUpgrade(char *str) +{ + char *saved_etc = NULL; + Boolean extractingBin = TRUE; + int waitstatus; + pid_t child; + + if (!Dists) { + msgConfirm("You haven't specified any distributions yet. The upgrade procedure\n" + "will only upgrade those portions of the system for which a distribution\n" + "has been selected. In the next screen, we'll go to the Distributions\n" + "menu to select those portions of 2.1 you wish to install on top of your\n" + "2.0.5 system."); + if (!dmenuOpenSimple(&MenuDistributions)) + return RET_FAIL; + } + + /* No bin selected? Not much of an upgrade.. */ + if (!(Dists & DIST_BIN)) { + if (msgYesNo("You didn't select the bin distribution as one of the distributons to load.\n" + "This one is pretty vital to a successful 2.1 upgrade. Are you SURE you don't\n" + "want to select the bin distribution? Chose _No_ to bring up the Distributions\n" + "menu.")) { + (void)dmenuOpenSimple(&MenuDistributions); + } + } + + /* Still?! OK! They must know what they're doing.. */ + if (!(Dists & DIST_BIN)) + extractingBin = FALSE; + + systemDisplayHelp("upgrade"); + + if (msgYesNo("Given all that scary stuff you just read, are you sure you want to\n" + "risk it all and proceed with this upgrade?")) + return RET_FAIL; + + msgConfirm("OK. First, we're going to go to the disk label editor. In this editor\n" + "you will be expected to *Mount* any partitions you're interested in\n" + "upgrading. Don't set the Newfs flag to `Y' on anything in the label\n" + "editor unless you're absolutely sure you know what you're doing! In\n" + "this instance, you'll be using the label editor as little more than a\n" + "fancy screen-oriented filesystem mounting utility!\n\n" + "Once you're done in the label editor, press Q to return here for the next\n" + "step.\n"); + + if (diskLabelEditor(NULL) == RET_FAIL) { + msgConfirm("The disk label editor failed to work properly! Upgrade operation\n" + "aborted."); + return RET_FAIL; + } + + if (diskLabelCommit(NULL) == RET_FAIL) { + msgConfirm("Not all file systems were properly mounted. Upgrade operation\n" + "aborted."); + return RET_FAIL; + } + + if (chroot("/mnt") == RET_FAIL) { + msgConfirm("Unable to chroot to /mnt - something is wrong with the\n" + "root partition or the way it's mounted if this doesn't work."); + return RET_FAIL; + } + chdir("/"); + if (extractingBin) { + while (!saved_etc) { + saved_etc = msgGetInput("/usr/tmp/etc", "Under which directory do you wish to save your current /etc?"); + if (!saved_etc || !*saved_etc || Mkdir(saved_etc, NULL)) { + if (msgYesNo("Directory was not specified, was invalid or user selected Cancel.\n\n" + "Doing an upgrade without first backing up your /etc directory is a very\n" + "bad idea! Do you want to go back and specify the save directory again?")) + break; + } + } + + if (saved_etc) { + msgNotify("Preserving /etc directory.."); + if (vsystem("cp -pr /etc/* %s", saved_etc)) { + msgConfirm("Unable to back up /etc directory to %s! Upgrade operation\n" + "aborted.", saved_etc); + return RET_FAIL; + } + } + + if (file_readable("/kernel")) { + msgNotify("Moving old kernel to /kernel.205."); + if (system("chflags noschg /mnt/kernel && mv /mnt/kernel /mnt/kernel.205")) + if (!msgYesNo("Hmmm! I couldn't move the old kernel over! Do you want to\n" + "treat this as a big problem and abort the upgrade?")) + return RET_FAIL; + } + } + msgNotify("Beginning extraction of distributions.."); + if (distExtractAll(NULL) == RET_FAIL) { + if (extractingBin && (Dists & DIST_BIN)) { + msgConfirm("Hmmmm. We couldn't even extract the bin distribution. This upgrade\n" + "should be considered a failure and started from the beginning, sorry!\n"); + return RET_FAIL; + } + msgConfirm("The extraction process seems to have had some problems, but we got most\n" + "of the essentials. We'll treat this as a warning since it may have been\n" + "a non-essential distribution which failed to load."); + } + + if (extractingBin) { + msgNotify("OK, now it's time to go pound on your root a little bit to create all the\n" + "/dev entries and such that a 2.1 system expects to see. I'll also perform a\n" + "few \"fixup\" operations to repair the effects of splatting a bin distribution\n" + "on top of an existing system.."); + if (installFixup() == RET_FAIL) + msgConfirm("Hmmmmm. The fixups don't seem to have been very happy.\n" + "You may wish to examine the system a little more closely when\n" + "it comes time to merge your /etc customizations back."); + } + + if (extractingBin) + configSysconfig(); + + if (installFinal() == RET_FAIL) + msgConfirm("Some of the final configuration stuff evidently failed, but\n" + "the first stage of the upgrade should otherwise be considered\n" + "a success!\n\n" + "Next comes stage 2, where we attempt to resurrect your /etc\n" + "directory!"); + else + msgConfirm("First stage of upgrade completed successfully!\n\n" + "Next comes stage 2, where we attempt to resurrect your /etc\n" + "directory!"); + + if (chdir(saved_etc)) { + msgConfirm("Unable to go to your saved /etc directory in %s?! Argh!\n" + "Something went seriously wrong! It's quite possible that\n" + "your former /etc is toast. I hope you didn't have any\n" + "important customizations you wanted to keep in there.. :(\n"); + return RET_FAIL; + } + + /* Now try to resurrect the /etc files */ + traverseHitlist(etc_files); + + msgConfirm("OK! At this stage, we've resurrected all the /etc files we could\n" + "(and you may have been warned about some that you'll have to merge\n" + "yourself, by hand) and we're going to drop you into a shell to do\n" + "the rest yourself (sorry about this!). Once the system looks good\n" + "to you, exit the shell and reboot the system."); + + chdir("/"); + dialog_clear(); + dialog_update(); + end_dialog(); + DialogActive = FALSE; + + if (!(child = fork())) { + int i, fd; + struct termios foo; + extern int login_tty(int); + + for (i = 0; i < 3; i++) + close(i); + fd = open("/dev/ttyv0", O_RDWR); + ioctl(0, TIOCSCTTY, &fd); + dup2(0, 1); + dup2(0, 2); + if (login_tty(fd) == -1) + msgDebug("Can't set the controlling terminal.\n"); + signal(SIGTTOU, SIG_IGN); + if (tcgetattr(fd, &foo) != -1) { + foo.c_cc[VERASE] = '\010'; + if (tcsetattr(fd, TCSANOW, &foo) == -1) + msgDebug("Unable to set the erase character.\n"); + } + else + msgDebug("Unable to get the terminal attributes!\n"); + printf("Well, good luck! When you're done, type exit to return.\n"); + execlp("sh", "-sh", 0); + msgDebug("Was unable to execute sh for post-upgrade shell!\n"); + exit(1); + } + else + (void)waitpid(child, &waitstatus, 0); + DialogActive = TRUE; + clear(); + dialog_clear(); + dialog_update(); + return RET_SUCCESS; +} |