121595Sdist /* 221595Sdist * Copyright (c) 1983 Regents of the University of California. 321595Sdist * All rights reserved. The Berkeley software License Agreement 421595Sdist * specifies the terms and conditions for redistribution. 521595Sdist */ 621595Sdist 76444Swnj #ifndef lint 821595Sdist char copyright[] = 921595Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 1021595Sdist All rights reserved.\n"; 1121595Sdist #endif not lint 126444Swnj 1321595Sdist #ifndef lint 14*26981Skarels static char sccsid[] = "@(#)rlogin.c 5.10 (Berkeley) 03/30/86"; 1521595Sdist #endif not lint 1621595Sdist 1712990Ssam /* 1812990Ssam * rlogin - remote login 1912990Ssam */ 20*26981Skarels #include <sys/param.h> 2125424Skarels #include <sys/errno.h> 2224727Smckusick #include <sys/file.h> 236444Swnj #include <sys/socket.h> 2413620Ssam #include <sys/wait.h> 259365Ssam 269207Ssam #include <netinet/in.h> 279365Ssam 289365Ssam #include <stdio.h> 299365Ssam #include <sgtty.h> 306444Swnj #include <errno.h> 316444Swnj #include <pwd.h> 329365Ssam #include <signal.h> 3325424Skarels #include <setjmp.h> 349365Ssam #include <netdb.h> 356444Swnj 3624726Smckusick # ifndef TIOCPKT_WINDOW 3724726Smckusick # define TIOCPKT_WINDOW 0x80 3824726Smckusick # endif TIOCPKT_WINDOW 3924726Smckusick 406444Swnj char *index(), *rindex(), *malloc(), *getenv(); 416444Swnj struct passwd *getpwuid(); 429365Ssam char *name; 436444Swnj int rem; 446444Swnj char cmdchar = '~'; 456444Swnj int eight; 4621583Sbloom int litout; 476444Swnj char *speeds[] = 486444Swnj { "0", "50", "75", "110", "134", "150", "200", "300", 496444Swnj "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" }; 5018358Ssam char term[256] = "network"; 519365Ssam extern int errno; 529365Ssam int lostpeer(); 5324726Smckusick int dosigwinch = 0; 54*26981Skarels #ifndef sigmask 55*26981Skarels #define sigmask(m) (1 << ((m)-1)) 56*26981Skarels #endif 57*26981Skarels #ifdef sun 58*26981Skarels struct ttysize winsize; 59*26981Skarels struct winsize { 60*26981Skarels unsigned short ws_row, ws_col; 61*26981Skarels unsigned short ws_xpixel, ws_ypixel; 62*26981Skarels }; 63*26981Skarels #else sun 6418358Ssam struct winsize winsize; 65*26981Skarels #endif sun 6624726Smckusick int sigwinch(), oob(); 676444Swnj 686444Swnj main(argc, argv) 696444Swnj int argc; 706444Swnj char **argv; 716444Swnj { 729365Ssam char *host, *cp; 736444Swnj struct sgttyb ttyb; 746444Swnj struct passwd *pwd; 759365Ssam struct servent *sp; 7624726Smckusick int uid, options = 0, oldmask; 7717449Slepreau int on = 1; 786444Swnj 796444Swnj host = rindex(argv[0], '/'); 806444Swnj if (host) 816444Swnj host++; 826444Swnj else 836444Swnj host = argv[0]; 846444Swnj argv++, --argc; 856444Swnj if (!strcmp(host, "rlogin")) 866444Swnj host = *argv++, --argc; 876444Swnj another: 8810839Ssam if (argc > 0 && !strcmp(*argv, "-d")) { 896444Swnj argv++, argc--; 9010415Ssam options |= SO_DEBUG; 916444Swnj goto another; 926444Swnj } 9310839Ssam if (argc > 0 && !strcmp(*argv, "-l")) { 946444Swnj argv++, argc--; 956444Swnj if (argc == 0) 966444Swnj goto usage; 976444Swnj name = *argv++; argc--; 986444Swnj goto another; 996444Swnj } 10010839Ssam if (argc > 0 && !strncmp(*argv, "-e", 2)) { 1016444Swnj cmdchar = argv[0][2]; 1026444Swnj argv++, argc--; 1036444Swnj goto another; 1046444Swnj } 10510839Ssam if (argc > 0 && !strcmp(*argv, "-8")) { 1066444Swnj eight = 1; 1076444Swnj argv++, argc--; 1086444Swnj goto another; 1096444Swnj } 11021583Sbloom if (argc > 0 && !strcmp(*argv, "-L")) { 11121583Sbloom litout = 1; 11221583Sbloom argv++, argc--; 11321583Sbloom goto another; 11421583Sbloom } 1156444Swnj if (host == 0) 1166444Swnj goto usage; 1176444Swnj if (argc > 0) 1186444Swnj goto usage; 1196444Swnj pwd = getpwuid(getuid()); 1206444Swnj if (pwd == 0) { 1216444Swnj fprintf(stderr, "Who are you?\n"); 1226444Swnj exit(1); 1236444Swnj } 1249365Ssam sp = getservbyname("login", "tcp"); 1259365Ssam if (sp == 0) { 1269365Ssam fprintf(stderr, "rlogin: login/tcp: unknown service\n"); 1279365Ssam exit(2); 1289365Ssam } 1299241Ssam cp = getenv("TERM"); 1309241Ssam if (cp) 1319241Ssam strcpy(term, cp); 13218358Ssam if (ioctl(0, TIOCGETP, &ttyb) == 0) { 1336444Swnj strcat(term, "/"); 1346444Swnj strcat(term, speeds[ttyb.sg_ospeed]); 1356444Swnj } 136*26981Skarels #ifdef sun 137*26981Skarels (void) ioctl(0, TIOCGSIZE, &winsize); 138*26981Skarels #else sun 13924726Smckusick (void) ioctl(0, TIOCGWINSZ, &winsize); 140*26981Skarels #endif sun 14112990Ssam signal(SIGPIPE, lostpeer); 14224726Smckusick signal(SIGURG, oob); 14324726Smckusick oldmask = sigblock(sigmask(SIGURG)); 1449365Ssam rem = rcmd(&host, sp->s_port, pwd->pw_name, 1456444Swnj name ? name : pwd->pw_name, term, 0); 1466444Swnj if (rem < 0) 1476444Swnj exit(1); 14810415Ssam if (options & SO_DEBUG && 14917449Slepreau setsockopt(rem, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)) < 0) 15010415Ssam perror("rlogin: setsockopt (SO_DEBUG)"); 1519365Ssam uid = getuid(); 1529365Ssam if (setuid(uid) < 0) { 1539365Ssam perror("rlogin: setuid"); 1549365Ssam exit(1); 1559365Ssam } 15624726Smckusick doit(oldmask); 1579365Ssam /*NOTREACHED*/ 1586444Swnj usage: 1596444Swnj fprintf(stderr, 16025341Smckusick "usage: rlogin host [ -ex ] [ -l username ] [ -8 ] [ -L ]\n"); 1616444Swnj exit(1); 1626444Swnj } 1636444Swnj 1646444Swnj #define CRLF "\r\n" 1656444Swnj 1669365Ssam int child; 16711803Sedward int catchild(); 16824726Smckusick int writeroob(); 1699365Ssam 17013075Ssam int defflags, tabflag; 17121583Sbloom int deflflags; 17213075Ssam char deferase, defkill; 17313075Ssam struct tchars deftc; 17413075Ssam struct ltchars defltc; 17513075Ssam struct tchars notc = { -1, -1, -1, -1, -1, -1 }; 17613075Ssam struct ltchars noltc = { -1, -1, -1, -1, -1, -1 }; 1776444Swnj 17824726Smckusick doit(oldmask) 1796444Swnj { 1806444Swnj int exit(); 18113075Ssam struct sgttyb sb; 1826444Swnj 18313075Ssam ioctl(0, TIOCGETP, (char *)&sb); 18413075Ssam defflags = sb.sg_flags; 18512155Ssam tabflag = defflags & TBDELAY; 1869962Ssam defflags &= ECHO | CRMOD; 18713075Ssam deferase = sb.sg_erase; 18813075Ssam defkill = sb.sg_kill; 18921583Sbloom ioctl(0, TIOCLGET, (char *)&deflflags); 19013075Ssam ioctl(0, TIOCGETC, (char *)&deftc); 19113075Ssam notc.t_startc = deftc.t_startc; 19213075Ssam notc.t_stopc = deftc.t_stopc; 19313075Ssam ioctl(0, TIOCGLTC, (char *)&defltc); 19424726Smckusick signal(SIGINT, SIG_IGN); 19512990Ssam signal(SIGHUP, exit); 19612990Ssam signal(SIGQUIT, exit); 1979365Ssam child = fork(); 1989365Ssam if (child == -1) { 1999365Ssam perror("rlogin: fork"); 20025424Skarels done(1); 2019365Ssam } 2029365Ssam if (child == 0) { 20324726Smckusick mode(1); 20424726Smckusick sigsetmask(oldmask); 20525424Skarels if (reader() == 0) { 20625424Skarels prf("Connection closed."); 20725424Skarels exit(0); 20825424Skarels } 20912155Ssam sleep(1); 21012155Ssam prf("\007Connection closed."); 2116444Swnj exit(3); 2126444Swnj } 21324726Smckusick signal(SIGURG, writeroob); 21424726Smckusick sigsetmask(oldmask); 21512990Ssam signal(SIGCHLD, catchild); 2169365Ssam writer(); 21712155Ssam prf("Closed connection."); 21825424Skarels done(0); 2196444Swnj } 2206444Swnj 22125424Skarels done(status) 22225424Skarels int status; 2236444Swnj { 2246444Swnj 2256444Swnj mode(0); 2269365Ssam if (child > 0 && kill(child, SIGKILL) >= 0) 2279365Ssam wait((int *)0); 22825424Skarels exit(status); 2296444Swnj } 2306444Swnj 23124726Smckusick /* 23224726Smckusick * This is called when the reader process gets the out-of-band (urgent) 23324726Smckusick * request to turn on the window-changing protocol. 23424726Smckusick */ 23524726Smckusick writeroob() 23624726Smckusick { 23724726Smckusick 23825341Smckusick if (dosigwinch == 0) { 23924919Smckusick sendwindow(); 24025341Smckusick signal(SIGWINCH, sigwinch); 24125341Smckusick } 24224726Smckusick dosigwinch = 1; 24324726Smckusick } 24424726Smckusick 24511803Sedward catchild() 24611803Sedward { 24711803Sedward union wait status; 24811803Sedward int pid; 24911803Sedward 25011803Sedward again: 25111803Sedward pid = wait3(&status, WNOHANG|WUNTRACED, 0); 25211803Sedward if (pid == 0) 25311803Sedward return; 25411803Sedward /* 25511803Sedward * if the child (reader) dies, just quit 25611803Sedward */ 25711803Sedward if (pid < 0 || pid == child && !WIFSTOPPED(status)) 25825424Skarels done(status.w_termsig | status.w_retcode); 25911803Sedward goto again; 26011803Sedward } 26111803Sedward 2626444Swnj /* 2639365Ssam * writer: write to remote: 0 -> line. 2649365Ssam * ~. terminate 2659365Ssam * ~^Z suspend rlogin process. 26610415Ssam * ~^Y suspend rlogin process, but leave reader alone. 2676444Swnj */ 2689365Ssam writer() 2696444Swnj { 27023530Sbloom char c; 27111803Sedward register n; 27223530Sbloom register bol = 1; /* beginning of line */ 27323530Sbloom register local = 0; 2746444Swnj 27511803Sedward for (;;) { 27611803Sedward n = read(0, &c, 1); 27718358Ssam if (n <= 0) { 27818358Ssam if (n < 0 && errno == EINTR) 27918358Ssam continue; 28011803Sedward break; 28118358Ssam } 2829365Ssam /* 2839365Ssam * If we're at the beginning of the line 2849365Ssam * and recognize a command character, then 2859365Ssam * we echo locally. Otherwise, characters 2869365Ssam * are echo'd remotely. If the command 2879365Ssam * character is doubled, this acts as a 2889365Ssam * force and local echo is suppressed. 2899365Ssam */ 29023530Sbloom if (bol) { 29123530Sbloom bol = 0; 29223530Sbloom if (c == cmdchar) { 29323530Sbloom bol = 0; 29423530Sbloom local = 1; 29523530Sbloom continue; 2966444Swnj } 29723530Sbloom } else if (local) { 29823530Sbloom local = 0; 29923530Sbloom if (c == '.' || c == deftc.t_eofc) { 30023530Sbloom echo(c); 30123530Sbloom break; 3026444Swnj } 30323530Sbloom if (c == defltc.t_suspc || c == defltc.t_dsuspc) { 30423530Sbloom bol = 1; 30523530Sbloom echo(c); 30623530Sbloom stop(c); 30723530Sbloom continue; 30823530Sbloom } 30923530Sbloom if (c != cmdchar) 31023530Sbloom write(rem, &cmdchar, 1); 3116444Swnj } 31223530Sbloom if (write(rem, &c, 1) == 0) { 31323530Sbloom prf("line gone"); 31423530Sbloom break; 3156444Swnj } 31623530Sbloom bol = c == defkill || c == deftc.t_eofc || 31725424Skarels c == deftc.t_intrc || c == defltc.t_suspc || 31823530Sbloom c == '\r' || c == '\n'; 3196444Swnj } 3206444Swnj } 3216444Swnj 32223530Sbloom echo(c) 32323530Sbloom register char c; 32423530Sbloom { 32523530Sbloom char buf[8]; 32623530Sbloom register char *p = buf; 32723530Sbloom 32823530Sbloom c &= 0177; 32923530Sbloom *p++ = cmdchar; 33023530Sbloom if (c < ' ') { 33123530Sbloom *p++ = '^'; 33223530Sbloom *p++ = c + '@'; 33323530Sbloom } else if (c == 0177) { 33423530Sbloom *p++ = '^'; 33523530Sbloom *p++ = '?'; 33623530Sbloom } else 33723530Sbloom *p++ = c; 33823530Sbloom *p++ = '\r'; 33923530Sbloom *p++ = '\n'; 34023530Sbloom write(1, buf, p - buf); 34123530Sbloom } 34223530Sbloom 34318358Ssam stop(cmdc) 34418358Ssam char cmdc; 34518358Ssam { 34618358Ssam mode(0); 34718358Ssam signal(SIGCHLD, SIG_IGN); 34818358Ssam kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP); 34918358Ssam signal(SIGCHLD, catchild); 35018358Ssam mode(1); 35118358Ssam sigwinch(); /* check for size changes */ 35218358Ssam } 35318358Ssam 354*26981Skarels #ifdef sun 35518358Ssam sigwinch() 35618358Ssam { 357*26981Skarels struct ttysize ws; 358*26981Skarels 359*26981Skarels if (dosigwinch && ioctl(0, TIOCGSIZE, &ws) == 0 && 360*26981Skarels bcmp(&ws, &winsize, sizeof (ws))) { 361*26981Skarels winsize = ws; 362*26981Skarels sendwindow(); 363*26981Skarels } 364*26981Skarels } 365*26981Skarels 366*26981Skarels #else sun 367*26981Skarels sigwinch() 368*26981Skarels { 36918358Ssam struct winsize ws; 37018358Ssam 37125341Smckusick if (dosigwinch && ioctl(0, TIOCGWINSZ, &ws) == 0 && 37218358Ssam bcmp(&ws, &winsize, sizeof (ws))) { 37318358Ssam winsize = ws; 37424726Smckusick sendwindow(); 37518358Ssam } 37618358Ssam } 377*26981Skarels #endif 37818358Ssam 37924726Smckusick /* 38024726Smckusick * Send the window size to the server via the magic escape 38124726Smckusick */ 38224726Smckusick sendwindow() 38324726Smckusick { 38424726Smckusick char obuf[4 + sizeof (struct winsize)]; 38524726Smckusick struct winsize *wp = (struct winsize *)(obuf+4); 38624726Smckusick 38724726Smckusick obuf[0] = 0377; 38824726Smckusick obuf[1] = 0377; 38924726Smckusick obuf[2] = 's'; 39024726Smckusick obuf[3] = 's'; 391*26981Skarels #ifdef sun 392*26981Skarels wp->ws_row = htons(winsize.ts_lines); 393*26981Skarels wp->ws_col = htons(winsize.ts_cols); 394*26981Skarels wp->ws_xpixel = 0; 395*26981Skarels wp->ws_ypixel = 0; 396*26981Skarels #else sun 39724726Smckusick wp->ws_row = htons(winsize.ws_row); 39824726Smckusick wp->ws_col = htons(winsize.ws_col); 39924726Smckusick wp->ws_xpixel = htons(winsize.ws_xpixel); 40024726Smckusick wp->ws_ypixel = htons(winsize.ws_ypixel); 401*26981Skarels #endif sun 40224726Smckusick (void) write(rem, obuf, sizeof(obuf)); 40324726Smckusick } 40424726Smckusick 40525424Skarels /* 40625424Skarels * reader: read from remote: line -> 1 40725424Skarels */ 40825424Skarels #define READING 1 40925424Skarels #define WRITING 2 41025424Skarels 41125424Skarels char rcvbuf[8 * 1024]; 41225424Skarels int rcvcnt; 41325424Skarels int rcvstate; 414*26981Skarels int ppid; 41525424Skarels jmp_buf rcvtop; 41625424Skarels 4176444Swnj oob() 4186444Swnj { 41925424Skarels int out = FWRITE, atmark, n; 42025424Skarels int rcvd = 0; 4219365Ssam char waste[BUFSIZ], mark; 42224726Smckusick struct sgttyb sb; 4236444Swnj 42425424Skarels while (recv(rem, &mark, 1, MSG_OOB) < 0) 42525424Skarels switch (errno) { 42625424Skarels 42725424Skarels case EWOULDBLOCK: 42825424Skarels /* 42925424Skarels * Urgent data not here yet. 43025424Skarels * It may not be possible to send it yet 43125424Skarels * if we are blocked for output 43225424Skarels * and our input buffer is full. 43325424Skarels */ 43425424Skarels if (rcvcnt < sizeof(rcvbuf)) { 43525424Skarels n = read(rem, rcvbuf + rcvcnt, 43625424Skarels sizeof(rcvbuf) - rcvcnt); 43725424Skarels if (n <= 0) 43825424Skarels return; 43925424Skarels rcvd += n; 44025424Skarels } else { 44125424Skarels n = read(rem, waste, sizeof(waste)); 44225424Skarels if (n <= 0) 44325424Skarels return; 44425424Skarels } 44525424Skarels continue; 44625424Skarels 44725424Skarels default: 44825424Skarels return; 4496444Swnj } 45025424Skarels if (mark & TIOCPKT_WINDOW) { 45124726Smckusick /* 45224726Smckusick * Let server know about window size changes 45324726Smckusick */ 454*26981Skarels kill(ppid, SIGURG); 45524726Smckusick } 45625424Skarels if (!eight && (mark & TIOCPKT_NOSTOP)) { 45724726Smckusick ioctl(0, TIOCGETP, (char *)&sb); 45824726Smckusick sb.sg_flags &= ~CBREAK; 45924726Smckusick sb.sg_flags |= RAW; 46024726Smckusick ioctl(0, TIOCSETN, (char *)&sb); 46113075Ssam notc.t_stopc = -1; 46213075Ssam notc.t_startc = -1; 46313075Ssam ioctl(0, TIOCSETC, (char *)¬c); 4646444Swnj } 46525424Skarels if (!eight && (mark & TIOCPKT_DOSTOP)) { 46624726Smckusick ioctl(0, TIOCGETP, (char *)&sb); 46724726Smckusick sb.sg_flags &= ~RAW; 46824726Smckusick sb.sg_flags |= CBREAK; 46924726Smckusick ioctl(0, TIOCSETN, (char *)&sb); 47013075Ssam notc.t_stopc = deftc.t_stopc; 47113075Ssam notc.t_startc = deftc.t_startc; 47213075Ssam ioctl(0, TIOCSETC, (char *)¬c); 4736444Swnj } 47425424Skarels if (mark & TIOCPKT_FLUSHWRITE) { 47525424Skarels ioctl(1, TIOCFLUSH, (char *)&out); 47625424Skarels for (;;) { 47725424Skarels if (ioctl(rem, SIOCATMARK, &atmark) < 0) { 47825424Skarels perror("ioctl"); 47925424Skarels break; 48025424Skarels } 48125424Skarels if (atmark) 48225424Skarels break; 48325424Skarels n = read(rem, waste, sizeof (waste)); 48425424Skarels if (n <= 0) 48525424Skarels break; 48625424Skarels } 48725424Skarels /* 48825424Skarels * Don't want any pending data to be output, 48925424Skarels * so clear the recv buffer. 49025424Skarels * If we were hanging on a write when interrupted, 49125424Skarels * don't want it to restart. If we were reading, 49225424Skarels * restart anyway. 49325424Skarels */ 49425424Skarels rcvcnt = 0; 49525424Skarels longjmp(rcvtop, 1); 49625424Skarels } 49725424Skarels /* 49825424Skarels * If we filled the receive buffer while a read was pending, 49925424Skarels * longjmp to the top to restart appropriately. Don't abort 50025424Skarels * a pending write, however, or we won't know how much was written. 50125424Skarels */ 50225424Skarels if (rcvd && rcvstate == READING) 50325424Skarels longjmp(rcvtop, 1); 5046444Swnj } 5056444Swnj 5069365Ssam /* 5079365Ssam * reader: read from remote: line -> 1 5089365Ssam */ 5099365Ssam reader() 5106444Swnj { 511*26981Skarels #if !defined(BSD) || BSD < 43 512*26981Skarels int pid = -getpid(); 513*26981Skarels #else 51425424Skarels int pid = getpid(); 515*26981Skarels #endif 51625424Skarels int n, remaining; 51725424Skarels char *bufp = rcvbuf; 5186444Swnj 51923530Sbloom signal(SIGTTOU, SIG_IGN); 52025424Skarels fcntl(rem, F_SETOWN, pid); 521*26981Skarels ppid = getppid(); 52225424Skarels (void) setjmp(rcvtop); 5236444Swnj for (;;) { 52425424Skarels while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) { 52525424Skarels rcvstate = WRITING; 52625424Skarels n = write(1, bufp, remaining); 52725424Skarels if (n < 0) { 52825424Skarels if (errno != EINTR) 52926189Slepreau return (-1); 53025424Skarels continue; 53125424Skarels } 53225424Skarels bufp += n; 53325424Skarels } 53425424Skarels bufp = rcvbuf; 53525424Skarels rcvcnt = 0; 53625424Skarels rcvstate = READING; 53725424Skarels rcvcnt = read(rem, rcvbuf, sizeof (rcvbuf)); 53825424Skarels if (rcvcnt == 0) 53925424Skarels return (0); 54025424Skarels if (rcvcnt < 0) { 5419365Ssam if (errno == EINTR) 5426444Swnj continue; 543*26981Skarels perror("read"); 54425424Skarels return (-1); 5456444Swnj } 5466444Swnj } 5476444Swnj } 5486444Swnj 5496444Swnj mode(f) 5506444Swnj { 55113075Ssam struct tchars *tc; 55213075Ssam struct ltchars *ltc; 55313075Ssam struct sgttyb sb; 55421583Sbloom int lflags; 5559365Ssam 55613075Ssam ioctl(0, TIOCGETP, (char *)&sb); 55721583Sbloom ioctl(0, TIOCLGET, (char *)&lflags); 5589962Ssam switch (f) { 5599962Ssam 5609962Ssam case 0: 56113075Ssam sb.sg_flags &= ~(CBREAK|RAW|TBDELAY); 56213075Ssam sb.sg_flags |= defflags|tabflag; 5639962Ssam tc = &deftc; 56413075Ssam ltc = &defltc; 56513075Ssam sb.sg_kill = defkill; 56613075Ssam sb.sg_erase = deferase; 56721583Sbloom lflags = deflflags; 5689962Ssam break; 5699962Ssam 5709962Ssam case 1: 57113075Ssam sb.sg_flags |= (eight ? RAW : CBREAK); 57213075Ssam sb.sg_flags &= ~defflags; 57312155Ssam /* preserve tab delays, but turn off XTABS */ 57413075Ssam if ((sb.sg_flags & TBDELAY) == XTABS) 57513075Ssam sb.sg_flags &= ~TBDELAY; 5769962Ssam tc = ¬c; 57713075Ssam ltc = &noltc; 57813075Ssam sb.sg_kill = sb.sg_erase = -1; 57921583Sbloom if (litout) 58021583Sbloom lflags |= LLITOUT; 5819962Ssam break; 5829962Ssam 5839962Ssam default: 5849962Ssam return; 5856444Swnj } 58613075Ssam ioctl(0, TIOCSLTC, (char *)ltc); 58713075Ssam ioctl(0, TIOCSETC, (char *)tc); 58813075Ssam ioctl(0, TIOCSETN, (char *)&sb); 58921583Sbloom ioctl(0, TIOCLSET, (char *)&lflags); 5906444Swnj } 5916444Swnj 5929365Ssam /*VARARGS*/ 59324726Smckusick prf(f, a1, a2, a3, a4, a5) 5949365Ssam char *f; 5956444Swnj { 59624726Smckusick fprintf(stderr, f, a1, a2, a3, a4, a5); 5976444Swnj fprintf(stderr, CRLF); 5986444Swnj } 5996444Swnj 6009365Ssam lostpeer() 6016444Swnj { 60212990Ssam signal(SIGPIPE, SIG_IGN); 60312155Ssam prf("\007Connection closed."); 60425424Skarels done(1); 6056444Swnj } 606*26981Skarels 607