system.c revision 8556
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.10 1995/05/11 09:01:35 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"
15 * license, so buy him a beer if you like it!  Buy him a beer for me, too!
16 */
17
18#include "sysinstall.h"
19#include <signal.h>
20#include <sys/reboot.h>
21#include <machine/console.h>
22#include <sys/fcntl.h>
23#include <sys/ioctl.h>
24#include <sys/wait.h>
25
26/*
27 * Handle interrupt signals - this probably won't work in all cases
28 * due to our having bogotified the internal state of dialog or curses,
29 * but we'll give it a try.
30 */
31static void
32handle_intr(int sig)
33{
34    if (!msgYesNo("Are you sure you want to abort the installation?"))
35	systemShutdown();
36}
37
38/* Welcome the user to the system */
39void
40systemWelcome(void)
41{
42    printf("Installation system initializing..\n");
43}
44
45/* Initialize system defaults */
46void
47systemInitialize(int argc, char **argv)
48{
49    signal(SIGINT, SIG_IGN);
50    globalsInit();
51
52    /* Are we running as init? */
53    if (getpid() == 1) {
54	setsid();
55	if (argc > 1 && strchr(argv[1],'C')) {
56	    /* Kernel told us that we are on a CDROM root */
57	    close(0); open("/bootcd/dev/console", O_RDWR);
58	    close(1); dup(0);
59	    close(2); dup(0);
60	    CpioFD = open("/floppies/cpio.flp", O_RDONLY);
61	    OnCDROM = TRUE;
62	    chroot("/bootcd");
63	} else {
64	    close(0); open("/dev/console", O_RDWR);
65	    close(1); dup(0);
66	    close(2); dup(0);
67	}
68	printf("%s running as init\n", argv[0]);
69
70	ioctl(0, TIOCSCTTY, (char *)NULL);
71	setlogin("root");
72	setbuf(stdin, 0);
73	setbuf(stdout, 0);
74	setbuf(stderr, 0);
75    }
76
77    if (set_termcap() == -1) {
78	printf("Can't find terminal entry\n");
79	exit(-1);
80    }
81
82    /* XXX - libdialog has particularly bad return value checking */
83    init_dialog();
84    /* If we haven't crashed I guess dialog is running ! */
85    DialogActive = TRUE;
86
87    signal(SIGINT, handle_intr);
88}
89
90/* Close down and prepare to exit */
91void
92systemShutdown(void)
93{
94    if (DialogActive) {
95	end_dialog();
96	DialogActive = FALSE;
97    }
98    /* REALLY exit! */
99    if (getpid() == 1)
100	reboot(RB_HALT);
101    else
102	exit(1);
103}
104
105/* Run some general command */
106int
107systemExecute(char *command)
108{
109    int status;
110
111    dialog_clear();
112    dialog_update();
113    end_dialog();
114    DialogActive = FALSE;
115    status = system(command);
116    DialogActive = TRUE;
117    dialog_clear();
118    dialog_update();
119    return status;
120}
121
122/* Find and execute a shell */
123int
124systemShellEscape(void)
125{
126    char *sh = NULL;
127
128    if (file_executable("/bin/sh"))
129	sh = "/bin/sh";
130    else if (file_executable("/stand/sh"))
131	sh = "/stand/sh";
132    else {
133	msgWarn("No shell available, sorry!");
134	return 1;
135    }
136    setenv("PATH", "/stand", 1);
137    setenv("PS1", "freebsd% ", 1);
138    dialog_clear();
139    dialog_update();
140    move(0, 0);
141    standout();
142    addstr("Type `exit' to leave this shell and continue installation");
143    standend();
144    refresh();
145    end_dialog();
146    DialogActive = FALSE;
147    if (fork() == 0)
148	execlp(sh, "-sh", 0);
149    else
150	wait(NULL);
151    dialog_clear();
152    DialogActive = TRUE;
153    return 0;
154}
155
156/* Display a file in a filebox */
157int
158systemDisplayFile(char *file)
159{
160    char *fname = NULL;
161    char buf[FILENAME_MAX];
162    WINDOW *w;
163
164    fname = systemHelpFile(file, buf);
165    if (!fname) {
166	snprintf(buf, FILENAME_MAX, "The %s file is not provided on this particular floppy image.", file);
167	use_helpfile(NULL);
168	use_helpline(NULL);
169	w = dupwin(newscr);
170	dialog_mesgbox("Sorry!", buf, -1, -1);
171	touchwin(w);
172	wrefresh(w);
173	delwin(w);
174	return 1;
175    }
176    else {
177	use_helpfile(NULL);
178	use_helpline(NULL);
179	w = dupwin(newscr);
180	dialog_textbox(file, fname, LINES, COLS);
181	touchwin(w);
182	wrefresh(w);
183	delwin(w);
184    }
185    return 0;
186}
187
188char *
189systemHelpFile(char *file, char *buf)
190{
191    char *cp, *fname = NULL;
192
193    if (!file)
194	return NULL;
195
196    if ((cp = getenv("LANG")) != NULL) {
197	snprintf(buf, FILENAME_MAX, "help/%s/%s", cp, file);
198	if (file_readable(buf))
199	    fname = buf;
200	else {
201	    snprintf(buf, FILENAME_MAX, "/stand/help/%s/%s", cp, file);
202	    if (file_readable(buf))
203		fname = buf;
204	}
205    }
206    if (!fname) {
207	snprintf(buf, FILENAME_MAX, "help/en_US.ISO8859-1/%s", file);
208	if (file_readable(buf))
209	    fname = buf;
210	else {
211	    snprintf(buf, FILENAME_MAX, "/stand/help/en_US.ISO8859-1/%s",
212		     file);
213	    if (file_readable(buf))
214		fname = buf;
215	}
216    }
217    return fname;
218}
219
220void
221systemChangeFont(const u_char font[])
222{
223    if (OnVTY) {
224	if (ioctl(0, PIO_FONT8x14, font) < 0)
225	    msgConfirm("Sorry!  Unable to load font for %s", getenv("LANG"));
226    }
227}
228
229void
230systemChangeLang(char *lang)
231{
232    variable_set2("LANG", lang);
233}
234
235void
236systemChangeTerminal(char *color, const u_char c_term[],
237		     char *mono, const u_char m_term[])
238{
239    if (!OnSerial) {
240	if (ColorDisplay) {
241	    setenv("TERM", color, 1);
242	    setenv("TERMCAP", c_term, 1);
243	/*    setterm(color); */
244	}
245	else {
246	    setenv("TERM", mono, 1);
247	    setenv("TERMCAP", m_term, 1);
248	/*    setterm(mono); */
249	}
250    }
251}
252
253void
254systemChangeScreenmap(const u_char newmap[])
255{
256    if (OnVTY) {
257	if (ioctl(0, PIO_SCRNMAP, newmap) < 0)
258	    msgConfirm("Sorry!  Unable to load the screenmap for %s",
259		       getenv("LANG"));
260    }
261}
262
263/* Execute a system command, with varargs */
264int
265vsystem(char *fmt, ...)
266{
267    va_list args;
268    char *cmd;
269    int i;
270
271    cmd = (char *)malloc(FILENAME_MAX);
272    cmd[0] = '\0';
273    va_start(args, fmt);
274    vsnprintf(cmd, FILENAME_MAX, fmt, args);
275    va_end(args);
276    msgNotify("Executing command: %s", cmd);
277    i = system(cmd);
278    msgDebug("Command `%s' returns status of %d\n", cmd, i);
279    free(cmd);
280    return i;
281}
282