Ported the telnet command from FreeBSD - compiles, but might not yet work; it's

completely untested at this point.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19494 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-12-13 16:28:15 +00:00
parent 8f813eeb9d
commit 8d5a60482c
17 changed files with 9546 additions and 0 deletions
+1
View File
@@ -7,5 +7,6 @@ SubInclude HAIKU_TOP src bin network ifconfig ;
#SubInclude HAIKU_TOP src bin network ppp_up ;
SubInclude HAIKU_TOP src bin network ping ;
SubInclude HAIKU_TOP src bin network route ;
SubInclude HAIKU_TOP src bin network telnet ;
SubInclude HAIKU_TOP src bin network telnetd ;
SubInclude HAIKU_TOP src bin network traceroute ;
+23
View File
@@ -0,0 +1,23 @@
SubDir HAIKU_TOP src bin network telnet ;
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs libtelnet ] : false ;
local defines = [ FDefines USE_TERMIO=1 OLD_ENVIRON=1 ENV_HACK=1 ] ;
SubDirCcFlags $(defines) ;
SubDirC++Flags $(defines) ;
BinCommand telnet :
authenc.c
commands.c
main.c
network.c
ring.c
sys_bsd.c
telnet.c
terminal.c
utilities.c
: libtermcap.a libncurses.a libtelnet.a libutil.a libbsd.so $(NETWORK_LIBS)
;
+111
View File
@@ -0,0 +1,111 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static const char sccsid[] = "@(#)authenc.c 8.1 (Berkeley) 6/6/93";
#endif
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/contrib/telnet/telnet/authenc.c,v 1.6 2003/05/04 02:54:48 obrien Exp $");
#ifdef AUTHENTICATION
#ifdef ENCRYPTION
#include <sys/types.h>
#include <arpa/telnet.h>
#include <pwd.h>
#include <unistd.h>
#include <libtelnet/encrypt.h>
#include <libtelnet/misc.h>
#include "general.h"
#include "ring.h"
#include "externs.h"
#include "defines.h"
#include "types.h"
int
net_write(unsigned char *str, int len)
{
if (NETROOM() > len) {
ring_supply_data(&netoring, str, len);
if (str[0] == IAC && str[1] == SE)
printsub('>', &str[2], len-2);
return(len);
}
return(0);
}
void
net_encrypt(void)
{
#ifdef ENCRYPTION
if (encrypt_output)
ring_encrypt(&netoring, encrypt_output);
else
ring_clearto(&netoring);
#endif /* ENCRYPTION */
}
int
telnet_spin(void)
{
return(-1);
}
char *
telnet_getenv(char *val)
{
return((char *)env_getvalue((unsigned char *)val));
}
char *
telnet_gets(const char *prom, char *result, int length, int echo)
{
extern int globalmode;
int om = globalmode;
char *res;
TerminalNewMode(-1);
if (echo) {
printf("%s", prom);
res = fgets(result, length, stdin);
} else if ((res = getpass(prom))) {
strncpy(result, res, length);
res = result;
}
TerminalNewMode(om);
return(res);
}
#endif /* ENCRYPTION */
#endif /* AUTHENTICATION */
File diff suppressed because it is too large Load Diff
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)defines.h 8.1 (Berkeley) 6/6/93
* $FreeBSD: src/contrib/telnet/telnet/defines.h,v 1.2 2001/11/30 21:06:35 markm Exp $
*/
#define settimer(x) clocks.x = clocks.system++
#define NETADD(c) { *netoring.supply = c; ring_supplied(&netoring, 1); }
#define NET2ADD(c1,c2) { NETADD(c1); NETADD(c2); }
#define NETBYTES() (ring_full_count(&netoring))
#define NETROOM() (ring_empty_count(&netoring))
#define TTYADD(c) if (!(SYNCHing||flushout)) { \
*ttyoring.supply = c; \
ring_supplied(&ttyoring, 1); \
}
#define TTYBYTES() (ring_full_count(&ttyoring))
#define TTYROOM() (ring_empty_count(&ttyoring))
/* Various modes */
#define MODE_LOCAL_CHARS(m) ((m)&(MODE_EDIT|MODE_TRAPSIG))
#define MODE_LOCAL_ECHO(m) ((m)&MODE_ECHO)
#define MODE_COMMAND_LINE(m) ((m)==-1)
#define CONTROL(x) ((x)&0x1f) /* CTRL(x) is not portable */
+491
View File
@@ -0,0 +1,491 @@
/*
* Copyright (c) 1988, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)externs.h 8.3 (Berkeley) 5/30/95
* $FreeBSD: src/contrib/telnet/telnet/externs.h,v 1.10 2003/05/11 18:17:00 markm Exp $
*/
#ifndef BSD
# define BSD 43
#endif
/*
* ucb stdio.h defines BSD as something weird
*/
#if defined(sun) && defined(__svr4__)
#define BSD 43
#endif
#ifndef USE_TERMIO
# if BSD > 43 || defined(SYSV_TERMIO)
# define USE_TERMIO
# endif
#endif
#include <stdio.h>
#include <setjmp.h>
#include <sys/ioctl.h>
#include <errno.h>
#ifdef USE_TERMIO
# ifndef VINTR
# include <termios.h>
# endif
# define termio termios
#endif
#if defined(NO_CC_T) || !defined(USE_TERMIO)
# if !defined(USE_TERMIO)
typedef char cc_t;
# else
typedef unsigned char cc_t;
# endif
#endif
#include <string.h>
#if defined(IPSEC)
#include <netinet6/ipsec.h>
#if defined(IPSEC_POLICY_IPSEC)
extern char *ipsec_policy_in;
extern char *ipsec_policy_out;
#endif
#endif
#ifndef _POSIX_VDISABLE
# ifdef sun
# include <sys/param.h> /* pick up VDISABLE definition, mayby */
# endif
# ifdef VDISABLE
# define _POSIX_VDISABLE VDISABLE
# else
# define _POSIX_VDISABLE ((cc_t)'\377')
# endif
#endif
#define SUBBUFSIZE 256
#if !defined(P)
# ifdef __STDC__
# define P(x) x
# else
# define P(x) ()
# endif
#endif
extern int
autologin, /* Autologin enabled */
skiprc, /* Don't process the ~/.telnetrc file */
eight, /* use eight bit mode (binary in and/or out */
family, /* address family of peer */
flushout, /* flush output */
connected, /* Are we connected to the other side? */
globalmode, /* Mode tty should be in */
telnetport, /* Are we connected to the telnet port? */
localflow, /* Flow control handled locally */
restartany, /* If flow control, restart output on any character */
localchars, /* we recognize interrupt/quit */
donelclchars, /* the user has set "localchars" */
showoptions,
net, /* Network file descriptor */
tin, /* Terminal input file descriptor */
tout, /* Terminal output file descriptor */
crlf, /* Should '\r' be mapped to <CR><LF> (or <CR><NUL>)? */
autoflush, /* flush output when interrupting? */
autosynch, /* send interrupt characters with SYNCH? */
SYNCHing, /* Is the stream in telnet SYNCH mode? */
donebinarytoggle, /* the user has put us in binary */
dontlecho, /* do we suppress local echoing right now? */
crmod,
netdata, /* Print out network data flow */
prettydump, /* Print "netdata" output in user readable format */
termdata, /* Print out terminal data flow */
telnet_debug, /* Debug level */
doaddrlookup, /* do a reverse lookup? */
clienteof; /* Client received EOF */
extern cc_t escape; /* Escape to command mode */
extern cc_t rlogin; /* Rlogin mode escape character */
#ifdef KLUDGELINEMODE
extern cc_t echoc; /* Toggle local echoing */
#endif
extern char
*prompt; /* Prompt for command. */
extern char
doopt[],
dont[],
will[],
wont[],
options[], /* All the little options */
*hostname; /* Who are we connected to? */
#ifdef ENCRYPTION
extern void (*encrypt_output)(unsigned char *, int);
extern int (*decrypt_input)(int);
#endif /* ENCRYPTION */
/*
* We keep track of each side of the option negotiation.
*/
#define MY_STATE_WILL 0x01
#define MY_WANT_STATE_WILL 0x02
#define MY_STATE_DO 0x04
#define MY_WANT_STATE_DO 0x08
/*
* Macros to check the current state of things
*/
#define my_state_is_do(opt) (options[opt]&MY_STATE_DO)
#define my_state_is_will(opt) (options[opt]&MY_STATE_WILL)
#define my_want_state_is_do(opt) (options[opt]&MY_WANT_STATE_DO)
#define my_want_state_is_will(opt) (options[opt]&MY_WANT_STATE_WILL)
#define my_state_is_dont(opt) (!my_state_is_do(opt))
#define my_state_is_wont(opt) (!my_state_is_will(opt))
#define my_want_state_is_dont(opt) (!my_want_state_is_do(opt))
#define my_want_state_is_wont(opt) (!my_want_state_is_will(opt))
#define set_my_state_do(opt) {options[opt] |= MY_STATE_DO;}
#define set_my_state_will(opt) {options[opt] |= MY_STATE_WILL;}
#define set_my_want_state_do(opt) {options[opt] |= MY_WANT_STATE_DO;}
#define set_my_want_state_will(opt) {options[opt] |= MY_WANT_STATE_WILL;}
#define set_my_state_dont(opt) {options[opt] &= ~MY_STATE_DO;}
#define set_my_state_wont(opt) {options[opt] &= ~MY_STATE_WILL;}
#define set_my_want_state_dont(opt) {options[opt] &= ~MY_WANT_STATE_DO;}
#define set_my_want_state_wont(opt) {options[opt] &= ~MY_WANT_STATE_WILL;}
/*
* Make everything symetrical
*/
#define HIS_STATE_WILL MY_STATE_DO
#define HIS_WANT_STATE_WILL MY_WANT_STATE_DO
#define HIS_STATE_DO MY_STATE_WILL
#define HIS_WANT_STATE_DO MY_WANT_STATE_WILL
#define his_state_is_do my_state_is_will
#define his_state_is_will my_state_is_do
#define his_want_state_is_do my_want_state_is_will
#define his_want_state_is_will my_want_state_is_do
#define his_state_is_dont my_state_is_wont
#define his_state_is_wont my_state_is_dont
#define his_want_state_is_dont my_want_state_is_wont
#define his_want_state_is_wont my_want_state_is_dont
#define set_his_state_do set_my_state_will
#define set_his_state_will set_my_state_do
#define set_his_want_state_do set_my_want_state_will
#define set_his_want_state_will set_my_want_state_do
#define set_his_state_dont set_my_state_wont
#define set_his_state_wont set_my_state_dont
#define set_his_want_state_dont set_my_want_state_wont
#define set_his_want_state_wont set_my_want_state_dont
#if defined(USE_TERMIO)
#define SIG_FUNC_RET void
#else
#define SIG_FUNC_RET int
#endif
#ifdef SIGINFO
extern SIG_FUNC_RET
ayt_status(void);
#endif
extern FILE
*NetTrace; /* Where debugging output goes */
extern unsigned char
NetTraceFile[]; /* Name of file where debugging output goes */
extern void
SetNetTrace(char *); /* Function to change where debugging goes */
extern jmp_buf
peerdied,
toplevel; /* For error conditions. */
extern void
command(int, const char *, int),
Dump(char, unsigned char *, int),
env_init(void),
Exit(int),
ExitString(const char *, int),
init_network(void),
init_sys(void),
init_telnet(void),
init_terminal(void),
intp(void),
optionstatus(void),
printoption(const char *, int, int),
printsub(char, unsigned char *, int),
quit(void),
sendabort(void),
sendbrk(void),
sendeof(void),
sendsusp(void),
sendnaws(void),
sendayt(void),
setconnmode(int),
setcommandmode(void),
set_escape_char(char *s),
setneturg(void),
sys_telnet_init(void),
telnet(char *),
tel_enter_binary(int),
tel_leave_binary(int),
TerminalFlushOutput(void),
TerminalNewMode(int),
TerminalRestoreState(void),
TerminalSaveState(void),
TerminalDefaultChars(void),
TerminalSpeeds(long *, long *),
tninit(void),
upcase(char *),
willoption(int),
wontoption(int);
extern void
send_do(int, int),
send_dont(int, int),
send_will(int, int),
send_wont(int, int);
extern void
lm_will(unsigned char *, int),
lm_wont(unsigned char *, int),
lm_do(unsigned char *, int),
lm_dont(unsigned char *, int),
lm_mode(unsigned char *, int, int);
extern void
slc_init(void),
slcstate(void),
slc_mode_export(void),
slc_mode_import(int),
slc_import(int),
slc_export(void),
slc(unsigned char *, int),
slc_check(void),
slc_start_reply(void),
slc_add_reply(unsigned char, unsigned char, cc_t),
slc_end_reply(void);
extern int
getconnmode(void),
opt_welldefined(const char *),
NetClose(int),
netflush(void),
process_rings(int, int, int, int, int, int),
rlogin_susp(void),
SetSockOpt(int, int, int, int),
slc_update(void),
stilloob(void),
telrcv(void),
TerminalRead(char *, int),
TerminalWrite(char *, int),
TerminalAutoFlush(void),
TerminalWindowSize(long *, long *),
TerminalSpecialChars(int),
tn(int, char **),
ttyflush(int);
extern void
env_opt(unsigned char *, int),
env_opt_start(void),
env_opt_start_info(void),
env_opt_add(unsigned char *),
env_opt_end(int);
extern unsigned char
*env_default(int, int),
*env_getvalue(const unsigned char *);
extern int
get_status(char *),
dosynch(char *);
extern cc_t
*tcval(int);
#ifndef USE_TERMIO
extern struct tchars ntc;
extern struct ltchars nltc;
extern struct sgttyb nttyb;
# define termEofChar ntc.t_eofc
# define termEraseChar nttyb.sg_erase
# define termFlushChar nltc.t_flushc
# define termIntChar ntc.t_intrc
# define termKillChar nttyb.sg_kill
# define termLiteralNextChar nltc.t_lnextc
# define termQuitChar ntc.t_quitc
# define termSuspChar nltc.t_suspc
# define termRprntChar nltc.t_rprntc
# define termWerasChar nltc.t_werasc
# define termStartChar ntc.t_startc
# define termStopChar ntc.t_stopc
# define termForw1Char ntc.t_brkc
extern cc_t termForw2Char;
extern cc_t termAytChar;
# define termEofCharp (cc_t *)&ntc.t_eofc
# define termEraseCharp (cc_t *)&nttyb.sg_erase
# define termFlushCharp (cc_t *)&nltc.t_flushc
# define termIntCharp (cc_t *)&ntc.t_intrc
# define termKillCharp (cc_t *)&nttyb.sg_kill
# define termLiteralNextCharp (cc_t *)&nltc.t_lnextc
# define termQuitCharp (cc_t *)&ntc.t_quitc
# define termSuspCharp (cc_t *)&nltc.t_suspc
# define termRprntCharp (cc_t *)&nltc.t_rprntc
# define termWerasCharp (cc_t *)&nltc.t_werasc
# define termStartCharp (cc_t *)&ntc.t_startc
# define termStopCharp (cc_t *)&ntc.t_stopc
# define termForw1Charp (cc_t *)&ntc.t_brkc
# define termForw2Charp (cc_t *)&termForw2Char
# define termAytCharp (cc_t *)&termAytChar
# else
extern struct termio new_tc;
# define termEofChar new_tc.c_cc[VEOF]
# define termEraseChar new_tc.c_cc[VERASE]
# define termIntChar new_tc.c_cc[VINTR]
# define termKillChar new_tc.c_cc[VKILL]
# define termQuitChar new_tc.c_cc[VQUIT]
# ifndef VSUSP
extern cc_t termSuspChar;
# else
# define termSuspChar new_tc.c_cc[VSUSP]
# endif
# if defined(VFLUSHO) && !defined(VDISCARD)
# define VDISCARD VFLUSHO
# endif
# ifndef VDISCARD
extern cc_t termFlushChar;
# else
# define termFlushChar new_tc.c_cc[VDISCARD]
# endif
# ifndef VWERASE
extern cc_t termWerasChar;
# else
# define termWerasChar new_tc.c_cc[VWERASE]
# endif
# ifndef VREPRINT
extern cc_t termRprntChar;
# else
# define termRprntChar new_tc.c_cc[VREPRINT]
# endif
# ifndef VLNEXT
extern cc_t termLiteralNextChar;
# else
# define termLiteralNextChar new_tc.c_cc[VLNEXT]
# endif
# ifndef VSTART
extern cc_t termStartChar;
# else
# define termStartChar new_tc.c_cc[VSTART]
# endif
# ifndef VSTOP
extern cc_t termStopChar;
# else
# define termStopChar new_tc.c_cc[VSTOP]
# endif
# ifndef VEOL
extern cc_t termForw1Char;
# else
# define termForw1Char new_tc.c_cc[VEOL]
# endif
# ifndef VEOL2
extern cc_t termForw2Char;
# else
# define termForw2Char new_tc.c_cc[VEOL]
# endif
# ifndef VSTATUS
extern cc_t termAytChar;
#else
# define termAytChar new_tc.c_cc[VSTATUS]
#endif
# if defined(__STDC__)
# define termEofCharp &termEofChar
# define termEraseCharp &termEraseChar
# define termIntCharp &termIntChar
# define termKillCharp &termKillChar
# define termQuitCharp &termQuitChar
# define termSuspCharp &termSuspChar
# define termFlushCharp &termFlushChar
# define termWerasCharp &termWerasChar
# define termRprntCharp &termRprntChar
# define termLiteralNextCharp &termLiteralNextChar
# define termStartCharp &termStartChar
# define termStopCharp &termStopChar
# define termForw1Charp &termForw1Char
# define termForw2Charp &termForw2Char
# define termAytCharp &termAytChar
# else
/* Work around a compiler bug */
# define termEofCharp 0
# define termEraseCharp 0
# define termIntCharp 0
# define termKillCharp 0
# define termQuitCharp 0
# define termSuspCharp 0
# define termFlushCharp 0
# define termWerasCharp 0
# define termRprntCharp 0
# define termLiteralNextCharp 0
# define termStartCharp 0
# define termStopCharp 0
# define termForw1Charp 0
# define termForw2Charp 0
# define termAytCharp 0
# endif
#endif
/* Ring buffer structures which are shared */
extern Ring
netoring,
netiring,
ttyoring,
ttyiring;
extern void
xmitAO(void),
xmitEC(void),
xmitEL(void);
+49
View File
@@ -0,0 +1,49 @@
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)fdset.h 8.1 (Berkeley) 6/6/93
*/
/*
* The following is defined just in case someone should want to run
* this telnet on a 4.2 system.
*
*/
#ifndef FD_SETSIZE
#define FD_SET(n, p) ((p)->fds_bits[0] |= (1<<(n)))
#define FD_CLR(n, p) ((p)->fds_bits[0] &= ~(1<<(n)))
#define FD_ISSET(n, p) ((p)->fds_bits[0] & (1<<(n)))
#define FD_ZERO(p) ((p)->fds_bits[0] = 0)
#endif
+45
View File
@@ -0,0 +1,45 @@
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)general.h 8.1 (Berkeley) 6/6/93
*/
/*
* Some general definitions.
*/
#define numberof(x) (sizeof x/sizeof x[0])
#define highestof(x) (numberof(x)-1)
#define ClearElement(x) memset((char *)&x, 0, sizeof x)
#define ClearArray(x) memset((char *)x, 0, sizeof x)
+386
View File
@@ -0,0 +1,386 @@
/*
* Copyright (c) 1988, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static const char sccsid[] = "@(#)main.c 8.3 (Berkeley) 5/30/95";
#endif
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/contrib/telnet/telnet/main.c,v 1.20 2005/01/09 10:24:45 maxim Exp $");
#include <sys/param.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "ring.h"
#include "externs.h"
#include "defines.h"
#ifdef AUTHENTICATION
#include <libtelnet/auth.h>
#endif
#ifdef ENCRYPTION
#include <libtelnet/encrypt.h>
#endif
/* These values need to be the same as defined in libtelnet/kerberos5.c */
/* Either define them in both places, or put in some common header file. */
#define OPTS_FORWARD_CREDS 0x00000002
#define OPTS_FORWARDABLE_CREDS 0x00000001
#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
char *ipsec_policy_in = NULL;
char *ipsec_policy_out = NULL;
#endif
extern int tos;
int family = AF_UNSPEC;
/*
* Initialize variables.
*/
void
tninit(void)
{
init_terminal();
init_network();
init_telnet();
init_sys();
}
static void
usage(void)
{
fprintf(stderr, "usage: %s %s%s%s%s\n",
prompt,
#ifdef AUTHENTICATION
"[-4] [-6] [-8] [-E] [-K] [-L] [-N] [-S tos] [-X atype] [-c] [-d]",
"\n\t[-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
#else
"[-4] [-6] [-8] [-E] [-L] [-N] [-S tos] [-c] [-d]",
"\n\t[-e char] [-l user] [-n tracefile] ",
#endif
"[-r] [-s src_addr] [-u] ",
#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
"[-P policy] "
#endif
#ifdef ENCRYPTION
"[-y] [host-name [port]]"
#else /* ENCRYPTION */
"[host-name [port]]"
#endif /* ENCRYPTION */
);
exit(1);
}
/*
* main. Parse arguments, invoke the protocol or command parser.
*/
int
main(int argc, char *argv[])
{
int ch;
#ifndef __BEOS__
char *ep;
u_long ultmp;
#endif
char *user;
char *src_addr = NULL;
#ifdef FORWARD
extern int forward_flags;
#endif /* FORWARD */
tninit(); /* Clear out things */
TerminalSaveState();
if ((prompt = strrchr(argv[0], '/')))
++prompt;
else
prompt = argv[0];
user = NULL;
rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
#ifdef AUTHENTICATION
autologin = 1;
#else
autologin = -1;
#endif
#ifdef ENCRYPTION
encrypt_auto(1);
decrypt_auto(1);
#endif
#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
#define IPSECOPT "P:"
#else
#define IPSECOPT
#endif
while ((ch = getopt(argc, argv,
"468EKLNS:X:acde:fFk:l:n:rs:uxy" IPSECOPT)) != -1)
#undef IPSECOPT
{
switch(ch) {
case '4':
family = AF_INET;
break;
#ifdef INET6
case '6':
family = AF_INET6;
break;
#endif
case '8':
eight = 3; /* binary output and input */
break;
case 'E':
rlogin = escape = _POSIX_VDISABLE;
break;
case 'K':
#ifdef AUTHENTICATION
autologin = 0;
#endif
break;
case 'L':
eight |= 2; /* binary output only */
break;
case 'N':
doaddrlookup = 0;
break;
case 'S':
#ifdef __BEOS__
fprintf(stderr, "-S option is not supported\n");
#else
# ifdef HAS_GETTOS
if ((tos = parsetos(optarg, "tcp")) < 0)
fprintf(stderr, "%s%s%s%s\n",
prompt, ": Bad TOS argument '",
optarg,
"; will try to use default TOS");
# else
# define MAXTOS 255
ultmp = strtoul(optarg, &ep, 0);
if (*ep || ep == optarg || ultmp > MAXTOS)
fprintf(stderr, "%s%s%s%s\n",
prompt, ": Bad TOS argument '",
optarg,
"; will try to use default TOS");
else
tos = ultmp;
# endif
#endif /* __BEOS__ */
break;
case 'X':
#ifdef AUTHENTICATION
auth_disable_name(optarg);
#endif
break;
case 'a':
#ifdef AUTHENTICATION
/* It's the default now, so ignore */
#else
autologin = 1;
#endif
break;
case 'c':
skiprc = 1;
break;
case 'd':
telnet_debug = 1;
break;
case 'e':
set_escape_char(optarg);
break;
case 'f':
#ifdef AUTHENTICATION
#if defined(KRB5) && defined(FORWARD)
if (forward_flags & OPTS_FORWARD_CREDS) {
fprintf(stderr,
"%s: Only one of -f and -F allowed.\n",
prompt);
usage();
}
forward_flags |= OPTS_FORWARD_CREDS;
#else
fprintf(stderr,
"%s: Warning: -f ignored, no Kerberos V5 support.\n",
prompt);
#endif
#else
fprintf(stderr,
"%s: Warning: -f ignored, no Kerberos V5 support.\n",
prompt);
#endif
break;
case 'F':
#ifdef AUTHENTICATION
#if defined(KRB5) && defined(FORWARD)
if (forward_flags & OPTS_FORWARD_CREDS) {
fprintf(stderr,
"%s: Only one of -f and -F allowed.\n",
prompt);
usage();
}
forward_flags |= OPTS_FORWARD_CREDS;
forward_flags |= OPTS_FORWARDABLE_CREDS;
#else
fprintf(stderr,
"%s: Warning: -F ignored, no Kerberos V5 support.\n",
prompt);
#endif
#else
fprintf(stderr,
"%s: Warning: -F ignored, no Kerberos V5 support.\n",
prompt);
#endif
break;
case 'k':
#ifdef AUTHENTICATION
#if defined(KRB4)
{
extern char *dest_realm, dst_realm_buf[], dst_realm_sz;
dest_realm = dst_realm_buf;
(void)strncpy(dest_realm, optarg, dst_realm_sz);
}
#else
fprintf(stderr,
"%s: Warning: -k ignored, no Kerberos V4 support.\n",
prompt);
#endif
#else
fprintf(stderr,
"%s: Warning: -k ignored, no Kerberos V4 support.\n",
prompt);
#endif
break;
case 'l':
#ifdef AUTHENTICATION
/* This is the default now, so ignore it */
#else
autologin = 1;
#endif
user = optarg;
break;
case 'n':
SetNetTrace(optarg);
break;
case 'r':
rlogin = '~';
break;
case 's':
src_addr = optarg;
break;
case 'u':
family = AF_UNIX;
break;
case 'x':
#ifndef ENCRYPTION
fprintf(stderr,
"%s: Warning: -x ignored, no ENCRYPT support.\n",
prompt);
#endif /* ENCRYPTION */
break;
case 'y':
#ifdef ENCRYPTION
encrypt_auto(0);
decrypt_auto(0);
#else
fprintf(stderr,
"%s: Warning: -y ignored, no ENCRYPT support.\n",
prompt);
#endif /* ENCRYPTION */
break;
#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
case 'P':
if (!strncmp("in", optarg, 2))
ipsec_policy_in = strdup(optarg);
else if (!strncmp("out", optarg, 3))
ipsec_policy_out = strdup(optarg);
else
usage();
break;
#endif
case '?':
default:
usage();
/* NOTREACHED */
}
}
if (autologin == -1)
autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
argc -= optind;
argv += optind;
if (argc) {
char *args[9], **argp = args;
if (argc > 2)
usage();
*argp++ = prompt;
if (user) {
*argp++ = strdup("-l");
*argp++ = user;
}
if (src_addr) {
*argp++ = strdup("-s");
*argp++ = src_addr;
}
*argp++ = argv[0]; /* host */
if (argc > 1)
*argp++ = argv[1]; /* port */
*argp = 0;
if (setjmp(toplevel) != 0)
Exit(0);
if (tn(argp - args, args) == 1)
return (0);
else
return (1);
}
(void)setjmp(toplevel);
for (;;) {
command(1, 0, 0);
}
return 0;
}
+182
View File
@@ -0,0 +1,182 @@
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static const char sccsid[] = "@(#)network.c 8.2 (Berkeley) 12/15/93";
#endif
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/contrib/telnet/telnet/network.c,v 1.7 2003/05/04 02:54:48 obrien Exp $");
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <errno.h>
#include <stdlib.h>
#include <arpa/telnet.h>
#include <unistd.h>
#include "ring.h"
#include "defines.h"
#include "externs.h"
#include "fdset.h"
Ring netoring, netiring;
unsigned char netobuf[2*BUFSIZ], netibuf[BUFSIZ];
/*
* Initialize internal network data structures.
*/
void
init_network(void)
{
if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) {
exit(1);
}
if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) {
exit(1);
}
NetTrace = stdout;
}
/*
* Check to see if any out-of-band data exists on a socket (for
* Telnet "synch" processing).
*/
int
stilloob(void)
{
static struct timeval timeout = { 0, 0 };
fd_set excepts;
int value;
do {
FD_ZERO(&excepts);
FD_SET(net, &excepts);
value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
} while ((value == -1) && (errno == EINTR));
if (value < 0) {
perror("select");
(void) quit();
/* NOTREACHED */
}
if (FD_ISSET(net, &excepts)) {
return 1;
} else {
return 0;
}
}
/*
* setneturg()
*
* Sets "neturg" to the current location.
*/
void
setneturg(void)
{
ring_mark(&netoring);
}
/*
* netflush
* Send as much data as possible to the network,
* handling requests for urgent data.
*
* The return value indicates whether we did any
* useful work.
*/
int
netflush(void)
{
int n, n1;
#ifdef ENCRYPTION
if (encrypt_output)
ring_encrypt(&netoring, encrypt_output);
#endif /* ENCRYPTION */
if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
if (!ring_at_mark(&netoring)) {
n = send(net, (char *)netoring.consume, n, 0); /* normal write */
} else {
/*
* In 4.2 (and 4.3) systems, there is some question about
* what byte in a sendOOB operation is the "OOB" data.
* To make ourselves compatible, we only send ONE byte
* out of band, the one WE THINK should be OOB (though
* we really have more the TCP philosophy of urgent data
* rather than the Unix philosophy of OOB data).
*/
n = send(net, (char *)netoring.consume, 1, MSG_OOB);/* URGENT data */
}
}
if (n < 0) {
if (errno != ENOBUFS && errno != EWOULDBLOCK) {
setcommandmode();
perror(hostname);
(void)NetClose(net);
ring_clear_mark(&netoring);
longjmp(peerdied, -1);
/*NOTREACHED*/
}
n = 0;
}
if (netdata && n) {
Dump('>', netoring.consume, n);
}
if (n) {
ring_consumed(&netoring, n);
/*
* If we sent all, and more to send, then recurse to pick
* up the other half.
*/
if ((n1 == n) && ring_full_consecutive(&netoring)) {
(void) netflush();
}
return 1;
} else {
return 0;
}
}
+322
View File
@@ -0,0 +1,322 @@
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static const char sccsid[] = "@(#)ring.c 8.2 (Berkeley) 5/30/95";
#endif
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/contrib/telnet/telnet/ring.c,v 1.7 2003/05/04 02:54:48 obrien Exp $");
/*
* This defines a structure for a ring buffer.
*
* The circular buffer has two parts:
*(((
* full: [consume, supply)
* empty: [supply, consume)
*]]]
*
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#ifdef size_t
#undef size_t
#endif
#include <sys/types.h>
#ifndef FILIO_H
#include <sys/ioctl.h>
#endif
#include <sys/socket.h>
#include "ring.h"
#include "general.h"
/* Internal macros */
#if !defined(MIN)
#define MIN(a,b) (((a)<(b))? (a):(b))
#endif /* !defined(MIN) */
#define ring_subtract(d,a,b) (((a)-(b) >= 0)? \
(a)-(b): (((a)-(b))+(d)->size))
#define ring_increment(d,a,c) (((a)+(c) < (d)->top)? \
(a)+(c) : (((a)+(c))-(d)->size))
#define ring_decrement(d,a,c) (((a)-(c) >= (d)->bottom)? \
(a)-(c) : (((a)-(c))-(d)->size))
/*
* The following is a clock, used to determine full, empty, etc.
*
* There is some trickiness here. Since the ring buffers are initialized
* to ZERO on allocation, we need to make sure, when interpreting the
* clock, that when the times are EQUAL, then the buffer is FULL.
*/
static u_long ring_clock = 0;
#define ring_empty(d) (((d)->consume == (d)->supply) && \
((d)->consumetime >= (d)->supplytime))
#define ring_full(d) (((d)->supply == (d)->consume) && \
((d)->supplytime > (d)->consumetime))
/* Buffer state transition routines */
int
ring_init(Ring *ring, unsigned char *buffer, int count)
{
memset((char *)ring, 0, sizeof *ring);
ring->size = count;
ring->supply = ring->consume = ring->bottom = buffer;
ring->top = ring->bottom+ring->size;
#ifdef ENCRYPTION
ring->clearto = 0;
#endif /* ENCRYPTION */
return 1;
}
/* Mark routines */
/*
* Mark the most recently supplied byte.
*/
void
ring_mark(Ring *ring)
{
ring->mark = ring_decrement(ring, ring->supply, 1);
}
/*
* Is the ring pointing to the mark?
*/
int
ring_at_mark(Ring *ring)
{
if (ring->mark == ring->consume) {
return 1;
} else {
return 0;
}
}
/*
* Clear any mark set on the ring.
*/
void
ring_clear_mark(Ring *ring)
{
ring->mark = 0;
}
/*
* Add characters from current segment to ring buffer.
*/
void
ring_supplied(Ring *ring, int count)
{
ring->supply = ring_increment(ring, ring->supply, count);
ring->supplytime = ++ring_clock;
}
/*
* We have just consumed "c" bytes.
*/
void
ring_consumed(Ring *ring, int count)
{
if (count == 0) /* don't update anything */
return;
if (ring->mark &&
(ring_subtract(ring, ring->mark, ring->consume) < count)) {
ring->mark = 0;
}
#ifdef ENCRYPTION
if (ring->consume < ring->clearto &&
ring->clearto <= ring->consume + count)
ring->clearto = 0;
else if (ring->consume + count > ring->top &&
ring->bottom <= ring->clearto &&
ring->bottom + ((ring->consume + count) - ring->top))
ring->clearto = 0;
#endif /* ENCRYPTION */
ring->consume = ring_increment(ring, ring->consume, count);
ring->consumetime = ++ring_clock;
/*
* Try to encourage "ring_empty_consecutive()" to be large.
*/
if (ring_empty(ring)) {
ring->consume = ring->supply = ring->bottom;
}
}
/* Buffer state query routines */
/* Number of bytes that may be supplied */
int
ring_empty_count(Ring *ring)
{
if (ring_empty(ring)) { /* if empty */
return ring->size;
} else {
return ring_subtract(ring, ring->consume, ring->supply);
}
}
/* number of CONSECUTIVE bytes that may be supplied */
int
ring_empty_consecutive(Ring *ring)
{
if ((ring->consume < ring->supply) || ring_empty(ring)) {
/*
* if consume is "below" supply, or empty, then
* return distance to the top
*/
return ring_subtract(ring, ring->top, ring->supply);
} else {
/*
* else, return what we may.
*/
return ring_subtract(ring, ring->consume, ring->supply);
}
}
/* Return the number of bytes that are available for consuming
* (but don't give more than enough to get to cross over set mark)
*/
int
ring_full_count(Ring *ring)
{
if ((ring->mark == 0) || (ring->mark == ring->consume)) {
if (ring_full(ring)) {
return ring->size; /* nothing consumed, but full */
} else {
return ring_subtract(ring, ring->supply, ring->consume);
}
} else {
return ring_subtract(ring, ring->mark, ring->consume);
}
}
/*
* Return the number of CONSECUTIVE bytes available for consuming.
* However, don't return more than enough to cross over set mark.
*/
int
ring_full_consecutive(Ring *ring)
{
if ((ring->mark == 0) || (ring->mark == ring->consume)) {
if ((ring->supply < ring->consume) || ring_full(ring)) {
return ring_subtract(ring, ring->top, ring->consume);
} else {
return ring_subtract(ring, ring->supply, ring->consume);
}
} else {
if (ring->mark < ring->consume) {
return ring_subtract(ring, ring->top, ring->consume);
} else { /* Else, distance to mark */
return ring_subtract(ring, ring->mark, ring->consume);
}
}
}
/*
* Move data into the "supply" portion of of the ring buffer.
*/
void
ring_supply_data(Ring *ring, unsigned char *buffer, int count)
{
int i;
while (count) {
i = MIN(count, ring_empty_consecutive(ring));
memcpy(ring->supply, buffer, i);
ring_supplied(ring, i);
count -= i;
buffer += i;
}
}
#ifdef ENCRYPTION
void
ring_encrypt(Ring *ring, void (*encryptor)(unsigned char *, int))
{
unsigned char *s, *c;
if (ring_empty(ring) || ring->clearto == ring->supply)
return;
if (!(c = ring->clearto))
c = ring->consume;
s = ring->supply;
if (s <= c) {
(*encryptor)(c, ring->top - c);
(*encryptor)(ring->bottom, s - ring->bottom);
} else
(*encryptor)(c, s - c);
ring->clearto = ring->supply;
}
void
ring_clearto(ring)
Ring *ring;
{
if (!ring_empty(ring))
ring->clearto = ring->supply;
else
ring->clearto = 0;
}
#endif /* ENCRYPTION */
+107
View File
@@ -0,0 +1,107 @@
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ring.h 8.1 (Berkeley) 6/6/93
* $FreeBSD: src/contrib/telnet/telnet/ring.h,v 1.4 2001/11/30 22:28:07 markm Exp $
*/
#if defined(P)
# undef P
#endif
#if defined(__STDC__) || defined(LINT_ARGS)
# define P(x) x
#else
# define P(x) ()
#endif
/*
* This defines a structure for a ring buffer.
*
* The circular buffer has two parts:
*(((
* full: [consume, supply)
* empty: [supply, consume)
*]]]
*
*/
typedef struct {
unsigned char *consume, /* where data comes out of */
*supply, /* where data comes in to */
*bottom, /* lowest address in buffer */
*top, /* highest address+1 in buffer */
*mark; /* marker (user defined) */
#ifdef ENCRYPTION
unsigned char *clearto; /* Data to this point is clear text */
unsigned char *encryyptedto; /* Data is encrypted to here */
#endif /* ENCRYPTION */
int size; /* size in bytes of buffer */
u_long consumetime, /* help us keep straight full, empty, etc. */
supplytime;
} Ring;
/* Here are some functions and macros to deal with the ring buffer */
/* Initialization routine */
extern int
ring_init(Ring *ring, unsigned char *buffer, int count);
/* Data movement routines */
extern void
ring_supply_data(Ring *ring, unsigned char *buffer, int count);
#ifdef notdef
extern void
ring_consume_data(Ring *ring, unsigned char *buffer, int count);
#endif
/* Buffer state transition routines */
extern void
ring_supplied(Ring *ring, int count),
ring_consumed(Ring *ring, int count);
/* Buffer state query routines */
extern int
ring_at_mark(Ring *),
ring_empty_count(Ring *ring),
ring_empty_consecutive(Ring *ring),
ring_full_count(Ring *ring),
ring_full_consecutive(Ring *ring);
#ifdef ENCRYPTION
extern void
ring_encrypt(Ring *ring, void (*func)(unsigned char *, int)),
ring_clearto(Ring *ring);
#endif /* ENCRYPTION */
extern void
ring_clear_mark(Ring *),
ring_mark(Ring *);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+242
View File
@@ -0,0 +1,242 @@
/*
* Copyright (c) 1988, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static const char sccsid[] = "@(#)terminal.c 8.2 (Berkeley) 2/16/95";
#endif
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/contrib/telnet/telnet/terminal.c,v 1.7 2003/05/04 02:54:48 obrien Exp $");
#include <arpa/telnet.h>
#include <sys/types.h>
#include <stdlib.h>
#include "ring.h"
#include "externs.h"
#include "types.h"
#ifdef ENCRYPTION
#include <libtelnet/encrypt.h>
#endif
Ring ttyoring, ttyiring;
unsigned char ttyobuf[2*BUFSIZ], ttyibuf[BUFSIZ];
int termdata; /* Debugging flag */
#ifdef USE_TERMIO
# ifndef VDISCARD
cc_t termFlushChar;
# endif
# ifndef VLNEXT
cc_t termLiteralNextChar;
# endif
# ifndef VSUSP
cc_t termSuspChar;
# endif
# ifndef VWERASE
cc_t termWerasChar;
# endif
# ifndef VREPRINT
cc_t termRprntChar;
# endif
# ifndef VSTART
cc_t termStartChar;
# endif
# ifndef VSTOP
cc_t termStopChar;
# endif
# ifndef VEOL
cc_t termForw1Char;
# endif
# ifndef VEOL2
cc_t termForw2Char;
# endif
# ifndef VSTATUS
cc_t termAytChar;
# endif
#else
cc_t termForw2Char;
cc_t termAytChar;
#endif
/*
* initialize the terminal data structures.
*/
void
init_terminal(void)
{
if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) {
exit(1);
}
if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) {
exit(1);
}
autoflush = TerminalAutoFlush();
}
/*
* Send as much data as possible to the terminal.
*
* Return value:
* -1: No useful work done, data waiting to go out.
* 0: No data was waiting, so nothing was done.
* 1: All waiting data was written out.
* n: All data - n was written out.
*/
int
ttyflush(int drop)
{
int n, n0, n1;
n0 = ring_full_count(&ttyoring);
if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) {
if (drop) {
TerminalFlushOutput();
/* we leave 'n' alone! */
} else {
n = TerminalWrite(ttyoring.consume, n);
}
}
if (n > 0) {
if (termdata && n) {
Dump('>', ttyoring.consume, n);
}
/*
* If we wrote everything, and the full count is
* larger than what we wrote, then write the
* rest of the buffer.
*/
if (n1 == n && n0 > n) {
n1 = n0 - n;
if (!drop)
n1 = TerminalWrite(ttyoring.bottom, n1);
if (n1 > 0)
n += n1;
}
ring_consumed(&ttyoring, n);
}
if (n < 0)
return -1;
if (n == n0) {
if (n0)
return -1;
return 0;
}
return n0 - n + 1;
}
/*
* These routines decides on what the mode should be (based on the values
* of various global variables).
*/
int
getconnmode(void)
{
extern int linemode;
int mode = 0;
#ifdef KLUDGELINEMODE
extern int kludgelinemode;
#endif
if (my_want_state_is_dont(TELOPT_ECHO))
mode |= MODE_ECHO;
if (localflow)
mode |= MODE_FLOW;
if (my_want_state_is_will(TELOPT_BINARY))
mode |= MODE_INBIN;
if (his_want_state_is_will(TELOPT_BINARY))
mode |= MODE_OUTBIN;
#ifdef KLUDGELINEMODE
if (kludgelinemode) {
if (my_want_state_is_dont(TELOPT_SGA)) {
mode |= (MODE_TRAPSIG|MODE_EDIT);
if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
mode &= ~MODE_ECHO;
}
}
return(mode);
}
#endif
if (my_want_state_is_will(TELOPT_LINEMODE))
mode |= linemode;
return(mode);
}
void
setconnmode(int force)
{
#ifdef ENCRYPTION
static int enc_passwd = 0;
#endif /* ENCRYPTION */
int newmode;
newmode = getconnmode()|(force?MODE_FORCE:0);
TerminalNewMode(newmode);
#ifdef ENCRYPTION
if ((newmode & (MODE_ECHO|MODE_EDIT)) == MODE_EDIT) {
if (my_want_state_is_will(TELOPT_ENCRYPT)
&& (enc_passwd == 0) && !encrypt_output) {
encrypt_request_start(0, 0);
enc_passwd = 1;
}
} else {
if (enc_passwd) {
encrypt_request_end();
enc_passwd = 0;
}
}
#endif /* ENCRYPTION */
}
void
setcommandmode(void)
{
TerminalNewMode(-1);
}
+52
View File
@@ -0,0 +1,52 @@
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)types.h 8.1 (Berkeley) 6/6/93
*/
typedef struct {
char *modedescriptions;
char modetype;
} Modelist;
extern Modelist modelist[];
typedef struct {
int
system, /* what the current time is */
echotoggle, /* last time user entered echo character */
modenegotiated, /* last time operating mode negotiated */
didnetreceive, /* last time we read data from network */
gotDM; /* when did we last see a data mark */
} Clocks;
extern Clocks clocks;
+912
View File
@@ -0,0 +1,912 @@
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static const char sccsid[] = "@(#)utilities.c 8.3 (Berkeley) 5/30/95";
#endif
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/contrib/telnet/telnet/utilities.c,v 1.8 2003/05/04 02:54:48 obrien Exp $");
#define TELOPTS
#define TELCMDS
#define SLC_NAMES
#include <arpa/telnet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include "general.h"
#include "fdset.h"
#include "ring.h"
#include "defines.h"
#include "externs.h"
#ifdef AUTHENTICATION
#include <libtelnet/auth.h>
#endif
#ifdef ENCRYPTION
#include <libtelnet/encrypt.h>
#endif
FILE *NetTrace = 0; /* Not in bss, since needs to stay */
int prettydump;
/*
* upcase()
*
* Upcase (in place) the argument.
*/
void
upcase(char *argument)
{
int c;
while ((c = *argument) != 0) {
if (islower(c)) {
*argument = toupper(c);
}
argument++;
}
}
/*
* SetSockOpt()
*
* Compensate for differences in 4.2 and 4.3 systems.
*/
int
SetSockOpt(int fd, int level, int option, int yesno)
{
return setsockopt(fd, level, option,
(char *)&yesno, sizeof yesno);
}
/*
* The following are routines used to print out debugging information.
*/
unsigned char NetTraceFile[256] = "(standard output)";
void
SetNetTrace(char *file)
{
if (NetTrace && NetTrace != stdout)
fclose(NetTrace);
if (file && (strcmp(file, "-") != 0)) {
NetTrace = fopen(file, "w");
if (NetTrace) {
strcpy((char *)NetTraceFile, file);
return;
}
fprintf(stderr, "Cannot open %s.\n", file);
}
NetTrace = stdout;
strcpy((char *)NetTraceFile, "(standard output)");
}
void
Dump(char direction, unsigned char *buffer, int length)
{
# define BYTES_PER_LINE 32
# define min(x,y) ((x<y)? x:y)
unsigned char *pThis;
int offset;
offset = 0;
while (length) {
/* print one line */
fprintf(NetTrace, "%c 0x%x\t", direction, offset);
pThis = buffer;
if (prettydump) {
buffer = buffer + min(length, BYTES_PER_LINE/2);
while (pThis < buffer) {
fprintf(NetTrace, "%c%.2x",
(((*pThis)&0xff) == 0xff) ? '*' : ' ',
(*pThis)&0xff);
pThis++;
}
length -= BYTES_PER_LINE/2;
offset += BYTES_PER_LINE/2;
} else {
buffer = buffer + min(length, BYTES_PER_LINE);
while (pThis < buffer) {
fprintf(NetTrace, "%.2x", (*pThis)&0xff);
pThis++;
}
length -= BYTES_PER_LINE;
offset += BYTES_PER_LINE;
}
if (NetTrace == stdout) {
fprintf(NetTrace, "\r\n");
} else {
fprintf(NetTrace, "\n");
}
if (length < 0) {
fflush(NetTrace);
return;
}
/* find next unique line */
}
fflush(NetTrace);
}
void
printoption(const char *direction, int cmd, int option)
{
if (!showoptions)
return;
if (cmd == IAC) {
if (TELCMD_OK(option))
fprintf(NetTrace, "%s IAC %s", direction, TELCMD(option));
else
fprintf(NetTrace, "%s IAC %d", direction, option);
} else {
const char *fmt;
fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" :
(cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0;
if (fmt) {
fprintf(NetTrace, "%s %s ", direction, fmt);
if (TELOPT_OK(option))
fprintf(NetTrace, "%s", TELOPT(option));
else if (option == TELOPT_EXOPL)
fprintf(NetTrace, "EXOPL");
else
fprintf(NetTrace, "%d", option);
} else
fprintf(NetTrace, "%s %d %d", direction, cmd, option);
}
if (NetTrace == stdout) {
fprintf(NetTrace, "\r\n");
fflush(NetTrace);
} else {
fprintf(NetTrace, "\n");
}
return;
}
void
optionstatus(void)
{
int i;
extern char will_wont_resp[], do_dont_resp[];
for (i = 0; i < 256; i++) {
if (do_dont_resp[i]) {
if (TELOPT_OK(i))
printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]);
else if (TELCMD_OK(i))
printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]);
else
printf("resp DO_DONT %d: %d\n", i,
do_dont_resp[i]);
if (my_want_state_is_do(i)) {
if (TELOPT_OK(i))
printf("want DO %s\n", TELOPT(i));
else if (TELCMD_OK(i))
printf("want DO %s\n", TELCMD(i));
else
printf("want DO %d\n", i);
} else {
if (TELOPT_OK(i))
printf("want DONT %s\n", TELOPT(i));
else if (TELCMD_OK(i))
printf("want DONT %s\n", TELCMD(i));
else
printf("want DONT %d\n", i);
}
} else {
if (my_state_is_do(i)) {
if (TELOPT_OK(i))
printf(" DO %s\n", TELOPT(i));
else if (TELCMD_OK(i))
printf(" DO %s\n", TELCMD(i));
else
printf(" DO %d\n", i);
}
}
if (will_wont_resp[i]) {
if (TELOPT_OK(i))
printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]);
else if (TELCMD_OK(i))
printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]);
else
printf("resp WILL_WONT %d: %d\n",
i, will_wont_resp[i]);
if (my_want_state_is_will(i)) {
if (TELOPT_OK(i))
printf("want WILL %s\n", TELOPT(i));
else if (TELCMD_OK(i))
printf("want WILL %s\n", TELCMD(i));
else
printf("want WILL %d\n", i);
} else {
if (TELOPT_OK(i))
printf("want WONT %s\n", TELOPT(i));
else if (TELCMD_OK(i))
printf("want WONT %s\n", TELCMD(i));
else
printf("want WONT %d\n", i);
}
} else {
if (my_state_is_will(i)) {
if (TELOPT_OK(i))
printf(" WILL %s\n", TELOPT(i));
else if (TELCMD_OK(i))
printf(" WILL %s\n", TELCMD(i));
else
printf(" WILL %d\n", i);
}
}
}
}
void
printsub(char direction, unsigned char *pointer, int length)
{
int i;
#ifdef AUTHENTICATION
char buf[512];
#endif
extern int want_status_response;
if (showoptions || direction == 0 ||
(want_status_response && (pointer[0] == TELOPT_STATUS))) {
if (direction) {
fprintf(NetTrace, "%s IAC SB ",
(direction == '<')? "RCVD":"SENT");
if (length >= 3) {
int j;
i = pointer[length-2];
j = pointer[length-1];
if (i != IAC || j != SE) {
fprintf(NetTrace, "(terminated by ");
if (TELOPT_OK(i))
fprintf(NetTrace, "%s ", TELOPT(i));
else if (TELCMD_OK(i))
fprintf(NetTrace, "%s ", TELCMD(i));
else
fprintf(NetTrace, "%d ", i);
if (TELOPT_OK(j))
fprintf(NetTrace, "%s", TELOPT(j));
else if (TELCMD_OK(j))
fprintf(NetTrace, "%s", TELCMD(j));
else
fprintf(NetTrace, "%d", j);
fprintf(NetTrace, ", not IAC SE!) ");
}
}
length -= 2;
}
if (length < 1) {
fprintf(NetTrace, "(Empty suboption??\?)");
if (NetTrace == stdout)
fflush(NetTrace);
return;
}
switch (pointer[0]) {
case TELOPT_TTYPE:
fprintf(NetTrace, "TERMINAL-TYPE ");
switch (pointer[1]) {
case TELQUAL_IS:
fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
break;
case TELQUAL_SEND:
fprintf(NetTrace, "SEND");
break;
default:
fprintf(NetTrace,
"- unknown qualifier %d (0x%x).",
pointer[1], pointer[1]);
}
break;
case TELOPT_TSPEED:
fprintf(NetTrace, "TERMINAL-SPEED");
if (length < 2) {
fprintf(NetTrace, " (empty suboption??\?)");
break;
}
switch (pointer[1]) {
case TELQUAL_IS:
fprintf(NetTrace, " IS ");
fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2);
break;
default:
if (pointer[1] == 1)
fprintf(NetTrace, " SEND");
else
fprintf(NetTrace, " %d (unknown)", pointer[1]);
for (i = 2; i < length; i++)
fprintf(NetTrace, " ?%d?", pointer[i]);
break;
}
break;
case TELOPT_LFLOW:
fprintf(NetTrace, "TOGGLE-FLOW-CONTROL");
if (length < 2) {
fprintf(NetTrace, " (empty suboption??\?)");
break;
}
switch (pointer[1]) {
case LFLOW_OFF:
fprintf(NetTrace, " OFF"); break;
case LFLOW_ON:
fprintf(NetTrace, " ON"); break;
case LFLOW_RESTART_ANY:
fprintf(NetTrace, " RESTART-ANY"); break;
case LFLOW_RESTART_XON:
fprintf(NetTrace, " RESTART-XON"); break;
default:
fprintf(NetTrace, " %d (unknown)", pointer[1]);
}
for (i = 2; i < length; i++)
fprintf(NetTrace, " ?%d?", pointer[i]);
break;
case TELOPT_NAWS:
fprintf(NetTrace, "NAWS");
if (length < 2) {
fprintf(NetTrace, " (empty suboption??\?)");
break;
}
if (length == 2) {
fprintf(NetTrace, " ?%d?", pointer[1]);
break;
}
fprintf(NetTrace, " %d %d (%d)",
pointer[1], pointer[2],
(int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
if (length == 4) {
fprintf(NetTrace, " ?%d?", pointer[3]);
break;
}
fprintf(NetTrace, " %d %d (%d)",
pointer[3], pointer[4],
(int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
for (i = 5; i < length; i++)
fprintf(NetTrace, " ?%d?", pointer[i]);
break;
#ifdef AUTHENTICATION
case TELOPT_AUTHENTICATION:
fprintf(NetTrace, "AUTHENTICATION");
if (length < 2) {
fprintf(NetTrace, " (empty suboption??\?)");
break;
}
switch (pointer[1]) {
case TELQUAL_REPLY:
case TELQUAL_IS:
fprintf(NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ?
"IS" : "REPLY");
if (AUTHTYPE_NAME_OK(pointer[2]))
fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[2]));
else
fprintf(NetTrace, "%d ", pointer[2]);
if (length < 3) {
fprintf(NetTrace, "(partial suboption??\?)");
break;
}
fprintf(NetTrace, "%s|%s",
((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
"CLIENT" : "SERVER",
((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
"MUTUAL" : "ONE-WAY");
auth_printsub(&pointer[1], length - 1, buf, sizeof(buf));
fprintf(NetTrace, "%s", buf);
break;
case TELQUAL_SEND:
i = 2;
fprintf(NetTrace, " SEND ");
while (i < length) {
if (AUTHTYPE_NAME_OK(pointer[i]))
fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[i]));
else
fprintf(NetTrace, "%d ", pointer[i]);
if (++i >= length) {
fprintf(NetTrace, "(partial suboption??\?)");
break;
}
fprintf(NetTrace, "%s|%s ",
((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
"CLIENT" : "SERVER",
((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
"MUTUAL" : "ONE-WAY");
++i;
}
break;
case TELQUAL_NAME:
i = 2;
fprintf(NetTrace, " NAME \"");
while (i < length)
putc(pointer[i++], NetTrace);
putc('"', NetTrace);
break;
default:
for (i = 2; i < length; i++)
fprintf(NetTrace, " ?%d?", pointer[i]);
break;
}
break;
#endif
#ifdef ENCRYPTION
case TELOPT_ENCRYPT:
fprintf(NetTrace, "ENCRYPT");
if (length < 2) {
fprintf(NetTrace, " (empty suboption??\?)");
break;
}
switch (pointer[1]) {
case ENCRYPT_START:
fprintf(NetTrace, " START");
break;
case ENCRYPT_END:
fprintf(NetTrace, " END");
break;
case ENCRYPT_REQSTART:
fprintf(NetTrace, " REQUEST-START");
break;
case ENCRYPT_REQEND:
fprintf(NetTrace, " REQUEST-END");
break;
case ENCRYPT_IS:
case ENCRYPT_REPLY:
fprintf(NetTrace, " %s ", (pointer[1] == ENCRYPT_IS) ?
"IS" : "REPLY");
if (length < 3) {
fprintf(NetTrace, " (partial suboption??\?)");
break;
}
if (ENCTYPE_NAME_OK(pointer[2]))
fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[2]));
else
fprintf(NetTrace, " %d (unknown)", pointer[2]);
encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf));
fprintf(NetTrace, "%s", buf);
break;
case ENCRYPT_SUPPORT:
i = 2;
fprintf(NetTrace, " SUPPORT ");
while (i < length) {
if (ENCTYPE_NAME_OK(pointer[i]))
fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[i]));
else
fprintf(NetTrace, "%d ", pointer[i]);
i++;
}
break;
case ENCRYPT_ENC_KEYID:
fprintf(NetTrace, " ENC_KEYID ");
goto encommon;
case ENCRYPT_DEC_KEYID:
fprintf(NetTrace, " DEC_KEYID ");
goto encommon;
default:
fprintf(NetTrace, " %d (unknown)", pointer[1]);
encommon:
for (i = 2; i < length; i++)
fprintf(NetTrace, " %d", pointer[i]);
break;
}
break;
#endif /* ENCRYPTION */
case TELOPT_LINEMODE:
fprintf(NetTrace, "LINEMODE ");
if (length < 2) {
fprintf(NetTrace, " (empty suboption??\?)");
break;
}
switch (pointer[1]) {
case WILL:
fprintf(NetTrace, "WILL ");
goto common;
case WONT:
fprintf(NetTrace, "WONT ");
goto common;
case DO:
fprintf(NetTrace, "DO ");
goto common;
case DONT:
fprintf(NetTrace, "DONT ");
common:
if (length < 3) {
fprintf(NetTrace, "(no option??\?)");
break;
}
switch (pointer[2]) {
case LM_FORWARDMASK:
fprintf(NetTrace, "Forward Mask");
for (i = 3; i < length; i++)
fprintf(NetTrace, " %x", pointer[i]);
break;
default:
fprintf(NetTrace, "%d (unknown)", pointer[2]);
for (i = 3; i < length; i++)
fprintf(NetTrace, " %d", pointer[i]);
break;
}
break;
case LM_SLC:
fprintf(NetTrace, "SLC");
for (i = 2; i < length - 2; i += 3) {
if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC]));
else
fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]);
switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
case SLC_NOSUPPORT:
fprintf(NetTrace, " NOSUPPORT"); break;
case SLC_CANTCHANGE:
fprintf(NetTrace, " CANTCHANGE"); break;
case SLC_VARIABLE:
fprintf(NetTrace, " VARIABLE"); break;
case SLC_DEFAULT:
fprintf(NetTrace, " DEFAULT"); break;
}
fprintf(NetTrace, "%s%s%s",
pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
SLC_FLUSHOUT| SLC_LEVELBITS))
fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]);
fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]);
if ((pointer[i+SLC_VALUE] == IAC) &&
(pointer[i+SLC_VALUE+1] == IAC))
i++;
}
for (; i < length; i++)
fprintf(NetTrace, " ?%d?", pointer[i]);
break;
case LM_MODE:
fprintf(NetTrace, "MODE ");
if (length < 3) {
fprintf(NetTrace, "(no mode??\?)");
break;
}
{
char tbuf[64];
sprintf(tbuf, "%s%s%s%s%s",
pointer[2]&MODE_EDIT ? "|EDIT" : "",
pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
pointer[2]&MODE_ACK ? "|ACK" : "");
fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0");
}
if (pointer[2]&~(MODE_MASK))
fprintf(NetTrace, " (0x%x)", pointer[2]);
for (i = 3; i < length; i++)
fprintf(NetTrace, " ?0x%x?", pointer[i]);
break;
default:
fprintf(NetTrace, "%d (unknown)", pointer[1]);
for (i = 2; i < length; i++)
fprintf(NetTrace, " %d", pointer[i]);
}
break;
case TELOPT_STATUS: {
const char *cp;
int j, k;
fprintf(NetTrace, "STATUS");
switch (pointer[1]) {
default:
if (pointer[1] == TELQUAL_SEND)
fprintf(NetTrace, " SEND");
else
fprintf(NetTrace, " %d (unknown)", pointer[1]);
for (i = 2; i < length; i++)
fprintf(NetTrace, " ?%d?", pointer[i]);
break;
case TELQUAL_IS:
if (--want_status_response < 0)
want_status_response = 0;
if (NetTrace == stdout)
fprintf(NetTrace, " IS\r\n");
else
fprintf(NetTrace, " IS\n");
for (i = 2; i < length; i++) {
switch(pointer[i]) {
case DO: cp = "DO"; goto common2;
case DONT: cp = "DONT"; goto common2;
case WILL: cp = "WILL"; goto common2;
case WONT: cp = "WONT"; goto common2;
common2:
i++;
if (TELOPT_OK((int)pointer[i]))
fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i]));
else
fprintf(NetTrace, " %s %d", cp, pointer[i]);
if (NetTrace == stdout)
fprintf(NetTrace, "\r\n");
else
fprintf(NetTrace, "\n");
break;
case SB:
fprintf(NetTrace, " SB ");
i++;
j = k = i;
while (j < length) {
if (pointer[j] == SE) {
if (j+1 == length)
break;
if (pointer[j+1] == SE)
j++;
else
break;
}
pointer[k++] = pointer[j++];
}
printsub(0, &pointer[i], k - i);
if (i < length) {
fprintf(NetTrace, " SE");
i = j;
} else
i = j - 1;
if (NetTrace == stdout)
fprintf(NetTrace, "\r\n");
else
fprintf(NetTrace, "\n");
break;
default:
fprintf(NetTrace, " %d", pointer[i]);
break;
}
}
break;
}
break;
}
case TELOPT_XDISPLOC:
fprintf(NetTrace, "X-DISPLAY-LOCATION ");
switch (pointer[1]) {
case TELQUAL_IS:
fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
break;
case TELQUAL_SEND:
fprintf(NetTrace, "SEND");
break;
default:
fprintf(NetTrace, "- unknown qualifier %d (0x%x).",
pointer[1], pointer[1]);
}
break;
case TELOPT_NEW_ENVIRON:
fprintf(NetTrace, "NEW-ENVIRON ");
#ifdef OLD_ENVIRON
goto env_common1;
case TELOPT_OLD_ENVIRON:
fprintf(NetTrace, "OLD-ENVIRON");
env_common1:
#endif
switch (pointer[1]) {
case TELQUAL_IS:
fprintf(NetTrace, "IS ");
goto env_common;
case TELQUAL_SEND:
fprintf(NetTrace, "SEND ");
goto env_common;
case TELQUAL_INFO:
fprintf(NetTrace, "INFO ");
env_common:
{
int noquote = 2;
#if defined(ENV_HACK) && defined(OLD_ENVIRON)
extern int old_env_var, old_env_value;
#endif
for (i = 2; i < length; i++ ) {
switch (pointer[i]) {
case NEW_ENV_VALUE:
#ifdef OLD_ENVIRON
/* case NEW_ENV_OVAR: */
if (pointer[0] == TELOPT_OLD_ENVIRON) {
# ifdef ENV_HACK
if (old_env_var == OLD_ENV_VALUE)
fprintf(NetTrace, "\" (VALUE) " + noquote);
else
# endif
fprintf(NetTrace, "\" VAR " + noquote);
} else
#endif /* OLD_ENVIRON */
fprintf(NetTrace, "\" VALUE " + noquote);
noquote = 2;
break;
case NEW_ENV_VAR:
#ifdef OLD_ENVIRON
/* case OLD_ENV_VALUE: */
if (pointer[0] == TELOPT_OLD_ENVIRON) {
# ifdef ENV_HACK
if (old_env_value == OLD_ENV_VAR)
fprintf(NetTrace, "\" (VAR) " + noquote);
else
# endif
fprintf(NetTrace, "\" VALUE " + noquote);
} else
#endif /* OLD_ENVIRON */
fprintf(NetTrace, "\" VAR " + noquote);
noquote = 2;
break;
case ENV_ESC:
fprintf(NetTrace, "\" ESC " + noquote);
noquote = 2;
break;
case ENV_USERVAR:
fprintf(NetTrace, "\" USERVAR " + noquote);
noquote = 2;
break;
default:
if (isprint(pointer[i]) && pointer[i] != '"') {
if (noquote) {
putc('"', NetTrace);
noquote = 0;
}
putc(pointer[i], NetTrace);
} else {
fprintf(NetTrace, "\" %03o " + noquote,
pointer[i]);
noquote = 2;
}
break;
}
}
if (!noquote)
putc('"', NetTrace);
break;
}
}
break;
default:
if (TELOPT_OK(pointer[0]))
fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0]));
else
fprintf(NetTrace, "%d (unknown)", pointer[0]);
for (i = 1; i < length; i++)
fprintf(NetTrace, " %d", pointer[i]);
break;
}
if (direction) {
if (NetTrace == stdout)
fprintf(NetTrace, "\r\n");
else
fprintf(NetTrace, "\n");
}
if (NetTrace == stdout)
fflush(NetTrace);
}
}
/* EmptyTerminal - called to make sure that the terminal buffer is empty.
* Note that we consider the buffer to run all the
* way to the kernel (thus the select).
*/
static void
EmptyTerminal(void)
{
fd_set o;
FD_ZERO(&o);
if (TTYBYTES() == 0) {
FD_SET(tout, &o);
(void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
(struct timeval *) 0); /* wait for TTLOWAT */
} else {
while (TTYBYTES()) {
(void) ttyflush(0);
FD_SET(tout, &o);
(void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
(struct timeval *) 0); /* wait for TTLOWAT */
}
}
}
static void
SetForExit(void)
{
setconnmode(0);
do {
(void)telrcv(); /* Process any incoming data */
EmptyTerminal();
} while (ring_full_count(&netiring)); /* While there is any */
setcommandmode();
fflush(stdout);
fflush(stderr);
setconnmode(0);
EmptyTerminal(); /* Flush the path to the tty */
setcommandmode();
}
void
Exit(int returnCode)
{
SetForExit();
exit(returnCode);
}
void
ExitString(const char *string, int returnCode)
{
SetForExit();
fwrite(string, 1, strlen(string), stderr);
exit(returnCode);
}