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 *)&ltc) == -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 *)&ltc) == -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: }

Defined functions

RefreshIcon defined in line 590; used 1 times
Serve defined in line 375; used 1 times
Syntax defined in line 333; used 14 times
consolepr defined in line 1197; used 1 times
get_pty defined in line 598; used 1 times
get_terminal defined in line 640; used 1 times
main defined in line 69; never used
reapchild defined in line 1180; used 2 times
spawn defined in line 914; used 1 times
strscan defined in line 359; used 1 times
  • in line 74
tty_gid defined in line 1220; used 1 times
utrelog defined in line 1235; used 2 times

Defined variables

SunConsole defined in line 64; used 2 times
am_slave defined in line 29; used 2 times
command_to_exec defined in line 42; used 6 times
d_disipline defined in line 57; used 1 times
d_lmode defined in line 58; used 1 times
d_ltc defined in line 53; used 1 times
d_sg defined in line 46; used 1 times
d_tc defined in line 49; used 1 times
debug defined in line 30; used 6 times
dologinflag defined in line 61; used 4 times
loginflag defined in line 60; used 2 times
no_dev_tty defined in line 59; used 2 times
ptydev defined in line 32; used 5 times
rcsid_ptyx_c defined in line 8; never used
ttydev defined in line 33; used 11 times
win_name defined in line 43; used 3 times
xterm_name defined in line 27; used 4 times

Defined macros

TTYGRPNAME defined in line 1218; used 1 times
Last modified: 1986-05-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4002
Valid CSS Valid XHTML 1.0 Strict