system.c revision 15393
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.52 1996/04/25 17:31:27 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    status = system(command);
113    DialogActive = TRUE;
114    return status;
115}
116
117/* Display a help file in a filebox */
118int
119systemDisplayHelp(char *file)
120{
121    char *fname = NULL;
122    char buf[FILENAME_MAX];
123    WINDOW *old = savescr();
124    int ret = 0;
125
126    fname = systemHelpFile(file, buf);
127    if (!fname) {
128	snprintf(buf, FILENAME_MAX, "The %s file is not provided on this particular floppy image.", file);
129	use_helpfile(NULL);
130	use_helpline(NULL);
131	dialog_mesgbox("Sorry!", buf, -1, -1);
132	ret = 1;
133    }
134    else {
135	use_helpfile(NULL);
136	use_helpline(NULL);
137	dialog_textbox(file, fname, LINES, COLS);
138    }
139    restorescr(old);
140    return ret;
141}
142
143char *
144systemHelpFile(char *file, char *buf)
145{
146    if (!file)
147	return NULL;
148
149    snprintf(buf, FILENAME_MAX, "/stand/help/%s.hlp", file);
150    if (file_readable(buf))
151	return buf;
152    return NULL;
153}
154
155void
156systemChangeTerminal(char *color, const u_char c_term[],
157		     char *mono, const u_char m_term[])
158{
159    extern void init_acs(void);
160
161    if (OnVTY) {
162	if (ColorDisplay) {
163	    setenv("TERM", color, 1);
164	    setenv("TERMCAP", c_term, 1);
165	    reset_shell_mode();
166	    setterm(color);
167	    init_acs();
168	    cbreak(); noecho();
169	}
170	else {
171	    setenv("TERM", mono, 1);
172	    setenv("TERMCAP", m_term, 1);
173	    reset_shell_mode();
174	    setterm(mono);
175	    init_acs();
176	    cbreak(); noecho();
177	}
178    }
179    clear();
180    refresh();
181    dialog_clear();
182}
183
184int
185vsystem(char *fmt, ...)
186{
187    va_list args;
188    int pstat;
189    pid_t pid;
190    int omask;
191    sig_t intsave, quitsave;
192    char *cmd;
193    int i;
194
195    cmd = (char *)malloc(FILENAME_MAX);
196    cmd[0] = '\0';
197    va_start(args, fmt);
198    vsnprintf(cmd, FILENAME_MAX, fmt, args);
199    va_end(args);
200
201    omask = sigblock(sigmask(SIGCHLD));
202    if (isDebug())
203	msgDebug("Executing command `%s'\n", cmd);
204    pid = fork();
205    if (pid == -1) {
206	(void)sigsetmask(omask);
207	i = 127;
208    }
209    else if (!pid) {	/* Junior */
210	(void)sigsetmask(omask);
211	if (DebugFD != -1) {
212	    if (OnVTY && isDebug() && RunningAsInit)
213		msgInfo("Command output is on VTY2 - type ALT-F2 to see it");
214	    dup2(DebugFD, 0);
215	    dup2(DebugFD, 1);
216	    dup2(DebugFD, 2);
217	}
218	execl("/stand/sh", "sh", "-c", cmd, (char *)NULL);
219	exit(1);
220    }
221    else {
222	intsave = signal(SIGINT, SIG_IGN);
223	quitsave = signal(SIGQUIT, SIG_IGN);
224	pid = waitpid(pid, &pstat, 0);
225	(void)sigsetmask(omask);
226	(void)signal(SIGINT, intsave);
227	(void)signal(SIGQUIT, quitsave);
228	i = (pid == -1) ? -1 : WEXITSTATUS(pstat);
229	if (isDebug())
230	    msgDebug("Command `%s' returns status of %d\n", cmd, i);
231        free(cmd);
232    }
233    return i;
234}
235
236void
237systemCreateHoloshell(void)
238{
239    if (OnVTY && RunningAsInit) {
240	if (!fork()) {
241	    int i, fd;
242	    struct termios foo;
243	    extern int login_tty(int);
244
245	    for (i = 0; i < 64; i++)
246		close(i);
247	    DebugFD = fd = open("/dev/ttyv3", O_RDWR);
248	    ioctl(0, TIOCSCTTY, &fd);
249	    dup2(0, 1);
250	    dup2(0, 2);
251	    if (login_tty(fd) == -1)
252		msgDebug("Doctor: I can't set the controlling terminal.\n");
253	    signal(SIGTTOU, SIG_IGN);
254	    if (tcgetattr(fd, &foo) != -1) {
255		foo.c_cc[VERASE] = '\010';
256		if (tcsetattr(fd, TCSANOW, &foo) == -1)
257		    msgDebug("Doctor: I'm unable to set the erase character.\n");
258	    }
259	    else
260		msgDebug("Doctor: I'm unable to get the terminal attributes!\n");
261	    execlp("sh", "-sh", 0);
262	    msgDebug("Was unable to execute sh for Holographic shell!\n");
263	    exit(1);
264	}
265	else
266	    msgNotify("Starting an emergency holographic shell on VTY4");
267    }
268}
269