system.c revision 16975
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.59 1996/05/16 11:47:46 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/* Where we stick our temporary expanded doc file */ 29#define DOC_TMP_FILE "/tmp/doc.tmp" 30 31/* 32 * Handle interrupt signals - this probably won't work in all cases 33 * due to our having bogotified the internal state of dialog or curses, 34 * but we'll give it a try. 35 */ 36static void 37handle_intr(int sig) 38{ 39 if (!msgYesNo("Are you sure you want to abort the installation?")) 40 systemShutdown(1); 41} 42 43/* Expand a file into a convenient location, nuking it each time */ 44static char * 45expand(char *fname) 46{ 47 unlink(DOC_TMP_FILE); 48 if (vsystem("gzip -c -d %s > %s", fname, DOC_TMP_FILE)) 49 return NULL; 50 return DOC_TMP_FILE; 51} 52 53/* Initialize system defaults */ 54void 55systemInitialize(int argc, char **argv) 56{ 57 int i; 58 59 signal(SIGINT, SIG_IGN); 60 globalsInit(); 61 62 /* Are we running as init? */ 63 if (getpid() == 1) { 64 setsid(); 65 close(0); open("/dev/ttyv0", O_RDWR); 66 close(1); dup(0); 67 close(2); dup(0); 68 printf("%s running as init\n", argv[0]); 69 RunningAsInit = 1; 70 i = ioctl(0, TIOCSCTTY, (char *)NULL); 71 setlogin("root"); 72 setenv("PATH", "/stand:/bin:/sbin:/usr/sbin:/usr/bin:/mnt/bin:/mnt/sbin:/mnt/usr/sbin:/mnt/usr/bin:/usr/X11R6/bin", 1); 73 setbuf(stdin, 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 85 /* If we haven't crashed I guess dialog is running ! */ 86 DialogActive = TRUE; 87 88 /* Make sure HOME is set for those utilities that need it */ 89 if (!getenv("HOME")) 90 setenv("HOME", "/", 1); 91 signal(SIGINT, handle_intr); 92} 93 94/* Close down and prepare to exit */ 95void 96systemShutdown(int status) 97{ 98 /* If some media is open, close it down */ 99 if (mediaDevice) 100 mediaDevice->shutdown(mediaDevice); 101 102 /* Shut down the dialog library */ 103 if (DialogActive) { 104 end_dialog(); 105 DialogActive = FALSE; 106 } 107 108 /* Shut down curses */ 109 endwin(); 110 111 /* If we have a temporary doc file lying around, nuke it */ 112 unlink(DOC_TMP_FILE); 113 114 /* REALLY exit! */ 115 if (RunningAsInit) { 116 /* Put the console back */ 117 ioctl(0, VT_ACTIVATE, 2); 118 reboot(0); 119 } 120 else 121 exit(status); 122} 123 124/* Run some general command */ 125int 126systemExecute(char *command) 127{ 128 int status; 129 struct termios foo; 130 131 dialog_update(); 132 end_dialog(); 133 DialogActive = FALSE; 134 if (tcgetattr(0, &foo) != -1) { 135 foo.c_cc[VERASE] = '\010'; 136 tcsetattr(0, TCSANOW, &foo); 137 } 138 if (!Fake) 139 status = system(command); 140 else { 141 status = 0; 142 msgDebug("systemExecute: Faked execution of `%s'\n", command); 143 } 144 DialogActive = TRUE; 145 return status; 146} 147 148/* Display a help file in a filebox */ 149int 150systemDisplayHelp(char *file) 151{ 152 char *fname = NULL; 153 char buf[FILENAME_MAX]; 154 WINDOW *old = savescr(); 155 int ret = 0; 156 157 fname = systemHelpFile(file, buf); 158 if (!fname) { 159 snprintf(buf, FILENAME_MAX, "The %s file is not provided on this particular floppy image.", file); 160 use_helpfile(NULL); 161 use_helpline(NULL); 162 dialog_mesgbox("Sorry!", buf, -1, -1); 163 ret = 1; 164 } 165 else { 166 use_helpfile(NULL); 167 use_helpline(NULL); 168 dialog_textbox(file, fname, LINES, COLS); 169 } 170 restorescr(old); 171 return ret; 172} 173 174char * 175systemHelpFile(char *file, char *buf) 176{ 177 if (!file) 178 return NULL; 179 180 snprintf(buf, FILENAME_MAX, "/stand/help/%s.hlp.gz", file); 181 if (file_readable(buf)) 182 return expand(buf); 183 snprintf(buf, FILENAME_MAX, "/usr/src/release/sysinstall/help/%s.hlp", file); 184 if (file_readable(buf)) 185 return buf; 186 return NULL; 187} 188 189void 190systemChangeTerminal(char *color, const u_char c_term[], 191 char *mono, const u_char m_term[]) 192{ 193 extern void init_acs(void); 194 195 if (OnVTY) { 196 if (ColorDisplay) { 197 setenv("TERM", color, 1); 198 setenv("TERMCAP", c_term, 1); 199 reset_shell_mode(); 200 setterm(color); 201 init_acs(); 202 cbreak(); noecho(); 203 } 204 else { 205 setenv("TERM", mono, 1); 206 setenv("TERMCAP", m_term, 1); 207 reset_shell_mode(); 208 setterm(mono); 209 init_acs(); 210 cbreak(); noecho(); 211 } 212 } 213 clear(); 214 refresh(); 215 dialog_clear(); 216} 217 218int 219vsystem(char *fmt, ...) 220{ 221 va_list args; 222 int pstat; 223 pid_t pid; 224 int omask; 225 sig_t intsave, quitsave; 226 char *cmd; 227 int i; 228 229 cmd = (char *)alloca(FILENAME_MAX); 230 cmd[0] = '\0'; 231 va_start(args, fmt); 232 vsnprintf(cmd, FILENAME_MAX, fmt, args); 233 va_end(args); 234 235 omask = sigblock(sigmask(SIGCHLD)); 236 if (Fake) { 237 msgDebug("vsystem: Faked execution of `%s'\n", cmd); 238 return 0; 239 } 240 if (isDebug()) 241 msgDebug("Executing command `%s'\n", cmd); 242 pid = fork(); 243 if (pid == -1) { 244 (void)sigsetmask(omask); 245 i = 127; 246 } 247 else if (!pid) { /* Junior */ 248 (void)sigsetmask(omask); 249 if (DebugFD != -1) { 250 if (OnVTY && isDebug() && RunningAsInit) 251 msgInfo("Command output is on VTY2 - type ALT-F2 to see it"); 252 dup2(DebugFD, 0); 253 dup2(DebugFD, 1); 254 dup2(DebugFD, 2); 255 } 256 else { 257 close(1); open("/dev/null", O_WRONLY); 258 dup2(1, 2); 259 } 260 if (!RunningAsInit) 261 execl("/bin/sh", "/bin/sh", "-c", cmd, (char *)NULL); 262 else 263 execl("/stand/sh", "/stand/sh", "-c", cmd, (char *)NULL); 264 exit(1); 265 } 266 else { 267 intsave = signal(SIGINT, SIG_IGN); 268 quitsave = signal(SIGQUIT, SIG_IGN); 269 pid = waitpid(pid, &pstat, 0); 270 (void)sigsetmask(omask); 271 (void)signal(SIGINT, intsave); 272 (void)signal(SIGQUIT, quitsave); 273 i = (pid == -1) ? -1 : WEXITSTATUS(pstat); 274 if (isDebug()) 275 msgDebug("Command `%s' returns status of %d\n", cmd, i); 276 } 277 return i; 278} 279 280void 281systemCreateHoloshell(void) 282{ 283 if (OnVTY && RunningAsInit) { 284 if (!fork()) { 285 int i, fd; 286 struct termios foo; 287 extern int login_tty(int); 288 289 for (i = 0; i < 64; i++) 290 close(i); 291 DebugFD = fd = open("/dev/ttyv3", O_RDWR); 292 ioctl(0, TIOCSCTTY, &fd); 293 dup2(0, 1); 294 dup2(0, 2); 295 if (login_tty(fd) == -1) 296 msgDebug("Doctor: I can't set the controlling terminal.\n"); 297 signal(SIGTTOU, SIG_IGN); 298 if (tcgetattr(fd, &foo) != -1) { 299 foo.c_cc[VERASE] = '\010'; 300 if (tcsetattr(fd, TCSANOW, &foo) == -1) 301 msgDebug("Doctor: I'm unable to set the erase character.\n"); 302 } 303 else 304 msgDebug("Doctor: I'm unable to get the terminal attributes!\n"); 305 execlp("sh", "-sh", 0); 306 msgDebug("Was unable to execute sh for Holographic shell!\n"); 307 exit(1); 308 } 309 else { 310 msgNotify("Starting an emergency holographic shell on VTY4"); 311 sleep(2); 312 } 313 } 314} 315