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