install.c revision 22842
1139825Simp/*
21541Srgrimes * The new sysinstall program.
31549Srgrimes *
41549Srgrimes * This is probably the last program in the `sysinstall' line - the next
59507Sdg * generation being essentially a complete rewrite.
69507Sdg *
71541Srgrimes * $FreeBSD: head/usr.sbin/sade/install.c 22842 1997-02-17 13:29:47Z jkh $
81541Srgrimes *
91541Srgrimes * Copyright (c) 1995
101541Srgrimes *	Jordan Hubbard.  All rights reserved.
111541Srgrimes *
121541Srgrimes * Redistribution and use in source and binary forms, with or without
131541Srgrimes * modification, are permitted provided that the following conditions
141541Srgrimes * are met:
151541Srgrimes * 1. Redistributions of source code must retain the above copyright
161541Srgrimes *    notice, this list of conditions and the following disclaimer,
171541Srgrimes *    verbatim and that no modifications are made prior to this
181541Srgrimes *    point in the file.
191541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
201541Srgrimes *    notice, this list of conditions and the following disclaimer in the
2158705Scharnier *    documentation and/or other materials provided with the distribution.
221541Srgrimes *
231541Srgrimes * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
241541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
251541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
261541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
271541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
281541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
291541Srgrimes * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
301541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
311541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
321541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
331541Srgrimes * SUCH DAMAGE.
341541Srgrimes *
351541Srgrimes */
361541Srgrimes
371541Srgrimes#include "sysinstall.h"
381541Srgrimes#include "uc_main.h"
391541Srgrimes#include <ctype.h>
401549Srgrimes#include <sys/disklabel.h>
411541Srgrimes#include <sys/errno.h>
421541Srgrimes#include <sys/ioctl.h>
431541Srgrimes#include <sys/fcntl.h>
441541Srgrimes#include <sys/wait.h>
451541Srgrimes#include <sys/param.h>
461541Srgrimes#define MSDOSFS
471549Srgrimes#include <sys/mount.h>
481549Srgrimes#undef MSDOSFS
499507Sdg#include <sys/stat.h>
507695Sdg#include <unistd.h>
511549Srgrimes
521549Srgrimesstatic void	create_termcap(void);
53116226Sobrienstatic void	fixit_common(void);
54116226Sobrien#ifdef SAVE_USERCONFIG
55116226Sobrienstatic void	save_userconfig_to_kernel(char *);
561541Srgrimes#endif
571541Srgrimes
581541Srgrimes#define TERMCAP_FILE	"/usr/share/misc/termcap"
591541Srgrimes
601541Srgrimesstatic void	installConfigure(void);
6160041Sphk
629507SdgBoolean
6312662SdgcheckLabels(Boolean whinge, Chunk **rdev, Chunk **sdev, Chunk **udev, Chunk **vdev)
64140767Sphk{
6551340Sdillon    Device **devs;
66127926Salc    Boolean status;
671541Srgrimes    Disk *disk;
681541Srgrimes    Chunk *c1, *c2, *rootdev, *swapdev, *usrdev, *vardev;
6912662Sdg    int i;
701541Srgrimes
719507Sdg    status = TRUE;
7231853Sdyson    *rdev = *sdev = *udev = *vdev = rootdev = swapdev = usrdev = vardev = NULL;
731541Srgrimes
7412662Sdg    /* We don't need to worry about root/usr/swap if we're already multiuser */
751541Srgrimes    if (!RunningAsInit)
7692727Salfred	return status;
7792727Salfred
7892727Salfred    devs = deviceFind(NULL, DEVICE_TYPE_DISK);
7992727Salfred    /* First verify that we have a root device */
8092727Salfred    for (i = 0; devs[i]; i++) {
8192727Salfred	if (!devs[i]->enabled)
8292727Salfred	    continue;
8392727Salfred	disk = (Disk *)devs[i]->private;
8492727Salfred	msgDebug("Scanning disk %s for root filesystem\n", disk->name);
85140767Sphk	if (!disk->chunks)
8611943Sbde	    msgFatal("No chunk list found for %s!", disk->name);
871541Srgrimes	for (c1 = disk->chunks->part; c1; c1 = c1->next) {
88118466Sphk	    if (c1->type == freebsd) {
89118466Sphk		for (c2 = c1->part; c2; c2 = c2->next) {
90118466Sphk		    if (c2->type == part && c2->subtype != FS_SWAP && c2->private_data) {
91118466Sphk			if (c2->flags & CHUNK_IS_ROOT) {
92118466Sphk			    if (rootdev) {
93118466Sphk				if (whinge)
941541Srgrimes				    msgConfirm("WARNING:  You have more than one root device set?!\n"
951541Srgrimes					       "Using the first one found.");
9679127Sjhb				continue;
9710556Sdyson			    }
98104094Sphk			    else {
9979127Sjhb				rootdev = c2;
10079127Sjhb				if (isDebug())
10142957Sdillon				    msgDebug("Found rootdev at %s!\n", rootdev->name);
10279127Sjhb			    }
10379127Sjhb			}
10479127Sjhb			else if (!strcmp(((PartInfo *)c2->private_data)->mountpoint, "/usr")) {
105140767Sphk			    if (usrdev) {
106140767Sphk				if (whinge)
107140767Sphk				    msgConfirm("WARNING:  You have more than one /usr filesystem.\n"
108140767Sphk					       "Using the first one found.");
109140767Sphk				continue;
110140767Sphk			    }
111140767Sphk			    else {
112140767Sphk				usrdev = c2;
113140767Sphk				if (isDebug())
114140767Sphk				    msgDebug("Found usrdev at %s!\n", usrdev->name);
115140767Sphk			    }
116140767Sphk			}
117140767Sphk			else if (!strcmp(((PartInfo *)c2->private_data)->mountpoint, "/var")) {
118140767Sphk			    if (vardev) {
119140767Sphk				if (whinge)
120140767Sphk				    msgConfirm("WARNING:  You have more than one /var filesystem.\n"
121140767Sphk					       "Using the first one found.");
122140767Sphk				continue;
123140767Sphk			    }
124140767Sphk			    else {
125140767Sphk				vardev = c2;
126140767Sphk				if (isDebug())
127140767Sphk				    msgDebug("Found vardev at %s!\n", vardev->name);
128140767Sphk			    }
129140767Sphk			}
130140767Sphk		    }
131140767Sphk		}
132140767Sphk	    }
133140767Sphk	}
134140767Sphk    }
135140767Sphk
136140767Sphk    /* Now check for swap devices */
137140767Sphk    for (i = 0; devs[i]; i++) {
138140767Sphk	if (!devs[i]->enabled)
139140767Sphk	    continue;
140140767Sphk	disk = (Disk *)devs[i]->private;
141140767Sphk	msgDebug("Scanning disk %s for swap partitions\n", disk->name);
142140767Sphk	if (!disk->chunks)
143140767Sphk	    msgFatal("No chunk list found for %s!", disk->name);
144140767Sphk	for (c1 = disk->chunks->part; c1; c1 = c1->next) {
145140767Sphk	    if (c1->type == freebsd) {
146140767Sphk		for (c2 = c1->part; c2; c2 = c2->next) {
147140767Sphk		    if (c2->type == part && c2->subtype == FS_SWAP && !swapdev) {
148140767Sphk			swapdev = c2;
149140767Sphk			if (isDebug())
150140767Sphk			    msgDebug("Found swapdev at %s!\n", swapdev->name);
151140767Sphk			break;
152140767Sphk		    }
153140929Sphk		}
154140929Sphk	    }
155140929Sphk	}
156140929Sphk    }
157140929Sphk
158140929Sphk    /* Copy our values over */
159140929Sphk    *rdev = rootdev;
160140929Sphk    *sdev = swapdev;
161143505Sjeff    *udev = usrdev;
162140929Sphk    *vdev = vardev;
163140929Sphk
164140929Sphk    if (!rootdev && whinge) {
165140929Sphk	msgConfirm("No root device found - you must label a partition as /\n"
166140929Sphk		   "in the label editor.");
167140929Sphk	status = FALSE;
168140929Sphk    }
169140929Sphk    if (!swapdev && whinge) {
170140929Sphk	msgConfirm("No swap devices found - you must create at least one\n"
171140929Sphk		   "swap partition.");
172140929Sphk	status = FALSE;
173140929Sphk    }
174140929Sphk    if (!usrdev && whinge) {
175140929Sphk	msgConfirm("WARNING:  No /usr filesystem found.  This is not technically\n"
176140929Sphk		   "an error if your root filesystem is big enough (or you later\n"
177140929Sphk		   "intend to mount your /usr filesystem over NFS), but it may otherwise\n"
178140929Sphk		   "cause you trouble if you're not exactly sure what you are doing!");
179140929Sphk    }
180140929Sphk    if (!vardev && whinge) {
181140929Sphk	msgConfirm("WARNING:  No /var filesystem found.  This is not technically\n"
182140929Sphk		   "an error if your root filesystem is big enough (or you later\n"
183140929Sphk		   "intend to link /var to someplace else), but it may otherwise\n"
184140929Sphk		   "cause your root filesystem to fill up if you receive lots of mail\n"
185140929Sphk		   "or edit large temporary files.");
186140929Sphk    }
1871541Srgrimes    return status;
1881541Srgrimes}
1891541Srgrimes
19098604Salcstatic int
19198604SalcinstallInitial(void)
1921541Srgrimes{
1939507Sdg    static Boolean alreadyDone = FALSE;
19440286Sdg
19528751Sbde    if (alreadyDone)
1961541Srgrimes	return DITEM_SUCCESS;
1979456Sdg
1981541Srgrimes    if (!variable_get(DISK_LABELLED)) {
1991541Srgrimes	msgConfirm("You need to assign disk labels before you can proceed with\n"
2001541Srgrimes		   "the installation.");
2011541Srgrimes	return DITEM_FAILURE;
2021541Srgrimes    }
2031541Srgrimes    /* If it's labelled, assume it's also partitioned */
2041827Sdg    if (!variable_get(DISK_PARTITIONED))
2051541Srgrimes	variable_set2(DISK_PARTITIONED, "yes");
2069411Sdg
2079411Sdg    /* If we refuse to proceed, bail. */
208103923Sjeff    dialog_clear_norefresh();
209103923Sjeff    if (msgYesNo("Last Chance!  Are you SURE you want continue the installation?\n\n"
2101541Srgrimes		 "If you're running this on a disk with data you wish to save\n"
2119411Sdg		 "then WE STRONGLY ENCOURAGE YOU TO MAKE PROPER BACKUPS before\n"
2129411Sdg		 "proceeding!\n\n"
2131541Srgrimes		 "We can take no responsibility for lost disk contents!") != 0)
214101308Sjeff	return DITEM_FAILURE | DITEM_RESTORE;
215101308Sjeff
216101308Sjeff    if (DITEM_STATUS(diskLabelCommit(NULL)) != DITEM_SUCCESS) {
217101308Sjeff	msgConfirm("Couldn't make filesystems properly.  Aborting.");
2189411Sdg	return DITEM_FAILURE;
219101308Sjeff    }
220101308Sjeff    else if (isDebug())
2219411Sdg	msgDebug("installInitial: Scribbled successfully on the disk(s)\n");
2229411Sdg
2239411Sdg    if (!copySelf()) {
2249411Sdg	msgConfirm("Couldn't clone the boot floppy onto the root file system.\n"
2259411Sdg		   "Aborting.");
226114074Salc	return DITEM_FAILURE;
227114074Salc    }
228114074Salc
229114074Salc    if (chroot("/mnt") == -1) {
230137297Salc	msgConfirm("Unable to chroot to %s - this is bad!", "/mnt");
231114074Salc	return DITEM_FAILURE;
2329507Sdg    }
2335455Sdg
23432071Sdyson    chdir("/");
23532071Sdyson    variable_set2(RUNNING_ON_ROOT, "yes");
23632071Sdyson    configResolv();
2379507Sdg
2381541Srgrimes    /* stick a helpful shell over on the 4th VTY */
2391541Srgrimes    systemCreateHoloshell();
2401541Srgrimes
24140286Sdg    alreadyDone = TRUE;
2421827Sdg    return DITEM_SUCCESS;
24340286Sdg}
2441549Srgrimes
2459507Sdgint
2469507SdginstallFixitHoloShell(dialogMenuItem *self)
2471541Srgrimes{
24832286Sdyson    systemCreateHoloshell();
249114074Salc    return DITEM_SUCCESS;
2501541Srgrimes}
251101308Sjeff
25298604Salcint
253101308SjeffinstallFixitCDROM(dialogMenuItem *self)
254101308Sjeff{
255101308Sjeff    struct stat sb;
2569411Sdg
2579411Sdg    if (!RunningAsInit)
258101308Sjeff	return DITEM_SUCCESS;
2599507Sdg
2601541Srgrimes    variable_set2(SYSTEM_STATE, "fixit");
2611541Srgrimes    (void)unlink("/mnt2");
262114774Salc    (void)rmdir("/mnt2");
263114774Salc
264114774Salc    while (1) {
26512820Sphk	msgConfirm("Please insert the second FreeBSD CDROM and press return");
2669507Sdg	if (DITEM_STATUS(mediaSetCDROM(NULL)) != DITEM_SUCCESS || !mediaDevice || !mediaDevice->init(mediaDevice)) {
2679507Sdg	    /* If we can't initialize it, it's probably not a FreeBSD CDROM so punt on it */
2681541Srgrimes	    if (mediaDevice) {
26979242Sdillon		mediaDevice->shutdown(mediaDevice);
2701541Srgrimes		mediaDevice = NULL;
2719507Sdg	    }
2729507Sdg	    if (msgYesNo("Unable to mount the CDROM - do you want to try again?") != 0)
2739507Sdg		return DITEM_FAILURE;
274114774Salc	}
27533817Sdyson	else
2761541Srgrimes	    break;
2779507Sdg    }
27833109Sdyson
279137297Salc    /* Since the fixit code expects everything to be in /mnt2, and the CDROM mounting stuff /dist, do
280137297Salc     * a little kludge dance here..
281137297Salc     */
282137297Salc    if (symlink("/dist", "/mnt2")) {
283101308Sjeff	msgConfirm("Unable to symlink /mnt2 to the CDROM mount point.  Please report this\n"
2849507Sdg		   "unexpected failure to bugs@freebsd.org.");
285140734Sphk	return DITEM_FAILURE;
2861549Srgrimes    }
2871541Srgrimes
28812820Sphk    /*
28912767Sdyson     * If /tmp points to /mnt2/tmp from a previous fixit floppy session, it's
2909507Sdg     * not very good for us if we point it to the CDROM now.  Rather make it
29112767Sdyson     * a directory in the root MFS then.  Experienced admins will still be
2929507Sdg     * able to mount their disk's /tmp over this if they need.
2939507Sdg     */
2941541Srgrimes    if (lstat("/tmp", &sb) == 0 && (sb.st_mode & S_IFMT) == S_IFLNK)
2959507Sdg	(void)unlink("/tmp");
29696572Sphk    Mkdir("/tmp");
29712423Sphk
29810556Sdyson    /*
29911701Sdyson     * Since setuid binaries ignore LD_LIBRARY_PATH, we indeed need the
30011701Sdyson     * ld.so.hints file.  Fortunately, it's fairly small (~ 3 KB).
30112914Sdyson     */
302140723Sjeff    if (!file_readable("/var/run/ld.so.hints")) {
3031541Srgrimes	Mkdir("/var/run");
304116695Salc	if (vsystem("/mnt2/sbin/ldconfig -s /mnt2/usr/lib")) {
30551340Sdillon	    msgConfirm("Warning: ldconfig could not create the ld.so hints file.\n"
30651340Sdillon		       "Dynamic executables from the CDROM likely won't work.");
30751340Sdillon	}
30851340Sdillon    }
309101308Sjeff
31032585Sdyson    /* Yet another iggly hardcoded pathname. */
31132585Sdyson    if (!file_readable("/usr/libexec/ld.so")) {
312103923Sjeff	Mkdir("/usr/libexec");
313103923Sjeff	if (symlink("/mnt2/usr/libexec/ld.so", "/usr/libexec/ld.so")) {
314103923Sjeff	    msgConfirm("Warning: could not create the symlink for ld.so.\n"
315101308Sjeff		       "Dynamic executables from the CDROM likely won't work.");
316103923Sjeff	}
317103923Sjeff    }
3181541Srgrimes
3195455Sdg    fixit_common();
3205455Sdg
3211541Srgrimes    msgConfirm("Please remove the FreeBSD CDROM now.");
32212767Sdyson    mediaDevice->shutdown(mediaDevice);
32381140Sjhb    return DITEM_SUCCESS;
3244797Sdg}
3251541Srgrimes
32611576Sdgint
32710556SdysoninstallFixitFloppy(dialogMenuItem *self)
32812914Sdyson{
32912914Sdyson    struct ufs_args args;
33012914Sdyson
33112914Sdyson    if (!RunningAsInit)
33212914Sdyson	return DITEM_SUCCESS;
33312914Sdyson
33412914Sdyson    variable_set2(SYSTEM_STATE, "fixit");
335116695Salc    memset(&args, 0, sizeof(args));
336140723Sjeff    args.fspec = "/dev/fd0";
337119045Sphk    Mkdir("/mnt2");
338140723Sjeff
339116695Salc    while (1) {
3408876Srgrimes	msgConfirm("Please insert a writable fixit floppy and press return");
3419507Sdg	if (mount(MOUNT_UFS, "/mnt2", 0, (caddr_t)&args) != -1)
34292029Seivind	    break;
34310576Sdyson	msgConfirm("An attempt to mount the fixit floppy failed, maybe the filesystem\n"
34412914Sdyson		   "is unclean.  Trying a forcible mount as a last resort...");
34512914Sdyson	if (mount(MOUNT_UFS, "/mnt2", MNT_FORCE, (caddr_t)&args) != -1)
34612914Sdyson	    break;
34712914Sdyson	if (msgYesNo("Unable to mount the fixit floppy - do you want to try again?") != 0)
34812914Sdyson	    return DITEM_FAILURE;
34910669Sdyson    }
35012914Sdyson
35112914Sdyson    if (!directory_exists("/tmp"))
35212914Sdyson	(void)symlink("/mnt2/tmp", "/tmp");
35312914Sdyson
35499211Srobert    fixit_common();
35599211Srobert
35699211Srobert    msgConfirm("Please remove the fixit floppy now.");
35799211Srobert    unmount("/mnt2", MNT_FORCE);
35899211Srobert    return DITEM_SUCCESS;
35912914Sdyson}
36012914Sdyson
36112914Sdyson/*
36212914Sdyson * The common code for both fixit variants.
36312914Sdyson */
36412914Sdysonstatic void
36512914Sdysonfixit_common(void)
36612914Sdyson{
36712914Sdyson    pid_t child;
36812914Sdyson    int waitstatus;
36912914Sdyson
37010556Sdyson    if (!directory_exists("/var/tmp/vi.recover")) {
37110576Sdyson	if (DITEM_STATUS(Mkdir("/var/tmp/vi.recover")) != DITEM_SUCCESS) {
3721541Srgrimes	    msgConfirm("Warning:  Was unable to create a /var/tmp/vi.recover directory.\n"
3731541Srgrimes		       "vi will kvetch and moan about it as a result but should still\n"
3741541Srgrimes		       "be essentially usable.");
3751541Srgrimes	}
3769507Sdg    }
3771541Srgrimes    if (!directory_exists("/bin"))
3781541Srgrimes	(void)Mkdir("/bin");
3791541Srgrimes    (void)symlink("/stand/sh", "/bin/sh");
3801541Srgrimes    /* Link the /etc/ files */
3811541Srgrimes    if (DITEM_STATUS(Mkdir("/etc")) != DITEM_SUCCESS)
3821541Srgrimes	msgConfirm("Unable to create an /etc directory!  Things are weird on this floppy..");
3831541Srgrimes    else if ((symlink("/mnt2/etc/spwd.db", "/etc/spwd.db") == -1 && errno != EEXIST) ||
3841541Srgrimes	     (symlink("/mnt2/etc/protocols", "/etc/protocols") == -1 && errno != EEXIST) ||
38512767Sdyson	     (symlink("/mnt2/etc/services", "/etc/services") == -1 && errno != EEXIST))
3861541Srgrimes	msgConfirm("Couldn't symlink the /etc/ files!  I'm not sure I like this..");
387116167Salc    if (!file_readable(TERMCAP_FILE))
388116167Salc	create_termcap();
38938542Sluoqi    if (!(child = fork())) {
3901541Srgrimes	int i, fd;
391116167Salc	struct termios foo;
3921541Srgrimes	extern int login_tty(int);
393116167Salc
394116167Salc	ioctl(0, TIOCNOTTY, NULL);
395116167Salc	for (i = getdtablesize(); i >= 0; --i)
396116167Salc	    close(i);
397116167Salc	fd = open("/dev/ttyv3", O_RDWR);
398116167Salc	ioctl(0, TIOCSCTTY, &fd);
3993374Sdg	dup2(0, 1);
400116167Salc	dup2(0, 2);
40138542Sluoqi	DebugFD = 2;
4029507Sdg	if (login_tty(fd) == -1)
403116167Salc	    msgDebug("fixit: I can't set the controlling terminal.\n");
404116167Salc
405116167Salc	signal(SIGTTOU, SIG_IGN);
406116167Salc	if (tcgetattr(0, &foo) != -1) {
40738542Sluoqi	    foo.c_cc[VERASE] = '\010';
408116167Salc	    if (tcsetattr(0, TCSANOW, &foo) == -1)
4091827Sdg		msgDebug("fixit shell: Unable to set erase character.\n");
4101827Sdg	}
41187834Sdillon	else
41287834Sdillon	    msgDebug("fixit shell: Unable to get terminal attributes!\n");
41387834Sdillon	setenv("PATH", "/bin:/sbin:/usr/bin:/usr/sbin:/stand:"
41487834Sdillon	       "/mnt2/stand:/mnt2/bin:/mnt2/sbin:/mnt2/usr/bin:/mnt2/usr/sbin", 1);
41587834Sdillon	/* use the .profile from the fixit medium */
4161827Sdg	setenv("HOME", "/mnt2", 1);
417116167Salc	chdir("/mnt2");
418121230Salc	execlp("sh", "-sh", 0);
419121230Salc	msgDebug("fixit shell: Failed to execute shell!\n");
420121230Salc	_exit(1);;
421121230Salc    }
42270374Sdillon    else {
423121230Salc	msgNotify("Waiting for fixit shell to exit.  Go to VTY4 now by\n"
424121230Salc		  "typing ALT-F4.  When you are done, type ``exit'' to exit\n"
425121230Salc		  "the fixit shell and be returned here.");
426121230Salc	(void)waitpid(child, &waitstatus, 0);
427121230Salc    }
42870374Sdillon    dialog_clear();
429121230Salc}
430121230Salc
431121230Salc
432121230Salcint
433121230SalcinstallExpress(dialogMenuItem *self)
434121230Salc{
435121230Salc    int i;
436121230Salc
437121230Salc    variable_set2(SYSTEM_STATE, "express");
438121230Salc    if (DITEM_STATUS((i = diskPartitionEditor(self))) == DITEM_FAILURE)
439121230Salc	return i;
440121230Salc
441121230Salc    if (DITEM_STATUS((i = diskLabelEditor(self))) == DITEM_FAILURE)
442121230Salc	return i;
44387834Sdillon
444121230Salc    if (DITEM_STATUS((i = installCommit(self))) == DITEM_SUCCESS) {
445121230Salc	i |= DITEM_LEAVE_MENU;
446121230Salc	/* Give user the option of one last configuration spree */
447121230Salc	installConfigure();
448121230Salc    }
449121230Salc    return i | DITEM_RESTORE;
450121230Salc}
451121230Salc
452121230Salc/* Novice mode installation */
453121230Salcint
454121230SalcinstallNovice(dialogMenuItem *self)
455121230Salc{
456121230Salc    int i;
457121230Salc
458121230Salc    variable_set2(SYSTEM_STATE, "novice");
459121230Salc    dialog_clear_norefresh();
460116167Salc    msgConfirm("In the next menu, you will need to set up a DOS-style (\"fdisk\") partitioning\n"
4611827Sdg	       "scheme for your hard disk.  If you simply wish to devote all disk space\n"
4621541Srgrimes	       "to FreeBSD (overwritting anything else that might be on the disk(s) selected)\n"
46312767Sdyson	       "then use the (A)ll command to select the default partitioning scheme followed\n"
46438542Sluoqi	       "by a (Q)uit.  If you wish to allocate only free space to FreeBSD, move to a\n"
465116167Salc	       "partition marked \"unused\" and use the (C)reate command.");
4661541Srgrimes
4671541Srgrimes    if (DITEM_STATUS(diskPartitionEditor(self)) == DITEM_FAILURE)
4681549Srgrimes	return DITEM_FAILURE;
4691549Srgrimes
4701549Srgrimes    dialog_clear_norefresh();
4711549Srgrimes    msgConfirm("Next, you need to create BSD partitions inside of the fdisk partition(s)\n"
47212820Sphk	       "just created.  If you have a reasonable amount of disk space (200MB or more)\n"
4736151Sdg	       "and don't have any special requirements, simply use the (A)uto command to\n"
4741549Srgrimes	       "allocate space automatically.  If you have more specific needs or just don't\n"
47512767Sdyson	       "care for the layout chosen by (A)uto, press F1 for more information on\n"
4766151Sdg	       "manual layout.");
4771549Srgrimes
4785455Sdg    if (DITEM_STATUS(diskLabelEditor(self)) == DITEM_FAILURE)
4795455Sdg	return DITEM_FAILURE;
48096572Sphk
4815455Sdg    if (DITEM_STATUS((i = installCommit(self))) == DITEM_FAILURE) {
48212767Sdyson	dialog_clear_norefresh();
48312767Sdyson	msgConfirm("Installation completed with some errors.  You may wish to\n"
4841549Srgrimes		   "scroll through the debugging messages on VTY1 with the\n"
485138531Salc		   "scroll-lock feature.  You can also chose \"No\" at the next\n"
4865455Sdg		   "prompt and go back into the installation menus to try and retry\n"
4875455Sdg		   "whichever operations have failed.");
48811701Sdyson	return i | DITEM_RESTORE;
48911701Sdyson
49011701Sdyson    }
4911549Srgrimes    else {
4921549Srgrimes	dialog_clear_norefresh();
4931549Srgrimes	msgConfirm("Congratulations!  You now have FreeBSD installed on your system.\n\n"
4941549Srgrimes		   "We will now move on to the final configuration questions.\n"
495119045Sphk		   "For any option you do not wish to configure, simply select\n"
4961549Srgrimes		   "No.\n\n"
4976151Sdg		   "If you wish to re-enter this utility after the system is up, you\n"
4981549Srgrimes		   "may do so by typing: /stand/sysinstall.");
4996151Sdg    }
5006626Sdg    if (mediaDevice->type != DEVICE_TYPE_FTP && mediaDevice->type != DEVICE_TYPE_NFS) {
50192029Seivind	if (!msgYesNo("Would you like to configure any SLIP/PPP or network interface devices?")) {
5026151Sdg	    Device *tmp;
5036151Sdg
5046151Sdg	    tmp = tcpDeviceSelect();
5056151Sdg	    if (tmp && !msgYesNo("Would you like to bring the %s interface up right now?", tmp->name))
5066151Sdg		if (!tmp->init(tmp))
5071549Srgrimes		    msgConfirm("Initialization of %s device failed.", tmp->name);
5081549Srgrimes	    dialog_clear_norefresh();
5091549Srgrimes	}
5101549Srgrimes    }
5111549Srgrimes
51296755Strhodes    dialog_clear_norefresh();
5131549Srgrimes    if (!msgYesNo("Would you like to configure Samba for connecting NETBUI clients to this\n"
51412820Sphk		  "machine?  Windows 95, Windows NT and Windows for Workgroups\n"
5159507Sdg		  "machines can use NETBUI transport for disk and printer sharing."))
5169507Sdg	configSamba(self);
5171549Srgrimes
5181549Srgrimes    dialog_clear_norefresh();
5195455Sdg    if (!msgYesNo("Will this machine be an IP gateway (e.g. will it forward packets\n"
520137726Sphk		  "between interfaces)?"))
521137726Sphk	variable_set2("gateway", "YES");
5221549Srgrimes
523127926Salc    dialog_clear_norefresh();
5245455Sdg    if (!msgYesNo("Do you want to allow anonymous FTP connections to this machine?"))
5251549Srgrimes	configAnonFTP(self);
5265455Sdg
5271549Srgrimes    dialog_clear_norefresh();
5289507Sdg    if (!msgYesNo("Do you want to configure this machine as an NFS server?"))
52911701Sdyson	configNFSServer(self);
53011701Sdyson
53111701Sdyson    dialog_clear_norefresh();
5321549Srgrimes    if (!msgYesNo("Do you want to configure this machine as an NFS client?"))
5331549Srgrimes	variable_set2("nfs_client", "YES");
534137726Sphk
5351549Srgrimes    dialog_clear_norefresh();
536127926Salc    if (!msgYesNo("Do you want to configure this machine as a WEB server?"))
5371549Srgrimes	configApache(self);
5381827Sdg
53986092Sdillon    dialog_clear_norefresh();
5401827Sdg    if (!msgYesNo("Would you like to customize your system console settings?")) {
54145561Sdt	WINDOW *w = savescr();
5425455Sdg
5431549Srgrimes	dmenuOpenSimple(&MenuSyscons, FALSE);
54486092Sdillon	restorescr(w);
54586092Sdillon    }
54686092Sdillon
54786092Sdillon    dialog_clear_norefresh();
54886092Sdillon    if (!msgYesNo("Would you like to set this machine's time zone now?")) {
54986092Sdillon	WINDOW *w = savescr();
5501827Sdg
55142957Sdillon	dialog_clear();
5521549Srgrimes	systemExecute("tzsetup");
5531827Sdg	restorescr(w);
55458345Sphk    }
555119092Sphk
55684827Sjhb    dialog_clear_norefresh();
55784827Sjhb    if (!msgYesNo("Does this system have a mouse attached to it?")) {
55891406Sjhb	WINDOW *w = savescr();
55991406Sjhb
560127926Salc	dmenuOpenSimple(&MenuMouse, FALSE);
5616626Sdg	restorescr(w);
562137726Sphk    }
5631549Srgrimes
5641549Srgrimes    if (directory_exists("/usr/X11R6")) {
56570374Sdillon	dialog_clear_norefresh();
56670374Sdillon	if (!msgYesNo("Would you like to configure your X server at this time?"))
5671827Sdg	    configXFree86(self);
5681827Sdg    }
569121205Sphk
570136927Sphk    dialog_clear_norefresh();
5711549Srgrimes    if (!msgYesNo("The FreeBSD package collection is a collection of hundreds of ready-to-run\n"
57233758Sdyson		  "applications, from text editors to games to WEB servers and more.  Would you\n"
5731549Srgrimes		  "like to browse the collection now?"))
574119092Sphk	configPackages(self);
575119092Sphk
57658934Sphk    dialog_clear_norefresh();
5771549Srgrimes    if (!msgYesNo("Would you like to add any initial user accounts to the system?\n"
5781549Srgrimes		  "Adding at least one account for yourself at this stage is suggested\n"
5791827Sdg		  "since working as the \"root\" user is dangerous (it is easy to do\n"
5801827Sdg		  "things which adversely affect the entire system)."))
5811827Sdg	configUsers(self);
582137726Sphk
58342957Sdillon    dialog_clear_norefresh();
5841827Sdg    if (!msgYesNo("Would you like to set the system manager's password now?\n\n"
5851549Srgrimes		  "This is the password you'll use to log in as \"root\".")) {
5865455Sdg	WINDOW *w = savescr();
587121264Salc
588107189Salc	systemExecute("passwd root");
58915583Sphk	restorescr(w);
590107189Salc    }
591121264Salc
5921549Srgrimes    /* XXX Put whatever other nice configuration questions you'd like to ask the user here XXX */
593121264Salc
594107189Salc    /* Give user the option of one last configuration spree */
59515583Sphk    installConfigure();
596107189Salc
597121264Salc    return DITEM_LEAVE_MENU | DITEM_RESTORE;
598127926Salc}
5991549Srgrimes
6001549Srgrimes/* The version of commit we call from the Install Custom menu */
601127926Salcint
602107347SalcinstallCustomCommit(dialogMenuItem *self)
60360755Speter{
604107347Salc    int i;
6051827Sdg
6064207Sdg    i = installCommit(self);
6071549Srgrimes    if (DITEM_STATUS(i) == DITEM_SUCCESS) {
6081549Srgrimes	/* Give user the option of one last configuration spree */
6091549Srgrimes	installConfigure();
6101549Srgrimes	return i;
6111549Srgrimes    }
6121549Srgrimes    else
6131549Srgrimes	msgConfirm("The commit operation completed with errors.  Not\n"
614139296Sphk		   "updating /etc files.");
6151549Srgrimes    return i;
61612820Sphk}
6179507Sdg
6189507Sdg/*
6191549Srgrimes * What happens when we finally decide to going ahead with the installation.
6201549Srgrimes *
6211541Srgrimes * This is broken into multiple stages so that the user can do a full
6221541Srgrimes * installation but come back here again to load more distributions,
6235455Sdg * perhaps from a different media type.  This would allow, for
6245455Sdg * example, the user to load the majority of the system from CDROM and
625127926Salc * then use ftp to load just the DES dist.
62677398Sjhb */
6271549Srgrimesint
628121495SalcinstallCommit(dialogMenuItem *self)
6291549Srgrimes{
6301827Sdg    int i;
6311549Srgrimes    char *str;
6321549Srgrimes    Boolean need_bin;
6331549Srgrimes
63412767Sdyson    if (!Dists) {
6351549Srgrimes	if (!dmenuOpenSimple(&MenuDistributions, FALSE) && !Dists)
6361549Srgrimes	    return DITEM_FAILURE | DITEM_RESTORE;
6371549Srgrimes    }
63812767Sdyson
63912767Sdyson    if (!mediaDevice) {
640121495Salc	if (!dmenuOpenSimple(&MenuMedia, FALSE) || !mediaDevice)
641121495Salc	    return DITEM_FAILURE | DITEM_RESTORE;
6427178Sdg    }
6435455Sdg
6445455Sdg    str = variable_get(SYSTEM_STATE);
6455455Sdg    if (isDebug())
6465455Sdg	msgDebug("installCommit: System state is `%s'\n", str);
647127926Salc
6487178Sdg    if (RunningAsInit) {
649127926Salc	/* Do things we wouldn't do to a multi-user system */
6501549Srgrimes	if (DITEM_STATUS((i = installInitial())) == DITEM_FAILURE)
6511549Srgrimes	    return i;
6521549Srgrimes	if (DITEM_STATUS((i = configFstab())) == DITEM_FAILURE)
65312767Sdyson	    return i;
6541549Srgrimes    }
6551549Srgrimes
6561549Srgrimestry_media:
65783366Sjulian    if (!mediaDevice->init(mediaDevice)) {
6581549Srgrimes	if (!msgYesNo("Unable to initialize selected media. Would you like to\n"
65991406Sjhb		      "adjust your media configuration and try again?")) {
6601549Srgrimes	    if (!dmenuOpenSimple(&MenuMedia, FALSE) || !mediaDevice)
66179242Sdillon		return DITEM_FAILURE | DITEM_RESTORE;
6621549Srgrimes	    else
6631549Srgrimes		goto try_media;
6641549Srgrimes	}
6651549Srgrimes	else
666127926Salc	    return DITEM_FAILURE | DITEM_RESTORE;
667127926Salc    }
6681549Srgrimes
669127926Salc    need_bin = Dists & DIST_BIN;
670121230Salc    i = distExtractAll(self);
671121230Salc    if (DITEM_STATUS(i) == DITEM_SUCCESS) {
6721549Srgrimes	if (need_bin && !(Dists & DIST_BIN))
673107347Salc	    i = installFixup(self);
67460755Speter    }
67549945Salc    variable_set2(SYSTEM_STATE, DITEM_STATUS(i) == DITEM_FAILURE ? "error-install" : "full-install");
676121230Salc    return i | DITEM_RESTORE;
67739739Srvb}
67839739Srvb
6794207Sdgstatic void
6801549SrgrimesinstallConfigure(void)
6811549Srgrimes{
6821549Srgrimes    /* Final menu of last resort */
6831549Srgrimes    dialog_clear_norefresh();
6841549Srgrimes    if (!msgYesNo("Visit the general configuration menu for a chance to set\n"
68510556Sdyson		  "any last options?")) {
68633847Smsmith	WINDOW *w = savescr();
68776827Salfred
68899211Srobert	dmenuOpenSimple(&MenuConfigure, FALSE);
68999211Srobert	restorescr(w);
69033847Smsmith    }
69133847Smsmith}
69233847Smsmith
69333847Smsmithint
69412820SphkinstallFixup(dialogMenuItem *self)
6959507Sdg{
6969507Sdg    Device **devs;
6971549Srgrimes    int i;
6989507Sdg
6999507Sdg    if (!file_readable("/kernel")) {
7001549Srgrimes	if (file_readable("/kernel.GENERIC")) {
70110556Sdyson#ifdef SAVE_USERCONFIG
70210556Sdyson	    /* Snapshot any boot -c changes back to the GENERIC kernel */
70334403Smsmith	    if (!strcmp(variable_get(VAR_RELNAME), RELEASE_NAME))
704140723Sjeff		save_userconfig_to_kernel("/kernel.GENERIC");
70532286Sdyson#endif
70610556Sdyson	    if (vsystem("cp -p /kernel.GENERIC /kernel")) {
707116279Salc		msgConfirm("Unable to link /kernel into place!");
708140723Sjeff		return DITEM_FAILURE;
70934403Smsmith	    }
71076827Salfred	}
71176827Salfred	else {
712140723Sjeff	    msgConfirm("Can't find a kernel image to link to on the root file system!\n"
713116279Salc		       "You're going to have a hard time getting this system to\n"
71433847Smsmith		       "boot from the hard disk, I'm afraid!");
71510556Sdyson	    return DITEM_FAILURE;
71610556Sdyson	}
71733847Smsmith    }
71833847Smsmith
71933847Smsmith    /* Resurrect /dev after bin distribution screws it up */
72033847Smsmith    if (RunningAsInit) {
72133847Smsmith	msgNotify("Remaking all devices.. Please wait!");
72233847Smsmith	if (vsystem("cd /dev; sh MAKEDEV all")) {
72333847Smsmith	    msgConfirm("MAKEDEV returned non-zero status");
72410556Sdyson	    return DITEM_FAILURE;
72533847Smsmith	}
72610556Sdyson
72710556Sdyson	msgNotify("Resurrecting /dev entries for slices..");
72833847Smsmith	devs = deviceFind(NULL, DEVICE_TYPE_DISK);
72912767Sdyson	if (!devs)
73034206Sdyson	    msgFatal("Couldn't get a disk device list!");
731100832Salc
732137726Sphk	/* Resurrect the slices that the former clobbered */
7336151Sdg	for (i = 0; devs[i]; i++) {
7346151Sdg	    Disk *disk = (Disk *)devs[i]->private;
7357178Sdg	    Chunk *c1;
73633847Smsmith
7375455Sdg	    if (!devs[i]->enabled)
7381549Srgrimes		continue;
73933847Smsmith	    if (!disk->chunks)
74033847Smsmith		msgFatal("No chunk list found for %s!", disk->name);
74133847Smsmith	    for (c1 = disk->chunks->part; c1; c1 = c1->next) {
742137726Sphk		if (c1->type == freebsd) {
743137726Sphk		    msgNotify("Making slice entries for %s", c1->name);
74411701Sdyson		    if (vsystem("cd /dev; sh MAKEDEV %sh", c1->name)) {
74511701Sdyson			msgConfirm("Unable to make slice entries for %s!", c1->name);
74611701Sdyson			return DITEM_FAILURE;
7471549Srgrimes		    }
7481549Srgrimes		}
7491549Srgrimes	    }
7501827Sdg	}
7511549Srgrimes	/* XXX Do all the last ugly work-arounds here which we'll try and excise someday right?? XXX */
7521827Sdg
7531827Sdg	msgNotify("Fixing permissions..");
7541549Srgrimes	/* BOGON #1:  XFree86 extracting /usr/X11R6 with root-only perms */
75512767Sdyson	if (directory_exists("/usr/X11R6")) {
7561827Sdg	    vsystem("chmod -R a+r /usr/X11R6");
7571549Srgrimes	    vsystem("find /usr/X11R6 -type d | xargs chmod a+x");
7581887Sdg	}
7591549Srgrimes	/* BOGON #2: We leave /etc in a bad state */
760137726Sphk	chmod("/etc", 0755);
761116512Salc
762100832Salc	/* BOGON #3: No /var/db/mountdtab complains */
763100832Salc	Mkdir("/var/db");
764100832Salc	creat("/var/db/mountdtab", 0644);
76575692Salfred
766100832Salc	/* Now run all the mtree stuff to fix things up */
7673612Sdg        vsystem("mtree -deU -f /etc/mtree/BSD.root.dist -p /");
7683612Sdg        vsystem("mtree -deU -f /etc/mtree/BSD.var.dist -p /var");
769121495Salc        vsystem("mtree -deU -f /etc/mtree/BSD.usr.dist -p /usr");
770121495Salc    }
771121495Salc    return DITEM_SUCCESS;
7721549Srgrimes}
7731827Sdg
7741827Sdg/* Go newfs and/or mount all the filesystems we've been asked to */
7751827Sdgint
7761827SdginstallFilesystems(dialogMenuItem *self)
7771827Sdg{
7781827Sdg    int i;
77938866Sbde    Disk *disk;
780116512Salc    Chunk *c1, *c2, *rootdev, *swapdev, *usrdev, *vardev;
781100832Salc    Device **devs;
782100832Salc    PartInfo *root;
783100832Salc    char dname[80], *str;
78475692Salfred    extern int MakeDevChunk(Chunk *c, char *n);
785100832Salc    Boolean upgrade = FALSE;
786116512Salc
7873612Sdg    /* If we've already done this, bail out */
7883612Sdg    if ((str = variable_get(DISK_LABELLED)) && !strcmp(str, "written"))
7899507Sdg	return DITEM_SUCCESS;
7901549Srgrimes
79145347Sjulian    str = variable_get(SYSTEM_STATE);
7921549Srgrimes
79345347Sjulian    if (!checkLabels(TRUE, &rootdev, &swapdev, &usrdev, &vardev))
79445347Sjulian	return DITEM_FAILURE;
79545347Sjulian
7961549Srgrimes    if (rootdev)
797121227Salc	root = (PartInfo *)rootdev->private_data;
79845347Sjulian    else
799100832Salc	root = NULL;
800100832Salc
8015455Sdg    command_clear();
80275692Salfred    upgrade = str && !strcmp(str, "upgrade");
803100832Salc
804116512Salc    if (swapdev && RunningAsInit) {
8055455Sdg	/* As the very first thing, try to get ourselves some swap space */
8061549Srgrimes	sprintf(dname, "/dev/%s", swapdev->name);
80745347Sjulian	if (!Fake && (!MakeDevChunk(swapdev, "/dev") || !file_readable(dname))) {
808121227Salc	    msgConfirm("Unable to make device node for %s in /dev!\n"
8097178Sdg		       "The creation of filesystems will be aborted.", dname);
8105455Sdg	    return DITEM_FAILURE;
8115455Sdg	}
8125455Sdg
81392029Seivind	if (!Fake) {
8141549Srgrimes	    if (!swapon(dname))
8151549Srgrimes		msgNotify("Added %s as initial swap device", dname);
8166151Sdg	    else
8171549Srgrimes		msgConfirm("WARNING!  Unable to swap to %s: %s\n"
81892029Seivind			   "This may cause the installation to fail at some point\n"
81912767Sdyson			   "if you don't have a lot of memory.", dname, strerror(errno));
82012767Sdyson	}
8216151Sdg    }
822116512Salc
8239507Sdg    if (rootdev && RunningAsInit) {
824106603Smux	/* Next, create and/or mount the root device */
825106603Smux	sprintf(dname, "/dev/r%sa", rootdev->disk->name);
826106603Smux	if (!Fake && (!MakeDevChunk(rootdev, "/dev") || !file_readable(dname))) {
827106603Smux	    msgConfirm("Unable to make device node for %s in /dev!\n"
828106603Smux		       "The creation of filesystems will be aborted.", dname);
829106603Smux	    return DITEM_FAILURE;
8306151Sdg	}
831100832Salc	if (strcmp(root->mountpoint, "/"))
83275692Salfred	    msgConfirm("Warning: %s is marked as a root partition but is mounted on %s", rootdev->name, root->mountpoint);
833100832Salc
834116512Salc	if (root->newfs) {
8356151Sdg	    int i;
8366151Sdg
8376151Sdg	    msgNotify("Making a new root filesystem on %s", dname);
8381549Srgrimes	    i = vsystem("%s %s", root->newfs_cmd, dname);
8396151Sdg	    if (i) {
8409507Sdg		msgConfirm("Unable to make new root filesystem on %s!\n"
841116512Salc			   "Command returned status %d", dname, i);
842100832Salc		return DITEM_FAILURE;
843100832Salc	    }
84475692Salfred	}
845100832Salc	else {
846116512Salc	    if (!upgrade) {
8471549Srgrimes		msgConfirm("Warning:  Using existing root partition.  It will be assumed\n"
8489507Sdg			   "that you have the appropriate device entries already in /dev.");
849116512Salc	    }
850100832Salc	    msgNotify("Checking integrity of existing %s filesystem.", dname);
8519507Sdg	    i = vsystem("fsck -y %s", dname);
85275692Salfred	    if (i)
853100832Salc		msgConfirm("Warning: fsck returned status of %d for %s.\n"
854116512Salc			   "This partition may be unsafe to use.", i, dname);
8556151Sdg	}
8566151Sdg
8576151Sdg	/* Switch to block device */
8581549Srgrimes	sprintf(dname, "/dev/%sa", rootdev->disk->name);
8596151Sdg	if (Mount("/mnt", dname)) {
8601549Srgrimes	    msgConfirm("Unable to mount the root file system on %s!  Giving up.", dname);
8611549Srgrimes	    return DITEM_FAILURE;
8621549Srgrimes	}
8631827Sdg    }
8641827Sdg
8651549Srgrimes    /* Now buzz through the rest of the partitions and mount them too */
8661549Srgrimes    devs = deviceFind(NULL, DEVICE_TYPE_DISK);
8671549Srgrimes    for (i = 0; devs[i]; i++) {
8681549Srgrimes	if (!devs[i]->enabled)
8691549Srgrimes	    continue;
8701549Srgrimes
8711549Srgrimes	disk = (Disk *)devs[i]->private;
8721549Srgrimes	if (!disk->chunks) {
8736151Sdg	    msgConfirm("No chunk list found for %s!", disk->name);
8741549Srgrimes	    return DITEM_FAILURE;
8751549Srgrimes	}
8761549Srgrimes	if (RunningAsInit && root && (root->newfs || upgrade)) {
87712767Sdyson	    Mkdir("/mnt/dev");
8781827Sdg	    if (!Fake)
8791549Srgrimes		MakeDevDisk(disk, "/mnt/dev");
8801549Srgrimes	}
8811549Srgrimes	else if (!RunningAsInit && !Fake)
8821549Srgrimes	    MakeDevDisk(disk, "/dev");
883134892Sphk
8849507Sdg	for (c1 = disk->chunks->part; c1; c1 = c1->next) {
8859507Sdg	    if (c1->type == freebsd) {
886134892Sphk		for (c2 = c1->part; c2; c2 = c2->next) {
8871549Srgrimes		    if (c2->type == part && c2->subtype != FS_SWAP && c2->private_data) {
8881549Srgrimes			PartInfo *tmp = (PartInfo *)c2->private_data;
88951340Sdillon
8901549Srgrimes			/* Already did root */
891137726Sphk			if (c2 == rootdev)
892137726Sphk			    continue;
893136977Sphk
894136977Sphk			if (tmp->newfs)
895136977Sphk			    command_shell_add(tmp->mountpoint, "%s %s/dev/r%s", tmp->newfs_cmd, RunningAsInit ? "/mnt" : "", c2->name);
89651340Sdillon			else
89751340Sdillon			    command_shell_add(tmp->mountpoint, "fsck -y %s/dev/r%s", RunningAsInit ? "/mnt" : "", c2->name);
8981549Srgrimes			command_func_add(tmp->mountpoint, Mount, c2->name);
89942957Sdillon		    }
9005455Sdg		    else if (c2->type == part && c2->subtype == FS_SWAP) {
9011887Sdg			char fname[80];
9021549Srgrimes			int i;
9031549Srgrimes
9041549Srgrimes			if (c2 == swapdev)
9051887Sdg			    continue;
9061549Srgrimes			sprintf(fname, "%s/dev/%s", RunningAsInit ? "/mnt" : "", c2->name);
9071549Srgrimes			i = (Fake || swapon(fname));
90858345Sphk			if (!i)
909119092Sphk			    msgNotify("Added %s as an additional swap device", fname);
91084827Sjhb			else
91184827Sjhb			    msgConfirm("Unable to add %s as a swap device: %s", fname, strerror(errno));
91291406Sjhb		    }
91391406Sjhb		}
9146626Sdg	    }
915137726Sphk	    else if (c1->type == fat && c1->private_data && (root->newfs || upgrade)) {
9161549Srgrimes		char name[FILENAME_MAX];
9171549Srgrimes
91870374Sdillon		sprintf(name, "%s/%s", RunningAsInit ? "/mnt" : "", ((PartInfo *)c1->private_data)->mountpoint);
91970374Sdillon		Mkdir(name);
9201549Srgrimes	    }
9213612Sdg	}
9223612Sdg    }
9233612Sdg
9241549Srgrimes    if (RunningAsInit) {
925121205Sphk	msgNotify("Copying initial device files..");
926136927Sphk	/* Copy the boot floppy's dev files */
9273612Sdg	if ((root->newfs || upgrade) && vsystem("find -x /dev | cpio %s -pdum /mnt", cpioVerbosity())) {
928119092Sphk	    msgConfirm("Couldn't clone the /dev files!");
9291549Srgrimes	    return DITEM_FAILURE;
93058934Sphk	}
9311549Srgrimes    }
9321549Srgrimes
9331549Srgrimes    command_sort();
9341549Srgrimes    command_execute();
9351827Sdg    return DITEM_SUCCESS;
9361549Srgrimes}
9375455Sdg
9381549Srgrimes/* Initialize various user-settable values to their defaults */
9391549Srgrimesint
9401549SrgrimesinstallVarDefaults(dialogMenuItem *self)
9411549Srgrimes{
942137726Sphk    char *cp;
94342957Sdillon
9441549Srgrimes    /* Set default startup options */
945116512Salc    variable_set2(VAR_ROUTER,			"NO");
946100736Salc    variable_set2(VAR_RELNAME,			RELEASE_NAME);
94734206Sdyson    variable_set2(VAR_CPIO_VERBOSITY,		"high");
94834206Sdyson    variable_set2(VAR_TAPE_BLOCKSIZE,		DEFAULT_TAPE_BLOCKSIZE);
94934206Sdyson    variable_set2(VAR_INSTALL_ROOT,		"/");
95034206Sdyson    cp = getenv("EDITOR");
95134206Sdyson    if (!cp)
95234206Sdyson	cp = "/usr/bin/ee";
95347239Sdt    variable_set2(VAR_EDITOR,			cp);
95445347Sjulian    variable_set2(VAR_FTP_USER,			"ftp");
95545347Sjulian    variable_set2(VAR_BROWSER_PACKAGE,		PACKAGE_LYNX);
95645347Sjulian    variable_set2(VAR_BROWSER_BINARY,		"/usr/local/bin/lynx");
95734206Sdyson    variable_set2(VAR_FTP_STATE,		"passive");
95849945Salc    variable_set2(VAR_PKG_TMPDIR,		"/usr/tmp");
95960755Speter    variable_set2(VAR_APACHE_PKG,		PACKAGE_APACHE);
96034206Sdyson    variable_set2(VAR_SAMBA_PKG,		PACKAGE_SAMBA);
96145347Sjulian    variable_set2(VAR_GATED_PKG,		PACKAGE_GATED);
96245347Sjulian    variable_set2(VAR_PCNFSD_PKG,		PACKAGE_PCNFSD);
96345347Sjulian    variable_set2(VAR_MEDIA_TIMEOUT,		itoa(MEDIA_TIMEOUT));
96445347Sjulian    if (getpid() != 1)
96545347Sjulian	variable_set2(SYSTEM_STATE,		"update");
96645347Sjulian    else
96745347Sjulian	variable_set2(SYSTEM_STATE,		"init");
96845347Sjulian    return DITEM_SUCCESS;
96945347Sjulian}
97045347Sjulian
97147239Sdt/* Load the environment up from various system configuration files */
97247239Sdtvoid
97346349SalcinstallEnvironment(void)
97446349Salc{
97534206Sdyson    if (file_readable("/etc/sysconfig"))
97634206Sdyson	configEnvironmentSysconfig("/etc/sysconfig");
9771549Srgrimes    if (file_readable("/etc/resolv.conf"))
9781827Sdg	configEnvironmentResolv("/etc/resolv.conf");
9791549Srgrimes}
9801827Sdg
9811827Sdg/* Copy the boot floppy contents into /stand */
9821827SdgBoolean
98358634ScharniercopySelf(void)
9841827Sdg{
9851549Srgrimes    int i;
9861827Sdg
9871549Srgrimes    msgWeHaveOutput("Copying the boot floppy to /stand on root filesystem");
9881827Sdg    i = vsystem("find -x /stand | cpio %s -pdum /mnt", cpioVerbosity());
9891827Sdg    if (i) {
9901549Srgrimes	msgConfirm("Copy returned error status of %d!", i);
9911549Srgrimes	return FALSE;
99234206Sdyson    }
99334206Sdyson
99433109Sdyson    /* Copy the /etc files into their rightful place */
99534206Sdyson    if (vsystem("cd /mnt/stand; find etc | cpio %s -pdum /mnt", cpioVerbosity())) {
99638799Sdfr	msgConfirm("Couldn't copy up the /etc files!");
9971549Srgrimes	return TRUE;
99875692Salfred    }
9991549Srgrimes    return TRUE;
10001549Srgrimes}
10011549Srgrimes
1002100736Salcstatic void
1003116512Salccreate_termcap(void)
10041549Srgrimes{
10059507Sdg    FILE *fp;
10061549Srgrimes
10074207Sdg    const char *caps[] = {
10081549Srgrimes	termcap_vt100, termcap_cons25, termcap_cons25_m, termcap_cons25r,
10091549Srgrimes	termcap_cons25r_m, termcap_cons25l1, termcap_cons25l1_m, NULL,
101033847Smsmith    };
101133847Smsmith    const char **cp;
101233847Smsmith
101333847Smsmith    if (!file_readable(TERMCAP_FILE)) {
101433847Smsmith	Mkdir("/usr/share/misc");
101533847Smsmith	fp = fopen(TERMCAP_FILE, "w");
101633847Smsmith	if (!fp) {
101733847Smsmith	    msgConfirm("Unable to initialize termcap file. Some screen-oriented\nutilities may not work.");
101843129Sdillon	    return;
101910556Sdyson	}
102010556Sdyson	cp = caps;
102110556Sdyson	while (*cp)
102210556Sdyson	    fprintf(fp, "%s\n", *(cp++));
102310556Sdyson	fclose(fp);
102410556Sdyson    }
102510556Sdyson}
102610556Sdyson
102710556Sdyson#ifdef SAVE_USERCONFIG
102862976Smckusickstatic void
102934403Smsmithsave_userconfig_to_kernel(char *kern)
103018973Sdyson{
103144321Salc    struct kernel *core, *boot;
103244321Salc    struct list *c_isa, *b_isa, *c_dev, *b_dev;
103344321Salc    int i, d;
103444321Salc
103544321Salc    if ((core = uc_open("-incore")) == NULL) {
103644321Salc	msgDebug("save_userconf: Can't read in-core information for kernel.\n");
103744321Salc	return;
103844321Salc    }
103944321Salc
104044321Salc    if ((boot = uc_open(kern)) == NULL) {
104144321Salc	msgDebug("save_userconf: Can't read device information for kernel image %s\n", kern);
104244321Salc	return;
104344321Salc    }
104444321Salc
104544321Salc    msgNotify("Saving any boot -c changes to new kernel...");
104644321Salc    c_isa = uc_getdev(core, "-isa");
104744321Salc    b_isa = uc_getdev(boot, "-isa");
104844321Salc    if (isDebug())
104910556Sdyson	msgDebug("save_userconf: got %d ISA device entries from core, %d from boot.\n", c_isa->ac, b_isa->ac);
1050121455Salc    for (d = 0; d < c_isa->ac; d++) {
105162976Smckusick	if (isDebug())
105262976Smckusick	    msgDebug("save_userconf: ISA device loop, c_isa->av[%d] = %s\n", d, c_isa->av[d]);
105362976Smckusick	if (strcmp(c_isa->av[d], "npx0")) { /* special case npx0, which mucks with its id_irq member */
105434403Smsmith	    c_dev = uc_getdev(core, c_isa->av[d]);
105576827Salfred	    b_dev = uc_getdev(boot, b_isa->av[d]);
105676827Salfred	    if (!c_dev || !b_dev) {
105762976Smckusick		msgDebug("save_userconf: c_dev: %x b_dev: %x\n", c_dev, b_dev);
1058121455Salc		continue;
105910556Sdyson	    }
106010556Sdyson	    if (isDebug())
106133847Smsmith		msgDebug("save_userconf: ISA device %s: %d config parameters (core), %d (boot)\n",
10621549Srgrimes			 c_isa->av[d], c_dev->ac, b_dev->ac);
106333847Smsmith	    for (i = 0; i < c_dev->ac; i++) {
106445057Seivind		if (isDebug())
106570374Sdillon		    msgDebug("save_userconf: c_dev->av[%d] = %s, b_dev->av[%d] = %s\n", i, c_dev->av[i], i, b_dev->av[i]);
106670374Sdillon		if (strcmp(c_dev->av[i], b_dev->av[i])) {
106770374Sdillon		    if (isDebug())
106870374Sdillon			msgDebug("save_userconf: %s (boot) -> %s (core)\n",
106970374Sdillon				 c_dev->av[i], b_dev->av[i]);
10701549Srgrimes		    isa_setdev(boot, c_dev);
107133847Smsmith		}
107234206Sdyson	    }
107333847Smsmith	}
10741549Srgrimes	else {
107533847Smsmith	    if (isDebug())
107634206Sdyson		msgDebug("skipping npx0\n");
10775455Sdg	}
10781549Srgrimes    }
10797695Sdg    if (isDebug())
108033847Smsmith	msgDebug("Closing kernels\n");
108133847Smsmith    uc_close(core, 0);
10821549Srgrimes    uc_close(boot, 1);
10837695Sdg}
108412767Sdyson#endif
10857695Sdg