[alt.sources] play with telnet via socket - teleplay 01/02

wht@tridom.uucp (Warren Tucker) (07/21/89)

Create a directory called teleplay and extract both shar files.
See the README file below.

#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
if test -f README; then echo "File README exists"; else
echo "x - extracting README (Text)"
sed 's/^X//' << 'SHAR_EOF' > README &&
XI, being a System-V kind of guy, didn't know much about sockets
Xand other such "grown-up" stuff.  I was charged with doing some
Xautomated thingies with our development environment and thought
Xtelnet was the way to go.  Then, low and behold, here came nntp
Xover the wire.  Many thanks to nelson@clutx.clarkson.edu and by
Xextension to ambar@athena.mit.edu fpr the jump-start.  This two
Xpart message has shars to rebuild my telnet experiments wherein
Xwe, from a Pyramid in the BSD environment, telnet to either the
XPyramid (ttest, system name tridom) or a Stratus (stest, system
Xname stratus).  Maybe these kludges can help other unfortunate,
Xyet eager, learners who thought sockets were where one plugs in
Xthe television set so one can watch Peewee Herman on Saturdays.
X
XI have never compiled the stuff without -DDEBUG.  You might get
Xcompilation errors if DEBUG is taken out.
SHAR_EOF
chmod 0644 README || echo "restore of README fails"
fi
if test -f Makefile; then echo "File Makefile exists"; else
echo "x - extracting Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
X#+-------------------------------------------------------------
X# Makefile teleplay related programs
X#--------------------------------------------------------------
X#+:EDITS:
X#:07-17-1989-14:23-wht-creation
X
XCFLAGS = -c -gx -DDEBUG
XLDFLAGS = -gx
X.c.o:;	fcrc -u $*.c ; /bin/time cc $(CFLAGS) $*.c 
X
XTOBJ = \
X	teleplay.o\
X	t_apply.o\
X	unixlogin.o\
X	hexdump.o
X
XSOBJ = \
X	teleplay.o\
X	s_apply.o\
X	stratlogin.o\
X	hexdump.o
X
Xall: stest ttest
X
Xttest: $(TOBJ)
X	cc $(LDFLAGS) $(TOBJ) -o $@
X
Xstest: $(SOBJ)
X	cc $(LDFLAGS) $(SOBJ) -o $@
X
SHAR_EOF
chmod 0644 Makefile || echo "restore of Makefile fails"
fi
if test -f MANIFEST; then echo "File MANIFEST exists"; else
echo "x - extracting MANIFEST (Text)"
sed 's/^X//' << 'SHAR_EOF' > MANIFEST &&
XREADME
XMakefile
XMANIFEST
Xhexdump.c
Xs_apply.c
Xstratlogin.c
Xt_apply.c
Xteleplay.c
Xunixlogin.c
SHAR_EOF
chmod 0644 MANIFEST || echo "restore of MANIFEST fails"
fi
if test -f teleplay.c; then echo "File teleplay.c exists"; else
echo "x - extracting teleplay.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > teleplay.c &&
X/* CHK=0xA0D1 */
X/*+-------------------------------------------------------------------------
X	teleplay.c - play with telnet by socket
X	...!gatech!emory!tridom!wht
X	thanks for inspiration and jumpstart to nelson@clutx.clarkson.edu
X
X  Error exit codes:
X	128 - socket I/O error
X	129 - connect or telnet protocol error
X	130 - timeout
X	131 - system resource error
X	255 - usage - (hostname error)
X
X  Defined functions:
X	_xmit_opt(tcmd,topt)
X	_xmit_ttype()
X	d_hostent(he)
X	d_servent(se)
X	d_sockaddr_in(sin)
X	do_use(topt)
X	dont_use(topt)
X	family_text(family)
X	hangup(code)
X	issubstr(target,search)
X	main(argc,argv,envp)
X	sperror(txt)
X	telgetc()
X	telgetc_raw()
X	telgets(buf,timeout,delim,raw_flag)
X	telnet_cmd()
X	telnet_cmd_text(tcmd)
X	telnet_option(tcmd,topt)
X	telnet_option_text(topt)
X	telnet_subnegotiate()
X	telputc(schar)
X	telputcs(schars,count)
X	telputs(sstr)
X	telsearch(maxlines,searchstr,timeout,delim,showit)
X	will_use(topt)
X	wont_use(topt)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-20-1989-16:38-wht-flush edits - rev. x1.0  */
X
X#if defined(pyr)
X#define BSD43
X#endif
X
X#define CR 0x0D
X#define LF 0x0A
X
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <sys/stat.h>
X#include <sys/ioctl.h>
X#include <sys/time.h>
X#include <sys/resource.h>
X
X#include <net/if.h>
X#include <netinet/in.h>
X#include <netinet/tcp.h>
X#include <arpa/telnet.h>
X
X#include <stdio.h>
X#include <errno.h>
X#include <ctype.h>
X#include <netdb.h>
X#include <signal.h>
X
Xchar *index();
Xu_long inet_addr();
X
Xextern int errno;
X
Xchar *hostname = (char *)0;
Xint ts = -1;		/* stream socket to telnet */
Xint debug = 5;		/* true if we're debugging. */
X
Xu_char Oecho = DO;				/* echo xmit data? */
Xu_char Ottype[] = "ANSI43";		/* terminal type */
X
Xint eol_type = 0;	/* 0 = strip 0x0D, LF terminator */
X					/* 1 = 0x0D+0x00 == 0x0A */
X
X/*+-------------------------------------------------------------------------
X	sperror(txt) - stdout equivalent of 'perror'
X--------------------------------------------------------------------------*/
Xvoid
Xsperror(txt)
Xchar *txt;
X{
Xextern int errno;
Xextern int sys_nerr;
Xextern char *sys_errlist[];
X
X	fputs(txt,stdout);
X	fputs(": ",stdout);
X	if(errno >= sys_nerr)
X		printf("Error %d (unknown error)\n",errno);
X	else
X		puts(sys_errlist[errno]);
X}	/* end of sperror */
X
X/*+-------------------------------------------------------------------------
X	hangup(code) - clean up application and exit
X--------------------------------------------------------------------------*/
Xvoid
Xhangup(code)
Xint code;
X{
X	application_hangup(code);
X	if(ts >= 0)
X		close(ts);
X	if(code != 0)
X		printf("abnormal termination: code %d\n",code);
X	exit(code);
X
X}	/* end of hangup */
X
X/*+-------------------------------------------------------------------------
X	issubstr(target,search) - find 'search' in 'target'?
Xreturn 1 if found, else 0
X--------------------------------------------------------------------------*/
Xint
Xissubstr(target,search)
Xchar *target;
Xregister char *search;
X{
Xregister len = strlen(search);
X
X	while((target = index(target,*search)) != NULL)
X	{
X		if(!strncmp(search,target,len))
X			return(1);
X		target++;
X	}
X	return(0);
X}	/* end of issubstr */
X
X/*+-------------------------------------------------------------------------
X	telnet_cmd_text(tcmd)
X
X		EOR ...........ef
X		SE             f0
X		NOP ...........f1
X		DM/SYNCH       f2
X		BREAK .........f3
X		IP             f4
X		AO ............f5
X		AYT            f6
X		EC ............f7
X		EL             f8
X		GA ............f9
X		SB             fa
X		WILL ..........fb
X		WONT           fc
X		DO ............fd
X		DONT           fe
X		IAC ...........ff
X--------------------------------------------------------------------------*/
Xchar *
Xtelnet_cmd_text(tcmd)
Xu_char tcmd;
X{
Xstatic char static6[6];
X
X	switch(tcmd)
X	{
X		case IAC:		return("IAC");
X		case DONT:		return("DONT");
X		case DO:		return("DO");
X		case WONT:		return("WONT");
X		case WILL:		return("WILL");
X		case SB:		return("SB");
X		case GA:		return("GA");
X		case EL:		return("EL");
X		case EC:		return("EC");
X		case AYT:		return("AYT");
X		case AO:		return("AO");
X		case IP:		return("IP");
X		case BREAK:		return("BREAK");
X		case DM:		return("DM/SYNCH");
X		case NOP:		return("NOP");
X		case SE:		return("SE");
X		case EOR:		return("EOR");
X		default:
X			sprintf(static6,"?%02x?",tcmd);
X			return(static6);
X	}
X
X}	/* end of telnet_cmd_text */
X
X/*+-------------------------------------------------------------------------
X	telnet_option_text(topt)
X--------------------------------------------------------------------------*/
Xchar *
Xtelnet_option_text(topt)
Xu_char topt;
X{
Xstatic char static6[6];
X
X	switch(topt)
X	{
X		case TELOPT_BINARY:			return("BINARY");
X		case TELOPT_ECHO:			return("ECHO");
X		case TELOPT_RCP:			return("RCP");
X		case TELOPT_SGA:			return("SGA");
X		case TELOPT_NAMS:			return("NAMS");
X		case TELOPT_STATUS:			return("STATUS");
X		case TELOPT_TM:				return("TM");
X		case TELOPT_RCTE:			return("RCTE");
X		case TELOPT_NAOL:			return("NAOL");
X		case TELOPT_NAOP:			return("NAOP");
X		case TELOPT_NAOCRD:			return("NAOCRD");
X		case TELOPT_NAOHTS:			return("NAOHTS");
X		case TELOPT_NAOHTD:			return("NAOHTD");
X		case TELOPT_NAOFFD:			return("NAOFFD");
X		case TELOPT_NAOVTS:			return("NAOVTS");
X		case TELOPT_NAOVTD:			return("NAOVTD");
X		case TELOPT_NAOLFD:			return("NAOLFD");
X		case TELOPT_XASCII:			return("XASCII");
X		case TELOPT_LOGOUT:			return("LOGOUT");
X		case TELOPT_BM:				return("BM");
X		case TELOPT_DET:			return("DET");
X		case TELOPT_SUPDUP:			return("SUPDUP");
X		case TELOPT_SUPDUPOUTPUT:	return("SUPDUPOUTPUT");
X		case TELOPT_SNDLOC:			return("SNDLOC");
X		case TELOPT_TTYPE:			return("TTYPE");
X		case TELOPT_EOR:			return("EOR");
X		case TELOPT_EXOPL:			return("EXOPL");
X		default:
X			sprintf(static6,"?%02x?",topt);
X			return(static6);
X	}
X}	/* end of telnet_option_text */
X
X/*+-------------------------------------------------------------------------
X	telgetc_raw() - read character from telnet socket (waiting "forever")
X--------------------------------------------------------------------------*/
Xint
Xtelgetc_raw()
X{
Xint erc;
Xu_char schar;
X
X	while(1)
X	{
X		if(read(ts,&schar,1) <= 0)
X		{
X			if(errno == EINTR)
X				continue;
X			sperror("telgetc_raw");
X			hangup(128);
X		}
X
X#if defined(DEBUG)
X		if(debug > 9)
X			printf("<< %02x\n",schar);
X#endif
X		return((int)schar);
X
X	}
X	/*NOTREACHED*/
X}	/* end of telgetc_raw */
X
X/*+-------------------------------------------------------------------------
X	telnet_option(tcmd,topt)
X--------------------------------------------------------------------------*/
Xvoid
Xtelnet_option(tcmd,topt)
Xu_char tcmd;
Xu_char topt;
X{
X#if defined(DEBUG)
X	if(debug > 1)
X		printf("remote said %s %s\n",telnet_cmd_text(tcmd),
X			telnet_option_text(topt));
X#endif
X}	/* end of telnet_option */
X
X/*+-------------------------------------------------------------------------
X	_xmit_ttype()
X--------------------------------------------------------------------------*/
Xvoid
X_xmit_ttype()
X{
Xu_char buf[64];
Xu_char *cptr;
Xvoid telputcs();
X
X	cptr = buf;
X	*cptr++ = IAC;
X	*cptr++ = SB;
X	*cptr++ = TELOPT_TTYPE;
X	*cptr++ = TELQUAL_IS;
X	strcpy(cptr,Ottype);
X	cptr += strlen(Ottype);
X	*cptr++ = IAC;
X	*cptr++ = SE;
X	telputcs(buf,(int)(cptr - buf));
X}	/* end of _xmit_ttype */
X
X/*+-------------------------------------------------------------------------
X	telnet_subnegotiate()
X--------------------------------------------------------------------------*/
Xtelnet_subnegotiate()
X{
Xu_char topt_list[20];
Xregister u_char *topt_ptr = topt_list;
Xregister u_char *cptr;
Xint topt_count = 0;
Xu_int itmp;
Xu_char buf[64];
Xvoid telputcs();
X
X	while((*topt_ptr = telgetc_raw()) != IAC)
X	{
X		topt_ptr++;
X		topt_count++;
X	}
X	if((itmp = telgetc_raw()) != SE)
X	{
X		printf("subnegotiate: expected SE, got 0x%02x",itmp);
X		hangup(129);
X	}
X	topt_ptr = topt_list;
X	switch(*topt_ptr)
X	{
X		case TELOPT_BINARY:			itmp = DONT; break;
X		case TELOPT_ECHO:			itmp = Oecho; break;
X		case TELOPT_RCP:			itmp = -1;   break;
X		case TELOPT_SGA:			itmp = DONT; break;
X		case TELOPT_NAMS:			itmp = -1;   break;
X		case TELOPT_STATUS:			itmp = -1;   break;
X		case TELOPT_TM:				itmp = -1;   break;
X		case TELOPT_RCTE:			itmp = -1;   break;
X		case TELOPT_NAOL:			itmp = -1;   break;
X		case TELOPT_NAOP:			itmp = -1;   break;
X		case TELOPT_NAOCRD:			itmp = -1;   break;
X		case TELOPT_NAOHTS:			itmp = -1;   break;
X		case TELOPT_NAOHTD:			itmp = -1;   break;
X		case TELOPT_NAOFFD:			itmp = -1;   break;
X		case TELOPT_NAOVTS:			itmp = -1;   break;
X		case TELOPT_NAOVTD:			itmp = -1;   break;
X		case TELOPT_NAOLFD:			itmp = -1;   break;
X		case TELOPT_XASCII:			itmp = DONT; break;
X		case TELOPT_LOGOUT:			itmp = DONT; break;
X		case TELOPT_BM:				itmp = -1;   break;
X		case TELOPT_DET:			itmp = -1;   break;
X		case TELOPT_SUPDUP:			itmp = -1;   break;
X		case TELOPT_SUPDUPOUTPUT:	itmp = -1;   break;
X		case TELOPT_SNDLOC:			itmp = -1;   break;
X		case TELOPT_TTYPE:
X			if(*(topt_ptr + 1) == TELQUAL_SEND)
X			{
X				_xmit_ttype();
X				itmp = 0;
X#if defined(DEBUG)
X				if(debug > 1)
X					printf("> subnegotiate: our ttype %s\n",Ottype);
X#endif
X			}
X			break;
X		case TELOPT_EOR:			itmp = DONT; break;
X		case TELOPT_EXOPL:			itmp = DONT; break;
X	}
X
X	if(*(topt_ptr + 1) == TELQUAL_SEND)
X	{
X		if(itmp)		/* if not handled in switch statement */
X		{
X			if(itmp == -1)
X				printf("dont know how to subnegotiate %s\n",
X					telnet_option_text(*topt_ptr));
X			else
X			{
X				_xmit_opt((u_char)itmp,*topt_ptr);
X#if defined(DEBUG)
X				if(debug > 1)
X					printf("> subnegotiate %s %s\n",
X						telnet_cmd_text((u_char)itmp),
X						telnet_option_text(*topt_ptr));
X#endif
X			}
X		}
X	}
X#if defined(DEBUG)
X	else
X	{
X		sprintf(buf,"<< %s",telnet_option_text(*topt_ptr));
X		hex_dump(topt_ptr + 2,topt_count - 2,buf,1);
X	}
X#endif
X
X}	/* end of telnet_subnegotiate */
X
X/*+-------------------------------------------------------------------------
X	telnet_cmd() - IAC received: read and process command
X--------------------------------------------------------------------------*/
Xvoid
Xtelnet_cmd()
X{
Xint cmd;
X
X	switch(cmd = telgetc_raw())
X	{
X		case DONT:
X		case DO:
X		case WONT:
X		case WILL:
X			telnet_option(cmd,telgetc_raw());
X			break;
X		case SB:
X			telnet_subnegotiate();
X			break;
X		case GA:
X		case EL:
X		case EC:
X		case AYT:
X		case AO:
X		case IP:
X		case BREAK:
X		case DM:
X		case NOP:
X		case SE:
X		case EOR:
X#if defined(DEBUG)
X			if(debug > 3)
X				printf("< %s: ignored",telnet_cmd_text(cmd));
X#endif
X			break;
X
X	}
X}	/* end of telnet_cmd */
X
X/*+-------------------------------------------------------------------------
X	telgetc() - read character from telnet socket (waiting "forever")
Xif IAC (0xFF) received, process command
X--------------------------------------------------------------------------*/
Xint
Xtelgetc()
X{
Xint schar;
X
X	if((schar = telgetc_raw()) == IAC)
X	{
X		telnet_cmd();
X		return(-2);
X	}
X	return(schar);
X}	/* end of telgetc */
X
X/*+-------------------------------------------------------------------------
X	telgets(buf,timeout,delim,raw_flag) - read string from telnet socket
X
X1.  process IAC commands as found
X2.  timeout and die if timeout exceeded
X3.  if 'delim' != NULL and strlen(delim) != 0, look for delimiter string
X4.  otherwise, read and accumulate up to newline (omit newline)
X--------------------------------------------------------------------------*/
Xint
Xtelgets(buf,timeout,delim,raw_flag)
Xu_char *buf;
Xint timeout;
Xu_char *delim;
Xint raw_flag;
X{
Xregister read_count = 0;
Xregister delim_len = 0;
X#if defined(BSD43)
Xfd_set fdmask;
X#else
Xint fdmask;
X#endif
Xstruct timeval tv;
Xint erc;
Xu_char *read_ptr = buf;
Xint rdchar;
Xint cr_last = 0;
X
X	if(delim)
X		delim_len = strlen(delim);
X
X	while(1)
X	{
X		tv.tv_sec = (long)timeout;
X		tv.tv_usec = 0L;
X#if defined(BSD43)
X		FD_ZERO(&fdmask);
X		FD_SET(ts,&fdmask);
X#else
X		fdmask = 1 << ts;
X#endif
X		erc = select(32,(fd_set *)&fdmask,(fd_set *)0,(fd_set *)&fdmask,&tv);
X
X		if(erc < 0)
X		{
X			if(errno == EINTR)
X				continue;
X			sperror("telgets select");
X			hangup(128);
X		}
X		if(erc == 0)
X		{
X			printf("telgets timed out\n");
X			hangup(130);
X		}
X
X		if((rdchar = telgetc()) < 0)
X		{
X			if(rdchar == -2)	/* if select succeded for cmd (IAC) */
X				continue;
X			sperror("telgets");
X			hangup(128);
X		}
X
X		rdchar &= 0x7F;
X
X		switch(eol_type)
X		{
X			case 0:
X				if(!rdchar || (!raw_flag && (rdchar == CR)))
X					continue;
X				break;
X			case 1:
X				if(cr_last && (rdchar == 0))
X					rdchar = LF;
X				cr_last = (rdchar == CR);
X				if(!rdchar || (!raw_flag && cr_last))
X					continue;
X				break;
X		}
X
X		*read_ptr = rdchar;
X
X		/* look for delimiter */
X		if(delim_len && (read_count + 1 >= delim_len))
X		{
X			if(!strncmp(delim,read_ptr - delim_len + 1,delim_len))
X			{
X				*++read_ptr = 0;
X#if defined(DEBUG)
X				if(debug > 5)
X					hex_dump(buf,strlen(buf),"<< telgetcs",1);
X#endif
X				return(strlen(buf));
X			}
X		}
X
X		/* look for end of line */
X		if(*read_ptr == LF)
X		{
X			if(raw_flag)
X				*read_ptr++ = LF;
X			*read_ptr = 0;
X			return(strlen(buf));
X		}
X
X		read_count++; 
X		read_ptr++;
X	}
X	/* NOTREACHED */
X}	/* end of telgets */
X
X/*+-------------------------------------------------------------------------
X	telputc(schar) - send character to telnet socket
X--------------------------------------------------------------------------*/
Xvoid
Xtelputc(schar)
Xu_char schar;
X{
X	if(write(ts,&schar,1) != 1)
X	{
X		sperror("write error on telnet socket\n");
X		hangup(128);
X	}
X}	/* end of telputc */
X
X/*+-------------------------------------------------------------------------
X	telputcs(schars,count) - send characters to telnet socket
X
XThis function did NOT work when write(ts,schars,count) was used,
Xthough the write succeeded; this is a puzzle.  Does telnet do a recv()
Xcall, throwing away "packets" > 1 in length.
X--------------------------------------------------------------------------*/
Xvoid
Xtelputcs(schars,count)
Xu_char *schars;
Xint count;
X{
Xregister u_char *cptr = schars;
Xregister icount = count;
X
X	while(icount--)
X		telputc(*cptr++);
X
X#if defined(DEBUG)
X	if(debug > 5)
X		hex_dump(schars,count,">> telputcs",1);
X#endif
X}	/* end of telputcs */
X
X/*+-------------------------------------------------------------------------
X	telputs(sstr) - send null-terminated string to telnet socket
X--------------------------------------------------------------------------*/
Xvoid
Xtelputs(sstr)
Xchar *sstr;
X{
X	telputcs(sstr,strlen(sstr));
X}	/* end of telputs */
X
X/*+-------------------------------------------------------------------------
X	_xmit_opt(tcmd,topt) - common "send option" routine
X--------------------------------------------------------------------------*/
Xvoid
X_xmit_opt(tcmd,topt)
Xu_char tcmd;
Xu_char topt;
X{
Xu_char optbuf[8];
Xu_char *optptr = optbuf;
X
X	*optptr++ = IAC;
X	*optptr++ = tcmd;
X	*optptr++ = topt;
X	telputcs(optbuf,(int)(optptr - optbuf));
X
X	if(debug)
X		printf("> we say %s %s\n",telnet_cmd_text(tcmd),
X			telnet_option_text(topt));
X}	/* end of _xmit_opt */
X
X/*+-------------------------------------------------------------------------
X	will_use(topt) - send to remote system that we will use an option
X--------------------------------------------------------------------------*/
Xvoid
Xwill_use(topt)
Xu_char topt;
X{
X	_xmit_opt(WILL,topt);
X}	/* end of will_use */
X
X/*+-------------------------------------------------------------------------
X	wont_use(topt) - send to remote system that we wont use an option
X--------------------------------------------------------------------------*/
Xvoid
Xwont_use(topt)
Xu_char topt;
X{
X	_xmit_opt(WONT,topt);
X}	/* end of wont_use */
X
X/*+-------------------------------------------------------------------------
X	do_use(topt) - ask remote system to use an option
X--------------------------------------------------------------------------*/
Xvoid
Xdo_use(topt)
Xu_char topt;
X{
X	_xmit_opt(DO,topt);
X}	/* end of do_use */
X
X/*+-------------------------------------------------------------------------
X	dont_use(topt) - ask remote system not to use an option
X--------------------------------------------------------------------------*/
Xvoid
Xdont_use(topt)
Xu_char topt;
X{
X	_xmit_opt(DONT,topt);
X}	/* end of dont_use */
X
X/*+-------------------------------------------------------------------------
X	family_text(family)
X--------------------------------------------------------------------------*/
X#if defined(DEBUG)
Xchar *
Xfamily_text(family)
Xshort family;
X{
Xstatic char static32[32];
X
X	switch(family)
X	{
X		case AF_UNSPEC:		return("Unspecified");
X		case AF_UNIX:		return("UNIX");
X		case AF_INET:		return("INTERNET");
X		case AF_IMPLINK:	return("ARPANET/IMP");
X		case AF_PUP:		return("PUP");
X		case AF_CHAOS:		return("MIT CHAOS");
X		case AF_NS:			return("XEROX NS");
X		case AF_NBS:		return("NBS");
X		case AF_ECMA:		return("EUROPEAN");
X		case AF_DATAKIT:	return("DATAKIT");
X		case AF_CCITT:		return("CCITT");
X		case AF_SNA:		return("SNA");
X		case AF_DECnet:		return("DECnet");
X		case AF_DLI:		return("DATA LINK INTERFACE");
X		case AF_LAT:		return("LAT");
X		case AF_HYLINK:		return("NSC Hyperchannel");
X		case AF_APPLETALK:	return("Apple Talk");
X		case AF_ISO:		return("ISO");
X		default:
X			sprintf(static32,"number %d\n",family);
X			return(static32);
X	}
X	/*NOTREACHED*/
X
X}	/* end of family_text */
X#endif
X
X/*+-------------------------------------------------------------------------
X	d_sockaddr_in(sin) display INTERNET socket address
X--------------------------------------------------------------------------*/
X#if defined(DEBUG)
Xvoid
Xd_sockaddr_in(sin)
Xstruct sockaddr_in *sin;
X{
Xregister itmp;
X
X	printf("sockaddr_in @ %08lx family: %s port: 0x%04x\n",sin,
X		family_text(sin->sin_family),sin->sin_port);
X	printf("            port 0x%08lx",sin->sin_addr.s_addr);
X	fputs(" zero:",stdout);
X	for(itmp = 0; itmp < sizeof(sin->sin_zero); itmp++)
X		printf(" %02x",sin->sin_zero[itmp]);
X	fputs("\n\n",stdout);
X}	/* end of d_sockaddr_in */
X#endif
X
X/*+-------------------------------------------------------------------------
X	d_hostent(he) - display host entry
X--------------------------------------------------------------------------*/
X#if defined(DEBUG)
Xvoid
Xd_hostent(he)
Xstruct hostent *he;
X{
Xregister itmp;
Xu_char *haddr;
X
X	printf("hostent @ %08lx name: %s family: %s address:",he,
X		he->h_name,family_text(he->h_addrtype));
X#if defined(BSD43)
X	haddr = (u_char *)he->h_addr_list[0];
X#else
X	haddr = (u_char *)he->h_addr;
X#endif
X	itmp = he->h_length;
X	while(itmp--)
X		printf(" %02x",*haddr++);
X	fputs("\n\n",stdout);
X
X}	/* end of d_hostent */
X#endif
X
X/*+-------------------------------------------------------------------------
X	d_servent(se) - display server entry
X--------------------------------------------------------------------------*/
X#if defined(DEBUG)
Xvoid
Xd_servent(se)
Xstruct servent *se;
X{
X	printf("servent @ %08lx name: %s port: 0x%08x protocol: %s\n\n",se,
X		se->s_name,se->s_port,se->s_proto);
X}	/* end of d_servent */
X#endif
X
X/*+-------------------------------------------------------------------------
X	telsearch(maxlines,searchstr,timeout,delim,showit)
X
X1. read socket, for 'maxlines', looking for line containing 'searchstr'
X2. if 'timeout' seconds pass before completion, kill program
X3. use 'delim' for early termination of socket reads (before NL)
X4. if 'showit' non-zero, display socket data on stdout
X
Xreturn 1 if 'searchstr' found, else 0
X--------------------------------------------------------------------------*/
Xint
Xtelsearch(maxlines,searchstr,timeout,delim,showit)
Xint maxlines;
Xchar *searchstr;
Xint timeout;
Xchar *delim;
Xint showit;
X{
Xchar buf[256];
X
X	while(maxlines--)
X	{
X		telgets(buf,timeout,delim,1);
X		if(showit)
X			fputs(buf,stdout);
X		if(issubstr(buf,searchstr))
X			return(1);
X	}
X	return(0);
X}	/* end of telsearch */
X
X/*+-------------------------------------------------------------------------
X	main(argc,argv,envp)
X--------------------------------------------------------------------------*/
Xmain(argc,argv,envp)
Xint argc;
Xchar **argv;
Xchar **envp;
X{
Xregister char *cptr;
Xchar buf[BUFSIZ];
Xint connected = 0;		/* 1 = connected */
Xint itmp;
Xint proto_num;
Xstruct hostent *he;
Xstruct servent *se;
Xstruct sockaddr_in sin;
Xchar telnet1[3];
X
X#if defined(DEBUG)
X	setbuf(stdout,NULL);
X#endif
X
X	application_init(argc,argv);
X	if(!hostname || !*hostname)
X	{
X		printf("no hostname specified\n");
X		hangup(255);
X	}
X
X	sin.sin_addr.s_addr = inet_addr(hostname);
X	if(sin.sin_addr.s_addr != -1)
X	{
X		sin.sin_family = AF_INET;
X#if defined(DEBUG)
X		if(debug > 4)
X		{
X			printf("inet_addr success: %s\n",hostname);
X			d_sockaddr_in(&sin);
X		}
X#endif
X	}
X	else 
X	{
X		he = gethostbyname(hostname);
X		if(he == NULL)
X		{
X			printf("unknown host: %s\n",hostname);
X			hangup(255);
X		}
X
X#if defined(DEBUG)
X		if(debug > 4)
X		{
X			printf("gethostbyname success: %s\n",hostname);
X			d_hostent(he);
X		}
X#endif
X
X		sin.sin_family = he->h_addrtype;
X#if defined(BSD43)
X		bcopy(he->h_addr_list[0],(caddr_t)&sin.sin_addr,
X		    he->h_length);
X#else
X		bcopy(he->h_addr,(caddr_t)&sin.sin_addr,
X		    he->h_length);
X#endif
X	}
X
X	if(!(se = getservbyname("telnet","tcp")))
X	{
X		perror("getservbyname telnet/tcp");
X		hangup(131);
X	}
X
X	sin.sin_port = se->s_port;
X
X#if defined(DEBUG)
X	if(debug > 4)
X	{
X		printf("getservbyname success: telnet/tcp\n");
X		d_servent(se);
X	}
X#endif
X
X	do	
X	{
X		ts = socket(PF_INET,SOCK_STREAM,0);
X		if(ts < 0)
X		{
X			perror("socket()");
X			hangup(131);
X		}
X#if defined(DEBUG)
X		if(debug > 6)
X		{
X			printf("socket id %d\n",ts);
X			getsockopt(ts,SOL_SOCKET,SO_SNDBUF,(char *)&itmp,sizeof(int));
X			printf("send bufsize %d ",itmp,sizeof(int));
X			getsockopt(ts,SOL_SOCKET,SO_RCVBUF,(char *)&itmp,sizeof(int));
X			printf("receive bufsize %d ",itmp,sizeof(int));
X			getsockopt(ts,SOL_SOCKET,SO_TYPE,(char *)&itmp,sizeof(int));
X			printf("type %d \n",itmp,sizeof(int));
X			puts("");
X		}
X#endif
X
X		if(connect(ts,(struct sockaddr *)&sin,sizeof(sin)) < 0)
X		{
X#if defined(BSD43)
X			if(he && he->h_addr_list[1])
X			{
X				he->h_addr_list++;
X				bcopy(he->h_addr_list[0],(caddr_t)&sin.sin_addr,he->h_length);
X				close(ts);
X				continue;
X			}
X#endif
X			perror("connect()");
X			hangup(129);
X		}
X		connected++;
X	}	while(connected == 0);
X
X#if defined(DEBUG)
X	if(debug)
X		printf("connected to telnet at %s\n\n",hostname);
X#endif
X
X	do_use(TELOPT_SGA);
X	will_use(TELOPT_TTYPE);
X
X	application();
X
X	hangup(0);
X}	/* end of main */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of teleplay.c */
SHAR_EOF
chmod 0644 teleplay.c || echo "restore of teleplay.c fails"
fi
exit 0
-- 
-------------------------------------------------------------------
Warren Tucker, Tridom Corporation       ...!gatech!emory!tridom!wht 
Ker-au'-lo-phon.  An 8-foot partial flue-stop, having metal pipes
surmounted by adjustable rings, and with a hole bored near the top
of each pipe, producing a soft and "reedy" tone.