home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume9 / xterm / part05 / main.c next >
Encoding:
C/C++ Source or Header  |  1987-04-20  |  34.0 KB  |  1,495 lines

  1. /*
  2.  *    $Source: /u1/X/xterm/RCS/main.c,v $
  3.  *    $Header: main.c,v 10.101 86/12/01 16:58:10 swick Rel $
  4.  */
  5.  
  6. #include <X/mit-copyright.h>
  7.  
  8. /* Copyright    Massachusetts Institute of Technology    1984, 1985    */
  9.  
  10. /* main.c */
  11.  
  12. #ifndef lint
  13. static char sccs_id[] = "@(#)main.c\tX10/6.6B\t12/28/86";
  14. #endif    lint
  15.  
  16. #include <pwd.h>
  17. #include <sgtty.h>
  18. #include <sys/wait.h>
  19. #include <sys/time.h>
  20. #include <sys/resource.h>
  21. #include <stdio.h>
  22. #include <sys/file.h>
  23. #include <errno.h>
  24. #include <signal.h>
  25. #include <strings.h>
  26. #include <setjmp.h>
  27. #include <utmp.h>
  28. #include <sys/param.h>    /* for NOFILE */
  29. #include <X/Xlib.h>
  30. #include "scrollbar.h"
  31. #include "ptyx.h"
  32. #include "data.h"
  33. #include "error.h"
  34. #include "main.h"
  35.  
  36. int switchfb[] = {0, 2, 1, 3};
  37.  
  38. static int reapchild ();
  39.  
  40. static char *brdr_color;
  41. static char **command_to_exec;
  42. #ifdef TIOCCONS
  43. static int Console;
  44. #endif TIOCCONS
  45. static struct  sgttyb d_sg = {
  46.         0, 0, 0177, CKILL, EVENP|ODDP|ECHO|XTABS|CRMOD
  47. };
  48. static struct  tchars d_tc = {
  49.         CINTR, CQUIT, CSTART,
  50.         CSTOP, CEOF, CBRK,
  51. };
  52. static struct  ltchars d_ltc = {
  53.         CSUSP, CDSUSP, CRPRNT,
  54.         CFLUSH, CWERASE, CLNEXT
  55. };
  56. static int d_disipline = NTTYDISC;
  57. static int d_lmode = LCRTBS|LCRTERA|LCRTKIL|LCTLECH;
  58. static char def_bold_font[] = DEFBOLDFONT;
  59. static char def_font[] = DEFFONT;
  60. static char def_title_font[] = DEFTITLEFONT;
  61. static char def_icon_font[] = DEFICONFONT;
  62. static char display[256];
  63. static char etc_utmp[] = "/etc/utmp";
  64. static char *get_ty;
  65. static char *iconbitmap;
  66. static int inhibit;
  67. static int log_on;
  68. static int login_shell;
  69. static char passedPty[2];    /* name if pty if slave */
  70. static int loginpty;
  71. static char *tekiconbitmap;
  72. static int tslot;
  73. static char *xdef[] = {
  74.     "ActiveIcon",        /* DEF_ACTIVEICON */
  75.     "AllowIconInput",    /* DEF_ALLOWICONINPUT */
  76.     "AutoRaise",        /* DEF_AUTORAISE */
  77.     "Background",        /* DEF_BACKGROUND */
  78.     "BodyFont",        /* DEF_BODYFONT */
  79.     "BoldFont",        /* DEF_BOLDFONT */
  80.     "Border",        /* DEF_BORDER */
  81.     "BorderWidth",        /* DEF_BORDERWIDTH */
  82.     "C132",            /* DEF_C132 */
  83.     "Curses",        /* DEF_CURSES */
  84.     "Cursor",        /* DEF_CURSOR */
  85.     "DeiconifyWarp",    /* DEF_DEICONWARP */
  86.     "Foreground",        /* DEF_FOREGROUND */
  87.     "IconBitmap",        /* DEF_ICONBITMAP */
  88.     "IconFont",        /* DEF_ICONFONT */
  89.     "IconStartup",        /* DEF_ICONSTARTUP */
  90.     "InternalBorder",    /* DEF_INTERNALBORDER */
  91.     "JumpScroll",        /* DEF_JUMPSCROLL */
  92. #ifdef KEYBD
  93.     "KeyBoard",        /* DEF_KEYBOARD */
  94. #endif KEYBD
  95.     "LogFile",        /* DEF_LOGFILE */
  96.     "Logging",        /* DEF_LOGGING */
  97.     "LogInhibit",        /* DEF_LOGINHIBIT */
  98.     "LoginShell",        /* DEF_LOGINSHELL */
  99.     "MarginBell",        /* DEF_MARGINBELL */
  100.     "Mouse",        /* DEF_MOUSE */
  101.     "NMarginBell",        /* DEF_NMARGINBELL */
  102.     "PageOverlap",        /* DEF_PAGEOVERLAP */
  103.     "PageScroll",        /* DEF_PAGESCROLL */
  104.     "ReverseVideo",        /* DEF_REVERSEVIDEO */
  105.     "ReverseWrap",        /* DEF_REVERSEWRAP */
  106.     "SaveLines",        /* DEF_SAVELINES */
  107.     "ScrollBar",        /* DEF_SCROLLBAR */
  108.     "ScrollInput",        /* DEF_SCROLLINPUT */
  109.     "ScrollKey",        /* DEF_SCROLLKEY */
  110.     "SignalInhibit",    /* DEF_SIGNALINHIBIT */
  111.     "StatusLine",        /* DEF_STATUSLINE */
  112.     "StatusNormal",        /* DEF_STATUSNORMAL */
  113.     "TekIconBitmap",    /* DEF_TEKICONBITMAP */
  114.     "TekInhibit",        /* DEF_TEKINHIBIT */
  115.     "TextUnderIcon",    /* DEF_TEXTUNDERICON */
  116.     "TitleBar",        /* DEF_TITLEBAR */
  117.     "TitleFont",        /* DEF_TITLEFONT */
  118.     "VisualBell",        /* DEF_VISUALBELL */
  119.     0,
  120. };
  121. #ifdef UTMP
  122. static int added_utmp_entry;
  123. #endif UTMP
  124.  
  125. main (argc, argv)
  126. int argc;
  127. char **argv;
  128. {
  129.     register Screen *screen = &term.screen;
  130.     register char *strind;
  131.     register int i, pty;
  132.     register char **cp;
  133.     short fnflag = 0;    /* True iff -fn option used */
  134.     short fbflag = 0;    /* True iff -fb option used */
  135.     int Xsocket, mode;
  136.     extern onalarm();
  137.     char *malloc();
  138.     char *basename();
  139.     int xerror(), xioerror();
  140. #ifdef KEYBD
  141.     extern char *keyboardtype;    /* used in XKeyBind.c */
  142.     char *getenv();
  143. #endif KEYBD
  144.  
  145.     xterm_name = (strcmp(*argv, "-") == 0) ? "xterm" : basename(*argv);
  146.  
  147.     term.flags = WRAPAROUND | SMOOTHSCROLL | AUTOREPEAT;
  148.     screen->border = DEFBORDER;
  149.     screen->borderwidth = DEFBORDERWIDTH;
  150.     screen->reversestatus = TRUE;
  151.     screen->mappedVwin = &screen->fullVwin;
  152.     screen->mappedTwin = &screen->fullTwin;
  153.     f_b = def_bold_font;
  154.     f_n = def_font;
  155.     f_t = def_title_font;
  156.     f_i = def_icon_font;
  157.  
  158.     display[0] = '\0';
  159. #ifdef KEYBD
  160.     if((strind = getenv("KEYBD")) && *strind) {
  161.         if((keyboardtype = malloc(strlen(strind) + 1)) == NULL)
  162.             SysError(ERROR_KMALLOC);
  163.         strcpy(keyboardtype, strind);
  164.     }
  165. #endif KEYBD
  166.  
  167.     /*
  168.      * go get options out of default file
  169.      */
  170.     for(i = 0, cp = xdef ; *cp ; i++, cp++) {
  171.         if(!(strind = XGetDefault(xterm_name, *cp)))
  172.             continue;
  173.         switch(i) {
  174.          case DEF_ACTIVEICON:
  175.             if (strcmp (strind, "on") == 0)
  176.                 screen->active_icon = TRUE;
  177.             continue;
  178.          case DEF_ALLOWICONINPUT:
  179.              if (strcmp (strind, "on") == 0)
  180.                     term.flags |= ICONINPUT;
  181.             continue;
  182.          case DEF_AUTORAISE:
  183.             if (strcmp (strind, "on") == 0) 
  184.                 screen->autoraise = TRUE;
  185.             continue;
  186.          case DEF_BACKGROUND:
  187.             back_color = strind;
  188.             continue;
  189.          case DEF_BODYFONT:
  190.             f_n = strind;
  191.             fnflag = TRUE;
  192.             continue;
  193.          case DEF_BOLDFONT:
  194.             f_b = strind;
  195.             fbflag = TRUE;
  196.             continue;
  197.          case DEF_BORDER:
  198.             brdr_color = strind;
  199.             continue;
  200.          case DEF_BORDERWIDTH:
  201.             screen->borderwidth = atoi (strind);
  202.             continue;
  203.          case DEF_C132:
  204.             if (strcmp (strind, "on") == 0) 
  205.                 screen->c132 = TRUE;
  206.             continue;
  207.          case DEF_CURSES:
  208.             if (strcmp (strind, "on") == 0) 
  209.                 screen->curses = TRUE;
  210.             continue;
  211.          case DEF_CURSOR:
  212.             curs_color = strind;
  213.             continue;
  214.          case DEF_DEICONWARP:
  215.             if (strcmp (strind, "on") == 0)
  216.                 screen->deiconwarp = TRUE;
  217.             continue;
  218.          case DEF_FOREGROUND:
  219.             fore_color = strind;
  220.             continue;
  221.          case DEF_ICONBITMAP:
  222.             iconbitmap = strind;
  223.             continue;
  224.          case DEF_ICONFONT:
  225.              f_i = strind;
  226.             continue;
  227.          case DEF_ICONSTARTUP:
  228.             if (strcmp (strind, "on") == 0)
  229.                 screen->icon_show = -1;
  230.             continue;
  231.          case DEF_INTERNALBORDER:
  232.             screen->border = atoi (strind);
  233.             continue;
  234.          case DEF_JUMPSCROLL:
  235.             if (strcmp (strind, "on") == 0) {
  236.                 screen->jumpscroll = TRUE;
  237.                 term.flags &= ~SMOOTHSCROLL;
  238.             }
  239.             continue;
  240. #ifdef KEYBD
  241.          case DEF_KEYBOARD:
  242.             if(keyboardtype)
  243.                 free(keyboardtype);
  244.             keyboardtype = strind;
  245.             continue;
  246. #endif KEYBD
  247.          case DEF_LOGFILE:
  248.             if(screen->logfile = malloc(strlen(strind) + 1))
  249.                 strcpy(screen->logfile, strind);
  250.             continue;
  251.          case DEF_LOGGING:
  252.             if (strcmp (strind, "on") == 0) 
  253.                 log_on = TRUE;
  254.             continue;
  255.          case DEF_LOGINHIBIT:
  256.             if (strcmp (strind, "on") == 0) 
  257.                 inhibit |= I_LOG;
  258.             continue;
  259.          case DEF_LOGINSHELL:
  260.             if (strcmp (strind, "on") == 0) 
  261.                 login_shell = TRUE;
  262.             continue;
  263.          case DEF_MARGINBELL:
  264.             if (strcmp (strind, "on") == 0) 
  265.                 screen->marginbell = TRUE;
  266.             continue;
  267.          case DEF_MOUSE:
  268.             mous_color = strind;
  269.             continue;
  270.          case DEF_NMARGINBELL:
  271.             n_marginbell = atoi (strind);
  272.             continue;
  273.          case DEF_PAGEOVERLAP:
  274.             if((screen->pageoverlap = atoi (strind) - 1) < 0)
  275.                 screen->pageoverlap = -1;
  276.             continue;
  277.          case DEF_PAGESCROLL:
  278.             if (strcmp (strind, "on") == 0)
  279.                 screen->pagemode = TRUE;
  280.             continue;
  281.          case DEF_REVERSEVIDEO:
  282.             if (strcmp (strind, "on") == 0)
  283.                 re_verse = TRUE;
  284.             continue;
  285.          case DEF_REVERSEWRAP:
  286.             if (strcmp (strind, "on") == 0) 
  287.                 term.flags |= REVERSEWRAP;
  288.             continue;
  289.          case DEF_SAVELINES:
  290.             save_lines = atoi (strind);
  291.             continue;
  292.          case DEF_SCROLLBAR:
  293.             if (strcmp (strind, "on") == 0) 
  294.                 screen->scrollbar = SCROLLBARWIDTH;
  295.             continue;
  296.          case DEF_SCROLLINPUT:
  297.             if (strcmp (strind, "on") == 0) 
  298.                 screen->scrollinput = TRUE;
  299.             continue;
  300.          case DEF_SCROLLKEY:
  301.             if (strcmp (strind, "on") == 0) 
  302.                 screen->scrollkey = TRUE;
  303.             continue;
  304.          case DEF_SIGNALINHIBIT:
  305.             if (strcmp (strind, "on") == 0) 
  306.                 inhibit |= I_SIGNAL;
  307.             continue;
  308.          case DEF_STATUSLINE:
  309.             if (strcmp (strind, "on") == 0) 
  310.                 screen->statusline = TRUE;
  311.             continue;
  312.          case DEF_STATUSNORMAL:
  313.             screen->reversestatus = (strcmp (strind, "on") != 0);
  314.             continue;
  315.          case DEF_TEKICONBITMAP:
  316.             tekiconbitmap = strind;
  317.             continue;
  318.          case DEF_TEKINHIBIT:
  319.             if (strcmp (strind, "on") == 0) 
  320.                 inhibit |= I_TEK;
  321.             continue;
  322.          case DEF_TEXTUNDERICON:
  323.             if (strcmp (strind, "on") == 0) 
  324.                 screen->textundericon = TRUE;
  325.             continue;
  326.          case DEF_TITLEBAR:
  327.             if (strcmp (strind, "on") == 0) 
  328.                 screen->fullVwin.titlebar = TRUE;
  329.             continue;
  330.          case DEF_TITLEFONT:
  331.             f_t = strind;
  332.             continue;
  333.          case DEF_VISUALBELL:
  334.             if (strcmp (strind, "on") == 0) 
  335.                 screen->visualbell = TRUE;
  336.             continue;
  337.         }
  338.     }
  339.  
  340.     /* parse command line */
  341.     
  342.     for (argc--, argv++ ; argc > 0 ; argc--, argv++) {
  343.         if (**argv == '=') {
  344.         geo_metry = *argv;
  345.         continue;
  346.         }
  347.  
  348.         if (**argv == '%') {
  349.         T_geometry = *argv;
  350.         *T_geometry = '=';
  351.         continue;
  352.         }
  353.  
  354.         if (**argv == '#') {
  355.         icon_geom = *argv;
  356.         *icon_geom = '=';
  357.         continue;
  358.         }
  359.  
  360.         if((strind = index (*argv, ':')) != NULL) {
  361.         strncpy(display, *argv, sizeof(display));
  362.         continue;
  363.         }
  364.  
  365.         if(!(i = (**argv == '-')) && **argv != '+') Syntax ();
  366.  
  367.         switch(argument(&(*argv)[1])) {
  368.          case ARG_132:
  369.         screen->c132 = i;
  370.         continue;
  371. #ifdef TIOCCONS
  372.          case ARG__C:
  373.         Console = i;
  374.         continue;
  375. #endif TIOCCONS
  376.          case ARG__L:
  377.         {
  378.         char tt[32];
  379.  
  380.         L_flag = 1;
  381.         get_ty = argv[--argc];
  382.         strcpy(tt,"/dev/");
  383.         strcat(tt, get_ty);
  384.         tt[5] = 'p';
  385.         loginpty = open( tt, O_RDWR, 0 );
  386.         dup2( loginpty, 4 );
  387.         close( loginpty );
  388.         loginpty = 4;
  389.         tt[5] = 't';
  390.         chown(tt, 0, 0);
  391.         chmod(tt, 0622);
  392.         if (open(tt, O_RDWR) < 0) {
  393.             consolepr("open failed\n");
  394.         }
  395.         signal(SIGHUP, SIG_IGN);
  396.         vhangup();
  397.         setpgrp(0,0);
  398.         signal(SIGHUP, SIG_DFL);
  399.         (void) close(0);
  400.         open(tt, O_RDWR, 0);
  401.         dup2(0, 1);
  402.         dup2(0, 2);
  403.         continue;
  404.         }
  405.          case ARG__S:
  406.         if(i) {
  407.             if (--argc <= 0) Syntax ();
  408.             sscanf(*++argv, "%c%c%d", passedPty, passedPty+1,
  409.              &am_slave);
  410.             if (am_slave <= 0) Syntax();
  411.         } else
  412.             am_slave = 0;
  413.         continue;
  414.          case ARG_AI:
  415.             screen->active_icon = i;
  416.         continue;
  417.          case ARG_AR:
  418.         screen->autoraise = i;
  419.         continue;
  420.          case ARG_B:
  421.         if(i) {
  422.             if (--argc <= 0) Syntax ();
  423.             screen->border = atoi (*++argv);
  424.         } else
  425.             screen->border = DEFBORDER;
  426.         continue;
  427.          case ARG_BD:
  428.         if(i) {
  429.             if (--argc <= 0) Syntax ();
  430.             brdr_color = *++argv;
  431.         } else
  432.             brdr_color = NULL;
  433.         continue;
  434.          case ARG_BG:
  435.         if(i) {
  436.             if (--argc <= 0) Syntax ();
  437.             back_color = *++argv;
  438.         } else
  439.             back_color = NULL;
  440.         continue;
  441.          case ARG_BW:
  442.         if(i) {
  443.             if (--argc <= 0) Syntax ();
  444.             screen->borderwidth = atoi (*++argv);
  445.         } else
  446.             screen->borderwidth = DEFBORDERWIDTH;
  447.         continue;
  448.          case ARG_CR:
  449.         if(i) {
  450.             if (--argc <= 0) Syntax ();
  451.             curs_color = *++argv;
  452.         } else
  453.             curs_color = NULL;
  454.         continue;
  455.          case ARG_CU:
  456.         screen->curses = i;
  457.         continue;
  458. #ifdef DEBUG
  459.          case ARG_D:
  460.         debug = i;
  461.         continue;
  462. #endif DEBUG
  463.          case ARG_DW:
  464.         screen->deiconwarp = i;
  465.         continue;
  466.          case ARG_E:
  467.          if(!i) Syntax();
  468.         if (argc <= 1) Syntax ();
  469.         command_to_exec = ++argv;
  470.         break;
  471.          case ARG_FB:
  472.         if(fbflag = i) {
  473.             if (--argc <= 0) Syntax ();
  474.             f_b = *++argv;
  475.             fbflag = TRUE;
  476.         } else {
  477.             f_b = def_bold_font;
  478.             fbflag = FALSE;
  479.         }
  480.         continue;
  481.          case ARG_FG:
  482.         if(i) {
  483.             if (--argc <= 0) Syntax ();
  484.             fore_color = *++argv;
  485.         } else
  486.             fore_color = NULL;
  487.         continue;
  488.          case ARG_FI:
  489.             if (i) {
  490.             if (--argc <= 0) Syntax();
  491.             f_i = *++argv;
  492.         } else
  493.             f_i = def_icon_font;
  494.         continue;
  495.          case ARG_FN:
  496.         if(fnflag = i) {
  497.             if (--argc <= 0) Syntax ();
  498.             f_n = *++argv;
  499.             fnflag = TRUE;
  500.         } else {
  501.             f_n = def_font;
  502.             fnflag = FALSE;
  503.         }
  504.         continue;
  505.          case ARG_FT:
  506.         if(i) {
  507.             if (--argc <= 0) Syntax ();
  508.             f_t = *++argv;
  509.         } else
  510.             f_t = def_title_font;
  511.         continue;
  512.          case ARG_I:
  513.         screen->icon_show = i ? -1 : 0;
  514.         continue;
  515.          case ARG_IB:
  516.         if(i) {
  517.             if (--argc <= 0) Syntax ();
  518.             iconbitmap = *++argv;
  519.         } else
  520.             iconbitmap = NULL;
  521.         continue;
  522.          case ARG_IT:
  523.         if(i) {
  524.             if (--argc <= 0) Syntax ();
  525.             tekiconbitmap = *++argv;
  526.         } else
  527.             tekiconbitmap = NULL;
  528.         continue;
  529.          case ARG_J:
  530.         if(screen->jumpscroll = i)
  531.             term.flags &= ~SMOOTHSCROLL;
  532.         else
  533.             term.flags |= SMOOTHSCROLL;
  534.         continue;
  535. #ifdef KEYBD
  536.          case ARG_K:
  537.         if(i) {
  538.             if (--argc <= 0) Syntax ();
  539.             keyboardtype = *++argv;
  540.         } else
  541.             keyboardtype = NULL;
  542.         continue;
  543. #endif KEYBD
  544.          case ARG_L:
  545.         log_on = i;
  546.         continue;
  547.          case ARG_LF:
  548.         if(screen->logfile)
  549.             free(screen->logfile);
  550.         if(i) {
  551.             if (--argc <= 0) Syntax ();
  552.             if(screen->logfile = malloc(strlen(*++argv) + 1))
  553.                 strcpy(screen->logfile, *argv);
  554.         } else
  555.             screen->logfile = NULL;
  556.         continue;
  557.          case ARG_LS:
  558.         login_shell = i;
  559.         continue;
  560.          case ARG_MB:
  561.         screen->marginbell = i;
  562.         continue;
  563.          case ARG_MS:
  564.         if(i) {
  565.             if (--argc <= 0) Syntax ();
  566.             mous_color = *++argv;
  567.         } else
  568.             mous_color = NULL;
  569.         continue;
  570.          case ARG_N:
  571.         if(i) {
  572.             if (--argc <= 0) Syntax ();
  573.             win_name = *++argv;
  574.         } else
  575.             win_name = NULL;
  576.         continue;
  577.          case ARG_NB:
  578.         if(i) {
  579.             if (--argc <= 0) Syntax ();
  580.             n_marginbell = atoi (*++argv);
  581.         } else
  582.             n_marginbell = N_MARGINBELL;
  583.         continue;
  584.          case ARG_PO:
  585.         if(i) {
  586.             if (--argc <= 0) Syntax ();
  587.             if((screen->pageoverlap = atoi (*++argv) - 1) < 0)
  588.             screen->pageoverlap = -1;
  589.         } else
  590.             screen->pageoverlap = 0;
  591.         continue;
  592.          case ARG_PS:
  593.         screen->pagemode = i;
  594.         continue;
  595.          case ARG_RV:
  596.         re_verse = i;
  597.         continue;
  598.          case ARG_RW:
  599.         if(i)
  600.             term.flags |= REVERSEWRAP;
  601.         else
  602.             term.flags &= ~REVERSEWRAP;
  603.         continue;
  604.          case ARG_S:
  605.         screen->multiscroll = i;
  606.         continue;
  607.          case ARG_SB:
  608.         screen->scrollbar = i ? SCROLLBARWIDTH : 0;
  609.         continue;
  610.          case ARG_SI:
  611.         screen->scrollinput = i;
  612.         continue;
  613.          case ARG_SK:
  614.         screen->scrollkey = i;
  615.         continue;
  616.          case ARG_SL:
  617.         if(i) {
  618.             if (--argc <= 0) Syntax ();
  619.             save_lines = atoi (*++argv);
  620.         } else
  621.             save_lines = SAVELINES;
  622.         continue;
  623.          case ARG_SN:
  624.         screen->reversestatus = !i;
  625.         continue;
  626.          case ARG_ST:
  627.         screen->statusline = i;
  628.         continue;
  629.          case ARG_T:
  630.         screen->TekEmu = i;
  631.         continue;
  632.          case ARG_TB:
  633.         screen->fullVwin.titlebar = i;
  634.         continue;
  635.          case ARG_TI:
  636.         screen->textundericon = i;
  637.         continue;
  638.          case ARG_VB:
  639.         screen->visualbell = i;
  640.         continue;
  641.          default:
  642.         Syntax ();
  643.         }
  644.         break;
  645.     }
  646.  
  647.     term.initflags = term.flags;
  648.  
  649.     if (fnflag && !fbflag) f_b = NULL;
  650.     if (!fnflag && fbflag) f_n = f_b;
  651.     if(!win_name) {
  652.         if(get_ty) {
  653.             char b[256];
  654.  
  655.             gethostname(b, sizeof(b) - 1);
  656.             b[sizeof(b) - 1] = 0;
  657.             if(strind = index(b, '.')) /* remove domain */
  658.                 *strind = 0;
  659.             win_name = malloc(strlen(b) + 8);
  660.             strcpy(win_name, "login(");
  661.             strcat(win_name, b);
  662.             strcat(win_name, ")");
  663.         } else
  664.             win_name = (am_slave ? "xterm slave" :
  665.              (command_to_exec ? basename(command_to_exec[0]) :
  666.              xterm_name));
  667.     }
  668.     if(inhibit & I_TEK)
  669.         screen->TekEmu = FALSE;
  670.  
  671.     /* set up stderr properly */
  672.     i = -1;
  673. #ifdef DEBUG
  674.     if(debug)
  675.         i = open ("xterm.debug.log", O_WRONLY | O_CREAT | O_TRUNC,
  676.          0666);
  677.     else
  678. #endif DEBUG
  679.     if(get_ty)
  680.         i = open("/dev/console", O_WRONLY);
  681.     if(i >= 0)
  682.         fileno(stderr) = i;
  683.     if(fileno(stderr) != (NOFILE - 1)) {
  684.         dup2(fileno(stderr), (NOFILE - 1));
  685.         if(fileno(stderr) >= 3)
  686.             close(fileno(stderr));
  687.         fileno(stderr) = (NOFILE - 1);
  688.     }
  689.  
  690.     signal (SIGCHLD, reapchild);
  691.     signal (SIGHUP, SIG_IGN);
  692.     signal(SIGALRM, onalarm);
  693.  
  694.     /* open a terminal for client */
  695.     get_terminal ();
  696.     spawn ();
  697.  
  698.     Xsocket = screen->display->fd;
  699.     pty = screen->respond;
  700.  
  701.     if (am_slave) { /* Write window id so master end can read and use */
  702.         write(pty, screen->TekEmu ? (char *)&TWindow(screen) :
  703.          (char *)&VWindow(screen), sizeof(Window));
  704.         write(pty, "\n", 1);
  705.     }
  706.  
  707.     if(log_on) {
  708.         log_on = FALSE;
  709.         StartLog(screen);
  710.     }
  711.     screen->inhibit = inhibit;
  712.     mode = 1;
  713.     if (ioctl (pty, FIONBIO, &mode) == -1) SysError (ERROR_FIONBIO);
  714.     
  715.     pty_mask = 1 << pty;
  716.     X_mask = 1 << Xsocket;
  717.     Select_mask = pty_mask | X_mask;
  718.     max_plus1 = (pty < Xsocket) ? (1 + Xsocket) : (1 + pty);
  719.  
  720. #ifdef DEBUG
  721.     if (debug) printf ("debugging on\n");
  722. #endif DEBUG
  723.     XErrorHandler(xerror);
  724.     XIOErrorHandler(xioerror);
  725.     for( ; ; )
  726.         if(screen->TekEmu)
  727.             TekRun();
  728.         else
  729.             VTRun();
  730. }
  731.  
  732. char *basename(name)
  733. char *name;
  734. {
  735.     register char *cp;
  736.     char *rindex();
  737.  
  738.     return((cp = rindex(name, '/')) ? cp + 1 : name);
  739. }
  740.  
  741. static struct argstr {
  742.     char *arg;
  743.     int val;
  744. } arg[] = {
  745.     {"132",    ARG_132},
  746. #ifdef TIOCCONS
  747.     {"C",    ARG__C},
  748. #endif TIOCCONS
  749.     {"L",    ARG__L},
  750.     {"S",    ARG__S},
  751.     {"ai",    ARG_AI},
  752.     {"ar",    ARG_AR},
  753.     {"b",    ARG_B},
  754.     {"bd",    ARG_BD},
  755.     {"bg",    ARG_BG},
  756.     {"bw",    ARG_BW},
  757.     {"cr",    ARG_CR},
  758.     {"cu",    ARG_CU},
  759. #ifdef DEBUG
  760.     {"d",    ARG_D},
  761. #endif DEBUG
  762.     {"dw",    ARG_DW},
  763.     {"e",    ARG_E},
  764.     {"fb",    ARG_FB},
  765.     {"fg",    ARG_FG},
  766.     {"fi",    ARG_FI},
  767.     {"fn",    ARG_FN},
  768.     {"ft",    ARG_FT},
  769.     {"i",    ARG_I},
  770.     {"ib",    ARG_IB},
  771.     {"it",    ARG_IT},
  772.     {"j",    ARG_J},
  773. #ifdef KEYBD
  774.     {"k",    ARG_K},
  775. #endif KEYBD
  776.     {"l",    ARG_L},
  777.     {"lf",    ARG_LF},
  778.     {"ls",    ARG_LS},
  779.     {"mb",    ARG_MB},
  780.     {"ms",    ARG_MS},
  781.     {"n",    ARG_N},
  782.     {"nb",    ARG_NB},
  783.     {"po",    ARG_PO},
  784.     {"ps",    ARG_PS},
  785.     {"r",    ARG_RV},
  786.     {"rv",    ARG_RV},
  787.     {"rw",    ARG_RW},
  788.     {"s",    ARG_S},
  789.     {"sb",    ARG_SB},
  790.     {"si",    ARG_SI},
  791.     {"sk",    ARG_SK},
  792.     {"sl",    ARG_SL},
  793.     {"sn",    ARG_SN},
  794.     {"st",    ARG_ST},
  795.     {"t",    ARG_T},
  796.     {"tb",    ARG_TB},
  797.     {"ti",    ARG_TI},
  798.     {"vb",    ARG_VB},
  799.     {"w",    ARG_BW},
  800. };
  801.  
  802. argument(s)
  803. register char *s;
  804. {
  805.     register int i, low, high, com;
  806.  
  807.     low = 0;
  808.     high = sizeof(arg) / sizeof(struct argstr) - 1;
  809.     while(low <= high) {/* use binary search, arg in lexigraphic order */
  810.         i = (low + high) / 2;
  811.         if ((com = strcmp(s, arg[i].arg)) == 0)
  812.             return(arg[i].val);
  813.         if(com > 0)
  814.             low = i + 1;
  815.         else
  816.             high = i - 1;
  817.     }
  818.     return(-1);
  819. }
  820.  
  821. static char *ustring[] = {
  822. "Usage: xterm [-132] [-ai] [-ar] [-b margin_width] [-bd border_color] \\\n",
  823. #ifdef ARG__C
  824. " [-bg backgrnd_color] [-bw border_width] [-C] [-cr cursor_color] [-cu] \\\n",
  825. #else ARG__C
  826. " [-bg backgrnd_color] [-bw border_width] [-cr cursor_color] [-cu] \\\n",
  827. #endif ARG__C
  828. " [-dw] [-fb bold_font] [-fg foregrnd_color] [-fi icon_font] [-fn norm_font] \\\n",
  829. " [-ft title_font] [-i] [-ib iconbitmap] [-it tekiconbitmap] [-j] \\\n",
  830. #ifdef ARG_K
  831. " [-k keybd] [-l] [-lf logfile] [-ls] [-mb] [-ms mouse_color] \\\n",
  832. #else ARG_K
  833. " [-l] [-lf logfile] [-ls] [-mb] [-ms mouse_color] \\\n",
  834. #endif ARG_K
  835. " [-n name] [-nb bell_margin] [-po] [-ps] [-rv] [-rw] [-s] \\\n",
  836. " [-sb] [-si] [-sk] [-sl save_lines] [-sn] [-st] [-t] [-tb] \\\n",
  837. " [-ti] [-vb] [=[width]x[height][[+-]xoff[[+-]yoff]]] \\\n",
  838. " [%[width]x[height][[+-]xoff[[+-]yoff]]] [#[+-]xoff[[+-]yoff]] \\\n",
  839. " [-e command_to_exec]\n\n",
  840. "Fonts must be of fixed width and of same size;\n",
  841. "If only one font is specified, it will be used for normal and bold text\n",
  842. "The -132 option allows 80 <-> 132 column escape sequences\n",
  843. "The -ai option turns on miniature (active) icons\n",
  844. "The -ar option turns auto raise window mode on\n",
  845. #ifdef ARG__C
  846. "The -C option forces output to /dev/console to appear in this window\n",
  847. #endif ARG__C
  848. "The -cu option turns a curses bug fix on\n",
  849. "The -dw option warps the mouse on deiconify\n",
  850. "The -i option enables icon startup\n",
  851. "The -j option enables jump scroll\n",
  852. "The -l option enables logging\n",
  853. "The -ls option makes the shell a login shell\n",
  854. "The -mb option turns the margin bell on\n",
  855. "The -ps option turns page scroll on\n",
  856. "The -rv option turns reverse video on\n",
  857. "The -rw option turns reverse wraparound on\n",
  858. "The -s option enables asynchronous scrolling\n",
  859. "The -sb option enables the scrollbar\n",
  860. "The -si option enables re-positioning the scrollbar at the bottom on input\n",
  861. "The -sk option causes the scrollbar to position at the bottom on a key\n",
  862. "The -sn option makes the status line normal video \n",
  863. "The -st option enables the status line\n",
  864. "The -t option starts Tektronix mode\n",
  865. "The -tb option enables the titlebar\n",
  866. "The -ti option places the window name under the icon\n",
  867. "The -vb option enables visual bell\n",
  868. 0
  869. };
  870.  
  871. Syntax ()
  872. {
  873.     register char **us = ustring;
  874.  
  875.     while (*us) fputs(*us++, stderr);
  876.     exit (1);
  877. }
  878.  
  879. get_pty (pty, tty)
  880. /*
  881.    opens a pty, storing fildes in pty and tty.
  882.  */
  883. int *pty, *tty;
  884. {
  885.     int devindex, letter = 0;
  886.  
  887.     while (letter < 4) {
  888.         ttydev [8] = ptydev [8] = "pqrs" [letter++];
  889.         devindex = 0;
  890.  
  891.         while (devindex < 16) {
  892.         ttydev [9] = ptydev [9] = "0123456789abcdef" [devindex++];
  893.         if ((*pty = open (ptydev, O_RDWR)) < 0)
  894.             continue;
  895.         if ((*tty = open (ttydev, O_RDWR)) < 0) {
  896.             close(*pty);
  897.             continue;
  898.         }
  899.         return;
  900.         }
  901.     }
  902.     
  903.     fprintf (stderr, "%s: Not enough available pty's\n", xterm_name);
  904.     exit (ERROR_PTYS);
  905. }
  906.  
  907. get_terminal ()
  908. /* 
  909.  * sets up X and initializes the terminal structure except for term.buf.fildes.
  910.  */
  911. {
  912.     register Screen *screen = &term.screen;
  913.     register int try;
  914.     Color cdef;
  915.     char *malloc();
  916.     
  917.     for (try = 10 ; ; ) {
  918.         if (screen->display = XOpenDisplay(display))
  919.         break;
  920.         if (!get_ty) {
  921.         fprintf(stderr, "%s: No such display server %s\n", xterm_name,
  922.          XDisplayName(display));
  923.         exit(ERROR_NOX);
  924.         }
  925.         if (--try <= 0)  {
  926.         fprintf (stderr, "%s: Can't connect to display server %s\n",
  927.          xterm_name, XDisplayName(display));
  928.         exit (ERROR_NOX2);
  929.         }        
  930.         sleep (5);
  931.     }
  932.  
  933.     if(re_verse) {
  934.         B_Pixel = WhitePixel;
  935.         B_Pixmap = WhitePixmap;
  936.         W_Pixel = BlackPixel;
  937.         W_Pixmap = BlackPixmap;
  938.     } else {
  939.         B_Pixel = BlackPixel;
  940.         B_Pixmap = BlackPixmap;
  941.         W_Pixel = WhitePixel;
  942.         W_Pixmap = WhitePixmap;
  943.     }
  944.  
  945.     if (brdr_color && DisplayCells() > 2 &&
  946.      XParseColor(brdr_color, &cdef) && XGetHardwareColor(&cdef)) {
  947.         if(!(screen->bordertile = XMakeTile(cdef.pixel)))
  948.         Error(ERROR_BORDER);
  949.     } else
  950.         screen->bordertile = B_Pixmap;
  951.     screen->graybordertile = make_gray();
  952.  
  953.     screen->foreground = B_Pixel;
  954.     screen->background = W_Pixel;
  955.     screen->cursorcolor = B_Pixel;
  956.     screen->mousecolor = B_Pixel;
  957.  
  958.     if (DisplayCells() > 2 && (fore_color || back_color ||
  959.      curs_color)) {
  960.         if (fore_color && XParseColor(fore_color, &cdef) &&
  961.          XGetHardwareColor(&cdef)) {
  962.             screen->foreground = cdef.pixel;
  963.             screen->color |= C_FOREGROUND;
  964.         }
  965.         if (back_color && XParseColor(back_color, &cdef) &&
  966.          XGetHardwareColor(&cdef)) {
  967.             screen->background = cdef.pixel;
  968.             screen->color |= C_BACKGROUND;
  969.         }
  970.         if (curs_color && XParseColor(curs_color, &cdef) &&
  971.          XGetHardwareColor(&cdef)) {
  972.             screen->cursorcolor = cdef.pixel;
  973.             screen->color |= C_CURSOR;
  974.         } else
  975.             screen->cursorcolor = screen->foreground;
  976.     }
  977.  
  978.     if (mous_color && DisplayCells() > 2 &&
  979.      XParseColor(mous_color, &cdef) && XGetHardwareColor(&cdef)) {
  980.         screen->mousecolor = cdef.pixel;
  981.         screen->color |= C_MOUSE;
  982.     } else
  983.         screen->mousecolor = screen->cursorcolor;
  984.  
  985.     if(screen->color & C_BACKGROUND) {
  986.         if(!(screen->bgndtile = XMakeTile(screen->background)))
  987.         Error(ERROR_BACK);
  988.     } else
  989.         screen->bgndtile = W_Pixmap;
  990.     screen->arrow = make_arrow(screen->mousecolor, screen->background,
  991.      GXcopy);
  992.  
  993.     XAutoRepeatOn();
  994.     if((screen->titlefont = XOpenFont(f_t)) == NULL) {
  995.         fprintf(stderr, "%s: Can't get title font %s\n", xterm_name,
  996.          f_t);
  997.         exit(ERROR_TITLEFONT);
  998.     }
  999.     screen->title_n_size= XQueryWidth("m", screen->titlefont->id);
  1000.     screen->titleheight = screen->titlefont->height + 2 * TITLEPAD + 1;
  1001.     if(screen->fullVwin.titlebar)
  1002.         screen->fullVwin.titlebar =
  1003.             screen->fullTwin.titlebar = screen->titleheight;
  1004.     IconInit(screen, iconbitmap, tekiconbitmap);
  1005. }
  1006.  
  1007. static char *tekterm[] = {
  1008.     "tek4015",
  1009.     "tek4014",
  1010.     "tek4013",
  1011.     "tek4010",
  1012.     "dumb",
  1013.     0
  1014. };
  1015.  
  1016. static char *vtterm[] = {
  1017.     "xterms",
  1018.     "xterm",
  1019.     "vt102",
  1020.     "vt100",
  1021.     "ansi",
  1022.     "dumb",
  1023.     0
  1024. };
  1025.  
  1026. spawn ()
  1027. /* 
  1028.  *  Inits pty and tty and forks a login process.
  1029.  *  Does not close fd Xsocket.
  1030.  *  If getty,  execs getty rather than csh and uses std fd's rather
  1031.  *  than opening a pty/tty pair.
  1032.  *  If slave, the pty named in passedPty is already open for use
  1033.  */
  1034. {
  1035.     register Screen *screen = &term.screen;
  1036.     int Xsocket = screen->display->fd;
  1037.     int index1, tty = -1;
  1038.     int discipline;
  1039.     unsigned lmode;
  1040.     struct tchars tc;
  1041.     struct ltchars ltc;
  1042.     struct sgttyb sg;
  1043.  
  1044.     char termcap [1024];
  1045.     char newtc [1024];
  1046.     char *ptr, *shname;
  1047.     int i, no_dev_tty = FALSE;
  1048.     char **envnew;        /* new environment */
  1049.     char buf[32];
  1050.     char *TermName = NULL;
  1051.     int ldisc = 0;
  1052. #ifdef sun
  1053. #ifdef TIOCSSIZE
  1054.     struct ttysize ts;
  1055. #endif TIOCSSIZE
  1056. #else sun
  1057. #ifdef TIOCSWINSZ
  1058.     struct winsize ws;
  1059. #endif TIOCSWINSZ
  1060. #endif sun
  1061.     struct passwd *pw = NULL;
  1062. #ifdef UTMP
  1063.     struct utmp utmp;
  1064. #endif UTMP
  1065.     extern int Exit();
  1066.     struct passwd *getpwuid();
  1067.     char *getenv();
  1068.     char *index (), *rindex (), *strindex ();
  1069.  
  1070.     screen->uid = getuid();
  1071.     screen->gid = getgid();
  1072.  
  1073. #ifdef UTMP
  1074.     added_utmp_entry = FALSE;
  1075. #endif UTMP
  1076.     /* so that TIOCSWINSZ || TIOCSIZE doesn't block */
  1077.     signal(SIGTTOU,SIG_IGN);
  1078.     if(!(screen->TekEmu ? TekInit() : VTInit()))
  1079.         exit(ERROR_INIT);
  1080.  
  1081.     if(screen->TekEmu) {
  1082.         envnew = tekterm;
  1083.         ptr = newtc;
  1084.     } else {
  1085.         /*
  1086.          * Special case of a 80x24 window, use "xterms"
  1087.          */
  1088.         envnew = (screen->max_col == 79 && screen->max_row ==
  1089.          23) ? vtterm : &vtterm[1];
  1090.         ptr = termcap;
  1091.     }
  1092.     while(*envnew) {
  1093.         if(tgetent(ptr, *envnew) == 1) {
  1094.             TermName = *envnew;
  1095.             if(!screen->TekEmu)
  1096.                 resize(screen, TermName, termcap, newtc);
  1097.             break;
  1098.         }
  1099.         envnew++;
  1100.     }
  1101.  
  1102.     if (get_ty) {
  1103.         screen->respond = loginpty;
  1104.         if((tslot = ttyslot()) <= 0)
  1105.             SysError(ERROR_TSLOT);
  1106. #ifdef TIOCCONS
  1107.         if (Console) {
  1108.             int on = 1;
  1109.             if (ioctl (0, TIOCCONS, &on) == -1)
  1110.                 SysError(ERROR_TIOCCONS);
  1111.         }
  1112. #endif TIOCCONS
  1113.     } else if (am_slave) {
  1114.         screen->respond = am_slave;
  1115.         ptydev[8] = ttydev[8] = passedPty[0];
  1116.         ptydev[9] = ttydev[9] = passedPty[1];
  1117.         if((tslot = ttyslot()) <= 0)
  1118.             SysError(ERROR_TSLOT2);
  1119.         setgid (screen->gid);
  1120.         setuid (screen->uid);
  1121.     } else {
  1122.         if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0) {
  1123.             if (errno != ENXIO) SysError(ERROR_OPDEVTTY);
  1124.             else {
  1125.                 no_dev_tty = TRUE;
  1126.                 sg = d_sg;
  1127.                 tc = d_tc;
  1128.                 discipline = d_disipline;
  1129.                 ltc = d_ltc;
  1130.                 lmode = d_lmode;
  1131.             }
  1132.         } else {
  1133.             /* get a copy of the current terminal's state */
  1134.  
  1135.             if(ioctl(tty, TIOCGETP, &sg) == -1)
  1136.                 SysError (ERROR_TIOCGETP);
  1137.             if(ioctl(tty, TIOCGETC, &tc) == -1)
  1138.                 SysError (ERROR_TIOCGETC);
  1139.             if(ioctl(tty, TIOCGETD, &discipline) == -1)
  1140.                 SysError (ERROR_TIOCGETD);
  1141.             if(ioctl(tty, TIOCGLTC, <c) == -1)
  1142.                 SysError (ERROR_TIOCGLTC);
  1143.             if(ioctl(tty, TIOCLGET, &lmode) == -1)
  1144.                 SysError (ERROR_TIOCLGET);
  1145.             close (tty);
  1146.  
  1147.             /* close all std file descriptors */
  1148.             for (index1 = 0; index1 < 3; index1++)
  1149.                 close (index1);
  1150.             if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0)
  1151.                 SysError (ERROR_OPDEVTTY2);
  1152.  
  1153.             if (ioctl (tty, TIOCNOTTY, 0) == -1)
  1154.                 SysError (ERROR_NOTTY);
  1155.             close (tty);
  1156.         }
  1157.  
  1158.         get_pty (&screen->respond, &tty);
  1159.  
  1160.         if (screen->respond != Xsocket + 1) {
  1161.             dup2 (screen->respond, Xsocket + 1);
  1162.             close (screen->respond);
  1163.             screen->respond = Xsocket + 1;
  1164.         }
  1165.  
  1166.         /* change ownership of tty to real group and user id */
  1167.         chown (ttydev, screen->uid, screen->gid);
  1168.  
  1169.         /* change protection of tty */
  1170.         chmod (ttydev, 0622);
  1171.  
  1172.         if (tty != Xsocket + 2)    {
  1173.             dup2 (tty, Xsocket + 2);
  1174.             close (tty);
  1175.             tty = Xsocket + 2;
  1176.         }
  1177.  
  1178.         /* set the new terminal's state to be the old one's 
  1179.            with minor modifications for efficiency */
  1180.  
  1181.         sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW);
  1182.         sg.sg_flags |= ECHO | CRMOD;
  1183.         /* make sure speed is set on pty so that editors work right*/
  1184.         sg.sg_ispeed = B9600;
  1185.         sg.sg_ospeed = B9600;
  1186.         /* reset t_brkc to default value */
  1187.         tc.t_brkc = -1;
  1188.  
  1189.         if (ioctl (tty, TIOCSETP, &sg) == -1)
  1190.             SysError (ERROR_TIOCSETP);
  1191.         if (ioctl (tty, TIOCSETC, &tc) == -1)
  1192.             SysError (ERROR_TIOCSETC);
  1193.         if (ioctl (tty, TIOCSETD, &discipline) == -1)
  1194.             SysError (ERROR_TIOCSETD);
  1195.         if (ioctl (tty, TIOCSLTC, <c) == -1)
  1196.             SysError (ERROR_TIOCSLTC);
  1197.         if (ioctl (tty, TIOCLSET, &lmode) == -1)
  1198.             SysError (ERROR_TIOCLSET);
  1199. #ifdef TIOCCONS
  1200.         if (Console) {
  1201.             int on = 1;
  1202.             if (ioctl (tty, TIOCCONS, &on) == -1)
  1203.                 SysError(ERROR_TIOCCONS);
  1204.         }
  1205. #endif TIOCCONS
  1206.  
  1207.         close (open ("/dev/null", O_RDWR, 0));
  1208.  
  1209.         for (index1 = 0; index1 < 3; index1++)
  1210.             dup2 (tty, index1);
  1211.         if((tslot = ttyslot()) <= 0)
  1212.             SysError(ERROR_TSLOT3);
  1213. #ifdef UTMP
  1214.         if((pw = getpwuid(screen->uid)) &&
  1215.          (i = open(etc_utmp, O_WRONLY)) >= 0) {
  1216.             bzero((char *)&utmp, sizeof(struct utmp));
  1217.             (void) strcpy(utmp.ut_line, &ttydev[5]);
  1218.             (void) strcpy(utmp.ut_name, pw->pw_name);
  1219.             (void) strcpy(utmp.ut_host, DisplayName());
  1220.             time(&utmp.ut_time);
  1221.             lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
  1222.             write(i, (char *)&utmp, sizeof(struct utmp));
  1223.             close(i);
  1224.             added_utmp_entry = TRUE;
  1225.         }
  1226. #endif UTMP
  1227.     }
  1228.  
  1229. #ifdef sun
  1230. #ifdef TIOCSSIZE
  1231.     /* tell tty how big window is */
  1232.     if(screen->TekEmu) {
  1233.         ts.ts_lines = 38;
  1234.         ts.ts_cols = 81;
  1235.     } else {
  1236.         ts.ts_lines = screen->max_row + 1;
  1237.         ts.ts_cols = screen->max_col + 1;
  1238.     }
  1239.     ioctl (screen->respond, TIOCSSIZE, &ts);
  1240. #endif TIOCSSIZE
  1241. #else sun
  1242. #ifdef TIOCSWINSZ
  1243.     /* tell tty how big window is */
  1244.     if(screen->TekEmu) {
  1245.         ws.ws_row = 38;
  1246.         ws.ws_col = 81;
  1247.         ws.ws_xpixel = TFullWidth(screen);
  1248.         ws.ws_ypixel = TFullHeight(screen);
  1249.     } else {
  1250.         ws.ws_row = screen->max_row + 1;
  1251.         ws.ws_col = screen->max_col + 1;
  1252.         ws.ws_xpixel = FullWidth(screen);
  1253.         ws.ws_ypixel = FullHeight(screen);
  1254.     }
  1255.     ioctl (screen->respond, TIOCSWINSZ, &ws);
  1256. #endif TIOCSWINSZ
  1257. #endif sun
  1258.  
  1259.     if (!am_slave) {
  1260.         if ((screen->pid = fork ()) == -1)
  1261.         SysError (ERROR_FORK);
  1262.         
  1263.         if (screen->pid == 0) {
  1264.         extern char **environ;
  1265.         int pgrp = getpid();
  1266.         char shell_name[64];
  1267.  
  1268.         close (Xsocket);
  1269.         close (screen->respond);
  1270.         if(fileno(stderr) >= 3)
  1271.             close (fileno(stderr));
  1272.  
  1273.         if (tty >= 0) close (tty);
  1274.  
  1275.         signal (SIGCHLD, SIG_DFL);
  1276.         signal (SIGHUP, SIG_IGN);
  1277.  
  1278.         /* copy the environment before Setenving */
  1279.         for (i = 0 ; environ [i] != NULL ; i++) ;
  1280.         /*
  1281.          * The `4' is the number of Setenv() calls which may add
  1282.          * a new entry to the environment.  The `1' is for the
  1283.          * NULL terminating entry.
  1284.          */
  1285.         envnew = (char **) calloc (i + (4 + 1), sizeof(char *));
  1286.         bcopy((char *)environ, (char *)envnew, i * sizeof(char *));
  1287.         environ = envnew;
  1288.         Setenv ("TERM=", TermName);
  1289.         if(!TermName)
  1290.             *newtc = 0;
  1291.         Setenv ("TERMCAP=", newtc);
  1292.         sprintf(buf, "%d", screen->TekEmu ? (int)TWindow(screen) :
  1293.          (int)VWindow(screen));
  1294.         Setenv ("WINDOWID=", buf);
  1295.         /* put the display into the environment of the shell*/
  1296.         if (display[0] != '\0') 
  1297.             Setenv ("DISPLAY=", screen->display->displayname);
  1298.  
  1299.         signal(SIGTERM, SIG_DFL);
  1300.         ioctl(0, TIOCSPGRP, &pgrp);
  1301.         setpgrp (0, 0);
  1302.         close(open(ttyname(0), O_WRONLY, 0));
  1303.         setpgrp (0, pgrp);
  1304.  
  1305.         setgid (screen->gid);
  1306.         setuid (screen->uid);
  1307.  
  1308.         if (command_to_exec) {
  1309.             execvp(*command_to_exec, command_to_exec);
  1310.             /* print error message on screen */
  1311.             fprintf(stderr, "%s: Can't execvp %s\n", xterm_name,
  1312.              *command_to_exec);
  1313.         }
  1314.         signal(SIGHUP, SIG_IGN);
  1315.         if (get_ty) {
  1316.             ioctl (0, TIOCNOTTY, 0);
  1317.             execl ("/etc/getty", "+", "Xwindow", get_ty, 0);
  1318.         }
  1319.         signal(SIGHUP, SIG_DFL);
  1320.  
  1321. #ifdef UTMP
  1322.         if(((ptr = getenv("SHELL")) == NULL || *ptr == 0) &&
  1323.          ((pw == NULL && (pw = getpwuid(screen->uid)) == NULL) ||
  1324.          *(ptr = pw->pw_shell) == 0))
  1325. #else UTMP
  1326.         if(((ptr = getenv("SHELL")) == NULL || *ptr == 0) &&
  1327.          ((pw = getpwuid(screen->uid)) == NULL ||
  1328.          *(ptr = pw->pw_shell) == 0))
  1329. #endif UTMP
  1330.             ptr = "/bin/sh";
  1331.         if(shname = rindex(ptr, '/'))
  1332.             shname++;
  1333.         else
  1334.             shname = ptr;
  1335.         i = strlen(shname) - 3;
  1336.         ldisc = (strcmp("csh", shname + i) == 0 ||
  1337.          strcmp("ksh", shname + i) == 0) ? NTTYDISC : 0;
  1338.         ioctl(0, TIOCSETD, &ldisc);
  1339.         if(login_shell)
  1340.             strcpy(shell_name, "-");
  1341.         else
  1342.             *shell_name = 0;
  1343.         strcat(shell_name, shname);
  1344.         execl (ptr, shell_name, 0);
  1345.         fprintf (stderr, "%s: Could not exec %s!\n", xterm_name, ptr);
  1346.         sleep(5);
  1347.         exit(ERROR_EXEC);
  1348.         }
  1349.     }
  1350.  
  1351.     if(tty >= 0) close (tty);
  1352.     signal(SIGHUP,SIG_IGN);
  1353.  
  1354.     if (!no_dev_tty) {
  1355.         if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0)
  1356.             SysError(ERROR_OPDEVTTY3);
  1357.         for (index1 = 0; index1 < 3; index1++)
  1358.             dup2 (tty, index1);
  1359.         if (tty > 2) close (tty);
  1360.     }
  1361.  
  1362.     signal(SIGINT, Exit);
  1363.     signal(SIGQUIT, Exit);
  1364.     signal(SIGTERM, Exit);
  1365. }
  1366.  
  1367. Exit(n)
  1368. int n;
  1369. {
  1370.     register Screen *screen = &term.screen;
  1371. #ifdef UTMP
  1372.     register int i;
  1373.     struct utmp utmp;
  1374.  
  1375.     if(added_utmp_entry && (i = open(etc_utmp, O_WRONLY)) >= 0) {
  1376.         bzero((char *)&utmp, sizeof(struct utmp));
  1377.         lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
  1378.         write(i, (char *)&utmp, sizeof(struct utmp));
  1379.         close(i);
  1380.     }
  1381. #endif UTMP
  1382.     if(screen->logging)
  1383.         CloseLog(screen);
  1384.  
  1385.     if(!get_ty && !am_slave) {
  1386.         /* restore ownership of tty */
  1387.         chown (ttydev, 0, 0);
  1388.  
  1389.         /* restore modes of tty */
  1390.         chmod (ttydev, 0666);
  1391.     }
  1392.     exit(n);
  1393. }
  1394.  
  1395. resize(screen, TermName, oldtc, newtc)
  1396. Screen *screen;
  1397. char *TermName;
  1398. register char *oldtc, *newtc;
  1399. {
  1400.     register char *ptr1, *ptr2;
  1401.     register int i;
  1402.     register int li_first = 0;
  1403.     register char *temp;
  1404.     char *index(), *strindex();
  1405.  
  1406.     if ((ptr1 = strindex (oldtc, "co#")) == NULL){
  1407.         fprintf(stderr, "%s: Can't find co# in termcap string %s\n",
  1408.             xterm_name, TermName);
  1409.         exit (ERROR_NOCO);
  1410.     }
  1411.     if ((ptr2 = strindex (oldtc, "li#")) == NULL){
  1412.         fprintf(stderr, "%s: Can't find li# in termcap string %s\n",
  1413.             xterm_name, TermName);
  1414.         exit (ERROR_NOLI);
  1415.     }
  1416.     if(ptr1 > ptr2) {
  1417.         li_first++;
  1418.         temp = ptr1;
  1419.         ptr1 = ptr2;
  1420.         ptr2 = temp;
  1421.     }
  1422.     ptr1 += 3;
  1423.     ptr2 += 3;
  1424.     strncpy (newtc, oldtc, i = ptr1 - oldtc);
  1425.     newtc += i;
  1426.     sprintf (newtc, "%d", li_first ? screen->max_row + 1 :
  1427.      screen->max_col + 1);
  1428.     newtc += strlen(newtc);
  1429.     ptr1 = index (ptr1, ':');
  1430.     strncpy (newtc, ptr1, i = ptr2 - ptr1);
  1431.     newtc += i;
  1432.     sprintf (newtc, "%d", li_first ? screen->max_col + 1 :
  1433.      screen->max_row + 1);
  1434.     ptr2 = index (ptr2, ':');
  1435.     strcat (newtc, ptr2);
  1436. }
  1437.  
  1438. static reapchild ()
  1439. {
  1440.     union wait status;
  1441.     register int pid;
  1442.     
  1443. #ifdef DEBUG
  1444.     if (debug) fputs ("Exiting\n", stderr);
  1445. #endif DEBUG
  1446.     pid  = wait3 (&status, WNOHANG, NULL);
  1447.     if (!pid) return;
  1448.     if (pid != term.screen.pid) return;
  1449.     
  1450.     Cleanup(0);
  1451. }
  1452.  
  1453. consolepr(string)
  1454. char *string;
  1455. {
  1456.     extern int errno;
  1457.     extern char *sys_errlist[];
  1458.     int oerrno;
  1459.     int f;
  1460.  
  1461.     oerrno = errno;
  1462.     f = open("/dev/console",O_WRONLY);
  1463.     write(f, "xterm: ", 7);
  1464.     write(f, string, strlen(string));
  1465.     write(f, ": ", 2);
  1466.     write(f, sys_errlist[oerrno],strlen(sys_errlist[oerrno]));
  1467.     write(f, "\n", 1);
  1468.     close(f);
  1469.     if ((f = open("/dev/tty", 2)) >= 0) {
  1470.         ioctl(f, TIOCNOTTY, 0);
  1471.         close(f);
  1472.     }
  1473. }
  1474.  
  1475. checklogin()
  1476. {
  1477.     register int i, j;
  1478.     register struct passwd *pw;
  1479.     struct utmp utmp;
  1480.  
  1481.     if((i = open(etc_utmp, O_RDONLY)) < 0)
  1482.         return(FALSE);
  1483.     lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
  1484.     j = read(i, (char *)&utmp, sizeof(utmp));
  1485.     close(i);
  1486.     if(j != sizeof(utmp) || strcmp(get_ty, utmp.ut_line) != 0 ||
  1487.      !*utmp.ut_name || (pw = getpwnam(utmp.ut_name)) == NULL)
  1488.         return(FALSE);
  1489.     chdir(pw->pw_dir);
  1490.     setgid(pw->pw_gid);
  1491.     setuid(pw->pw_uid);
  1492.     L_flag = 0;
  1493.     return(TRUE);
  1494. }
  1495.