18097Sjkh/*
28097Sjkh * The new sysinstall program.
38097Sjkh *
48097Sjkh * This is probably the last attempt in the `sysinstall' line, the next
58097Sjkh * generation being slated for what's essentially a complete rewrite.
68097Sjkh *
750479Speter * $FreeBSD$
88097Sjkh *
98097Sjkh * Copyright (c) 1995
108097Sjkh *	Jordan Hubbard.  All rights reserved.
118097Sjkh *
128097Sjkh * Redistribution and use in source and binary forms, with or without
138097Sjkh * modification, are permitted provided that the following conditions
148097Sjkh * are met:
158097Sjkh * 1. Redistributions of source code must retain the above copyright
168881Srgrimes *    notice, this list of conditions and the following disclaimer,
178881Srgrimes *    verbatim and that no modifications are made prior to this
188097Sjkh *    point in the file.
198097Sjkh * 2. Redistributions in binary form must reproduce the above copyright
208097Sjkh *    notice, this list of conditions and the following disclaimer in the
218097Sjkh *    documentation and/or other materials provided with the distribution.
228097Sjkh *
238097Sjkh * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
248097Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
258097Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
268097Sjkh * ARE DISCLAIMED.  IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
278097Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
288097Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
298097Sjkh * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
308097Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
318097Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
328097Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
338097Sjkh * SUCH DAMAGE.
348097Sjkh *
358097Sjkh */
368097Sjkh
378097Sjkh#include "sysinstall.h"
3812661Speter#include <sys/signal.h>
3918501Spst#include <sys/fcntl.h>
40174954Skensmith#include <sys/time.h>
41174954Skensmith#include <sys/resource.h>
428097Sjkh
4367862Seivindconst char *StartName;		/* Initial contents of argv[0] */
44178946Sobrienconst char *ProgName = "sysinstall";
4567862Seivind
4612661Speterstatic void
4712661Speterscreech(int sig)
4812661Speter{
4922950Sjkh    msgDebug("\007Signal %d caught!  That's bad!\n", sig);
5025052Sjkh    longjmp(BailOut, sig);
5112661Speter}
5212661Speter
538097Sjkhint
548097Sjkhmain(int argc, char **argv)
558097Sjkh{
5625052Sjkh    int choice, scroll, curr, max, status;
57160380Ssimon    char titlestr[80], *arch, *osrel, *ostype;
58174954Skensmith    struct rlimit rlim;
59211417Sbrucec    char *arg;
60211417Sbrucec    int i;
61211417Sbrucec    int optionArgs = 0;
62211417Sbrucec
6367862Seivind    /* Record name to be able to restart */
6467862Seivind    StartName = argv[0];
658097Sjkh
66211417Sbrucec    Restarting = FALSE;
67211417Sbrucec    RunningAsInit = FALSE;
68211417Sbrucec    Fake = FALSE;
69211417Sbrucec
70211417Sbrucec    for (i = 1; i < argc; i++) {
71211417Sbrucec	arg = argv[i];
72211417Sbrucec
73211417Sbrucec	if (arg[0] != '-')
74211417Sbrucec		break;
75211417Sbrucec
76211417Sbrucec	optionArgs++;
77211417Sbrucec
78211417Sbrucec	if (!strcmp(arg, "-fake")) {
79211417Sbrucec		variable_set2(VAR_DEBUG, "YES", 0);
80211417Sbrucec		Fake = TRUE;
81211417Sbrucec	} else if (!strcmp(arg, "-restart")) {
82211417Sbrucec		Restarting = TRUE;
83211417Sbrucec	} else if (!strcmp(arg, "-fakeInit")) {
84211417Sbrucec		RunningAsInit = TRUE;
85211417Sbrucec	}
86211417Sbrucec
87211417Sbrucec	arg = argv[optionArgs+1];
88211417Sbrucec    }
89211417Sbrucec
90211417Sbrucec    if (getpid() == 1)
91211417Sbrucec	    RunningAsInit = TRUE;
92211417Sbrucec
9315091Sjkh    /* Catch fatal signals and complain about them if running as init */
94211417Sbrucec    if (RunningAsInit) {
9512661Speter	signal(SIGBUS, screech);
9612661Speter	signal(SIGSEGV, screech);
9712661Speter    }
9855390Sjkh    signal(SIGPIPE, SIG_IGN);
9915091Sjkh
10015091Sjkh    /* We don't work too well when running as non-root anymore */
1018262Sjkh    if (geteuid() != 0) {
10215091Sjkh	fprintf(stderr, "Error: This utility should only be run as root.\n");
10315091Sjkh	return 1;
1048262Sjkh    }
10515091Sjkh
106174963Skensmith    /*
107174963Skensmith     * Given what it does sysinstall (and stuff sysinstall runs like
108174963Skensmith     * pkg_add) shouldn't be subject to process limits.  Better to just
109174963Skensmith     * let them have what they think they need than have them blow
110174963Skensmith     * their brains out during an install (in sometimes strange and
111174963Skensmith     * mysterious ways).
112174963Skensmith     */
113174963Skensmith
114174954Skensmith    rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
115174954Skensmith    if (setrlimit(RLIMIT_DATA, &rlim) != 0)
116174963Skensmith	fprintf(stderr, "Warning: setrlimit() of datasize failed.\n");
117174954Skensmith    if (setrlimit(RLIMIT_STACK, &rlim) != 0)
118174963Skensmith	fprintf(stderr, "Warning: setrlimit() of stacksize failed.\n");
119174954Skensmith
12061277Snyan#ifdef PC98
12161277Snyan    {
12261277Snyan	/* XXX */
12361277Snyan	char *p = getenv("TERM");
12461277Snyan	if (p && strcmp(p, "cons25") == 0)
125171195Sscf	    setenv("TERM", "cons25w", 1);
12661277Snyan    }
12761277Snyan#endif
12861277Snyan
1298097Sjkh    /* Set up whatever things need setting up */
1308097Sjkh    systemInitialize(argc, argv);
1318097Sjkh
13215439Sjkh    /* Set default flag and variable values */
13315439Sjkh    installVarDefaults(NULL);
13434466Sjkh    /* only when multi-user is it reasonable to do this here */
13534466Sjkh    if (!RunningAsInit)
13634466Sjkh	installEnvironment();
13715439Sjkh
138211417Sbrucec    if (Fake)
13915439Sjkh	msgConfirm("I'll be just faking it from here on out, OK?");
14015439Sjkh
1419202Srgrimes    /* Try to preserve our scroll-back buffer */
14220354Sjkh    if (OnVTY) {
1439202Srgrimes	for (curr = 0; curr < 25; curr++)
1449202Srgrimes	    putchar('\n');
14520354Sjkh    }
14622102Sjkh    /* Move stderr aside */
14722102Sjkh    if (DebugFD)
14822102Sjkh	dup2(DebugFD, 2);
1499202Srgrimes
15083880Smurray    /* Initialize driver modules, if we haven't already done so (ie,
15183880Smurray       the user hit Ctrl-C -> Restart. */
15283880Smurray    if (!pvariable_get("modulesInitialize")) {
15383880Smurray	moduleInitialize();
15483880Smurray	pvariable_set("modulesInitialize=1");
15583880Smurray    }
15668048Shosokawa
1578556Sjkh    /* Probe for all relevant devices on the system */
1588556Sjkh    deviceGetAll();
1598556Sjkh
160109333Sjhb    /* Prompt for the driver floppy if appropriate. */
161109333Sjhb    if (!pvariable_get("driverFloppyCheck")) {
162109333Sjhb	driverFloppyCheck();
163109333Sjhb	pvariable_set("driverFloppyCheck=1");
164109333Sjhb    }
165109333Sjhb
16616766Sjkh    /* First, see if we have any arguments to process (and argv[0] counts if it's not "sysinstall") */
16716766Sjkh    if (!RunningAsInit) {
168242902Sdteske	int start_arg;
169242902Sdteske
170242902Sdteske	if (!strstr(argv[0], "sysinstall"))
171242902Sdteske		start_arg = 0;
172242902Sdteske	else
173242902Sdteske		start_arg = optionArgs + 1;
174242902Sdteske
175242902Sdteske	for (i = start_arg; i < argc; i++) {
17615788Sjkh	    if (DITEM_STATUS(dispatchCommand(argv[i])) != DITEM_SUCCESS)
17715788Sjkh		systemShutdown(1);
17816766Sjkh	}
179211417Sbrucec
180211417Sbrucec	/* If we were given commands to process on the command line, just exit
181211417Sbrucec	 * now */
182242902Sdteske	if (argc > start_arg)
18316766Sjkh	    systemShutdown(0);
18415788Sjkh    }
18529517Sjkh    else
18629517Sjkh	dispatch_load_file_int(TRUE);
18718501Spst
18825052Sjkh    status = setjmp(BailOut);
18925052Sjkh    if (status) {
19025052Sjkh	msgConfirm("A signal %d was caught - I'm saving what I can and shutting\n"
19174999Sjkh		   "down.  If you can reproduce the problem, please turn Debug on\n"
19274999Sjkh		   "in the Options menu for the extra information it provides\n"
19374999Sjkh		   "in debugging problems like this.", status);
19425052Sjkh	systemShutdown(status);
19525052Sjkh    }
19625052Sjkh
197156118Sjhb    /* Get user's country and keymap */
198156118Sjhb    if (RunningAsInit)
199156118Sjhb	configCountry(NULL);
200156118Sjhb
201160380Ssimon    /* Add FreeBSD version info to the menu title */
202160380Ssimon    arch = getsysctlbyname("hw.machine_arch");
203160380Ssimon    osrel = getsysctlbyname("kern.osrelease");
204160380Ssimon    ostype = getsysctlbyname("kern.ostype");
205160380Ssimon    snprintf(titlestr, sizeof(titlestr), "%s/%s %s - %s", ostype, arch,
206160380Ssimon	     osrel, MenuInitial.title);
207160380Ssimon    free(arch);
208160380Ssimon    free(osrel);
209160380Ssimon    free(ostype);
210160380Ssimon    MenuInitial.title = titlestr;
211160380Ssimon
2128097Sjkh    /* Begin user dialog at outer menu */
21318144Sjkh    dialog_clear();
2148278Sjkh    while (1) {
2158278Sjkh	choice = scroll = curr = max = 0;
21616887Sjkh	dmenuOpen(&MenuInitial, &choice, &scroll, &curr, &max, TRUE);
217211417Sbrucec	if (!RunningAsInit
218186075Skensmith#if defined(__sparc64__)
21970005Sjkh	    || !msgNoYes("Are you sure you wish to exit?  The system will halt.")
22042386Sjkh#else
221186131Skensmith	    || !msgNoYes("Are you sure you wish to exit?  The system will reboot.")
22242386Sjkh#endif
22342386Sjkh	    )
2248278Sjkh	    break;
2258278Sjkh    }
2268810Sjkh
2278097Sjkh    /* Say goodnight, Gracie */
22815788Sjkh    systemShutdown(0);
2298097Sjkh
23015788Sjkh    return 0; /* We should never get here */
2318097Sjkh}
232