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