|
|
1.1 ! root 1: /* vtd.c - VT responder */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/vt/RCS/vtd.c,v 7.2 90/07/09 14:52:06 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/vt/RCS/vtd.c,v 7.2 90/07/09 14:52:06 mrose Exp $ ! 9: * ! 10: * ! 11: * $Log: vtd.c,v $ ! 12: * Revision 7.2 90/07/09 14:52:06 mrose ! 13: * sync ! 14: * ! 15: * Revision 7.1 89/11/30 23:51:42 mrose ! 16: * pa2str ! 17: * ! 18: * Revision 7.0 89/11/23 22:31:55 mrose ! 19: * Release 6.0 ! 20: * ! 21: */ ! 22: ! 23: /* ! 24: * NOTICE ! 25: * ! 26: * Acquisition, use, and distribution of this module and related ! 27: * materials are subject to the restrictions of a license agreement. ! 28: * Consult the Preface in the User's Manual for the full terms of ! 29: * this agreement. ! 30: * ! 31: */ ! 32: ! 33: ! 34: #undef MAP_BACKSPACE /*Map backspace character to VT ERASE CHAR*/ ! 35: ! 36: #include <signal.h> ! 37: #include "vtpm.h" ! 38: #include "sector1.h" ! 39: #include "tailor.h" ! 40: #include <sys/ioctl.h> ! 41: #ifdef BSD44 ! 42: #include <sys/termios.h> ! 43: #include <sys/ttydefaults.h> ! 44: #endif ! 45: ! 46: #ifndef _PATH_LOGIN ! 47: #ifndef BSD44 ! 48: #define _PATH_LOGIN "/bin/login" ! 49: #else ! 50: #define _PATH_LOGIN "/usr/bin/login" ! 51: #endif ! 52: #endif ! 53: ! 54: #include <arpa/telnet.h> ! 55: ! 56: #include <ctype.h> ! 57: #include <setjmp.h> ! 58: #include <pwd.h> ! 59: #include <varargs.h> ! 60: ! 61: #define BELL '\07' ! 62: #ifndef SUNOS4 ! 63: #define BANNER "\r\n\r\n4.2 BSD UNIX (%s)\r\n\r\n\r%s" ! 64: #else ! 65: #define BANNER "\r\n\r\nSunOS UNIX (%s)\r\n\r\n\r%s" ! 66: #endif ! 67: ! 68: int connected = FALSE; ! 69: char command[256]; ! 70: ! 71: ! 72: /* ! 73: * I/O data buffers, pointers, and counters. ! 74: */ ! 75: char ptyobuf[BUFSIZ], *pfrontp = ptyobuf, *pbackp = ptyobuf; ! 76: char netobuf[BUFSIZ], *nfrontp = netobuf, *nbackp = netobuf; ! 77: int pcc; ! 78: ! 79: VT_PROFILE vtp_profile; ! 80: int rflag = 0; ! 81: char erase_char; ! 82: char erase_line; ! 83: char intr_char; ! 84: char *crp = "\r"; ! 85: char *my_displayobj = "D"; /*Acceptor's Display Object Name*/ ! 86: char *my_echo_obj = "NA"; /*Acceptor's Negotiation Control Object Name*/ ! 87: char *my_signal_obj = "DI"; /*Acceptor's Signal Control Object*/ ! 88: char *his_echo_obj = "NI"; /*Initiator's Negotiation Control Object*/ ! 89: char *his_signal_obj = "KB"; /*Initiator/s Signal control Object*/ ! 90: int my_right = ACCEPTOR; ! 91: char kb_image; /*KB Control Object image*/ ! 92: char di_image; /*DI Control Object Image*/ ! 93: char ni_image; /*NI Control Object image*/ ! 94: char na_image; /*NA Control Object image*/ ! 95: char nego_state; /*Current state of NA affected options*/ ! 96: char sync_image; /*SY Control Object image*/ ! 97: char ga_image; ! 98: int transparent = 0; /*Flag for Transparent repertoire*/ ! 99: int telnet_profile =1; ! 100: int do_break = 1; /*If VT-BREAK agreed to*/ ! 101: int showoptions = 0; ! 102: int debug = 0; ! 103: ! 104: #ifdef BSD44 ! 105: struct termios oterm; ! 106: #else ! 107: struct tchars otc; ! 108: struct ltchars oltc; ! 109: struct sgttyb ottyb; ! 110: #endif ! 111: char *myhostname; ! 112: char peerhost[BUFSIZ]; ! 113: struct PSAPaddr ts_bound; ! 114: struct passwd *pwd; ! 115: ! 116: int pty, net; ! 117: int inter; ! 118: extern char **environ; ! 119: extern int errno; ! 120: char line[] = "/dev/ptyp0"; ! 121: char *envinit[] = { "TERM=network", 0 }; ! 122: SFD cleanup(); ! 123: static int do_cleaning = 0; ! 124: ! 125: char *myname; ! 126: LLog _vt_log = { ! 127: "vt.log", NULLCP, NULLCP, ! 128: LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL, -1, ! 129: LLOGCLS | LLOGCRT | LLOGZER, NOTOK ! 130: ! 131: }; ! 132: LLog *vt_log = &_vt_log; ! 133: ! 134: main(argc, argv) ! 135: int argc; ! 136: char *argv[]; ! 137: { ! 138: int f = 0; ! 139: char *cp = line; ! 140: char *logname = NULLCP; ! 141: int i, p, t; ! 142: char j; ! 143: #ifndef BSD44 ! 144: struct sgttyb b; ! 145: #endif ! 146: ! 147: if (myname = rindex (*argv, '/')) ! 148: myname++; ! 149: if (myname == NULL || *myname == NULL) ! 150: myname = *argv; ! 151: ! 152: isodetailor (myname, 0); ! 153: if (debug = isatty (fileno (stderr))) ! 154: ll_dbinit (vt_log, myname); ! 155: else ! 156: ll_hdinit (vt_log, myname); ! 157: ! 158: for(i=1; i<(argc - 2); i++) ! 159: { ! 160: if (!strcmp(argv[i], "-d")) ! 161: { ! 162: if (!isdigit(argv[++i][0]) ! 163: || sscanf(argv[i], "%d", &debug) != 1) ! 164: adios (NULLCP, "usage: %s -d 0-7", myname); ! 165: advise(LLOG_DEBUG,NULLCP, "setting debug level to %d", debug); ! 166: if (debug) ! 167: ll_dbinit (vt_log, myname); ! 168: } ! 169: else if(!strcmp(argv[i], "-F")) ! 170: { ! 171: if ((logname = argv[++i]) == NULL || *logname == '-') ! 172: adios (NULLCP, "usage: %s -F logfile", myname); ! 173: vt_log -> ll_file = logname; ! 174: (void) ll_close (vt_log); ! 175: advise(LLOG_DEBUG,NULLCP, "logging to %s",logname); ! 176: } ! 177: else ! 178: adios(NULLCP, "usage: %s [-F logfile] [-d N]", ! 179: myname); ! 180: } ! 181: ! 182: advise (LLOG_NOTICE,NULLCP, "starting"); ! 183: ! 184: acc = &accs; ! 185: acr = &acrs; ! 186: aci = &acis; ! 187: acs = &acss; ! 188: ! 189: if (ass_ind(argc,argv) == OK) { ! 190: connected = TRUE; ! 191: if( !strcmp(vtp_profile.profile_name,"default") ) ! 192: telnet_profile = 0; ! 193: } ! 194: else ! 195: exit(1); ! 196: #ifdef BSD44 ! 197: na_image = 0; ! 198: nego_state = 0; /*Start off in Local echo*/ ! 199: i = forkpty(&p, line, NULL, NULL); ! 200: if (i == -1) { ! 201: perror("vtd -- forkpty"); ! 202: vrelreq(); ! 203: /*NOTREACHED*/ ! 204: } ! 205: if (i) { ! 206: vtd(sd, p); ! 207: /*NOTREACHED*/ ! 208: } ! 209: #else ! 210: /* ! 211: * Get a pty, scan input lines. ! 212: */ ! 213: for (j = 'p' ; j <= 't'; j++) { ! 214: cp[strlen ("/dev/pty")] = j; ! 215: for (i = 0; i < 16; i++) { ! 216: cp[strlen("/dev/ptyp")] = "0123456789abcdef"[i]; ! 217: p = open(cp, 2); ! 218: if (p >= 0) ! 219: goto gotpty; ! 220: } ! 221: } ! 222: perror("All network ports in use"); ! 223: vrelreq(); ! 224: /*NOTREACHED*/ ! 225: gotpty: ! 226: ! 227: cp[strlen("/dev/")] = 't'; ! 228: t = open("/dev/tty", 2); ! 229: if (t >= 0) { ! 230: if (ioctl(t, TIOCNOTTY, 0) == -1) { ! 231: perror("ioctl (TIOCNOTTY)"); ! 232: } ! 233: (void)close(t); ! 234: } ! 235: t = open(cp, 2); ! 236: if (t < 0) ! 237: fatalperror(f, cp, errno); ! 238: if (ioctl(t, TIOCGETP, (char*)&b) == -1) { ! 239: perror("ioctl (TIOCGETP)"); ! 240: adios(NULLCP, "ioctl failed (TIOCGETP)"); ! 241: } ! 242: b.sg_flags = CRMOD|XTABS|ANYP; ! 243: if (ioctl(t, TIOCSETP, (char*)&b) == -1) { ! 244: perror("ioctl (TIOCSETP)"); ! 245: adios(NULLCP, "ioctl failed (TIOCSETP)"); ! 246: } ! 247: if (ioctl(p, TIOCGETP, (char*)&b) == -1) { /* XXX why is this done on the controller */ ! 248: perror("ioctl (TIOCGETP)"); ! 249: adios(NULLCP, "ioctl failed (TIOCGETP)"); ! 250: } ! 251: if (telnet_profile) ! 252: b.sg_flags &= ~ECHO; ! 253: else ! 254: b.sg_flags |= ECHO; /*Remote echo for Default*/ ! 255: if (ioctl(p, TIOCSETP, (char*)&b) == -1) { ! 256: perror("ioctl (TIOCSETP)"); ! 257: adios(NULLCP, "ioctl failed (TIOCSETP)"); ! 258: } ! 259: na_image = 0; ! 260: nego_state = 0; /*Start off in Local echo*/ ! 261: ! 262: if ((i = fork()) < 0) ! 263: fatalperror(f, "fork", errno); ! 264: if (i) ! 265: vtd(sd, p); ! 266: (void)close(sd); ! 267: (void)close(p); ! 268: if (dup2(t, 0) == -1) { ! 269: perror("dup2"); ! 270: adios(NULLCP, "dup2 failed"); ! 271: } ! 272: if (dup2(t, 1) == -1) { ! 273: perror("dup2"); ! 274: adios(NULLCP, "dup2 failed"); ! 275: } ! 276: if (dup2(t, 2) == -1) { ! 277: perror("dup2"); ! 278: adios(NULLCP, "dup2 failed"); ! 279: } ! 280: (void)close(t); ! 281: #endif ! 282: environ = envinit; ! 283: ! 284: execl(_PATH_LOGIN,"login","-h",peerhost,NULLCP); ! 285: fatalperror(f, _PATH_LOGIN, errno); ! 286: /*NOTREACHED*/ ! 287: } ! 288: ! 289: fatal(f, msg) ! 290: int f; ! 291: char *msg; ! 292: { ! 293: char buf[BUFSIZ]; ! 294: ! 295: (void) sprintf(buf, "%s: %s.\n", myname, msg); ! 296: (void) write(f, buf, strlen(buf)); ! 297: adios (NULLCP, msg); ! 298: } ! 299: ! 300: fatalperror(f, msg, errnum) ! 301: int f; ! 302: char *msg; ! 303: int errnum; ! 304: { ! 305: char buf[BUFSIZ]; ! 306: extern char *sys_errlist[]; ! 307: ! 308: (void) sprintf(buf, "%s: %s", msg, sys_errlist[errnum]); ! 309: fatal(f, buf); ! 310: } ! 311: ! 312: /* ! 313: * Main loop. Select from pty and network. ! 314: */ ! 315: ! 316: vtd(f, p) ! 317: { ! 318: int on = 1; ! 319: int nfds, result; ! 320: ! 321: do_cleaning = 1; ! 322: net = f, pty = p; ! 323: nfds = (f > p ? f : p) + 1; ! 324: ! 325: if (ioctl(p, FIONBIO, (char*)&on) == -1) { ! 326: perror("ioctl"); ! 327: adios(NULLCP, "ioctl failed (FIONBIO)"); ! 328: } ! 329: #ifdef SIGTSTP ! 330: (void) signal(SIGTSTP, SIG_IGN); ! 331: #endif ! 332: #ifdef SIGCHLD ! 333: (void) signal(SIGCHLD, cleanup); ! 334: #endif ! 335: /* ! 336: * Show banner that getty never gave. ! 337: */ ! 338: myhostname = PLocalHostName (); ! 339: (void) sprintf(nfrontp, BANNER, myhostname, ""); ! 340: nfrontp += strlen(nfrontp); ! 341: ! 342: #ifdef BSD44 ! 343: if (tcgetattr(pty, &oterm) == -1) { ! 344: perror("tcgetattr"); ! 345: adios(NULLCP, "tcgetattr failed"); ! 346: } ! 347: if (telnet_profile) { ! 348: oterm.c_lflag &= ~ECHO; ! 349: if (tcsetattr(pty, TCSADRAIN, &oterm) == -1) { ! 350: perror("tcgetattr"); ! 351: adios(NULLCP, "tcgetattr failed"); ! 352: } ! 353: } ! 354: erase_char = oterm.c_cc[VERASE]; ! 355: erase_line = oterm.c_cc[VKILL]; ! 356: intr_char = oterm.c_cc[VINTR]; ! 357: #else ! 358: if (ioctl(pty,TIOCGETP,(char*)&ottyb) == -1) { ! 359: perror("ioctl"); ! 360: adios(NULLCP, "ioctl failed (TIOCGETP)"); ! 361: } ! 362: if (ioctl(pty,TIOCGETC,(char*)&otc) == -1) { ! 363: perror("ioctl"); ! 364: adios(NULLCP, "ioctl failed (TIOCGETC)"); ! 365: } ! 366: if (ioctl(pty,TIOCGLTC,(char*)&oltc) == -1) { ! 367: perror("ioctl"); ! 368: adios(NULLCP, "ioctl failed (TIOCGLTC)"); ! 369: } ! 370: erase_char = ottyb.sg_erase; ! 371: erase_line = ottyb.sg_kill; ! 372: intr_char = otc.t_intrc; ! 373: #endif ! 374: ! 375: ! 376: for (;;) { ! 377: fd_set ibits, obits; ! 378: register int c; ! 379: ! 380: FD_ZERO (&ibits); ! 381: FD_ZERO (&obits); ! 382: /* ! 383: * Never look for input if there's still ! 384: * stuff in the corresponding output buffer ! 385: */ ! 386: if (nfrontp - nbackp) { ! 387: FD_SET (f, &obits); ! 388: } ! 389: else { ! 390: FD_SET (p, &ibits); ! 391: } ! 392: if (pfrontp - pbackp) { ! 393: FD_SET (p, &obits); ! 394: } ! 395: else { ! 396: FD_SET (f, &ibits); ! 397: } ! 398: if (FD_ISSET (f, &ibits) && data_pending()) { ! 399: FD_CLR (f, &ibits); ! 400: ! 401: result = xselect(nfds, &ibits, &obits, ! 402: (fd_set *)NULL, OK); ! 403: ! 404: if (result < 0) ! 405: adios("failed", "xselect"); ! 406: FD_SET (f, &ibits); ! 407: } ! 408: else { ! 409: if (xselect(nfds, &ibits, &obits, (fd_set *)NULL, ! 410: NOTOK) == -1) ! 411: adios("failed", "xselect"); ! 412: } ! 413: if (!FD_ISSET (f, &ibits) ! 414: && !FD_ISSET (p, &ibits) ! 415: && !FD_ISSET (f, &obits) ! 416: && !FD_ISSET (p, &obits)) { ! 417: sleep(5); ! 418: continue; ! 419: } ! 420: ! 421: /* ! 422: * Something to read from the network... ! 423: */ ! 424: if (FD_ISSET (f, &ibits)) { ! 425: while ((c = getch()) > 0) ! 426: *pfrontp++ = c; ! 427: } ! 428: if (c == E_EOF) { ! 429: break; ! 430: } ! 431: ! 432: /* ! 433: * Something to read from the pty... ! 434: */ ! 435: if (FD_ISSET (p, &ibits)) { ! 436: pcc = read(p, nfrontp, (&netobuf[BUFSIZ] - nfrontp)); ! 437: ! 438: if (pcc < 0 && errno == EWOULDBLOCK) ! 439: pcc = 0; ! 440: else { ! 441: if (pcc <= 0) { ! 442: if (debug) ! 443: advise(LLOG_EXCEPTIONS,NULLCP, ! 444: "problem reading from pty"); ! 445: break; ! 446: } ! 447: } ! 448: nfrontp += pcc; ! 449: } ! 450: ! 451: if (FD_ISSET (f, &obits) && (nfrontp - nbackp) > 0) ! 452: netflush(); ! 453: ! 454: if (FD_ISSET (p, &obits) && (pfrontp - pbackp) > 0) ! 455: ptyflush(); ! 456: } ! 457: if (debug) ! 458: advise(LLOG_DEBUG,NULLCP, "finished loop in vtp"); ! 459: cleanup(); ! 460: } ! 461: ! 462: /* ! 463: * Send interrupt to process on other side of pty. ! 464: * If it is in raw mode, just write NULL; ! 465: * otherwise, write intr char. ! 466: */ ! 467: interrupt() ! 468: { ! 469: #ifdef BSD44 ! 470: struct termios term; ! 471: ! 472: ptyflush(); ! 473: if (tcgetattr(pty, &term) == -1) { ! 474: perror("tcgetattr"); ! 475: return; ! 476: } ! 477: if ((term.c_lflag&ISIG) && term.c_cc[VINTR] != _POSIX_VDISABLE) ! 478: *pfrontp++ = term.c_cc[VINTR]; ! 479: else ! 480: *pfrontp++ = '\0'; ! 481: #else ! 482: struct sgttyb b; ! 483: struct tchars tchars; ! 484: ! 485: ptyflush(); /* half-hearted */ ! 486: if (ioctl(pty, TIOCGETP, (char*)&b) == -1) { ! 487: perror("ioctl"); ! 488: adios(NULLCP, "ioctl failed"); ! 489: } ! 490: if (b.sg_flags & RAW) { ! 491: *pfrontp++ = '\0'; ! 492: return; ! 493: } ! 494: *pfrontp++ = ioctl(pty, TIOCGETC, (char*)&tchars) < 0 ? ! 495: '\177' : tchars.t_intrc; ! 496: #endif ! 497: } ! 498: ! 499: netflush() ! 500: { ! 501: register char *cp; ! 502: int n; ! 503: int i, j; ! 504: int nl_flag; /*Records if Newline is included in current PDU to ! 505: decide if Deliver Request should follow it. Should ! 506: not be required but some implementations may wait ! 507: for it before delivering NDQ to application*/ ! 508: ! 509: nl_flag = 0; ! 510: if ((n = nfrontp - nbackp) > 0) { ! 511: ! 512: if (debug) { ! 513: (void) ll_log (vt_log, LLOG_DEBUG, NULLCP, ! 514: ("writing to the net")); ! 515: (void) ll_printf (vt_log, "<<"); ! 516: for(i=0; i<(nfrontp-nbackp); i++) ! 517: (void)ll_printf (vt_log, "%02x ",*(nbackp+i)); ! 518: (void)ll_printf (vt_log, ">>\n"); ! 519: (void)ll_sync (vt_log); ! 520: } ! 521: if(transparent) ! 522: { ! 523: (void)vt_text(nbackp,n); ! 524: vtsend(); ! 525: cp = nbackp; ! 526: for(i=0; i<n; i++) ! 527: { ! 528: if((*cp == '\r') || ! 529: (*cp == '\n')) ! 530: { ! 531: vdelreq(FALSE); ! 532: break; ! 533: } ! 534: ++cp; ! 535: } ! 536: nbackp += n; ! 537: } ! 538: else ! 539: { ! 540: cp = nbackp; ! 541: for(i=0,j=0; i<n; i++) ! 542: { ! 543: if(*cp == '\r') ! 544: { ! 545: if(rflag) (void)vt_text(crp,1); ! 546: /*Previous char was CR so put one in NDQ*/ ! 547: if(j) ! 548: (void)vt_text(nbackp,j); ! 549: nbackp += (j+1); /*Skip over current CR*/ ! 550: cp = nbackp; ! 551: j = 0; ! 552: if(i == (n-1) ) (void)vt_text(crp,1); ! 553: /*If CR is last char in buffer, send it*/ ! 554: else rflag = 1; ! 555: /*If not last char in buffer, read next one*/ ! 556: continue; ! 557: } ! 558: else if(rflag) /*If previous character was CR*/ ! 559: { ! 560: if(*cp == '\n') /*Got CR-LF -- map to Next X-Array*/ ! 561: { ! 562: nbackp += (j+1); ! 563: cp = nbackp; ! 564: rflag = 0; ! 565: vt_newline(); ! 566: ++nl_flag; ! 567: continue; ! 568: } ! 569: else /*Preceeding char was CR but not followed by ! 570: LF. Put CR in buffer*/ ! 571: (void) vt_text(crp,1); ! 572: rflag = 0; ! 573: } ! 574: if(telnet_profile) ! 575: { ! 576: rflag = 0; ! 577: #ifdef MAP_BACKSPACE ! 578: if(*cp == 0x08) /*If believed to be erase*/ ! 579: { ! 580: if(j) ! 581: (void)vt_text(nbackp,j); ! 582: nbackp += (j+1); ! 583: cp = nbackp; ! 584: j = 0; ! 585: vt_char_erase(); ! 586: continue; ! 587: } ! 588: #endif ! 589: if(!vtp_profile.arg_val.tel_arg_list.full_ascii) ! 590: /*If ASCII GO, dump ctrl chars*/ ! 591: { ! 592: if((*cp < 0x20) || (*cp > 0x7e)) ! 593: { ! 594: if(j) ! 595: (void)vt_text(nbackp,j); ! 596: nbackp += (j+1); ! 597: cp = nbackp; ! 598: j = 0; ! 599: } ! 600: else ! 601: { ! 602: ++j; ++cp; ! 603: } ! 604: } ! 605: else ! 606: { ! 607: ++j; ! 608: ++cp; ! 609: } ! 610: } ! 611: else /*Else Default Profile*/ ! 612: { ! 613: if((*cp < 0x20) || (*cp > 0x7e)) ! 614: { ! 615: if(j) ! 616: (void)vt_text(nbackp,j); ! 617: nbackp += (j+1); ! 618: cp = nbackp; ! 619: j = 0; ! 620: } ! 621: else ! 622: { ! 623: ++j; ! 624: ++cp; ! 625: } ! 626: } ! 627: } /*End for loop*/ ! 628: if(j) ! 629: (void)vt_text(nbackp,j); /*Load anything left if CR or LF ! 630: wasn't last char in buffer*/ ! 631: nbackp += j; ! 632: vtsend(); /*Send the whole NDQ*/ ! 633: if(nl_flag && telnet_profile) vdelreq(FALSE); ! 634: } ! 635: } ! 636: if (n < 0) { ! 637: if (errno != ENOBUFS && errno != EWOULDBLOCK) { ! 638: adios("closed", "association"); ! 639: /*NOTREACHED*/ ! 640: } ! 641: n = 0; ! 642: } ! 643: if (nbackp == nfrontp) ! 644: nbackp = nfrontp = netobuf; ! 645: } ! 646: ! 647: SFD cleanup() ! 648: { ! 649: sleep(1); ! 650: while(getch() > 0); /*Clean out unread VT-DATA PDU's still held ! 651: in network. Kludge to overcome deficiency ! 652: in Session Release. */ ! 653: rmut(); ! 654: #ifndef BSD44 ! 655: vhangup(); ! 656: #endif ! 657: vrelreq(); ! 658: (void)kill(0, SIGKILL); ! 659: exit(1); ! 660: } ! 661: ! 662: #include <utmp.h> ! 663: ! 664: struct utmp wtmp; ! 665: char wtmpf[] = "/usr/adm/wtmp"; ! 666: char utmp[] = "/etc/utmp"; ! 667: #define SCPYN(a, b) strncpy(a, b, sizeof (a)) ! 668: #define SCMPN(a, b) strncmp(a, b, sizeof (a)) ! 669: ! 670: long lseek (), time (); ! 671: ! 672: rmut() ! 673: { ! 674: register f; ! 675: int found = 0; ! 676: ! 677: f = open(utmp, 2); ! 678: if (f >= 0) { ! 679: while(read(f, (char *)&wtmp, sizeof (wtmp)) == sizeof (wtmp)) { ! 680: if (SCMPN(wtmp.ut_line, line+5) || wtmp.ut_name[0]==0) ! 681: continue; ! 682: (void)lseek(f, -(long)sizeof (wtmp), 1); ! 683: (void)SCPYN(wtmp.ut_name, ""); ! 684: #if !defined(SYS5) && !defined(bsd43_ut_host) ! 685: (void)SCPYN(wtmp.ut_host, ""); ! 686: #endif ! 687: (void)time(&wtmp.ut_time); ! 688: (void) write(f, (char *)&wtmp, sizeof (wtmp)); ! 689: found++; ! 690: } ! 691: (void)close(f); ! 692: } ! 693: if (found) { ! 694: f = open(wtmpf, 1); ! 695: if (f >= 0) { ! 696: (void)SCPYN(wtmp.ut_line, line+5); ! 697: (void)SCPYN(wtmp.ut_name, ""); ! 698: #if !defined(SYS5) && !defined(bsd43_ut_host) ! 699: (void)SCPYN(wtmp.ut_host, ""); ! 700: #endif ! 701: (void)time(&wtmp.ut_time); ! 702: (void)lseek(f, (long)0, 2); ! 703: (void) write(f, (char *)&wtmp, sizeof (wtmp)); ! 704: (void)close(f); ! 705: } ! 706: } ! 707: (void)chmod(line, 0666); ! 708: (void)chown(line, 0, 0); ! 709: line[strlen("/dev/")] = 'p'; ! 710: (void)chmod(line, 0666); ! 711: (void)chown(line, 0, 0); ! 712: } ! 713: ! 714: bye() ! 715: { ! 716: if(do_cleaning) { ! 717: rmut(); ! 718: (void)kill(0, SIGKILL); ! 719: } ! 720: exit(0); ! 721: } ! 722: ! 723: flushbufs() ! 724: { ! 725: pcc = 0; ! 726: pfrontp = pbackp = ptyobuf; ! 727: nfrontp = nbackp = netobuf; ! 728: while (getch() > 0) ! 729: continue; ! 730: } ! 731: ! 732: /* ERRORS */ ! 733: ! 734: void finalbye () ! 735: { ! 736: bye (); ! 737: } ! 738: ! 739: ! 740: #ifndef lint ! 741: void adios (va_alist) ! 742: va_dcl ! 743: { ! 744: va_list ap; ! 745: ! 746: va_start (ap); ! 747: ! 748: (void) _ll_log (vt_log, LLOG_FATAL, ap); ! 749: ! 750: va_end (ap); ! 751: ! 752: bye (); ! 753: ! 754: _exit (1); ! 755: } ! 756: #else ! 757: /* VARARGS2 */ ! 758: ! 759: void adios (what, fmt) ! 760: char *what, ! 761: *fmt; ! 762: { ! 763: adios (what, fmt); ! 764: } ! 765: #endif ! 766: ! 767: ! 768: #ifndef lint ! 769: void advise (va_alist) ! 770: va_dcl ! 771: { ! 772: int code; ! 773: va_list ap; ! 774: ! 775: va_start (ap); ! 776: ! 777: code = va_arg (ap, int); ! 778: ! 779: (void) _ll_log (vt_log, code, ap); ! 780: ! 781: va_end (ap); ! 782: } ! 783: #else ! 784: /* VARARGS3 */ ! 785: ! 786: void advise (code, what, fmt) ! 787: int code; ! 788: char *what, ! 789: *fmt; ! 790: { ! 791: advise (code, what, fmt); ! 792: } ! 793: #endif ! 794: ! 795: ptyflush() ! 796: { ! 797: int n; ! 798: ! 799: if ((n = pfrontp - pbackp) > 0) ! 800: { ! 801: n = write(pty, pbackp, n); ! 802: } ! 803: if (n < 0) ! 804: return; ! 805: pbackp += n; ! 806: if (pbackp == pfrontp) ! 807: pbackp = pfrontp = ptyobuf; ! 808: } ! 809: ! 810: #ifdef BSD44 ! 811: ptyecho(on) ! 812: { ! 813: struct termios term; ! 814: ! 815: ptyflush(); ! 816: if (tcgetattr(pty, &term) == -1) { ! 817: perror("tcgetattr"); ! 818: return; ! 819: } ! 820: if (on) ! 821: term.c_lflag |= ECHO; ! 822: else ! 823: term.c_lflag &= ECHO; ! 824: if (tcsetattr(pty, TCSAFLUSH, &term) == -1) { ! 825: perror("tcsetattr"); ! 826: return; ! 827: } ! 828: } ! 829: #else ! 830: setmode(on, off) ! 831: int on, off; ! 832: { ! 833: struct sgttyb b; ! 834: ! 835: ptyflush(); ! 836: if(ioctl(pty, TIOCGETP, (char*)&b) < 0) { ! 837: perror("ioctl"); ! 838: adios(NULLCP, "ioctl failed"); ! 839: } ! 840: b.sg_flags |= on; ! 841: b.sg_flags &= ~off; ! 842: if (ioctl(pty, TIOCSETP, (char*)&b) == -1) { ! 843: perror("ioctl"); ! 844: adios(NULLCP, "ioctl failed"); ! 845: } ! 846: } ! 847: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.