Annotation of researchv9/X11/src/X.V11R1/clients/xterm/main.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     $Source: /orpheus/u1/X11/clients/xterm/RCS/main.c,v $
                      3:  *     $Header: main.c,v 1.29 87/08/03 17:05:39 swick Locked $
                      4:  */
                      5: 
                      6: #include <X11/copyright.h>
                      7: 
                      8: /*
                      9:  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
                     10:  *
                     11:  *                         All Rights Reserved
                     12:  *
                     13:  * Permission to use, copy, modify, and distribute this software and its
                     14:  * documentation for any purpose and without fee is hereby granted,
                     15:  * provided that the above copyright notice appear in all copies and that
                     16:  * both that copyright notice and this permission notice appear in
                     17:  * supporting documentation, and that the name of Digital Equipment
                     18:  * Corporation not be used in advertising or publicity pertaining to
                     19:  * distribution of the software without specific, written prior permission.
                     20:  *
                     21:  *
                     22:  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     23:  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     24:  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     25:  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     26:  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     27:  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     28:  * SOFTWARE.
                     29:  */
                     30: 
                     31: /* main.c */
                     32: 
                     33: #ifndef lint
                     34: static char rcs_id[] = "$Header: main.c,v 1.29 87/08/03 17:05:39 swick Locked $";
                     35: #endif lint
                     36: 
                     37: #include <pwd.h>
                     38: #include <sgtty.h>
                     39: #include <sys/wait.h>
                     40: #include <sys/time.h>
                     41: #include <sys/resource.h>
                     42: #include <stdio.h>
                     43: #include <sys/file.h>
                     44: #include <errno.h>
                     45: #include <signal.h>
                     46: #include <strings.h>
                     47: #include <setjmp.h>
                     48: 
                     49: #ifdef apollo
                     50: #include <sys/types.h>
                     51: #define ttyslot() 1
                     52: #define vhangup() ;
                     53: #endif
                     54: 
                     55: #include <utmp.h>
                     56: #include <sys/param.h> /* for NOFILE */
                     57: #include <X11/Xlib.h>
                     58: #include <X11/Xtlib.h>
                     59: #include "ptyx.h"
                     60: #include "data.h"
                     61: #include "error.h"
                     62: #include "main.h"
                     63: 
                     64: extern Pixmap make_gray();
                     65: extern char *malloc();
                     66: extern char *calloc();
                     67: extern char *ttyname();
                     68: extern void exit();
                     69: extern void sleep();
                     70: extern void bcopy();
                     71: extern void vhangup();
                     72: extern long lseek();
                     73: 
                     74: XrmNameList nameList;
                     75: XrmClassList classList;
                     76: 
                     77: int switchfb[] = {0, 2, 1, 3};
                     78: 
                     79: static int reapchild ();
                     80: 
                     81: static char **command_to_exec;
                     82: static struct  sgttyb d_sg = {
                     83:         0, 0, 0177, CKILL, EVENP|ODDP|ECHO|XTABS|CRMOD
                     84: };
                     85: static struct  tchars d_tc = {
                     86:         CINTR, CQUIT, CSTART,
                     87:         CSTOP, CEOF, CBRK,
                     88: };
                     89: static struct  ltchars d_ltc = {
                     90:         CSUSP, CDSUSP, CRPRNT,
                     91:         CFLUSH, CWERASE, CLNEXT
                     92: };
                     93: static int d_disipline = NTTYDISC;
                     94: static long int d_lmode = LCRTBS|LCRTERA|LCRTKIL|LCTLECH;
                     95: static char display[256];
                     96: static char etc_utmp[] = "/etc/utmp";
                     97: static char *get_ty;
                     98: static int inhibit;
                     99: static int log_on;
                    100: static int login_shell;
                    101: static char passedPty[2];      /* name if pty if slave */
                    102: static int loginpty;
                    103: #ifdef TIOCCONS
                    104: static int Console;
                    105: #endif TIOCCONS
                    106: static int tslot;
                    107: static jmp_buf env;
                    108: 
                    109: #define        XtNxterm                "xterm"
                    110: #define        XtNwindowName           "windowName"
                    111: #define        XtNboldFont             "boldFont"
                    112: #define        XtNc132                 "c132"
                    113: #define XtNtitle               "title"
                    114: #define        XtNcurses               "curses"
                    115: #define        XtNcursor               "cursor"
                    116: #define        XtNcursorShape          "cursorShape"
                    117: #define        XtNgeometry             "geometry"
                    118: #define        XtNiconStartup          "iconStartup"
                    119: #define        XtNinternalBorder       "internalBorder"
                    120: #define        XtNjumpScroll           "jumpScroll"
                    121: #define        XtNlogFile              "logFile"
                    122: #define        XtNlogging              "logging"
                    123: #define        XtNlogInhibit           "logInhibit"
                    124: #define        XtNloginShell           "loginShell"
                    125: #define        XtNmarginBell           "marginBell"
                    126: #define        XtNmouse                "mouse"
                    127: #define        XtNmultiScroll          "multiScroll"
                    128: #define        XtNnMarginBell          "nMarginBell"
                    129: #define        XtNreverseWrap          "reverseWrap"
                    130: #define        XtNsaveLines            "saveLines"
                    131: #define        XtNscrollBar            "scrollBar"
                    132: #define        XtNscrollInput          "scrollInput"
                    133: #define        XtNscrollKey            "scrollKey"
                    134: #define        XtNsignalInhibit        "signalInhibit"
                    135: #define        XtNtekInhibit           "tekInhibit"
                    136: #define        XtNtekStartup           "tekStartup"
                    137: #define        XtNvisualBell           "visualBell"
                    138: 
                    139: #define        XtCApp                  "App"
                    140: #define        XtCC132                 "C132"
                    141: #define        XtCCurses               "Curses"
                    142: #define        XtCBitmapbits           "Bitmapbits"
                    143: #define        XtCGeometry             "Geometry"
                    144: #define        XtCIconstartup          "Iconstartup"
                    145: #define        XtCJumpscroll           "Jumpscroll"
                    146: #define        XtCLogfile              "Logfile"
                    147: #define        XtCLogging              "Logging"
                    148: #define        XtCLoginhibit           "Loginhibit"
                    149: #define        XtCLoginshell           "Loginshell"
                    150: #define        XtCMarginbell           "Marginbell"
                    151: #define        XtCMultiscroll          "Multiscroll"
                    152: #define        XtCColumn               "Column"
                    153: #define        XtCReverseVideo         "ReverseVideo"
                    154: #define        XtCReverseWrap          "ReverseWrap"
                    155: #define        XtCRows                 "Rows"
                    156: #define        XtCScrollbar            "ScrollBar"
                    157: #define        XtCScrollcond           "Scrollcond"
                    158: #define        XtCSignalInibit         "SignalInibit"
                    159: #define        XtCTekInhibit           "TekInhibit"
                    160: #define        XtCTekStartup           "TekStartup"
                    161: #define        XtCVisualbell           "Visualbell"
                    162: 
                    163: 
                    164: /* Defaults */
                    165: static  Boolean        defaultFALSE       = FALSE;
                    166: static  Boolean        defaultTRUE        = TRUE;
                    167: static char    *defaultNULL       = NULL;
                    168: static int     defaultBorderWidth = DEFBORDERWIDTH;
                    169: static int     defaultIntBorder   = DEFBORDER;
                    170: static  int    defaultSaveLines   = SAVELINES;
                    171: static int     defaultNMarginBell = N_MARGINBELL;
                    172: static  char   *defaultFont       = DEFFONT;
                    173: static char    *defaultBoldFont  = DEFBOLDFONT;
                    174: 
                    175: /* term.screen.flags things that don't map directly from option */
                    176: static Boolean reverseWrap;
                    177: static Boolean logInhibit;
                    178: static Boolean signalInhibit;
                    179: static Boolean tekInhibit;
                    180: 
                    181: /* term.screen.xxx things that don't map directly from option */
                    182: static Boolean scrollbar;
                    183: 
                    184: 
                    185: /*static*/ Resource resourceList[] = {
                    186: {XtNbackground,        XtCColor,       XrmRPixel,      sizeof(Pixel),
                    187:        (caddr_t) &term.screen.background,      (caddr_t) &XtDefaultBGPixel},
                    188: {XtNforeground,        XtCColor,       XrmRPixel,      sizeof(Pixel),
                    189:        (caddr_t) &term.screen.foreground,      (caddr_t) &XtDefaultFGPixel},
                    190: {XtNfont,      XtCFont,        XrmRString,     sizeof(char *),
                    191:        (caddr_t) &f_n,                         (caddr_t) &defaultNULL},
                    192: {XtNboldFont,  XtCFont,        XrmRString,     sizeof(char *),
                    193:        (caddr_t) &f_b,                         (caddr_t) &defaultNULL},
                    194: {XtNborder,    XtCColor,       XrmRPixel,      sizeof(Pixel),
                    195:        (caddr_t) &term.screen.bordercolor,     (caddr_t) &XtDefaultFGPixel},
                    196: {XtNborderWidth,XtCBorderWidth,        XrmRInt,                sizeof(int),
                    197:        (caddr_t) &term.screen.borderwidth,     (caddr_t)&defaultBorderWidth},
                    198: {XtNc132,      XtCC132,        XrmRBoolean,    sizeof(Boolean),
                    199:        (caddr_t) &term.screen.c132,            (caddr_t) &defaultFALSE},
                    200: {XtNcurses,    XtCCurses,      XrmRBoolean,    sizeof(Boolean),
                    201:        (caddr_t) &term.screen.curses,          (caddr_t) &defaultFALSE},
                    202: {XtNcursor,    XtCColor,       XrmRPixel,      sizeof(Pixel),
                    203:        (caddr_t) &term.screen.cursorcolor,     
                    204:        (caddr_t) &term.screen.foreground},
                    205: {XtNcursorShape,XtCCursor,     XrmRString,     sizeof(char *),
                    206:        (caddr_t) &curs_shape,                  (caddr_t) &defaultNULL},
                    207: {XtNgeometry,XtCGeometry,      XrmRString,     sizeof(char *),
                    208:        (caddr_t) &geo_metry,                   (caddr_t) &defaultNULL},
                    209: {XtNiconStartup,XtCIconstartup,        XrmRBoolean,    sizeof(Boolean),
                    210:        (caddr_t) &iconstartup,                 (caddr_t) &defaultFALSE},
                    211: {XtNinternalBorder,XtCBorderWidth,XrmRInt,     sizeof(int),
                    212:        (caddr_t) &term.screen.border,          (caddr_t) &defaultIntBorder},
                    213: {XtNjumpScroll,        XtCJumpscroll,  XrmRBoolean,    sizeof(Boolean),
                    214:        (caddr_t) &term.screen.jumpscroll,      (caddr_t) &defaultTRUE},
                    215: {XtNlogFile,   XtCLogfile,     XrmRString,     sizeof(char *),
                    216:        (caddr_t) &term.screen.logfile,         (caddr_t) &defaultNULL},
                    217: {XtNlogging,   XtCLogging,     XrmRBoolean,    sizeof(Boolean),
                    218:        (caddr_t) &log_on,                      (caddr_t) &defaultFALSE},
                    219: {XtNlogInhibit,        XtCLoginhibit,  XrmRBoolean,    sizeof(Boolean),
                    220:        (caddr_t) &logInhibit,                  (caddr_t) &defaultFALSE},
                    221: {XtNloginShell,        XtCLoginshell,  XrmRBoolean,    sizeof(Boolean),
                    222:        (caddr_t) &login_shell,                 (caddr_t) &defaultFALSE},
                    223: {XtNmarginBell,        XtCMarginbell,  XrmRBoolean,    sizeof(Boolean),
                    224:        (caddr_t) &term.screen.marginbell,      (caddr_t) &defaultFALSE},
                    225: {XtNmouse,     XtCColor,       XrmRPixel,      sizeof(Pixel),
                    226: /*     (caddr_t) &term.screen.mousecolor,      (caddr_t) &XtDefaultFGPixel},
                    227: */
                    228:        (caddr_t) &term.screen.mousecolor,      
                    229:        (caddr_t) &term.screen.cursorcolor},
                    230: {XtNmultiScroll,XtCMultiscroll,        XrmRBoolean,    sizeof(Boolean),
                    231:        (caddr_t) &term.screen.multiscroll,     (caddr_t) &defaultFALSE},
                    232: {XtNnMarginBell,XtCColumn,     XrmRInt,        sizeof(int),
                    233:        (caddr_t) &term.screen.nmarginbell,     (caddr_t) &defaultNMarginBell},
                    234: {XtNreverseVideo,XtCReverseVideo,XrmRBoolean,  sizeof(Boolean),
                    235:        (caddr_t) &re_verse,                    (caddr_t) &defaultFALSE},
                    236: {XtNreverseWrap,XtCReverseWrap,        XrmRBoolean,    sizeof(Boolean),
                    237:        (caddr_t) &reverseWrap,                 (caddr_t) &defaultFALSE},
                    238: {XtNsaveLines, XtCRows,        XrmRInt,        sizeof(int),
                    239:        (caddr_t) &save_lines,                  (caddr_t) &defaultSaveLines},
                    240: {XtNscrollBar, XtCScrollbar,   XrmRBoolean,    sizeof(Boolean),
                    241:        (caddr_t) &scrollbar,                   (caddr_t) &defaultFALSE},
                    242: {XtNscrollInput,XtCScrollcond, XrmRBoolean,    sizeof(Boolean),
                    243:        (caddr_t) &term.screen.scrollinput,     (caddr_t) &defaultTRUE},
                    244: {XtNscrollKey, XtCScrollcond,  XrmRBoolean,    sizeof(Boolean),
                    245:        (caddr_t) &term.screen.scrollkey,       (caddr_t) &defaultFALSE},
                    246: {XtNsignalInhibit,XtCSignalInibit,XrmRBoolean, sizeof(Boolean),
                    247:        (caddr_t) &signalInhibit,               (caddr_t) &defaultFALSE},
                    248: {XtNtekInhibit,        XtCTekInhibit,  XrmRBoolean,    sizeof(Boolean),
                    249:        (caddr_t) &tekInhibit,                  (caddr_t) &defaultFALSE},
                    250: {XtNtekStartup,        XtCTekStartup,  XrmRBoolean,    sizeof(Boolean),
                    251:        (caddr_t) &term.screen.TekEmu,          (caddr_t) &defaultFALSE},
                    252: {XtNtitle,     XtCString,      XrmRString,     sizeof(char *),
                    253:        (caddr_t) &title_name,                  (caddr_t) &defaultNULL},
                    254: {XtNvisualBell,XtCVisualbell,  XrmRBoolean,    sizeof(Boolean),
                    255:        (caddr_t) &term.screen.visualbell,      (caddr_t) &defaultFALSE},
                    256: {XtNwindowName,        XtCString,      XrmRString,     sizeof(char *),
                    257:        (caddr_t) &window_name,                 (caddr_t) &defaultNULL},
                    258: 
                    259: };
                    260: 
                    261: 
                    262: /* Command line options table.  Only resources are entered here...there is a
                    263:    pass over the remaining options after XtParseCommand is let loose. */
                    264: 
                    265: static XrmOptionDescRec optionDescList[] = {
                    266: {"=",          XtNgeometry,    XrmoptionIsArg,         (caddr_t) NULL},
                    267: {"-132",       XtNc132,        XrmoptionNoArg,         (caddr_t) "on"},
                    268: {"+132",       XtNc132,        XrmoptionNoArg,         (caddr_t) "off"},
                    269: {"-T",         XtNtitle,       XrmoptionSepArg,        (caddr_t) NULL},
                    270: {"-b",         XtNinternalBorder,XrmoptionSepArg,      (caddr_t) NULL},
                    271: {"-bd",                XtNborder,      XrmoptionSepArg,        (caddr_t) NULL},
                    272: {"-bg",                XtNbackground,  XrmoptionSepArg,        (caddr_t) NULL},
                    273: {"-bw",                XtNborderWidth, XrmoptionSepArg,        (caddr_t) NULL},
                    274: {"-cr",                XtNcursor,      XrmoptionSepArg,        (caddr_t) NULL},
                    275: {"-cu",                XtNcurses,      XrmoptionNoArg,         (caddr_t) "on"},
                    276: {"+cu",                XtNcurses,      XrmoptionNoArg,         (caddr_t) "off"},
                    277: {"-e",         NULL,           XrmoptionSkipLine,      (caddr_t) NULL},
                    278: {"-fb",                XtNboldFont,    XrmoptionSepArg,        (caddr_t) NULL},
                    279: {"-fg",                XtNforeground,  XrmoptionSepArg,        (caddr_t) NULL},
                    280: {"-fn",                XtNfont,        XrmoptionSepArg,        (caddr_t) NULL},
                    281: {"-i",         XtNiconStartup, XrmoptionNoArg,         (caddr_t) "on"},
                    282: {"-j",         XtNjumpScroll,  XrmoptionNoArg,         (caddr_t) "on"},
                    283: {"+j",         XtNjumpScroll,  XrmoptionNoArg,         (caddr_t) "off"},
                    284: {"-l",         XtNlogging,     XrmoptionNoArg,         (caddr_t) "on"},
                    285: {"+l",         XtNlogging,     XrmoptionNoArg,         (caddr_t) "off"},
                    286: {"-lf",                XtNlogFile,     XrmoptionSepArg,        (caddr_t) NULL},
                    287: {"-ls",                XtNloginShell,  XrmoptionNoArg,         (caddr_t) "on"},
                    288: {"+ls",                XtNloginShell,  XrmoptionNoArg,         (caddr_t) "off"},
                    289: {"-mb",                XtNmarginBell,  XrmoptionNoArg,         (caddr_t) "on"},
                    290: {"+mb",                XtNmarginBell,  XrmoptionNoArg,         (caddr_t) "off"},
                    291: {"-ms",                XtNmouse,       XrmoptionSepArg,        (caddr_t) NULL},
                    292: {"-n",         XtNwindowName,  XrmoptionSepArg,        (caddr_t) NULL},
                    293: {"-nb",                XtNnMarginBell, XrmoptionSepArg,        (caddr_t) NULL},
                    294: {"-r",         XtNreverseVideo,XrmoptionNoArg,         (caddr_t) "on"},
                    295: {"+r",         XtNreverseVideo,XrmoptionNoArg,         (caddr_t) "off"},
                    296: {"-rv",                XtNreverseVideo,XrmoptionNoArg,         (caddr_t) "on"},
                    297: {"+rv",                XtNreverseVideo,XrmoptionNoArg,         (caddr_t) "off"},
                    298: {"-rw",                XtNreverseWrap, XrmoptionNoArg,         (caddr_t) "on"},
                    299: {"+rw",                XtNreverseWrap, XrmoptionNoArg,         (caddr_t) "off"},
                    300: {"-s",         XtNmultiScroll, XrmoptionNoArg,         (caddr_t) "on"},
                    301: {"+s",         XtNmultiScroll, XrmoptionNoArg,         (caddr_t) "off"},
                    302: {"-sb",                XtNscrollBar,   XrmoptionNoArg,         (caddr_t) "on"},
                    303: {"+sb",                XtNscrollBar,   XrmoptionNoArg,         (caddr_t) "off"},
                    304: {"-si",                XtNscrollInput, XrmoptionNoArg,         (caddr_t) "off"},
                    305: {"+si",                XtNscrollInput, XrmoptionNoArg,         (caddr_t) "on"},
                    306: {"-sk",                XtNscrollKey,   XrmoptionNoArg,         (caddr_t) "on"},
                    307: {"+sk",                XtNscrollKey,   XrmoptionNoArg,         (caddr_t) "off"},
                    308: {"-sl",                XtNsaveLines,   XrmoptionSepArg,        (caddr_t) NULL},
                    309: {"-t",         XtNtekStartup,  XrmoptionNoArg,         (caddr_t) "on"},
                    310: {"+t",         XtNtekStartup,  XrmoptionNoArg,         (caddr_t) "off"},
                    311: {"-vb",                XtNvisualBell,  XrmoptionNoArg,         (caddr_t) "on"},
                    312: {"+vb",                XtNvisualBell,  XrmoptionNoArg,         (caddr_t) "off"},
                    313: {"-w",         XtNborderWidth, XrmoptionSepArg,        (caddr_t) NULL},
                    314: };
                    315: 
                    316: void XtGetUsersDataBase()
                    317: {
                    318:        XrmResourceDataBase resources, userResources;
                    319:        int uid;
                    320:        extern struct passwd *getpwuid();
                    321:        struct passwd *pw;
                    322:        char filename[1024];
                    323:        FILE *f;
                    324: 
                    325:        strcpy(filename, LIBDIR);
                    326:        strcat(filename, "/Xdefaults" );
                    327:        f = fopen(filename, "r");
                    328:        if (f) {
                    329:                XrmGetDataBase(f, &resources);
                    330:                fclose(f);
                    331:        } else
                    332:                resources = NULL;
                    333: 
                    334:        /* Open .Xdefaults file and merge into existing data base */
                    335:        uid = getuid();
                    336:        pw = getpwuid(uid);
                    337:        if (pw) {
                    338:                strcpy(filename, pw->pw_dir);
                    339:                strcat(filename, "/.Xdefaults");
                    340:                f = fopen(filename, "r");
                    341:                if (f) {
                    342:                        XrmGetDataBase(f, &userResources);
                    343:                        if (resources)
                    344:                            XrmMergeDataBases(userResources, &resources);
                    345:                        else
                    346:                            resources = userResources;
                    347:                        fclose(f);
                    348:                }
                    349:                strcpy(filename, pw->pw_dir);
                    350:                strcat(filename, "/.X11defaults");
                    351:                f = fopen(filename, "r");
                    352:                if (f) {
                    353:                        XrmGetDataBase(f, &userResources);
                    354:                        if (resources)
                    355:                            XrmMergeDataBases(userResources, &resources);
                    356:                        else
                    357:                            resources = userResources;
                    358:                        fclose(f);
                    359:                }
                    360:        }
                    361:        if (resources) XrmSetCurrentDataBase(resources);
                    362: }
                    363: 
                    364: 
                    365: OpenDisplay()
                    366: {
                    367:        register TScreen *screen = &term.screen;
                    368:        register int try;
                    369:        for (try = 10 ; ; ) {
                    370:            if (screen->display = XOpenDisplay(display))
                    371:                break;
                    372:            if (!get_ty) {
                    373:                fprintf(stderr, "%s: No such display server %s\n", xterm_name,
                    374:                 XDisplayName(display));
                    375:                exit(ERROR_NOX);
                    376:            }
                    377:            if (--try <= 0)  {
                    378:                fprintf (stderr, "%s: Can't connect to display server %s\n",
                    379:                 xterm_name,  XDisplayName(display));
                    380:                exit (ERROR_NOX2);
                    381:            }       
                    382:            sleep (5);
                    383:        }
                    384: 
                    385:        if (screen->display->fd > 31) {
                    386:                fprintf(stderr, 
                    387:                 "%s: Display server returned bogus file descriptor %d\n",
                    388:                  xterm_name, screen->display->fd);
                    389:                exit (ERROR_NOX3);
                    390:        };
                    391: }
                    392: 
                    393: /* ||| */
                    394: struct timeval startT, initT, endT;
                    395: struct timezone tz;
                    396: 
                    397: main (argc, argv)
                    398: int argc;
                    399: char **argv;
                    400: {
                    401:        register TScreen *screen = &term.screen;
                    402:        register int i, pty;
                    403:        int Xsocket, mode;
                    404:        char *malloc();
                    405:        char *basename();
                    406:        int xerror(), xioerror();
                    407: 
                    408:        xterm_name = (XStrCmp(*argv, "-") == 0) ? "xterm" : basename(*argv);
                    409: 
                    410: /* ||| 
                    411: gettimeofday(&startT, &tz);
                    412: */
                    413:        /* Init the Toolkit. */
                    414:        XtInitialize();
                    415: /* ||| 
                    416: gettimeofday(&initT, &tz);
                    417: */
                    418:        /* Parse the command line for resources */
                    419:        XtGetUsersDataBase();
                    420:        XrmParseCommand(optionDescList, XtNumber(optionDescList), XtNxterm,
                    421:         &argc, argv);
                    422: 
                    423:        /* Parse the rest of the command line */
                    424:        display[0] = '\0';
                    425:        for (argc--, argv++ ; argc > 0 ; argc--, argv++) {
                    426:            if (**argv == '%') {
                    427:                T_geometry = *argv;
                    428:                *T_geometry = '=';
                    429:                continue;
                    430:            }
                    431: 
                    432:            if (**argv == '#') {
                    433:                icon_geom = *argv;
                    434:                *icon_geom = '=';
                    435:                continue;
                    436:            }
                    437: 
                    438:            if(index(*argv, ':') != NULL) {
                    439:                strncpy(display, *argv, sizeof(display));
                    440:                continue;
                    441:            }
                    442: 
                    443:            if(!(i = (**argv == '-'))) Syntax (*argv);
                    444: 
                    445:            switch(argv[0][1]) {
                    446: #ifdef TIOCCONS
                    447:             case 'C':
                    448:                Console = TRUE;
                    449:                continue;
                    450: #endif TIOCCONS
                    451:             case 'L':
                    452:                {
                    453:                char tt[32];
                    454: 
                    455:                L_flag = 1;
                    456:                get_ty = argv[--argc];
                    457:                strcpy(tt,"/dev/");
                    458:                strcat(tt, get_ty);
                    459:                tt[5] = 'p';
                    460:                loginpty = open( tt, O_RDWR, 0 );
                    461:                dup2( loginpty, 4 );
                    462:                close( loginpty );
                    463:                loginpty = 4;
                    464:                tt[5] = 't';
                    465:                chown(tt, 0, 0);
                    466:                chmod(tt, 0622);
                    467:                if (open(tt, O_RDWR, 0) < 0) {
                    468:                        consolepr("open(%s) failed\n", tt);
                    469:                }
                    470:                signal(SIGHUP, SIG_IGN);
                    471:                vhangup();
                    472:                setpgrp(0,0);
                    473:                signal(SIGHUP, SIG_DFL);
                    474:                (void) close(0);
                    475:                open(tt, O_RDWR, 0);
                    476:                dup2(0, 1);
                    477:                dup2(0, 2);
                    478:                continue;
                    479:                }
                    480:             case 'S':
                    481:                sscanf(*argv + 2, "%c%c%d", passedPty, passedPty+1,
                    482:                 &am_slave);
                    483:                if (am_slave <= 0) Syntax(*argv);
                    484:                continue;
                    485: #ifdef DEBUG
                    486:             case 'D':
                    487:                debug = TRUE;
                    488:                continue;
                    489: #endif DEBUG
                    490:             case 'e':
                    491:                if (argc <= 1) Syntax (*argv);
                    492:                command_to_exec = ++argv;
                    493:                break;
                    494:             default:
                    495:                Syntax (*argv);
                    496:            }
                    497:            break;
                    498:        }
                    499: 
                    500: 
                    501:        /* Initialize the display connection */
                    502:        OpenDisplay();
                    503:        /* Get initial values from .Xdefaults file */
                    504:        XtGetResources(
                    505:            screen->display,
                    506:            resourceList,
                    507:            XtNumber(resourceList), 
                    508:            (ArgList) NULL,
                    509:            0,
                    510:            DefaultRootWindow(screen->display),
                    511:            XtNxterm,
                    512:            XtCApp,
                    513:            &nameList,
                    514:            &classList);
                    515: 
                    516: /* ||| 
                    517:     gettimeofday(&endT, &tz);
                    518:     printf("init: %8.3f,   total: %8.3f\n",
                    519:         ((initT.tv_sec*1000000.0+initT.tv_usec)
                    520:           - (startT.tv_sec*1000000.0+startT.tv_usec))/1000000.0,
                    521:         ((endT.tv_sec*1000000.0+endT.tv_usec)
                    522:           - (startT.tv_sec*1000000.0+startT.tv_usec))/1000000.0);
                    523:    exit(0);
                    524: */
                    525:        /* Do additional processing on complex .Xdefaults stuff */
                    526: 
                    527:        if (!f_n) {
                    528:                if (f_b)
                    529:                        f_n = f_b;
                    530:                else {
                    531:                        f_n = defaultFont;
                    532:                        f_b = defaultBoldFont;
                    533:                }
                    534:        }
                    535: 
                    536:        term.flags = WRAPAROUND | AUTOREPEAT;
                    537:        if (!screen->jumpscroll)        term.flags |= SMOOTHSCROLL;
                    538:        if (reverseWrap)                term.flags |= REVERSEWRAP;
                    539: 
                    540:        inhibit = 0;
                    541:        if (logInhibit)                 inhibit |= I_LOG;
                    542:        if (signalInhibit)              inhibit |= I_SIGNAL;
                    543:        if (tekInhibit)                 inhibit |= I_TEK;
                    544: 
                    545:        if (scrollbar)                  screen->scrollbar = SCROLLBARWIDTH;
                    546: 
                    547:        screen->color = 0;
                    548:        if (screen->foreground != XtDefaultFGPixel)
                    549:                screen->color |= C_FOREGROUND;
                    550:        if (screen->background != XtDefaultBGPixel) {
                    551:                screen->color |= C_BACKGROUND;
                    552:        }
                    553:        if (screen->cursorcolor != XtDefaultFGPixel)
                    554:                screen->color |= C_CURSOR;
                    555:        if (screen->mousecolor != XtDefaultFGPixel)
                    556:                screen->color |= C_MOUSE;
                    557: 
                    558:        term.initflags = term.flags;
                    559: 
                    560:        if(!window_name)
                    561:                window_name = (get_ty ? "login" : (am_slave ? "xterm slave" :
                    562:                 (command_to_exec ? basename(command_to_exec[0]) :
                    563:                 xterm_name)));
                    564:        if (!title_name)
                    565:                title_name = window_name;
                    566:        if(inhibit & I_TEK)
                    567:                screen->TekEmu = FALSE;
                    568: 
                    569:        /* set up stderr properly */
                    570:        i = -1;
                    571: #ifdef DEBUG
                    572:        if(debug)
                    573:                i = open ("xterm.debug.log", O_WRONLY | O_CREAT | O_TRUNC,
                    574:                 0666);
                    575:        else
                    576: #endif DEBUG
                    577:        if(get_ty)
                    578:                i = open("/dev/console", O_WRONLY, 0);
                    579:        if(i >= 0)
                    580:                fileno(stderr) = i;
                    581:        if(fileno(stderr) != (NOFILE - 1)) {
                    582:                dup2(fileno(stderr), (NOFILE - 1));
                    583:                if(fileno(stderr) >= 3)
                    584:                        close(fileno(stderr));
                    585:                fileno(stderr) = (NOFILE - 1);
                    586:        }
                    587: 
                    588:        signal (SIGCHLD, reapchild);
                    589: 
                    590:        /* open a terminal for client */
                    591:        get_terminal ();
                    592:        spawn ();
                    593: 
                    594:        Xsocket = screen->display->fd;
                    595:        pty = screen->respond;
                    596: 
                    597:        if (am_slave) { /* Write window id so master end can read and use */
                    598:            write(pty, screen->TekEmu ? (char *)&TWindow(screen) :
                    599:             (char *)&VWindow(screen), sizeof(Window));
                    600:            write(pty, "\n", 1);
                    601:        }
                    602: 
                    603:        if(log_on) {
                    604:                log_on = FALSE;
                    605:                StartLog(screen);
                    606:        }
                    607:        screen->inhibit = inhibit;
                    608:        mode = 1;
                    609:        if (ioctl (pty, FIONBIO, (char *)&mode) == -1) SysError (ERROR_FIONBIO);
                    610:        
                    611:        pty_mask = 1 << pty;
                    612:        X_mask = 1 << Xsocket;
                    613:        Select_mask = pty_mask | X_mask;
                    614:        max_plus1 = (pty < Xsocket) ? (1 + Xsocket) : (1 + pty);
                    615: 
                    616: #ifdef DEBUG
                    617:        if (debug) printf ("debugging on\n");
                    618: #endif DEBUG
                    619:        XSetErrorHandler(xerror);
                    620:        XSetIOErrorHandler(xioerror);
                    621:        for( ; ; )
                    622:                if(screen->TekEmu)
                    623:                        TekRun();
                    624:                else
                    625:                        VTRun();
                    626: }
                    627: 
                    628: char *basename(name)
                    629: char *name;
                    630: {
                    631:        register char *cp;
                    632:        char *rindex();
                    633: 
                    634:        return((cp = rindex(name, '/')) ? cp + 1 : name);
                    635: }
                    636: 
                    637: static char *ustring[] = {
                    638: "Usage: xterm [-132] [-b inner_border_width] [-bd border_color] \\\n",
                    639: #ifdef TIOCCONS
                    640: " [-bg backgrnd_color] [-bw border_width] [-C] [-cr cursor_color] [-cu] \\\n",
                    641: #else TIOCCONS
                    642: " [-bg backgrnd_color] [-bw border_width] [-cr cursor_color] [-cu] \\\n",
                    643: #endif TIOCCONS
                    644: " [-fb bold_font] [-fg foregrnd_color] [-fn norm_font] \\\n",
                    645: " [-i] [-j] [-l] [-lf logfile] [-ls] [-mb] [-ms mouse_color] \\\n",
                    646: " [-n name] [-nb bell_margin] [-rv] [-rw] [-s] \\\n",
                    647: " [-sb] [-si] [-sk] [-sl save_lines] [-sn] [-st] [-T title] [-t] [-tb] \\\n",
                    648: " [-vb] [=[width]x[height][[+-]xoff[[+-]yoff]]] \\\n",
                    649: " [%[width]x[height][[+-]xoff[[+-]yoff]]] [#[+-]xoff[[+-]yoff]] \\\n",
                    650: " [-e command_to_exec]\n\n",
                    651: "Fonts must be of fixed width and of same size;\n",
                    652: "If only one font is specified, it will be used for normal and bold text\n",
                    653: "The -132 option allows 80 <-> 132 column escape sequences\n",
                    654: #ifdef TIOCCONS
                    655: "The -C option forces output to /dev/console to appear in this window\n",
                    656: #endif TIOCCONS
                    657: "The -cu option turns a curses bug fix on\n",
                    658: "The -i  option enables iconic startup\n",
                    659: "The -j  option enables jump scroll\n",
                    660: "The -l  option enables logging\n",
                    661: "The -ls option makes the shell a login shell\n",
                    662: "The -mb option turns the margin bell on\n",
                    663: "The -rv option turns reverse video on\n",
                    664: "The -rw option turns reverse wraparound on\n",
                    665: "The -s  option enables asynchronous scrolling\n",
                    666: "The -sb option enables the scrollbar\n",
                    667: "The -si option disables re-positioning the scrollbar at the bottom on input\n",
                    668: "The -sk option causes the scrollbar to position at the bottom on a key\n",
                    669: "The -t  option starts Tektronix mode\n",
                    670: "The -vb option enables visual bell\n",
                    671: 0
                    672: };
                    673: 
                    674: Syntax (badOption)
                    675: char   *badOption;
                    676: {
                    677:        register char **us = ustring;
                    678: 
                    679:        fprintf(stderr, "Unknown option \"%s\"\n\n", badOption);
                    680:        while (*us) fputs(*us++, stderr);
                    681:        exit (1);
                    682: }
                    683: 
                    684: get_pty (pty, tty)
                    685: /*
                    686:    opens a pty, storing fildes in pty and tty.
                    687:  */
                    688: int *pty, *tty;
                    689: {
                    690:        int devindex, letter = 0;
                    691: 
                    692:        while (letter < 11) {
                    693:            ttydev [8] = ptydev [8] = "pqrstuvwxyz" [letter++];
                    694:            devindex = 0;
                    695: 
                    696:            while (devindex < 16) {
                    697:                ttydev [9] = ptydev [9] = "0123456789abcdef" [devindex++];
                    698:                if ((*pty = open (ptydev, O_RDWR)) < 0)
                    699:                        continue;
                    700:                if ((*tty = open (ttydev, O_RDWR)) < 0) {
                    701:                        close(*pty);
                    702:                        continue;
                    703:                }
                    704:                return;
                    705:            }
                    706:        }
                    707:        
                    708:        fprintf (stderr, "%s: Not enough available pty's\n", xterm_name);
                    709:        exit (ERROR_PTYS);
                    710: }
                    711: 
                    712: get_terminal ()
                    713: /* 
                    714:  * sets up X and initializes the terminal structure except for term.buf.fildes.
                    715:  */
                    716: {
                    717:        register TScreen *screen = &term.screen;
                    718:        char *malloc();
                    719:        
                    720:        screen->graybordertile = make_gray(screen->bordercolor,
                    721:                screen->background,
                    722:                DefaultDepth(screen->display, DefaultScreen(screen->display)));
                    723: 
                    724:        screen->arrow = make_arrow(screen->mousecolor, screen->background);
                    725: 
                    726:        XAutoRepeatOn(screen->display);
                    727: 
                    728:        if((screen->iconname = malloc((unsigned) strlen(window_name) + 10)) == NULL)
                    729:                Error(ERROR_WINNAME);
                    730:        strcpy(screen->iconname, window_name);
                    731:        screen->iconnamelen = strlen(screen->iconname);
                    732:        if((screen->titlename = malloc((unsigned) strlen(title_name) + 10)) == NULL)
                    733:                Error(ERROR_WINNAME);
                    734:        strcpy(screen->titlename, title_name);
                    735:        screen->titlenamelen = strlen(screen->titlename);
                    736: 
                    737: }
                    738: 
                    739: static char *tekterm[] = {
                    740:        "tek4015",
                    741:        "tek4014",
                    742:        "tek4013",
                    743:        "tek4010",
                    744:        "dumb",
                    745:        0
                    746: };
                    747: 
                    748: static char *vtterm[] = {
                    749:        "xterm",
                    750:        "vt102",
                    751:        "vt100",
                    752:        "ansi",
                    753:        "dumb",
                    754:        0
                    755: };
                    756: 
                    757: hungtty()
                    758: {
                    759:        longjmp(env, 1);
                    760: }
                    761: 
                    762: spawn ()
                    763: /* 
                    764:  *  Inits pty and tty and forks a login process.
                    765:  *  Does not close fd Xsocket.
                    766:  *  If getty,  execs getty rather than csh and uses std fd's rather
                    767:  *  than opening a pty/tty pair.
                    768:  *  If slave, the pty named in passedPty is already open for use
                    769:  */
                    770: {
                    771:        register TScreen *screen = &term.screen;
                    772:        int Xsocket = screen->display->fd;
                    773:        int index1, tty = -1;
                    774:        int discipline;
                    775:        unsigned lmode;
                    776:        struct tchars tc;
                    777:        struct ltchars ltc;
                    778:        struct sgttyb sg;
                    779: 
                    780:        char termcap [1024];
                    781:        char newtc [1024];
                    782:        char *ptr, *shname;
                    783:        int i, no_dev_tty = FALSE;
                    784:        char **envnew;          /* new environment */
                    785:        char buf[32];
                    786:        char *TermName = NULL;
                    787:        int ldisc = 0;
                    788: #ifdef sun
                    789: #ifdef TIOCSSIZE
                    790:        struct ttysize ts;
                    791: #endif TIOCSSIZE
                    792: #else sun
                    793: #ifdef TIOCSWINSZ
                    794:        struct winsize ws;
                    795: #endif TIOCSWINSZ
                    796: #endif sun
                    797:        struct passwd *pw = NULL;
                    798: #ifdef UTMP
                    799:        struct utmp utmp;
                    800: #endif UTMP
                    801:        extern int Exit();
                    802:        char *getenv();
                    803:        char *index (), *rindex (), *strindex ();
                    804: 
                    805:        screen->uid = getuid();
                    806:        screen->gid = getgid();
                    807: 
                    808:        /* so that TIOCSWINSZ || TIOCSIZE doesn't block */
                    809:        signal(SIGTTOU,SIG_IGN);
                    810:        if(!(screen->TekEmu ? TekInit() : VTInit()))
                    811:                exit(ERROR_INIT);
                    812: 
                    813:        if(screen->TekEmu) {
                    814:                envnew = tekterm;
                    815:                ptr = newtc;
                    816:        } else {
                    817:                envnew = vtterm;
                    818:                ptr = termcap;
                    819:        }
                    820:        while(*envnew) {
                    821:                if(tgetent(ptr, *envnew) == 1) {
                    822:                        TermName = *envnew;
                    823:                        if(!screen->TekEmu)
                    824:                            resize(screen, TermName, termcap, newtc);
                    825:                        break;
                    826:                }
                    827:                envnew++;
                    828:        }
                    829: 
                    830:        if (get_ty) {
                    831:                screen->respond = loginpty;
                    832:                if((tslot = ttyslot()) <= 0)
                    833:                        SysError(ERROR_TSLOT);
                    834:        } else if (am_slave) {
                    835:                screen->respond = am_slave;
                    836:                ptydev[8] = ttydev[8] = passedPty[0];
                    837:                ptydev[9] = ttydev[9] = passedPty[1];
                    838:                if((tslot = ttyslot()) <= 0)
                    839:                        SysError(ERROR_TSLOT2);
                    840:                setgid (screen->gid);
                    841:                setuid (screen->uid);
                    842:        } else {
                    843:                /*
                    844:                 * Sometimes /dev/tty hangs on open (as in the case of a pty
                    845:                 * that has gone away).  Simply make up some reasonable
                    846:                 * defaults.
                    847:                 */
                    848:                signal(SIGALRM, hungtty);
                    849:                alarm(1);               
                    850:                if (! setjmp(env)) {
                    851:                        tty = open ("/dev/tty", O_RDWR, 0);
                    852:                        alarm(0);
                    853:                } else {
                    854:                        tty = -1;
                    855:                        errno = ENXIO;
                    856:                }
                    857:                signal(SIGALRM, SIG_DFL);
                    858:  
                    859:                if (tty < 0) {
                    860:                        if (errno != ENXIO) SysError(ERROR_OPDEVTTY);
                    861:                        else {
                    862:                                no_dev_tty = TRUE;
                    863:                                sg = d_sg;
                    864:                                tc = d_tc;
                    865:                                discipline = d_disipline;
                    866:                                ltc = d_ltc;
                    867:                                lmode = d_lmode;
                    868:                        }
                    869:                } else {
                    870:                        /* get a copy of the current terminal's state */
                    871: 
                    872:                        if(ioctl(tty, TIOCGETP, (char *)&sg) == -1)
                    873:                                SysError (ERROR_TIOCGETP);
                    874:                        if(ioctl(tty, TIOCGETC, (char *)&tc) == -1)
                    875:                                SysError (ERROR_TIOCGETC);
                    876:                        if(ioctl(tty, TIOCGETD, (char *)&discipline) == -1)
                    877:                                SysError (ERROR_TIOCGETD);
                    878:                        if(ioctl(tty, TIOCGLTC, (char *)&ltc) == -1)
                    879:                                SysError (ERROR_TIOCGLTC);
                    880:                        if(ioctl(tty, TIOCLGET, (char *)&lmode) == -1)
                    881:                                SysError (ERROR_TIOCLGET);
                    882:                        close (tty);
                    883: 
                    884:                        /* close all std file descriptors */
                    885:                        for (index1 = 0; index1 < 3; index1++)
                    886:                                close (index1);
                    887:                        if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0)
                    888:                                SysError (ERROR_OPDEVTTY2);
                    889: 
                    890:                        if (ioctl (tty, TIOCNOTTY, (char *) NULL) == -1)
                    891:                                SysError (ERROR_NOTTY);
                    892:                        close (tty);
                    893:                }
                    894: 
                    895:                get_pty (&screen->respond, &tty);
                    896: 
                    897:                if (screen->respond != Xsocket + 1) {
                    898:                        dup2 (screen->respond, Xsocket + 1);
                    899:                        close (screen->respond);
                    900:                        screen->respond = Xsocket + 1;
                    901:                }
                    902: 
                    903:                /* change ownership of tty to real group and user id */
                    904:                chown (ttydev, screen->uid, screen->gid);
                    905: 
                    906:                /* change protection of tty */
                    907:                chmod (ttydev, 0622);
                    908: 
                    909:                if (tty != Xsocket + 2) {
                    910:                        dup2 (tty, Xsocket + 2);
                    911:                        close (tty);
                    912:                        tty = Xsocket + 2;
                    913:                }
                    914: 
                    915:                /* set the new terminal's state to be the old one's 
                    916:                   with minor modifications for efficiency */
                    917: 
                    918:                sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW);
                    919:                sg.sg_flags |= ECHO | CRMOD;
                    920:                /* make sure speed is set on pty so that editors work right*/
                    921:                sg.sg_ispeed = B9600;
                    922:                sg.sg_ospeed = B9600;
                    923:                /* reset t_brkc to default value */
                    924:                tc.t_brkc = -1;
                    925: 
                    926:                if (ioctl (tty, TIOCSETP, (char *)&sg) == -1)
                    927:                        SysError (ERROR_TIOCSETP);
                    928:                if (ioctl (tty, TIOCSETC, (char *)&tc) == -1)
                    929:                        SysError (ERROR_TIOCSETC);
                    930:                if (ioctl (tty, TIOCSETD, (char *)&discipline) == -1)
                    931:                        SysError (ERROR_TIOCSETD);
                    932:                if (ioctl (tty, TIOCSLTC, (char *)&ltc) == -1)
                    933:                        SysError (ERROR_TIOCSLTC);
                    934:                if (ioctl (tty, TIOCLSET, (char *)&lmode) == -1)
                    935:                        SysError (ERROR_TIOCLSET);
                    936: #ifdef TIOCCONS
                    937:                if (Console) {
                    938:                        int on = 1;
                    939:                        if (ioctl (tty, TIOCCONS, (char *)&on) == -1)
                    940:                                SysError(ERROR_TIOCCONS);
                    941:                }
                    942: #endif TIOCCONS
                    943: 
                    944:                close (open ("/dev/null", O_RDWR, 0));
                    945: 
                    946:                for (index1 = 0; index1 < 3; index1++)
                    947:                        dup2 (tty, index1);
                    948:                if((tslot = ttyslot()) <= 0)
                    949:                        SysError(ERROR_TSLOT3);
                    950: #ifdef UTMP
                    951:                if((pw = getpwuid(screen->uid)) &&
                    952:                 (i = open(etc_utmp, O_WRONLY)) >= 0) {
                    953:                        bzero((char *)&utmp, sizeof(struct utmp));
                    954:                        (void) strcpy(utmp.ut_line, &ttydev[5]);
                    955:                        (void) strcpy(utmp.ut_name, pw->pw_name);
                    956:                        (void) strcpy(utmp.ut_host, XDisplayName(display));
                    957:                        time(&utmp.ut_time);
                    958:                        lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
                    959:                        write(i, (char *)&utmp, sizeof(struct utmp));
                    960:                        close(i);
                    961:                } else
                    962:                        tslot = -tslot;
                    963: #endif UTMP
                    964:        }
                    965: 
                    966: #ifdef sun
                    967: #ifdef TIOCSSIZE
                    968:        /* tell tty how big window is */
                    969:        if(screen->TekEmu) {
                    970:                ts.ts_lines = 38;
                    971:                ts.ts_cols = 81;
                    972:        } else {
                    973:                ts.ts_lines = screen->max_row + 1;
                    974:                ts.ts_cols = screen->max_col + 1;
                    975:        }
                    976:        ioctl  (screen->respond, TIOCSSIZE, &ts);
                    977: #endif TIOCSSIZE
                    978: #else sun
                    979: #ifdef TIOCSWINSZ
                    980:        /* tell tty how big window is */
                    981:        if(screen->TekEmu) {
                    982:                ws.ws_row = 38;
                    983:                ws.ws_col = 81;
                    984:                ws.ws_xpixel = TFullWidth(screen);
                    985:                ws.ws_ypixel = TFullHeight(screen);
                    986:        } else {
                    987:                ws.ws_row = screen->max_row + 1;
                    988:                ws.ws_col = screen->max_col + 1;
                    989:                ws.ws_xpixel = FullWidth(screen);
                    990:                ws.ws_ypixel = FullHeight(screen);
                    991:        }
                    992:        ioctl (screen->respond, TIOCSWINSZ, (char *)&ws);
                    993: #endif TIOCSWINSZ
                    994: #endif sun
                    995: 
                    996:        if (!am_slave) {
                    997:            if ((screen->pid = fork ()) == -1)
                    998:                SysError (ERROR_FORK);
                    999:                
                   1000:            if (screen->pid == 0) {
                   1001:                extern char **environ;
                   1002:                int pgrp = getpid();
                   1003: 
                   1004:                close (Xsocket);
                   1005:                close (screen->respond);
                   1006:                if(fileno(stderr) >= 3)
                   1007:                        close (fileno(stderr));
                   1008: 
                   1009:                if (tty >= 0) close (tty);
                   1010: 
                   1011:                signal (SIGCHLD, SIG_DFL);
                   1012:                signal (SIGHUP, SIG_IGN);
                   1013: 
                   1014:                /* copy the environment before Setenving */
                   1015:                for (i = 0 ; environ [i] != NULL ; i++) ;
                   1016:                /*
                   1017:                 * The `4' is the number of Setenv() calls which may add
                   1018:                 * a new entry to the environment.  The `1' is for the
                   1019:                 * NULL terminating entry.
                   1020:                 */
                   1021:                envnew = (char **) calloc ((unsigned) i + (4 + 1), sizeof(char *));
                   1022:                bcopy((char *)environ, (char *)envnew, i * sizeof(char *));
                   1023:                environ = envnew;
                   1024:                Setenv ("TERM=", TermName);
                   1025:                if(!TermName)
                   1026:                        *newtc = 0;
                   1027:                Setenv ("TERMCAP=", newtc);
                   1028:                sprintf(buf, "%d", screen->TekEmu ? (int)TWindow(screen) :
                   1029:                 (int)VWindow(screen));
                   1030:                Setenv ("WINDOWID=", buf);
                   1031:                /* put the display into the environment of the shell*/
                   1032:                if (display[0] != '\0') 
                   1033:                        Setenv ("DISPLAY=", XDisplayName(display));
                   1034: 
                   1035:                signal(SIGTERM, SIG_DFL);
                   1036:                ioctl(0, TIOCSPGRP, (char *)&pgrp);
                   1037:                setpgrp (0, 0);
                   1038:                close(open(ttyname(0), O_WRONLY, 0));
                   1039:                setpgrp (0, pgrp);
                   1040: 
                   1041:                setgid (screen->gid);
                   1042:                setuid (screen->uid);
                   1043: 
                   1044:                if (command_to_exec) {
                   1045:                        execvp(*command_to_exec, command_to_exec);
                   1046:                        /* print error message on screen */
                   1047:                        fprintf(stderr, "%s: Can't execvp %s\n", xterm_name,
                   1048:                         *command_to_exec);
                   1049:                }
                   1050:                signal(SIGHUP, SIG_IGN);
                   1051:                if (get_ty) {
                   1052:                        ioctl (0, TIOCNOTTY, (char *) NULL);
                   1053:                        execl ("/etc/getty", "+", "Xwindow", get_ty, 0);
                   1054:                }
                   1055:                signal(SIGHUP, SIG_DFL);
                   1056: 
                   1057: #ifdef UTMP
                   1058:                if(((ptr = getenv("SHELL")) == NULL || *ptr == 0) &&
                   1059:                 ((pw == NULL && (pw = getpwuid(screen->uid)) == NULL) ||
                   1060:                 *(ptr = pw->pw_shell) == 0))
                   1061: #else UTMP
                   1062:                if(((ptr = getenv("SHELL")) == NULL || *ptr == 0) &&
                   1063:                 ((pw = getpwuid(screen->uid)) == NULL ||
                   1064:                 *(ptr = pw->pw_shell) == 0))
                   1065: #endif UTMP
                   1066:                        ptr = "/bin/sh";
                   1067:                if(shname = rindex(ptr, '/'))
                   1068:                        shname++;
                   1069:                else
                   1070:                        shname = ptr;
                   1071:                ldisc = XStrCmp("csh", shname + strlen(shname) - 3) == 0 ?
                   1072:                 NTTYDISC : 0;
                   1073:                ioctl(0, TIOCSETD, (char *)&ldisc);
                   1074:                execl (ptr, login_shell ? "-" : shname, 0);
                   1075:                fprintf (stderr, "%s: Could not exec %s!\n", xterm_name, ptr);
                   1076:                sleep(5);
                   1077:                exit(ERROR_EXEC);
                   1078:            }
                   1079:        }
                   1080: 
                   1081:        if(tty >= 0) close (tty);
                   1082:        signal(SIGHUP,SIG_IGN);
                   1083: 
                   1084:        if (!no_dev_tty) {
                   1085:                if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0)
                   1086:                        SysError(ERROR_OPDEVTTY3);
                   1087:                for (index1 = 0; index1 < 3; index1++)
                   1088:                        dup2 (tty, index1);
                   1089:                if (tty > 2) close (tty);
                   1090:        }
                   1091: 
                   1092:        signal(SIGINT, Exit); 
                   1093:        signal(SIGQUIT, Exit);
                   1094:        signal(SIGTERM, Exit);
                   1095: }
                   1096: 
                   1097: Exit(n)
                   1098: int n;
                   1099: {
                   1100:        register TScreen *screen = &term.screen;
                   1101:         int pty = term.screen.respond;  /* file descriptor of pty */
                   1102: #ifdef UTMP
                   1103:        register int i;
                   1104:        struct utmp utmp;
                   1105: 
                   1106:        if(!am_slave && tslot > 0 && (i = open(etc_utmp, O_WRONLY)) >= 0) {
                   1107:                bzero((char *)&utmp, sizeof(struct utmp));
                   1108:                lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
                   1109:                write(i, (char *)&utmp, sizeof(struct utmp));
                   1110:                close(i);
                   1111:        }
                   1112: #endif UTMP
                   1113:         close(pty); /* close explicitly to avoid race with slave side */
                   1114:        if(screen->logging)
                   1115:                CloseLog(screen);
                   1116: 
                   1117:        if(!get_ty && !am_slave) {
                   1118:                /* restore ownership of tty */
                   1119:                chown (ttydev, 0, 0);
                   1120: 
                   1121:                /* restore modes of tty */
                   1122:                chmod (ttydev, 0666);
                   1123:        }
                   1124:        exit(n);
                   1125: }
                   1126: 
                   1127: resize(screen, TermName, oldtc, newtc)
                   1128: TScreen *screen;
                   1129: char *TermName;
                   1130: register char *oldtc, *newtc;
                   1131: {
                   1132:        register char *ptr1, *ptr2;
                   1133:        register int i;
                   1134:        register int li_first = 0;
                   1135:        register char *temp;
                   1136:        char *index(), *strindex();
                   1137: 
                   1138:        if ((ptr1 = strindex (oldtc, "co#")) == NULL){
                   1139:                fprintf(stderr, "%s: Can't find co# in termcap string %s\n",
                   1140:                        xterm_name, TermName);
                   1141:                exit (ERROR_NOCO);
                   1142:        }
                   1143:        if ((ptr2 = strindex (oldtc, "li#")) == NULL){
                   1144:                fprintf(stderr, "%s: Can't find li# in termcap string %s\n",
                   1145:                        xterm_name, TermName);
                   1146:                exit (ERROR_NOLI);
                   1147:        }
                   1148:        if(ptr1 > ptr2) {
                   1149:                li_first++;
                   1150:                temp = ptr1;
                   1151:                ptr1 = ptr2;
                   1152:                ptr2 = temp;
                   1153:        }
                   1154:        ptr1 += 3;
                   1155:        ptr2 += 3;
                   1156:        strncpy (newtc, oldtc, i = ptr1 - oldtc);
                   1157:        newtc += i;
                   1158:        sprintf (newtc, "%d", li_first ? screen->max_row + 1 :
                   1159:         screen->max_col + 1);
                   1160:        newtc += strlen(newtc);
                   1161:        ptr1 = index (ptr1, ':');
                   1162:        strncpy (newtc, ptr1, i = ptr2 - ptr1);
                   1163:        newtc += i;
                   1164:        sprintf (newtc, "%d", li_first ? screen->max_col + 1 :
                   1165:         screen->max_row + 1);
                   1166:        ptr2 = index (ptr2, ':');
                   1167:        strcat (newtc, ptr2);
                   1168: }
                   1169: 
                   1170: static reapchild ()
                   1171: {
                   1172:        union wait status;
                   1173:        register int pid;
                   1174:        
                   1175: #ifdef DEBUG
                   1176:        if (debug) fputs ("Exiting\n", stderr);
                   1177: #endif DEBUG
                   1178:        pid  = wait3 (&status, WNOHANG, (struct rusage *)NULL);
                   1179:        if (!pid) return;
                   1180:        if (pid != term.screen.pid) return;
                   1181:        
                   1182:        Cleanup(0);
                   1183: }
                   1184: 
                   1185: /* VARARGS1 */
                   1186: consolepr(fmt,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
                   1187: char *fmt;
                   1188: {
                   1189:        extern int errno;
                   1190:        extern char *sys_errlist[];
                   1191:        int oerrno;
                   1192:        int f;
                   1193:        char buf[ BUFSIZ ];
                   1194: 
                   1195:        oerrno = errno;
                   1196:        strcpy(buf, "xterm: ");
                   1197:        sprintf(buf+strlen(buf), fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
                   1198:        strcat(buf, ": ");
                   1199:        strcat(buf, sys_errlist[oerrno]);
                   1200:        strcat(buf, "\n");      
                   1201:        f = open("/dev/console",O_WRONLY);
                   1202:        write(f, buf, strlen(buf));
                   1203:        close(f);
                   1204:        if ((f = open("/dev/tty", 2)) >= 0) {
                   1205:                ioctl(f, TIOCNOTTY, (char *)NULL);
                   1206:                close(f);
                   1207:        }
                   1208: }
                   1209: 
                   1210: checklogin()
                   1211: {
                   1212:        register int ts, i;
                   1213:        register struct passwd *pw;
                   1214:        struct utmp utmp;
                   1215: 
                   1216:        ts = tslot > 0 ? tslot : -tslot;
                   1217:        if((i = open(etc_utmp, O_RDONLY)) < 0)
                   1218:                return(FALSE);
                   1219:        lseek(i, (long)(ts * sizeof(struct utmp)), 0);
                   1220:        ts = read(i, (char *)&utmp, sizeof(utmp));
                   1221:        close(i);
                   1222:        if(ts != sizeof(utmp) || XStrCmp(get_ty, utmp.ut_line) != 0 ||
                   1223:         !*utmp.ut_name || (pw = getpwnam(utmp.ut_name)) == NULL)
                   1224:                return(FALSE);
                   1225:        chdir(pw->pw_dir);
                   1226:        setgid(pw->pw_gid);
                   1227:        setuid(pw->pw_uid);
                   1228:        L_flag = 0;
                   1229:        return(TRUE);
                   1230: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.