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