diff options
Diffstat (limited to 'secure/libexec')
| -rw-r--r-- | secure/libexec/telnetd/Makefile | 37 | ||||
| -rw-r--r-- | secure/libexec/telnetd/authenc.c | 91 | ||||
| -rw-r--r-- | secure/libexec/telnetd/defs.h | 296 | ||||
| -rw-r--r-- | secure/libexec/telnetd/ext.h | 240 | ||||
| -rw-r--r-- | secure/libexec/telnetd/global.c | 48 | ||||
| -rw-r--r-- | secure/libexec/telnetd/pathnames.h | 55 | ||||
| -rw-r--r-- | secure/libexec/telnetd/slc.c | 493 | ||||
| -rw-r--r-- | secure/libexec/telnetd/state.c | 1620 | ||||
| -rw-r--r-- | secure/libexec/telnetd/sys_term.c | 2135 | ||||
| -rw-r--r-- | secure/libexec/telnetd/telnetd.8 | 605 | ||||
| -rw-r--r-- | secure/libexec/telnetd/telnetd.c | 1582 | ||||
| -rw-r--r-- | secure/libexec/telnetd/telnetd.h | 49 | ||||
| -rw-r--r-- | secure/libexec/telnetd/termstat.c | 660 | ||||
| -rw-r--r-- | secure/libexec/telnetd/utility.c | 1192 | 
14 files changed, 0 insertions, 9103 deletions
| diff --git a/secure/libexec/telnetd/Makefile b/secure/libexec/telnetd/Makefile deleted file mode 100644 index 0bfa3c3f5109..000000000000 --- a/secure/libexec/telnetd/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -#	@(#)Makefile	8.2 (Berkeley) 12/15/93 - -PROG=	telnetd -CFLAGS+=-DLINEMODE -DKLUDGELINEMODE -DUSE_TERMIO -DDIAGNOSTICS -CFLAGS+=-DOLD_ENVIRON -DENV_HACK -CFLAGS+=-I${.CURDIR}/../../lib -#CFLAGS+=-DAUTHENTICATION -DENCRYPTION -SRCS=	authenc.c global.c slc.c state.c sys_term.c telnetd.c \ -	termstat.c utility.c -DPADD=	${LIBUTIL} ${LIBTERMCAP} -LDADD=	-lutil -ltermcap -ltelnet -#LDADD+=	-lkrb -ldes -MAN8=	telnetd.8 - -# These are the sources that have encryption stuff in them. -CRYPT_SRC= authenc.c ext.h state.c telnetd.c termstat.c -CRYPT_SRC+= utility.c Makefile -NOCRYPT_DIR=${.CURDIR}/Nocrypt - -.include <bsd.prog.mk> - -nocrypt: -#ifdef	ENCRYPTION -	@for i in ${CRYPT_SRC}; do \ -	    if [ ! -d ${NOCRYPT_DIR} ]; then \ -		echo Creating subdirectory ${NOCRYPT_DIR}; \ -		mkdir ${NOCRYPT_DIR}; \ -	    fi; \ -	    echo ${NOCRYPT_DIR}/$$i; \ -	    unifdef -UENCRYPTION ${.CURDIR}/$$i | \ -		sed "s/ || defined(ENCRYPTION)//" > ${NOCRYPT_DIR}/$$i; \ -	done - -placeholder: -#else	/* ENCRYPTION */ -	@echo "Encryption code already removed." -#endif	/* ENCRYPTION */ diff --git a/secure/libexec/telnetd/authenc.c b/secure/libexec/telnetd/authenc.c deleted file mode 100644 index fcd17fcf73b6..000000000000 --- a/secure/libexec/telnetd/authenc.c +++ /dev/null @@ -1,91 +0,0 @@ -/*- - * 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. - */ - -#ifndef lint -static char sccsid[] = "@(#)authenc.c	8.1 (Berkeley) 6/4/93"; -#endif /* not lint */ - -#if	defined(AUTHENTICATION) || defined(ENCRYPTION) -#include "telnetd.h" -#include <libtelnet/misc.h> - -	int -net_write(str, len) -	unsigned char *str; -	int len; -{ -	if (nfrontp + len < netobuf + BUFSIZ) { -		bcopy((void *)str, (void *)nfrontp, len); -		nfrontp += len; -		return(len); -	} -	return(0); -} - -	void -net_encrypt() -{ -#ifdef	ENCRYPTION -	char *s = (nclearto > nbackp) ? nclearto : nbackp; -	if (s < nfrontp && encrypt_output) { -		(*encrypt_output)((unsigned char *)s, nfrontp - s); -	} -	nclearto = nfrontp; -#endif /* ENCRYPTION */ -} - -	int -telnet_spin() -{ -	ttloop(); -	return(0); -} - -	char * -telnet_getenv(val) -	char *val; -{ -	extern char *getenv(); -	return(getenv(val)); -} - -	char * -telnet_gets(prompt, result, length, echo) -	char *prompt; -	char *result; -	int length; -	int echo; -{ -	return((char *)0); -} -#endif	/* defined(AUTHENTICATION) || defined(ENCRYPTION) */ diff --git a/secure/libexec/telnetd/defs.h b/secure/libexec/telnetd/defs.h deleted file mode 100644 index a73d4a619978..000000000000 --- a/secure/libexec/telnetd/defs.h +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (c) 1989, 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. - * - *	@(#)defs.h	8.1 (Berkeley) 6/4/93 - */ - -/* - * Telnet server defines - */ -#include <sys/types.h> -#include <sys/param.h> - -#ifndef	BSD -# define	BSD 43 -#endif - -#if	defined(CRAY) && !defined(LINEMODE) -# define SYSV_TERMIO -# define LINEMODE -# define KLUDGELINEMODE -# define DIAGNOSTICS -# if defined(UNICOS50) && !defined(UNICOS5) -#  define UNICOS5 -# endif -# if !defined(UNICOS5) -#  define BFTPDAEMON -#  define HAS_IP_TOS -# endif -#endif /* CRAY */ -#if defined(UNICOS5) && !defined(NO_SETSID) -# define NO_SETSID -#endif - -#if defined(PRINTOPTIONS) && defined(DIAGNOSTICS) -#define TELOPTS -#define TELCMDS -#define	SLC_NAMES -#endif - -#if	defined(SYSV_TERMIO) && !defined(USE_TERMIO) -# define	USE_TERMIO -#endif - -#include <sys/socket.h> -#ifndef	CRAY -#include <sys/wait.h> -#endif	/* CRAY */ -#include <fcntl.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/time.h> -#ifndef	FILIO_H -#include <sys/ioctl.h> -#else -#include <sys/filio.h> -#endif - -#include <netinet/in.h> - -#include <arpa/telnet.h> - -#include <stdio.h> -#ifdef	__STDC__ -#include <stdlib.h> -#endif -#include <signal.h> -#include <errno.h> -#include <netdb.h> -#include <syslog.h> -#ifndef	LOG_DAEMON -#define	LOG_DAEMON	0 -#endif -#ifndef	LOG_ODELAY -#define	LOG_ODELAY	0 -#endif -#include <ctype.h> -#ifndef NO_STRING_H -#include <string.h> -#else -#include <strings.h> -#endif - -#ifndef	USE_TERMIO -#include <sgtty.h> -#else -# ifdef	SYSV_TERMIO -# include <termio.h> -# else -# include <termios.h> -# endif -#endif -#if !defined(USE_TERMIO) || defined(NO_CC_T) -typedef unsigned char cc_t; -#endif - -#ifdef	__STDC__ -#include <unistd.h> -#endif - -#ifndef _POSIX_VDISABLE -# ifdef VDISABLE -#  define _POSIX_VDISABLE VDISABLE -# else -#  define _POSIX_VDISABLE ((unsigned char)'\377') -# endif -#endif - - -#ifdef	CRAY -# ifdef	CRAY1 -# include <sys/pty.h> -#  ifndef FD_ZERO -# include <sys/select.h> -#  endif /* FD_ZERO */ -# endif	/* CRAY1 */ - -#include <memory.h> -#endif	/* CRAY */ - -#ifdef __hpux -#include <sys/ptyio.h> -#endif - -#if	!defined(TIOCSCTTY) && defined(TCSETCTTY) -# define	TIOCSCTTY TCSETCTTY -#endif - -#ifndef	FD_SET -#ifndef	HAVE_fd_set -typedef struct fd_set { int fds_bits[1]; } fd_set; -#endif - -#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	/* FD_SET */ - -/* - * I/O data buffers defines - */ -#define	NETSLOP	64 -#ifdef CRAY -#undef BUFSIZ -#define BUFSIZ  2048 -#endif - -#define	NIACCUM(c)	{   *netip++ = c; \ -			    ncc++; \ -			} - -/* clock manipulations */ -#define	settimer(x)	(clocks.x = ++clocks.system) -#define	sequenceIs(x,y)	(clocks.x < clocks.y) - -/* - * Linemode support states, in decreasing order of importance - */ -#define REAL_LINEMODE	0x04 -#define KLUDGE_OK	0x03 -#define	NO_AUTOKLUDGE	0x02 -#define KLUDGE_LINEMODE	0x01 -#define NO_LINEMODE	0x00 - -/* - * Structures of information for each special character function. - */ -typedef struct { -	unsigned char	flag;		/* the flags for this function */ -	cc_t		val;		/* the value of the special character */ -} slcent, *Slcent; - -typedef struct { -	slcent		defset;		/* the default settings */ -	slcent		current;	/* the current settings */ -	cc_t		*sptr;		/* a pointer to the char in */ -					/* system data structures */ -} slcfun, *Slcfun; - -#ifdef DIAGNOSTICS -/* - * Diagnostics capabilities - */ -#define	TD_REPORT	0x01	/* Report operations to client */ -#define TD_EXERCISE	0x02	/* Exercise client's implementation */ -#define TD_NETDATA	0x04	/* Display received data stream */ -#define TD_PTYDATA	0x08	/* Display data passed to pty */ -#define	TD_OPTIONS	0x10	/* Report just telnet options */ -#endif /* DIAGNOSTICS */ - -/* - * 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) - -/* - * Tricky code here.  What we want to know is if the MY_STATE_WILL - * and MY_WANT_STATE_WILL bits have the same value.  Since the two - * bits are adjacent, a little arithmatic will show that by adding - * in the lower bit, the upper bit will be set if the two bits were - * different, and clear if they were the same. - */ -#define my_will_wont_is_changing(opt) \ -			((options[opt]+MY_STATE_WILL) & MY_WANT_STATE_WILL) - -#define my_do_dont_is_changing(opt) \ -			((options[opt]+MY_STATE_DO) & MY_WANT_STATE_DO) - -/* - * 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 - -#define his_will_wont_is_changing	my_do_dont_is_changing -#define his_do_dont_is_changing		my_will_wont_is_changing diff --git a/secure/libexec/telnetd/ext.h b/secure/libexec/telnetd/ext.h deleted file mode 100644 index 19bc0d638296..000000000000 --- a/secure/libexec/telnetd/ext.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 1989, 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. - * - *	@(#)ext.h	8.2 (Berkeley) 12/15/93 - */ - -/* - * Telnet server variable declarations - */ -extern char	options[256]; -extern char	do_dont_resp[256]; -extern char	will_wont_resp[256]; -extern int	linemode;	/* linemode on/off */ -#ifdef	LINEMODE -extern int	uselinemode;	/* what linemode to use (on/off) */ -extern int	editmode;	/* edit modes in use */ -extern int	useeditmode;	/* edit modes to use */ -extern int	alwayslinemode;	/* command line option */ -# ifdef	KLUDGELINEMODE -extern int	lmodetype;	/* Client support for linemode */ -# endif	/* KLUDGELINEMODE */ -#endif	/* LINEMODE */ -extern int	flowmode;	/* current flow control state */ -extern int	restartany;	/* restart output on any character state */ -#ifdef DIAGNOSTICS -extern int	diagnostic;	/* telnet diagnostic capabilities */ -#endif /* DIAGNOSTICS */ -#ifdef BFTPDAEMON -extern int	bftpd;		/* behave as bftp daemon */ -#endif /* BFTPDAEMON */ -#if	defined(SecurID) -extern int	require_SecurID; -#endif -#if	defined(AUTHENTICATION) -extern int	auth_level; -#endif - -extern slcfun	slctab[NSLC + 1];	/* slc mapping table */ - -char	*terminaltype; - -/* - * I/O data buffers, pointers, and counters. - */ -extern char	ptyobuf[BUFSIZ+NETSLOP], *pfrontp, *pbackp; - -extern char	netibuf[BUFSIZ], *netip; - -extern char	netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp; -extern char	*neturg;		/* one past last bye of urgent data */ - -extern int	pcc, ncc; - -#if defined(CRAY2) && defined(UNICOS5) -extern int unpcc;  /* characters left unprocessed by CRAY-2 terminal routine */ -extern char *unptyip;  /* pointer to remaining characters in buffer */ -#endif - -extern int	pty, net; -extern char	*line; -extern int	SYNCHing;		/* we are in TELNET SYNCH mode */ - -#ifndef	P -# ifdef	__STDC__ -#  define P(x)	x -# else -#  define P(x)	() -# endif -#endif - -extern void -	_termstat P((void)), -	add_slc P((int, int, int)), -	check_slc P((void)), -	change_slc P((int, int, int)), -	cleanup P((int)), -	clientstat P((int, int, int)), -	copy_termbuf P((char *, int)), -	deferslc P((void)), -	defer_terminit P((void)), -	do_opt_slc P((unsigned char *, int)), -	doeof P((void)), -	dooption P((int)), -	dontoption P((int)), -	edithost P((char *, char *)), -	fatal P((int, char *)), -	fatalperror P((int, char *)), -	get_slc_defaults P((void)), -	init_env P((void)), -	init_termbuf P((void)), -	interrupt P((void)), -	localstat P((void)), -	flowstat P((void)), -	netclear P((void)), -	netflush P((void)), -#ifdef DIAGNOSTICS -	printoption P((char *, int)), -	printdata P((char *, char *, int)), -	printsub P((int, unsigned char *, int)), -#endif -	ptyflush P((void)), -	putchr P((int)), -	putf P((char *, char *)), -	recv_ayt P((void)), -	send_do P((int, int)), -	send_dont P((int, int)), -	send_slc P((void)), -	send_status P((void)), -	send_will P((int, int)), -	send_wont P((int, int)), -	sendbrk P((void)), -	sendsusp P((void)), -	set_termbuf P((void)), -	start_login P((char *, int, char *)), -	start_slc P((int)), -#if	defined(AUTHENTICATION) -	start_slave P((char *)), -#else -	start_slave P((char *, int, char *)), -#endif -	suboption P((void)), -	telrcv P((void)), -	ttloop P((void)), -	tty_binaryin P((int)), -	tty_binaryout P((int)); - -extern int -	end_slc P((unsigned char **)), -	getnpty P((void)), -#ifndef convex -	getpty P((int *)), -#endif -	login_tty P((int)), -	spcset P((int, cc_t *, cc_t **)), -	stilloob P((int)), -	terminit P((void)), -	termstat P((void)), -	tty_flowmode P((void)), -	tty_restartany P((void)), -	tty_isbinaryin P((void)), -	tty_isbinaryout P((void)), -	tty_iscrnl P((void)), -	tty_isecho P((void)), -	tty_isediting P((void)), -	tty_islitecho P((void)), -	tty_isnewmap P((void)), -	tty_israw P((void)), -	tty_issofttab P((void)), -	tty_istrapsig P((void)), -	tty_linemode P((void)); - -extern void -	tty_rspeed P((int)), -	tty_setecho P((int)), -	tty_setedit P((int)), -	tty_setlinemode P((int)), -	tty_setlitecho P((int)), -	tty_setsig P((int)), -	tty_setsofttab P((int)), -	tty_tspeed P((int)), -	willoption P((int)), -	wontoption P((int)), -	writenet P((unsigned char *, int)); - -#ifdef	ENCRYPTION -extern void	(*encrypt_output) P((unsigned char *, int)); -extern int	(*decrypt_input) P((int)); -extern char	*nclearto; -#endif	/* ENCRYPTION */ - - -/* - * The following are some clocks used to decide how to interpret - * the relationship between various variables. - */ - -extern 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 */ -	ttypesubopt,		/* ttype subopt is received */ -	tspeedsubopt,		/* tspeed subopt is received */ -	environsubopt,		/* environ subopt is received */ -	oenvironsubopt,		/* old environ subopt is received */ -	xdisplocsubopt,		/* xdisploc subopt is received */ -	baseline,		/* time started to do timed action */ -	gotDM;			/* when did we last see a data mark */ -} clocks; - - -#if	defined(CRAY2) && defined(UNICOS5) -extern int	needtermstat; -#endif - -#ifndef	DEFAULT_IM -# ifdef CRAY -#  define DEFAULT_IM	"\r\n\r\nCray UNICOS (%h) (%t)\r\n\r\r\n\r" -# else -#  ifdef sun -#   define DEFAULT_IM	"\r\n\r\nSunOS UNIX (%h) (%t)\r\n\r\r\n\r" -#  else -#   ifdef ultrix -#    define DEFAULT_IM	"\r\n\r\nULTRIX (%h) (%t)\r\n\r\r\n\r" -#   else -#    define DEFAULT_IM	"\r\n\r\n4.4 BSD UNIX (%h) (%t)\r\n\r\r\n\r" -#   endif -#  endif -# endif -#endif diff --git a/secure/libexec/telnetd/global.c b/secure/libexec/telnetd/global.c deleted file mode 100644 index af21acc69fb1..000000000000 --- a/secure/libexec/telnetd/global.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 1989, 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. - */ - -#ifndef lint -static char sccsid[] = "@(#)global.c	8.1 (Berkeley) 6/4/93"; -#endif /* not lint */ - -/* - * Allocate global variables.  We do this - * by including the header file that defines - * them all as externs, but first we define - * the keyword "extern" to be nothing, so that - * we will actually allocate the space. - */ - -#include "defs.h" -#define extern -#include "ext.h" diff --git a/secure/libexec/telnetd/pathnames.h b/secure/libexec/telnetd/pathnames.h deleted file mode 100644 index c8b0806e7814..000000000000 --- a/secure/libexec/telnetd/pathnames.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 1989, 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. - * - *	@(#)pathnames.h	8.1 (Berkeley) 6/4/93 - */ - -#if BSD > 43 - -# include <paths.h> - -# ifndef _PATH_LOGIN -#  define	_PATH_LOGIN	"/usr/bin/login" -# endif - -#else -  -# define	_PATH_TTY	"/dev/tty" -# ifndef _PATH_LOGIN -#  define	_PATH_LOGIN	"/bin/login" -# endif - -#endif - -#ifdef BFTPDAEMON -#define		BFTPPATH	"/usr/ucb/bftp" -#endif  /* BFTPDAEMON */ diff --git a/secure/libexec/telnetd/slc.c b/secure/libexec/telnetd/slc.c deleted file mode 100644 index 145746afeaf4..000000000000 --- a/secure/libexec/telnetd/slc.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright (c) 1989, 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. - */ - -#ifndef lint -static char sccsid[] = "@(#)slc.c	8.1 (Berkeley) 6/4/93"; -#endif /* not lint */ - -#include "telnetd.h" - -#ifdef	LINEMODE -/* - * local varibles - */ -static unsigned char	*def_slcbuf = (unsigned char *)0; -static int		def_slclen = 0; -static int		slcchange;	/* change to slc is requested */ -static unsigned char	*slcptr;	/* pointer into slc buffer */ -static unsigned char	slcbuf[NSLC*6];	/* buffer for slc negotiation */ - -/* - * send_slc - * - * Write out the current special characters to the client. - */ -	void -send_slc() -{ -	register int i; - -	/* -	 * Send out list of triplets of special characters -	 * to client.  We only send info on the characters -	 * that are currently supported. -	 */ -	for (i = 1; i <= NSLC; i++) { -		if ((slctab[i].defset.flag & SLC_LEVELBITS) == SLC_NOSUPPORT) -			continue; -		add_slc((unsigned char)i, slctab[i].current.flag, -							slctab[i].current.val); -	} - -}  /* end of send_slc */ - -/* - * default_slc - * - * Set pty special characters to all the defaults. - */ -	void -default_slc() -{ -	register int i; - -	for (i = 1; i <= NSLC; i++) { -		slctab[i].current.val = slctab[i].defset.val; -		if (slctab[i].current.val == (cc_t)(_POSIX_VDISABLE)) -			slctab[i].current.flag = SLC_NOSUPPORT; -		else -			slctab[i].current.flag = slctab[i].defset.flag; -		if (slctab[i].sptr) { -			*(slctab[i].sptr) = slctab[i].defset.val; -		} -	} -	slcchange = 1; - -}  /* end of default_slc */ -#endif	/* LINEMODE */ - -/* - * get_slc_defaults - * - * Initialize the slc mapping table. - */ -	void -get_slc_defaults() -{ -	register int i; - -	init_termbuf(); - -	for (i = 1; i <= NSLC; i++) { -		slctab[i].defset.flag =  -			spcset(i, &slctab[i].defset.val, &slctab[i].sptr); -		slctab[i].current.flag = SLC_NOSUPPORT;  -		slctab[i].current.val = 0;  -	} - -}  /* end of get_slc_defaults */ - -#ifdef	LINEMODE -/* - * add_slc - * - * Add an slc triplet to the slc buffer. - */ -	void -add_slc(func, flag, val) -	register char func, flag; -	register cc_t val; -{ - -	if ((*slcptr++ = (unsigned char)func) == 0xff) -		*slcptr++ = 0xff; - -	if ((*slcptr++ = (unsigned char)flag) == 0xff) -		*slcptr++ = 0xff; - -	if ((*slcptr++ = (unsigned char)val) == 0xff) -		*slcptr++ = 0xff; - -}  /* end of add_slc */ - -/* - * start_slc - * - * Get ready to process incoming slc's and respond to them. - * - * The parameter getit is non-zero if it is necessary to grab a copy - * of the terminal control structures. - */ -	void -start_slc(getit) -	register int getit; -{ - -	slcchange = 0; -	if (getit) -		init_termbuf(); -	(void) sprintf((char *)slcbuf, "%c%c%c%c", -					IAC, SB, TELOPT_LINEMODE, LM_SLC); -	slcptr = slcbuf + 4; - -}  /* end of start_slc */ - -/* - * end_slc - * - * Finish up the slc negotiation.  If something to send, then send it. - */ -	int -end_slc(bufp) -	register unsigned char **bufp; -{ -	register int len; -	void netflush(); - -	/* -	 * If a change has occured, store the new terminal control -	 * structures back to the terminal driver. -	 */ -	if (slcchange) { -		set_termbuf(); -	} - -	/* -	 * If the pty state has not yet been fully processed and there is a -	 * deferred slc request from the client, then do not send any -	 * sort of slc negotiation now.  We will respond to the client's -	 * request very soon. -	 */ -	if (def_slcbuf && (terminit() == 0)) { -		return(0); -	} - -	if (slcptr > (slcbuf + 4)) { -		if (bufp) { -			*bufp = &slcbuf[4]; -			return(slcptr - slcbuf - 4); -		} else { -			(void) sprintf((char *)slcptr, "%c%c", IAC, SE); -			slcptr += 2; -			len = slcptr - slcbuf; -			writenet(slcbuf, len); -			netflush();  /* force it out immediately */ -			DIAG(TD_OPTIONS, printsub('>', slcbuf+2, len-2);); -		} -	} -	return (0); - -}  /* end of end_slc */ - -/* - * process_slc - * - * Figure out what to do about the client's slc - */ -	void -process_slc(func, flag, val) -	register unsigned char func, flag; -	register cc_t val; -{ -	register int hislevel, mylevel, ack; - -	/* -	 * Ensure that we know something about this function -	 */ -	if (func > NSLC) { -		add_slc(func, SLC_NOSUPPORT, 0); -		return; -	} - -	/* -	 * Process the special case requests of 0 SLC_DEFAULT 0 -	 * and 0 SLC_VARIABLE 0.  Be a little forgiving here, don't -	 * worry about whether the value is actually 0 or not. -	 */ -	if (func == 0) { -		if ((flag = flag & SLC_LEVELBITS) == SLC_DEFAULT) { -			default_slc(); -			send_slc(); -		} else if (flag == SLC_VARIABLE) { -			send_slc(); -		} -		return; -	} - -	/* -	 * Appears to be a function that we know something about.  So -	 * get on with it and see what we know. -	 */ - -	hislevel = flag & SLC_LEVELBITS; -	mylevel = slctab[func].current.flag & SLC_LEVELBITS; -	ack = flag & SLC_ACK; -	/* -	 * ignore the command if: -	 * the function value and level are the same as what we already have; -	 * or the level is the same and the ack bit is set -	 */ -	if (hislevel == mylevel && (val == slctab[func].current.val || ack)) { -		return; -	} else if (ack) { -		/* -		 * If we get here, we got an ack, but the levels don't match. -		 * This shouldn't happen.  If it does, it is probably because -		 * we have sent two requests to set a variable without getting -		 * a response between them, and this is the first response. -		 * So, ignore it, and wait for the next response. -		 */ -		return; -	} else { -		change_slc(func, flag, val); -	} - -}  /* end of process_slc */ - -/* - * change_slc - * - * Process a request to change one of our special characters. - * Compare client's request with what we are capable of supporting. - */ -	void -change_slc(func, flag, val) -	register char func, flag; -	register cc_t val; -{ -	register int hislevel, mylevel; -	 -	hislevel = flag & SLC_LEVELBITS; -	mylevel = slctab[func].defset.flag & SLC_LEVELBITS; -	/* -	 * If client is setting a function to NOSUPPORT -	 * or DEFAULT, then we can easily and directly -	 * accomodate the request. -	 */ -	if (hislevel == SLC_NOSUPPORT) { -		slctab[func].current.flag = flag; -		slctab[func].current.val = (cc_t)_POSIX_VDISABLE; -		flag |= SLC_ACK; -		add_slc(func, flag, val); -		return; -	} -	if (hislevel == SLC_DEFAULT) { -		/* -		 * Special case here.  If client tells us to use -		 * the default on a function we don't support, then -		 * return NOSUPPORT instead of what we may have as a -		 * default level of DEFAULT. -		 */ -		if (mylevel == SLC_DEFAULT) { -			slctab[func].current.flag = SLC_NOSUPPORT; -		} else { -			slctab[func].current.flag = slctab[func].defset.flag; -		} -		slctab[func].current.val = slctab[func].defset.val; -		add_slc(func, slctab[func].current.flag, -						slctab[func].current.val); -		return; -	} - -	/* -	 * Client wants us to change to a new value or he -	 * is telling us that he can't change to our value. -	 * Some of the slc's we support and can change, -	 * some we do support but can't change, -	 * and others we don't support at all. -	 * If we can change it then we have a pointer to -	 * the place to put the new value, so change it, -	 * otherwise, continue the negotiation. -	 */ -	if (slctab[func].sptr) { -		/* -		 * We can change this one. -		 */ -		slctab[func].current.val = val; -		*(slctab[func].sptr) = val; -		slctab[func].current.flag = flag; -		flag |= SLC_ACK; -		slcchange = 1; -		add_slc(func, flag, val); -	} else { -		/* -		* It is not possible for us to support this -		* request as he asks. -		* -		* If our level is DEFAULT, then just ack whatever was -		* sent.  -		* -		* If he can't change and we can't change, -		* then degenerate to NOSUPPORT. -		* -		* Otherwise we send our level back to him, (CANTCHANGE -		* or NOSUPPORT) and if CANTCHANGE, send -		* our value as well. -		*/ -		if (mylevel == SLC_DEFAULT) { -			slctab[func].current.flag = flag; -			slctab[func].current.val = val; -			flag |= SLC_ACK; -		} else if (hislevel == SLC_CANTCHANGE && -				    mylevel == SLC_CANTCHANGE) { -			flag &= ~SLC_LEVELBITS; -			flag |= SLC_NOSUPPORT; -			slctab[func].current.flag = flag; -		} else { -			flag &= ~SLC_LEVELBITS; -			flag |= mylevel; -			slctab[func].current.flag = flag; -			if (mylevel == SLC_CANTCHANGE) { -				slctab[func].current.val = -					slctab[func].defset.val; -				val = slctab[func].current.val; -			} -			 -		} -		add_slc(func, flag, val); -	} - -}  /* end of change_slc */ - -#if	defined(USE_TERMIO) && (VEOF == VMIN) -cc_t oldeofc = '\004'; -#endif - -/* - * check_slc - * - * Check the special characters in use and notify the client if any have - * changed.  Only those characters that are capable of being changed are - * likely to have changed.  If a local change occurs, kick the support level - * and flags up to the defaults. - */ -	void -check_slc() -{ -	register int i; - -	for (i = 1; i <= NSLC; i++) { -#if	defined(USE_TERMIO) && (VEOF == VMIN) -		/* -		 * In a perfect world this would be a neat little -		 * function.  But in this world, we should not notify -		 * client of changes to the VEOF char when -		 * ICANON is off, because it is not representing -		 * a special character. -		 */ -		if (i == SLC_EOF) { -			if (!tty_isediting()) -				continue; -			else if (slctab[i].sptr) -				oldeofc = *(slctab[i].sptr); -		} -#endif	/* defined(USE_TERMIO) && defined(SYSV_TERMIO) */ -		if (slctab[i].sptr && -				(*(slctab[i].sptr) != slctab[i].current.val)) { -			slctab[i].current.val = *(slctab[i].sptr); -			if (*(slctab[i].sptr) == (cc_t)_POSIX_VDISABLE) -				slctab[i].current.flag = SLC_NOSUPPORT; -			else -				slctab[i].current.flag = slctab[i].defset.flag; -			add_slc((unsigned char)i, slctab[i].current.flag, -						slctab[i].current.val); -		} -	} -			 -}  /* check_slc */ - -/* - * do_opt_slc - * - * Process an slc option buffer.  Defer processing of incoming slc's - * until after the terminal state has been processed.  Save the first slc - * request that comes along, but discard all others. - * - * ptr points to the beginning of the buffer, len is the length. - */ -	void -do_opt_slc(ptr, len) -	register unsigned char *ptr; -	register int len; -{ -	register unsigned char func, flag; -	cc_t val; -	register unsigned char *end = ptr + len; - -	if (terminit()) {  /* go ahead */ -		while (ptr < end) { -			func = *ptr++; -			if (ptr >= end) break; -			flag = *ptr++; -			if (ptr >= end) break; -			val = (cc_t)*ptr++; - -			process_slc(func, flag, val); - -		} -	} else { -		/* -		 * save this slc buffer if it is the first, otherwise dump -		 * it. -		 */ -		if (def_slcbuf == (unsigned char *)0) { -			def_slclen = len; -			def_slcbuf = (unsigned char *)malloc((unsigned)len); -			if (def_slcbuf == (unsigned char *)0) -				return;  /* too bad */ -			bcopy(ptr, def_slcbuf, len); -		} -	} - -}  /* end of do_opt_slc */ - -/* - * deferslc - * - * Do slc stuff that was deferred. - */ -	void -deferslc() -{ -	if (def_slcbuf) { -		start_slc(1); -		do_opt_slc(def_slcbuf, def_slclen); -		(void) end_slc(0); -		free(def_slcbuf); -		def_slcbuf = (unsigned char *)0; -		def_slclen = 0; -	} - -}  /* end of deferslc */ - -#endif	/* LINEMODE */ diff --git a/secure/libexec/telnetd/state.c b/secure/libexec/telnetd/state.c deleted file mode 100644 index 2d327a5b3f72..000000000000 --- a/secure/libexec/telnetd/state.c +++ /dev/null @@ -1,1620 +0,0 @@ -/* - * Copyright (c) 1989, 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. - */ - -#ifndef lint -static char sccsid[] = "@(#)state.c	8.2 (Berkeley) 12/15/93"; -#endif /* not lint */ - -#include "telnetd.h" -#if	defined(AUTHENTICATION) -#include <libtelnet/auth.h> -#endif - -unsigned char	doopt[] = { IAC, DO, '%', 'c', 0 }; -unsigned char	dont[] = { IAC, DONT, '%', 'c', 0 }; -unsigned char	will[] = { IAC, WILL, '%', 'c', 0 }; -unsigned char	wont[] = { IAC, WONT, '%', 'c', 0 }; -int	not42 = 1; - -/* - * Buffer for sub-options, and macros - * for suboptions buffer manipulations - */ -unsigned char subbuffer[512], *subpointer= subbuffer, *subend= subbuffer; - -#define	SB_CLEAR()	subpointer = subbuffer -#define	SB_TERM()	{ subend = subpointer; SB_CLEAR(); } -#define	SB_ACCUM(c)	if (subpointer < (subbuffer+sizeof subbuffer)) { \ -				*subpointer++ = (c); \ -			} -#define	SB_GET()	((*subpointer++)&0xff) -#define	SB_EOF()	(subpointer >= subend) -#define	SB_LEN()	(subend - subpointer) - -#ifdef	ENV_HACK -unsigned char *subsave; -#define SB_SAVE()	subsave = subpointer; -#define	SB_RESTORE()	subpointer = subsave; -#endif - - -/* - * State for recv fsm - */ -#define	TS_DATA		0	/* base state */ -#define	TS_IAC		1	/* look for double IAC's */ -#define	TS_CR		2	/* CR-LF ->'s CR */ -#define	TS_SB		3	/* throw away begin's... */ -#define	TS_SE		4	/* ...end's (suboption negotiation) */ -#define	TS_WILL		5	/* will option negotiation */ -#define	TS_WONT		6	/* wont " */ -#define	TS_DO		7	/* do " */ -#define	TS_DONT		8	/* dont " */ - -	void -telrcv() -{ -	register int c; -	static int state = TS_DATA; -#if	defined(CRAY2) && defined(UNICOS5) -	char *opfrontp = pfrontp; -#endif - -	while (ncc > 0) { -		if ((&ptyobuf[BUFSIZ] - pfrontp) < 2) -			break; -		c = *netip++ & 0377, ncc--; -#ifdef	ENCRYPTION -		if (decrypt_input) -			c = (*decrypt_input)(c); -#endif	/* ENCRYPTION */ -		switch (state) { - -		case TS_CR: -			state = TS_DATA; -			/* Strip off \n or \0 after a \r */ -			if ((c == 0) || (c == '\n')) { -				break; -			} -			/* FALL THROUGH */ - -		case TS_DATA: -			if (c == IAC) { -				state = TS_IAC; -				break; -			} -			/* -			 * We now map \r\n ==> \r for pragmatic reasons. -			 * Many client implementations send \r\n when -			 * the user hits the CarriageReturn key. -			 * -			 * We USED to map \r\n ==> \n, since \r\n says -			 * that we want to be in column 1 of the next -			 * printable line, and \n is the standard -			 * unix way of saying that (\r is only good -			 * if CRMOD is set, which it normally is). -			 */ -			if ((c == '\r') && his_state_is_wont(TELOPT_BINARY)) { -				int nc = *netip; -#ifdef	ENCRYPTION -				if (decrypt_input) -					nc = (*decrypt_input)(nc & 0xff); -#endif	/* ENCRYPTION */ -#ifdef	LINEMODE -				/* -				 * If we are operating in linemode, -				 * convert to local end-of-line. -				 */ -				if (linemode && (ncc > 0) && (('\n' == nc) || -					 ((0 == nc) && tty_iscrnl())) ) { -					netip++; ncc--; -					c = '\n'; -				} else -#endif -				{ -#ifdef	ENCRYPTION -					if (decrypt_input) -						(void)(*decrypt_input)(-1); -#endif	/* ENCRYPTION */ -					state = TS_CR; -				} -			} -			*pfrontp++ = c; -			break; - -		case TS_IAC: -gotiac:			switch (c) { - -			/* -			 * Send the process on the pty side an -			 * interrupt.  Do this with a NULL or -			 * interrupt char; depending on the tty mode. -			 */ -			case IP: -				DIAG(TD_OPTIONS, -					printoption("td: recv IAC", c)); -				interrupt(); -				break; - -			case BREAK: -				DIAG(TD_OPTIONS, -					printoption("td: recv IAC", c)); -				sendbrk(); -				break; - -			/* -			 * Are You There? -			 */ -			case AYT: -				DIAG(TD_OPTIONS, -					printoption("td: recv IAC", c)); -				recv_ayt(); -				break; - -			/* -			 * Abort Output -			 */ -			case AO: -			    { -				DIAG(TD_OPTIONS, -					printoption("td: recv IAC", c)); -				ptyflush();	/* half-hearted */ -				init_termbuf(); - -				if (slctab[SLC_AO].sptr && -				    *slctab[SLC_AO].sptr != (cc_t)(_POSIX_VDISABLE)) { -				    *pfrontp++ = -					(unsigned char)*slctab[SLC_AO].sptr; -				} - -				netclear();	/* clear buffer back */ -				*nfrontp++ = IAC; -				*nfrontp++ = DM; -				neturg = nfrontp-1; /* off by one XXX */ -				DIAG(TD_OPTIONS, -					printoption("td: send IAC", DM)); -				break; -			    } - -			/* -			 * Erase Character and -			 * Erase Line -			 */ -			case EC: -			case EL: -			    { -				cc_t ch; - -				DIAG(TD_OPTIONS, -					printoption("td: recv IAC", c)); -				ptyflush();	/* half-hearted */ -				init_termbuf(); -				if (c == EC) -					ch = *slctab[SLC_EC].sptr; -				else -					ch = *slctab[SLC_EL].sptr; -				if (ch != (cc_t)(_POSIX_VDISABLE)) -					*pfrontp++ = (unsigned char)ch; -				break; -			    } - -			/* -			 * Check for urgent data... -			 */ -			case DM: -				DIAG(TD_OPTIONS, -					printoption("td: recv IAC", c)); -				SYNCHing = stilloob(net); -				settimer(gotDM); -				break; - - -			/* -			 * Begin option subnegotiation... -			 */ -			case SB: -				state = TS_SB; -				SB_CLEAR(); -				continue; - -			case WILL: -				state = TS_WILL; -				continue; - -			case WONT: -				state = TS_WONT; -				continue; - -			case DO: -				state = TS_DO; -				continue; - -			case DONT: -				state = TS_DONT; -				continue; -			case EOR: -				if (his_state_is_will(TELOPT_EOR)) -					doeof(); -				break; - -			/* -			 * Handle RFC 10xx Telnet linemode option additions -			 * to command stream (EOF, SUSP, ABORT). -			 */ -			case xEOF: -				doeof(); -				break; - -			case SUSP: -				sendsusp(); -				break; - -			case ABORT: -				sendbrk(); -				break; - -			case IAC: -				*pfrontp++ = c; -				break; -			} -			state = TS_DATA; -			break; - -		case TS_SB: -			if (c == IAC) { -				state = TS_SE; -			} else { -				SB_ACCUM(c); -			} -			break; - -		case TS_SE: -			if (c != SE) { -				if (c != IAC) { -					/* -					 * bad form of suboption negotiation. -					 * handle it in such a way as to avoid -					 * damage to local state.  Parse -					 * suboption buffer found so far, -					 * then treat remaining stream as -					 * another command sequence. -					 */ - -					/* for DIAGNOSTICS */ -					SB_ACCUM(IAC); -					SB_ACCUM(c); -					subpointer -= 2; - -					SB_TERM(); -					suboption(); -					state = TS_IAC; -					goto gotiac; -				} -				SB_ACCUM(c); -				state = TS_SB; -			} else { -				/* for DIAGNOSTICS */ -				SB_ACCUM(IAC); -				SB_ACCUM(SE); -				subpointer -= 2; - -				SB_TERM(); -				suboption();	/* handle sub-option */ -				state = TS_DATA; -			} -			break; - -		case TS_WILL: -			willoption(c); -			state = TS_DATA; -			continue; - -		case TS_WONT: -			wontoption(c); -			state = TS_DATA; -			continue; - -		case TS_DO: -			dooption(c); -			state = TS_DATA; -			continue; - -		case TS_DONT: -			dontoption(c); -			state = TS_DATA; -			continue; - -		default: -			syslog(LOG_ERR, "telnetd: panic state=%d\n", state); -			printf("telnetd: panic state=%d\n", state); -			exit(1); -		} -	} -#if	defined(CRAY2) && defined(UNICOS5) -	if (!linemode) { -		char	xptyobuf[BUFSIZ+NETSLOP]; -		char	xbuf2[BUFSIZ]; -		register char *cp; -		int n = pfrontp - opfrontp, oc; -		bcopy(opfrontp, xptyobuf, n); -		pfrontp = opfrontp; -		pfrontp += term_input(xptyobuf, pfrontp, n, BUFSIZ+NETSLOP, -					xbuf2, &oc, BUFSIZ); -		for (cp = xbuf2; oc > 0; --oc) -			if ((*nfrontp++ = *cp++) == IAC) -				*nfrontp++ = IAC; -	} -#endif	/* defined(CRAY2) && defined(UNICOS5) */ -}  /* end of telrcv */ - -/* - * The will/wont/do/dont state machines are based on Dave Borman's - * Telnet option processing state machine. - * - * These correspond to the following states: - *	my_state = the last negotiated state - *	want_state = what I want the state to go to - *	want_resp = how many requests I have sent - * All state defaults are negative, and resp defaults to 0. - * - * When initiating a request to change state to new_state: - *  - * if ((want_resp == 0 && new_state == my_state) || want_state == new_state) { - *	do nothing; - * } else { - *	want_state = new_state; - *	send new_state; - *	want_resp++; - * } - * - * When receiving new_state: - * - * if (want_resp) { - *	want_resp--; - *	if (want_resp && (new_state == my_state)) - *		want_resp--; - * } - * if ((want_resp == 0) && (new_state != want_state)) { - *	if (ok_to_switch_to new_state) - *		want_state = new_state; - *	else - *		want_resp++; - *	send want_state; - * } - * my_state = new_state; - * - * Note that new_state is implied in these functions by the function itself. - * will and do imply positive new_state, wont and dont imply negative. - * - * Finally, there is one catch.  If we send a negative response to a - * positive request, my_state will be the positive while want_state will - * remain negative.  my_state will revert to negative when the negative - * acknowlegment arrives from the peer.  Thus, my_state generally tells - * us not only the last negotiated state, but also tells us what the peer - * wants to be doing as well.  It is important to understand this difference - * as we may wish to be processing data streams based on our desired state - * (want_state) or based on what the peer thinks the state is (my_state). - * - * This all works fine because if the peer sends a positive request, the data - * that we receive prior to negative acknowlegment will probably be affected - * by the positive state, and we can process it as such (if we can; if we - * can't then it really doesn't matter).  If it is that important, then the - * peer probably should be buffering until this option state negotiation - * is complete. - * - */ -	void -send_do(option, init) -	int option, init; -{ -	if (init) { -		if ((do_dont_resp[option] == 0 && his_state_is_will(option)) || -		    his_want_state_is_will(option)) -			return; -		/* -		 * Special case for TELOPT_TM:  We send a DO, but pretend -		 * that we sent a DONT, so that we can send more DOs if -		 * we want to. -		 */ -		if (option == TELOPT_TM) -			set_his_want_state_wont(option); -		else -			set_his_want_state_will(option); -		do_dont_resp[option]++; -	} -	(void) sprintf(nfrontp, (char *)doopt, option); -	nfrontp += sizeof (dont) - 2; - -	DIAG(TD_OPTIONS, printoption("td: send do", option)); -} - -#ifdef	AUTHENTICATION -extern void auth_request(); -#endif -#ifdef	LINEMODE -extern void doclientstat(); -#endif -#ifdef	ENCRYPTION -extern void encrypt_send_support(); -#endif	/* ENCRYPTION */ - -	void -willoption(option) -	int option; -{ -	int changeok = 0; -	void (*func)() = 0; - -	/* -	 * process input from peer. -	 */ - -	DIAG(TD_OPTIONS, printoption("td: recv will", option)); - -	if (do_dont_resp[option]) { -		do_dont_resp[option]--; -		if (do_dont_resp[option] && his_state_is_will(option)) -			do_dont_resp[option]--; -	} -	if (do_dont_resp[option] == 0) { -	    if (his_want_state_is_wont(option)) { -		switch (option) { - -		case TELOPT_BINARY: -			init_termbuf(); -			tty_binaryin(1); -			set_termbuf(); -			changeok++; -			break; - -		case TELOPT_ECHO: -			/* -			 * See comments below for more info. -			 */ -			not42 = 0;	/* looks like a 4.2 system */ -			break; - -		case TELOPT_TM: -#if	defined(LINEMODE) && defined(KLUDGELINEMODE) -			/* -			 * This telnetd implementation does not really -			 * support timing marks, it just uses them to -			 * support the kludge linemode stuff.  If we -			 * receive a will or wont TM in response to our -			 * do TM request that may have been sent to -			 * determine kludge linemode support, process -			 * it, otherwise TM should get a negative -			 * response back. -			 */ -			/* -			 * Handle the linemode kludge stuff. -			 * If we are not currently supporting any -			 * linemode at all, then we assume that this -			 * is the client telling us to use kludge -			 * linemode in response to our query.  Set the -			 * linemode type that is to be supported, note -			 * that the client wishes to use linemode, and -			 * eat the will TM as though it never arrived. -			 */ -			if (lmodetype < KLUDGE_LINEMODE) { -				lmodetype = KLUDGE_LINEMODE; -				clientstat(TELOPT_LINEMODE, WILL, 0); -				send_wont(TELOPT_SGA, 1); -			} else if (lmodetype == NO_AUTOKLUDGE) { -				lmodetype = KLUDGE_OK; -			} -#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */ -			/* -			 * We never respond to a WILL TM, and -			 * we leave the state WONT. -			 */ -			return; - -		case TELOPT_LFLOW: -			/* -			 * If we are going to support flow control -			 * option, then don't worry peer that we can't -			 * change the flow control characters. -			 */ -			slctab[SLC_XON].defset.flag &= ~SLC_LEVELBITS; -			slctab[SLC_XON].defset.flag |= SLC_DEFAULT; -			slctab[SLC_XOFF].defset.flag &= ~SLC_LEVELBITS; -			slctab[SLC_XOFF].defset.flag |= SLC_DEFAULT; -		case TELOPT_TTYPE: -		case TELOPT_SGA: -		case TELOPT_NAWS: -		case TELOPT_TSPEED: -		case TELOPT_XDISPLOC: -		case TELOPT_NEW_ENVIRON: -		case TELOPT_OLD_ENVIRON: -			changeok++; -			break; - -#ifdef	LINEMODE -		case TELOPT_LINEMODE: -# ifdef	KLUDGELINEMODE -			/* -			 * Note client's desire to use linemode. -			 */ -			lmodetype = REAL_LINEMODE; -# endif	/* KLUDGELINEMODE */ -			func = doclientstat; -			changeok++; -			break; -#endif	/* LINEMODE */ - -#ifdef	AUTHENTICATION -		case TELOPT_AUTHENTICATION: -			func = auth_request; -			changeok++; -			break; -#endif - -#ifdef	ENCRYPTION -		case TELOPT_ENCRYPT: -			func = encrypt_send_support; -			changeok++; -			break; -#endif	/* ENCRYPTION */ - -		default: -			break; -		} -		if (changeok) { -			set_his_want_state_will(option); -			send_do(option, 0); -		} else { -			do_dont_resp[option]++; -			send_dont(option, 0); -		} -	    } else { -		/* -		 * Option processing that should happen when -		 * we receive conformation of a change in -		 * state that we had requested. -		 */ -		switch (option) { -		case TELOPT_ECHO: -			not42 = 0;	/* looks like a 4.2 system */ -			/* -			 * Egads, he responded "WILL ECHO".  Turn -			 * it off right now! -			 */ -			send_dont(option, 1); -			/* -			 * "WILL ECHO".  Kludge upon kludge! -			 * A 4.2 client is now echoing user input at -			 * the tty.  This is probably undesireable and -			 * it should be stopped.  The client will -			 * respond WONT TM to the DO TM that we send to -			 * check for kludge linemode.  When the WONT TM -			 * arrives, linemode will be turned off and a -			 * change propogated to the pty.  This change -			 * will cause us to process the new pty state -			 * in localstat(), which will notice that -			 * linemode is off and send a WILL ECHO -			 * so that we are properly in character mode and -			 * all is well. -			 */ -			break; -#ifdef	LINEMODE -		case TELOPT_LINEMODE: -# ifdef	KLUDGELINEMODE -			/* -			 * Note client's desire to use linemode. -			 */ -			lmodetype = REAL_LINEMODE; -# endif	/* KLUDGELINEMODE */ -			func = doclientstat; -			break; -#endif	/* LINEMODE */ - -#ifdef	AUTHENTICATION -		case TELOPT_AUTHENTICATION: -			func = auth_request; -			break; -#endif - -#ifdef	ENCRYPTION -		case TELOPT_ENCRYPT: -			func = encrypt_send_support; -			break; -#endif	/* ENCRYPTION */ -		case TELOPT_LFLOW: -			func = flowstat; -			break; -		} -	    } -	} -	set_his_state_will(option); -	if (func) -		(*func)(); -}  /* end of willoption */ - -	void -send_dont(option, init) -	int option, init; -{ -	if (init) { -		if ((do_dont_resp[option] == 0 && his_state_is_wont(option)) || -		    his_want_state_is_wont(option)) -			return; -		set_his_want_state_wont(option); -		do_dont_resp[option]++; -	} -	(void) sprintf(nfrontp, (char *)dont, option); -	nfrontp += sizeof (doopt) - 2; - -	DIAG(TD_OPTIONS, printoption("td: send dont", option)); -} - -	void -wontoption(option) -	int option; -{ -	/* -	 * Process client input. -	 */ - -	DIAG(TD_OPTIONS, printoption("td: recv wont", option)); - -	if (do_dont_resp[option]) { -		do_dont_resp[option]--; -		if (do_dont_resp[option] && his_state_is_wont(option)) -			do_dont_resp[option]--; -	} -	if (do_dont_resp[option] == 0) { -	    if (his_want_state_is_will(option)) { -		/* it is always ok to change to negative state */ -		switch (option) { -		case TELOPT_ECHO: -			not42 = 1; /* doesn't seem to be a 4.2 system */ -			break; - -		case TELOPT_BINARY: -			init_termbuf(); -			tty_binaryin(0); -			set_termbuf(); -			break; - -#ifdef	LINEMODE -		case TELOPT_LINEMODE: -# ifdef	KLUDGELINEMODE -			/* -			 * If real linemode is supported, then client is -			 * asking to turn linemode off. -			 */ -			if (lmodetype != REAL_LINEMODE) -				break; -			lmodetype = KLUDGE_LINEMODE; -# endif	/* KLUDGELINEMODE */ -			clientstat(TELOPT_LINEMODE, WONT, 0); -			break; -#endif	/* LINEMODE */ - -		case TELOPT_TM: -			/* -			 * If we get a WONT TM, and had sent a DO TM, -			 * don't respond with a DONT TM, just leave it -			 * as is.  Short circut the state machine to -			 * achive this. -			 */ -			set_his_want_state_wont(TELOPT_TM); -			return; - -		case TELOPT_LFLOW: -			/* -			 * If we are not going to support flow control -			 * option, then let peer know that we can't -			 * change the flow control characters. -			 */ -			slctab[SLC_XON].defset.flag &= ~SLC_LEVELBITS; -			slctab[SLC_XON].defset.flag |= SLC_CANTCHANGE; -			slctab[SLC_XOFF].defset.flag &= ~SLC_LEVELBITS; -			slctab[SLC_XOFF].defset.flag |= SLC_CANTCHANGE; -			break; - -#if	defined(AUTHENTICATION) -		case TELOPT_AUTHENTICATION: -			auth_finished(0, AUTH_REJECT); -			break; -#endif - -		/* -		 * For options that we might spin waiting for -		 * sub-negotiation, if the client turns off the -		 * option rather than responding to the request, -		 * we have to treat it here as if we got a response -		 * to the sub-negotiation, (by updating the timers) -		 * so that we'll break out of the loop. -		 */ -		case TELOPT_TTYPE: -			settimer(ttypesubopt); -			break; - -		case TELOPT_TSPEED: -			settimer(tspeedsubopt); -			break; - -		case TELOPT_XDISPLOC: -			settimer(xdisplocsubopt); -			break; - -		case TELOPT_OLD_ENVIRON: -			settimer(oenvironsubopt); -			break; - -		case TELOPT_NEW_ENVIRON: -			settimer(environsubopt); -			break; - -		default: -			break; -		} -		set_his_want_state_wont(option); -		if (his_state_is_will(option)) -			send_dont(option, 0); -	    } else { -		switch (option) { -		case TELOPT_TM: -#if	defined(LINEMODE) && defined(KLUDGELINEMODE) -			if (lmodetype < NO_AUTOKLUDGE) { -				lmodetype = NO_LINEMODE; -				clientstat(TELOPT_LINEMODE, WONT, 0); -				send_will(TELOPT_SGA, 1); -				send_will(TELOPT_ECHO, 1); -			} -#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */ -			break; - -#if	defined(AUTHENTICATION) -		case TELOPT_AUTHENTICATION: -			auth_finished(0, AUTH_REJECT); -			break; -#endif -		default: -			break; -		} -	    } -	} -	set_his_state_wont(option); - -}  /* end of wontoption */ - -	void -send_will(option, init) -	int option, init; -{ -	if (init) { -		if ((will_wont_resp[option] == 0 && my_state_is_will(option))|| -		    my_want_state_is_will(option)) -			return; -		set_my_want_state_will(option); -		will_wont_resp[option]++; -	} -	(void) sprintf(nfrontp, (char *)will, option); -	nfrontp += sizeof (doopt) - 2; - -	DIAG(TD_OPTIONS, printoption("td: send will", option)); -} - -#if	!defined(LINEMODE) || !defined(KLUDGELINEMODE) -/* - * When we get a DONT SGA, we will try once to turn it - * back on.  If the other side responds DONT SGA, we - * leave it at that.  This is so that when we talk to - * clients that understand KLUDGELINEMODE but not LINEMODE, - * we'll keep them in char-at-a-time mode. - */ -int turn_on_sga = 0; -#endif - -	void -dooption(option) -	int option; -{ -	int changeok = 0; - -	/* -	 * Process client input. -	 */ - -	DIAG(TD_OPTIONS, printoption("td: recv do", option)); - -	if (will_wont_resp[option]) { -		will_wont_resp[option]--; -		if (will_wont_resp[option] && my_state_is_will(option)) -			will_wont_resp[option]--; -	} -	if ((will_wont_resp[option] == 0) && (my_want_state_is_wont(option))) { -		switch (option) { -		case TELOPT_ECHO: -#ifdef	LINEMODE -# ifdef	KLUDGELINEMODE -			if (lmodetype == NO_LINEMODE) -# else -			if (his_state_is_wont(TELOPT_LINEMODE)) -# endif -#endif -			{ -				init_termbuf(); -				tty_setecho(1); -				set_termbuf(); -			} -			changeok++; -			break; - -		case TELOPT_BINARY: -			init_termbuf(); -			tty_binaryout(1); -			set_termbuf(); -			changeok++; -			break; - -		case TELOPT_SGA: -#if	defined(LINEMODE) && defined(KLUDGELINEMODE) -			/* -			 * If kludge linemode is in use, then we must -			 * process an incoming do SGA for linemode -			 * purposes. -			 */ -			if (lmodetype == KLUDGE_LINEMODE) { -				/* -				 * Receipt of "do SGA" in kludge -				 * linemode is the peer asking us to -				 * turn off linemode.  Make note of -				 * the request. -				 */ -				clientstat(TELOPT_LINEMODE, WONT, 0); -				/* -				 * If linemode did not get turned off -				 * then don't tell peer that we did. -				 * Breaking here forces a wont SGA to -				 * be returned. -				 */ -				if (linemode) -					break; -			} -#else -			turn_on_sga = 0; -#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */ -			changeok++; -			break; - -		case TELOPT_STATUS: -			changeok++; -			break; - -		case TELOPT_TM: -			/* -			 * Special case for TM.  We send a WILL, but -			 * pretend we sent a WONT. -			 */ -			send_will(option, 0); -			set_my_want_state_wont(option); -			set_my_state_wont(option); -			return; - -		case TELOPT_LOGOUT: -			/* -			 * When we get a LOGOUT option, respond -			 * with a WILL LOGOUT, make sure that -			 * it gets written out to the network, -			 * and then just go away... -			 */ -			set_my_want_state_will(TELOPT_LOGOUT); -			send_will(TELOPT_LOGOUT, 0); -			set_my_state_will(TELOPT_LOGOUT); -			(void)netflush(); -			cleanup(0); -			/* NOT REACHED */ -			break; - -#ifdef	ENCRYPTION -		case TELOPT_ENCRYPT: -			changeok++; -			break; -#endif	/* ENCRYPTION */ -		case TELOPT_LINEMODE: -		case TELOPT_TTYPE: -		case TELOPT_NAWS: -		case TELOPT_TSPEED: -		case TELOPT_LFLOW: -		case TELOPT_XDISPLOC: -#ifdef	TELOPT_ENVIRON -		case TELOPT_NEW_ENVIRON: -#endif -		case TELOPT_OLD_ENVIRON: -		default: -			break; -		} -		if (changeok) { -			set_my_want_state_will(option); -			send_will(option, 0); -		} else { -			will_wont_resp[option]++; -			send_wont(option, 0); -		} -	} -	set_my_state_will(option); - -}  /* end of dooption */ - -	void -send_wont(option, init) -	int option, init; -{ -	if (init) { -		if ((will_wont_resp[option] == 0 && my_state_is_wont(option)) || -		    my_want_state_is_wont(option)) -			return; -		set_my_want_state_wont(option); -		will_wont_resp[option]++; -	} -	(void) sprintf(nfrontp, (char *)wont, option); -	nfrontp += sizeof (wont) - 2; - -	DIAG(TD_OPTIONS, printoption("td: send wont", option)); -} - -	void -dontoption(option) -	int option; -{ -	/* -	 * Process client input. -	 */ - - -	DIAG(TD_OPTIONS, printoption("td: recv dont", option)); - -	if (will_wont_resp[option]) { -		will_wont_resp[option]--; -		if (will_wont_resp[option] && my_state_is_wont(option)) -			will_wont_resp[option]--; -	} -	if ((will_wont_resp[option] == 0) && (my_want_state_is_will(option))) { -		switch (option) { -		case TELOPT_BINARY: -			init_termbuf(); -			tty_binaryout(0); -			set_termbuf(); -			break; - -		case TELOPT_ECHO:	/* we should stop echoing */ -#ifdef	LINEMODE -# ifdef	KLUDGELINEMODE -			if ((lmodetype != REAL_LINEMODE) && -			    (lmodetype != KLUDGE_LINEMODE)) -# else -			if (his_state_is_wont(TELOPT_LINEMODE)) -# endif -#endif -			{ -				init_termbuf(); -				tty_setecho(0); -				set_termbuf(); -			} -			break; - -		case TELOPT_SGA: -#if	defined(LINEMODE) && defined(KLUDGELINEMODE) -			/* -			 * If kludge linemode is in use, then we -			 * must process an incoming do SGA for -			 * linemode purposes. -			 */ -			if ((lmodetype == KLUDGE_LINEMODE) || -			    (lmodetype == KLUDGE_OK)) { -				/* -				 * The client is asking us to turn -				 * linemode on. -				 */ -				lmodetype = KLUDGE_LINEMODE; -				clientstat(TELOPT_LINEMODE, WILL, 0); -				/* -				 * If we did not turn line mode on, -				 * then what do we say?  Will SGA? -				 * This violates design of telnet. -				 * Gross.  Very Gross. -				 */ -			} -			break; -#else -			set_my_want_state_wont(option); -			if (my_state_is_will(option)) -				send_wont(option, 0); -			set_my_state_wont(option); -			if (turn_on_sga ^= 1) -				send_will(option, 1); -			return; -#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */ - -		default: -			break; -		} - -		set_my_want_state_wont(option); -		if (my_state_is_will(option)) -			send_wont(option, 0); -	} -	set_my_state_wont(option); - -}  /* end of dontoption */ - -#ifdef	ENV_HACK -int env_ovar = -1; -int env_ovalue = -1; -#else	/* ENV_HACK */ -# define env_ovar OLD_ENV_VAR -# define env_ovalue OLD_ENV_VALUE -#endif	/* ENV_HACK */ - -/* - * suboption() - * - *	Look at the sub-option buffer, and try to be helpful to the other - * side. - * - *	Currently we recognize: - * - *	Terminal type is - *	Linemode - *	Window size - *	Terminal speed - */ -	void -suboption() -{ -    register int subchar; - -    DIAG(TD_OPTIONS, {netflush(); printsub('<', subpointer, SB_LEN()+2);}); - -    subchar = SB_GET(); -    switch (subchar) { -    case TELOPT_TSPEED: { -	register int xspeed, rspeed; - -	if (his_state_is_wont(TELOPT_TSPEED))	/* Ignore if option disabled */ -		break; - -	settimer(tspeedsubopt); - -	if (SB_EOF() || SB_GET() != TELQUAL_IS) -		return; - -	xspeed = atoi((char *)subpointer); - -	while (SB_GET() != ',' && !SB_EOF()); -	if (SB_EOF()) -		return; - -	rspeed = atoi((char *)subpointer); -	clientstat(TELOPT_TSPEED, xspeed, rspeed); - -	break; - -    }  /* end of case TELOPT_TSPEED */ - -    case TELOPT_TTYPE: {		/* Yaaaay! */ -	static char terminalname[41]; - -	if (his_state_is_wont(TELOPT_TTYPE))	/* Ignore if option disabled */ -		break; -	settimer(ttypesubopt); - -	if (SB_EOF() || SB_GET() != TELQUAL_IS) { -	    return;		/* ??? XXX but, this is the most robust */ -	} - -	terminaltype = terminalname; - -	while ((terminaltype < (terminalname + sizeof terminalname-1)) && -								    !SB_EOF()) { -	    register int c; - -	    c = SB_GET(); -	    if (isupper(c)) { -		c = tolower(c); -	    } -	    *terminaltype++ = c;    /* accumulate name */ -	} -	*terminaltype = 0; -	terminaltype = terminalname; -	break; -    }  /* end of case TELOPT_TTYPE */ - -    case TELOPT_NAWS: { -	register int xwinsize, ywinsize; - -	if (his_state_is_wont(TELOPT_NAWS))	/* Ignore if option disabled */ -		break; - -	if (SB_EOF()) -		return; -	xwinsize = SB_GET() << 8; -	if (SB_EOF()) -		return; -	xwinsize |= SB_GET(); -	if (SB_EOF()) -		return; -	ywinsize = SB_GET() << 8; -	if (SB_EOF()) -		return; -	ywinsize |= SB_GET(); -	clientstat(TELOPT_NAWS, xwinsize, ywinsize); - -	break; - -    }  /* end of case TELOPT_NAWS */ - -#ifdef	LINEMODE -    case TELOPT_LINEMODE: { -	register int request; - -	if (his_state_is_wont(TELOPT_LINEMODE))	/* Ignore if option disabled */ -		break; -	/* -	 * Process linemode suboptions. -	 */ -	if (SB_EOF()) -	    break;		/* garbage was sent */ -	request = SB_GET();	/* get will/wont */ - -	if (SB_EOF()) -	    break;		/* another garbage check */ - -	if (request == LM_SLC) {  /* SLC is not preceeded by WILL or WONT */ -		/* -		 * Process suboption buffer of slc's -		 */ -		start_slc(1); -		do_opt_slc(subpointer, subend - subpointer); -		(void) end_slc(0); -		break; -	} else if (request == LM_MODE) { -		if (SB_EOF()) -		    return; -		useeditmode = SB_GET();  /* get mode flag */ -		clientstat(LM_MODE, 0, 0); -		break; -	} - -	if (SB_EOF()) -	    break; -	switch (SB_GET()) {  /* what suboption? */ -	case LM_FORWARDMASK: -		/* -		 * According to spec, only server can send request for -		 * forwardmask, and client can only return a positive response. -		 * So don't worry about it. -		 */ - -	default: -		break; -	} -	break; -    }  /* end of case TELOPT_LINEMODE */ -#endif -    case TELOPT_STATUS: { -	int mode; - -	if (SB_EOF()) -	    break; -	mode = SB_GET(); -	switch (mode) { -	case TELQUAL_SEND: -	    if (my_state_is_will(TELOPT_STATUS)) -		send_status(); -	    break; - -	case TELQUAL_IS: -	    break; - -	default: -	    break; -	} -	break; -    }  /* end of case TELOPT_STATUS */ - -    case TELOPT_XDISPLOC: { -	if (SB_EOF() || SB_GET() != TELQUAL_IS) -		return; -	settimer(xdisplocsubopt); -	subpointer[SB_LEN()] = '\0'; -	(void)setenv("DISPLAY", (char *)subpointer, 1); -	break; -    }  /* end of case TELOPT_XDISPLOC */ - -#ifdef	TELOPT_NEW_ENVIRON -    case TELOPT_NEW_ENVIRON: -#endif -    case TELOPT_OLD_ENVIRON: { -	register int c; -	register char *cp, *varp, *valp; - -	if (SB_EOF()) -		return; -	c = SB_GET(); -	if (c == TELQUAL_IS) { -		if (subchar == TELOPT_OLD_ENVIRON) -			settimer(oenvironsubopt); -		else -			settimer(environsubopt); -	} else if (c != TELQUAL_INFO) { -		return; -	} - -#ifdef	TELOPT_NEW_ENVIRON -	if (subchar == TELOPT_NEW_ENVIRON) { -	    while (!SB_EOF()) { -		c = SB_GET(); -		if ((c == NEW_ENV_VAR) || (c == ENV_USERVAR)) -			break; -	    } -	} else -#endif -	{ -#ifdef	ENV_HACK -	    /* -	     * We only want to do this if we haven't already decided -	     * whether or not the other side has its VALUE and VAR -	     * reversed. -	     */ -	    if (env_ovar < 0) { -		register int last = -1;		/* invalid value */ -		int empty = 0; -		int got_var = 0, got_value = 0, got_uservar = 0; - -		/* -		 * The other side might have its VALUE and VAR values -		 * reversed.  To be interoperable, we need to determine -		 * which way it is.  If the first recognized character -		 * is a VAR or VALUE, then that will tell us what -		 * type of client it is.  If the fist recognized -		 * character is a USERVAR, then we continue scanning -		 * the suboption looking for two consecutive -		 * VAR or VALUE fields.  We should not get two -		 * consecutive VALUE fields, so finding two -		 * consecutive VALUE or VAR fields will tell us -		 * what the client is. -		 */ -		SB_SAVE(); -		while (!SB_EOF()) { -			c = SB_GET(); -			switch(c) { -			case OLD_ENV_VAR: -				if (last < 0 || last == OLD_ENV_VAR -				    || (empty && (last == OLD_ENV_VALUE))) -					goto env_ovar_ok; -				got_var++; -				last = OLD_ENV_VAR; -				break; -			case OLD_ENV_VALUE: -				if (last < 0 || last == OLD_ENV_VALUE -				    || (empty && (last == OLD_ENV_VAR))) -					goto env_ovar_wrong; -				got_value++; -				last = OLD_ENV_VALUE; -				break; -			case ENV_USERVAR: -				/* count strings of USERVAR as one */ -				if (last != ENV_USERVAR) -					got_uservar++; -				if (empty) { -					if (last == OLD_ENV_VALUE) -						goto env_ovar_ok; -					if (last == OLD_ENV_VAR) -						goto env_ovar_wrong; -				} -				last = ENV_USERVAR; -				break; -			case ENV_ESC: -				if (!SB_EOF()) -					c = SB_GET(); -				/* FALL THROUGH */ -			default: -				empty = 0; -				continue; -			} -			empty = 1; -		} -		if (empty) { -			if (last == OLD_ENV_VALUE) -				goto env_ovar_ok; -			if (last == OLD_ENV_VAR) -				goto env_ovar_wrong; -		} -		/* -		 * Ok, the first thing was a USERVAR, and there -		 * are not two consecutive VAR or VALUE commands, -		 * and none of the VAR or VALUE commands are empty. -		 * If the client has sent us a well-formed option, -		 * then the number of VALUEs received should always -		 * be less than or equal to the number of VARs and -		 * USERVARs received. -		 * -		 * If we got exactly as many VALUEs as VARs and -		 * USERVARs, the client has the same definitions. -		 * -		 * If we got exactly as many VARs as VALUEs and -		 * USERVARS, the client has reversed definitions. -		 */ -		if (got_uservar + got_var == got_value) { -	    env_ovar_ok: -			env_ovar = OLD_ENV_VAR; -			env_ovalue = OLD_ENV_VALUE; -		} else if (got_uservar + got_value == got_var) { -	    env_ovar_wrong: -			env_ovar = OLD_ENV_VALUE; -			env_ovalue = OLD_ENV_VAR; -			DIAG(TD_OPTIONS, {sprintf(nfrontp, -				"ENVIRON VALUE and VAR are reversed!\r\n"); -				nfrontp += strlen(nfrontp);}); - -		} -	    } -	    SB_RESTORE(); -#endif - -	    while (!SB_EOF()) { -		c = SB_GET(); -		if ((c == env_ovar) || (c == ENV_USERVAR)) -			break; -	    } -	} - -	if (SB_EOF()) -		return; - -	cp = varp = (char *)subpointer; -	valp = 0; - -	while (!SB_EOF()) { -		c = SB_GET(); -		if (subchar == TELOPT_OLD_ENVIRON) { -			if (c == env_ovar) -				c = NEW_ENV_VAR; -			else if (c == env_ovalue) -				c = NEW_ENV_VALUE; -		} -		switch (c) { - -		case NEW_ENV_VALUE: -			*cp = '\0'; -			cp = valp = (char *)subpointer; -			break; - -		case NEW_ENV_VAR: -		case ENV_USERVAR: -			*cp = '\0'; -			if (valp) -				(void)setenv(varp, valp, 1); -			else -				unsetenv(varp); -			cp = varp = (char *)subpointer; -			valp = 0; -			break; - -		case ENV_ESC: -			if (SB_EOF()) -				break; -			c = SB_GET(); -			/* FALL THROUGH */ -		default: -			*cp++ = c; -			break; -		} -	} -	*cp = '\0'; -	if (valp) -		(void)setenv(varp, valp, 1); -	else -		unsetenv(varp); -	break; -    }  /* end of case TELOPT_NEW_ENVIRON */ -#if	defined(AUTHENTICATION) -    case TELOPT_AUTHENTICATION: -	if (SB_EOF()) -		break; -	switch(SB_GET()) { -	case TELQUAL_SEND: -	case TELQUAL_REPLY: -		/* -		 * These are sent by us and cannot be sent by -		 * the client. -		 */ -		break; -	case TELQUAL_IS: -		auth_is(subpointer, SB_LEN()); -		break; -	case TELQUAL_NAME: -		auth_name(subpointer, SB_LEN()); -		break; -	} -	break; -#endif -#ifdef	ENCRYPTION -    case TELOPT_ENCRYPT: -	if (SB_EOF()) -		break; -	switch(SB_GET()) { -	case ENCRYPT_SUPPORT: -		encrypt_support(subpointer, SB_LEN()); -		break; -	case ENCRYPT_IS: -		encrypt_is(subpointer, SB_LEN()); -		break; -	case ENCRYPT_REPLY: -		encrypt_reply(subpointer, SB_LEN()); -		break; -	case ENCRYPT_START: -		encrypt_start(subpointer, SB_LEN()); -		break; -	case ENCRYPT_END: -		encrypt_end(); -		break; -	case ENCRYPT_REQSTART: -		encrypt_request_start(subpointer, SB_LEN()); -		break; -	case ENCRYPT_REQEND: -		/* -		 * We can always send an REQEND so that we cannot -		 * get stuck encrypting.  We should only get this -		 * if we have been able to get in the correct mode -		 * anyhow. -		 */ -		encrypt_request_end(); -		break; -	case ENCRYPT_ENC_KEYID: -		encrypt_enc_keyid(subpointer, SB_LEN()); -		break; -	case ENCRYPT_DEC_KEYID: -		encrypt_dec_keyid(subpointer, SB_LEN()); -		break; -	default: -		break; -	} -	break; -#endif	/* ENCRYPTION */ - -    default: -	break; -    }  /* end of switch */ - -}  /* end of suboption */ - -	void -doclientstat() -{ -	clientstat(TELOPT_LINEMODE, WILL, 0); -} - -#define	ADD(c)	 *ncp++ = c; -#define	ADD_DATA(c) { *ncp++ = c; if (c == SE) *ncp++ = c; } -	void -send_status() -{ -	unsigned char statusbuf[256]; -	register unsigned char *ncp; -	register unsigned char i; - -	ncp = statusbuf; - -	netflush();	/* get rid of anything waiting to go out */ - -	ADD(IAC); -	ADD(SB); -	ADD(TELOPT_STATUS); -	ADD(TELQUAL_IS); - -	/* -	 * We check the want_state rather than the current state, -	 * because if we received a DO/WILL for an option that we -	 * don't support, and the other side didn't send a DONT/WONT -	 * in response to our WONT/DONT, then the "state" will be -	 * WILL/DO, and the "want_state" will be WONT/DONT.  We -	 * need to go by the latter. -	 */ -	for (i = 0; i < (unsigned char)NTELOPTS; i++) { -		if (my_want_state_is_will(i)) { -			ADD(WILL); -			ADD_DATA(i); -			if (i == IAC) -				ADD(IAC); -		} -		if (his_want_state_is_will(i)) { -			ADD(DO); -			ADD_DATA(i); -			if (i == IAC) -				ADD(IAC); -		} -	} - -	if (his_want_state_is_will(TELOPT_LFLOW)) { -		ADD(SB); -		ADD(TELOPT_LFLOW); -		if (flowmode) { -			ADD(LFLOW_ON); -		} else { -			ADD(LFLOW_OFF); -		} -		ADD(SE); - -		if (restartany >= 0) { -			ADD(SB) -			ADD(TELOPT_LFLOW); -			if (restartany) { -				ADD(LFLOW_RESTART_ANY); -			} else { -				ADD(LFLOW_RESTART_XON); -			} -			ADD(SE) -			ADD(SB); -		} -	} - -#ifdef	LINEMODE -	if (his_want_state_is_will(TELOPT_LINEMODE)) { -		unsigned char *cp, *cpe; -		int len; - -		ADD(SB); -		ADD(TELOPT_LINEMODE); -		ADD(LM_MODE); -		ADD_DATA(editmode); -		if (editmode == IAC) -			ADD(IAC); -		ADD(SE); - -		ADD(SB); -		ADD(TELOPT_LINEMODE); -		ADD(LM_SLC); -		start_slc(0); -		send_slc(); -		len = end_slc(&cp); -		for (cpe = cp + len; cp < cpe; cp++) -			ADD_DATA(*cp); -		ADD(SE); -	} -#endif	/* LINEMODE */ - -	ADD(IAC); -	ADD(SE); - -	writenet(statusbuf, ncp - statusbuf); -	netflush();	/* Send it on its way */ - -	DIAG(TD_OPTIONS, -		{printsub('>', statusbuf, ncp - statusbuf); netflush();}); -} diff --git a/secure/libexec/telnetd/sys_term.c b/secure/libexec/telnetd/sys_term.c deleted file mode 100644 index 1e5021672c64..000000000000 --- a/secure/libexec/telnetd/sys_term.c +++ /dev/null @@ -1,2135 +0,0 @@ -/* - * Copyright (c) 1989, 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. - */ - -#ifndef lint -static char sccsid[] = "@(#)sys_term.c	8.2 (Berkeley) 12/15/93"; -#endif /* not lint */ - -#include "telnetd.h" -#include "pathnames.h" - -#if	defined(AUTHENTICATION) -#include <libtelnet/auth.h> -#endif - -#if defined(CRAY) || defined(__hpux) -# define PARENT_DOES_UTMP -#endif - -#ifdef	NEWINIT -#include <initreq.h> -int	utmp_len = MAXHOSTNAMELEN;	/* sizeof(init_request.host) */ -#else	/* NEWINIT*/ -# ifdef	UTMPX -# include <utmpx.h> -struct	utmpx wtmp; -# else -# include <utmp.h> -struct	utmp wtmp; -# endif /* UTMPX */ - -int	utmp_len = sizeof(wtmp.ut_host); -# ifndef PARENT_DOES_UTMP -char	wtmpf[]	= "/usr/adm/wtmp"; -char	utmpf[] = "/etc/utmp"; -# else /* PARENT_DOES_UTMP */ -char	wtmpf[]	= "/etc/wtmp"; -# endif /* PARENT_DOES_UTMP */ - -# ifdef CRAY -#include <tmpdir.h> -#include <sys/wait.h> -#  if defined(_SC_CRAY_SECURE_SYS) && !defined(SCM_SECURITY) -   /* -    * UNICOS 6.0/6.1 do not have SCM_SECURITY defined, so we can -    * use it to tell us to turn off all the socket security code, -    * since that is only used in UNICOS 7.0 and later. -    */ -#   undef _SC_CRAY_SECURE_SYS -#  endif - -#  if defined(_SC_CRAY_SECURE_SYS) -#include <sys/sysv.h> -#include <sys/secstat.h> -extern int secflag; -extern struct sysv sysv; -#  endif /* _SC_CRAY_SECURE_SYS */ -# endif	/* CRAY */ -#endif	/* NEWINIT */ - -#ifdef	STREAMSPTY -#include <sac.h> -#include <sys/stropts.h> -#endif - -#define SCPYN(a, b)	(void) strncpy(a, b, sizeof(a)) -#define SCMPN(a, b)	strncmp(a, b, sizeof(a)) - -#ifdef	STREAMS -#include <sys/stream.h> -#endif -#ifdef __hpux -#include <sys/resource.h> -#include <sys/proc.h> -#endif -#include <sys/tty.h> -#ifdef	t_erase -#undef	t_erase -#undef	t_kill -#undef	t_intrc -#undef	t_quitc -#undef	t_startc -#undef	t_stopc -#undef	t_eofc -#undef	t_brkc -#undef	t_suspc -#undef	t_dsuspc -#undef	t_rprntc -#undef	t_flushc -#undef	t_werasc -#undef	t_lnextc -#endif - -#if defined(UNICOS5) && defined(CRAY2) && !defined(EXTPROC) -# define EXTPROC 0400 -#endif - -#ifndef	USE_TERMIO -struct termbuf { -	struct sgttyb sg; -	struct tchars tc; -	struct ltchars ltc; -	int state; -	int lflags; -} termbuf, termbuf2; -# define	cfsetospeed(tp, val)	(tp)->sg.sg_ospeed = (val) -# define	cfsetispeed(tp, val)	(tp)->sg.sg_ispeed = (val) -# define	cfgetospeed(tp)		(tp)->sg.sg_ospeed -# define	cfgetispeed(tp)		(tp)->sg.sg_ispeed -#else	/* USE_TERMIO */ -# ifdef	SYSV_TERMIO -#	define termios termio -# endif -# ifndef	TCSANOW -#  ifdef TCSETS -#   define	TCSANOW		TCSETS -#   define	TCSADRAIN	TCSETSW -#   define	tcgetattr(f, t)	ioctl(f, TCGETS, (char *)t) -#  else -#   ifdef TCSETA -#    define	TCSANOW		TCSETA -#    define	TCSADRAIN	TCSETAW -#    define	tcgetattr(f, t)	ioctl(f, TCGETA, (char *)t) -#   else -#    define	TCSANOW		TIOCSETA -#    define	TCSADRAIN	TIOCSETAW -#    define	tcgetattr(f, t)	ioctl(f, TIOCGETA, (char *)t) -#   endif -#  endif -#  define	tcsetattr(f, a, t)	ioctl(f, a, t) -#  define	cfsetospeed(tp, val)	(tp)->c_cflag &= ~CBAUD; \ -					(tp)->c_cflag |= (val) -#  define	cfgetospeed(tp)		((tp)->c_cflag & CBAUD) -#  ifdef CIBAUD -#   define	cfsetispeed(tp, val)	(tp)->c_cflag &= ~CIBAUD; \ -					(tp)->c_cflag |= ((val)<<IBSHIFT) -#   define	cfgetispeed(tp)		(((tp)->c_cflag & CIBAUD)>>IBSHIFT) -#  else -#   define	cfsetispeed(tp, val)	(tp)->c_cflag &= ~CBAUD; \ -					(tp)->c_cflag |= (val) -#   define	cfgetispeed(tp)		((tp)->c_cflag & CBAUD) -#  endif -# endif /* TCSANOW */ -struct termios termbuf, termbuf2;	/* pty control structure */ -# ifdef  STREAMSPTY -int ttyfd = -1; -# endif -#endif	/* USE_TERMIO */ - -/* - * init_termbuf() - * copy_termbuf(cp) - * set_termbuf() - * - * These three routines are used to get and set the "termbuf" structure - * to and from the kernel.  init_termbuf() gets the current settings. - * copy_termbuf() hands in a new "termbuf" to write to the kernel, and - * set_termbuf() writes the structure into the kernel. - */ - -	void -init_termbuf() -{ -#ifndef	USE_TERMIO -	(void) ioctl(pty, TIOCGETP, (char *)&termbuf.sg); -	(void) ioctl(pty, TIOCGETC, (char *)&termbuf.tc); -	(void) ioctl(pty, TIOCGLTC, (char *)&termbuf.ltc); -# ifdef	TIOCGSTATE -	(void) ioctl(pty, TIOCGSTATE, (char *)&termbuf.state); -# endif -#else -# ifdef  STREAMSPTY -	(void) tcgetattr(ttyfd, &termbuf); -# else -	(void) tcgetattr(pty, &termbuf); -# endif -#endif -	termbuf2 = termbuf; -} - -#if	defined(LINEMODE) && defined(TIOCPKT_IOCTL) -	void -copy_termbuf(cp, len) -	char *cp; -	int len; -{ -	if (len > sizeof(termbuf)) -		len = sizeof(termbuf); -	bcopy(cp, (char *)&termbuf, len); -	termbuf2 = termbuf; -} -#endif	/* defined(LINEMODE) && defined(TIOCPKT_IOCTL) */ - -	void -set_termbuf() -{ -	/* -	 * Only make the necessary changes. -	 */ -#ifndef	USE_TERMIO -	if (bcmp((char *)&termbuf.sg, (char *)&termbuf2.sg, sizeof(termbuf.sg))) -		(void) ioctl(pty, TIOCSETN, (char *)&termbuf.sg); -	if (bcmp((char *)&termbuf.tc, (char *)&termbuf2.tc, sizeof(termbuf.tc))) -		(void) ioctl(pty, TIOCSETC, (char *)&termbuf.tc); -	if (bcmp((char *)&termbuf.ltc, (char *)&termbuf2.ltc, -							sizeof(termbuf.ltc))) -		(void) ioctl(pty, TIOCSLTC, (char *)&termbuf.ltc); -	if (termbuf.lflags != termbuf2.lflags) -		(void) ioctl(pty, TIOCLSET, (char *)&termbuf.lflags); -#else	/* USE_TERMIO */ -	if (bcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf))) -# ifdef  STREAMSPTY -		(void) tcsetattr(ttyfd, TCSANOW, &termbuf); -# else -		(void) tcsetattr(pty, TCSANOW, &termbuf); -# endif -# if	defined(CRAY2) && defined(UNICOS5) -	needtermstat = 1; -# endif -#endif	/* USE_TERMIO */ -} - - -/* - * spcset(func, valp, valpp) - * - * This function takes various special characters (func), and - * sets *valp to the current value of that character, and - * *valpp to point to where in the "termbuf" structure that - * value is kept. - * - * It returns the SLC_ level of support for this function. - */ - -#ifndef	USE_TERMIO -	int -spcset(func, valp, valpp) -	int func; -	cc_t *valp; -	cc_t **valpp; -{ -	switch(func) { -	case SLC_EOF: -		*valp = termbuf.tc.t_eofc; -		*valpp = (cc_t *)&termbuf.tc.t_eofc; -		return(SLC_VARIABLE); -	case SLC_EC: -		*valp = termbuf.sg.sg_erase; -		*valpp = (cc_t *)&termbuf.sg.sg_erase; -		return(SLC_VARIABLE); -	case SLC_EL: -		*valp = termbuf.sg.sg_kill; -		*valpp = (cc_t *)&termbuf.sg.sg_kill; -		return(SLC_VARIABLE); -	case SLC_IP: -		*valp = termbuf.tc.t_intrc; -		*valpp = (cc_t *)&termbuf.tc.t_intrc; -		return(SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT); -	case SLC_ABORT: -		*valp = termbuf.tc.t_quitc; -		*valpp = (cc_t *)&termbuf.tc.t_quitc; -		return(SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT); -	case SLC_XON: -		*valp = termbuf.tc.t_startc; -		*valpp = (cc_t *)&termbuf.tc.t_startc; -		return(SLC_VARIABLE); -	case SLC_XOFF: -		*valp = termbuf.tc.t_stopc; -		*valpp = (cc_t *)&termbuf.tc.t_stopc; -		return(SLC_VARIABLE); -	case SLC_AO: -		*valp = termbuf.ltc.t_flushc; -		*valpp = (cc_t *)&termbuf.ltc.t_flushc; -		return(SLC_VARIABLE); -	case SLC_SUSP: -		*valp = termbuf.ltc.t_suspc; -		*valpp = (cc_t *)&termbuf.ltc.t_suspc; -		return(SLC_VARIABLE); -	case SLC_EW: -		*valp = termbuf.ltc.t_werasc; -		*valpp = (cc_t *)&termbuf.ltc.t_werasc; -		return(SLC_VARIABLE); -	case SLC_RP: -		*valp = termbuf.ltc.t_rprntc; -		*valpp = (cc_t *)&termbuf.ltc.t_rprntc; -		return(SLC_VARIABLE); -	case SLC_LNEXT: -		*valp = termbuf.ltc.t_lnextc; -		*valpp = (cc_t *)&termbuf.ltc.t_lnextc; -		return(SLC_VARIABLE); -	case SLC_FORW1: -		*valp = termbuf.tc.t_brkc; -		*valpp = (cc_t *)&termbuf.ltc.t_lnextc; -		return(SLC_VARIABLE); -	case SLC_BRK: -	case SLC_SYNCH: -	case SLC_AYT: -	case SLC_EOR: -		*valp = (cc_t)0; -		*valpp = (cc_t *)0; -		return(SLC_DEFAULT); -	default: -		*valp = (cc_t)0; -		*valpp = (cc_t *)0; -		return(SLC_NOSUPPORT); -	} -} - -#else	/* USE_TERMIO */ - -	int -spcset(func, valp, valpp) -	int func; -	cc_t *valp; -	cc_t **valpp; -{ - -#define	setval(a, b)	*valp = termbuf.c_cc[a]; \ -			*valpp = &termbuf.c_cc[a]; \ -			return(b); -#define	defval(a) *valp = ((cc_t)a); *valpp = (cc_t *)0; return(SLC_DEFAULT); - -	switch(func) { -	case SLC_EOF: -		setval(VEOF, SLC_VARIABLE); -	case SLC_EC: -		setval(VERASE, SLC_VARIABLE); -	case SLC_EL: -		setval(VKILL, SLC_VARIABLE); -	case SLC_IP: -		setval(VINTR, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT); -	case SLC_ABORT: -		setval(VQUIT, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT); -	case SLC_XON: -#ifdef	VSTART -		setval(VSTART, SLC_VARIABLE); -#else -		defval(0x13); -#endif -	case SLC_XOFF: -#ifdef	VSTOP -		setval(VSTOP, SLC_VARIABLE); -#else -		defval(0x11); -#endif -	case SLC_EW: -#ifdef	VWERASE -		setval(VWERASE, SLC_VARIABLE); -#else -		defval(0); -#endif -	case SLC_RP: -#ifdef	VREPRINT -		setval(VREPRINT, SLC_VARIABLE); -#else -		defval(0); -#endif -	case SLC_LNEXT: -#ifdef	VLNEXT -		setval(VLNEXT, SLC_VARIABLE); -#else -		defval(0); -#endif -	case SLC_AO: -#if	!defined(VDISCARD) && defined(VFLUSHO) -# define VDISCARD VFLUSHO -#endif -#ifdef	VDISCARD -		setval(VDISCARD, SLC_VARIABLE|SLC_FLUSHOUT); -#else -		defval(0); -#endif -	case SLC_SUSP: -#ifdef	VSUSP -		setval(VSUSP, SLC_VARIABLE|SLC_FLUSHIN); -#else -		defval(0); -#endif -#ifdef	VEOL -	case SLC_FORW1: -		setval(VEOL, SLC_VARIABLE); -#endif -#ifdef	VEOL2 -	case SLC_FORW2: -		setval(VEOL2, SLC_VARIABLE); -#endif -	case SLC_AYT: -#ifdef	VSTATUS -		setval(VSTATUS, SLC_VARIABLE); -#else -		defval(0); -#endif - -	case SLC_BRK: -	case SLC_SYNCH: -	case SLC_EOR: -		defval(0); - -	default: -		*valp = 0; -		*valpp = 0; -		return(SLC_NOSUPPORT); -	} -} -#endif	/* USE_TERMIO */ - -#ifdef CRAY -/* - * getnpty() - * - * Return the number of pty's configured into the system. - */ -	int -getnpty() -{ -#ifdef _SC_CRAY_NPTY -	int numptys; - -	if ((numptys = sysconf(_SC_CRAY_NPTY)) != -1) -		return numptys; -	else -#endif /* _SC_CRAY_NPTY */ -		return 128; -} -#endif /* CRAY */ - -#ifndef	convex -/* - * getpty() - * - * Allocate a pty.  As a side effect, the external character - * array "line" contains the name of the slave side. - * - * Returns the file descriptor of the opened pty. - */ -#ifndef	__GNUC__ -char *line = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; -#else -static char Xline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; -char *line = Xline; -#endif -#ifdef	CRAY -char *myline = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; -#endif	/* CRAY */ - -	int -getpty(ptynum) -int *ptynum; -{ -	register int p; -#ifdef	STREAMSPTY -	int t; -	char *ptsname(); - -	p = open("/dev/ptmx", 2); -	if (p > 0) { -		grantpt(p); -		unlockpt(p); -		strcpy(line, ptsname(p)); -		return(p); -	} - -#else	/* ! STREAMSPTY */ -#ifndef CRAY -	register char *cp, *p1, *p2; -	register int i; -#if defined(sun) && defined(TIOCGPGRP) && BSD < 199207 -	int dummy; -#endif - -#ifndef	__hpux -	(void) sprintf(line, "/dev/ptyXX"); -	p1 = &line[8]; -	p2 = &line[9]; -#else -	(void) sprintf(line, "/dev/ptym/ptyXX"); -	p1 = &line[13]; -	p2 = &line[14]; -#endif - -	for (cp = "pqrstuvwxyzPQRST"; *cp; cp++) { -		struct stat stb; - -		*p1 = *cp; -		*p2 = '0'; -		/* -		 * This stat() check is just to keep us from -		 * looping through all 256 combinations if there -		 * aren't that many ptys available. -		 */ -		if (stat(line, &stb) < 0) -			break; -		for (i = 0; i < 16; i++) { -			*p2 = "0123456789abcdef"[i]; -			p = open(line, 2); -			if (p > 0) { -#ifndef	__hpux -				line[5] = 't'; -#else -				for (p1 = &line[8]; *p1; p1++) -					*p1 = *(p1+1); -				line[9] = 't'; -#endif -				chown(line, 0, 0); -				chmod(line, 0600); -#if defined(sun) && defined(TIOCGPGRP) && BSD < 199207 -				if (ioctl(p, TIOCGPGRP, &dummy) == 0 -				    || errno != EIO) { -					chmod(line, 0666); -					close(p); -					line[5] = 'p'; -				} else -#endif /* defined(sun) && defined(TIOCGPGRP) && BSD < 199207 */ -					return(p); -			} -		} -	} -#else	/* CRAY */ -	extern lowpty, highpty; -	struct stat sb; - -	for (*ptynum = lowpty; *ptynum <= highpty; (*ptynum)++) { -		(void) sprintf(myline, "/dev/pty/%03d", *ptynum); -		p = open(myline, 2); -		if (p < 0) -			continue; -		(void) sprintf(line, "/dev/ttyp%03d", *ptynum); -		/* -		 * Here are some shenanigans to make sure that there -		 * are no listeners lurking on the line. -		 */ -		if(stat(line, &sb) < 0) { -			(void) close(p); -			continue; -		} -		if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) { -			chown(line, 0, 0); -			chmod(line, 0600); -			(void)close(p); -			p = open(myline, 2); -			if (p < 0) -				continue; -		} -		/* -		 * Now it should be safe...check for accessability. -		 */ -		if (access(line, 6) == 0) -			return(p); -		else { -			/* no tty side to pty so skip it */ -			(void) close(p); -		} -	} -#endif	/* CRAY */ -#endif	/* STREAMSPTY */ -	return(-1); -} -#endif	/* convex */ - -#ifdef	LINEMODE -/* - * tty_flowmode()	Find out if flow control is enabled or disabled. - * tty_linemode()	Find out if linemode (external processing) is enabled. - * tty_setlinemod(on)	Turn on/off linemode. - * tty_isecho()		Find out if echoing is turned on. - * tty_setecho(on)	Enable/disable character echoing. - * tty_israw()		Find out if terminal is in RAW mode. - * tty_binaryin(on)	Turn on/off BINARY on input. - * tty_binaryout(on)	Turn on/off BINARY on output. - * tty_isediting()	Find out if line editing is enabled. - * tty_istrapsig()	Find out if signal trapping is enabled. - * tty_setedit(on)	Turn on/off line editing. - * tty_setsig(on)	Turn on/off signal trapping. - * tty_issofttab()	Find out if tab expansion is enabled. - * tty_setsofttab(on)	Turn on/off soft tab expansion. - * tty_islitecho()	Find out if typed control chars are echoed literally - * tty_setlitecho()	Turn on/off literal echo of control chars - * tty_tspeed(val)	Set transmit speed to val. - * tty_rspeed(val)	Set receive speed to val. - */ - -#ifdef convex -static int linestate; -#endif - -	int -tty_linemode() -{ -#ifndef convex -#ifndef	USE_TERMIO -	return(termbuf.state & TS_EXTPROC); -#else -	return(termbuf.c_lflag & EXTPROC); -#endif -#else -	return(linestate); -#endif -} - -	void -tty_setlinemode(on) -	int on; -{ -#ifdef	TIOCEXT -# ifndef convex -	set_termbuf(); -# else -	linestate = on; -# endif -	(void) ioctl(pty, TIOCEXT, (char *)&on); -# ifndef convex -	init_termbuf(); -# endif -#else	/* !TIOCEXT */ -# ifdef	EXTPROC -	if (on) -		termbuf.c_lflag |= EXTPROC; -	else -		termbuf.c_lflag &= ~EXTPROC; -# endif -#endif	/* TIOCEXT */ -} -#endif	/* LINEMODE */ - -	int -tty_isecho() -{ -#ifndef USE_TERMIO -	return (termbuf.sg.sg_flags & ECHO); -#else -	return (termbuf.c_lflag & ECHO); -#endif -} - -	int -tty_flowmode() -{ -#ifndef USE_TERMIO -	return(((termbuf.tc.t_startc) > 0 && (termbuf.tc.t_stopc) > 0) ? 1 : 0); -#else -	return((termbuf.c_iflag & IXON) ? 1 : 0); -#endif -} - -	int -tty_restartany() -{ -#ifndef USE_TERMIO -# ifdef	DECCTQ -	return((termbuf.lflags & DECCTQ) ? 0 : 1); -# else -	return(-1); -# endif -#else -	return((termbuf.c_iflag & IXANY) ? 1 : 0); -#endif -} - -	void -tty_setecho(on) -	int on; -{ -#ifndef	USE_TERMIO -	if (on) -		termbuf.sg.sg_flags |= ECHO|CRMOD; -	else -		termbuf.sg.sg_flags &= ~(ECHO|CRMOD); -#else -	if (on) -		termbuf.c_lflag |= ECHO; -	else -		termbuf.c_lflag &= ~ECHO; -#endif -} - -	int -tty_israw() -{ -#ifndef USE_TERMIO -	return(termbuf.sg.sg_flags & RAW); -#else -	return(!(termbuf.c_lflag & ICANON)); -#endif -} - -#if	defined (AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R) -	int -tty_setraw(on) -{ -#  ifndef USE_TERMIO -	if (on) -		termbuf.sg.sg_flags |= RAW; -	else -		termbuf.sg.sg_flags &= ~RAW; -#  else -	if (on) -		termbuf.c_lflag &= ~ICANON; -	else -		termbuf.c_lflag |= ICANON; -#  endif -} -#endif - -	void -tty_binaryin(on) -	int on; -{ -#ifndef	USE_TERMIO -	if (on) -		termbuf.lflags |= LPASS8; -	else -		termbuf.lflags &= ~LPASS8; -#else -	if (on) { -		termbuf.c_iflag &= ~ISTRIP; -	} else { -		termbuf.c_iflag |= ISTRIP; -	} -#endif -} - -	void -tty_binaryout(on) -	int on; -{ -#ifndef	USE_TERMIO -	if (on) -		termbuf.lflags |= LLITOUT; -	else -		termbuf.lflags &= ~LLITOUT; -#else -	if (on) { -		termbuf.c_cflag &= ~(CSIZE|PARENB); -		termbuf.c_cflag |= CS8; -		termbuf.c_oflag &= ~OPOST; -	} else { -		termbuf.c_cflag &= ~CSIZE; -		termbuf.c_cflag |= CS7|PARENB; -		termbuf.c_oflag |= OPOST; -	} -#endif -} - -	int -tty_isbinaryin() -{ -#ifndef	USE_TERMIO -	return(termbuf.lflags & LPASS8); -#else -	return(!(termbuf.c_iflag & ISTRIP)); -#endif -} - -	int -tty_isbinaryout() -{ -#ifndef	USE_TERMIO -	return(termbuf.lflags & LLITOUT); -#else -	return(!(termbuf.c_oflag&OPOST)); -#endif -} - -#ifdef	LINEMODE -	int -tty_isediting() -{ -#ifndef USE_TERMIO -	return(!(termbuf.sg.sg_flags & (CBREAK|RAW))); -#else -	return(termbuf.c_lflag & ICANON); -#endif -} - -	int -tty_istrapsig() -{ -#ifndef USE_TERMIO -	return(!(termbuf.sg.sg_flags&RAW)); -#else -	return(termbuf.c_lflag & ISIG); -#endif -} - -	void -tty_setedit(on) -	int on; -{ -#ifndef USE_TERMIO -	if (on) -		termbuf.sg.sg_flags &= ~CBREAK; -	else -		termbuf.sg.sg_flags |= CBREAK; -#else -	if (on) -		termbuf.c_lflag |= ICANON; -	else -		termbuf.c_lflag &= ~ICANON; -#endif -} - -	void -tty_setsig(on) -	int on; -{ -#ifndef	USE_TERMIO -	if (on) -		; -#else -	if (on) -		termbuf.c_lflag |= ISIG; -	else -		termbuf.c_lflag &= ~ISIG; -#endif -} -#endif	/* LINEMODE */ - -	int -tty_issofttab() -{ -#ifndef	USE_TERMIO -	return (termbuf.sg.sg_flags & XTABS); -#else -# ifdef	OXTABS -	return (termbuf.c_oflag & OXTABS); -# endif -# ifdef	TABDLY -	return ((termbuf.c_oflag & TABDLY) == TAB3); -# endif -#endif -} - -	void -tty_setsofttab(on) -	int on; -{ -#ifndef	USE_TERMIO -	if (on) -		termbuf.sg.sg_flags |= XTABS; -	else -		termbuf.sg.sg_flags &= ~XTABS; -#else -	if (on) { -# ifdef	OXTABS -		termbuf.c_oflag |= OXTABS; -# endif -# ifdef	TABDLY -		termbuf.c_oflag &= ~TABDLY; -		termbuf.c_oflag |= TAB3; -# endif -	} else { -# ifdef	OXTABS -		termbuf.c_oflag &= ~OXTABS; -# endif -# ifdef	TABDLY -		termbuf.c_oflag &= ~TABDLY; -		termbuf.c_oflag |= TAB0; -# endif -	} -#endif -} - -	int -tty_islitecho() -{ -#ifndef	USE_TERMIO -	return (!(termbuf.lflags & LCTLECH)); -#else -# ifdef	ECHOCTL -	return (!(termbuf.c_lflag & ECHOCTL)); -# endif -# ifdef	TCTLECH -	return (!(termbuf.c_lflag & TCTLECH)); -# endif -# if	!defined(ECHOCTL) && !defined(TCTLECH) -	return (0);	/* assumes ctl chars are echoed '^x' */ -# endif -#endif -} - -	void -tty_setlitecho(on) -	int on; -{ -#ifndef	USE_TERMIO -	if (on) -		termbuf.lflags &= ~LCTLECH; -	else -		termbuf.lflags |= LCTLECH; -#else -# ifdef	ECHOCTL -	if (on) -		termbuf.c_lflag &= ~ECHOCTL; -	else -		termbuf.c_lflag |= ECHOCTL; -# endif -# ifdef	TCTLECH -	if (on) -		termbuf.c_lflag &= ~TCTLECH; -	else -		termbuf.c_lflag |= TCTLECH; -# endif -#endif -} - -	int -tty_iscrnl() -{ -#ifndef	USE_TERMIO -	return (termbuf.sg.sg_flags & CRMOD); -#else -	return (termbuf.c_iflag & ICRNL); -#endif -} - -/* - * A table of available terminal speeds - */ -struct termspeeds { -	int	speed; -	int	value; -} termspeeds[] = { -	{ 0,     B0 },    { 50,    B50 },   { 75,    B75 }, -	{ 110,   B110 },  { 134,   B134 },  { 150,   B150 }, -	{ 200,   B200 },  { 300,   B300 },  { 600,   B600 }, -	{ 1200,  B1200 }, { 1800,  B1800 }, { 2400,  B2400 }, -	{ 4800,  B4800 }, { 9600,  B9600 }, { 19200, B9600 }, -	{ 38400, B9600 }, { -1,    B9600 } -}; - -	void -tty_tspeed(val) -	int val; -{ -	register struct termspeeds *tp; - -	for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++) -		; -	cfsetospeed(&termbuf, tp->value); -} - -	void -tty_rspeed(val) -	int val; -{ -	register struct termspeeds *tp; - -	for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++) -		; -	cfsetispeed(&termbuf, tp->value); -} - -#if	defined(CRAY2) && defined(UNICOS5) -	int -tty_isnewmap() -{ -	return((termbuf.c_oflag & OPOST) && (termbuf.c_oflag & ONLCR) && -			!(termbuf.c_oflag & ONLRET)); -} -#endif - -#ifdef PARENT_DOES_UTMP -# ifndef NEWINIT -extern	struct utmp wtmp; -extern char wtmpf[]; -# else	/* NEWINIT */ -int	gotalarm; - -	/* ARGSUSED */ -	void -nologinproc(sig) -	int sig; -{ -	gotalarm++; -} -# endif	/* NEWINIT */ -#endif /* PARENT_DOES_UTMP */ - -#ifndef	NEWINIT -# ifdef PARENT_DOES_UTMP -extern void utmp_sig_init P((void)); -extern void utmp_sig_reset P((void)); -extern void utmp_sig_wait P((void)); -extern void utmp_sig_notify P((int)); -# endif /* PARENT_DOES_UTMP */ -#endif - -/* - * getptyslave() - * - * Open the slave side of the pty, and do any initialization - * that is necessary.  The return value is a file descriptor - * for the slave side. - */ -	int -getptyslave() -{ -	register int t = -1; - -#if	!defined(CRAY) || !defined(NEWINIT) -# ifdef	LINEMODE -	int waslm; -# endif -# ifdef	TIOCGWINSZ -	struct winsize ws; -	extern int def_row, def_col; -# endif -	extern int def_tspeed, def_rspeed; -	/* -	 * Opening the slave side may cause initilization of the -	 * kernel tty structure.  We need remember the state of -	 * 	if linemode was turned on -	 *	terminal window size -	 *	terminal speed -	 * so that we can re-set them if we need to. -	 */ -# ifdef	LINEMODE -	waslm = tty_linemode(); -# endif - - -	/* -	 * Make sure that we don't have a controlling tty, and -	 * that we are the session (process group) leader. -	 */ -# ifdef	TIOCNOTTY -	t = open(_PATH_TTY, O_RDWR); -	if (t >= 0) { -		(void) ioctl(t, TIOCNOTTY, (char *)0); -		(void) close(t); -	} -# endif - - -# ifdef PARENT_DOES_UTMP -	/* -	 * Wait for our parent to get the utmp stuff to get done. -	 */ -	utmp_sig_wait(); -# endif - -	t = cleanopen(line); -	if (t < 0) -		fatalperror(net, line); - -#ifdef  STREAMSPTY -#ifdef	USE_TERMIO -	ttyfd = t; -#endif -	if (ioctl(t, I_PUSH, "ptem") < 0)  -		fatal(net, "I_PUSH ptem"); -	if (ioctl(t, I_PUSH, "ldterm") < 0) -		fatal(net, "I_PUSH ldterm"); -	if (ioctl(t, I_PUSH, "ttcompat") < 0) -		fatal(net, "I_PUSH ttcompat"); -	if (ioctl(pty, I_PUSH, "pckt") < 0) -		fatal(net, "I_PUSH pckt"); -#endif - -	/* -	 * set up the tty modes as we like them to be. -	 */ -	init_termbuf(); -# ifdef	TIOCGWINSZ -	if (def_row || def_col) { -		bzero((char *)&ws, sizeof(ws)); -		ws.ws_col = def_col; -		ws.ws_row = def_row; -		(void)ioctl(t, TIOCSWINSZ, (char *)&ws); -	} -# endif - -	/* -	 * Settings for sgtty based systems -	 */ -# ifndef	USE_TERMIO -	termbuf.sg.sg_flags |= CRMOD|ANYP|ECHO|XTABS; -# endif	/* USE_TERMIO */ - -	/* -	 * Settings for UNICOS (and HPUX) -	 */ -# if defined(CRAY) || defined(__hpux) -	termbuf.c_oflag = OPOST|ONLCR|TAB3; -	termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON; -	termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK; -	termbuf.c_cflag = EXTB|HUPCL|CS8; -# endif - -	/* -	 * Settings for all other termios/termio based -	 * systems, other than 4.4BSD.  In 4.4BSD the -	 * kernel does the initial terminal setup. -	 */ -# if defined(USE_TERMIO) && !(defined(CRAY) || defined(__hpux)) && (BSD <= 43) -#  ifndef	OXTABS -#   define OXTABS	0 -#  endif -	termbuf.c_lflag |= ECHO; -	termbuf.c_oflag |= ONLCR|OXTABS; -	termbuf.c_iflag |= ICRNL; -	termbuf.c_iflag &= ~IXOFF; -# endif /* defined(USE_TERMIO) && !defined(CRAY) && (BSD <= 43) */ -	tty_rspeed((def_rspeed > 0) ? def_rspeed : 9600); -	tty_tspeed((def_tspeed > 0) ? def_tspeed : 9600); -# ifdef	LINEMODE -	if (waslm) -		tty_setlinemode(1); -# endif	/* LINEMODE */ - -	/* -	 * Set the tty modes, and make this our controlling tty. -	 */ -	set_termbuf(); -	if (login_tty(t) == -1) -		fatalperror(net, "login_tty"); -#endif	/* !defined(CRAY) || !defined(NEWINIT) */ -	if (net > 2) -		(void) close(net); -#if	defined(AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R) -	/* -	 * Leave the pty open so that we can write out the rlogin -	 * protocol for /bin/login, if the authentication works. -	 */ -#else -	if (pty > 2) { -		(void) close(pty); -		pty = -1; -	} -#endif -} - -#if	!defined(CRAY) || !defined(NEWINIT) -#ifndef	O_NOCTTY -#define	O_NOCTTY	0 -#endif -/* - * Open the specified slave side of the pty, - * making sure that we have a clean tty. - */ -	int -cleanopen(line) -	char *line; -{ -	register int t; -#if	defined(_SC_CRAY_SECURE_SYS) -	struct secstat secbuf; -#endif	/* _SC_CRAY_SECURE_SYS */ - -#ifndef STREAMSPTY -	/* -	 * Make sure that other people can't open the -	 * slave side of the connection. -	 */ -	(void) chown(line, 0, 0); -	(void) chmod(line, 0600); -#endif - -# if !defined(CRAY) && (BSD > 43) -	(void) revoke(line); -# endif -#if	defined(_SC_CRAY_SECURE_SYS) -	if (secflag) { -		if (secstat(line, &secbuf) < 0) -			return(-1); -		if (setulvl(secbuf.st_slevel) < 0) -			return(-1); -		if (setucmp(secbuf.st_compart) < 0) -			return(-1); -	} -#endif	/* _SC_CRAY_SECURE_SYS */ - -	t = open(line, O_RDWR|O_NOCTTY); - -#if	defined(_SC_CRAY_SECURE_SYS) -	if (secflag) { -		if (setulvl(sysv.sy_minlvl) < 0) -			return(-1); -		if (setucmp(0) < 0) -			return(-1); -	} -#endif	/* _SC_CRAY_SECURE_SYS */ - -	if (t < 0) -		return(-1); - -	/* -	 * Hangup anybody else using this ttyp, then reopen it for -	 * ourselves. -	 */ -# if !(defined(CRAY) || defined(__hpux)) && (BSD <= 43) && !defined(STREAMSPTY) -	(void) signal(SIGHUP, SIG_IGN); -	vhangup(); -	(void) signal(SIGHUP, SIG_DFL); -	t = open(line, O_RDWR|O_NOCTTY); -	if (t < 0) -		return(-1); -# endif -# if	defined(CRAY) && defined(TCVHUP) -	{ -		register int i; -		(void) signal(SIGHUP, SIG_IGN); -		(void) ioctl(t, TCVHUP, (char *)0); -		(void) signal(SIGHUP, SIG_DFL); -		setpgrp(); - -#if		defined(_SC_CRAY_SECURE_SYS) -		if (secflag) { -			if (secstat(line, &secbuf) < 0) -				return(-1); -			if (setulvl(secbuf.st_slevel) < 0) -				return(-1); -			if (setucmp(secbuf.st_compart) < 0) -				return(-1); -		} -#endif		/* _SC_CRAY_SECURE_SYS */ - -		i = open(line, O_RDWR); - -#if		defined(_SC_CRAY_SECURE_SYS) -		if (secflag) { -			if (setulvl(sysv.sy_minlvl) < 0) -				return(-1); -			if (setucmp(0) < 0) -				return(-1); -		} -#endif		/* _SC_CRAY_SECURE_SYS */ - -		if (i < 0) -			return(-1); -		(void) close(t); -		t = i; -	} -# endif	/* defined(CRAY) && defined(TCVHUP) */ -	return(t); -} -#endif	/* !defined(CRAY) || !defined(NEWINIT) */ - -#if BSD <= 43 - -	int -login_tty(t) -	int t; -{ -	if (setsid() < 0) { -#ifdef ultrix -		/* -		 * The setsid() may have failed because we -		 * already have a pgrp == pid.  Zero out -		 * our pgrp and try again... -		 */ -		if ((setpgrp(0, 0) < 0) || (setsid() < 0)) -#endif -			fatalperror(net, "setsid()"); -	} -# ifdef	TIOCSCTTY -	if (ioctl(t, TIOCSCTTY, (char *)0) < 0) -		fatalperror(net, "ioctl(sctty)"); -#  if defined(CRAY) -	/* -	 * Close the hard fd to /dev/ttypXXX, and re-open through -	 * the indirect /dev/tty interface. -	 */ -	close(t); -	if ((t = open("/dev/tty", O_RDWR)) < 0) -		fatalperror(net, "open(/dev/tty)"); -#  endif -# else -	/* -	 * We get our controlling tty assigned as a side-effect -	 * of opening up a tty device.  But on BSD based systems, -	 * this only happens if our process group is zero.  The -	 * setsid() call above may have set our pgrp, so clear -	 * it out before opening the tty... -	 */ -	(void) setpgrp(0, 0); -	close(open(line, O_RDWR)); -# endif -	if (t != 0) -		(void) dup2(t, 0); -	if (t != 1) -		(void) dup2(t, 1); -	if (t != 2) -		(void) dup2(t, 2); -	if (t > 2) -		close(t); -	return(0); -} -#endif	/* BSD <= 43 */ - -#ifdef	NEWINIT -char *gen_id = "fe"; -#endif - -/* - * startslave(host) - * - * Given a hostname, do whatever - * is necessary to startup the login process on the slave side of the pty. - */ - -/* ARGSUSED */ -	void -startslave(host, autologin, autoname) -	char *host; -	int autologin; -	char *autoname; -{ -	register int i; -	long time(); -	char name[256]; -#ifdef	NEWINIT -	extern char *ptyip; -	struct init_request request; -	void nologinproc(); -	register int n; -#endif	/* NEWINIT */ - -#if	defined(AUTHENTICATION) -	if (!autoname || !autoname[0]) -		autologin = 0; - -	if (autologin < auth_level) { -		fatal(net, "Authorization failed"); -		exit(1); -	} -#endif - -#ifndef	NEWINIT -# ifdef	PARENT_DOES_UTMP -	utmp_sig_init(); -# endif	/* PARENT_DOES_UTMP */ - -	if ((i = fork()) < 0) -		fatalperror(net, "fork"); -	if (i) { -# ifdef PARENT_DOES_UTMP -		/* -		 * Cray parent will create utmp entry for child and send -		 * signal to child to tell when done.  Child waits for signal -		 * before doing anything important. -		 */ -		register int pid = i; -		void sigjob P((int)); - -		setpgrp(); -		utmp_sig_reset();		/* reset handler to default */ -		/* -		 * Create utmp entry for child -		 */ -		(void) time(&wtmp.ut_time); -		wtmp.ut_type = LOGIN_PROCESS; -		wtmp.ut_pid = pid; -		SCPYN(wtmp.ut_user, "LOGIN"); -		SCPYN(wtmp.ut_host, host); -		SCPYN(wtmp.ut_line, line + sizeof("/dev/") - 1); -#ifndef	__hpux -		SCPYN(wtmp.ut_id, wtmp.ut_line+3); -#else -		SCPYN(wtmp.ut_id, wtmp.ut_line+7); -#endif -		pututline(&wtmp); -		endutent(); -		if ((i = open(wtmpf, O_WRONLY|O_APPEND)) >= 0) { -			(void) write(i, (char *)&wtmp, sizeof(struct utmp)); -			(void) close(i); -		} -#ifdef	CRAY -		(void) signal(WJSIGNAL, sigjob); -#endif -		utmp_sig_notify(pid); -# endif	/* PARENT_DOES_UTMP */ -	} else { -		getptyslave(autologin); -		start_login(host, autologin, autoname); -		/*NOTREACHED*/ -	} -#else	/* NEWINIT */ - -	/* -	 * Init will start up login process if we ask nicely.  We only wait -	 * for it to start up and begin normal telnet operation. -	 */ -	if ((i = open(INIT_FIFO, O_WRONLY)) < 0) { -		char tbuf[128]; -		(void) sprintf(tbuf, "Can't open %s\n", INIT_FIFO); -		fatalperror(net, tbuf); -	} -	memset((char *)&request, 0, sizeof(request)); -	request.magic = INIT_MAGIC; -	SCPYN(request.gen_id, gen_id); -	SCPYN(request.tty_id, &line[8]); -	SCPYN(request.host, host); -	SCPYN(request.term_type, terminaltype ? terminaltype : "network"); -#if	!defined(UNICOS5) -	request.signal = SIGCLD; -	request.pid = getpid(); -#endif -#ifdef BFTPDAEMON -	/* -	 * Are we working as the bftp daemon? -	 */ -	if (bftpd) { -		SCPYN(request.exec_name, BFTPPATH); -	} -#endif /* BFTPDAEMON */ -	if (write(i, (char *)&request, sizeof(request)) < 0) { -		char tbuf[128]; -		(void) sprintf(tbuf, "Can't write to %s\n", INIT_FIFO); -		fatalperror(net, tbuf); -	} -	(void) close(i); -	(void) signal(SIGALRM, nologinproc); -	for (i = 0; ; i++) { -		char tbuf[128]; -		alarm(15); -		n = read(pty, ptyip, BUFSIZ); -		if (i == 3 || n >= 0 || !gotalarm) -			break; -		gotalarm = 0; -		sprintf(tbuf, "telnetd: waiting for /etc/init to start login process on %s\r\n", line); -		(void) write(net, tbuf, strlen(tbuf)); -	} -	if (n < 0 && gotalarm) -		fatal(net, "/etc/init didn't start login process"); -	pcc += n; -	alarm(0); -	(void) signal(SIGALRM, SIG_DFL); - -	return; -#endif	/* NEWINIT */ -} - -char	*envinit[3]; -extern char **environ; - -	void -init_env() -{ -	extern char *getenv(); -	char **envp; - -	envp = envinit; -	if (*envp = getenv("TZ")) -		*envp++ -= 3; -#if	defined(CRAY) || defined(__hpux) -	else -		*envp++ = "TZ=GMT0"; -#endif -	*envp = 0; -	environ = envinit; -} - -#ifndef	NEWINIT - -/* - * start_login(host) - * - * Assuming that we are now running as a child processes, this - * function will turn us into the login process. - */ - -	void -start_login(host, autologin, name) -	char *host; -	int autologin; -	char *name; -{ -	register char *cp; -	register char **argv; -	char **addarg(); -	extern char *getenv(); -#ifdef	UTMPX -	register int pid = getpid(); -	struct utmpx utmpx; -#endif -#ifdef SOLARIS -	char *term; -	char termbuf[64]; -#endif - -#ifdef	UTMPX -	/* -	 * Create utmp entry for child -	 */ - -	bzero(&utmpx, sizeof(utmpx)); -	SCPYN(utmpx.ut_user, ".telnet"); -	SCPYN(utmpx.ut_line, line + sizeof("/dev/") - 1); -	utmpx.ut_pid = pid; -	utmpx.ut_id[0] = 't'; -	utmpx.ut_id[1] = 'n'; -	utmpx.ut_id[2] = SC_WILDC; -	utmpx.ut_id[3] = SC_WILDC; -	utmpx.ut_type = LOGIN_PROCESS; -	(void) time(&utmpx.ut_tv.tv_sec); -	if (makeutx(&utmpx) == NULL) -		fatal(net, "makeutx failed"); -#endif - -	/* -	 * -h : pass on name of host. -	 *		WARNING:  -h is accepted by login if and only if -	 *			getuid() == 0. -	 * -p : don't clobber the environment (so terminal type stays set). -	 * -	 * -f : force this login, he has already been authenticated -	 */ -	argv = addarg(0, "login"); - -#if	!defined(NO_LOGIN_H) - -# if	defined (AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R) -	/* -	 * Don't add the "-h host" option if we are going -	 * to be adding the "-r host" option down below... -	 */ -	if ((auth_level < 0) || (autologin != AUTH_VALID)) -# endif -	{ -		argv = addarg(argv, "-h"); -		argv = addarg(argv, host); -#ifdef	SOLARIS -		/* -		 * SVR4 version of -h takes TERM= as second arg, or - -		 */ -		term = getenv("TERM"); -		if (term == NULL || term[0] == 0) { -			term = "-"; -		} else { -			strcpy(termbuf, "TERM="); -			strncat(termbuf, term, sizeof(termbuf) - 6); -			term = termbuf; -		} -		argv = addarg(argv, term); -#endif -	} -#endif -#if	!defined(NO_LOGIN_P) -	argv = addarg(argv, "-p"); -#endif -#ifdef	BFTPDAEMON -	/* -	 * Are we working as the bftp daemon?  If so, then ask login -	 * to start bftp instead of shell. -	 */ -	if (bftpd) { -		argv = addarg(argv, "-e"); -		argv = addarg(argv, BFTPPATH); -	} else  -#endif -#if	defined (SecurID) -	/* -	 * don't worry about the -f that might get sent. -	 * A -s is supposed to override it anyhow. -	 */ -	if (require_SecurID) -		argv = addarg(argv, "-s"); -#endif -#if	defined (AUTHENTICATION) -	if (auth_level >= 0 && autologin == AUTH_VALID) { -# if	!defined(NO_LOGIN_F) -		argv = addarg(argv, "-f"); -		argv = addarg(argv, name); -# else -#  if defined(LOGIN_R) -		/* -		 * We don't have support for "login -f", but we -		 * can fool /bin/login into thinking that we are -		 * rlogind, and allow us to log in without a -		 * password.  The rlogin protocol expects -		 *	local-user\0remote-user\0term/speed\0 -		 */ - -		if (pty > 2) { -			register char *cp; -			char speed[128]; -			int isecho, israw, xpty, len; -			extern int def_rspeed; -#  ifndef LOGIN_HOST -			/* -			 * Tell login that we are coming from "localhost". -			 * If we passed in the real host name, then the -			 * user would have to allow .rhost access from -			 * every machine that they want authenticated -			 * access to work from, which sort of defeats -			 * the purpose of an authenticated login... -			 * So, we tell login that the session is coming -			 * from "localhost", and the user will only have -			 * to have "localhost" in their .rhost file. -			 */ -#			define LOGIN_HOST "localhost" -#  endif -			argv = addarg(argv, "-r"); -			argv = addarg(argv, LOGIN_HOST); - -			xpty = pty; -# ifndef  STREAMSPTY -			pty = 0; -# else -			ttyfd = 0; -# endif -			init_termbuf(); -			isecho = tty_isecho(); -			israw = tty_israw(); -			if (isecho || !israw) { -				tty_setecho(0);		/* Turn off echo */ -				tty_setraw(1);		/* Turn on raw */ -				set_termbuf(); -			} -			len = strlen(name)+1; -			write(xpty, name, len); -			write(xpty, name, len); -			sprintf(speed, "%s/%d", (cp = getenv("TERM")) ? cp : "", -				(def_rspeed > 0) ? def_rspeed : 9600); -			len = strlen(speed)+1; -			write(xpty, speed, len); - -			if (isecho || !israw) { -				init_termbuf(); -				tty_setecho(isecho); -				tty_setraw(israw); -				set_termbuf(); -				if (!israw) { -					/* -					 * Write a newline to ensure -					 * that login will be able to -					 * read the line... -					 */ -					write(xpty, "\n", 1); -				} -			} -			pty = xpty; -		} -#  else -		argv = addarg(argv, name); -#  endif -# endif -	} else -#endif -	if (getenv("USER")) { -		argv = addarg(argv, getenv("USER")); -#if	defined(LOGIN_ARGS) && defined(NO_LOGIN_P) -		{ -			register char **cpp; -			for (cpp = environ; *cpp; cpp++) -				argv = addarg(argv, *cpp); -		} -#endif -		/* -		 * Assume that login will set the USER variable -		 * correctly.  For SysV systems, this means that -		 * USER will no longer be set, just LOGNAME by -		 * login.  (The problem is that if the auto-login -		 * fails, and the user then specifies a different -		 * account name, he can get logged in with both -		 * LOGNAME and USER in his environment, but the -		 * USER value will be wrong. -		 */ -		unsetenv("USER"); -	} -#if	defined(AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R) -	if (pty > 2) -		close(pty); -#endif -	closelog(); -	execv(_PATH_LOGIN, argv); - -	syslog(LOG_ERR, "%s: %m\n", _PATH_LOGIN); -	fatalperror(net, _PATH_LOGIN); -	/*NOTREACHED*/ -} - -	char ** -addarg(argv, val) -	register char **argv; -	register char *val; -{ -	register char **cpp; - -	if (argv == NULL) { -		/* -		 * 10 entries, a leading length, and a null -		 */ -		argv = (char **)malloc(sizeof(*argv) * 12); -		if (argv == NULL) -			return(NULL); -		*argv++ = (char *)10; -		*argv = (char *)0; -	} -	for (cpp = argv; *cpp; cpp++) -		; -	if (cpp == &argv[(int)argv[-1]]) { -		--argv; -		*argv = (char *)((int)(*argv) + 10); -		argv = (char **)realloc(argv, (int)(*argv) + 2); -		if (argv == NULL) -			return(NULL); -		argv++; -		cpp = &argv[(int)argv[-1] - 10]; -	} -	*cpp++ = val; -	*cpp = 0; -	return(argv); -} -#endif	/* NEWINIT */ - -/* - * cleanup() - * - * This is the routine to call when we are all through, to - * clean up anything that needs to be cleaned up. - */ -	/* ARGSUSED */ -	void -cleanup(sig) -	int sig; -{ -#ifndef	PARENT_DOES_UTMP -# if (BSD > 43) || defined(convex) -	char *p; - -	p = line + sizeof("/dev/") - 1; -	if (logout(p)) -		logwtmp(p, "", ""); -	(void)chmod(line, 0666); -	(void)chown(line, 0, 0); -	*p = 'p'; -	(void)chmod(line, 0666); -	(void)chown(line, 0, 0); -	(void) shutdown(net, 2); -	exit(1); -# else -	void rmut(); - -	rmut(); -	vhangup();	/* XXX */ -	(void) shutdown(net, 2); -	exit(1); -# endif -#else	/* PARENT_DOES_UTMP */ -# ifdef	NEWINIT -	(void) shutdown(net, 2); -	exit(1); -# else	/* NEWINIT */ -#  ifdef CRAY -	static int incleanup = 0; -	register int t; - -	/* -	 * 1: Pick up the zombie, if we are being called -	 *    as the signal handler. -	 * 2: If we are a nested cleanup(), return. -	 * 3: Try to clean up TMPDIR. -	 * 4: Fill in utmp with shutdown of process. -	 * 5: Close down the network and pty connections. -	 * 6: Finish up the TMPDIR cleanup, if needed. -	 */ -	if (sig == SIGCHLD) -		while (waitpid(-1, 0, WNOHANG) > 0) -			;	/* VOID */ -	t = sigblock(sigmask(SIGCHLD)); -	if (incleanup) { -		sigsetmask(t); -		return; -	} -	incleanup = 1; -	sigsetmask(t); -	if (secflag) { -		/* -		 *	We need to set ourselves back to a null -		 *	label to clean up. -		 */ - -		setulvl(sysv.sy_minlvl); -		setucmp((long)0); -	} - -	t = cleantmp(&wtmp); -	setutent();	/* just to make sure */ -#  endif /* CRAY */ -	rmut(line); -	close(pty); -	(void) shutdown(net, 2); -#  ifdef CRAY -	if (t == 0) -		cleantmp(&wtmp); -#  endif /* CRAY */ -	exit(1); -# endif	/* NEWINT */ -#endif	/* PARENT_DOES_UTMP */ -} - -#if defined(PARENT_DOES_UTMP) && !defined(NEWINIT) -/* - * _utmp_sig_rcv - * utmp_sig_init - * utmp_sig_wait - *	These three functions are used to coordinate the handling of - *	the utmp file between the server and the soon-to-be-login shell. - *	The server actually creates the utmp structure, the child calls - *	utmp_sig_wait(), until the server calls utmp_sig_notify() and - *	signals the future-login shell to proceed. - */ -static int caught=0;		/* NZ when signal intercepted */ -static void (*func)();		/* address of previous handler */ - -	void -_utmp_sig_rcv(sig) -	int sig; -{ -	caught = 1; -	(void) signal(SIGUSR1, func); -} - -	void -utmp_sig_init() -{ -	/* -	 * register signal handler for UTMP creation -	 */ -	if ((int)(func = signal(SIGUSR1, _utmp_sig_rcv)) == -1) -		fatalperror(net, "telnetd/signal"); -} - -	void -utmp_sig_reset() -{ -	(void) signal(SIGUSR1, func);	/* reset handler to default */ -} - -# ifdef __hpux -# define sigoff() /* do nothing */ -# define sigon() /* do nothing */ -# endif - -	void -utmp_sig_wait() -{ -	/* -	 * Wait for parent to write our utmp entry. -	 */ -	sigoff(); -	while (caught == 0) { -		pause();	/* wait until we get a signal (sigon) */ -		sigoff();	/* turn off signals while we check caught */ -	} -	sigon();		/* turn on signals again */ -} - -	void -utmp_sig_notify(pid) -{ -	kill(pid, SIGUSR1); -} - -# ifdef CRAY -static int gotsigjob = 0; - -	/*ARGSUSED*/ -	void -sigjob(sig) -	int sig; -{ -	register int jid; -	register struct jobtemp *jp; - -	while ((jid = waitjob(NULL)) != -1) { -		if (jid == 0) { -			return; -		} -		gotsigjob++; -		jobend(jid, NULL, NULL); -	} -} - -/* - * Clean up the TMPDIR that login created. - * The first time this is called we pick up the info - * from the utmp.  If the job has already gone away, - * then we'll clean up and be done.  If not, then - * when this is called the second time it will wait - * for the signal that the job is done. - */ -	int -cleantmp(wtp) -	register struct utmp *wtp; -{ -	struct utmp *utp; -	static int first = 1; -	register int mask, omask, ret; -	extern struct utmp *getutid P((const struct utmp *_Id)); - - -	mask = sigmask(WJSIGNAL); - -	if (first == 0) { -		omask = sigblock(mask); -		while (gotsigjob == 0) -			sigpause(omask); -		return(1); -	} -	first = 0; -	setutent();	/* just to make sure */ - -	utp = getutid(wtp); -	if (utp == 0) { -		syslog(LOG_ERR, "Can't get /etc/utmp entry to clean TMPDIR"); -		return(-1); -	} -	/* -	 * Nothing to clean up if the user shell was never started. -	 */ -	if (utp->ut_type != USER_PROCESS || utp->ut_jid == 0) -		return(1); - -	/* -	 * Block the WJSIGNAL while we are in jobend(). -	 */ -	omask = sigblock(mask); -	ret = jobend(utp->ut_jid, utp->ut_tpath, utp->ut_user); -	sigsetmask(omask); -	return(ret); -} - -	int -jobend(jid, path, user) -	register int jid; -	register char *path; -	register char *user; -{ -	static int saved_jid = 0; -	static char saved_path[sizeof(wtmp.ut_tpath)+1]; -	static char saved_user[sizeof(wtmp.ut_user)+1]; - -	if (path) { -		strncpy(saved_path, path, sizeof(wtmp.ut_tpath)); -		strncpy(saved_user, user, sizeof(wtmp.ut_user)); -		saved_path[sizeof(saved_path)] = '\0'; -		saved_user[sizeof(saved_user)] = '\0'; -	} -	if (saved_jid == 0) { -		saved_jid = jid; -		return(0); -	} -	cleantmpdir(jid, saved_path, saved_user); -	return(1); -} - -/* - * Fork a child process to clean up the TMPDIR - */ -cleantmpdir(jid, tpath, user) -	register int jid; -	register char *tpath; -	register char *user; -{ -	switch(fork()) { -	case -1: -		syslog(LOG_ERR, "TMPDIR cleanup(%s): fork() failed: %m\n", -							tpath); -		break; -	case 0: -		execl(CLEANTMPCMD, CLEANTMPCMD, user, tpath, 0); -		syslog(LOG_ERR, "TMPDIR cleanup(%s): execl(%s) failed: %m\n", -							tpath, CLEANTMPCMD); -		exit(1); -	default: -		/* -		 * Forget about child.  We will exit, and -		 * /etc/init will pick it up. -		 */ -		break; -	} -} -# endif /* CRAY */ -#endif	/* defined(PARENT_DOES_UTMP) && !defined(NEWINIT) */ - -/* - * rmut() - * - * This is the function called by cleanup() to - * remove the utmp entry for this person. - */ - -#ifdef	UTMPX -	void -rmut() -{ -	register f; -	int found = 0; -	struct utmp *u, *utmp; -	int nutmp; -	struct stat statbf; - -	struct utmpx *utxp, utmpx; - -	/* -	 * This updates the utmpx and utmp entries and make a wtmp/x entry -	 */ - -	SCPYN(utmpx.ut_line, line + sizeof("/dev/") - 1); -	utxp = getutxline(&utmpx); -	if (utxp) { -		utxp->ut_type = DEAD_PROCESS; -		utxp->ut_exit.e_termination = 0; -		utxp->ut_exit.e_exit = 0; -		(void) time(&utmpx.ut_tv.tv_sec); -		utmpx.ut_tv.tv_usec = 0; -		modutx(utxp); -	} -	endutxent(); -}  /* end of rmut */ -#endif - -#if	!defined(UTMPX) && !(defined(CRAY) || defined(__hpux)) && BSD <= 43 -	void -rmut() -{ -	register f; -	int found = 0; -	struct utmp *u, *utmp; -	int nutmp; -	struct stat statbf; - -	f = open(utmpf, O_RDWR); -	if (f >= 0) { -		(void) fstat(f, &statbf); -		utmp = (struct utmp *)malloc((unsigned)statbf.st_size); -		if (!utmp) -			syslog(LOG_ERR, "utmp malloc failed"); -		if (statbf.st_size && utmp) { -			nutmp = read(f, (char *)utmp, (int)statbf.st_size); -			nutmp /= sizeof(struct utmp); -		 -			for (u = utmp ; u < &utmp[nutmp] ; u++) { -				if (SCMPN(u->ut_line, line+5) || -				    u->ut_name[0]==0) -					continue; -				(void) lseek(f, ((long)u)-((long)utmp), L_SET); -				SCPYN(u->ut_name, ""); -				SCPYN(u->ut_host, ""); -				(void) time(&u->ut_time); -				(void) write(f, (char *)u, sizeof(wtmp)); -				found++; -			} -		} -		(void) close(f); -	} -	if (found) { -		f = open(wtmpf, O_WRONLY|O_APPEND); -		if (f >= 0) { -			SCPYN(wtmp.ut_line, line+5); -			SCPYN(wtmp.ut_name, ""); -			SCPYN(wtmp.ut_host, ""); -			(void) time(&wtmp.ut_time); -			(void) write(f, (char *)&wtmp, sizeof(wtmp)); -			(void) close(f); -		} -	} -	(void) chmod(line, 0666); -	(void) chown(line, 0, 0); -	line[strlen("/dev/")] = 'p'; -	(void) chmod(line, 0666); -	(void) chown(line, 0, 0); -}  /* end of rmut */ -#endif	/* CRAY */ - -#ifdef __hpux -rmut (line) -char *line; -{ -	struct utmp utmp; -	struct utmp *utptr; -	int fd;			/* for /etc/wtmp */ - -	utmp.ut_type = USER_PROCESS; -	(void) strncpy(utmp.ut_id, line+12, sizeof(utmp.ut_id)); -	(void) setutent(); -	utptr = getutid(&utmp); -	/* write it out only if it exists */ -	if (utptr) { -		utptr->ut_type = DEAD_PROCESS; -		utptr->ut_time = time((long *) 0); -		(void) pututline(utptr); -		/* set wtmp entry if wtmp file exists */ -		if ((fd = open(wtmpf, O_WRONLY | O_APPEND)) >= 0) { -			(void) write(fd, utptr, sizeof(utmp)); -			(void) close(fd); -		} -	} -	(void) endutent(); - -	(void) chmod(line, 0666); -	(void) chown(line, 0, 0); -	line[14] = line[13]; -	line[13] = line[12]; -	line[8] = 'm'; -	line[9] = '/'; -	line[10] = 'p'; -	line[11] = 't'; -	line[12] = 'y'; -	(void) chmod(line, 0666); -	(void) chown(line, 0, 0); -} -#endif diff --git a/secure/libexec/telnetd/telnetd.8 b/secure/libexec/telnetd/telnetd.8 deleted file mode 100644 index fee552640689..000000000000 --- a/secure/libexec/telnetd/telnetd.8 +++ /dev/null @@ -1,605 +0,0 @@ -.\" Copyright (c) 1983, 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. -.\" -.\"	@(#)telnetd.8	8.3 (Berkeley) 3/1/94 -.\" -.Dd March 1, 1994 -.Dt TELNETD 8 -.Os BSD 4.2 -.Sh NAME -.Nm telnetd -.Nd DARPA -.Tn TELNET -protocol server -.Sh SYNOPSIS -.Nm /usr/libexec/telnetd -.Op Fl BUhlkns -.Op Fl D Ar debugmode -.Op Fl I Ns Ar initid -.Op Fl S Ar tos -.Op Fl X Ar authtype -.Op Fl a Ar authmode -.Op Fl edebug -.Op Fl r Ns Ar lowpty-highpty -.Op Fl u Ar len -.Op Fl debug Op Ar port -.Sh DESCRIPTION -The -.Nm telnetd -command is a server which supports the -.Tn DARPA -standard -.Tn TELNET -virtual terminal protocol. -.Nm Telnetd -is normally invoked by the internet server (see -.Xr inetd 8 ) -for requests to connect to the -.Tn TELNET -port as indicated by the -.Pa /etc/services -file (see -.Xr services 5 ) . -The -.Fl debug -option may be used to start up -.Nm telnetd -manually, instead of through -.Xr inetd 8 . -If started up this way,  -.Ar port -may be specified to run -.Nm telnetd -on an alternate -.Tn TCP -port number. -.Pp -The -.Nm telnetd -command accepts the following options: -.Bl -tag -width "-a authmode" -.It Fl a Ar authmode -This option may be used for specifying what mode should -be used for authentication. -Note that this option is only useful if -.Nm telnetd -has been compiled with support for the -.Dv AUTHENTICATION -option. -There are several valid values for -.Ar authmode: -.Bl -tag -width debug -.It debug -Turns on authentication debugging code. -.It user -Only allow connections when the remote user -can provide valid authentication information -to identify the remote user, -and is allowed access to the specified account -without providing a password. -.It valid -Only allow connections when the remote user -can provide valid authentication information -to identify the remote user. -The -.Xr login 1 -command will provide any additional user verification -needed if the remote user is not allowed automatic -access to the specified account. -.It other -Only allow connections that supply some authentication information. -This option is currently not supported -by any of the existing authentication mechanisms, -and is thus the same as specifying -.Fl a -.Cm valid . -.It none -This is the default state. -Authentication information is not required. -If no or insufficient authentication information -is provided, then the -.Xr login 1 -program will provide the necessary user -verification. -.It off -This disables the authentication code. -All user verification will happen through the -.Xr login 1 -program. -.El -.It Fl B -Specifies bftp server mode.  In this mode, -.Nm telnetd -causes login to start a -.Xr bftp 1 -session rather than the user's -normal shell.  In bftp daemon mode normal -logins are not supported, and it must be used -on a port other than the normal -.Tn TELNET -port. -.It Fl D Ar debugmode -This option may be used for debugging purposes. -This allows -.Nm telnetd -to print out debugging information -to the connection, allowing the user to see what -.Nm telnetd -is doing. -There are several possible values for  -.Ar debugmode: -.Bl -tag -width exercise -.It Cm options -Prints information about the negotiation of -.Tn TELNET -options. -.It Cm report -Prints the  -.Cm options -information, plus some additional information -about what processing is going on. -.It Cm netdata -Displays the data stream received by -.Nm telnetd. -.It Cm ptydata -Displays data written to the pty. -.It Cm exercise -Has not been implemented yet. -.El -.It Fl debug -Enables debugging on each socket created by -.Nm telnetd -(see -.Dv SO_DEBUG -in -.Xr socket 2 ) . -.It Fl edebug -If -.Nm telnetd -has been compiled with support for data encryption, then the -.Fl edebug -option may be used to enable encryption debugging code. -.It Fl h -Disables the printing of host-specific information before -login has been completed. -.It Fl I Ar initid -This option is only applicable to -.Tn UNICOS -systems prior to 7.0. -It specifies the -.Dv ID -from -.Pa /etc/inittab -to use when init starts login sessions.  The default -.Dv ID -is -.Dv fe. -.It Fl k -This option is only useful if -.Nm telnetd -has been compiled with both linemode and kludge linemode -support.  If the -.Fl k -option is specified, then if the remote client does not -support the -.Dv LINEMODE -option, then -.Nm telnetd -will operate in character at a time mode. -It will still support kludge linemode, but will only -go into kludge linemode if the remote client requests -it. -(This is done by by the client sending -.Dv DONT SUPPRESS-GO-AHEAD -and -.Dv DONT ECHO . ) -The -.Fl k -option is most useful when there are remote clients -that do not support kludge linemode, but pass the heuristic -(if they respond with -.Dv WILL TIMING-MARK -in response to a -.Dv DO TIMING-MARK) -for kludge linemode support. -.It Fl l -Specifies line mode.  Tries to force clients to use line- -at-a-time mode. -If the -.Dv LINEMODE -option is not supported, it will go -into kludge linemode. -.It Fl n -Disable -.Dv TCP -keep-alives.  Normally -.Nm telnetd -enables the -.Tn TCP -keep-alive mechanism to probe connections that -have been idle for some period of time to determine -if the client is still there, so that idle connections -from machines that have crashed or can no longer -be reached may be cleaned up. -.It Fl r Ar lowpty-highpty -This option is only enabled when -.Nm telnetd -is compiled for -.Dv UNICOS. -It specifies an inclusive range of pseudo-terminal devices to -use.  If the system has sysconf variable -.Dv _SC_CRAY_NPTY -configured, the default pty search range is 0 to -.Dv _SC_CRAY_NPTY; -otherwise, the default range is 0 to 128.  Either -.Ar lowpty -or -.Ar highpty -may be omitted to allow changing -either end of the search range.  If -.Ar lowpty -is omitted, the - character is still required so that -.Nm telnetd -can differentiate -.Ar highpty -from -.Ar lowpty . -.It Fl s -This option is only enabled if -.Nm telnetd -is compiled with support for -.Tn SecurID -cards. -It causes the -.Fl s -option to be passed on to -.Xr login 1 , -and thus is only useful if -.Xr login 1 -supports the -.Fl s -flag to indicate that only -.Tn SecurID -validated logins are allowed, and is -usually useful for controlling remote logins -from outside of a firewall. -.It Fl S Ar tos -.It Fl u Ar len -This option is used to specify the size of the field -in the -.Dv utmp -structure that holds the remote host name. -If the resolved host name is longer than -.Ar len , -the dotted decimal value will be used instead. -This allows hosts with very long host names that -overflow this field to still be uniquely identified. -Specifying -.Fl u0 -indicates that only dotted decimal addresses -should be put into the -.Pa utmp -file. -.It Fl U -This option causes -.Nm telnetd -to refuse connections from addresses that -cannot be mapped back into a symbolic name -via the -.Xr gethostbyaddr 3 -routine. -.It Fl X Ar authtype -This option is only valid if -.Nm telnetd -has been built with support for the authentication option. -It disables the use of -.Ar authtype -authentication, and -can be used to temporarily disable -a specific authentication type without having to recompile -.Nm telnetd . -.El -.Pp -.Nm Telnetd -operates by allocating a pseudo-terminal device (see -.Xr pty 4 ) -for a client, then creating a login process which has -the slave side of the pseudo-terminal as  -.Dv stdin , -.Dv stdout -and -.Dv stderr . -.Nm Telnetd -manipulates the master side of the pseudo-terminal, -implementing the -.Tn TELNET -protocol and passing characters -between the remote client and the login process. -.Pp -When a -.Tn TELNET -session is started up,  -.Nm telnetd -sends -.Tn TELNET -options to the client side indicating -a willingness to do the -following -.Tn TELNET -options, which are described in more detail below: -.Bd -literal -offset indent -DO AUTHENTICATION -WILL ENCRYPT -DO TERMINAL TYPE -DO TSPEED -DO XDISPLOC -DO NEW-ENVIRON -DO ENVIRON -WILL SUPPRESS GO AHEAD -DO ECHO -DO LINEMODE -DO NAWS -WILL STATUS -DO LFLOW -DO TIMING-MARK -.Ed -.Pp -The pseudo-terminal allocated to the client is configured -to operate in \*(lqcooked\*(rq mode, and with -.Dv XTABS and -.Dv CRMOD -enabled (see -.Xr tty 4 ) . -.Pp -.Nm Telnetd -has support for enabling locally the following -.Tn TELNET -options: -.Bl -tag -width "DO AUTHENTICATION" -.It "WILL ECHO" -When the -.Dv LINEMODE -option is enabled, a -.Dv WILL ECHO -or -.Dv WONT ECHO -will be sent to the client to indicate the -current state of terminal echoing. -When terminal echo is not desired, a -.Dv WILL ECHO -is sent to indicate that -.Tn telnetd -will take care of echoing any data that needs to be -echoed to the terminal, and then nothing is echoed. -When terminal echo is desired, a -.Dv WONT ECHO -is sent to indicate that -.Tn telnetd -will not be doing any terminal echoing, so the -client should do any terminal echoing that is needed. -.It "WILL BINARY" -Indicates that the client is willing to send a -8 bits of data, rather than the normal 7 bits -of the Network Virtual Terminal. -.It "WILL SGA" -Indicates that it will not be sending -.Dv IAC GA, -go ahead, commands. -.It "WILL STATUS" -Indicates a willingness to send the client, upon -request, of the current status of all -.Tn TELNET -options. -.It "WILL TIMING-MARK" -Whenever a -.Dv DO TIMING-MARK -command is received, it is always responded -to with a -.Dv WILL TIMING-MARK -.It "WILL LOGOUT" -When a -.Dv DO LOGOUT -is received, a -.Dv WILL LOGOUT -is sent in response, and the -.Tn TELNET -session is shut down. -.It "WILL ENCRYPT" -Only sent if -.Nm telnetd -is compiled with support for data encryption, and -indicates a willingness to decrypt -the data stream. -.El -.Pp -.Nm Telnetd -has support for enabling remotely the following -.Tn TELNET -options: -.Bl -tag -width "DO AUTHENTICATION" -.It "DO BINARY" -Sent to indicate that -.Tn telnetd -is willing to receive an 8 bit data stream. -.It "DO LFLOW" -Requests that the client handle flow control -characters remotely. -.It "DO ECHO" -This is not really supported, but is sent to identify a 4.2BSD -.Xr telnet 1 -client, which will improperly respond with -.Dv WILL ECHO. -If a -.Dv WILL ECHO -is received, a -.Dv DONT ECHO -will be sent in response. -.It "DO TERMINAL-TYPE" -Indicates a desire to be able to request the -name of the type of terminal that is attached -to the client side of the connection. -.It "DO SGA" -Indicates that it does not need to receive -.Dv IAC GA, -the go ahead command. -.It "DO NAWS" -Requests that the client inform the server when -the window (display) size changes. -.It "DO TERMINAL-SPEED" -Indicates a desire to be able to request information -about the speed of the serial line to which -the client is attached. -.It "DO XDISPLOC" -Indicates a desire to be able to request the name -of the X windows display that is associated with -the telnet client. -.It "DO NEW-ENVIRON" -Indicates a desire to be able to request environment -variable information, as described in RFC 1572. -.It "DO ENVIRON" -Indicates a desire to be able to request environment -variable information, as described in RFC 1408. -.It "DO LINEMODE" -Only sent if -.Nm telnetd -is compiled with support for linemode, and -requests that the client do line by line processing. -.It "DO TIMING-MARK" -Only sent if -.Nm telnetd -is compiled with support for both linemode and -kludge linemode, and the client responded with -.Dv WONT LINEMODE. -If the client responds with -.Dv WILL TM, -the it is assumed that the client supports -kludge linemode. -Note that the -.Op Fl k -option can be used to disable this. -.It "DO AUTHENTICATION" -Only sent if -.Nm telnetd -is compiled with support for authentication, and -indicates a willingness to receive authentication -information for automatic login. -.It "DO ENCRYPT" -Only sent if -.Nm telnetd -is compiled with support for data encryption, and -indicates a willingness to decrypt -the data stream. -.Sh ENVIRONMENT -.Sh FILES -.Pa /etc/services -.br -.Pa /etc/inittab -(UNICOS systems only) -.br -.Pa /etc/iptos -(if supported) -.br -.Pa /usr/ucb/bftp -(if supported) -.Sh "SEE ALSO" -.Xr telnet 1 , -.Xr login 1 , -.Xr bftp 1 -(if supported) -.Sh STANDARDS -.Bl -tag -compact -width RFC-1572 -.It Cm RFC-854 -.Tn TELNET -PROTOCOL SPECIFICATION -.It Cm RFC-855 -TELNET OPTION SPECIFICATIONS -.It Cm RFC-856 -TELNET BINARY TRANSMISSION -.It Cm RFC-857 -TELNET ECHO OPTION -.It Cm RFC-858 -TELNET SUPPRESS GO AHEAD OPTION -.It Cm RFC-859 -TELNET STATUS OPTION -.It Cm RFC-860 -TELNET TIMING MARK OPTION -.It Cm RFC-861 -TELNET EXTENDED OPTIONS - LIST OPTION -.It Cm RFC-885 -TELNET END OF RECORD OPTION -.It Cm RFC-1073 -Telnet Window Size Option -.It Cm RFC-1079 -Telnet Terminal Speed Option -.It Cm RFC-1091 -Telnet Terminal-Type Option -.It Cm RFC-1096 -Telnet X Display Location Option -.It Cm RFC-1123 -Requirements for Internet Hosts -- Application and Support -.It Cm RFC-1184 -Telnet Linemode Option -.It Cm RFC-1372 -Telnet Remote Flow Control Option -.It Cm RFC-1416 -Telnet Authentication Option -.It Cm RFC-1411 -Telnet Authentication: Kerberos Version 4 -.It Cm RFC-1412 -Telnet Authentication: SPX -.It Cm RFC-1571 -Telnet Environment Option Interoperability Issues -.It Cm RFC-1572 -Telnet Environment Option -.Sh BUGS -Some -.Tn TELNET -commands are only partially implemented. -.Pp -Because of bugs in the original 4.2 BSD -.Xr telnet 1 , -.Nm telnetd -performs some dubious protocol exchanges to try to discover if the remote -client is, in fact, a 4.2 BSD -.Xr telnet 1 . -.Pp -Binary mode -has no common interpretation except between similar operating systems -(Unix in this case). -.Pp -The terminal type name received from the remote client is converted to -lower case. -.Pp -.Nm Telnetd -never sends -.Tn TELNET -.Dv IAC GA -(go ahead) commands. diff --git a/secure/libexec/telnetd/telnetd.c b/secure/libexec/telnetd/telnetd.c deleted file mode 100644 index 6860534853d4..000000000000 --- a/secure/libexec/telnetd/telnetd.c +++ /dev/null @@ -1,1582 +0,0 @@ -/* - * Copyright (c) 1989, 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. - */ - -#ifndef lint -static char copyright[] = -"@(#) Copyright (c) 1989, 1993\n\ -	The Regents of the University of California.  All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -static char sccsid[] = "@(#)telnetd.c	8.2 (Berkeley) 12/15/93"; -#endif /* not lint */ - -#include "telnetd.h" -#include "pathnames.h" - -#if	defined(_SC_CRAY_SECURE_SYS) && !defined(SCM_SECURITY) -/* - * UNICOS 6.0/6.1 do not have SCM_SECURITY defined, so we can - * use it to tell us to turn off all the socket security code, - * since that is only used in UNICOS 7.0 and later. - */ -# undef _SC_CRAY_SECURE_SYS -#endif - -#if	defined(_SC_CRAY_SECURE_SYS) -#include <sys/sysv.h> -#include <sys/secdev.h> -# ifdef SO_SEC_MULTI		/* 8.0 code */ -#include <sys/secparm.h> -#include <sys/usrv.h> -# endif /* SO_SEC_MULTI */ -int	secflag; -char	tty_dev[16]; -struct	secdev dv; -struct	sysv sysv; -# ifdef SO_SEC_MULTI		/* 8.0 code */ -struct	socksec ss; -# else /* SO_SEC_MULTI */	/* 7.0 code */ -struct	socket_security ss; -# endif /* SO_SEC_MULTI */ -#endif	/* _SC_CRAY_SECURE_SYS */ - -#if	defined(AUTHENTICATION) -#include <libtelnet/auth.h> -int	auth_level = 0; -#endif -#if	defined(SecurID) -int	require_SecurID = 0; -#endif - -extern	int utmp_len; -int	registerd_host_only = 0; - -#ifdef	STREAMSPTY -# include <stropts.h> -# include <termio.h> -/* make sure we don't get the bsd version */ -# include "/usr/include/sys/tty.h" -# include <sys/ptyvar.h> - -/* - * Because of the way ptyibuf is used with streams messages, we need - * ptyibuf+1 to be on a full-word boundary.  The following wierdness - * is simply to make that happen. - */ -long	ptyibufbuf[BUFSIZ/sizeof(long)+1]; -char	*ptyibuf = ((char *)&ptyibufbuf[1])-1; -char	*ptyip = ((char *)&ptyibufbuf[1])-1; -char	ptyibuf2[BUFSIZ]; -unsigned char ctlbuf[BUFSIZ]; -struct	strbuf strbufc, strbufd; - -int readstream(); - -#else	/* ! STREAMPTY */ - -/* - * I/O data buffers, - * pointers, and counters. - */ -char	ptyibuf[BUFSIZ], *ptyip = ptyibuf; -char	ptyibuf2[BUFSIZ]; - -#endif /* ! STREAMPTY */ - -int	hostinfo = 1;			/* do we print login banner? */ - -#ifdef	CRAY -extern int      newmap; /* nonzero if \n maps to ^M^J */ -int	lowpty = 0, highpty;	/* low, high pty numbers */ -#endif /* CRAY */ - -int debug = 0; -int keepalive = 1; -char *progname; - -extern void usage P((void)); - -/* - * The string to pass to getopt().  We do it this way so - * that only the actual options that we support will be - * passed off to getopt(). - */ -char valid_opts[] = { -	'd', ':', 'h', 'k', 'n', 'S', ':', 'u', ':', 'U', -#ifdef	AUTHENTICATION -	'a', ':', 'X', ':', -#endif -#ifdef BFTPDAEMON -	'B', -#endif -#ifdef DIAGNOSTICS -	'D', ':', -#endif -#ifdef	ENCRYPTION -	'e', ':', -#endif -#if	defined(CRAY) && defined(NEWINIT) -	'I', ':', -#endif -#ifdef	LINEMODE -	'l', -#endif -#ifdef CRAY -	'r', ':', -#endif -#ifdef	SecurID -	's', -#endif -	'\0' -}; - -main(argc, argv) -	char *argv[]; -{ -	struct sockaddr_in from; -	int on = 1, fromlen; -	register int ch; -	extern char *optarg; -	extern int optind; -#if	defined(IPPROTO_IP) && defined(IP_TOS) -	int tos = -1; -#endif - -	pfrontp = pbackp = ptyobuf; -	netip = netibuf; -	nfrontp = nbackp = netobuf; -#ifdef	ENCRYPTION -	nclearto = 0; -#endif	/* ENCRYPTION */ - -	progname = *argv; - -#ifdef CRAY -	/* -	 * Get number of pty's before trying to process options, -	 * which may include changing pty range. -	 */ -	highpty = getnpty(); -#endif /* CRAY */ - -	while ((ch = getopt(argc, argv, valid_opts)) != EOF) { -		switch(ch) { - -#ifdef	AUTHENTICATION -		case 'a': -			/* -			 * Check for required authentication level -			 */ -			if (strcmp(optarg, "debug") == 0) { -				extern int auth_debug_mode; -				auth_debug_mode = 1; -			} else if (strcasecmp(optarg, "none") == 0) { -				auth_level = 0; -			} else if (strcasecmp(optarg, "other") == 0) { -				auth_level = AUTH_OTHER; -			} else if (strcasecmp(optarg, "user") == 0) { -				auth_level = AUTH_USER; -			} else if (strcasecmp(optarg, "valid") == 0) { -				auth_level = AUTH_VALID; -			} else if (strcasecmp(optarg, "off") == 0) { -				/* -				 * This hack turns off authentication -				 */ -				auth_level = -1; -			} else { -				fprintf(stderr, -			    "telnetd: unknown authorization level for -a\n"); -			} -			break; -#endif	/* AUTHENTICATION */ - -#ifdef BFTPDAEMON -		case 'B': -			bftpd++; -			break; -#endif /* BFTPDAEMON */ - -		case 'd': -			if (strcmp(optarg, "ebug") == 0) { -				debug++; -				break; -			} -			usage(); -			/* NOTREACHED */ -			break; - -#ifdef DIAGNOSTICS -		case 'D': -			/* -			 * Check for desired diagnostics capabilities. -			 */ -			if (!strcmp(optarg, "report")) { -				diagnostic |= TD_REPORT|TD_OPTIONS; -			} else if (!strcmp(optarg, "exercise")) { -				diagnostic |= TD_EXERCISE; -			} else if (!strcmp(optarg, "netdata")) { -				diagnostic |= TD_NETDATA; -			} else if (!strcmp(optarg, "ptydata")) { -				diagnostic |= TD_PTYDATA; -			} else if (!strcmp(optarg, "options")) { -				diagnostic |= TD_OPTIONS; -			} else { -				usage(); -				/* NOT REACHED */ -			} -			break; -#endif /* DIAGNOSTICS */ - -#ifdef	ENCRYPTION -		case 'e': -			if (strcmp(optarg, "debug") == 0) { -				extern int encrypt_debug_mode; -				encrypt_debug_mode = 1; -				break; -			} -			usage(); -			/* NOTREACHED */ -			break; -#endif	/* ENCRYPTION */ - -		case 'h': -			hostinfo = 0; -			break; - -#if	defined(CRAY) && defined(NEWINIT) -		case 'I': -		    { -			extern char *gen_id; -			gen_id = optarg; -			break; -		    } -#endif	/* defined(CRAY) && defined(NEWINIT) */ - -#ifdef	LINEMODE -		case 'l': -			alwayslinemode = 1; -			break; -#endif	/* LINEMODE */ - -		case 'k': -#if	defined(LINEMODE) && defined(KLUDGELINEMODE) -			lmodetype = NO_AUTOKLUDGE; -#else -			/* ignore -k option if built without kludge linemode */ -#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */ -			break; - -		case 'n': -			keepalive = 0; -			break; - -#ifdef CRAY -		case 'r': -		    { -			char *strchr(); -			char *c; - -			/* -			 * Allow the specification of alterations -			 * to the pty search range.  It is legal to -			 * specify only one, and not change the -			 * other from its default. -			 */ -			c = strchr(optarg, '-'); -			if (c) { -				*c++ = '\0'; -				highpty = atoi(c); -			} -			if (*optarg != '\0') -				lowpty = atoi(optarg); -			if ((lowpty > highpty) || (lowpty < 0) || -							(highpty > 32767)) { -				usage(); -				/* NOT REACHED */ -			} -			break; -		    } -#endif	/* CRAY */ - -#ifdef	SecurID -		case 's': -			/* SecurID required */ -			require_SecurID = 1; -			break; -#endif	/* SecurID */ -		case 'S': -#ifdef	HAS_GETTOS -			if ((tos = parsetos(optarg, "tcp")) < 0) -				fprintf(stderr, "%s%s%s\n", -					"telnetd: Bad TOS argument '", optarg, -					"'; will try to use default TOS"); -#else -			fprintf(stderr, "%s%s\n", "TOS option unavailable; ", -						"-S flag not supported\n"); -#endif -			break; - -		case 'u': -			utmp_len = atoi(optarg); -			break; - -		case 'U': -			registerd_host_only = 1; -			break; - -#ifdef	AUTHENTICATION -		case 'X': -			/* -			 * Check for invalid authentication types -			 */ -			auth_disable_name(optarg); -			break; -#endif	/* AUTHENTICATION */ - -		default: -			fprintf(stderr, "telnetd: %c: unknown option\n", ch); -			/* FALLTHROUGH */ -		case '?': -			usage(); -			/* NOTREACHED */ -		} -	} - -	argc -= optind; -	argv += optind; - -	if (debug) { -	    int s, ns, foo; -	    struct servent *sp; -	    static struct sockaddr_in sin = { AF_INET }; - -	    if (argc > 1) { -		usage(); -		/* NOT REACHED */ -	    } else if (argc == 1) { -		    if (sp = getservbyname(*argv, "tcp")) { -			sin.sin_port = sp->s_port; -		    } else { -			sin.sin_port = atoi(*argv); -			if ((int)sin.sin_port <= 0) { -			    fprintf(stderr, "telnetd: %s: bad port #\n", *argv); -			    usage(); -			    /* NOT REACHED */ -			} -			sin.sin_port = htons((u_short)sin.sin_port); -		   } -	    } else { -		sp = getservbyname("telnet", "tcp"); -		if (sp == 0) { -		    fprintf(stderr, "telnetd: tcp/telnet: unknown service\n"); -		    exit(1); -		} -		sin.sin_port = sp->s_port; -	    } - -	    s = socket(AF_INET, SOCK_STREAM, 0); -	    if (s < 0) { -		    perror("telnetd: socket");; -		    exit(1); -	    } -	    (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, -				(char *)&on, sizeof(on)); -	    if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0) { -		perror("bind"); -		exit(1); -	    } -	    if (listen(s, 1) < 0) { -		perror("listen"); -		exit(1); -	    } -	    foo = sizeof sin; -	    ns = accept(s, (struct sockaddr *)&sin, &foo); -	    if (ns < 0) { -		perror("accept"); -		exit(1); -	    } -	    (void) dup2(ns, 0); -	    (void) close(ns); -	    (void) close(s); -#ifdef convex -	} else if (argc == 1) { -		; /* VOID*/		/* Just ignore the host/port name */ -#endif -	} else if (argc > 0) { -		usage(); -		/* NOT REACHED */ -	} - -#if	defined(_SC_CRAY_SECURE_SYS) -	secflag = sysconf(_SC_CRAY_SECURE_SYS); - -	/* -	 *	Get socket's security label -	 */ -	if (secflag)  { -		int szss = sizeof(ss); -#ifdef SO_SEC_MULTI			/* 8.0 code */ -		int sock_multi; -		int szi = sizeof(int); -#endif /* SO_SEC_MULTI */ - -		bzero((char *)&dv, sizeof(dv)); - -		if (getsysv(&sysv, sizeof(struct sysv)) != 0) { -			perror("getsysv"); -			exit(1); -		} - -		/* -		 *	Get socket security label and set device values -		 *	   {security label to be set on ttyp device} -		 */ -#ifdef SO_SEC_MULTI			/* 8.0 code */ -		if ((getsockopt(0, SOL_SOCKET, SO_SECURITY, -			       (char *)&ss, &szss) < 0) || -		    (getsockopt(0, SOL_SOCKET, SO_SEC_MULTI, -				(char *)&sock_multi, &szi) < 0)) { -			perror("getsockopt"); -			exit(1); -		} else { -			dv.dv_actlvl = ss.ss_actlabel.lt_level; -			dv.dv_actcmp = ss.ss_actlabel.lt_compart; -			if (!sock_multi) { -				dv.dv_minlvl = dv.dv_maxlvl = dv.dv_actlvl; -				dv.dv_valcmp = dv.dv_actcmp; -			} else { -				dv.dv_minlvl = ss.ss_minlabel.lt_level; -				dv.dv_maxlvl = ss.ss_maxlabel.lt_level; -				dv.dv_valcmp = ss.ss_maxlabel.lt_compart; -			} -			dv.dv_devflg = 0; -		} -#else /* SO_SEC_MULTI */		/* 7.0 code */ -		if (getsockopt(0, SOL_SOCKET, SO_SECURITY, -				(char *)&ss, &szss) >= 0) { -			dv.dv_actlvl = ss.ss_slevel; -			dv.dv_actcmp = ss.ss_compart; -			dv.dv_minlvl = ss.ss_minlvl; -			dv.dv_maxlvl = ss.ss_maxlvl; -			dv.dv_valcmp = ss.ss_maxcmp; -		} -#endif /* SO_SEC_MULTI */ -	} -#endif	/* _SC_CRAY_SECURE_SYS */ - -	openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON); -	fromlen = sizeof (from); -	if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) { -		fprintf(stderr, "%s: ", progname); -		perror("getpeername"); -		_exit(1); -	} -	if (keepalive && -	    setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, -			(char *)&on, sizeof (on)) < 0) { -		syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); -	} - -#if	defined(IPPROTO_IP) && defined(IP_TOS) -	{ -# if	defined(HAS_GETTOS) -		struct tosent *tp; -		if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) -			tos = tp->t_tos; -# endif -		if (tos < 0) -			tos = 020;	/* Low Delay bit */ -		if (tos -		   && (setsockopt(0, IPPROTO_IP, IP_TOS, -				  (char *)&tos, sizeof(tos)) < 0) -		   && (errno != ENOPROTOOPT) ) -			syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); -	} -#endif	/* defined(IPPROTO_IP) && defined(IP_TOS) */ -	net = 0; -	doit(&from); -	/* NOTREACHED */ -}  /* end of main */ - -	void -usage() -{ -	fprintf(stderr, "Usage: telnetd"); -#ifdef	AUTHENTICATION -	fprintf(stderr, " [-a (debug|other|user|valid|off|none)]\n\t"); -#endif -#ifdef BFTPDAEMON -	fprintf(stderr, " [-B]"); -#endif -	fprintf(stderr, " [-debug]"); -#ifdef DIAGNOSTICS -	fprintf(stderr, " [-D (options|report|exercise|netdata|ptydata)]\n\t"); -#endif -#ifdef	AUTHENTICATION -	fprintf(stderr, " [-edebug]"); -#endif -	fprintf(stderr, " [-h]"); -#if	defined(CRAY) && defined(NEWINIT) -	fprintf(stderr, " [-Iinitid]"); -#endif -#if	defined(LINEMODE) && defined(KLUDGELINEMODE) -	fprintf(stderr, " [-k]"); -#endif -#ifdef LINEMODE -	fprintf(stderr, " [-l]"); -#endif -	fprintf(stderr, " [-n]"); -#ifdef	CRAY -	fprintf(stderr, " [-r[lowpty]-[highpty]]"); -#endif -	fprintf(stderr, "\n\t"); -#ifdef	SecurID -	fprintf(stderr, " [-s]"); -#endif -#ifdef	HAS_GETTOS -	fprintf(stderr, " [-S tos]"); -#endif -#ifdef	AUTHENTICATION -	fprintf(stderr, " [-X auth-type]"); -#endif -	fprintf(stderr, " [-u utmp_hostname_length] [-U]"); -	fprintf(stderr, " [port]\n"); -	exit(1); -} - -/* - * getterminaltype - * - *	Ask the other end to send along its terminal type and speed. - * Output is the variable terminaltype filled in. - */ -static unsigned char ttytype_sbbuf[] = { -	IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE -}; - -    int -getterminaltype(name) -    char *name; -{ -    int retval = -1; -    void _gettermname(); - -    settimer(baseline); -#if	defined(AUTHENTICATION) -    /* -     * Handle the Authentication option before we do anything else. -     */ -    send_do(TELOPT_AUTHENTICATION, 1); -    while (his_will_wont_is_changing(TELOPT_AUTHENTICATION)) -	ttloop(); -    if (his_state_is_will(TELOPT_AUTHENTICATION)) { -	retval = auth_wait(name); -    } -#endif - -#ifdef	ENCRYPTION -    send_will(TELOPT_ENCRYPT, 1); -#endif	/* ENCRYPTION */ -    send_do(TELOPT_TTYPE, 1); -    send_do(TELOPT_TSPEED, 1); -    send_do(TELOPT_XDISPLOC, 1); -    send_do(TELOPT_NEW_ENVIRON, 1); -    send_do(TELOPT_OLD_ENVIRON, 1); -    while ( -#ifdef	ENCRYPTION -	   his_do_dont_is_changing(TELOPT_ENCRYPT) || -#endif	/* ENCRYPTION */ -	   his_will_wont_is_changing(TELOPT_TTYPE) || -	   his_will_wont_is_changing(TELOPT_TSPEED) || -	   his_will_wont_is_changing(TELOPT_XDISPLOC) || -	   his_will_wont_is_changing(TELOPT_NEW_ENVIRON) || -	   his_will_wont_is_changing(TELOPT_OLD_ENVIRON)) { -	ttloop(); -    } -#ifdef	ENCRYPTION -    /* -     * Wait for the negotiation of what type of encryption we can -     * send with.  If autoencrypt is not set, this will just return. -     */ -    if (his_state_is_will(TELOPT_ENCRYPT)) { -	encrypt_wait(); -    } -#endif	/* ENCRYPTION */ -    if (his_state_is_will(TELOPT_TSPEED)) { -	static unsigned char sb[] = -			{ IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE }; - -	bcopy(sb, nfrontp, sizeof sb); -	nfrontp += sizeof sb; -    } -    if (his_state_is_will(TELOPT_XDISPLOC)) { -	static unsigned char sb[] = -			{ IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE }; - -	bcopy(sb, nfrontp, sizeof sb); -	nfrontp += sizeof sb; -    } -    if (his_state_is_will(TELOPT_NEW_ENVIRON)) { -	static unsigned char sb[] = -			{ IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE }; - -	bcopy(sb, nfrontp, sizeof sb); -	nfrontp += sizeof sb; -    } -    else if (his_state_is_will(TELOPT_OLD_ENVIRON)) { -	static unsigned char sb[] = -			{ IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE }; - -	bcopy(sb, nfrontp, sizeof sb); -	nfrontp += sizeof sb; -    } -    if (his_state_is_will(TELOPT_TTYPE)) { - -	bcopy(ttytype_sbbuf, nfrontp, sizeof ttytype_sbbuf); -	nfrontp += sizeof ttytype_sbbuf; -    } -    if (his_state_is_will(TELOPT_TSPEED)) { -	while (sequenceIs(tspeedsubopt, baseline)) -	    ttloop(); -    } -    if (his_state_is_will(TELOPT_XDISPLOC)) { -	while (sequenceIs(xdisplocsubopt, baseline)) -	    ttloop(); -    } -    if (his_state_is_will(TELOPT_NEW_ENVIRON)) { -	while (sequenceIs(environsubopt, baseline)) -	    ttloop(); -    } -    if (his_state_is_will(TELOPT_OLD_ENVIRON)) { -	while (sequenceIs(oenvironsubopt, baseline)) -	    ttloop(); -    } -    if (his_state_is_will(TELOPT_TTYPE)) { -	char first[256], last[256]; - -	while (sequenceIs(ttypesubopt, baseline)) -	    ttloop(); - -	/* -	 * If the other side has already disabled the option, then -	 * we have to just go with what we (might) have already gotten. -	 */ -	if (his_state_is_will(TELOPT_TTYPE) && !terminaltypeok(terminaltype)) { -	    (void) strncpy(first, terminaltype, sizeof(first)); -	    for(;;) { -		/* -		 * Save the unknown name, and request the next name. -		 */ -		(void) strncpy(last, terminaltype, sizeof(last)); -		_gettermname(); -		if (terminaltypeok(terminaltype)) -		    break; -		if ((strncmp(last, terminaltype, sizeof(last)) == 0) || -		    his_state_is_wont(TELOPT_TTYPE)) { -		    /* -		     * We've hit the end.  If this is the same as -		     * the first name, just go with it. -		     */ -		    if (strncmp(first, terminaltype, sizeof(first)) == 0) -			break; -		    /* -		     * Get the terminal name one more time, so that -		     * RFC1091 compliant telnets will cycle back to -		     * the start of the list. -		     */ -		     _gettermname(); -		    if (strncmp(first, terminaltype, sizeof(first)) != 0) -			(void) strncpy(terminaltype, first, sizeof(first)); -		    break; -		} -	    } -	} -    } -    return(retval); -}  /* end of getterminaltype */ - -    void -_gettermname() -{ -    /* -     * If the client turned off the option, -     * we can't send another request, so we -     * just return. -     */ -    if (his_state_is_wont(TELOPT_TTYPE)) -	return; -    settimer(baseline); -    bcopy(ttytype_sbbuf, nfrontp, sizeof ttytype_sbbuf); -    nfrontp += sizeof ttytype_sbbuf; -    while (sequenceIs(ttypesubopt, baseline)) -	ttloop(); -} - -    int -terminaltypeok(s) -    char *s; -{ -    char buf[1024]; - -    if (terminaltype == NULL) -	return(1); - -    /* -     * tgetent() will return 1 if the type is known, and -     * 0 if it is not known.  If it returns -1, it couldn't -     * open the database.  But if we can't open the database, -     * it won't help to say we failed, because we won't be -     * able to verify anything else.  So, we treat -1 like 1. -     */ -    if (tgetent(buf, s) == 0) -	return(0); -    return(1); -} - -#ifndef	MAXHOSTNAMELEN -#define	MAXHOSTNAMELEN 64 -#endif	/* MAXHOSTNAMELEN */ - -char *hostname; -char host_name[MAXHOSTNAMELEN]; -char remote_host_name[MAXHOSTNAMELEN]; - -#ifndef	convex -extern void telnet P((int, int)); -#else -extern void telnet P((int, int, char *)); -#endif - -/* - * Get a pty, scan input lines. - */ -doit(who) -	struct sockaddr_in *who; -{ -	char *host, *inet_ntoa(); -	int t; -	struct hostent *hp; -	int level; -	int ptynum; -	char user_name[256]; - -	/* -	 * Find an available pty to use. -	 */ -#ifndef	convex -	pty = getpty(&ptynum); -	if (pty < 0) -		fatal(net, "All network ports in use"); -#else -	for (;;) { -		char *lp; -		extern char *line, *getpty(); - -		if ((lp = getpty()) == NULL) -			fatal(net, "Out of ptys"); - -		if ((pty = open(lp, 2)) >= 0) { -			strcpy(line,lp); -			line[5] = 't'; -			break; -		} -	} -#endif - -#if	defined(_SC_CRAY_SECURE_SYS) -	/* -	 *	set ttyp line security label  -	 */ -	if (secflag) { -		char slave_dev[16]; - -		sprintf(tty_dev, "/dev/pty/%03d", ptynum); -		if (setdevs(tty_dev, &dv) < 0) -		 	fatal(net, "cannot set pty security"); -		sprintf(slave_dev, "/dev/ttyp%03d", ptynum); -		if (setdevs(slave_dev, &dv) < 0) -		 	fatal(net, "cannot set tty security"); -	} -#endif	/* _SC_CRAY_SECURE_SYS */ - -	/* get name of connected client */ -	hp = gethostbyaddr((char *)&who->sin_addr, sizeof (struct in_addr), -		who->sin_family); - -	if (hp == NULL && registerd_host_only) { -		fatal(net, "Couldn't resolve your address into a host name.\r\n\ -         Please contact your net administrator"); -	} else if (hp && -	    (strlen(hp->h_name) <= ((utmp_len < 0) ? -utmp_len : utmp_len))) { -		host = hp->h_name; -	} else { -		host = inet_ntoa(who->sin_addr); -	} -	/* -	 * We must make a copy because Kerberos is probably going -	 * to also do a gethost* and overwrite the static data... -	 */ -	strncpy(remote_host_name, host, sizeof(remote_host_name)-1); -	remote_host_name[sizeof(remote_host_name)-1] = 0; -	host = remote_host_name; - -	(void) gethostname(host_name, sizeof (host_name)); -	hostname = host_name; - -#if	defined(AUTHENTICATION) || defined(ENCRYPTION) -	auth_encrypt_init(hostname, host, "TELNETD", 1); -#endif - -	init_env(); -	/* -	 * get terminal type. -	 */ -	*user_name = 0; -	level = getterminaltype(user_name); -	setenv("TERM", terminaltype ? terminaltype : "network", 1); - -	/* -	 * Start up the login process on the slave side of the terminal -	 */ -#ifndef	convex -	startslave(host, level, user_name); - -#if	defined(_SC_CRAY_SECURE_SYS) -	if (secflag) { -		if (setulvl(dv.dv_actlvl) < 0) -			fatal(net,"cannot setulvl()"); -		if (setucmp(dv.dv_actcmp) < 0) -			fatal(net, "cannot setucmp()"); -	} -#endif	/* _SC_CRAY_SECURE_SYS */ - -	telnet(net, pty);  /* begin server processing */ -#else -	telnet(net, pty, host); -#endif -	/*NOTREACHED*/ -}  /* end of doit */ - -#if	defined(CRAY2) && defined(UNICOS5) && defined(UNICOS50) -	int -Xterm_output(ibufp, obuf, icountp, ocount) -	char **ibufp, *obuf; -	int *icountp, ocount; -{ -	int ret; -	ret = term_output(*ibufp, obuf, *icountp, ocount); -	*ibufp += *icountp; -	*icountp = 0; -	return(ret); -} -#define	term_output	Xterm_output -#endif	/* defined(CRAY2) && defined(UNICOS5) && defined(UNICOS50) */ - -/* - * Main loop.  Select from pty and network, and - * hand data to telnet receiver finite state machine. - */ -	void -#ifndef	convex -telnet(f, p) -#else -telnet(f, p, host) -#endif -	int f, p; -#ifdef convex -	char *host; -#endif -{ -	int on = 1; -#define	TABBUFSIZ	512 -	char	defent[TABBUFSIZ]; -	char	defstrs[TABBUFSIZ]; -#undef	TABBUFSIZ -	char *HE; -	char *HN; -	char *IM; -	void netflush(); - -	/* -	 * Initialize the slc mapping table. -	 */ -	get_slc_defaults(); - -	/* -	 * Do some tests where it is desireable to wait for a response. -	 * Rather than doing them slowly, one at a time, do them all -	 * at once. -	 */ -	if (my_state_is_wont(TELOPT_SGA)) -		send_will(TELOPT_SGA, 1); -	/* -	 * Is the client side a 4.2 (NOT 4.3) system?  We need to know this -	 * because 4.2 clients are unable to deal with TCP urgent data. -	 * -	 * To find out, we send out a "DO ECHO".  If the remote system -	 * answers "WILL ECHO" it is probably a 4.2 client, and we note -	 * that fact ("WILL ECHO" ==> that the client will echo what -	 * WE, the server, sends it; it does NOT mean that the client will -	 * echo the terminal input). -	 */ -	send_do(TELOPT_ECHO, 1); - -#ifdef	LINEMODE -	if (his_state_is_wont(TELOPT_LINEMODE)) { -		/* Query the peer for linemode support by trying to negotiate -		 * the linemode option. -		 */ -		linemode = 0; -		editmode = 0; -		send_do(TELOPT_LINEMODE, 1);  /* send do linemode */ -	} -#endif	/* LINEMODE */ - -	/* -	 * Send along a couple of other options that we wish to negotiate. -	 */ -	send_do(TELOPT_NAWS, 1); -	send_will(TELOPT_STATUS, 1); -	flowmode = 1;		/* default flow control state */ -	restartany = -1;	/* uninitialized... */ -	send_do(TELOPT_LFLOW, 1); - -	/* -	 * Spin, waiting for a response from the DO ECHO.  However, -	 * some REALLY DUMB telnets out there might not respond -	 * to the DO ECHO.  So, we spin looking for NAWS, (most dumb -	 * telnets so far seem to respond with WONT for a DO that -	 * they don't understand...) because by the time we get the -	 * response, it will already have processed the DO ECHO. -	 * Kludge upon kludge. -	 */ -	while (his_will_wont_is_changing(TELOPT_NAWS)) -		ttloop(); - -	/* -	 * But... -	 * The client might have sent a WILL NAWS as part of its -	 * startup code; if so, we'll be here before we get the -	 * response to the DO ECHO.  We'll make the assumption -	 * that any implementation that understands about NAWS -	 * is a modern enough implementation that it will respond -	 * to our DO ECHO request; hence we'll do another spin -	 * waiting for the ECHO option to settle down, which is -	 * what we wanted to do in the first place... -	 */ -	if (his_want_state_is_will(TELOPT_ECHO) && -	    his_state_is_will(TELOPT_NAWS)) { -		while (his_will_wont_is_changing(TELOPT_ECHO)) -			ttloop(); -	} -	/* -	 * On the off chance that the telnet client is broken and does not -	 * respond to the DO ECHO we sent, (after all, we did send the -	 * DO NAWS negotiation after the DO ECHO, and we won't get here -	 * until a response to the DO NAWS comes back) simulate the -	 * receipt of a will echo.  This will also send a WONT ECHO -	 * to the client, since we assume that the client failed to -	 * respond because it believes that it is already in DO ECHO -	 * mode, which we do not want. -	 */ -	if (his_want_state_is_will(TELOPT_ECHO)) { -		DIAG(TD_OPTIONS, -			{sprintf(nfrontp, "td: simulating recv\r\n"); -			 nfrontp += strlen(nfrontp);}); -		willoption(TELOPT_ECHO); -	} - -	/* -	 * Finally, to clean things up, we turn on our echo.  This -	 * will break stupid 4.2 telnets out of local terminal echo. -	 */ - -	if (my_state_is_wont(TELOPT_ECHO)) -		send_will(TELOPT_ECHO, 1); - -#ifndef	STREAMSPTY -	/* -	 * Turn on packet mode -	 */ -	(void) ioctl(p, TIOCPKT, (char *)&on); -#endif - -#if	defined(LINEMODE) && defined(KLUDGELINEMODE) -	/* -	 * Continuing line mode support.  If client does not support -	 * real linemode, attempt to negotiate kludge linemode by sending -	 * the do timing mark sequence. -	 */ -	if (lmodetype < REAL_LINEMODE) -		send_do(TELOPT_TM, 1); -#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */ - -	/* -	 * Call telrcv() once to pick up anything received during -	 * terminal type negotiation, 4.2/4.3 determination, and -	 * linemode negotiation. -	 */ -	telrcv(); - -	(void) ioctl(f, FIONBIO, (char *)&on); -	(void) ioctl(p, FIONBIO, (char *)&on); -#if	defined(CRAY2) && defined(UNICOS5) -	init_termdriver(f, p, interrupt, sendbrk); -#endif - -#if	defined(SO_OOBINLINE) -	(void) setsockopt(net, SOL_SOCKET, SO_OOBINLINE, -				(char *)&on, sizeof on); -#endif	/* defined(SO_OOBINLINE) */ - -#ifdef	SIGTSTP -	(void) signal(SIGTSTP, SIG_IGN); -#endif -#ifdef	SIGTTOU -	/* -	 * Ignoring SIGTTOU keeps the kernel from blocking us -	 * in ttioct() in /sys/tty.c. -	 */ -	(void) signal(SIGTTOU, SIG_IGN); -#endif - -	(void) signal(SIGCHLD, cleanup); - -#if	defined(CRAY2) && defined(UNICOS5) -	/* -	 * Cray-2 will send a signal when pty modes are changed by slave -	 * side.  Set up signal handler now. -	 */ -	if ((int)signal(SIGUSR1, termstat) < 0) -		perror("signal"); -	else if (ioctl(p, TCSIGME, (char *)SIGUSR1) < 0) -		perror("ioctl:TCSIGME"); -	/* -	 * Make processing loop check terminal characteristics early on. -	 */ -	termstat(); -#endif - -#ifdef  TIOCNOTTY -	{ -		register int t; -		t = open(_PATH_TTY, O_RDWR); -		if (t >= 0) { -			(void) ioctl(t, TIOCNOTTY, (char *)0); -			(void) close(t); -		} -	} -#endif - -#if	defined(CRAY) && defined(NEWINIT) && defined(TIOCSCTTY) -	(void) setsid(); -	ioctl(p, TIOCSCTTY, 0); -#endif - -	/* -	 * Show banner that getty never gave. -	 * -	 * We put the banner in the pty input buffer.  This way, it -	 * gets carriage return null processing, etc., just like all -	 * other pty --> client data. -	 */ - -#if	!defined(CRAY) || !defined(NEWINIT) -	if (getenv("USER")) -		hostinfo = 0; -#endif - -	if (getent(defent, "default") == 1) { -		char *getstr(); -		char *cp=defstrs; - -		HE = getstr("he", &cp); -		HN = getstr("hn", &cp); -		IM = getstr("im", &cp); -		if (HN && *HN) -			(void) strcpy(host_name, HN); -		if (IM == 0) -			IM = ""; -	} else { -		IM = DEFAULT_IM; -		HE = 0; -	} -	edithost(HE, host_name); -	if (hostinfo && *IM) -		putf(IM, ptyibuf2); - -	if (pcc) -		(void) strncat(ptyibuf2, ptyip, pcc+1); -	ptyip = ptyibuf2; -	pcc = strlen(ptyip); -#ifdef	LINEMODE -	/* -	 * Last check to make sure all our states are correct. -	 */ -	init_termbuf(); -	localstat(); -#endif	/* LINEMODE */ - -	DIAG(TD_REPORT, -		{sprintf(nfrontp, "td: Entering processing loop\r\n"); -		 nfrontp += strlen(nfrontp);}); - -#ifdef	convex -	startslave(host); -#endif - -	for (;;) { -		fd_set ibits, obits, xbits; -		register int c; - -		if (ncc < 0 && pcc < 0) -			break; - -#if	defined(CRAY2) && defined(UNICOS5) -		if (needtermstat) -			_termstat(); -#endif	/* defined(CRAY2) && defined(UNICOS5) */ -		FD_ZERO(&ibits); -		FD_ZERO(&obits); -		FD_ZERO(&xbits); -		/* -		 * Never look for input if there's still -		 * stuff in the corresponding output buffer -		 */ -		if (nfrontp - nbackp || pcc > 0) { -			FD_SET(f, &obits); -		} else { -			FD_SET(p, &ibits); -		} -		if (pfrontp - pbackp || ncc > 0) { -			FD_SET(p, &obits); -		} else { -			FD_SET(f, &ibits); -		} -		if (!SYNCHing) { -			FD_SET(f, &xbits); -		} -		if ((c = select(16, &ibits, &obits, &xbits, -						(struct timeval *)0)) < 1) { -			if (c == -1) { -				if (errno == EINTR) { -					continue; -				} -			} -			sleep(5); -			continue; -		} - -		/* -		 * Any urgent data? -		 */ -		if (FD_ISSET(net, &xbits)) { -		    SYNCHing = 1; -		} - -		/* -		 * Something to read from the network... -		 */ -		if (FD_ISSET(net, &ibits)) { -#if	!defined(SO_OOBINLINE) -			/* -			 * In 4.2 (and 4.3 beta) systems, the -			 * OOB indication and data handling in the kernel -			 * is such that if two separate TCP Urgent requests -			 * come in, one byte of TCP data will be overlaid. -			 * This is fatal for Telnet, but we try to live -			 * with it. -			 * -			 * In addition, in 4.2 (and...), a special protocol -			 * is needed to pick up the TCP Urgent data in -			 * the correct sequence. -			 * -			 * What we do is:  if we think we are in urgent -			 * mode, we look to see if we are "at the mark". -			 * If we are, we do an OOB receive.  If we run -			 * this twice, we will do the OOB receive twice, -			 * but the second will fail, since the second -			 * time we were "at the mark", but there wasn't -			 * any data there (the kernel doesn't reset -			 * "at the mark" until we do a normal read). -			 * Once we've read the OOB data, we go ahead -			 * and do normal reads. -			 * -			 * There is also another problem, which is that -			 * since the OOB byte we read doesn't put us -			 * out of OOB state, and since that byte is most -			 * likely the TELNET DM (data mark), we would -			 * stay in the TELNET SYNCH (SYNCHing) state. -			 * So, clocks to the rescue.  If we've "just" -			 * received a DM, then we test for the -			 * presence of OOB data when the receive OOB -			 * fails (and AFTER we did the normal mode read -			 * to clear "at the mark"). -			 */ -		    if (SYNCHing) { -			int atmark; - -			(void) ioctl(net, SIOCATMARK, (char *)&atmark); -			if (atmark) { -			    ncc = recv(net, netibuf, sizeof (netibuf), MSG_OOB); -			    if ((ncc == -1) && (errno == EINVAL)) { -				ncc = read(net, netibuf, sizeof (netibuf)); -				if (sequenceIs(didnetreceive, gotDM)) { -				    SYNCHing = stilloob(net); -				} -			    } -			} else { -			    ncc = read(net, netibuf, sizeof (netibuf)); -			} -		    } else { -			ncc = read(net, netibuf, sizeof (netibuf)); -		    } -		    settimer(didnetreceive); -#else	/* !defined(SO_OOBINLINE)) */ -		    ncc = read(net, netibuf, sizeof (netibuf)); -#endif	/* !defined(SO_OOBINLINE)) */ -		    if (ncc < 0 && errno == EWOULDBLOCK) -			ncc = 0; -		    else { -			if (ncc <= 0) { -			    break; -			} -			netip = netibuf; -		    } -		    DIAG((TD_REPORT | TD_NETDATA), -			    {sprintf(nfrontp, "td: netread %d chars\r\n", ncc); -			     nfrontp += strlen(nfrontp);}); -		    DIAG(TD_NETDATA, printdata("nd", netip, ncc)); -		} - -		/* -		 * Something to read from the pty... -		 */ -		if (FD_ISSET(p, &ibits)) { -#ifndef	STREAMSPTY -			pcc = read(p, ptyibuf, BUFSIZ); -#else -			pcc = readstream(p, ptyibuf, BUFSIZ); -#endif -			/* -			 * On some systems, if we try to read something -			 * off the master side before the slave side is -			 * opened, we get EIO. -			 */ -			if (pcc < 0 && (errno == EWOULDBLOCK || -#ifdef	EAGAIN -					errno == EAGAIN || -#endif -					errno == EIO)) { -				pcc = 0; -			} else { -				if (pcc <= 0) -					break; -#if	!defined(CRAY2) || !defined(UNICOS5) -#ifdef	LINEMODE -				/* -				 * If ioctl from pty, pass it through net -				 */ -				if (ptyibuf[0] & TIOCPKT_IOCTL) { -					copy_termbuf(ptyibuf+1, pcc-1); -					localstat(); -					pcc = 1; -				} -#endif	/* LINEMODE */ -				if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) { -					netclear();	/* clear buffer back */ -#ifndef	NO_URGENT -					/* -					 * There are client telnets on some -					 * operating systems get screwed up -					 * royally if we send them urgent -					 * mode data. -					 */ -					*nfrontp++ = IAC; -					*nfrontp++ = DM; -					neturg = nfrontp-1; /* off by one XXX */ -#endif -				} -				if (his_state_is_will(TELOPT_LFLOW) && -				    (ptyibuf[0] & -				     (TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))) { -					int newflow = -					    ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0; -					if (newflow != flowmode) { -						flowmode = newflow; -						(void) sprintf(nfrontp, -							"%c%c%c%c%c%c", -							IAC, SB, TELOPT_LFLOW, -							flowmode ? LFLOW_ON -								 : LFLOW_OFF, -							IAC, SE); -						nfrontp += 6; -					} -				} -				pcc--; -				ptyip = ptyibuf+1; -#else	/* defined(CRAY2) && defined(UNICOS5) */ -				if (!uselinemode) { -					unpcc = pcc; -					unptyip = ptyibuf; -					pcc = term_output(&unptyip, ptyibuf2, -								&unpcc, BUFSIZ); -					ptyip = ptyibuf2; -				} else -					ptyip = ptyibuf; -#endif	/* defined(CRAY2) && defined(UNICOS5) */ -			} -		} - -		while (pcc > 0) { -			if ((&netobuf[BUFSIZ] - nfrontp) < 2) -				break; -			c = *ptyip++ & 0377, pcc--; -			if (c == IAC) -				*nfrontp++ = c; -#if	defined(CRAY2) && defined(UNICOS5) -			else if (c == '\n' && -				     my_state_is_wont(TELOPT_BINARY) && newmap) -				*nfrontp++ = '\r'; -#endif	/* defined(CRAY2) && defined(UNICOS5) */ -			*nfrontp++ = c; -			if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) { -				if (pcc > 0 && ((*ptyip & 0377) == '\n')) { -					*nfrontp++ = *ptyip++ & 0377; -					pcc--; -				} else -					*nfrontp++ = '\0'; -			} -		} -#if	defined(CRAY2) && defined(UNICOS5) -		/* -		 * If chars were left over from the terminal driver, -		 * note their existence. -		 */ -		if (!uselinemode && unpcc) { -			pcc = unpcc; -			unpcc = 0; -			ptyip = unptyip; -		} -#endif	/* defined(CRAY2) && defined(UNICOS5) */ - -		if (FD_ISSET(f, &obits) && (nfrontp - nbackp) > 0) -			netflush(); -		if (ncc > 0) -			telrcv(); -		if (FD_ISSET(p, &obits) && (pfrontp - pbackp) > 0) -			ptyflush(); -	} -	cleanup(0); -}  /* end of telnet */ -	 -#ifndef	TCSIG -# ifdef	TIOCSIG -#  define TCSIG TIOCSIG -# endif -#endif - -#ifdef	STREAMSPTY - -int flowison = -1;  /* current state of flow: -1 is unknown */ - -int readstream(p, ibuf, bufsize) -	int p; -	char *ibuf; -	int bufsize; -{ -	int flags = 0; -	int ret = 0; -	struct termios *tsp; -	struct termio *tp; -	struct iocblk *ip; -	char vstop, vstart; -	int ixon; -	int newflow; - -	strbufc.maxlen = BUFSIZ; -	strbufc.buf = (char *)ctlbuf; -	strbufd.maxlen = bufsize-1; -	strbufd.len = 0; -	strbufd.buf = ibuf+1; -	ibuf[0] = 0; - -	ret = getmsg(p, &strbufc, &strbufd, &flags); -	if (ret < 0)  /* error of some sort -- probably EAGAIN */ -		return(-1); - -	if (strbufc.len <= 0 || ctlbuf[0] == M_DATA) { -		/* data message */ -		if (strbufd.len > 0) {			/* real data */ -			return(strbufd.len + 1);	/* count header char */ -		} else { -			/* nothing there */ -			errno = EAGAIN; -			return(-1); -		} -	} - -	/* -	 * It's a control message.  Return 1, to look at the flag we set -	 */ - -	switch (ctlbuf[0]) { -	case M_FLUSH: -		if (ibuf[1] & FLUSHW) -			ibuf[0] = TIOCPKT_FLUSHWRITE; -		return(1); - -	case M_IOCTL: -		ip = (struct iocblk *) (ibuf+1); - -		switch (ip->ioc_cmd) { -		case TCSETS: -		case TCSETSW: -		case TCSETSF: -			tsp = (struct termios *) -					(ibuf+1 + sizeof(struct iocblk)); -			vstop = tsp->c_cc[VSTOP]; -			vstart = tsp->c_cc[VSTART]; -			ixon = tsp->c_iflag & IXON; -			break; -		case TCSETA: -		case TCSETAW: -		case TCSETAF: -			tp = (struct termio *) (ibuf+1 + sizeof(struct iocblk)); -			vstop = tp->c_cc[VSTOP]; -			vstart = tp->c_cc[VSTART]; -			ixon = tp->c_iflag & IXON;       -			break; -		default: -			errno = EAGAIN; -			return(-1); -		} - -		newflow =  (ixon && (vstart == 021) && (vstop == 023)) ? 1 : 0; -		if (newflow != flowison) {  /* it's a change */ -			flowison = newflow; -			ibuf[0] = newflow ? TIOCPKT_DOSTOP : TIOCPKT_NOSTOP; -			return(1); -		} -	} - -	/* nothing worth doing anything about */ -	errno = EAGAIN; -	return(-1); -} -#endif /* STREAMSPTY */ - -/* - * Send interrupt to process on other side of pty. - * If it is in raw mode, just write NULL; - * otherwise, write intr char. - */ -	void -interrupt() -{ -	ptyflush();	/* half-hearted */ - -#ifdef	TCSIG -	(void) ioctl(pty, TCSIG, (char *)SIGINT); -#else	/* TCSIG */ -	init_termbuf(); -	*pfrontp++ = slctab[SLC_IP].sptr ? -			(unsigned char)*slctab[SLC_IP].sptr : '\177'; -#endif	/* TCSIG */ -} - -/* - * Send quit to process on other side of pty. - * If it is in raw mode, just write NULL; - * otherwise, write quit char. - */ -	void -sendbrk() -{ -	ptyflush();	/* half-hearted */ -#ifdef	TCSIG -	(void) ioctl(pty, TCSIG, (char *)SIGQUIT); -#else	/* TCSIG */ -	init_termbuf(); -	*pfrontp++ = slctab[SLC_ABORT].sptr ? -			(unsigned char)*slctab[SLC_ABORT].sptr : '\034'; -#endif	/* TCSIG */ -} - -	void -sendsusp() -{ -#ifdef	SIGTSTP -	ptyflush();	/* half-hearted */ -# ifdef	TCSIG -	(void) ioctl(pty, TCSIG, (char *)SIGTSTP); -# else	/* TCSIG */ -	*pfrontp++ = slctab[SLC_SUSP].sptr ? -			(unsigned char)*slctab[SLC_SUSP].sptr : '\032'; -# endif	/* TCSIG */ -#endif	/* SIGTSTP */ -} - -/* - * When we get an AYT, if ^T is enabled, use that.  Otherwise, - * just send back "[Yes]". - */ -	void -recv_ayt() -{ -#if	defined(SIGINFO) && defined(TCSIG) -	if (slctab[SLC_AYT].sptr && *slctab[SLC_AYT].sptr != _POSIX_VDISABLE) { -		(void) ioctl(pty, TCSIG, (char *)SIGINFO); -		return; -	} -#endif -	(void) strcpy(nfrontp, "\r\n[Yes]\r\n"); -	nfrontp += 9; -} - -	void -doeof() -{ -	init_termbuf(); - -#if	defined(LINEMODE) && defined(USE_TERMIO) && (VEOF == VMIN) -	if (!tty_isediting()) { -		extern char oldeofc; -		*pfrontp++ = oldeofc; -		return; -	} -#endif -	*pfrontp++ = slctab[SLC_EOF].sptr ? -			(unsigned char)*slctab[SLC_EOF].sptr : '\004'; -} diff --git a/secure/libexec/telnetd/telnetd.h b/secure/libexec/telnetd/telnetd.h deleted file mode 100644 index 234b9739e758..000000000000 --- a/secure/libexec/telnetd/telnetd.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 1989, 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. - * - *	@(#)telnetd.h	8.1 (Berkeley) 6/4/93 - */ - - -#include "defs.h" -#include "ext.h" - -#ifdef	DIAGNOSTICS -#define	DIAG(a,b)	if (diagnostic & (a)) b -#else -#define	DIAG(a,b) -#endif - -/* other external variables */ -extern	char **environ; -extern	int errno; - diff --git a/secure/libexec/telnetd/termstat.c b/secure/libexec/telnetd/termstat.c deleted file mode 100644 index a3f69312217f..000000000000 --- a/secure/libexec/telnetd/termstat.c +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Copyright (c) 1989, 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. - */ - -#ifndef lint -static char sccsid[] = "@(#)termstat.c	8.1 (Berkeley) 6/4/93"; -#endif /* not lint */ - -#include "telnetd.h" - -/* - * local variables - */ -int def_tspeed = -1, def_rspeed = -1; -#ifdef	TIOCSWINSZ -int def_row = 0, def_col = 0; -#endif -#ifdef	LINEMODE -static int _terminit = 0; -#endif	/* LINEMODE */ - -#if	defined(CRAY2) && defined(UNICOS5) -int	newmap = 1;	/* nonzero if \n maps to ^M^J */ -#endif - -#ifdef	LINEMODE -/* - * localstat - * - * This function handles all management of linemode. - * - * Linemode allows the client to do the local editing of data - * and send only complete lines to the server.  Linemode state is - * based on the state of the pty driver.  If the pty is set for - * external processing, then we can use linemode.  Further, if we - * can use real linemode, then we can look at the edit control bits - * in the pty to determine what editing the client should do. - * - * Linemode support uses the following state flags to keep track of - * current and desired linemode state. - *	alwayslinemode : true if -l was specified on the telnetd - * 	command line.  It means to have linemode on as much as - *	possible. - * - * 	lmodetype: signifies whether the client can - *	handle real linemode, or if use of kludgeomatic linemode - *	is preferred.  It will be set to one of the following: - *		REAL_LINEMODE : use linemode option - *		NO_KLUDGE : don't initiate kludge linemode. - *		KLUDGE_LINEMODE : use kludge linemode - *		NO_LINEMODE : client is ignorant of linemode - * - *	linemode, uselinemode : linemode is true if linemode - *	is currently on, uselinemode is the state that we wish - *	to be in.  If another function wishes to turn linemode - *	on or off, it sets or clears uselinemode. - * - *	editmode, useeditmode : like linemode/uselinemode, but - *	these contain the edit mode states (edit and trapsig). - * - * The state variables correspond to some of the state information - * in the pty. - *	linemode: - *		In real linemode, this corresponds to whether the pty - *		expects external processing of incoming data. - *		In kludge linemode, this more closely corresponds to the - *		whether normal processing is on or not.  (ICANON in - *		system V, or COOKED mode in BSD.) - *		If the -l option was specified (alwayslinemode), then - *		an attempt is made to force external processing on at - *		all times. - * - * The following heuristics are applied to determine linemode - * handling within the server. - *	1) Early on in starting up the server, an attempt is made - *	   to negotiate the linemode option.  If this succeeds - *	   then lmodetype is set to REAL_LINEMODE and all linemode - *	   processing occurs in the context of the linemode option. - *	2) If the attempt to negotiate the linemode option failed, - *	   and the "-k" (don't initiate kludge linemode) isn't set, - *	   then we try to use kludge linemode.  We test for this - *	   capability by sending "do Timing Mark".  If a positive - *	   response comes back, then we assume that the client - *	   understands kludge linemode (ech!) and the - *	   lmodetype flag is set to KLUDGE_LINEMODE. - *	3) Otherwise, linemode is not supported at all and - *	   lmodetype remains set to NO_LINEMODE (which happens - *	   to be 0 for convenience). - *	4) At any time a command arrives that implies a higher - *	   state of linemode support in the client, we move to that - *	   linemode support. - * - * A short explanation of kludge linemode is in order here. - *	1) The heuristic to determine support for kludge linemode - *	   is to send a do timing mark.  We assume that a client - *	   that supports timing marks also supports kludge linemode. - *	   A risky proposition at best. - *	2) Further negotiation of linemode is done by changing the - *	   the server's state regarding SGA.  If server will SGA, - *	   then linemode is off, if server won't SGA, then linemode - *	   is on. - */ -	void -localstat() -{ -	void netflush(); -	int need_will_echo = 0; - -#if	defined(CRAY2) && defined(UNICOS5) -	/* -	 * Keep track of that ol' CR/NL mapping while we're in the -	 * neighborhood. -	 */ -	newmap = tty_isnewmap(); -#endif	/* defined(CRAY2) && defined(UNICOS5) */ - -	/* -	 * Check for state of BINARY options. -	 */ -	if (tty_isbinaryin()) { -		if (his_want_state_is_wont(TELOPT_BINARY)) -			send_do(TELOPT_BINARY, 1); -	} else { -		if (his_want_state_is_will(TELOPT_BINARY)) -			send_dont(TELOPT_BINARY, 1); -	} - -	if (tty_isbinaryout()) { -		if (my_want_state_is_wont(TELOPT_BINARY)) -			send_will(TELOPT_BINARY, 1); -	} else { -		if (my_want_state_is_will(TELOPT_BINARY)) -			send_wont(TELOPT_BINARY, 1); -	} - -	/* -	 * Check for changes to flow control if client supports it. -	 */ -	flowstat(); - -	/* -	 * Check linemode on/off state -	 */ -	uselinemode = tty_linemode(); - -	/* -	 * If alwayslinemode is on, and pty is changing to turn it off, then -	 * force linemode back on. -	 */ -	if (alwayslinemode && linemode && !uselinemode) { -		uselinemode = 1; -		tty_setlinemode(uselinemode); -	} - -#ifdef	ENCRYPTION -	/* -	 * If the terminal is not echoing, but editing is enabled, -	 * something like password input is going to happen, so -	 * if we the other side is not currently sending encrypted -	 * data, ask the other side to start encrypting. -	 */ -	if (his_state_is_will(TELOPT_ENCRYPT)) { -		static int enc_passwd = 0; -		if (uselinemode && !tty_isecho() && tty_isediting() -		    && (enc_passwd == 0) && !decrypt_input) { -			encrypt_send_request_start(); -			enc_passwd = 1; -		} else if (enc_passwd) { -			encrypt_send_request_end(); -			enc_passwd = 0; -		} -	} -#endif	/* ENCRYPTION */ - -	/* -	 * Do echo mode handling as soon as we know what the -	 * linemode is going to be. -	 * If the pty has echo turned off, then tell the client that -	 * the server will echo.  If echo is on, then the server -	 * will echo if in character mode, but in linemode the -	 * client should do local echoing.  The state machine will -	 * not send anything if it is unnecessary, so don't worry -	 * about that here. -	 * -	 * If we need to send the WILL ECHO (because echo is off), -	 * then delay that until after we have changed the MODE. -	 * This way, when the user is turning off both editing -	 * and echo, the client will get editing turned off first. -	 * This keeps the client from going into encryption mode -	 * and then right back out if it is doing auto-encryption -	 * when passwords are being typed. -	 */ -	if (uselinemode) { -		if (tty_isecho()) -			send_wont(TELOPT_ECHO, 1); -		else -			need_will_echo = 1; -#ifdef	KLUDGELINEMODE -		if (lmodetype == KLUDGE_OK) -			lmodetype = KLUDGE_LINEMODE; -#endif -	} - -	/* -	 * If linemode is being turned off, send appropriate -	 * command and then we're all done. -	 */ -	 if (!uselinemode && linemode) { -# ifdef	KLUDGELINEMODE -		if (lmodetype == REAL_LINEMODE) { -# endif	/* KLUDGELINEMODE */ -			send_dont(TELOPT_LINEMODE, 1); -# ifdef	KLUDGELINEMODE -		} else if (lmodetype == KLUDGE_LINEMODE) -			send_will(TELOPT_SGA, 1); -# endif	/* KLUDGELINEMODE */ -		send_will(TELOPT_ECHO, 1); -		linemode = uselinemode; -		goto done; -	} - -# ifdef	KLUDGELINEMODE -	/* -	 * If using real linemode check edit modes for possible later use. -	 * If we are in kludge linemode, do the SGA negotiation. -	 */ -	if (lmodetype == REAL_LINEMODE) { -# endif	/* KLUDGELINEMODE */ -		useeditmode = 0; -		if (tty_isediting()) -			useeditmode |= MODE_EDIT; -		if (tty_istrapsig()) -			useeditmode |= MODE_TRAPSIG; -		if (tty_issofttab()) -			useeditmode |= MODE_SOFT_TAB; -		if (tty_islitecho()) -			useeditmode |= MODE_LIT_ECHO; -# ifdef	KLUDGELINEMODE -	} else if (lmodetype == KLUDGE_LINEMODE) { -		if (tty_isediting() && uselinemode) -			send_wont(TELOPT_SGA, 1); -		else -			send_will(TELOPT_SGA, 1); -	} -# endif	/* KLUDGELINEMODE */ - -	/* -	 * Negotiate linemode on if pty state has changed to turn it on. -	 * Send appropriate command and send along edit mode, then all done. -	 */ -	if (uselinemode && !linemode) { -# ifdef	KLUDGELINEMODE -		if (lmodetype == KLUDGE_LINEMODE) { -			send_wont(TELOPT_SGA, 1); -		} else if (lmodetype == REAL_LINEMODE) { -# endif	/* KLUDGELINEMODE */ -			send_do(TELOPT_LINEMODE, 1); -			/* send along edit modes */ -			(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB, -				TELOPT_LINEMODE, LM_MODE, useeditmode, -				IAC, SE); -			nfrontp += 7; -			editmode = useeditmode; -# ifdef	KLUDGELINEMODE -		} -# endif	/* KLUDGELINEMODE */ -		linemode = uselinemode; -		goto done; -	} - -# ifdef	KLUDGELINEMODE -	/* -	 * None of what follows is of any value if not using -	 * real linemode. -	 */ -	if (lmodetype < REAL_LINEMODE) -		goto done; -# endif	/* KLUDGELINEMODE */ - -	if (linemode && his_state_is_will(TELOPT_LINEMODE)) { -		/* -		 * If edit mode changed, send edit mode. -		 */ -		 if (useeditmode != editmode) { -			/* -			 * Send along appropriate edit mode mask. -			 */ -			(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB, -				TELOPT_LINEMODE, LM_MODE, useeditmode, -				IAC, SE); -			nfrontp += 7; -			editmode = useeditmode; -		} -							 - -		/* -		 * Check for changes to special characters in use. -		 */ -		start_slc(0); -		check_slc(); -		(void) end_slc(0); -	} - -done: -	if (need_will_echo) -		send_will(TELOPT_ECHO, 1); -	/* -	 * Some things should be deferred until after the pty state has -	 * been set by the local process.  Do those things that have been -	 * deferred now.  This only happens once. -	 */ -	if (_terminit == 0) { -		_terminit = 1; -		defer_terminit(); -	} - -	netflush(); -	set_termbuf(); -	return; - -}  /* end of localstat */ -#endif	/* LINEMODE */ - -/* - * flowstat - * - * Check for changes to flow control - */ -	void -flowstat() -{ -	if (his_state_is_will(TELOPT_LFLOW)) { -		if (tty_flowmode() != flowmode) { -			flowmode = tty_flowmode(); -			(void) sprintf(nfrontp, "%c%c%c%c%c%c", -					IAC, SB, TELOPT_LFLOW, -					flowmode ? LFLOW_ON : LFLOW_OFF, -					IAC, SE); -			nfrontp += 6; -		} -		if (tty_restartany() != restartany) { -			restartany = tty_restartany(); -			(void) sprintf(nfrontp, "%c%c%c%c%c%c", -					IAC, SB, TELOPT_LFLOW, -					restartany ? LFLOW_RESTART_ANY -						   : LFLOW_RESTART_XON, -					IAC, SE); -			nfrontp += 6; -		} -	} -} - -/* - * clientstat - * - * Process linemode related requests from the client. - * Client can request a change to only one of linemode, editmode or slc's - * at a time, and if using kludge linemode, then only linemode may be - * affected. - */ -	void -clientstat(code, parm1, parm2) -	register int code, parm1, parm2; -{ -	void netflush(); - -	/* -	 * Get a copy of terminal characteristics. -	 */ -	init_termbuf(); - -	/* -	 * Process request from client. code tells what it is. -	 */ -	switch (code) { -#ifdef	LINEMODE -	case TELOPT_LINEMODE: -		/* -		 * Don't do anything unless client is asking us to change -		 * modes. -		 */ -		uselinemode = (parm1 == WILL); -		if (uselinemode != linemode) { -# ifdef	KLUDGELINEMODE -			/* -			 * If using kludge linemode, make sure that -			 * we can do what the client asks. -			 * We can not turn off linemode if alwayslinemode -			 * and the ICANON bit is set. -			 */ -			if (lmodetype == KLUDGE_LINEMODE) { -				if (alwayslinemode && tty_isediting()) { -					uselinemode = 1; -				} -			} -		 -			/* -			 * Quit now if we can't do it. -			 */ -			if (uselinemode == linemode) -				return; - -			/* -			 * If using real linemode and linemode is being -			 * turned on, send along the edit mode mask. -			 */ -			if (lmodetype == REAL_LINEMODE && uselinemode) -# else	/* KLUDGELINEMODE */ -			if (uselinemode) -# endif	/* KLUDGELINEMODE */ -			{ -				useeditmode = 0; -				if (tty_isediting()) -					useeditmode |= MODE_EDIT; -				if (tty_istrapsig) -					useeditmode |= MODE_TRAPSIG; -				if (tty_issofttab()) -					useeditmode |= MODE_SOFT_TAB; -				if (tty_islitecho()) -					useeditmode |= MODE_LIT_ECHO; -				(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, -					SB, TELOPT_LINEMODE, LM_MODE, -							useeditmode, IAC, SE); -				nfrontp += 7; -				editmode = useeditmode; -			} - - -			tty_setlinemode(uselinemode); - -			linemode = uselinemode; - -			if (!linemode) -				send_will(TELOPT_ECHO, 1); -		} -		break; -	 -	case LM_MODE: -	    { -		register int ack, changed; - -		/* -		 * Client has sent along a mode mask.  If it agrees with -		 * what we are currently doing, ignore it; if not, it could -		 * be viewed as a request to change.  Note that the server -		 * will change to the modes in an ack if it is different from -		 * what we currently have, but we will not ack the ack. -		 */ -		 useeditmode &= MODE_MASK; -		 ack = (useeditmode & MODE_ACK); -		 useeditmode &= ~MODE_ACK; - -		 if (changed = (useeditmode ^ editmode)) { -			/* -			 * This check is for a timing problem.  If the -			 * state of the tty has changed (due to the user -			 * application) we need to process that info -			 * before we write in the state contained in the -			 * ack!!!  This gets out the new MODE request, -			 * and when the ack to that command comes back -			 * we'll set it and be in the right mode. -			 */ -			if (ack) -				localstat(); -			if (changed & MODE_EDIT) -				tty_setedit(useeditmode & MODE_EDIT); - -			if (changed & MODE_TRAPSIG) -				tty_setsig(useeditmode & MODE_TRAPSIG); - -			if (changed & MODE_SOFT_TAB) -				tty_setsofttab(useeditmode & MODE_SOFT_TAB); - -			if (changed & MODE_LIT_ECHO) -				tty_setlitecho(useeditmode & MODE_LIT_ECHO); - -			set_termbuf(); - - 			if (!ack) { - 				(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, -					SB, TELOPT_LINEMODE, LM_MODE, - 					useeditmode|MODE_ACK, - 					IAC, SE); - 				nfrontp += 7; - 			} - 		 -			editmode = useeditmode; -		} - -		break; - -	    }  /* end of case LM_MODE */ -#endif	/* LINEMODE */ - -	case TELOPT_NAWS: -#ifdef	TIOCSWINSZ -	    { -		struct winsize ws; - -		def_col = parm1; -		def_row = parm2; -#ifdef	LINEMODE -		/* -		 * Defer changing window size until after terminal is -		 * initialized. -		 */ -		if (terminit() == 0) -			return; -#endif	/* LINEMODE */ - -		/* -		 * Change window size as requested by client. -		 */ - -		ws.ws_col = parm1; -		ws.ws_row = parm2; -		(void) ioctl(pty, TIOCSWINSZ, (char *)&ws); -	    } -#endif	/* TIOCSWINSZ */ -		 -		break; -	 -	case TELOPT_TSPEED: -	    { -		def_tspeed = parm1; -		def_rspeed = parm2; -#ifdef	LINEMODE -		/* -		 * Defer changing the terminal speed. -		 */ -		if (terminit() == 0) -			return; -#endif	/* LINEMODE */ -		/* -		 * Change terminal speed as requested by client. -		 * We set the receive speed first, so that if we can't -		 * store seperate receive and transmit speeds, the transmit -		 * speed will take precedence. -		 */ -		tty_rspeed(parm2); -		tty_tspeed(parm1); -		set_termbuf(); - -		break; - -	    }  /* end of case TELOPT_TSPEED */ - -	default: -		/* What? */ -		break; -	}  /* end of switch */ - -#if	defined(CRAY2) && defined(UNICOS5) -	/* -	 * Just in case of the likely event that we changed the pty state. -	 */ -	rcv_ioctl(); -#endif	/* defined(CRAY2) && defined(UNICOS5) */ - -	netflush(); - -}  /* end of clientstat */ - -#if	defined(CRAY2) && defined(UNICOS5) -	void -termstat() -{ -	needtermstat = 1; -} - -	void -_termstat() -{ -	needtermstat = 0; -	init_termbuf(); -	localstat(); -	rcv_ioctl(); -} -#endif	/* defined(CRAY2) && defined(UNICOS5) */ - -#ifdef	LINEMODE -/* - * defer_terminit - * - * Some things should not be done until after the login process has started - * and all the pty modes are set to what they are supposed to be.  This - * function is called when the pty state has been processed for the first time.  - * It calls other functions that do things that were deferred in each module. - */ -	void -defer_terminit() -{ - -	/* -	 * local stuff that got deferred. -	 */ -	if (def_tspeed != -1) { -		clientstat(TELOPT_TSPEED, def_tspeed, def_rspeed); -		def_tspeed = def_rspeed = 0; -	} - -#ifdef	TIOCSWINSZ -	if (def_col || def_row) { -		struct winsize ws; - -		bzero((char *)&ws, sizeof(ws)); -		ws.ws_col = def_col; -		ws.ws_row = def_row; -		(void) ioctl(pty, TIOCSWINSZ, (char *)&ws); -	} -#endif - -	/* -	 * The only other module that currently defers anything. -	 */ -	deferslc(); - -}  /* end of defer_terminit */ - -/* - * terminit - * - * Returns true if the pty state has been processed yet. - */ -	int -terminit() -{ -	return(_terminit); - -}  /* end of terminit */ -#endif	/* LINEMODE */ diff --git a/secure/libexec/telnetd/utility.c b/secure/libexec/telnetd/utility.c deleted file mode 100644 index 8c08bdc9dbe4..000000000000 --- a/secure/libexec/telnetd/utility.c +++ /dev/null @@ -1,1192 +0,0 @@ -/* - * Copyright (c) 1989, 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. - */ - -#ifndef lint -static char sccsid[] = "@(#)utility.c	8.2 (Berkeley) 12/15/93"; -#endif /* not lint */ - -#define PRINTOPTIONS -#include "telnetd.h" - -/* - * utility functions performing io related tasks - */ - -/* - * ttloop - * - *	A small subroutine to flush the network output buffer, get some data - * from the network, and pass it through the telnet state machine.  We - * also flush the pty input buffer (by dropping its data) if it becomes - * too full. - */ - -    void -ttloop() -{ -    void netflush(); - -    DIAG(TD_REPORT, {sprintf(nfrontp, "td: ttloop\r\n"); -		     nfrontp += strlen(nfrontp);}); -    if (nfrontp-nbackp) { -	netflush(); -    } -    ncc = read(net, netibuf, sizeof netibuf); -    if (ncc < 0) { -	syslog(LOG_INFO, "ttloop:  read: %m\n"); -	exit(1); -    } else if (ncc == 0) { -	syslog(LOG_INFO, "ttloop:  peer died: %m\n"); -	exit(1); -    } -    DIAG(TD_REPORT, {sprintf(nfrontp, "td: ttloop read %d chars\r\n", ncc); -		     nfrontp += strlen(nfrontp);}); -    netip = netibuf; -    telrcv();			/* state machine */ -    if (ncc > 0) { -	pfrontp = pbackp = ptyobuf; -	telrcv(); -    } -}  /* end of ttloop */ - -/* - * Check a descriptor to see if out of band data exists on it. - */ -    int -stilloob(s) -    int	s;		/* socket number */ -{ -    static struct timeval timeout = { 0 }; -    fd_set	excepts; -    int value; - -    do { -	FD_ZERO(&excepts); -	FD_SET(s, &excepts); -	value = select(s+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout); -    } while ((value == -1) && (errno == EINTR)); - -    if (value < 0) { -	fatalperror(pty, "select"); -    } -    if (FD_ISSET(s, &excepts)) { -	return 1; -    } else { -	return 0; -    } -} - -	void -ptyflush() -{ -	int n; - -	if ((n = pfrontp - pbackp) > 0) { -		DIAG((TD_REPORT | TD_PTYDATA), -			{ sprintf(nfrontp, "td: ptyflush %d chars\r\n", n); -			  nfrontp += strlen(nfrontp); }); -		DIAG(TD_PTYDATA, printdata("pd", pbackp, n)); -		n = write(pty, pbackp, n); -	} -	if (n < 0) { -		if (errno == EWOULDBLOCK || errno == EINTR) -			return; -		cleanup(0); -	} -	pbackp += n; -	if (pbackp == pfrontp) -		pbackp = pfrontp = ptyobuf; -} - -/* - * nextitem() - * - *	Return the address of the next "item" in the TELNET data - * stream.  This will be the address of the next character if - * the current address is a user data character, or it will - * be the address of the character following the TELNET command - * if the current address is a TELNET IAC ("I Am a Command") - * character. - */ -    char * -nextitem(current) -    char	*current; -{ -    if ((*current&0xff) != IAC) { -	return current+1; -    } -    switch (*(current+1)&0xff) { -    case DO: -    case DONT: -    case WILL: -    case WONT: -	return current+3; -    case SB:		/* loop forever looking for the SE */ -	{ -	    register char *look = current+2; - -	    for (;;) { -		if ((*look++&0xff) == IAC) { -		    if ((*look++&0xff) == SE) { -			return look; -		    } -		} -	    } -	} -    default: -	return current+2; -    } -}  /* end of nextitem */ - - -/* - * netclear() - * - *	We are about to do a TELNET SYNCH operation.  Clear - * the path to the network. - * - *	Things are a bit tricky since we may have sent the first - * byte or so of a previous TELNET command into the network. - * So, we have to scan the network buffer from the beginning - * until we are up to where we want to be. - * - *	A side effect of what we do, just to keep things - * simple, is to clear the urgent data pointer.  The principal - * caller should be setting the urgent data pointer AFTER calling - * us in any case. - */ -    void -netclear() -{ -    register char *thisitem, *next; -    char *good; -#define	wewant(p)	((nfrontp > p) && ((*p&0xff) == IAC) && \ -				((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL)) - -#ifdef	ENCRYPTION -    thisitem = nclearto > netobuf ? nclearto : netobuf; -#else	/* ENCRYPTION */ -    thisitem = netobuf; -#endif	/* ENCRYPTION */ - -    while ((next = nextitem(thisitem)) <= nbackp) { -	thisitem = next; -    } - -    /* Now, thisitem is first before/at boundary. */ - -#ifdef	ENCRYPTION -    good = nclearto > netobuf ? nclearto : netobuf; -#else	/* ENCRYPTION */ -    good = netobuf;	/* where the good bytes go */ -#endif	/* ENCRYPTION */ - -    while (nfrontp > thisitem) { -	if (wewant(thisitem)) { -	    int length; - -	    next = thisitem; -	    do { -		next = nextitem(next); -	    } while (wewant(next) && (nfrontp > next)); -	    length = next-thisitem; -	    bcopy(thisitem, good, length); -	    good += length; -	    thisitem = next; -	} else { -	    thisitem = nextitem(thisitem); -	} -    } - -    nbackp = netobuf; -    nfrontp = good;		/* next byte to be sent */ -    neturg = 0; -}  /* end of netclear */ - -/* - *  netflush - *		Send as much data as possible to the network, - *	handling requests for urgent data. - */ -    void -netflush() -{ -    int n; -    extern int not42; - -    if ((n = nfrontp - nbackp) > 0) { -	DIAG(TD_REPORT, -	    { sprintf(nfrontp, "td: netflush %d chars\r\n", n); -	      n += strlen(nfrontp);  /* get count first */ -	      nfrontp += strlen(nfrontp);  /* then move pointer */ -	    }); -#ifdef	ENCRYPTION -	if (encrypt_output) { -		char *s = nclearto ? nclearto : nbackp; -		if (nfrontp - s > 0) { -			(*encrypt_output)((unsigned char *)s, nfrontp-s); -			nclearto = nfrontp; -		} -	} -#endif	/* ENCRYPTION */ -	/* -	 * if no urgent data, or if the other side appears to be an -	 * old 4.2 client (and thus unable to survive TCP urgent data), -	 * write the entire buffer in non-OOB mode. -	 */ -	if ((neturg == 0) || (not42 == 0)) { -	    n = write(net, nbackp, n);	/* normal write */ -	} else { -	    n = neturg - nbackp; -	    /* -	     * 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). -	     */ -	    if (n > 1) { -		n = send(net, nbackp, n-1, 0);	/* send URGENT all by itself */ -	    } else { -		n = send(net, nbackp, n, MSG_OOB);	/* URGENT data */ -	    } -	} -    } -    if (n < 0) { -	if (errno == EWOULDBLOCK || errno == EINTR) -		return; -	cleanup(0); -    } -    nbackp += n; -#ifdef	ENCRYPTION -    if (nbackp > nclearto) -	nclearto = 0; -#endif	/* ENCRYPTION */ -    if (nbackp >= neturg) { -	neturg = 0; -    } -    if (nbackp == nfrontp) { -	nbackp = nfrontp = netobuf; -#ifdef	ENCRYPTION -	nclearto = 0; -#endif	/* ENCRYPTION */ -    } -    return; -}  /* end of netflush */ - - -/* - * writenet - * - * Just a handy little function to write a bit of raw data to the net. - * It will force a transmit of the buffer if necessary - * - * arguments - *    ptr - A pointer to a character string to write - *    len - How many bytes to write - */ -	void -writenet(ptr, len) -	register unsigned char *ptr; -	register int len; -{ -	/* flush buffer if no room for new data) */ -	if ((&netobuf[BUFSIZ] - nfrontp) < len) { -		/* if this fails, don't worry, buffer is a little big */ -		netflush(); -	} - -	bcopy(ptr, nfrontp, len); -	nfrontp += len; - -}  /* end of writenet */ - - -/* - * miscellaneous functions doing a variety of little jobs follow ... - */ - - -	void -fatal(f, msg) -	int f; -	char *msg; -{ -	char buf[BUFSIZ]; - -	(void) sprintf(buf, "telnetd: %s.\r\n", msg); -#ifdef	ENCRYPTION -	if (encrypt_output) { -		/* -		 * Better turn off encryption first.... -		 * Hope it flushes... -		 */ -		encrypt_send_end(); -		netflush(); -	} -#endif	/* ENCRYPTION */ -	(void) write(f, buf, (int)strlen(buf)); -	sleep(1);	/*XXX*/ -	exit(1); -} - -	void -fatalperror(f, msg) -	int f; -	char *msg; -{ -	char buf[BUFSIZ], *strerror(); - -	(void) sprintf(buf, "%s: %s\r\n", msg, strerror(errno)); -	fatal(f, buf); -} - -char editedhost[32]; - -	void -edithost(pat, host) -	register char *pat; -	register char *host; -{ -	register char *res = editedhost; -	char *strncpy(); - -	if (!pat) -		pat = ""; -	while (*pat) { -		switch (*pat) { - -		case '#': -			if (*host) -				host++; -			break; - -		case '@': -			if (*host) -				*res++ = *host++; -			break; - -		default: -			*res++ = *pat; -			break; -		} -		if (res == &editedhost[sizeof editedhost - 1]) { -			*res = '\0'; -			return; -		} -		pat++; -	} -	if (*host) -		(void) strncpy(res, host, -				sizeof editedhost - (res - editedhost) -1); -	else -		*res = '\0'; -	editedhost[sizeof editedhost - 1] = '\0'; -} - -static char *putlocation; - -	void -putstr(s) -	register char *s; -{ - -	while (*s) -		putchr(*s++); -} - -	void -putchr(cc) -	int cc; -{ -	*putlocation++ = cc; -} - -/* - * This is split on two lines so that SCCS will not see the M - * between two % signs and expand it... - */ -static char fmtstr[] = { "%l:%M\ -%P on %A, %d %B %Y" }; - -	void -putf(cp, where) -	register char *cp; -	char *where; -{ -	char *slash; -	time_t t; -	char db[100]; -#ifdef	STREAMSPTY -	extern char *index(); -#else -	extern char *rindex(); -#endif - -	putlocation = where; - -	while (*cp) { -		if (*cp != '%') { -			putchr(*cp++); -			continue; -		} -		switch (*++cp) { - -		case 't': -#ifdef	STREAMSPTY -			/* names are like /dev/pts/2 -- we want pts/2 */ -			slash = index(line+1, '/'); -#else -			slash = rindex(line, '/'); -#endif -			if (slash == (char *) 0) -				putstr(line); -			else -				putstr(&slash[1]); -			break; - -		case 'h': -			putstr(editedhost); -			break; - -		case 'd': -			(void)time(&t); -			(void)strftime(db, sizeof(db), fmtstr, localtime(&t)); -			putstr(db); -			break; - -		case '%': -			putchr('%'); -			break; -		} -		cp++; -	} -} - -#ifdef DIAGNOSTICS -/* - * Print telnet options and commands in plain text, if possible. - */ -	void -printoption(fmt, option) -	register char *fmt; -	register int option; -{ -	if (TELOPT_OK(option)) -		sprintf(nfrontp, "%s %s\r\n", fmt, TELOPT(option)); -	else if (TELCMD_OK(option)) -		sprintf(nfrontp, "%s %s\r\n", fmt, TELCMD(option)); -	else -		sprintf(nfrontp, "%s %d\r\n", fmt, option); -	nfrontp += strlen(nfrontp); -	return; -} - -    void -printsub(direction, pointer, length) -    char		direction;	/* '<' or '>' */ -    unsigned char	*pointer;	/* where suboption data sits */ -    int			length;		/* length of suboption data */ -{ -    register int i; -    char buf[512]; - -        if (!(diagnostic & TD_OPTIONS)) -		return; - -	if (direction) { -	    sprintf(nfrontp, "td: %s suboption ", -					direction == '<' ? "recv" : "send"); -	    nfrontp += strlen(nfrontp); -	    if (length >= 3) { -		register int j; - -		i = pointer[length-2]; -		j = pointer[length-1]; - -		if (i != IAC || j != SE) { -		    sprintf(nfrontp, "(terminated by "); -		    nfrontp += strlen(nfrontp); -		    if (TELOPT_OK(i)) -			sprintf(nfrontp, "%s ", TELOPT(i)); -		    else if (TELCMD_OK(i)) -			sprintf(nfrontp, "%s ", TELCMD(i)); -		    else -			sprintf(nfrontp, "%d ", i); -		    nfrontp += strlen(nfrontp); -		    if (TELOPT_OK(j)) -			sprintf(nfrontp, "%s", TELOPT(j)); -		    else if (TELCMD_OK(j)) -			sprintf(nfrontp, "%s", TELCMD(j)); -		    else -			sprintf(nfrontp, "%d", j); -		    nfrontp += strlen(nfrontp); -		    sprintf(nfrontp, ", not IAC SE!) "); -		    nfrontp += strlen(nfrontp); -		} -	    } -	    length -= 2; -	} -	if (length < 1) { -	    sprintf(nfrontp, "(Empty suboption??\?)"); -	    nfrontp += strlen(nfrontp); -	    return; -	} -	switch (pointer[0]) { -	case TELOPT_TTYPE: -	    sprintf(nfrontp, "TERMINAL-TYPE "); -	    nfrontp += strlen(nfrontp); -	    switch (pointer[1]) { -	    case TELQUAL_IS: -		sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2); -		break; -	    case TELQUAL_SEND: -		sprintf(nfrontp, "SEND"); -		break; -	    default: -		sprintf(nfrontp, -				"- unknown qualifier %d (0x%x).", -				pointer[1], pointer[1]); -	    } -	    nfrontp += strlen(nfrontp); -	    break; -	case TELOPT_TSPEED: -	    sprintf(nfrontp, "TERMINAL-SPEED"); -	    nfrontp += strlen(nfrontp); -	    if (length < 2) { -		sprintf(nfrontp, " (empty suboption??\?)"); -		nfrontp += strlen(nfrontp); -		break; -	    } -	    switch (pointer[1]) { -	    case TELQUAL_IS: -		sprintf(nfrontp, " IS %.*s", length-2, (char *)pointer+2); -		nfrontp += strlen(nfrontp); -		break; -	    default: -		if (pointer[1] == 1) -		    sprintf(nfrontp, " SEND"); -		else -		    sprintf(nfrontp, " %d (unknown)", pointer[1]); -		nfrontp += strlen(nfrontp); -		for (i = 2; i < length; i++) { -		    sprintf(nfrontp, " ?%d?", pointer[i]); -		    nfrontp += strlen(nfrontp); -		} -		break; -	    } -	    break; - -	case TELOPT_LFLOW: -	    sprintf(nfrontp, "TOGGLE-FLOW-CONTROL"); -	    nfrontp += strlen(nfrontp); -	    if (length < 2) { -		sprintf(nfrontp, " (empty suboption??\?)"); -		nfrontp += strlen(nfrontp); -		break; -	    } -	    switch (pointer[1]) { -	    case LFLOW_OFF: -		sprintf(nfrontp, " OFF"); break; -	    case LFLOW_ON: -		sprintf(nfrontp, " ON"); break; -	    case LFLOW_RESTART_ANY: -		sprintf(nfrontp, " RESTART-ANY"); break; -	    case LFLOW_RESTART_XON: -		sprintf(nfrontp, " RESTART-XON"); break; -	    default: -		sprintf(nfrontp, " %d (unknown)", pointer[1]); -	    } -	    nfrontp += strlen(nfrontp); -	    for (i = 2; i < length; i++) { -		sprintf(nfrontp, " ?%d?", pointer[i]); -		nfrontp += strlen(nfrontp); -	    } -	    break; - -	case TELOPT_NAWS: -	    sprintf(nfrontp, "NAWS"); -	    nfrontp += strlen(nfrontp); -	    if (length < 2) { -		sprintf(nfrontp, " (empty suboption??\?)"); -		nfrontp += strlen(nfrontp); -		break; -	    } -	    if (length == 2) { -		sprintf(nfrontp, " ?%d?", pointer[1]); -		nfrontp += strlen(nfrontp); -		break; -	    } -	    sprintf(nfrontp, " %d %d (%d)", -		pointer[1], pointer[2], -		(int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2]))); -	    nfrontp += strlen(nfrontp); -	    if (length == 4) { -		sprintf(nfrontp, " ?%d?", pointer[3]); -		nfrontp += strlen(nfrontp); -		break; -	    } -	    sprintf(nfrontp, " %d %d (%d)", -		pointer[3], pointer[4], -		(int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4]))); -	    nfrontp += strlen(nfrontp); -	    for (i = 5; i < length; i++) { -		sprintf(nfrontp, " ?%d?", pointer[i]); -		nfrontp += strlen(nfrontp); -	    } -	    break; - -	case TELOPT_LINEMODE: -	    sprintf(nfrontp, "LINEMODE "); -	    nfrontp += strlen(nfrontp); -	    if (length < 2) { -		sprintf(nfrontp, " (empty suboption??\?)"); -		nfrontp += strlen(nfrontp); -		break; -	    } -	    switch (pointer[1]) { -	    case WILL: -		sprintf(nfrontp, "WILL "); -		goto common; -	    case WONT: -		sprintf(nfrontp, "WONT "); -		goto common; -	    case DO: -		sprintf(nfrontp, "DO "); -		goto common; -	    case DONT: -		sprintf(nfrontp, "DONT "); -	    common: -		nfrontp += strlen(nfrontp); -		if (length < 3) { -		    sprintf(nfrontp, "(no option??\?)"); -		    nfrontp += strlen(nfrontp); -		    break; -		} -		switch (pointer[2]) { -		case LM_FORWARDMASK: -		    sprintf(nfrontp, "Forward Mask"); -		    nfrontp += strlen(nfrontp); -		    for (i = 3; i < length; i++) { -			sprintf(nfrontp, " %x", pointer[i]); -			nfrontp += strlen(nfrontp); -		    } -		    break; -		default: -		    sprintf(nfrontp, "%d (unknown)", pointer[2]); -		    nfrontp += strlen(nfrontp); -		    for (i = 3; i < length; i++) { -			sprintf(nfrontp, " %d", pointer[i]); -			nfrontp += strlen(nfrontp); -		    } -		    break; -		} -		break; -		 -	    case LM_SLC: -		sprintf(nfrontp, "SLC"); -		nfrontp += strlen(nfrontp); -		for (i = 2; i < length - 2; i += 3) { -		    if (SLC_NAME_OK(pointer[i+SLC_FUNC])) -			sprintf(nfrontp, " %s", SLC_NAME(pointer[i+SLC_FUNC])); -		    else -			sprintf(nfrontp, " %d", pointer[i+SLC_FUNC]); -		    nfrontp += strlen(nfrontp); -		    switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) { -		    case SLC_NOSUPPORT: -			sprintf(nfrontp, " NOSUPPORT"); break; -		    case SLC_CANTCHANGE: -			sprintf(nfrontp, " CANTCHANGE"); break; -		    case SLC_VARIABLE: -			sprintf(nfrontp, " VARIABLE"); break; -		    case SLC_DEFAULT: -			sprintf(nfrontp, " DEFAULT"); break; -		    } -		    nfrontp += strlen(nfrontp); -		    sprintf(nfrontp, "%s%s%s", -			pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "", -			pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "", -			pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : ""); -		    nfrontp += strlen(nfrontp); -		    if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN| -						SLC_FLUSHOUT| SLC_LEVELBITS)) { -			sprintf(nfrontp, "(0x%x)", pointer[i+SLC_FLAGS]); -			nfrontp += strlen(nfrontp); -		    } -		    sprintf(nfrontp, " %d;", pointer[i+SLC_VALUE]); -		    nfrontp += strlen(nfrontp); -		    if ((pointer[i+SLC_VALUE] == IAC) && -			(pointer[i+SLC_VALUE+1] == IAC)) -				i++; -		} -		for (; i < length; i++) { -		    sprintf(nfrontp, " ?%d?", pointer[i]); -		    nfrontp += strlen(nfrontp); -		} -		break; - -	    case LM_MODE: -		sprintf(nfrontp, "MODE "); -		nfrontp += strlen(nfrontp); -		if (length < 3) { -		    sprintf(nfrontp, "(no mode??\?)"); -		    nfrontp += strlen(nfrontp); -		    break; -		} -		{ -		    char tbuf[32]; -		    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" : ""); -		    sprintf(nfrontp, "%s", tbuf[1] ? &tbuf[1] : "0"); -		    nfrontp += strlen(nfrontp); -		} -		if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK)) { -		    sprintf(nfrontp, " (0x%x)", pointer[2]); -		    nfrontp += strlen(nfrontp); -		} -		for (i = 3; i < length; i++) { -		    sprintf(nfrontp, " ?0x%x?", pointer[i]); -		    nfrontp += strlen(nfrontp); -		} -		break; -	    default: -		sprintf(nfrontp, "%d (unknown)", pointer[1]); -		nfrontp += strlen(nfrontp); -		for (i = 2; i < length; i++) { -		    sprintf(nfrontp, " %d", pointer[i]); -		    nfrontp += strlen(nfrontp); -		} -	    } -	    break; - -	case TELOPT_STATUS: { -	    register char *cp; -	    register int j, k; - -	    sprintf(nfrontp, "STATUS"); -	    nfrontp += strlen(nfrontp); - -	    switch (pointer[1]) { -	    default: -		if (pointer[1] == TELQUAL_SEND) -		    sprintf(nfrontp, " SEND"); -		else -		    sprintf(nfrontp, " %d (unknown)", pointer[1]); -		nfrontp += strlen(nfrontp); -		for (i = 2; i < length; i++) { -		    sprintf(nfrontp, " ?%d?", pointer[i]); -		    nfrontp += strlen(nfrontp); -		} -		break; -	    case TELQUAL_IS: -		sprintf(nfrontp, " IS\r\n"); -		nfrontp += strlen(nfrontp); - -		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(pointer[i])) -			    sprintf(nfrontp, " %s %s", cp, TELOPT(pointer[i])); -			else -			    sprintf(nfrontp, " %s %d", cp, pointer[i]); -			nfrontp += strlen(nfrontp); - -			sprintf(nfrontp, "\r\n"); -			nfrontp += strlen(nfrontp); -			break; - -		    case SB: -			sprintf(nfrontp, " SB "); -			nfrontp += strlen(nfrontp); -			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) { -			    sprintf(nfrontp, " SE"); -			    nfrontp += strlen(nfrontp); -			    i = j; -			} else -			    i = j - 1; - -			sprintf(nfrontp, "\r\n"); -			nfrontp += strlen(nfrontp); - -			break; -				 -		    default: -			sprintf(nfrontp, " %d", pointer[i]); -			nfrontp += strlen(nfrontp); -			break; -		    } -		} -		break; -	    } -	    break; -	  } - -	case TELOPT_XDISPLOC: -	    sprintf(nfrontp, "X-DISPLAY-LOCATION "); -	    nfrontp += strlen(nfrontp); -	    switch (pointer[1]) { -	    case TELQUAL_IS: -		sprintf(nfrontp, "IS \"%.*s\"", length-2, (char *)pointer+2); -		break; -	    case TELQUAL_SEND: -		sprintf(nfrontp, "SEND"); -		break; -	    default: -		sprintf(nfrontp, "- unknown qualifier %d (0x%x).", -				pointer[1], pointer[1]); -	    } -	    nfrontp += strlen(nfrontp); -	    break; - -	case TELOPT_NEW_ENVIRON: -	    sprintf(nfrontp, "NEW-ENVIRON "); -	    goto env_common1; -	case TELOPT_OLD_ENVIRON: -	    sprintf(nfrontp, "OLD-ENVIRON"); -	env_common1: -	    nfrontp += strlen(nfrontp); -	    switch (pointer[1]) { -	    case TELQUAL_IS: -		sprintf(nfrontp, "IS "); -		goto env_common; -	    case TELQUAL_SEND: -		sprintf(nfrontp, "SEND "); -		goto env_common; -	    case TELQUAL_INFO: -		sprintf(nfrontp, "INFO "); -	    env_common: -		nfrontp += strlen(nfrontp); -		{ -		    register int noquote = 2; -		    for (i = 2; i < length; i++ ) { -			switch (pointer[i]) { -			case NEW_ENV_VAR: -			    sprintf(nfrontp, "\" VAR " + noquote); -			    nfrontp += strlen(nfrontp); -			    noquote = 2; -			    break; - -			case NEW_ENV_VALUE: -			    sprintf(nfrontp, "\" VALUE " + noquote); -			    nfrontp += strlen(nfrontp); -			    noquote = 2; -			    break; - -			case ENV_ESC: -			    sprintf(nfrontp, "\" ESC " + noquote); -			    nfrontp += strlen(nfrontp); -			    noquote = 2; -			    break; - -			case ENV_USERVAR: -			    sprintf(nfrontp, "\" USERVAR " + noquote); -			    nfrontp += strlen(nfrontp); -			    noquote = 2; -			    break; - -			default: -			def_case: -			    if (isprint(pointer[i]) && pointer[i] != '"') { -				if (noquote) { -				    *nfrontp++ = '"'; -				    noquote = 0; -				} -				*nfrontp++ = pointer[i]; -			    } else { -				sprintf(nfrontp, "\" %03o " + noquote, -							pointer[i]); -				nfrontp += strlen(nfrontp); -				noquote = 2; -			    } -			    break; -			} -		    } -		    if (!noquote) -			*nfrontp++ = '"'; -		    break; -		} -	    } -	    break; - -#if	defined(AUTHENTICATION) -	case TELOPT_AUTHENTICATION: -	    sprintf(nfrontp, "AUTHENTICATION"); -	    nfrontp += strlen(nfrontp); -	 -	    if (length < 2) { -		sprintf(nfrontp, " (empty suboption??\?)"); -		nfrontp += strlen(nfrontp); -		break; -	    } -	    switch (pointer[1]) { -	    case TELQUAL_REPLY: -	    case TELQUAL_IS: -		sprintf(nfrontp, " %s ", (pointer[1] == TELQUAL_IS) ? -							"IS" : "REPLY"); -		nfrontp += strlen(nfrontp); -		if (AUTHTYPE_NAME_OK(pointer[2])) -		    sprintf(nfrontp, "%s ", AUTHTYPE_NAME(pointer[2])); -		else -		    sprintf(nfrontp, "%d ", pointer[2]); -		nfrontp += strlen(nfrontp); -		if (length < 3) { -		    sprintf(nfrontp, "(partial suboption??\?)"); -		    nfrontp += strlen(nfrontp); -		    break; -		} -		sprintf(nfrontp, "%s|%s", -			((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? -			"CLIENT" : "SERVER", -			((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? -			"MUTUAL" : "ONE-WAY"); -		nfrontp += strlen(nfrontp); - -		auth_printsub(&pointer[1], length - 1, buf, sizeof(buf)); -		sprintf(nfrontp, "%s", buf); -		nfrontp += strlen(nfrontp); -		break; - -	    case TELQUAL_SEND: -		i = 2; -		sprintf(nfrontp, " SEND "); -		nfrontp += strlen(nfrontp); -		while (i < length) { -		    if (AUTHTYPE_NAME_OK(pointer[i])) -			sprintf(nfrontp, "%s ", AUTHTYPE_NAME(pointer[i])); -		    else -			sprintf(nfrontp, "%d ", pointer[i]); -		    nfrontp += strlen(nfrontp); -		    if (++i >= length) { -			sprintf(nfrontp, "(partial suboption??\?)"); -			nfrontp += strlen(nfrontp); -			break; -		    } -		    sprintf(nfrontp, "%s|%s ", -			((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? -							"CLIENT" : "SERVER", -			((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? -							"MUTUAL" : "ONE-WAY"); -		    nfrontp += strlen(nfrontp); -		    ++i; -		} -		break; - -	    case TELQUAL_NAME: -		i = 2; -		sprintf(nfrontp, " NAME \""); -		nfrontp += strlen(nfrontp); -		while (i < length) -		    *nfrontp += pointer[i++]; -		*nfrontp += '"'; -		break; - -	    default: -		    for (i = 2; i < length; i++) { -			sprintf(nfrontp, " ?%d?", pointer[i]); -			nfrontp += strlen(nfrontp); -		    } -		    break; -	    } -	    break; -#endif - -#ifdef	ENCRYPTION -	case TELOPT_ENCRYPT: -	    sprintf(nfrontp, "ENCRYPT"); -	    nfrontp += strlen(nfrontp); -	    if (length < 2) { -		sprintf(nfrontp, " (empty suboption??\?)"); -		nfrontp += strlen(nfrontp); -		break; -	    } -	    switch (pointer[1]) { -	    case ENCRYPT_START: -		sprintf(nfrontp, " START"); -		nfrontp += strlen(nfrontp); -		break; - -	    case ENCRYPT_END: -		sprintf(nfrontp, " END"); -		nfrontp += strlen(nfrontp); -		break; - -	    case ENCRYPT_REQSTART: -		sprintf(nfrontp, " REQUEST-START"); -		nfrontp += strlen(nfrontp); -		break; - -	    case ENCRYPT_REQEND: -		sprintf(nfrontp, " REQUEST-END"); -		nfrontp += strlen(nfrontp); -		break; - -	    case ENCRYPT_IS: -	    case ENCRYPT_REPLY: -		sprintf(nfrontp, " %s ", (pointer[1] == ENCRYPT_IS) ? -							"IS" : "REPLY"); -		nfrontp += strlen(nfrontp); -		if (length < 3) { -		    sprintf(nfrontp, " (partial suboption??\?)"); -		    nfrontp += strlen(nfrontp); -		    break; -		} -		if (ENCTYPE_NAME_OK(pointer[2])) -		    sprintf(nfrontp, "%s ", ENCTYPE_NAME(pointer[2])); -		else -		    sprintf(nfrontp, " %d (unknown)", pointer[2]); -		nfrontp += strlen(nfrontp); - -		encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf)); -		sprintf(nfrontp, "%s", buf); -		nfrontp += strlen(nfrontp); -		break; - -	    case ENCRYPT_SUPPORT: -		i = 2; -		sprintf(nfrontp, " SUPPORT "); -		nfrontp += strlen(nfrontp); -		while (i < length) { -		    if (ENCTYPE_NAME_OK(pointer[i])) -			sprintf(nfrontp, "%s ", ENCTYPE_NAME(pointer[i])); -		    else -			sprintf(nfrontp, "%d ", pointer[i]); -		    nfrontp += strlen(nfrontp); -		    i++; -		} -		break; - -	    case ENCRYPT_ENC_KEYID: -		sprintf(nfrontp, " ENC_KEYID", pointer[1]); -		nfrontp += strlen(nfrontp); -		goto encommon; - -	    case ENCRYPT_DEC_KEYID: -		sprintf(nfrontp, " DEC_KEYID", pointer[1]); -		nfrontp += strlen(nfrontp); -		goto encommon; - -	    default: -		sprintf(nfrontp, " %d (unknown)", pointer[1]); -		nfrontp += strlen(nfrontp); -	    encommon: -		for (i = 2; i < length; i++) { -		    sprintf(nfrontp, " %d", pointer[i]); -		    nfrontp += strlen(nfrontp); -		} -		break; -	    } -	    break; -#endif	/* ENCRYPTION */ - -	default: -	    if (TELOPT_OK(pointer[0])) -	        sprintf(nfrontp, "%s (unknown)", TELOPT(pointer[0])); -	    else -	        sprintf(nfrontp, "%d (unknown)", pointer[i]); -	    nfrontp += strlen(nfrontp); -	    for (i = 1; i < length; i++) { -		sprintf(nfrontp, " %d", pointer[i]); -		nfrontp += strlen(nfrontp); -	    } -	    break; -	} -	sprintf(nfrontp, "\r\n"); -	nfrontp += strlen(nfrontp); -} - -/* - * Dump a data buffer in hex and ascii to the output data stream. - */ -	void -printdata(tag, ptr, cnt) -	register char *tag; -	register char *ptr; -	register int cnt; -{ -	register int i; -	char xbuf[30]; - -	while (cnt) { -		/* flush net output buffer if no room for new data) */ -		if ((&netobuf[BUFSIZ] - nfrontp) < 80) { -			netflush(); -		} - -		/* add a line of output */ -		sprintf(nfrontp, "%s: ", tag); -		nfrontp += strlen(nfrontp); -		for (i = 0; i < 20 && cnt; i++) { -			sprintf(nfrontp, "%02x", *ptr); -			nfrontp += strlen(nfrontp);  -			if (isprint(*ptr)) { -				xbuf[i] = *ptr; -			} else { -				xbuf[i] = '.'; -			} -			if (i % 2) {  -				*nfrontp = ' '; -				nfrontp++; -			} -			cnt--; -			ptr++; -		} -		xbuf[i] = '\0'; -		sprintf(nfrontp, " %s\r\n", xbuf ); -		nfrontp += strlen(nfrontp); -	}  -} -#endif /* DIAGNOSTICS */ | 
