Annotation of 43BSDTahoe/new/X/xterm/main.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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