Drat! Forgot the adds..

This commit is contained in:
Jordan K. Hubbard 1995-10-19 16:15:43 +00:00
parent 8ca961b3b4
commit 6430d4acf6
4 changed files with 972 additions and 0 deletions

View file

@ -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!

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}