|
|
1.1 ! root 1: #include <X/mit-copyright.h> ! 2: ! 3: /* Copyright Massachusetts Institute of Technology 1984, 1985 */ ! 4: ! 5: /* ptyx.c */ ! 6: ! 7: #ifndef lint ! 8: static char *rcsid_ptyx_c = "$Header: main.c,v 10.44 86/05/16 10:17:20 jg Exp $"; ! 9: #endif lint ! 10: ! 11: #include <pwd.h> ! 12: #include <sgtty.h> ! 13: #include <sys/wait.h> ! 14: #include <sys/time.h> ! 15: #include <sys/resource.h> ! 16: #include <stdio.h> ! 17: #include <sys/file.h> ! 18: #include <errno.h> ! 19: #include <signal.h> ! 20: #include <strings.h> ! 21: #include <X/Xlib.h> ! 22: #include "ptyx.h" ! 23: #include <grp.h> ! 24: #include <ttyent.h> ! 25: #include <utmp.h> ! 26: ! 27: char *xterm_name; /* argv[0] */ ! 28: Terminal term; /* master data structure for client */ ! 29: int am_slave = 0; /* set to 1 if running as a slave process */ ! 30: int debug = 0; /* true causes error messages to be displayed */ ! 31: ! 32: static char *ptydev = "/dev/ptyxx"; ! 33: static char *ttydev = "/dev/ttyxx"; ! 34: ! 35: #include "../cursors/xterm.cursor" ! 36: #include "../cursors/xterm_mask.cursor" ! 37: #include "icon.ic" ! 38: #include "icon_mask.ic" ! 39: ! 40: static int reapchild (); ! 41: ! 42: static char **command_to_exec = (char **) NULL; ! 43: static char *win_name = (char *) 0; ! 44: ! 45: ! 46: static struct sgttyb d_sg = { ! 47: 0, 0, 0177, CKILL, EVENP|ODDP|ECHO|XTABS|CRMOD ! 48: }; ! 49: static struct tchars d_tc = { ! 50: CINTR, CQUIT, CSTART, ! 51: CSTOP, CEOF, CBRK, ! 52: }; ! 53: static struct ltchars d_ltc = { ! 54: CSUSP, CDSUSP, CRPRNT, ! 55: CFLUSH, CWERASE, CLNEXT ! 56: }; ! 57: static int d_disipline = NTTYDISC; ! 58: static int d_lmode = LCRTBS|LCRTERA|LCRTKIL|LCTLECH; ! 59: static int no_dev_tty = 0; ! 60: static int loginflag = 0; ! 61: static int dologinflag = 0; ! 62: #ifdef sun ! 63: #ifdef TIOCCONS ! 64: static int SunConsole = 0; ! 65: #endif TIOCCONS ! 66: #endif sun ! 67: ! 68: ! 69: main (argc, argv) ! 70: int argc; ! 71: char **argv; ! 72: { ! 73: int ind; ! 74: char *strind, *strind1, *strscan(); ! 75: char *fn = "vtsingle"; ! 76: char *fb = "vtbold"; ! 77: short fnflag = 0; /* True iff -fn option used */ ! 78: short fbflag = 0; /* True iff -fb option used */ ! 79: char *getty = NULL; ! 80: int reverse = 0, multiscroll = 0; ! 81: int border = 1, tek = 0; ! 82: int borderwidth = 2; ! 83: int bitmapicon = 0; ! 84: #ifdef JUMPSCROLL ! 85: int jumpscroll = 0; ! 86: #endif JUMPSCROLL ! 87: int slave = 0; /* if non-zero, run as slave */ ! 88: char passedPty[2]; /* name if pty if slave */ ! 89: char *fore_color; ! 90: char *back_color; ! 91: char *brdr_color; ! 92: char *curs_color; ! 93: char *mous_color; ! 94: char display[256]; ! 95: char *getenv(); ! 96: char *option; ! 97: char *geometry, *def = "=80x24+1+1"; ! 98: ! 99: xterm_name = argv[0]; ! 100: ! 101: display[0] = '\0'; ! 102: /* ! 103: * go get options out of default file ! 104: */ ! 105: if ((option = XGetDefault(argv[0], "BodyFont")) != NULL) { ! 106: fn = option; ! 107: fnflag = 1; ! 108: } ! 109: if ((option = XGetDefault(argv[0], "BoldFont")) != NULL) { ! 110: fb = option; ! 111: fbflag = 1; ! 112: } ! 113: if ((option = XGetDefault(argv[0], "InternalBorder")) != NULL) { ! 114: border = atoi (option); ! 115: } ! 116: if ((option = XGetDefault(argv[0], "BorderWidth")) != NULL) { ! 117: borderwidth = atoi (option); ! 118: } ! 119: ! 120: if ((option = XGetDefault(argv[0], "BitmapIcon")) != NULL) ! 121: if (strcmp (option, "on") == 0) ! 122: bitmapicon = 1; ! 123: ! 124: if ((option = XGetDefault(argv[0], "ReverseVideo")) != NULL) ! 125: if (strcmp (option, "on") == 0) ! 126: reverse = 1; ! 127: ! 128: if ((option = XGetDefault(argv[0], "Tektronix")) != NULL) ! 129: if (strcmp (option, "on") == 0) ! 130: tek = 1; ! 131: #ifdef JUMPSCROLL ! 132: if ((option = XGetDefault(argv[0], "JumpScroll")) != NULL) ! 133: if (strcmp (option, "on") == 0) ! 134: jumpscroll = 1; ! 135: #endif JUMPSCROLL ! 136: ! 137: fore_color = XGetDefault(argv[0], "Foreground"); ! 138: back_color = XGetDefault(argv[0], "Background"); ! 139: brdr_color = XGetDefault(argv[0], "Border"); ! 140: curs_color = XGetDefault(argv[0], "Cursor"); ! 141: mous_color = XGetDefault(argv[0], "Mouse"); ! 142: ! 143: /* parse command line */ ! 144: ! 145: for (ind = 1; ind < argc; ind++) { ! 146: if (argv [ind] [0] == '=') { ! 147: geometry = argv[ind]; ! 148: continue; ! 149: } ! 150: ! 151: strind = index (argv[ind], ':'); ! 152: if(strind != NULL) { ! 153: strncpy(display,argv[ind],sizeof(display)); ! 154: continue; ! 155: } ! 156: ! 157: ! 158: strind = (char *) index (argv [ind], '-'); ! 159: ! 160: if (strind == NULL) Syntax (); ! 161: ! 162: if (strcmp (argv [ind], "-L") == 0) { ! 163: char tt[32]; ! 164: int mode = O_RDWR|O_NDELAY; ! 165: loginflag = 1; ! 166: getty = argv[argc-1]; ! 167: argc -= 1; ! 168: strcpy(tt,"/dev/"); ! 169: strcat(tt, getty); ! 170: chown(tt, 0, 0); ! 171: chmod(tt, 0622); ! 172: if (open(tt, mode, 0) < 0) { ! 173: consolepr("open failed\n"); ! 174: } ! 175: signal(SIGHUP, SIG_IGN); ! 176: vhangup(); ! 177: setpgrp(0,0); ! 178: signal(SIGHUP, SIG_DFL); ! 179: open(tt, mode, 0); ! 180: close(0); ! 181: dup(1); ! 182: dup(0); ! 183: continue; ! 184: } ! 185: ! 186: if (strncmp (argv [ind], "-S", 2) == 0) { ! 187: sscanf(argv[ind] + 2, "%c%c%d", passedPty, passedPty+1, ! 188: &slave); ! 189: if (slave <= 0) Syntax(); ! 190: am_slave = 1; ! 191: continue; ! 192: } ! 193: ! 194: if (strcmp (argv [ind], "-e") == 0) { ! 195: if (++ind >= argc) Syntax (); ! 196: command_to_exec = argv + ind; ! 197: break; ! 198: } ! 199: ! 200: /* Switch to set up Tektronix-shaped (4096x3128 -> 512x390) window ! 201: * with characters sized to fit 39 lines of 85 characters each */ ! 202: ! 203: if (strcmp (argv [ind], "-t") == 0) { ! 204: tek = 1; ! 205: if (!fnflag) fn = "6x10"; ! 206: if (!fbflag) fb = "6x10"; ! 207: def = "85x39+1+1"; ! 208: continue; ! 209: } ! 210: ! 211: if (strcmp (argv [ind], "-fn") == 0) { ! 212: if (++ind >= argc) Syntax (); ! 213: fn = argv [ind]; ! 214: fnflag = 1; ! 215: continue; ! 216: } ! 217: ! 218: if (strcmp (argv [ind], "-fb") == 0) { ! 219: if (++ind >= argc) Syntax (); ! 220: fb = argv [ind]; ! 221: fbflag = 1; ! 222: continue; ! 223: } ! 224: ! 225: if (strcmp (argv [ind], "-fg") == 0) { ! 226: if (++ind >= argc) Syntax (); ! 227: fore_color = argv [ind]; ! 228: continue; ! 229: } ! 230: ! 231: if (strcmp (argv [ind], "-bg") == 0) { ! 232: if (++ind >= argc) Syntax (); ! 233: back_color = argv [ind]; ! 234: continue; ! 235: } ! 236: ! 237: if (strcmp (argv [ind], "-bd") == 0) { ! 238: if (++ind >= argc) Syntax (); ! 239: brdr_color = argv [ind]; ! 240: continue; ! 241: } ! 242: ! 243: if (strcmp (argv [ind], "-cr") == 0) { ! 244: if (++ind >= argc) Syntax (); ! 245: curs_color = argv [ind]; ! 246: continue; ! 247: } ! 248: ! 249: if (strcmp (argv [ind], "-ms") == 0) { ! 250: if (++ind >= argc) Syntax (); ! 251: mous_color = argv [ind]; ! 252: continue; ! 253: } ! 254: ! 255: if (strcmp (argv [ind], "-l") == 0) { ! 256: dologinflag = 1; ! 257: continue; ! 258: } ! 259: ! 260: if (strcmp (argv [ind], "-d") == 0) { ! 261: debug = 1; ! 262: continue; ! 263: } ! 264: ! 265: if (strcmp (argv [ind], "-b") == 0) { ! 266: if (++ind >= argc) Syntax (); ! 267: border = atoi (argv [ind]); ! 268: continue; ! 269: } ! 270: ! 271: if (strcmp (argv [ind], "-bw") == 0 || ! 272: strcmp (argv [ind], "-w") == 0) { ! 273: if (++ind >= argc) Syntax (); ! 274: borderwidth = atoi (argv [ind]); ! 275: continue; ! 276: } ! 277: ! 278: if (strcmp (argv [ind], "-rv") == 0 || ! 279: strcmp (argv [ind], "-r") == 0) { ! 280: reverse = 1; /* backwards from usual definition */ ! 281: continue; ! 282: } ! 283: ! 284: if (strcmp (argv [ind], "-s") == 0) { ! 285: multiscroll = 1; ! 286: continue; ! 287: } ! 288: ! 289: if (strcmp (argv [ind], "-i") == 0) { ! 290: bitmapicon = 1; ! 291: continue; ! 292: } ! 293: ! 294: #ifdef JUMPSCROLL ! 295: if (strcmp (argv [ind], "-j") == 0) { ! 296: jumpscroll = 1; ! 297: continue; ! 298: } ! 299: #endif JUMPSCROLL ! 300: ! 301: if (strcmp (argv [ind], "-n") == 0) { ! 302: if (++ind >= argc) Syntax (); ! 303: win_name = argv [ind]; ! 304: continue; ! 305: } ! 306: #ifdef sun ! 307: #ifdef TIOCCONS ! 308: if (strcmp (argv [ind], "-C") == 0) { ! 309: SunConsole = 1; ! 310: continue; ! 311: } ! 312: #endif TIOCCONS ! 313: #endif sun ! 314: ! 315: Syntax (); ! 316: } ! 317: ! 318: if (fnflag && !fbflag) fb = fn; ! 319: if (!fnflag && fbflag) fn = fb; ! 320: #ifdef JUMPSCROLL ! 321: if(tek) ! 322: jumpscroll = 0; ! 323: #endif JUMPSCROLL ! 324: Serve (display, fn, fb, geometry, def, getty, slave, passedPty, ! 325: border, borderwidth, tek, reverse, multiscroll, bitmapicon, ! 326: fore_color, back_color, brdr_color, curs_color, mous_color ! 327: #ifdef JUMPSCROLL ! 328: , jumpscroll ! 329: #endif JUMPSCROLL ! 330: ); ! 331: } ! 332: ! 333: Syntax () ! 334: { ! 335: static char *ustring[] = { ! 336: "Usage: xterm [-rv] [-fn normal_font] [-fb bold_font]\n", ! 337: "\t[=[width]x[height][[+-]xoff[[+-]yoff]]] [-bw bdr_width]\n", ! 338: "\t[-fg color] [-bg color] [-bd color] [-cr color] [-ms color]\n", ! 339: "\t[[[host]:vs]] [-d] [-s] [-t] [-i] [-j] [-e command_to_exec]\n", ! 340: "\t[-n window_name]\n\n", ! 341: "Fonts must be of fixed width and of same size;\n", ! 342: "If only one font is specified, it will be used for normal and bold text\n", ! 343: #ifdef JUMPSCROLL ! 344: "The -j option enables jump scroll\n", ! 345: #endif ! 346: "The -s option enables asynchronous scrolling\n", ! 347: "The -t option enables Tektronics 4010 emulation\n", ! 348: "The -i option enables bitmap icons\n", ! 349: "The -d option turns debugging on (error messages printed)\n", ! 350: "The -n option sets the window name\n", ! 351: "The -b option specifies the inner padding\n", ! 352: "Default is: xterm -fn vtsingle -fb vtbold =80x24 :0\n", ! 353: 0}; ! 354: char **us = ustring; ! 355: while (*us) fputs(*us++, stderr); ! 356: exit (1); ! 357: } ! 358: ! 359: char *strscan (search, what) ! 360: /* ! 361: Returns pointer to first char ins search which is also in what, else NULL. ! 362: */ ! 363: char *search, *what; ! 364: { ! 365: int i, len = strlen (what); ! 366: char c; ! 367: ! 368: while ((c = *(search++)) != NULL) ! 369: for (i = 0; i < len; i++) ! 370: if (c == what [i]) return (--search); ! 371: ! 372: return (NULL); ! 373: } ! 374: ! 375: Serve (disp, fn, fb, geometry, def, getty, slave, passedPty, ! 376: border, borderwidth, tek, reverse, multiscroll, bitmapicon, ! 377: fore_color, back_color, brdr_color, curs_color, mous_color ! 378: #ifdef JUMPSCROLL ! 379: , jumpscroll ! 380: #endif JUMPSCROLL ! 381: ) ! 382: char *disp; /* host of display to serve */ ! 383: char *fn; /* fontname of normal characters */ ! 384: char *fb; /* fontname of bold characters */ ! 385: char *getty; /* true iff child should be getty */ ! 386: int slave; /* true if should run as slave (contains file # of pty) */ ! 387: char *passedPty; /* name of pty to use if slave */ ! 388: char *geometry; /* user supplied geometry spec */ ! 389: char *def; /* default geometry spec */ ! 390: int border; /* inner border in pixels */ ! 391: int borderwidth; /* outer border in pixels */ ! 392: int tek; /* true ==> Tektronics emulation */ ! 393: int reverse; /* true ==> black background, white characters */ ! 394: int multiscroll; /* true ==> asynchronous full-screen scrolling */ ! 395: int bitmapicon; /* true ==> bitmap icons rather than text icon */ ! 396: #ifdef JUMPSCROLL ! 397: int jumpscroll; /* true ==> fast multi-line scrolling */ ! 398: #endif JUMPSCROLL ! 399: char *fore_color;/* text color */ ! 400: char *back_color;/* background color */ ! 401: char *brdr_color;/* border color */ ! 402: char *curs_color;/* text cursor color */ ! 403: char *mous_color;/* mouse cursor color */ ! 404: { ! 405: int pty; /* fildes for pty of client */ ! 406: XEvent reply; ! 407: XEvent *rep = & reply; ! 408: int aborted = 0; ! 409: int Select_mask, select_mask = 0; ! 410: int maxplus1; ! 411: short toggled = NULL; ! 412: Screen *screen = &term.screen; ! 413: int Xsocket; ! 414: int pty_mask, X_mask; ! 415: extern int errno; ! 416: int mode = 1; ! 417: #ifdef TIOCSWINSZ ! 418: struct winsize ws; ! 419: #endif ! 420: ! 421: signal (SIGCHLD, reapchild); ! 422: signal (SIGHUP, SIG_IGN); ! 423: ! 424: /* open a terminal for client */ ! 425: get_terminal (disp, &term, fn, fb, geometry, def, border, ! 426: borderwidth, (int)getty, slave, reverse, multiscroll, bitmapicon, ! 427: tek, fore_color, back_color, brdr_color, curs_color, mous_color ! 428: #ifdef JUMPSCROLL ! 429: , jumpscroll ! 430: #endif JUMPSCROLL ! 431: ); ! 432: ! 433: Xsocket = screen->display->fd; ! 434: ! 435: spawn (disp, &pty, Xsocket, screen, getty, slave, passedPty); ! 436: ! 437: if (slave) { /* Write window id so master end can read and use */ ! 438: write(pty, &screen->window, sizeof(screen->window)); ! 439: write(pty, "\n", 1); ! 440: } ! 441: ! 442: screen->respond = term.buf.fildes = pty; ! 443: ! 444: #ifdef TIOCSWINSZ ! 445: /* tell tty how big window is */ ! 446: ws.ws_row = screen->max_row + 1; ! 447: ws.ws_col = screen->max_col + 1; ! 448: ws.ws_xpixel = screen->width; ! 449: ws.ws_ypixel = screen->height; ! 450: ioctl (screen->respond, TIOCSWINSZ, &ws); ! 451: #endif ! 452: ! 453: /* Initialize Tektronix graphics mode parameters */ ! 454: TekErase (&term); ! 455: screen->TekEmu = tek; ! 456: screen->cur_x = screen->cur_y = 0; ! 457: screen->cur_X = screen->cur_Y = 0; ! 458: screen->TekGMode = 0; ! 459: screen->TekAMode = 0; ! 460: screen->TekPMode = 0; ! 461: ! 462: if (ioctl (pty, FIONBIO, &mode) == -1) Error (); ! 463: ! 464: pty_mask = 1 << pty; ! 465: X_mask = 1 << Xsocket; ! 466: Select_mask = pty_mask | X_mask; ! 467: maxplus1 = (pty < Xsocket) ? (1 + Xsocket) : (1 + pty); ! 468: ! 469: if (debug) printf ("debugging on\n"); ! 470: ! 471: while (1) ! 472: { ! 473: if (! aborted) ! 474: { ! 475: #ifdef JUMPSCROLL ! 476: if(screen->scroll_amt) ! 477: FlushScroll(screen); ! 478: #endif JUMPSCROLL ! 479: if (toggled) ! 480: { ! 481: CursorToggle (screen, toggled); ! 482: toggled = NULL; ! 483: } ! 484: ! 485: select_mask = Select_mask; ! 486: XFlush(); ! 487: while (select (maxplus1, &select_mask, NULL, NULL, 0) <= 0) { ! 488: if (errno != EINTR) Error(); ! 489: } ! 490: } ! 491: else select_mask = NULL; ! 492: ! 493: if (select_mask & pty_mask || aborted) ! 494: { ! 495: if (!toggled) ! 496: { ! 497: CursorToggle (screen, toggled); ! 498: toggled = 1; ! 499: } ! 500: do { ! 501: aborted = (*screen->mode)(&term); ! 502: } while (screen->display->qlen==0 && term.buf.cnt>0); ! 503: } ! 504: ! 505: if (select_mask & X_mask || aborted) ! 506: { ! 507: #ifdef JUMPSCROLL ! 508: if(screen->scroll_amt) ! 509: FlushScroll(screen); ! 510: #endif JUMPSCROLL ! 511: XPending (); ! 512: do { ! 513: XNextEvent (&reply); ! 514: ! 515: switch ((int)reply.type) ! 516: { ! 517: case KeyPressed: ! 518: Input (&term.keyboard, &term.screen, ! 519: (XKeyPressedEvent *)rep); ! 520: break; ! 521: ! 522: case ExposeWindow: ! 523: if (bitmapicon) { ! 524: if (((XExposeWindowEvent *)rep)->window ! 525: == screen->iconwindow) { ! 526: RefreshIcon(screen); ! 527: break; ! 528: } ! 529: } ! 530: toggled = 1; ! 531: if (ScreenResize (screen, ! 532: ((XExposeWindowEvent *)rep)->width, ! 533: ((XExposeWindowEvent *)rep)->height, ! 534: &term.flags) != -1) ! 535: { ! 536: TabReset (term.tabs); ! 537: XClear (screen->window); ! 538: ScrnRefresh (screen, 0, 0, ! 539: screen->max_row + 1, ! 540: screen->max_col + 1); ! 541: ! 542: if (screen->TekEmu) TekRefresh (&term); ! 543: } ! 544: break; ! 545: ! 546: case ExposeRegion: ! 547: if (((XExposeWindowEvent *)rep)->detail == ! 548: ExposeCopy && ! 549: screen->incopy <= 0) { ! 550: screen->incopy = 1; ! 551: if (screen->scrolls > 0) ! 552: screen->scrolls--; ! 553: } ! 554: if (HandleExposure (screen, &reply)) ! 555: toggled = 1; ! 556: break; ! 557: ! 558: case ExposeCopy: ! 559: if (screen->incopy <= 0 && screen->scrolls > 0) ! 560: screen->scrolls--; ! 561: if (screen->scrolls) ! 562: screen->incopy = -1; ! 563: else ! 564: screen->incopy = 0; ! 565: break; ! 566: ! 567: case ButtonPressed: ! 568: case ButtonReleased: ! 569: if (screen->incopy) ! 570: CopyWait (screen); ! 571: if (HandleButtons(&term,&reply,pty)) ! 572: toggled = 1; ! 573: break; ! 574: /* ! 575: * Enter window is being handled just to give xterm ! 576: * a kick in the pants when the mouse gets in the ! 577: * window in case it was swapped out. Of course, ! 578: * one might thrash... ! 579: */ ! 580: case EnterWindow: ! 581: break; ! 582: default: ! 583: break; ! 584: } ! 585: } while (screen->display->qlen > 0); ! 586: } ! 587: } ! 588: } ! 589: ! 590: RefreshIcon(screen) ! 591: register Screen *screen; ! 592: { ! 593: XBitmapBitsPut(screen->iconwindow, 0, 0, icon_width, icon_height, ! 594: icon_bits, screen->foreground, screen->background, ! 595: screen->iconmask, GXcopy, AllPlanes); ! 596: } ! 597: ! 598: get_pty (pty, pty_name) ! 599: /* ! 600: opens a pty, storing fildes in pty ! 601: and it's identifying character in pty_name. ! 602: */ ! 603: int *pty; ! 604: char *pty_name; ! 605: { ! 606: int devindex, letter = 0; ! 607: int fd; ! 608: extern errno; ! 609: ! 610: if (debug) { ! 611: fd = open ("xterm.debug.log", O_WRONLY | O_CREAT | O_TRUNC, 0666); ! 612: dup2 (fd, fileno (stderr)); ! 613: } ! 614: ! 615: while (letter < 4) { ! 616: ttydev [8] = ptydev [8] = "pqrs" [letter++]; ! 617: devindex = 0; ! 618: ! 619: while (devindex < 16) { ! 620: ptydev [9] = *pty_name = "0123456789abcdef" [devindex++]; ! 621: if ((*pty = open (ptydev, O_RDWR, 0)) < 0) { ! 622: if (debug) fprintf (stderr, "pty %d code %d\n", ! 623: devindex - 1, errno); ! 624: continue; ! 625: } ! 626: goto got_pty; ! 627: } ! 628: } ! 629: ! 630: fprintf (stderr,"Not enough available pty's\n"); ! 631: exit (11); ! 632: ! 633: got_pty: ! 634: if (debug) { ! 635: close (fileno (stderr)); ! 636: close (fd); ! 637: } ! 638: } ! 639: ! 640: get_terminal (disp, term, fn, fb, geometry, def, ! 641: border, borderwidth, do_warp, slave, reverse, multiscroll, bitmapicon, ! 642: tek, fore_color, back_color, brdr_color, curs_color, mous_color ! 643: #ifdef JUMPSCROLL ! 644: , jumpscroll ! 645: #endif JUMPSCROLL ! 646: ) ! 647: /* ! 648: * sets up X and initializes the terminal structure except for term.buf.fildes. ! 649: */ ! 650: char *disp; ! 651: register Terminal *term; ! 652: char *fn, *fb; ! 653: char *geometry, *def; ! 654: int border, borderwidth, do_warp, reverse, multiscroll, bitmapicon; ! 655: int slave; ! 656: int tek; ! 657: #ifdef JUMPSCROLL ! 658: int jumpscroll; ! 659: #endif JUMPSCROLL ! 660: char *fore_color, *back_color, *brdr_color, *curs_color, *mous_color; ! 661: { ! 662: int width, height; ! 663: FontInfo *fInfo; ! 664: register Keyboard *keyboard; ! 665: register Screen *screen; ! 666: Buffer *buf; ! 667: double scale_x, scale_y; ! 668: Color cdef; ! 669: int pixels[2]; ! 670: int try = 10; ! 671: OpaqueFrame twindow; ! 672: ! 673: keyboard = &term->keyboard; ! 674: screen = &term->screen; ! 675: buf = &term->buf; ! 676: ! 677: term->flags = WRAPAROUND|SMOOTHSCROLL; ! 678: ! 679: keyboard->flags = NULL; ! 680: keyboard->offset = 0; ! 681: ! 682: buf->cnt = 0; ! 683: buf->ptr = &buf->buf[0]; ! 684: ! 685: TabReset (term->tabs); ! 686: ! 687: while (try--) ! 688: if ((screen->display = XOpenDisplay(disp)) == NULL) { ! 689: if (loginflag == 0) { ! 690: fprintf(stderr,"No such display server %s\n", disp); ! 691: exit(1); ! 692: } ! 693: sleep (5); ! 694: continue; ! 695: } ! 696: else break; ! 697: ! 698: if (try <= 0) { ! 699: fprintf (stderr,"Can't connect to display server %s\n", ! 700: disp); ! 701: exit (111); ! 702: } ! 703: ! 704: screen->foreground = BlackPixel; ! 705: screen->background = WhitePixel; ! 706: screen->cursorcolor = BlackPixel; ! 707: screen->mousecolor = BlackPixel; ! 708: screen->xorplane = 1; ! 709: if (DisplayCells() > 2 && (fore_color || back_color || curs_color)) { ! 710: if (tek) { ! 711: if (curs_color && XParseColor(curs_color, &cdef)) { ! 712: if (XGetColorCells(0, 2, 1, &screen->xorplane, ! 713: pixels)) { ! 714: screen->background = pixels[0]; ! 715: screen->foreground = pixels[1]; ! 716: screen->cursorcolor = screen->background | ! 717: screen->xorplane; ! 718: cdef.pixel = screen->cursorcolor; ! 719: XStoreColor(&cdef); ! 720: } ! 721: } ! 722: else if (XGetColorCells(0, 1, 1, &screen->xorplane, ! 723: &screen->background)) { ! 724: screen->foreground = screen->background | ! 725: screen->xorplane; ! 726: screen->cursorcolor = screen->foreground; ! 727: } ! 728: if (screen->background != WhitePixel) { ! 729: if (back_color == NULL || ! 730: !XParseColor(back_color, &cdef)) { ! 731: cdef.pixel = WhitePixel; ! 732: XQueryColor(&cdef); ! 733: } ! 734: cdef.pixel = screen->background; ! 735: XStoreColor(&cdef); ! 736: if(screen->cursorcolor != screen->foreground) { ! 737: cdef.pixel = screen->foreground | ! 738: screen->xorplane; ! 739: XStoreColor(&cdef); ! 740: } ! 741: if (fore_color == NULL || ! 742: !XParseColor(fore_color, &cdef)) { ! 743: cdef.pixel = BlackPixel; ! 744: XQueryColor(&cdef); ! 745: } ! 746: cdef.pixel = screen->foreground; ! 747: XStoreColor(&cdef); ! 748: } ! 749: } ! 750: else { ! 751: if (fore_color && XParseColor(fore_color, &cdef) && ! 752: XGetHardwareColor(&cdef)) { ! 753: screen->foreground = ! 754: screen->foreground = cdef.pixel; ! 755: reverse = 0; ! 756: } ! 757: if (back_color && XParseColor(back_color, &cdef) && ! 758: XGetHardwareColor(&cdef)) { ! 759: screen->background = cdef.pixel; ! 760: reverse = 0; ! 761: } ! 762: if (curs_color && XParseColor(curs_color, &cdef) && ! 763: XGetHardwareColor(&cdef)) ! 764: screen->cursorcolor = cdef.pixel; ! 765: else ! 766: screen->cursorcolor = screen->foreground; ! 767: } ! 768: } ! 769: ! 770: screen->border = border; ! 771: screen->borderwidth = borderwidth; ! 772: screen->fnt_norm = screen->fnt_bold = NULL; ! 773: ! 774: if ((fInfo = XOpenFont(fn)) == NULL) { ! 775: fprintf(stderr, "%s: Could not open font %s!\n", ! 776: xterm_name, fn); ! 777: exit(1); ! 778: } ! 779: if (fn) screen->fnt_norm = fInfo->id; ! 780: if (fb) screen->fnt_bold = XOpenFont(fb)->id; ! 781: screen->f_width = fInfo->width; ! 782: screen->f_height = fInfo->height; ! 783: ! 784: if (brdr_color && DisplayCells() > 2 && ! 785: XParseColor(brdr_color, &cdef) && XGetHardwareColor(&cdef)) ! 786: screen->bordertile = XMakeTile(cdef.pixel); ! 787: else ! 788: screen->bordertile = BlackPixmap; ! 789: ! 790: screen->cursor = XStoreBitmap(xterm_width, xterm_height, xterm_bits); ! 791: screen->mask = XStoreBitmap(xterm_mask_width, xterm_mask_height, ! 792: xterm_mask_bits); ! 793: if (mous_color && DisplayCells() > 2 && ! 794: XParseColor(mous_color, &cdef) && XGetHardwareColor(&cdef)) ! 795: screen->mousecolor = cdef.pixel; ! 796: else ! 797: screen->mousecolor = screen->cursorcolor; ! 798: screen->curs = XStoreCursor(screen->cursor, screen->mask, 5, 8, ! 799: screen->mousecolor, screen->background, GXcopy); ! 800: screen->rcurs = XStoreCursor(screen->cursor, screen->mask, 5, 8, ! 801: screen->background, screen->mousecolor, GXcopy); ! 802: ! 803: if (reverse) { /* reverse is black background with white chars */ ! 804: term->flags |= REVERSE_VIDEO; ! 805: screen->cursorcolor = screen->background; ! 806: screen->background = screen->foreground; ! 807: screen->foreground = screen->cursorcolor; ! 808: if (screen->bordertile == BlackPixmap) ! 809: screen->bordertile = WhitePixmap; ! 810: } ! 811: screen->bgndtile = XMakeTile(screen->background); ! 812: ! 813: twindow.bdrwidth = screen->borderwidth; ! 814: twindow.border = screen->bordertile; ! 815: twindow.background = screen->bgndtile; ! 816: ! 817: screen->window = XCreateTerm ("Terminal Emulator", xterm_name, ! 818: geometry, def, &twindow, 12, 8, ! 819: screen->border * 2, screen->border * 2, ! 820: &width, &height, ! 821: fInfo, fInfo->width, fInfo->height); ! 822: ! 823: screen->width = twindow.width - border * 2; ! 824: screen->height = twindow.height - border * 2; ! 825: ! 826: /* Reset variables used by ANSI emulation. */ ! 827: ! 828: screen->ansi.a_type = 0; /* New sequence. */ ! 829: screen->ansi.a_pintro = 0; /* New sequence. */ ! 830: screen->ansi.a_final = 0; /* New sequence. */ ! 831: screen->gsets[0] = 'B'; /* ASCII_G */ ! 832: screen->gsets[1] = 'B'; ! 833: screen->gsets[2] = '<'; /* DEC supplemental. */ ! 834: screen->gsets[3] = '<'; ! 835: screen->curgl = 0; /* G0 => GL. */ ! 836: screen->curgr = 2; /* G2 => GR. */ ! 837: screen->curss = 0; /* No single shift. */ ! 838: screen->rx8bit = 0; /* 7 bit. */ ! 839: screen->tx8bit = 0; /* 7 bit. */ ! 840: screen->mode = ANSInormal; ! 841: ! 842: /* Reset Tektronix alpha mode */ ! 843: screen->TekGMode = 0; ! 844: screen->TekAMode = 0; ! 845: screen->cur_x = screen->cur_y = 0; ! 846: screen->cur_X = screen->cur_Y = 0; ! 847: ! 848: scale_x = screen->width / 4096.0; ! 849: scale_y = screen->height / 3128.0; ! 850: screen->TekScale = scale_x; ! 851: if (scale_y < scale_x) screen->TekScale = scale_y; ! 852: ! 853: if (bitmapicon) { ! 854: screen->iconwindow = XCreateWindow (RootWindow, ! 855: 0, 0, icon_width, icon_height, 0, 0, 0); ! 856: ! 857: XTileRelative(screen->iconwindow); ! 858: ! 859: XSetIconWindow(screen->window, screen->iconwindow); ! 860: ! 861: screen->iconmask = XStoreBitmap(icon_mask_width, ! 862: icon_mask_height, icon_mask_bits); ! 863: ! 864: XSelectInput (screen->iconwindow, ExposeWindow); ! 865: } ! 866: ! 867: if (reverse) ! 868: XDefineCursor(screen->window, screen->rcurs); ! 869: else XDefineCursor(screen->window, screen->curs); ! 870: ! 871: XStoreName (screen->window, (win_name != (char *) 0 ? win_name: ! 872: (do_warp ? "login" : ! 873: (slave ? "xtermslave" : ! 874: (command_to_exec ? command_to_exec[0] : "xterm"))))); ! 875: ! 876: XSetResizeHint (screen->window, ! 877: 2 * border, 2 * border, fInfo->width, fInfo->height); ! 878: ! 879: XMapWindow (screen->window); ! 880: ! 881: XSelectInput (screen->window, KeyPressed | ExposeWindow | EnterWindow | ! 882: ButtonPressed | ButtonReleased | ExposeRegion | ExposeCopy); ! 883: ! 884: ! 885: if (do_warp) ! 886: XWarpMouse (screen->window, ! 887: screen->width >> 1, screen->height >>1); ! 888: ! 889: screen->cur_col = screen->cur_row = 0; ! 890: screen->max_col = screen->width / fInfo->width - 1; ! 891: screen->top_marg = 0; ! 892: screen->bot_marg = screen->max_row = screen->height/ fInfo->height - 1; ! 893: ! 894: screen->sc.row = screen->sc.col = screen->sc.flags = NULL; ! 895: ! 896: ! 897: /* allocate memory for screen buffer */ ! 898: screen->buf = (ScrnBuf) Allocate (screen->max_row + 1, ! 899: screen->max_col +1); ! 900: ! 901: screen->do_wrap = NULL; ! 902: screen->scrolls = screen->incopy = 0; ! 903: screen->multiscroll = multiscroll; ! 904: #ifdef JUMPSCROLL ! 905: if (screen->jumpscroll = jumpscroll) ! 906: term->flags &= ~SMOOTHSCROLL; ! 907: #endif JUMPSCROLL ! 908: ! 909: ! 910: /* display initial cursor */ ! 911: CursorToggle (screen, 1); ! 912: } ! 913: ! 914: spawn (display, pty, Xsocket, screen, getty, slave, passedPty) ! 915: /* ! 916: * Inits pty and tty and forks a login process. Returns fd for pty in pty. ! 917: * Does not close fd Xsocket. ! 918: * If getty, execs getty rather than csh and uses std fd's rather ! 919: * than opening a pty/tty pair. ! 920: * If slave, the pty named in passedPty is already open for use ! 921: */ ! 922: int *pty, Xsocket; ! 923: Screen *screen; ! 924: char *getty; /* if true execs /etc/getty - Xwindow */ ! 925: int slave; ! 926: char *passedPty; ! 927: char *display; ! 928: { ! 929: int index1, tty; ! 930: char pty_name; ! 931: int discipline; ! 932: unsigned lmode; ! 933: struct tchars tc; ! 934: struct ltchars ltc; ! 935: struct sgttyb sg; ! 936: ! 937: char termcap [1024]; ! 938: char newtc [1024]; ! 939: char prog [256]; ! 940: char numbuf[10]; ! 941: char *ptr; ! 942: char *index (), *strindex (); ! 943: int i = 0; ! 944: char **envnew; /* new environment */ ! 945: struct passwd *getpwuid(); ! 946: struct passwd *pw; ! 947: char logindev[32]; ! 948: char *TermName = "xterm"; ! 949: int ldisc = 0; ! 950: ! 951: /* be real paranoid about getting some usable entry */ ! 952: if (tgetent (termcap, TermName) == 1 ! 953: || (TermName = "vt102", tgetent(termcap, TermName)) == 1 ! 954: || (TermName = "ansi", tgetent(termcap, TermName)) == 1) { ! 955: /* update termcap string */ ! 956: /* first do columns */ ! 957: if ((ptr = strindex (termcap, "co#")) == NULL){ ! 958: fprintf(stderr,"Can't find co# in termcap string %s\n", ! 959: TermName); ! 960: exit (1); ! 961: } ! 962: strncpy (newtc, termcap, ptr - termcap + 3); ! 963: newtc[ptr-termcap+3] = '\0'; ! 964: sprintf (numbuf, "%d\0", screen->max_col + 1); ! 965: strcat (newtc, numbuf); ! 966: ptr = index (ptr, ':'); ! 967: strcat (newtc, ptr); ! 968: strncpy (termcap, newtc, sizeof(termcap)); ! 969: /* now do lines */ ! 970: if ((ptr = strindex (termcap, "li#")) == NULL) { ! 971: fprintf(stderr,"Can't find li# in termcap string %s\n", ! 972: TermName); ! 973: exit (1); ! 974: } ! 975: strncpy (newtc, termcap, ptr - termcap + 3); ! 976: newtc[ptr-termcap+3] = '\0'; ! 977: sprintf (numbuf, "%d\0", screen->max_row + 1); ! 978: strcat (newtc, numbuf); ! 979: ptr = index (ptr, ':'); ! 980: strcat (newtc, ptr); ! 981: if (strcmp(TermName, "xterm") != 0) ! 982: fprintf(stderr, ! 983: "xterm: can't find xterm termcap entry, using %s instead!\n", TermName); ! 984: } ! 985: else fprintf(stderr,"xterm: can't find any usable termcap entry!\n"); ! 986: ! 987: if (getty) { ! 988: strcpy(logindev,"/dev/"); ! 989: strcat(logindev,getty); ! 990: logindev [5] = 'p'; ! 991: *pty = open (logindev, O_RDWR, 0); ! 992: } ! 993: else if (slave) { ! 994: *pty = slave; ! 995: ptydev[8] = ttydev[8] = passedPty[0]; ! 996: ptydev[9] = ttydev[9] = passedPty[1]; ! 997: } ! 998: else { ! 999: if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0) { ! 1000: if (errno != ENXIO) Error(); ! 1001: else { ! 1002: no_dev_tty = 1; ! 1003: sg = d_sg; ! 1004: tc = d_tc; ! 1005: discipline = d_disipline; ! 1006: ltc = d_ltc; ! 1007: lmode = d_lmode; ! 1008: for (index1 = 0; index1 < 3; index1++) ! 1009: close (index1); ! 1010: } ! 1011: } ! 1012: else { ! 1013: /* get a copy of the current terminal's state */ ! 1014: ! 1015: if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0) Error (); ! 1016: ! 1017: if (ioctl (tty, TIOCGETP, &sg) == -1) Error (); ! 1018: if (ioctl (tty, TIOCGETC, (int *)&tc) == -1) Error (); ! 1019: if (ioctl (tty, TIOCGETD, &discipline) == -1) Error (); ! 1020: if (ioctl (tty, TIOCGLTC, (int *)<c) == -1) Error (); ! 1021: if (ioctl (tty, TIOCLGET, &lmode) == -1) Error (); ! 1022: ! 1023: close (tty); ! 1024: ! 1025: /* close all std file descriptors */ ! 1026: for (index1 = 0; index1 < 3; index1++) ! 1027: close (index1); ! 1028: if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0) Error (); ! 1029: ! 1030: if (ioctl (tty, TIOCNOTTY, 0) == -1) Error (); ! 1031: close (tty); ! 1032: } ! 1033: ! 1034: get_pty (pty, &pty_name); ! 1035: ! 1036: if (*pty != Xsocket + 1) { ! 1037: dup2 (*pty, Xsocket + 1); ! 1038: close (*pty); ! 1039: *pty = Xsocket + 1; ! 1040: } ! 1041: ! 1042: ttydev [9] = pty_name; ! 1043: if ((tty = open (ttydev, O_RDWR, 0)) < 0) Error (); ! 1044: ! 1045: /* change ownership of tty to real group and user id */ ! 1046: chown (ttydev, getuid (), tty_gid (getgid())); ! 1047: ! 1048: /* change protection of tty */ ! 1049: chmod (ttydev, 0620); ! 1050: ! 1051: if (tty != Xsocket + 2) { ! 1052: dup2 (tty, Xsocket + 2); ! 1053: close (tty); ! 1054: tty = Xsocket + 2; ! 1055: } ! 1056: ! 1057: /* set the new terminal's state to be the old one's ! 1058: with minor modifications for efficiency */ ! 1059: ! 1060: sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW); ! 1061: sg.sg_flags |= ECHO | CRMOD; ! 1062: /* make sure speed is set on pty so that editors work right*/ ! 1063: sg.sg_ispeed = B9600; ! 1064: sg.sg_ospeed = B9600; ! 1065: ! 1066: if (ioctl (tty, TIOCSETP, &sg) == -1) Error (); ! 1067: if (ioctl (tty, TIOCSETC, (int *)&tc) == -1) Error (); ! 1068: if (ioctl (tty, TIOCSETD, &discipline) == -1) Error (); ! 1069: if (ioctl (tty, TIOCSLTC, (int *)<c) == -1) Error (); ! 1070: if (ioctl (tty, TIOCLSET, &lmode) == -1) Error (); ! 1071: #ifdef sun ! 1072: #ifdef TIOCCONS ! 1073: if (SunConsole) { ! 1074: int on = 1; ! 1075: if (ioctl (tty, TIOCCONS, &on) == -1) Error(); ! 1076: } ! 1077: #endif TIOCCONS ! 1078: #endif sun ! 1079: ! 1080: close (open ("/dev/null", O_RDWR, 0)); ! 1081: ! 1082: for (index1 = 0; index1 < 3; index1++) ! 1083: dup2 (tty, index1); ! 1084: } ! 1085: ! 1086: if (!slave && (screen->pid = fork ()) == -1) Error (); ! 1087: ! 1088: if (!slave && screen->pid == 0) { ! 1089: extern char **environ; ! 1090: int pgrp = getpid(); ! 1091: ! 1092: close (Xsocket); ! 1093: close (*pty); ! 1094: ! 1095: if (getty == NULL) close (tty); ! 1096: ! 1097: signal (SIGCHLD, SIG_DFL); ! 1098: signal (SIGHUP, SIG_IGN); ! 1099: ! 1100: /* copy the environment before Setenving */ ! 1101: while (environ [i] != NULL) i++; ! 1102: envnew = (char **) malloc (sizeof (char *) * (i + 4)); ! 1103: for (; i >= 0; i--) envnew [i] = environ [i]; ! 1104: environ = envnew; ! 1105: Setenv ("TERM=", TermName); ! 1106: Setenv ("TERMCAP=", newtc); ! 1107: /* put the display into the environment of the shell*/ ! 1108: if (display[0] != '\0') ! 1109: Setenv ("DISPLAY=", screen->display->displayname); ! 1110: ! 1111: pw = getpwuid (getuid ()); ! 1112: signal(SIGTERM, SIG_DFL); ! 1113: ioctl(0, TIOCSPGRP, &pgrp); ! 1114: setpgrp (0, 0); ! 1115: close(open(ttyname(0), O_WRONLY, 0)); ! 1116: setpgrp (0, pgrp); ! 1117: if (dologinflag) /* login */ ! 1118: utrelog(1, pw->pw_name, screen->display->displayname); ! 1119: ! 1120: setgid(getgid ()); ! 1121: setuid(getuid ()); ! 1122: ! 1123: if (command_to_exec) { ! 1124: execvp(command_to_exec[0], command_to_exec, 0); ! 1125: } ! 1126: signal(SIGHUP, SIG_IGN); ! 1127: if (getty) { ! 1128: ioctl (0, TIOCNOTTY, 0); ! 1129: execl ("/etc/getty", "+", "Xwindow", getty, 0); ! 1130: } ! 1131: signal(SIGHUP, SIG_DFL); ! 1132: ! 1133: if (*pw->pw_shell == '\0') pw->pw_shell = "/bin/sh"; ! 1134: ! 1135: /* make sure line discipline gets set */ ! 1136: ldisc = 0; ! 1137: ioctl(0, TIOCSETD, &ldisc); ! 1138: if (!strcmp(pw->pw_shell, "/bin/csh")) { ! 1139: ldisc = NTTYDISC; ! 1140: ioctl(0, TIOCSETD, &ldisc); ! 1141: } ! 1142: ! 1143: ptr = rindex(pw->pw_shell, '/'); ! 1144: if (ptr == NULL) ! 1145: ptr = pw->pw_shell; ! 1146: else ! 1147: ptr++; ! 1148: if (dologinflag) { ! 1149: prog[0] = '-'; ! 1150: strcpy(&prog[1], ptr); ! 1151: } else ! 1152: strcpy(prog, ptr); ! 1153: execlp (pw->pw_shell, prog, 0); ! 1154: fprintf (stderr,"Error: Could not exec %s!\n", pw->pw_shell); ! 1155: sleep(5); ! 1156: Cleanup(121); ! 1157: } ! 1158: ! 1159: close (tty); ! 1160: signal(SIGHUP,SIG_IGN); ! 1161: signal(SIGTTOU,SIG_IGN); /* so that TIOCSWINSZ doesn't block */ ! 1162: ! 1163: if ((tty = open (no_dev_tty ? "/dev/null" : "/dev/tty", ! 1164: O_RDWR, 0)) < 0) Error(); ! 1165: for (index1 = 0; index1 < 3; index1++) ! 1166: dup2 (tty, index1); ! 1167: if (tty > 2) close (tty); ! 1168: ! 1169: /* set ids to user's */ ! 1170: /* ! 1171: setgid (getgid ()); ! 1172: setuid (getuid ()); ! 1173: setregid (getegid (), getgid ()); ! 1174: setreuid (geteuid (), getuid ()); ! 1175: */ ! 1176: ! 1177: } ! 1178: ! 1179: ! 1180: static reapchild () ! 1181: { ! 1182: extern Terminal term; ! 1183: register long pgrp; ! 1184: union wait status; ! 1185: int pid; ! 1186: ! 1187: if (debug) printf ("Exiting\n"); ! 1188: pid = wait3 (&status, WNOHANG, NULL); ! 1189: if (!pid) return; ! 1190: if (pid != term.screen.pid) return; ! 1191: ! 1192: if (dologinflag) ! 1193: utrelog(0, "", ""); ! 1194: Cleanup(0); ! 1195: } ! 1196: ! 1197: consolepr(string) ! 1198: char *string; ! 1199: { ! 1200: extern int errno; ! 1201: extern char *sys_errlist[]; ! 1202: int oerrno; ! 1203: int f; ! 1204: oerrno = errno; ! 1205: f = open("/dev/console",O_WRONLY, 0); ! 1206: write(f, "xterm: ", 7); ! 1207: write(f, string, strlen(string)); ! 1208: write(f, ": ", 2); ! 1209: write(f, sys_errlist[oerrno],strlen(sys_errlist[oerrno])); ! 1210: write(f, "\n", 1); ! 1211: close(f); ! 1212: if ((f = open("/dev/tty", 2, 0)) >= 0) { ! 1213: ioctl(f, TIOCNOTTY, 0); ! 1214: close(f); ! 1215: } ! 1216: } ! 1217: ! 1218: #define TTYGRPNAME "tty" ! 1219: ! 1220: tty_gid(default_gid) ! 1221: int default_gid; ! 1222: { ! 1223: struct group *getgrnam(), *gr; ! 1224: int gid = default_gid; ! 1225: ! 1226: gr = getgrnam(TTYGRPNAME); ! 1227: if (gr != (struct group *) 0) ! 1228: gid = gr->gr_gid; ! 1229: ! 1230: endgrent(); ! 1231: ! 1232: return (gid); ! 1233: } ! 1234: ! 1235: utrelog(io, user, display) ! 1236: int io; ! 1237: char *user; ! 1238: char *display; ! 1239: { ! 1240: struct utmp ut; ! 1241: struct ttyent *ty; ! 1242: register int s; ! 1243: long slot; ! 1244: int ufd; ! 1245: char *colon; ! 1246: ! 1247: if (io == 1) { ! 1248: strncpy(ut.ut_line, &ttydev[5], sizeof ut.ut_line); ! 1249: colon = index(display, ':'); ! 1250: if (colon) ! 1251: *colon = '\0'; ! 1252: strncpy(ut.ut_host, display, sizeof ut.ut_host); ! 1253: if (colon) ! 1254: *colon = ':'; ! 1255: strncpy(ut.ut_name, user, sizeof ut.ut_name); ! 1256: (void) time(&ut.ut_time); ! 1257: } ! 1258: else { ! 1259: strcpy(ut.ut_line, ""); ! 1260: strcpy(ut.ut_name, ""); ! 1261: strcpy(ut.ut_host, ""); ! 1262: ut.ut_time = 0; ! 1263: chown(ttydev, 0, 0); ! 1264: chmod(ttydev, 0666); ! 1265: } ! 1266: ! 1267: setttyent(); ! 1268: slot = 0; ! 1269: s = 0; ! 1270: while ((ty = getttyent()) != NULL) { ! 1271: s++; ! 1272: if (strcmp(ty->ty_name, &ttydev[5]) == 0) { ! 1273: slot = s; ! 1274: break; ! 1275: } ! 1276: } ! 1277: endttyent(); ! 1278: if (slot > 0 && (ufd = open("/etc/utmp", O_WRONLY, 0)) >= 0) { ! 1279: if (lseek(ufd, slot * sizeof ut, 0) < 0L || ! 1280: write(ufd, (char *)&ut, sizeof ut) != sizeof ut) { ! 1281: close(ufd); ! 1282: return(-1); ! 1283: } ! 1284: close(ufd); ! 1285: } ! 1286: return(0); ! 1287: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.