69df29fff8
use them yet, but it's close (we're working on the last wrinkles in the CD install for now). 2. Complete the CDROM installation strategy code. 3. Simplify the distribtuion loading code. 4. General error message cleanup. 5. Write the /etc/fstab file now and split those routines into config.c 6. Clean up the menus a little more.
356 lines
7.5 KiB
C
356 lines
7.5 KiB
C
/*
|
|
* The new sysinstall program.
|
|
*
|
|
* This is probably the last program in the `sysinstall' line - the next
|
|
* generation being essentially a complete rewrite.
|
|
*
|
|
* $Id: system.c,v 1.28 1995/05/21 06:12:44 phk Exp $
|
|
*
|
|
* Jordan Hubbard
|
|
*
|
|
* My contributions are in the public domain.
|
|
*
|
|
* Parts of this file are also blatently stolen from Poul-Henning Kamp's
|
|
* previous version of sysinstall, and as such fall under his "BEERWARE license"
|
|
* so buy him a beer if you like it! Buy him a beer for me, too!
|
|
* Heck, get him completely drunk and send me pictures! :-)
|
|
*/
|
|
|
|
#include "sysinstall.h"
|
|
#include <signal.h>
|
|
#include <sys/reboot.h>
|
|
#include <machine/console.h>
|
|
#include <sys/fcntl.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/wait.h>
|
|
|
|
/*
|
|
* Handle interrupt signals - this probably won't work in all cases
|
|
* due to our having bogotified the internal state of dialog or curses,
|
|
* but we'll give it a try.
|
|
*/
|
|
static void
|
|
handle_intr(int sig)
|
|
{
|
|
if (!msgYesNo("Are you sure you want to abort the installation?"))
|
|
systemShutdown();
|
|
}
|
|
|
|
/* Welcome the user to the system */
|
|
void
|
|
systemWelcome(void)
|
|
{
|
|
printf("Installation system initializing..\n");
|
|
}
|
|
|
|
/* Initialize system defaults */
|
|
void
|
|
systemInitialize(int argc, char **argv)
|
|
{
|
|
int i;
|
|
|
|
signal(SIGINT, SIG_IGN);
|
|
globalsInit();
|
|
|
|
/* Are we running as init? */
|
|
if (getpid() == 1) {
|
|
setsid();
|
|
if (argc > 1 && strchr(argv[1],'C')) {
|
|
/* Kernel told us that we are on a CDROM root */
|
|
close(0); open("/bootcd/dev/console", O_RDWR);
|
|
close(1); dup(0);
|
|
close(2); dup(0);
|
|
CpioFD = open("/floppies/cpio.flp", O_RDONLY);
|
|
OnCDROM = TRUE;
|
|
chroot("/bootcd");
|
|
} else {
|
|
close(0); open("/dev/console", O_RDWR);
|
|
close(1); dup(0);
|
|
close(2); dup(0);
|
|
}
|
|
printf("%s running as init\n", argv[0]);
|
|
|
|
ioctl(0, TIOCSCTTY, (char *)NULL);
|
|
setlogin("root");
|
|
setenv("PATH", "/stand:/mnt/bin:/mnt/sbin:/mnt/usr/sbin:/mnt/usr/bin", 1);
|
|
setbuf(stdin, 0);
|
|
setbuf(stderr, 0);
|
|
}
|
|
|
|
for(i = 0; i < 256; i++)
|
|
default_scrnmap[i] = i;
|
|
|
|
if (set_termcap() == -1) {
|
|
printf("Can't find terminal entry\n");
|
|
exit(-1);
|
|
}
|
|
|
|
/* XXX - libdialog has particularly bad return value checking */
|
|
init_dialog();
|
|
/* If we haven't crashed I guess dialog is running ! */
|
|
DialogActive = TRUE;
|
|
|
|
signal(SIGINT, handle_intr);
|
|
}
|
|
|
|
/* Close down and prepare to exit */
|
|
void
|
|
systemShutdown(void)
|
|
{
|
|
if (DialogActive) {
|
|
end_dialog();
|
|
DialogActive = FALSE;
|
|
}
|
|
/* REALLY exit! */
|
|
if (getpid() == 1)
|
|
reboot(RB_HALT);
|
|
else
|
|
exit(1);
|
|
}
|
|
|
|
/* Run some general command */
|
|
int
|
|
systemExecute(char *command)
|
|
{
|
|
int status;
|
|
|
|
dialog_clear();
|
|
dialog_update();
|
|
end_dialog();
|
|
DialogActive = FALSE;
|
|
status = system(command);
|
|
DialogActive = TRUE;
|
|
dialog_clear();
|
|
dialog_update();
|
|
return status;
|
|
}
|
|
|
|
/* Find and execute a shell */
|
|
int
|
|
systemShellEscape(void)
|
|
{
|
|
char *sh = NULL;
|
|
|
|
if (file_executable("/bin/sh"))
|
|
sh = "/bin/sh";
|
|
else if (file_executable("/stand/sh"))
|
|
sh = "/stand/sh";
|
|
else {
|
|
msgWarn("No shell available, sorry!");
|
|
return 1;
|
|
}
|
|
setenv("PS1", "freebsd% ", 1);
|
|
dialog_clear();
|
|
dialog_update();
|
|
move(0, 0);
|
|
standout();
|
|
addstr("Type `exit' to leave this shell and continue installation");
|
|
standend();
|
|
refresh();
|
|
end_dialog();
|
|
DialogActive = FALSE;
|
|
if (fork() == 0)
|
|
execlp(sh, "-sh", 0);
|
|
else
|
|
wait(NULL);
|
|
dialog_clear();
|
|
DialogActive = TRUE;
|
|
return 0;
|
|
}
|
|
|
|
/* Display a file in a filebox */
|
|
int
|
|
systemDisplayFile(char *file)
|
|
{
|
|
char *fname = NULL;
|
|
char buf[FILENAME_MAX];
|
|
WINDOW *w;
|
|
|
|
fname = systemHelpFile(file, buf);
|
|
if (!fname) {
|
|
snprintf(buf, FILENAME_MAX, "The %s file is not provided on this particular floppy image.", file);
|
|
use_helpfile(NULL);
|
|
use_helpline(NULL);
|
|
w = dupwin(newscr);
|
|
dialog_mesgbox("Sorry!", buf, -1, -1);
|
|
touchwin(w);
|
|
wrefresh(w);
|
|
delwin(w);
|
|
return 1;
|
|
}
|
|
else {
|
|
use_helpfile(NULL);
|
|
use_helpline(NULL);
|
|
w = dupwin(newscr);
|
|
dialog_textbox(file, fname, LINES, COLS);
|
|
touchwin(w);
|
|
wrefresh(w);
|
|
delwin(w);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
char *
|
|
systemHelpFile(char *file, char *buf)
|
|
{
|
|
char *cp, *fname = NULL;
|
|
|
|
if (!file)
|
|
return NULL;
|
|
|
|
if ((cp = getenv("LANG")) != NULL) {
|
|
snprintf(buf, FILENAME_MAX, "help/%s/%s", cp, file);
|
|
if (file_readable(buf))
|
|
fname = buf;
|
|
else {
|
|
snprintf(buf, FILENAME_MAX, "/stand/help/%s/%s", cp, file);
|
|
if (file_readable(buf))
|
|
fname = buf;
|
|
}
|
|
}
|
|
if (!fname) {
|
|
snprintf(buf, FILENAME_MAX, "help/en_US.ISO8859-1/%s", file);
|
|
if (file_readable(buf))
|
|
fname = buf;
|
|
else {
|
|
snprintf(buf, FILENAME_MAX, "/stand/help/en_US.ISO8859-1/%s",
|
|
file);
|
|
if (file_readable(buf))
|
|
fname = buf;
|
|
}
|
|
}
|
|
return fname;
|
|
}
|
|
|
|
void
|
|
systemChangeFont(const u_char font[])
|
|
{
|
|
if (OnVTY && ColorDisplay) {
|
|
if (ioctl(0, PIO_FONT8x16, font) < 0)
|
|
msgConfirm("Sorry! Unable to load font for %s", getenv("LANG"));
|
|
}
|
|
dialog_clear();
|
|
}
|
|
|
|
void
|
|
systemChangeLang(char *lang)
|
|
{
|
|
variable_set2("LANG", lang);
|
|
}
|
|
|
|
void
|
|
systemChangeTerminal(char *color, const u_char c_term[],
|
|
char *mono, const u_char m_term[])
|
|
{
|
|
extern void init_acs(void);
|
|
|
|
if (OnVTY) {
|
|
if (ColorDisplay) {
|
|
setenv("TERM", color, 1);
|
|
setenv("TERMCAP", c_term, 1);
|
|
reset_shell_mode();
|
|
setterm(color);
|
|
init_acs();
|
|
cbreak(); noecho();
|
|
}
|
|
else {
|
|
setenv("TERM", mono, 1);
|
|
setenv("TERMCAP", m_term, 1);
|
|
reset_shell_mode();
|
|
setterm(mono);
|
|
init_acs();
|
|
cbreak(); noecho();
|
|
}
|
|
dialog_clear();
|
|
}
|
|
}
|
|
|
|
void
|
|
systemChangeScreenmap(const u_char newmap[])
|
|
{
|
|
if (OnVTY) {
|
|
if (ioctl(0, PIO_SCRNMAP, newmap) < 0)
|
|
msgConfirm("Sorry! Unable to load the screenmap for %s",
|
|
getenv("LANG"));
|
|
}
|
|
dialog_clear();
|
|
}
|
|
|
|
int
|
|
vsystem(char *fmt, ...)
|
|
{
|
|
va_list args;
|
|
union wait pstat;
|
|
pid_t pid;
|
|
int omask;
|
|
sig_t intsave, quitsave;
|
|
char *cmd,*p;
|
|
int i,magic=0;
|
|
|
|
cmd = (char *)malloc(FILENAME_MAX);
|
|
cmd[0] = '\0';
|
|
va_start(args, fmt);
|
|
vsnprintf(cmd, FILENAME_MAX, fmt, args);
|
|
va_end(args);
|
|
/* Find out if this command needs the wizardry of the shell */
|
|
for (p="<>|'`=\"()" ; *p; p++)
|
|
if (strchr(cmd,*p)) magic++;
|
|
omask = sigblock(sigmask(SIGCHLD));
|
|
msgDebug("Executing command `%s' (Magic=%d)\n", cmd, magic);
|
|
switch(pid = fork()) {
|
|
case -1: /* error */
|
|
(void)sigsetmask(omask);
|
|
i = 127;
|
|
|
|
case 0: /* child */
|
|
(void)sigsetmask(omask);
|
|
if (DebugFD != -1) {
|
|
if (OnVTY)
|
|
msgInfo("Command output is on debugging screen - type ALT-F2 to see it");
|
|
dup2(DebugFD, 0);
|
|
dup2(DebugFD, 1);
|
|
dup2(DebugFD, 2);
|
|
}
|
|
#ifdef CRUNCHED_BINARY
|
|
if (magic) {
|
|
char *argv[100];
|
|
i = 0;
|
|
argv[i++] = "crunch";
|
|
argv[i++] = "sh";
|
|
argv[i++] = "-c";
|
|
argv[i++] = cmd;
|
|
argv[i] = 0;
|
|
exit(crunched_main(i,argv));
|
|
} else {
|
|
char *argv[100];
|
|
i = 0;
|
|
argv[i++] = "crunch";
|
|
while (cmd && *cmd) {
|
|
argv[i] = strsep(&cmd," \t");
|
|
if (*argv[i])
|
|
i++;
|
|
}
|
|
argv[i] = 0;
|
|
if (crunched_here(argv[1]))
|
|
exit(crunched_main(i,argv));
|
|
else
|
|
execvp(argv[1],argv+1);
|
|
kill(getpid(),9);
|
|
}
|
|
#else /* !CRUNCHED_BINARY */
|
|
execl("/stand/sh", "sh", "-c", cmd, (char *)NULL);
|
|
kill(getpid(),9);
|
|
#endif /* CRUNCHED_BINARY */
|
|
}
|
|
intsave = signal(SIGINT, SIG_IGN);
|
|
quitsave = signal(SIGQUIT, SIG_IGN);
|
|
pid = waitpid(pid, (int *)&pstat, 0);
|
|
(void)sigsetmask(omask);
|
|
(void)signal(SIGINT, intsave);
|
|
(void)signal(SIGQUIT, quitsave);
|
|
i = (pid == -1) ? -1 : pstat.w_status;
|
|
msgDebug("Command `%s' returns status of %d\n", cmd, i);
|
|
free(cmd);
|
|
return i;
|
|
}
|