|
|
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, <c) == -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, <c) == -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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.