
		****  terminal_1.c ****

*
     This program demonstrates the use of the simplest (polling) 
     method of using non blocking features in the socket library. 
     This program runs on CTOS only (not UNIX).  
     It must be linked with terminal.obj.
    
    
     Usage:
     
      terminal_1 hostname [remote_port [local_echo [debug level]]]
    
     The program supports a small subset of the Telnet protocol, which
     allows it to act as a very dumb terminal on some unix hosts
       use hostname 23 N to log on to unix
    
     If the server is echoserver or multecho, remote_port is 3000.
     local echo: Use y for yes
    
  
   OGA 090991  		MCsocket.lib build
   efw 092193  		TCP 2.2 build
  
    
                                                                            *

include <stdio.h>
include systypes.h
include syssocket.h
include netinetin.h
include netdb.h

	**** CTOSLIB functions ****

ifdef __BTOSC__
int ReadKbdDirect plm far (int mode, char *pCharRet);
int Delay plm far (int N);
else
define ReadKbdDirect @
define Delay @
include <ctos.lib.h>
endif

	**** defines ****

define CR 13				* ASCII                * 
define LF 10				* ASCII                * 
define KBDNOBLOCK  1		* ReadKbdDirect param  *
define NOCHARAVAIL  602 	* ReadKbdDirect erc    *
define BUFSZ 2048			* Buffer size for TCP  *
define KBDBUFFSZ 512		* Keyboard Buffer size *

	**** functions imported from terminal.c ****

void CheckArgs(int argc, char *argv[]);	* CheckArgs *
void CheckP(int N, char *msg);	* UNIX style return code check *
void CheckZ(int N, char *msg);	* CTOS Erc check               *
void InitTelnet();              * Telnet startup for unix      *
void RecvTelnet(unsigned char *iBf, int iBfSz);
                                * Telnet input processing for unix  *
	**** Global Data ****

extern unsigned int errno;	* global error code returned from system calls *
int Erc;					* last CTOS erc                            *
int Debug=0;				* Debugging                                *
char Kbuff[KBDBUFFSZ+1];	* keyboard buffer                          *
int Ksz=0;					*          ..... and pointer               *
int S;      				* file descriptor returned by socket call  *
int N;         				* return value of function calls           *
struct sockaddr_in server; 	* server socket address                    *
struct hostent *hp;    		* pointer to structure containing host address *
char inbuff[BUFSZ];			* input buffer                             *
char KeyChar;				* The character entered from keyboard      *
int LocalEcho;				* TRUE if remote does not echo             *
int LoopCt=0;				* times around main loop, with no data     *
int RemotePort=23;			* Default to the Telnet port               *

void main(int argc, char *argv[])
*******************************

* AF_INET is communications domain, SOCK_STREAM specifies the type of 
 * communications, and IPPROTO_TCP represents the protocol to be used. 
 *
{
	CheckArgs(argc, argv);
	S = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	CheckP((int)S, socket);
	server.sin_family = AF_INET;  					* assign domain *
	server.sin_port = htons(RemotePort);			* assign remote port*
	
* take the host name entered as an argument to this program
 *  and uses it to get the address of the remote host we connect to.
 *
	hp = gethostbyname(argv[1]);
	if (hp == NULL) {
        printf(invalid host argument = s\n,argv[1]);
        exit(1);
	}
	CheckP( (hp==NULL ? 1 : 0) , gethostbyname);
	
* take the h_addr field of the hostent structure returned by
 *  gethostbyname and copies it to the server address.
 *
	memcpy((char*)server.sin_addr.s_addr, hp>h_addr, hp>h_length);
	
										*connect to the remote host. *
	N = connect(S, server, sizeof(server)); 	
	checkP(N,connect);
	printf(polling terminal  connect successful\n);
	printf(\npress FINISH to Exit\n\n);
	if (RemotePort==23){
		InitTelnet();
		printf(InitTelnet\n);
	}

 	for(;;){

		Erc = ReadKbdDirect(KBDNOBLOCK, KeyChar);		* first check KBD *
		if (Erc){
			if (Erc =NOCHARAVAIL) CheckZ(Erc, readkbd);
		}else{
			if (KeyChar==0x04){
				sclose(S);
				exit(0);
			}
			if (LocalEcho)
				fwrite(KeyChar, 1, 1, stdout);
			if (Ksz>=KBDBUFFSZ) Ksz;
			Kbuff[Ksz++]=KeyChar;
			if (KeyChar == LF){		* LF is the CTOS 'return' key       *
				Kbuff[Ksz1]=CR;	* The SMPT protocol,  some others  *
				Kbuff[Ksz++]=LF;	*  require messages terminated CRLF *
				N = ssend (S, Kbuff, Ksz, 0);
				CheckP(N, ssend);
				Ksz=0;
			}
			LoopCt=0;
		}	
													 * next, check incoming *
		N = recv(S, inbuff, sizeof(inbuff), MSG_NOBLOCK);
		if (N<0) {
			if (errno = EWOULDBLOCK) CheckP (N, recv);
		}else{
			RecvTelnet((unsigned char*)inbuff, N);
			LoopCt=0;
		}
		
		if (LoopCt++>2){
			if (LocalEcho  Ksz){
				N = ssend (S, Kbuff, Ksz, 0);
				CheckP(N, ssend);
				Ksz=0;
			}
			Delay(1);
		}
		
	} *end for *
} * end main *
