/* * This file is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify this file without charge, but are not authorized to * license or distribute it to anyone else except as part of a product * or program developed by the user. * * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * This file is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even * if Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ #ifndef lint static char sccsid[] = "@(#)main.c 1.4 88/01/18 Copyright 1987 Sun Micro"; #endif /* * Copyright (c) 1987 by Sun Microsystems, Inc. * Steve Isaac 12/18/87 * */ /* Copyright Massachusetts Institute of Technology 1984, 1985 */ /* main.c */ #ifndef lint #endif lint #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* for NOFILE */ #include "NeWS.h" #include "ptyx.h" #include "data.h" #include "error.h" #include "main.h" int switchfb[] = {0, 2, 1, 3}; static int reapchild(); static char *brdr_color; static char **command_to_exec; #ifdef TIOCCONS static int Console; #endif TIOCCONS static struct sgttyb d_sg = { 0, 0, 0177, CKILL, EVENP | ODDP | ECHO | XTABS | CRMOD }; static struct tchars d_tc = { CINTR, CQUIT, CSTART, CSTOP, CEOF, CBRK, }; static struct ltchars d_ltc = { CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT }; static int d_disipline = NTTYDISC; static int d_lmode = LCRTBS | LCRTERA | LCRTKIL | LCTLECH; static char def_bold_font[] = DEFBOLDFONT; static char def_font[] = DEFFONT; static char def_title_font[] = DEFTITLEFONT; static char def_icon_font[] = DEFICONFONT; static char display[256]; static char etc_utmp[] = "/etc/utmp"; static char *get_ty; static char *iconbitmap; static int inhibit; static int log_on; static int login_shell; static char passedPty[2]; /* name if pty if slave */ static int loginpty; static char *tekiconbitmap; static int tslot; #ifdef UTMP static int added_utmp_entry; #endif UTMP main(argc, argv) int argc; char **argv; { register Screen *screen = &term.screen; register char *strind; register int i, pty; register char **cp; short fnflag = 0; /* True iff -fn option used */ short fbflag = 0; /* True iff -fb option used */ int Xsocket, mode; char *malloc(); char *basename(); int xerror(), xioerror(); #ifdef KEYBD extern char *keyboardtype; /* used in XKeyBind.c */ char *getenv(); #endif KEYBD for (i=0; i < MAXSCREENWIDTH; i++) blankline[i] = 32; /* BLANK */ xterm_name = (strcmp(*argv, "-") == 0) ? "nterm" : basename(*argv); term.flags = 0; screen->visualbell = TRUE; display[0] = '\0'; /* parse command line */ for (argc--, argv++; argc > 0; argc--, argv++) { if (**argv == '=') { geo_metry = *argv; continue; } if (**argv == '%') { continue; } if (**argv == '#') { continue; } if ((strind = index(*argv, ':')) != NULL) { strncpy(display, *argv, sizeof(display)); continue; } if (!(i = (**argv == '-')) && **argv != '+') Syntax(); switch (argument(&(*argv)[1])) { case ARG_132: screen->c132 = i; continue; #ifdef TIOCCONS case ARG__C: Console = i; continue; #endif TIOCCONS case ARG__L: { char tt[32]; L_flag = 1; get_ty = argv[--argc]; strcpy(tt, "/dev/"); strcat(tt, get_ty); tt[5] = 'p'; loginpty = open(tt, O_RDWR, 0); dup2(loginpty, 4); close(loginpty); loginpty = 4; tt[5] = 't'; chown(tt, 0, 0); chmod(tt, 0622); if (open(tt, O_RDWR) < 0) { consolepr("open failed\n"); } signal(SIGHUP, SIG_IGN); vhangup(); setpgrp(0, 0); signal(SIGHUP, SIG_DFL); (void) close(0); open(tt, O_RDWR, 0); dup2(0, 1); dup2(0, 2); continue; } case ARG__S: if (i) { if (--argc <= 0) Syntax(); sscanf(*++argv, "%c%c%d", passedPty, passedPty + 1, &am_slave); if (am_slave <= 0) Syntax(); } else am_slave = 0; continue; case ARG_AI: screen->active_icon = i; continue; case ARG_AR: screen->autoraise = i; continue; case ARG_AW: if (i) term.flags |= WRAPAROUND; else term.flags &= ~WRAPAROUND; continue; case ARG_B: continue; case ARG_BD: if (i) { if (--argc <= 0) Syntax(); brdr_color = *++argv; } else brdr_color = NULL; continue; case ARG_BG: if (i) { if (--argc <= 0) Syntax(); back_color = *++argv; } else back_color = NULL; continue; case ARG_BW: continue; case ARG_CR: if (i) { if (--argc <= 0) Syntax(); curs_color = *++argv; } else curs_color = NULL; continue; case ARG_CU: screen->curses = i; continue; #ifdef DEBUG case ARG_D: debug = i; continue; #endif DEBUG case ARG_DW: screen->deiconwarp = i; continue; case ARG_E: if (!i) Syntax(); if (argc <= 1) Syntax(); command_to_exec = ++argv; break; case ARG_FB: if (fbflag = i) { if (--argc <= 0) Syntax(); f_b = *++argv; fbflag = TRUE; } else { f_b = def_bold_font; fbflag = FALSE; } continue; case ARG_FG: if (i) { if (--argc <= 0) Syntax(); fore_color = *++argv; } else fore_color = NULL; continue; case ARG_FI: if (i) { if (--argc <= 0) Syntax(); f_i = *++argv; } else f_i = def_icon_font; continue; case ARG_FN: if (fnflag = i) { if (--argc <= 0) Syntax(); f_n = *++argv; fnflag = TRUE; } else { f_n = def_font; fnflag = FALSE; } continue; case ARG_FT: if (i) { if (--argc <= 0) Syntax(); f_t = *++argv; } else f_t = def_title_font; continue; case ARG_I: continue; case ARG_IB: if (i) { if (--argc <= 0) Syntax(); iconbitmap = *++argv; } else iconbitmap = NULL; continue; case ARG_IT: if (i) { if (--argc <= 0) Syntax(); tekiconbitmap = *++argv; } else tekiconbitmap = NULL; continue; case ARG_J: continue; #ifdef KEYBD case ARG_K: if (i) { if (--argc <= 0) Syntax(); keyboardtype = *++argv; } else keyboardtype = NULL; continue; #endif KEYBD case ARG_L: log_on = i; continue; case ARG_LF: if (screen->logfile) free(screen->logfile); if (i) { if (--argc <= 0) Syntax(); if (screen->logfile = malloc(strlen(*++argv) + 1)) strcpy(screen->logfile, *argv); } else screen->logfile = NULL; continue; case ARG_LS: login_shell = i; continue; case ARG_MB: screen->marginbell = i; continue; case ARG_MS: if (i) { if (--argc <= 0) Syntax(); mous_color = *++argv; } else mous_color = NULL; continue; case ARG_N: if (i) { if (--argc <= 0) Syntax(); win_name = *++argv; } else win_name = NULL; continue; case ARG_NB: if (i) { if (--argc <= 0) Syntax(); n_marginbell = atoi(*++argv); } else n_marginbell = N_MARGINBELL; continue; case ARG_PO: continue; case ARG_PS: screen->pagemode = i; continue; case ARG_RV: re_verse = i; continue; case ARG_RW: if (i) term.flags |= REVERSEWRAP; else term.flags &= ~REVERSEWRAP; continue; case ARG_S: screen->multiscroll = i; continue; case ARG_SB: continue; case ARG_SD: if (i) { if (--argc <= 0) Syntax(); select_delay = atoi(*++argv); } else select_delay = SELECTDELAY; continue; case ARG_SI: screen->scrollinput = i; continue; case ARG_SK: screen->scrollkey = i; continue; case ARG_SL: if (i) { if (--argc <= 0) Syntax(); save_lines = atoi(*++argv); if (save_lines < SAVELINES) save_lines = SAVELINES; } else save_lines = SAVELINES; continue; case ARG_SN: screen->reversestatus = !i; continue; case ARG_ST: screen->statusline = i; continue; case ARG_T: continue; case ARG_TB: continue; case ARG_TI: screen->textundericon = i; continue; case ARG_VB: screen->visualbell = i; continue; default: Syntax(); } break; } term.initflags = term.flags; if (fnflag && !fbflag) f_b = NULL; if (!fnflag && fbflag) f_n = f_b; /* set up stderr properly */ i = -1; #ifdef DEBUG if (debug) i = open("xterm.debug.log", O_WRONLY | O_CREAT | O_TRUNC, 0666); else #endif DEBUG if (get_ty) i = open("/dev/console", O_WRONLY); if (i >= 0) fileno(stderr) = i; if (fileno(stderr) != (NOFILE - 1)) { dup2(fileno(stderr), (NOFILE - 1)); if (fileno(stderr) >= 3) close(fileno(stderr)); fileno(stderr) = (NOFILE - 1); } signal(SIGCHLD, reapchild); signal(SIGHUP, SIG_IGN); /* signal(SIGALRM, SIG_IGN); */ /* open a terminal for client */ get_terminal(); spawn(); Xsocket = psio_fileno(PostScriptInput); pty = screen->respond; if (log_on) { log_on = FALSE; StartLog(screen); } screen->inhibit = inhibit; mode = 1; if (ioctl(pty, FIONBIO, &mode) == -1) SysError(ERROR_FIONBIO); pty_mask = 1 << pty; X_mask = 1 << Xsocket; Select_mask = pty_mask | X_mask; max_plus1 = (pty < Xsocket) ? (1 + Xsocket) : (1 + pty); #ifdef DEBUG if (debug) printf("debugging on\n"); #endif DEBUG for (;;) VTRun(); } char * basename(name) char *name; { register char *cp; char *rindex(); return ((cp = rindex(name, '/')) ? cp + 1 : name); } static struct argstr { char *arg; int val; } arg[] = { { "132", ARG_132 }, #ifdef TIOCCONS { "C", ARG__C }, #endif TIOCCONS { "L", ARG__L }, { "S", ARG__S }, { "ai", ARG_AI }, { "ar", ARG_AR }, { "aw", ARG_AW }, { "b", ARG_B }, { "bd", ARG_BD }, { "bg", ARG_BG }, { "bw", ARG_BW }, { "cr", ARG_CR }, { "cu", ARG_CU }, #ifdef DEBUG { "d", ARG_D }, #endif DEBUG { "dw", ARG_DW }, { "e", ARG_E }, { "fb", ARG_FB }, { "fg", ARG_FG }, { "fi", ARG_FI }, { "fn", ARG_FN }, { "ft", ARG_FT }, { "i", ARG_I }, { "ib", ARG_IB }, { "it", ARG_IT }, { "j", ARG_J }, #ifdef KEYBD { "k", ARG_K }, #endif KEYBD { "l", ARG_L }, { "lf", ARG_LF }, { "ls", ARG_LS }, { "mb", ARG_MB }, { "ms", ARG_MS }, { "n", ARG_N }, { "nb", ARG_NB }, { "po", ARG_PO }, { "ps", ARG_PS }, { "r", ARG_RV }, { "rv", ARG_RV }, { "rw", ARG_RW }, { "s", ARG_S }, { "sb", ARG_SB }, { "sd", ARG_SD }, { "si", ARG_SI }, { "sk", ARG_SK }, { "sl", ARG_SL }, { "sn", ARG_SN }, { "st", ARG_ST }, { "t", ARG_T }, { "tb", ARG_TB }, { "ti", ARG_TI }, { "vb", ARG_VB }, { "w", ARG_BW }, }; argument(s) register char *s; { register int i, low, high, com; low = 0; high = sizeof(arg) / sizeof(struct argstr) - 1; while (low <= high) { /* use binary search, arg in lexigraphic order */ i = (low + high) / 2; if ((com = strcmp(s, arg[i].arg)) == 0) return (arg[i].val); if (com > 0) low = i + 1; else high = i - 1; } return (-1); } static char *ustring[] = { #ifdef ARG__C "Usage: nterm [-aw] [-C] [-e command] [-ls] [-s] [-sl num_lines] \n", #else ARG__C "Usage: nterm [-aw] [-e command] [-ls] [-s] [-sl num_lines] \n", #endif ARG__C "The -aw option turns auto line wrapping mode on\n", #ifdef ARG__C "The -C option forces output to /dev/console to appear in this window\n", #endif ARG__C "The -e option execs the specified command instead of a shell\n", "The -ls option makes the shell a login shell\n", "The -s option enables asynchronous scrolling\n", "The -sl option sets the number of display and history lines\n", 0 }; Syntax() { register char **us = ustring; while (*us) fputs(*us++, stderr); exit(1); } get_pty(pty, tty) /* * opens a pty, storing fildes in pty and tty. */ int *pty, *tty; { int devindex, letter = 0; while (letter < 4) { ttydev[8] = ptydev[8] = "pqrs"[letter++]; devindex = 0; while (devindex < 16) { ttydev[9] = ptydev[9] = "0123456789abcdef"[devindex++]; if ((*pty = open(ptydev, O_RDWR)) < 0) continue; if ((*tty = open(ttydev, O_RDWR)) < 0) { close(*pty); continue; } return; } } exit(ERROR_PTYS); } get_terminal() /* * sets up NeWS and initializes the terminal structure except for * term.buf.fildes. */ { register Screen *screen = &term.screen; register int try; char *malloc(); if (ps_open_PostScript() == 0) { fprintf(stderr, "%s: Can't connect to display server\n", xterm_name); exit(ERROR_NOX2); } #ifdef TIOCCONS ps_initialize(Console ? "Console" : "Termulator",save_lines,&screen_cols, &screen_rows,&screen_pixwidth,&screen_pixheight); #else TIOCCONS ps_initialize("Termulator",save_lines,&screen_cols, &screen_rows,&screen_pixwidth,&screen_pixheight); #endif TIOCCONS if (re_verse) ps_reversevideo(); ps_flush_PostScript(); } static char *tekterm[] = { "tek4015", "tek4014", "tek4013", "tek4010", "dumb", 0 }; static char *vtterm[] = { "nterms", "nterm", "xterm", "vt102", "vt100", "ansi", "dumb", 0 }; #ifdef UTMP char * DisplayName(fd) { register struct hostent *h; struct sockaddr_in addr; int namelen; namelen = sizeof addr; if (getpeername(fd, &addr, &namelen) < 0 || (h = gethostbyaddr(&addr.sin_addr, sizeof addr.sin_addr, addr.sin_family)) == 0) return ""; else return h->h_name; } #endif changesize() /* * The user has changed the window size */ { register Screen *screen = &term.screen; register int i, *p; #ifdef sun #ifdef TIOCSSIZE struct ttysize ts; ts.ts_lines = screen_rows; ts.ts_cols = screen_cols; ioctl(screen->respond, TIOCSSIZE, &ts); #endif TIOCSSIZE #else sun #ifdef TIOCSWINSZ struct winsize ws; ws.ws_row = screen_rows; ws.ws_col = screen_cols; ws.ws_xpixel = screen_pixwidth; ws.ws_ypixel = screen_pixheight; ioctl(screen->respond, TIOCSWINSZ, &ws); #endif TIOCSWINSZ #endif sun p = linelength; for (i=1; i<=screen_rows; i++) ps_getlinelength(i,p+i); ps_getcaretpos(&caretX,&caretY); scrollingregion_enabled = FALSE; scrolling_disabled = FALSE; screen->top_marg = 1; screen->bot_marg = screen_rows; } spawn() /* * Inits pty and tty and forks a login process. Does not close fd Xsocket. If * getty, execs getty rather than csh and uses std fd's rather than opening a * pty/tty pair. If slave, the pty named in passedPty is already open for use */ { register Screen *screen = &term.screen; int Xsocket = psio_fileno(PostScriptInput); int index1, tty = -1; int discipline; unsigned lmode; struct tchars tc; struct ltchars ltc; struct sgttyb sg; char termcap[1024]; char newtc[1024]; char *ptr, *shname; int i, no_dev_tty = FALSE; char **envnew; /* new environment */ char buf[32]; char *TermName = NULL; int ldisc = 0; struct passwd *pw = NULL; #ifdef UTMP struct utmp utmp; #endif UTMP extern int Exit(); struct passwd *getpwuid(); char *getenv(); char *index(), *rindex(), *strindex(); screen->uid = getuid(); screen->gid = getgid(); #ifdef UTMP added_utmp_entry = FALSE; #endif UTMP /* so that TIOCSWINSZ || TIOCSIZE doesn't block */ signal(SIGTTOU, SIG_IGN); VTInit(); /* * Special case of a 80x24 window, use "nterms" */ envnew = (screen_cols == 80 && screen_rows == 24) ? vtterm : &vtterm[1]; ptr = termcap; while (*envnew) { if (tgetent(ptr, *envnew) == 1) { TermName = *envnew; resize(screen, TermName, termcap, newtc); break; } envnew++; } if (get_ty) { screen->respond = loginpty; if ((tslot = ttyslot()) <= 0) SysError(ERROR_TSLOT); #ifdef TIOCCONS if (Console) { int on = 1; if (ioctl(0, TIOCCONS, &on) == -1) SysError(ERROR_TIOCCONS); } #endif TIOCCONS } else if (am_slave) { screen->respond = am_slave; ptydev[8] = ttydev[8] = passedPty[0]; ptydev[9] = ttydev[9] = passedPty[1]; if ((tslot = ttyslot()) <= 0) SysError(ERROR_TSLOT2); setgid(screen->gid); setuid(screen->uid); } else { if ((tty = open("/dev/tty", O_RDWR, 0)) < 0) { if (errno != ENXIO) SysError(ERROR_OPDEVTTY); else { no_dev_tty = TRUE; sg = d_sg; tc = d_tc; discipline = d_disipline; ltc = d_ltc; lmode = d_lmode; } } else { /* get a copy of the current terminal's state */ if (ioctl(tty, TIOCGETP, &sg) == -1) SysError(ERROR_TIOCGETP); if (ioctl(tty, TIOCGETC, &tc) == -1) SysError(ERROR_TIOCGETC); if (ioctl(tty, TIOCGETD, &discipline) == -1) SysError(ERROR_TIOCGETD); if (ioctl(tty, TIOCGLTC, <c) == -1) SysError(ERROR_TIOCGLTC); if (ioctl(tty, TIOCLGET, &lmode) == -1) SysError(ERROR_TIOCLGET); close(tty); /* close all std file descriptors */ for (index1 = 0; index1 < 3; index1++) close(index1); if ((tty = open("/dev/tty", O_RDWR, 0)) < 0) SysError(ERROR_OPDEVTTY2); if (ioctl(tty, TIOCNOTTY, 0) == -1) SysError(ERROR_NOTTY); close(tty); } get_pty(&screen->respond, &tty); if (screen->respond != Xsocket + 1) { dup2(screen->respond, Xsocket + 1); close(screen->respond); screen->respond = Xsocket + 1; } /* change ownership of tty to real group and user id */ chown(ttydev, screen->uid, screen->gid); /* change protection of tty */ chmod(ttydev, 0622); if (tty != Xsocket + 2) { dup2(tty, Xsocket + 2); close(tty); tty = Xsocket + 2; } /* * set the new terminal's state to be the old one's with minor * modifications for efficiency */ sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW); sg.sg_flags |= ECHO | CRMOD; /* make sure speed is set on pty so that editors work right */ sg.sg_ispeed = B9600; sg.sg_ospeed = B9600; /* reset t_brkc to default value */ tc.t_brkc = -1; if (ioctl(tty, TIOCSETP, &sg) == -1) SysError(ERROR_TIOCSETP); if (ioctl(tty, TIOCSETC, &tc) == -1) SysError(ERROR_TIOCSETC); if (ioctl(tty, TIOCSETD, &discipline) == -1) SysError(ERROR_TIOCSETD); if (ioctl(tty, TIOCSLTC, <c) == -1) SysError(ERROR_TIOCSLTC); if (ioctl(tty, TIOCLSET, &lmode) == -1) SysError(ERROR_TIOCLSET); #ifdef TIOCCONS if (Console) { int on = 1; if (ioctl(tty, TIOCCONS, &on) == -1) SysError(ERROR_TIOCCONS); } #endif TIOCCONS close(open("/dev/null", O_RDWR, 0)); for (index1 = 0; index1 < 3; index1++) dup2(tty, index1); if ((tslot = ttyslot()) <= 0) SysError(ERROR_TSLOT3); #ifdef UTMP if ((pw = getpwuid(screen->uid)) && (i = open(etc_utmp, O_WRONLY)) >= 0) { bzero((char *) &utmp, sizeof(struct utmp)); (void) strcpy(utmp.ut_line, &ttydev[5]); (void) strcpy(utmp.ut_name, pw->pw_name); (void) strcpy(utmp.ut_host, DisplayName(fileno(PostScript))); time(&utmp.ut_time); lseek(i, (long) (tslot * sizeof(struct utmp)), 0); write(i, (char *) &utmp, sizeof(struct utmp)); close(i); added_utmp_entry = TRUE; } #endif UTMP } changesize(); if (!am_slave) { if ((screen->pid = fork()) == -1) SysError(ERROR_FORK); if (screen->pid == 0) { extern char **environ; int pgrp = getpid(); char shell_name[64]; close(Xsocket); close(screen->respond); if (fileno(stderr) >= 3) close(fileno(stderr)); if (tty >= 0) close(tty); signal(SIGCHLD, SIG_DFL); signal(SIGHUP, SIG_IGN); /* copy the environment before Setenving */ for (i = 0; environ[i] != NULL; i++); /* * The `4' is the number of Setenv() calls which may add a new * entry to the environment. The `1' is for the NULL terminating * entry. */ envnew = (char **) calloc(i + (4 + 1), sizeof(char *)); bcopy((char *) environ, (char *) envnew, i * sizeof(char *)); environ = envnew; Setenv("TERM=", TermName); if (!TermName) *newtc = 0; Setenv("TERMCAP=", newtc); signal(SIGTERM, SIG_DFL); ioctl(0, TIOCSPGRP, &pgrp); setpgrp(0, 0); close(open(ttyname(0), O_WRONLY, 0)); close(Xsocket); setpgrp(0, pgrp); setgid(screen->gid); setuid(screen->uid); signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); if (command_to_exec) { execvp(*command_to_exec, command_to_exec); /* print error message on screen */ fprintf(stderr, "%s: Can't execvp %s\n", xterm_name, *command_to_exec); } signal(SIGHUP, SIG_IGN); if (get_ty) { ioctl(0, TIOCNOTTY, 0); execl("/etc/getty", "+", "NeWS", get_ty, 0); } signal(SIGHUP, SIG_DFL); #ifdef UTMP if (((ptr = getenv("SHELL")) == NULL || *ptr == 0) && ((pw == NULL && (pw = getpwuid(screen->uid)) == NULL) || *(ptr = pw->pw_shell) == 0)) #else UTMP if (((ptr = getenv("SHELL")) == NULL || *ptr == 0) && ((pw = getpwuid(screen->uid)) == NULL || *(ptr = pw->pw_shell) == 0)) #endif UTMP ptr = "/bin/sh"; if (shname = rindex(ptr, '/')) shname++; else shname = ptr; i = strlen(shname) - 3; ldisc = (strcmp("csh", shname + i) == 0 || strcmp("ksh", shname + i) == 0) ? NTTYDISC : 0; ioctl(0, TIOCSETD, &ldisc); if (login_shell) strcpy(shell_name, "-"); else *shell_name = 0; strcat(shell_name, shname); execlp(ptr, shell_name, 0); fprintf(stderr, "%s: Could not exec %s!\n", xterm_name, ptr); sleep(5); exit(ERROR_EXEC); } } if (tty >= 0) close(tty); signal(SIGHUP, SIG_IGN); if (!no_dev_tty) { if ((tty = open("/dev/tty", O_RDWR, 0)) < 0) SysError(ERROR_OPDEVTTY3); for (index1 = 0; index1 < 3; index1++) dup2(tty, index1); if (tty > 2) close(tty); } signal(SIGINT, Exit); signal(SIGQUIT, Exit); signal(SIGTERM, Exit); } Exit(n) int n; { register Screen *screen = &term.screen; #ifdef UTMP register int i; struct utmp utmp; if (added_utmp_entry && (i = open(etc_utmp, O_WRONLY)) >= 0) { bzero((char *) &utmp, sizeof(struct utmp)); lseek(i, (long) (tslot * sizeof(struct utmp)), 0); write(i, (char *) &utmp, sizeof(struct utmp)); close(i); } #endif UTMP if (screen->logging) CloseLog(screen); if (!get_ty && !am_slave) { /* restore ownership of tty */ chown(ttydev, 0, 0); /* restore modes of tty */ chmod(ttydev, 0666); } exit(n); } resize(screen, TermName, oldtc, newtc) Screen *screen; char *TermName; register char *oldtc, *newtc; { register char *ptr1, *ptr2; register int i; register int li_first = 0; register char *temp; char *index(), *strindex(); if ((ptr1 = strindex(oldtc, "co#")) == NULL) { fprintf(stderr, "%s: Can't find co# in termcap string %s\n", xterm_name, TermName); exit(ERROR_NOCO); } if ((ptr2 = strindex(oldtc, "li#")) == NULL) { fprintf(stderr, "%s: Can't find li# in termcap string %s\n", xterm_name, TermName); exit(ERROR_NOLI); } if (ptr1 > ptr2) { li_first++; temp = ptr1; ptr1 = ptr2; ptr2 = temp; } ptr1 += 3; ptr2 += 3; strncpy(newtc, oldtc, i = ptr1 - oldtc); newtc += i; sprintf(newtc, "%d", li_first ? screen_rows : screen_cols); newtc += strlen(newtc); ptr1 = index(ptr1, ':'); strncpy(newtc, ptr1, i = ptr2 - ptr1); newtc += i; sprintf(newtc, "%d", li_first ? screen_cols : screen_rows); ptr2 = index(ptr2, ':'); strcat(newtc, ptr2); } static reapchild() { union wait status; register int pid; #ifdef DEBUG if (debug) fputs("Exiting\n", stderr); #endif DEBUG pid = wait3(&status, WNOHANG, NULL); if (!pid) return; if (pid != term.screen.pid) return; Cleanup(0); } consolepr(string) char *string; { extern int errno; extern char *sys_errlist[]; int oerrno; int f; oerrno = errno; f = open("/dev/console", O_WRONLY); write(f, "nterm: ", 7); write(f, string, strlen(string)); write(f, ": ", 2); write(f, sys_errlist[oerrno], strlen(sys_errlist[oerrno])); write(f, "\n", 1); close(f); if ((f = open("/dev/tty", 2)) >= 0) { ioctl(f, TIOCNOTTY, 0); close(f); } } checklogin() { register int i, j; register struct passwd *pw; struct utmp utmp; if ((i = open(etc_utmp, O_RDONLY)) < 0) return (FALSE); lseek(i, (long) (tslot * sizeof(struct utmp)), 0); j = read(i, (char *) &utmp, sizeof(utmp)); close(i); if (j != sizeof(utmp) || strcmp(get_ty, utmp.ut_line) != 0 || !*utmp.ut_name || (pw = getpwnam(utmp.ut_name)) == NULL) return (FALSE); chdir(pw->pw_dir); setgid(pw->pw_gid); setuid(pw->pw_uid); L_flag = 0; return (TRUE); }