system.c revision 15439
1/*
2 * The new sysinstall program.
3 *
4 * This is probably the last program in the `sysinstall' line - the next
5 * generation being essentially a complete rewrite.
6 *
7 * $Id: system.c,v 1.55 1996/04/28 03:27:26 jkh Exp $
8 *
9 * Jordan Hubbard
10 *
11 * My contributions are in the public domain.
12 *
13 * Parts of this file are also blatently stolen from Poul-Henning Kamp's
14 * previous version of sysinstall, and as such fall under his "BEERWARE license"
15 * so buy him a beer if you like it!  Buy him a beer for me, too!
16 * Heck, get him completely drunk and send me pictures! :-)
17 */
18
19#include "sysinstall.h"
20#include <signal.h>
21#include <sys/reboot.h>
22#include <machine/console.h>
23#include <sys/fcntl.h>
24#include <sys/ioctl.h>
25#include <sys/wait.h>
26
27/*
28 * Handle interrupt signals - this probably won't work in all cases
29 * due to our having bogotified the internal state of dialog or curses,
30 * but we'll give it a try.
31 */
32static void
33handle_intr(int sig)
34{
35    if (!msgYesNo("Are you sure you want to abort the installation?"))
36	systemShutdown();
37}
38
39/* Initialize system defaults */
40void
41systemInitialize(int argc, char **argv)
42{
43    int i;
44
45    signal(SIGINT, SIG_IGN);
46    globalsInit();
47
48    /* Are we running as init? */
49    if (getpid() == 1) {
50	setsid();
51	close(0); open("/dev/ttyv0", O_RDWR);
52	close(1); dup(0);
53	close(2); dup(0);
54	printf("%s running as init\n", argv[0]);
55	RunningAsInit = 1;
56	i = ioctl(0, TIOCSCTTY, (char *)NULL);
57	setlogin("root");
58	setenv("PATH", "/stand:/bin:/sbin:/usr/sbin:/usr/bin:/mnt/bin:/mnt/sbin:/mnt/usr/sbin:/mnt/usr/bin:/usr/X11R6/bin", 1);
59	setbuf(stdin, 0);
60	setbuf(stderr, 0);
61    }
62
63    if (set_termcap() == -1) {
64	printf("Can't find terminal entry\n");
65	exit(-1);
66    }
67
68    /* XXX - libdialog has particularly bad return value checking */
69    init_dialog();
70
71    /* If we haven't crashed I guess dialog is running ! */
72    DialogActive = TRUE;
73
74    /* Make sure HOME is set for those utilities that need it */
75    if (!getenv("HOME"))
76	setenv("HOME", "/", 1);
77    signal(SIGINT, handle_intr);
78}
79
80/* Close down and prepare to exit */
81void
82systemShutdown(void)
83{
84    if (DialogActive) {
85	end_dialog();
86	DialogActive = FALSE;
87    }
88    /* REALLY exit! */
89    if (RunningAsInit) {
90	/* Put the console back */
91	ioctl(0, VT_ACTIVATE, 2);
92	reboot(0);
93    }
94    else
95	exit(1);
96}
97
98/* Run some general command */
99int
100systemExecute(char *command)
101{
102    int status;
103    struct termios foo;
104
105    dialog_update();
106    end_dialog();
107    DialogActive = FALSE;
108    if (tcgetattr(0, &foo) != -1) {
109	foo.c_cc[VERASE] = '\010';
110	tcsetattr(0, TCSANOW, &foo);
111    }
112    if (!Fake)
113	status = system(command);
114    else {
115	status = 0;
116	msgDebug("systemExecute:  Faked execution of `%s'\n", command);
117    }
118    DialogActive = TRUE;
119    return status;
120}
121
122/* Display a help file in a filebox */
123int
124systemDisplayHelp(char *file)
125{
126    char *fname = NULL;
127    char buf[FILENAME_MAX];
128    WINDOW *old = savescr();
129    int ret = 0;
130
131    fname = systemHelpFile(file, buf);
132    if (!fname) {
133	snprintf(buf, FILENAME_MAX, "The %s file is not provided on this particular floppy image.", file);
134	use_helpfile(NULL);
135	use_helpline(NULL);
136	dialog_mesgbox("Sorry!", buf, -1, -1);
137	ret = 1;
138    }
139    else {
140	use_helpfile(NULL);
141	use_helpline(NULL);
142	dialog_textbox(file, fname, LINES, COLS);
143    }
144    restorescr(old);
145    return ret;
146}
147
148char *
149systemHelpFile(char *file, char *buf)
150{
151    if (!file)
152	return NULL;
153
154    snprintf(buf, FILENAME_MAX, "/stand/help/%s.hlp", file);
155    if (file_readable(buf))
156	return buf;
157    return NULL;
158}
159
160void
161systemChangeTerminal(char *color, const u_char c_term[],
162		     char *mono, const u_char m_term[])
163{
164    extern void init_acs(void);
165
166    if (OnVTY) {
167	if (ColorDisplay) {
168	    setenv("TERM", color, 1);
169	    setenv("TERMCAP", c_term, 1);
170	    reset_shell_mode();
171	    setterm(color);
172	    init_acs();
173	    cbreak(); noecho();
174	}
175	else {
176	    setenv("TERM", mono, 1);
177	    setenv("TERMCAP", m_term, 1);
178	    reset_shell_mode();
179	    setterm(mono);
180	    init_acs();
181	    cbreak(); noecho();
182	}
183    }
184    clear();
185    refresh();
186    dialog_clear();
187}
188
189int
190vsystem(char *fmt, ...)
191{
192    va_list args;
193    int pstat;
194    pid_t pid;
195    int omask;
196    sig_t intsave, quitsave;
197    char *cmd;
198    int i;
199
200    cmd = (char *)alloca(FILENAME_MAX);
201    cmd[0] = '\0';
202    va_start(args, fmt);
203    vsnprintf(cmd, FILENAME_MAX, fmt, args);
204    va_end(args);
205
206    omask = sigblock(sigmask(SIGCHLD));
207    if (Fake) {
208	msgDebug("vsystem:  Faked execution of `%s'\n", cmd);
209	return 0;
210    }
211    if (isDebug())
212	msgDebug("Executing command `%s'\n", cmd);
213    pid = fork();
214    if (pid == -1) {
215	(void)sigsetmask(omask);
216	i = 127;
217    }
218    else if (!pid) {	/* Junior */
219	(void)sigsetmask(omask);
220	if (DebugFD != -1) {
221	    if (OnVTY && isDebug() && RunningAsInit)
222		msgInfo("Command output is on VTY2 - type ALT-F2 to see it");
223	    dup2(DebugFD, 0);
224	    dup2(DebugFD, 1);
225	    dup2(DebugFD, 2);
226	}
227	else {
228	    close(1); open("/dev/null", O_WRONLY);
229	    dup2(1, 2);
230	}
231	if (!RunningAsInit)
232	    execl("/bin/sh", "/bin/sh", "-c", cmd, (char *)NULL);
233	else
234	    execl("/stand/sh", "/stand/sh", "-c", cmd, (char *)NULL);
235	exit(1);
236    }
237    else {
238	intsave = signal(SIGINT, SIG_IGN);
239	quitsave = signal(SIGQUIT, SIG_IGN);
240	pid = waitpid(pid, &pstat, 0);
241	(void)sigsetmask(omask);
242	(void)signal(SIGINT, intsave);
243	(void)signal(SIGQUIT, quitsave);
244	i = (pid == -1) ? -1 : WEXITSTATUS(pstat);
245	if (isDebug())
246	    msgDebug("Command `%s' returns status of %d\n", cmd, i);
247    }
248    return i;
249}
250
251void
252systemCreateHoloshell(void)
253{
254    if (OnVTY && RunningAsInit) {
255	if (!fork()) {
256	    int i, fd;
257	    struct termios foo;
258	    extern int login_tty(int);
259
260	    for (i = 0; i < 64; i++)
261		close(i);
262	    DebugFD = fd = open("/dev/ttyv3", O_RDWR);
263	    ioctl(0, TIOCSCTTY, &fd);
264	    dup2(0, 1);
265	    dup2(0, 2);
266	    if (login_tty(fd) == -1)
267		msgDebug("Doctor: I can't set the controlling terminal.\n");
268	    signal(SIGTTOU, SIG_IGN);
269	    if (tcgetattr(fd, &foo) != -1) {
270		foo.c_cc[VERASE] = '\010';
271		if (tcsetattr(fd, TCSANOW, &foo) == -1)
272		    msgDebug("Doctor: I'm unable to set the erase character.\n");
273	    }
274	    else
275		msgDebug("Doctor: I'm unable to get the terminal attributes!\n");
276	    execlp("sh", "-sh", 0);
277	    msgDebug("Was unable to execute sh for Holographic shell!\n");
278	    exit(1);
279	}
280	else
281	    msgNotify("Starting an emergency holographic shell on VTY4");
282    }
283}
284