+++ /dev/null
-.\" Copyright (c) 1983 Regents of the University of California.
-.\" All rights reserved. The Berkeley software License Agreement
-.\" specifies the terms and conditions for redistribution.
-.\"
-.\" @(#)telnet.1c 6.5 (Berkeley) 5/10/86
-.\"
-.TH TELNET 1 "May 10, 1986"
-.UC 5
-.SH NAME
-telnet \- user interface to the \s-1TELNET\s0 protocol
-.SH SYNOPSIS
-telnet [
-.I host
-[
-.I port
-] ]
-.SH DESCRIPTION
-.I Telnet
-is used to communicate with another host using the
-.B TELNET
-protocol.
-If
-.I telnet
-is invoked without arguments, it enters command mode,
-indicated by its prompt (\*(lqtelnet>\*(rq).
-In this mode, it accepts and executes the commands listed below.
-If it is invoked with arguments, it performs an
-.B open
-command (see below) with those arguments.
-.PP
-Once a connection has been opened,
-.I telnet
-enters an input mode.
-The input mode entered will be either \*(lqcharacter at a time\*(rq
-or \*(lqline by line\*(rq
-depending on what the remote system supports.
-.PP
-In \*(lqcharacter at a time\*(rq mode, most
-text typed is immediately sent to the remote host for processing.
-.PP
-In \*(lqline by line\*(rq mode, all text is echoed locally,
-and (normally) only completed lines are sent to the remote host.
-The \*(lqlocal echo character\*(rq (initially \*(lq^E\*(rq) may be used
-to turn off and on the local echo
-(this would mostly be used to enter passwords
-without the password being echoed).
-.PP
-In either mode, if the
-.I localchars
-toggle is TRUE (the default in line mode; see below),
-the user's
-.IR quit ,
-.IR intr ,
-and
-.I flush
-characters are trapped locally, and sent as
-.B TELNET
-protocol sequences to the remote side.
-There are options (see
-.B toggle
-.I autoflush
-and
-.B toggle
-.I autosynch
-below)
-which cause this action to flush subsequent output to the terminal
-(until the remote host acknowledges the
-.B TELNET
-sequence) and flush previous terminal input
-(in the case of
-.I quit
-and
-.IR intr ).
-.PP
-While connected to a remote host,
-.I telnet
-command mode may be entered by typing the
-.I telnet
-\*(lqescape character\*(rq (initially \*(lq^]\*(rq).
-When in command mode, the normal terminal editing conventions are available.
-.PP
-.B COMMANDS
-.PP
-The following commands are available.
-Only enough of each command to uniquely identify it need be typed
-(this is also true for arguments to the
-.BR mode ,
-.BR set ,
-.BR toggle ,
-and
-.B display
-commands).
-.PP
-.TP
-.B open \fIhost\fP \fR[\fP \fIport\fP \fR]\fP
-.br
-Open a connection to the named host.
-If no port number
-is specified,
-.I telnet
-will attempt to contact a
-.B TELNET
-server at the default port.
-The host specification may be either a host name (see
-.IR hosts (5))
-or an Internet address specified in the \*(lqdot notation\*(rq (see
-.IR inet (3N)).
-.TP
-.B close
-.br
-Close a
-.B TELNET
-session and return to command mode.
-.TP
-.B quit
-.br
-Close any open
-.B TELNET
-session and exit
-.IR telnet .
-An end of file (in command mode) will also close a session and exit.
-.TP
-.B z
-.br
-Suspend
-.IR telnet .
-This command only works when the user is using the
-.IR csh (1).
-.TP
-.B mode \fItype\fP
-.br
-.I Type
-is either
-.I line
-(for \*(lqline by line\*(rq mode)
-or
-.I character
-(for \*(lqcharacter at a time\*(rq mode).
-The remote host is asked for permission to go into the requested mode.
-If the remote host is capable of entering that mode, the requested
-mode will be entered.
-.TP
-.B status
-.br
-Show the current status of
-.IR telnet .
-This includes the peer one is connected to, as well
-as the current mode.
-.TP
-.B display \fR[\fP \fIargument...\fP \fR]\fP
-.br
-Displays all, or some, of the
-.B set
-and
-.B toggle
-values (see below).
-.TP
-.B ? \fR[\fP \fIcommand\fP \fR]\fP
-.br
-Get help. With no arguments,
-.I telnet
-prints a help summary.
-If a command is specified,
-.I telnet
-will print the help information for just that command.
-.TP
-.B send \fIarguments\fP
-.br
-Sends one or more special character sequences to the remote host.
-The following are the arguments which may be specified
-(more than one argument may be specified at a time):
-.RS
-.TP
-.I escape
-.br
-Sends the current
-.I telnet
-escape character (initially \*(lq^]\*(rq).
-.TP
-.I synch
-.br
-Sends the
-.B TELNET SYNCH
-sequence.
-This sequence causes the remote system to discard all previously typed
-(but not yet read) input.
-This sequence is sent as TCP urgent
-data (and may not work if the remote system is a 4.2 BSD system -- if
-it doesn't work, a lower case \*(lqr\*(rq may be echoed on the terminal).
-.TP
-.I brk
-.br
-Sends the
-.B TELNET BRK
-(Break) sequence, which may have significance to the remote
-system.
-.TP
-.I ip
-.br
-Sends the
-.B TELNET IP
-(Interrupt Process) sequence, which should cause the remote
-system to abort the currently running process.
-.TP
-.I ao
-.br
-Sends the
-.B TELNET AO
-(Abort Output) sequence, which should cause the remote system to flush
-all output
-.B from
-the remote system
-.B to
-the user's terminal.
-.TP
-.I ayt
-.br
-Sends the
-.B TELNET AYT
-(Are You There)
-sequence, to which the remote system may or may not choose to respond.
-.TP
-.I ec
-.br
-Sends the
-.B TELNET EC
-(Erase Character)
-sequence, which should cause the remote system to erase the last character
-entered.
-.TP
-.I el
-.br
-Sends the
-.B TELNET EL
-(Erase Line)
-sequence, which should cause the remote system to erase the line currently
-being entered.
-.TP
-.I ga
-.br
-Sends the
-.B TELNET GA
-(Go Ahead)
-sequence, which likely has no significance to the remote system.
-.TP
-.I nop
-.br
-Sends the
-.B TELNET NOP
-(No OPeration)
-sequence.
-.TP
-.I ?
-.br
-Prints out help information for the
-.B send
-command.
-.RE
-.TP
-.B set \fIargument value\fP
-.br
-Set any one of a number of
-.I telnet
-variables to a specific value.
-The special value \*(lqoff\*(rq turns off the function associated with
-the variable.
-The values of variables may be interrogated with the
-.B display
-command.
-The variables which may be specified are:
-.RS
-.TP
-.I echo
-.br
-This is the value (initially \*(lq^E\*(rq) which, when in
-\*(lqline by line\*(rq mode, toggles between doing local echoing
-of entered characters (for normal processing), and suppressing
-echoing of entered characters (for entering, say, a password).
-.TP
-.I escape
-.br
-This is the
-.I telnet
-escape character (initially \*(lq^[\*(rq) which causes entry
-into
-.I telnet
-command mode (when connected to a remote system).
-.TP
-.I interrupt
-.br
-If
-.I telnet
-is in
-.I localchars
-mode (see
-.B toggle
-.I localchars
-below)
-and the
-.I interrupt
-character is typed, a
-.B TELNET IP
-sequence (see
-.B send
-.I ip
-above)
-is sent to the remote host.
-The initial value for the interrupt character is taken to be
-the terminal's
-.B intr
-character.
-.TP
-.I quit
-.br
-If
-.I telnet
-is in
-.I localchars
-mode (see
-.B toggle
-.I localchars
-below)
-and the
-.I quit
-character is typed, a
-.B TELNET BRK
-sequence (see
-.B send
-.I brk
-above)
-is sent to the remote host.
-The initial value for the quit character is taken to be
-the terminal's
-.B quit
-character.
-.TP
-.I flushoutput
-.br
-If
-.I telnet
-is in
-.I localchars
-mode (see
-.B toggle
-.I localchars
-below)
-and the
-.I flushoutput
-character is typed, a
-.B TELNET AO
-sequence (see
-.B send
-.I ao
-above)
-is sent to the remote host.
-The initial value for the flush character is taken to be
-the terminal's
-.B flush
-character.
-.TP
-.I erase
-.br
-If
-.I telnet
-is in
-.I localchars
-mode (see
-.B toggle
-.I localchars
-below),
-.B and
-if
-.I telnet
-is operating in \*(lqcharacter at a time\*(rq mode, then when this
-character is typed, a
-.B TELNET EC
-sequence (see
-.B send
-.I ec
-above)
-is sent to the remote system.
-The initial value for the erase character is taken to be
-the terminal's
-.B erase
-character.
-.TP
-.I kill
-.br
-If
-.I telnet
-is in
-.I localchars
-mode (see
-.B toggle
-.I localchars
-below),
-.B and
-if
-.I telnet
-is operating in \*(lqcharacter at a time\*(rq mode, then when this
-character is typed, a
-.B TELNET EL
-sequence (see
-.B send
-.I el
-above)
-is sent to the remote system.
-The initial value for the kill character is taken to be
-the terminal's
-.B kill
-character.
-.TP
-.I eof
-.br
-If
-.I telnet
-is operating in \*(lqline by line\*(rq mode, entering this character
-as the first character on a line will cause this character to be
-sent to the remote system.
-The initial value of the eof character is taken to be the terminal's
-.B eof
-character.
-.RE
-.TP
-.B toggle \fIarguments...\fP
-.br
-Toggle (between
-TRUE
-and
-FALSE)
-various flags that control how
-.I telnet
-responds to events.
-More than one argument may be specified.
-The state of these flags may be interrogated with the
-.B display
-command.
-Valid arguments are:
-.RS
-.TP
-.I localchars
-.br
-If this is
-TRUE,
-then the
-.IR flush ,
-.IR interrupt ,
-.IR quit ,
-.IR erase ,
-and
-.I kill
-characters (see
-.B set
-above) are recognized locally, and transformed into (hopefully) appropriate
-.B TELNET
-control sequences
-(respectively
-.IR ao ,
-.IR ip ,
-.IR brk ,
-.IR ec ,
-and
-.IR el ;
-see
-.B send
-above).
-The initial value for this toggle is TRUE in \*(lqline by line\*(rq mode,
-and FALSE in \*(lqcharacter at a time\*(rq mode.
-.TP
-.I autoflush
-.br
-If
-.I autoflush
-and
-.I localchars
-are both
-TRUE,
-then when the
-.IR ao ,
-.IR intr ,
-or
-.I quit
-characters are recognized (and transformed into
-.B TELNET
-sequences; see
-.B set
-above for details),
-.I telnet
-refuses to display any data on the user's terminal
-until the remote system acknowledges (via a
-.B TELNET
-.I Timing Mark
-option)
-that it has processed those
-.B TELNET
-sequences.
-The initial value for this toggle is TRUE if the terminal user had not
-done an "stty noflsh", otherwise FALSE (see
-.IR stty(1)).
-.TP
-.I autosynch
-If
-.I autosynch
-and
-.I localchars
-are both
-TRUE,
-then when either the
-.I intr
-or
-.I quit
-characters is typed (see
-.B set
-above for descriptions of the
-.I intr
-and
-.I quit
-characters), the resulting
-.B TELNET
-sequence sent is followed by the
-.B TELNET SYNCH
-sequence.
-This procedure
-.B should
-cause the remote system to begin throwing away all previously
-typed input until both of the
-.B TELNET
-sequences have been read and acted upon.
-The initial value of this toggle is FALSE.
-.TP
-.I crmod
-.br
-Toggle carriage return mode.
-When this mode is enabled, most carriage return characters received from
-the remote host will be mapped into a carriage return followed by
-a line feed.
-This mode does not affect those characters typed by the user, only
-those received from the remote host.
-This mode is not very useful unless the remote host
-only sends carriage return, but never line feed.
-The initial value for this toggle is FALSE.
-.TP
-.I debug
-.br
-Toggles socket level debugging (useful only to the
-.IR super user ).
-The initial value for this toggle is FALSE.
-.TP
-.I options
-.br
-Toggles the display of some internal
-.I telnet
-protocol processing (having to do with
-.B TELNET
-options).
-The initial value for this toggle is FALSE.
-.TP
-.I netdata
-.br
-Toggles the display of all network data (in hexadecimal format).
-The initial value for this toggle is FALSE.
-.TP
-.I ?
-.br
-Displays the legal
-.B toggle
-commands.
-.RE
-.SH BUGS
-.PP
-There is no adequate way for dealing with flow control.
-.PP
-On some remote systems, echo has to be turned off manually when in
-\*(lqline by line\*(rq mode.
-.PP
-There is enough settable state to justify a
-.RI . telnetrc
-file.
-.PP
-No capability for a
-.RI . telnetrc
-file is provided.
-.PP
-In \*(lqline by line\*(rq mode, the terminal's
-.I eof
-character is only recognized (and sent to the remote system)
-when it is the first character on a line.
+++ /dev/null
-/*
-ttn.c
-*/
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <termios.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <net/hton.h>
-#include <net/netlib.h>
-#include <net/gen/in.h>
-#include <net/gen/inet.h>
-#include <netdb.h>
-#include <net/gen/tcp.h>
-#include <net/gen/tcp_io.h>
-#include <arpa/inet.h>
-#include "ttn.h"
-
-#if __STDC__
-#define PROTOTYPE(func,args) func args
-#else
-#define PROTOTYPE(func,args) func()
-#endif
-
-static int do_read(int fd, char *buf, unsigned len);
-static void screen(void);
-static void keyboard(void);
-static void send_brk(void);
-static int process_opt (char *bp, int count);
-static void do_option (int optsrt);
-static void dont_option (int optsrt);
-static void will_option (int optsrt);
-static void wont_option (int optsrt);
-static int writeall (int fd, char *buffer, int buf_size);
-static int sb_termtype (char *sb, int count);
-static void fatal(char *fmt, ...);
-static void usage(void);
-
-#if DEBUG
-#define where() (fprintf(stderr, "%s %d:", __FILE__, __LINE__))
-#endif
-
-static char *prog_name;
-static int tcp_fd;
-static char *term_env;
-static int esc_char= '~';
-static enum { LS_NORM, LS_BOL, LS_ESC } line_state= LS_BOL;
-
-int main(int argc, char *argv[])
-{
- struct hostent *hostent;
- struct servent *servent;
- ipaddr_t host;
- tcpport_t port;
- int pid, ppid;
- nwio_tcpconf_t tcpconf;
- int c, r;
- nwio_tcpcl_t tcpconnopt;
- struct termios termios;
- char *tcp_device, *remote_name, *port_name;
- char *e_arg;
-
- (prog_name=strrchr(argv[0],'/')) ? prog_name++ : (prog_name=argv[0]);
-
- e_arg= NULL;
- while (c= getopt(argc, argv, "?e:"), c != -1)
- {
- switch(c)
- {
- case '?': usage();
- case 'e': e_arg= optarg; break;
- default:
- fatal("Optind failed: '%c'", c);
- }
- }
-
- if (optind >= argc)
- usage();
- remote_name= argv[optind++];
- if (optind < argc)
- port_name= argv[optind++];
- else
- port_name= NULL;
- if (optind != argc)
- usage();
-
- if (e_arg)
- {
- switch(strlen(e_arg))
- {
- case 0: esc_char= -1; break;
- case 1: esc_char= e_arg[0]; break;
- default: fatal("Invalid escape character '%s'", e_arg);
- }
- }
-
- hostent= gethostbyname(remote_name);
- if (!hostent)
- fatal("Unknown host %s", remote_name);
- host= *(ipaddr_t *)(hostent->h_addr);
-
- if (!port_name)
- port= htons(TCPPORT_TELNET);
- else
- {
- servent= getservbyname (port_name, "tcp");
- if (!servent)
- {
- port= htons(strtol(port_name, (char **)0, 0));
- if (!port)
- fatal("Unknown port %s", port_name);
- }
- else
- port= (tcpport_t)(servent->s_port);
- }
-
- fprintf(stderr, "Connecting to %s:%u...\n",
- inet_ntoa(*(struct in_addr *)&host), ntohs(port));
-
- tcp_device= getenv("TCP_DEVICE");
- if (tcp_device == NULL)
- tcp_device= TCP_DEVICE;
- tcp_fd= open (tcp_device, O_RDWR);
- if (tcp_fd == -1)
- fatal("Unable to open %s: %s", tcp_device, strerror(errno));
-
- tcpconf.nwtc_flags= NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP;
- tcpconf.nwtc_remaddr= host;
- tcpconf.nwtc_remport= port;
-
- r= ioctl (tcp_fd, NWIOSTCPCONF, &tcpconf);
- if (r == -1)
- fatal("NWIOSTCPCONF failed: %s", strerror(errno));
-
- tcpconnopt.nwtcl_flags= 0;
- do
- {
- r= ioctl (tcp_fd, NWIOTCPCONN, &tcpconnopt);
- if (r == -1 && errno == EAGAIN)
- {
- fprintf(stderr, "%s: Got EAGAIN, sleeping(1s)\n",
- prog_name);
- sleep(1);
- }
- } while (r == -1 && errno == EAGAIN);
- if (r == -1)
- fatal("Unable to connect: %s", strerror(errno));
- printf("Connected\n");
- ppid= getpid();
- pid= fork();
- switch(pid)
- {
- case 0:
- keyboard();
-#if DEBUG
-fprintf(stderr, "killing %d with %d\r\n", ppid, SIGKILL);
-#endif
- kill(ppid, SIGKILL);
- break;
- case -1:
- fprintf(stderr, "%s: fork failed: %s\r\n", argv[0],
- strerror(errno));
- exit(1);
- break;
- default:
- tcgetattr(0, &termios);
- screen();
-#if DEBUG
-fprintf(stderr, "killing %d with %d\r\n", pid, SIGKILL);
-#endif
- kill(pid, SIGKILL);
- tcsetattr(0, TCSANOW, &termios);
- break;
- }
- exit(0);
-}
-
-static int do_read(fd, buf, len)
-int fd;
-char *buf;
-unsigned len;
-{
- nwio_tcpopt_t tcpopt;
- int count;
-
- for (;;)
- {
- count= read (fd, buf, len);
- if (count <0)
- {
- if (errno == EURG || errno == ENOURG)
- {
- /* Toggle urgent mode. */
- tcpopt.nwto_flags= errno == EURG ?
- NWTO_RCV_URG : NWTO_RCV_NOTURG;
- if (ioctl(tcp_fd, NWIOSTCPOPT, &tcpopt) == -1)
- {
- return -1;
- }
- continue;
- }
- return -1;
- }
- return count;
- }
-}
-
-static void screen()
-{
- char buffer[1024], *bp, *iacptr;
- int count, optsize;
-
- for (;;)
- {
- count= do_read (tcp_fd, buffer, sizeof(buffer));
-#if DEBUG && 0
- { where(); fprintf(stderr, "read %d bytes\r\n", count); }
-#endif
- if (count <0)
- {
- perror ("read");
- return;
- }
- if (!count)
- return;
- bp= buffer;
- do
- {
- iacptr= memchr (bp, IAC, count);
- if (!iacptr)
- {
- write(1, bp, count);
- count= 0;
- }
- if (iacptr && iacptr>bp)
- {
-#if DEBUG
- { where(); fprintf(stderr, "iacptr-bp= %d\r\n", iacptr-bp); }
-#endif
- write(1, bp, iacptr-bp);
- count -= (iacptr-bp);
- bp= iacptr;
- continue;
- }
- if (iacptr)
- {
-assert (iacptr == bp);
- optsize= process_opt(bp, count);
-#if DEBUG && 0
- { where(); fprintf(stderr, "process_opt(...)= %d\r\n", optsize); }
-#endif
- if (optsize<0)
- return;
-assert (optsize);
- bp += optsize;
- count -= optsize;
- }
- } while (count);
- }
-}
-
-static void keyboard()
-{
- char c, buffer[1024];
- int count;
-
- for (;;)
- {
- count= read (0, buffer, 1 /* sizeof(buffer) */);
- if (count == -1)
- fatal("Read: %s\r\n", strerror(errno));
- if (!count)
- return;
-
- if (line_state != LS_NORM)
- {
- c= buffer[0];
- if (line_state == LS_BOL)
- {
- if (c == esc_char)
- {
- line_state= LS_ESC;
- continue;
- }
- line_state= LS_NORM;
- }
- else if (line_state == LS_ESC)
- {
- line_state= LS_NORM;
- if (c == '.')
- return;
- if (c == '#')
- {
- send_brk();
- continue;
- }
-
- /* Not a valid command or a repeat of the
- * escape char
- */
- if (c != esc_char)
- {
- c= esc_char;
- write(tcp_fd, &c, 1);
- }
- }
- }
- if (buffer[0] == '\n')
- write(tcp_fd, "\r", 1);
- count= write(tcp_fd, buffer, count);
- if (buffer[0] == '\r')
- {
- line_state= LS_BOL;
- write(tcp_fd, "\0", 1);
- }
- if (count<0)
- {
- perror("write");
- fprintf(stderr, "errno= %d\r\n", errno);
- return;
- }
- if (!count)
- return;
- }
-}
-
-static void send_brk(void)
-{
- int r;
- unsigned char buffer[2];
-
- buffer[0]= IAC;
- buffer[1]= IAC_BRK;
-
- r= writeall(tcp_fd, (char *)buffer, 2);
- if (r == -1)
- fatal("Error writing to TCP connection: %s", strerror(errno));
-}
-
-#define next_char(var) \
- if (offset<count) { (var) = bp[offset++]; } \
- else if (do_read(tcp_fd, (char *)&(var), 1) <= 0) \
- { perror ("read"); return -1; }
-
-static int process_opt (char *bp, int count)
-{
- unsigned char iac, command, optsrt, sb_command;
- int offset, result; ;
-#if DEBUG && 0
- { where(); fprintf(stderr, "process_opt(bp= 0x%x, count= %d)\r\n",
- bp, count); }
-#endif
-
- offset= 0;
-assert (count);
- next_char(iac);
-assert (iac == IAC);
- next_char(command);
- switch(command)
- {
- case IAC_NOP:
- break;
- case IAC_DataMark:
- /* Ought to flush input queue or something. */
- break;
- case IAC_BRK:
-fprintf(stderr, "got a BRK\r\n");
- break;
- case IAC_IP:
-fprintf(stderr, "got a IP\r\n");
- break;
- case IAC_AO:
-fprintf(stderr, "got a AO\r\n");
- break;
- case IAC_AYT:
-fprintf(stderr, "got a AYT\r\n");
- break;
- case IAC_EC:
-fprintf(stderr, "got a EC\r\n");
- break;
- case IAC_EL:
-fprintf(stderr, "got a EL\r\n");
- break;
- case IAC_GA:
-fprintf(stderr, "got a GA\r\n");
- break;
- case IAC_SB:
- next_char(sb_command);
- switch (sb_command)
- {
- case OPT_TERMTYPE:
-#if DEBUG && 0
-fprintf(stderr, "got SB TERMINAL-TYPE\r\n");
-#endif
- result= sb_termtype(bp+offset, count-offset);
- if (result<0)
- return result;
- else
- return result+offset;
- default:
-fprintf(stderr, "got an unknown SB (skiping)\r\n");
- for (;;)
- {
- next_char(iac);
- if (iac != IAC)
- continue;
- next_char(optsrt);
- if (optsrt == IAC)
- continue;
-if (optsrt != IAC_SE)
- fprintf(stderr, "got IAC %d\r\n", optsrt);
- break;
- }
- }
- break;
- case IAC_WILL:
- next_char(optsrt);
- will_option(optsrt);
- break;
- case IAC_WONT:
- next_char(optsrt);
- wont_option(optsrt);
- break;
- case IAC_DO:
- next_char(optsrt);
- do_option(optsrt);
- break;
- case IAC_DONT:
- next_char(optsrt);
- dont_option(optsrt);
- break;
- case IAC:
-fprintf(stderr, "got a IAC\r\n");
- break;
- default:
-fprintf(stderr, "got unknown command (%d)\r\n", command);
- }
- return offset;
-}
-
-static void do_option (int optsrt)
-{
- unsigned char reply[3];
- int result;
-
- switch (optsrt)
- {
- case OPT_TERMTYPE:
- if (WILL_terminal_type)
- return;
- if (!WILL_terminal_type_allowed)
- {
- reply[0]= IAC;
- reply[1]= IAC_WONT;
- reply[2]= optsrt;
- }
- else
- {
- WILL_terminal_type= TRUE;
- term_env= getenv("TERM");
- if (!term_env)
- term_env= "unknown";
- reply[0]= IAC;
- reply[1]= IAC_WILL;
- reply[2]= optsrt;
- }
- break;
- default:
-#if DEBUG
- fprintf(stderr, "got a DO (%d)\r\n", optsrt);
- fprintf(stderr, "WONT (%d)\r\n", optsrt);
-#endif
- reply[0]= IAC;
- reply[1]= IAC_WONT;
- reply[2]= optsrt;
- break;
- }
- result= writeall(tcp_fd, (char *)reply, 3);
- if (result<0)
- perror("write");
-}
-
-static void will_option (int optsrt)
-{
- unsigned char reply[3];
- int result;
-
- switch (optsrt)
- {
- case OPT_ECHO:
- if (DO_echo)
- break;
- if (!DO_echo_allowed)
- {
- reply[0]= IAC;
- reply[1]= IAC_DONT;
- reply[2]= optsrt;
- }
- else
- {
- struct termios termios;
-
- tcgetattr(0, &termios);
- termios.c_iflag &= ~(ICRNL|IGNCR|INLCR|IXON|IXOFF);
- termios.c_oflag &= ~(OPOST);
- termios.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
- tcsetattr(0, TCSANOW, &termios);
-
- DO_echo= TRUE;
- reply[0]= IAC;
- reply[1]= IAC_DO;
- reply[2]= optsrt;
- }
- result= writeall(tcp_fd, (char *)reply, 3);
- if (result<0)
- perror("write");
- break;
- case OPT_SUPP_GA:
- if (DO_suppress_go_ahead)
- break;
- if (!DO_suppress_go_ahead_allowed)
- {
- reply[0]= IAC;
- reply[1]= IAC_DONT;
- reply[2]= optsrt;
- }
- else
- {
- DO_suppress_go_ahead= TRUE;
- reply[0]= IAC;
- reply[1]= IAC_DO;
- reply[2]= optsrt;
- }
- result= writeall(tcp_fd, (char *)reply, 3);
- if (result<0)
- perror("write");
- break;
- default:
-#if DEBUG
- fprintf(stderr, "got a WILL (%d)\r\n", optsrt);
- fprintf(stderr, "DONT (%d)\r\n", optsrt);
-#endif
- reply[0]= IAC;
- reply[1]= IAC_DONT;
- reply[2]= optsrt;
- result= writeall(tcp_fd, (char *)reply, 3);
- if (result<0)
- perror("write");
- break;
- }
-}
-
-static int writeall (fd, buffer, buf_size)
-int fd;
-char *buffer;
-int buf_size;
-{
- int result;
-
- while (buf_size)
- {
- result= write (fd, buffer, buf_size);
- if (result <= 0)
- return -1;
-assert (result <= buf_size);
- buffer += result;
- buf_size -= result;
- }
- return 0;
-}
-
-static void dont_option (int optsrt)
-{
- switch (optsrt)
- {
- default:
-#if DEBUG
- fprintf(stderr, "got a DONT (%d)\r\n", optsrt);
-#endif
- break;
- }
-}
-
-static void wont_option (int optsrt)
-{
- switch (optsrt)
- {
- default:
-#if DEBUG
- fprintf(stderr, "got a WONT (%d)\r\n", optsrt);
-#endif
- break;
- }
-}
-
-static int sb_termtype (char *bp, int count)
-{
- unsigned char command, iac, optsrt;
- unsigned char buffer[4];
- int offset, result;
-
- offset= 0;
- next_char(command);
- if (command == TERMTYPE_SEND)
- {
- buffer[0]= IAC;
- buffer[1]= IAC_SB;
- buffer[2]= OPT_TERMTYPE;
- buffer[3]= TERMTYPE_IS;
- result= writeall(tcp_fd, (char *)buffer,4);
- if (result<0)
- return result;
- count= strlen(term_env);
- if (!count)
- {
- term_env= "unknown";
- count= strlen(term_env);
- }
- result= writeall(tcp_fd, term_env, count);
- if (result<0)
- return result;
- buffer[0]= IAC;
- buffer[1]= IAC_SE;
- result= writeall(tcp_fd, (char *)buffer,2);
- if (result<0)
- return result;
-
- }
- else
- {
-#if DEBUG
- where();
-#endif
- fprintf(stderr, "got an unknown command (skipping)\r\n");
- }
- for (;;)
- {
- next_char(iac);
- if (iac != IAC)
- continue;
- next_char(optsrt);
- if (optsrt == IAC)
- continue;
- if (optsrt != IAC_SE)
- {
-#if DEBUG
- where();
-#endif
- fprintf(stderr, "got IAC %d\r\n", optsrt);
- }
- break;
- }
- return offset;
-}
-
-static void fatal(char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- fprintf(stderr, "%s: ", prog_name);
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- va_end(ap);
-
- exit(1);
-}
-
-static void usage(void)
-{
- fprintf(stderr, "Usage: %s [-e esc-char] host [port]\r\n",
- prog_name);
- exit(1);
-}
-
-/*
- * $PchId: ttn.c,v 1.5 2002/05/07 12:06:41 philip Exp $
- */