system.c revision 8738
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.31 1995/05/24 23:36:50 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/* Welcome the user to the system */ 40void 41systemWelcome(void) 42{ 43 printf("Installation system initializing..\n"); 44} 45 46/* Initialize system defaults */ 47void 48systemInitialize(int argc, char **argv) 49{ 50 int i; 51 52 signal(SIGINT, SIG_IGN); 53 globalsInit(); 54 55 /* Are we running as init? */ 56 if (getpid() == 1) { 57 setsid(); 58 if (argc > 1 && strchr(argv[1],'C')) { 59 /* Kernel told us that we are on a CDROM root */ 60 close(0); open("/bootcd/dev/console", O_RDWR); 61 close(1); dup(0); 62 close(2); dup(0); 63 CpioFD = open("/floppies/cpio.flp", O_RDONLY); 64 OnCDROM = TRUE; 65 chroot("/bootcd"); 66 } else { 67 close(0); open("/dev/console", O_RDWR); 68 close(1); dup(0); 69 close(2); dup(0); 70 } 71 printf("%s running as init\n", argv[0]); 72 73 ioctl(0, TIOCSCTTY, (char *)NULL); 74 setlogin("root"); 75 setenv("PATH", "/stand:/mnt/bin:/mnt/sbin:/mnt/usr/sbin:/mnt/usr/bin", 1); 76 setbuf(stdin, 0); 77 setbuf(stderr, 0); 78 } 79 80 for(i = 0; i < 256; i++) 81 default_scrnmap[i] = i; 82 83 if (set_termcap() == -1) { 84 printf("Can't find terminal entry\n"); 85 exit(-1); 86 } 87 88 /* If we're running as init, stick a shell over on the 4th VTY */ 89 if (RunningAsInit && !fork()) { 90 int i; 91 92 for (i = 0; i < 64; i++) 93 close(i); 94 open("/dev/ttyv3", O_RDWR); 95 ioctl(0, TIOCSCTTY, (char *)NULL); 96 dup2(0, 1); 97 dup2(0, 2); 98 execlp("/stand/sh", "-sh", 0); 99 exit(1); 100 } 101 102 /* XXX - libdialog has particularly bad return value checking */ 103 init_dialog(); 104 /* If we haven't crashed I guess dialog is running ! */ 105 DialogActive = TRUE; 106 107 signal(SIGINT, handle_intr); 108} 109 110/* Close down and prepare to exit */ 111void 112systemShutdown(void) 113{ 114 if (DialogActive) { 115 end_dialog(); 116 DialogActive = FALSE; 117 } 118 /* REALLY exit! */ 119 if (getpid() == 1) 120 reboot(RB_HALT); 121 else 122 exit(1); 123} 124 125/* Run some general command */ 126int 127systemExecute(char *command) 128{ 129 int status; 130 131 dialog_clear(); 132 dialog_update(); 133 end_dialog(); 134 DialogActive = FALSE; 135 status = system(command); 136 DialogActive = TRUE; 137 dialog_clear(); 138 dialog_update(); 139 return status; 140} 141 142/* Find and execute a shell */ 143int 144systemShellEscape(void) 145{ 146 char *sh = NULL; 147 148 if (file_executable("/bin/sh")) 149 sh = "/bin/sh"; 150 else if (file_executable("/stand/sh")) 151 sh = "/stand/sh"; 152 else { 153 msgWarn("No shell available, sorry!"); 154 return 1; 155 } 156 setenv("PS1", "freebsd% ", 1); 157 dialog_clear(); 158 dialog_update(); 159 move(0, 0); 160 standout(); 161 addstr("Type `exit' to leave this shell and continue installation"); 162 standend(); 163 refresh(); 164 end_dialog(); 165 DialogActive = FALSE; 166 if (fork() == 0) 167 execlp(sh, "-sh", 0); 168 else 169 wait(NULL); 170 dialog_clear(); 171 DialogActive = TRUE; 172 return 0; 173} 174 175/* Display a file in a filebox */ 176int 177systemDisplayFile(char *file) 178{ 179 char *fname = NULL; 180 char buf[FILENAME_MAX]; 181 WINDOW *w; 182 183 fname = systemHelpFile(file, buf); 184 if (!fname) { 185 snprintf(buf, FILENAME_MAX, "The %s file is not provided on this particular floppy image.", file); 186 use_helpfile(NULL); 187 use_helpline(NULL); 188 w = dupwin(newscr); 189 dialog_mesgbox("Sorry!", buf, -1, -1); 190 touchwin(w); 191 wrefresh(w); 192 delwin(w); 193 return 1; 194 } 195 else { 196 use_helpfile(NULL); 197 use_helpline(NULL); 198 w = dupwin(newscr); 199 dialog_textbox(file, fname, LINES, COLS); 200 touchwin(w); 201 wrefresh(w); 202 delwin(w); 203 } 204 return 0; 205} 206 207char * 208systemHelpFile(char *file, char *buf) 209{ 210 char *cp, *fname = NULL; 211 212 if (!file) 213 return NULL; 214 215 if ((cp = getenv("LANG")) != NULL) { 216 snprintf(buf, FILENAME_MAX, "help/%s/%s", cp, file); 217 if (file_readable(buf)) 218 fname = buf; 219 else { 220 snprintf(buf, FILENAME_MAX, "/stand/help/%s/%s", cp, file); 221 if (file_readable(buf)) 222 fname = buf; 223 } 224 } 225 if (!fname) { 226 snprintf(buf, FILENAME_MAX, "help/en_US.ISO8859-1/%s", file); 227 if (file_readable(buf)) 228 fname = buf; 229 else { 230 snprintf(buf, FILENAME_MAX, "/stand/help/en_US.ISO8859-1/%s", 231 file); 232 if (file_readable(buf)) 233 fname = buf; 234 } 235 } 236 return fname; 237} 238 239void 240systemChangeFont(const u_char font[]) 241{ 242 if (OnVTY && ColorDisplay) { 243 if (ioctl(0, PIO_FONT8x16, font) < 0) 244 msgConfirm("Sorry! Unable to load font for %s", getenv("LANG")); 245 } 246 dialog_clear(); 247} 248 249void 250systemChangeLang(char *lang) 251{ 252 variable_set2("LANG", lang); 253} 254 255void 256systemChangeTerminal(char *color, const u_char c_term[], 257 char *mono, const u_char m_term[]) 258{ 259 extern void init_acs(void); 260 261 if (OnVTY) { 262 if (ColorDisplay) { 263 setenv("TERM", color, 1); 264 setenv("TERMCAP", c_term, 1); 265 reset_shell_mode(); 266 setterm(color); 267 init_acs(); 268 cbreak(); noecho(); 269 } 270 else { 271 setenv("TERM", mono, 1); 272 setenv("TERMCAP", m_term, 1); 273 reset_shell_mode(); 274 setterm(mono); 275 init_acs(); 276 cbreak(); noecho(); 277 } 278 dialog_clear(); 279 } 280} 281 282void 283systemChangeScreenmap(const u_char newmap[]) 284{ 285 if (OnVTY) { 286 if (ioctl(0, PIO_SCRNMAP, newmap) < 0) 287 msgConfirm("Sorry! Unable to load the screenmap for %s", 288 getenv("LANG")); 289 } 290 dialog_clear(); 291} 292 293int 294vsystem(char *fmt, ...) 295{ 296 va_list args; 297 union wait pstat; 298 pid_t pid; 299 int omask; 300 sig_t intsave, quitsave; 301 char *cmd,*p; 302 int i,magic=0; 303 304 cmd = (char *)malloc(FILENAME_MAX); 305 cmd[0] = '\0'; 306 va_start(args, fmt); 307 vsnprintf(cmd, FILENAME_MAX, fmt, args); 308 va_end(args); 309 /* Find out if this command needs the wizardry of the shell */ 310 for (p="<>|'`=\"()" ; *p; p++) 311 if (strchr(cmd,*p)) magic++; 312 omask = sigblock(sigmask(SIGCHLD)); 313 msgDebug("Executing command `%s' (Magic=%d)\n", cmd, magic); 314 switch(pid = fork()) { 315 case -1: /* error */ 316 (void)sigsetmask(omask); 317 i = 127; 318 319 case 0: /* child */ 320 (void)sigsetmask(omask); 321 if (DebugFD != -1) { 322 if (OnVTY) 323 msgInfo("Command output is on debugging screen - type ALT-F2 to see it"); 324 dup2(DebugFD, 0); 325 dup2(DebugFD, 1); 326 dup2(DebugFD, 2); 327 } 328#ifdef CRUNCHED_BINARY 329 if (magic) { 330 char *argv[100]; 331 i = 0; 332 argv[i++] = "crunch"; 333 argv[i++] = "sh"; 334 argv[i++] = "-c"; 335 argv[i++] = cmd; 336 argv[i] = 0; 337 exit(crunched_main(i,argv)); 338 } else { 339 char *argv[100]; 340 i = 0; 341 argv[i++] = "crunch"; 342 while (cmd && *cmd) { 343 argv[i] = strsep(&cmd," \t"); 344 if (*argv[i]) 345 i++; 346 } 347 argv[i] = 0; 348 if (crunched_here(argv[1])) 349 exit(crunched_main(i,argv)); 350 else 351 execvp(argv[1],argv+1); 352 kill(getpid(),9); 353 } 354#else /* !CRUNCHED_BINARY */ 355 execl("/stand/sh", "sh", "-c", cmd, (char *)NULL); 356 kill(getpid(),9); 357#endif /* CRUNCHED_BINARY */ 358 } 359 intsave = signal(SIGINT, SIG_IGN); 360 quitsave = signal(SIGQUIT, SIG_IGN); 361 pid = waitpid(pid, (int *)&pstat, 0); 362 (void)sigsetmask(omask); 363 (void)signal(SIGINT, intsave); 364 (void)signal(SIGQUIT, quitsave); 365 i = (pid == -1) ? -1 : pstat.w_status; 366 msgDebug("Command `%s' returns status of %d\n", cmd, i); 367 free(cmd); 368 return i; 369} 370