[comp.protocols.tcp-ip.ibmpc] Mods to CMU PC-IP for INT14, part 2/2

msa@clinet.FI (Markku Savela) (01/23/88)

	This is part 2 of my CMU PC-IP Telnet modifications containing:

	\PC-IP\SRCCMD\BTN	- Modified Basic TN

		MAKEFILE	- Build BTN.EXE (3COM variant only)
		TELNET.H	- "tnsemulate" added
		TELNET.C	- (modified from original TELNET.C)
		BTN.C		- (modified from original TN.C)
--
-- Markku Savela, UUCP: msa@clinet.fi
-- Nokia Information Systems (or Nokia Data Systems?)
-- P.O.BOX 780 SF-00101 HELSINKI, FINLAND
--
-*cut here*------------ \pc-ip\srccmd\btn\makefile -----------------

telnet.obj: telnet.c ..\..\include\tftp.h ..\..\include\em.h  telnet.h \
..\..\include\custom.h ..\..\include\ip.h
	cl /c /DMSC /Gs /I..\..\include /Zd /Zl telnet.c

btn.obj: btn.c ..\..\include\custom.h ..\..\include\ip.h telnet.h
	cl /c /DMSC /Gs /I..\..\include /Zd /Gs btn.c

btn.exe: telnet.obj btn.obj
	link btn telnet,btn,btn/map/noi,tftp4n tcp4n domain4n udp4n ip4n net4n 3com4n task4n pc4n int144n
	mapsym btn
	exemod btn.exe /stack 0a00

-*cut here*------------ \pc-ip\srccmd\btn\telnet.h -----------------

/* Copyright 1986 by Carnegie Mellon */
/*  Copyright 1986 by Carnegie Mellon  */
/*  See permission and disclaimer notice in file "cmu-note.h"  */
#include	<cmu-note.h>
/*  Copyright 1984 by the Massachusetts Institute of Technology  */
/*  See permission and disclaimer notice in file "notice.h"  */
#include	<notice.h>

/* 11-5-85	Added terminal type information, and option negotiation code
		from Jacob Rekhter, IBM Corp.
					<Drew D. Perkins>
 */

/* Definitions for telnet */

struct ucb {
	int	u_state;	/* ESTAB or CLOSING */
	int	u_tcpfull;	/* is tcp's output buffer full? */
	int	u_tftp;		/* tftp acceptance */
	int	u_rstate;	/* Read terminal state */
				/* NORMALMODE */
				/* BLOCK - don't read terminal */
	int	u_rspecial;	/* Read terminal character handling */
				/* NORMALMODE */
				/* SPECIAL - processing char after prompt */
				/* CONFIRM - quit confirmation */
				/* TCPFULL - tcp output buffer full */
	int	u_wstate;	/* Write terminal state */
				/* NORMALMODE */
				/* URGENTM - urgent mode
				   ignore nonspecial chars */
	int	u_wspecial;	/* Write terminal character handling */
				/* NORMALMODE */
				/* '\r' (13), IAC, WILL, WONT, DO, DONT -
				   processing special chars */
	int	u_prompt;	/* Prompt char */
	int	u_sendm;	/* Send mode */
				/* EVERYC - send to net on every char */
				/* NEWLINE - send to net on newline */
	int	u_echom;	/* Echo mode */
				/* LOCAL - local echo */
				/* REMOTE - remote echo */
	int	u_echongo;	/* Echo negotiation request outstanding */
				/* NORMALMODE */
				/* LECHOREQ - IAC DONT ECHO was sent */
				/* RECHOREQ - IAC DO ECHO was sent */
	int	u_mode;		/* status line on or off flag */
	int	u_ask;		/* ask about tftp transfers */
	int     u_terminal;	/* DDP - ASCII or 3278 */
	};

#define NORMALMODE		0
#define SPECIAL		1
/*
#define TEST		2
*/
#define	CONFIRM		3
#define HOLD		4

#define	TFUNKNOWN	1
#define TFWAITING	2
#define	TFYES		3
#define	TFNO		4

#define ASCII_TERM      1       /* DDP - ASCII terminal emulator */
#define E3278_TERM      2       /* DDP - 3278 emulator */

#define	BLOCK		1
#define NOBLOCK		2
#define URGENTM		1
#define EVERYC		1
#define NEWLINE		2
#define LOCAL		1
#define REMOTE		2
#define LECHOREQ	1
#define RECHOREQ	2

#define IAC	255
#define WILL	251
#define WONT	252
#define DO	253
#define DONT	254
#define DM	242
#define INTP	244
#define AO	245
#define AYT	246
#define GA	249
#define OPTECHO	1
#define	OPTSPGA	3
#define TERMTYPE	24	/* DDP - TERMINALtype */
#define TRANS_BIN	0	/* DDP - Transmit Binary */
#define SBNVT	250             /* DDP - SBnvt*/
#define SENVT	240             /* DDP - SEnvt */
#define IS	0               /* DDP - ISchar */
#define SEND	1               /* DDP - SEnvt */
#define EOR	239             /* DDP - End-of-Record */

#define	DFESC	'\036'		/* default escape char */

#define ESTAB	1
#define CLOSING	2
#define CLOSED	3

#define TELNETSOCK	23	/* Telnet well known socket no. */

extern struct ucb	ucb;
extern struct	task		*TNsend;	/* Telnet send task. */
extern int	speed;
extern char tnshost[];		/* foreign host's string name */
extern char tnsemulate[];	/* terminal emulation command */

-*cut here*------------ \pc-ip\srccmd\btn\telnet.c -----------------

/*  Copyright 1986 by Carnegie Mellon  */
/*  See permission and disclaimer notice in file "cmu-note.h"  */
#include	<cmu-note.h>
/*  Copyright 1984 by the Massachusetts Institute of Technology  */
/*  See permission and disclaimer notice in file "notice.h"  */
#include	<notice.h>


/*  Modified to send octal internet address on F10/control-I, to put
a blank after octal and decimal internet address, to leave the line-25
message containing "My internet address" displayed indefinitely, to
leave the message "file transfer in progress" on line 25 for the
duration of the transfer, to accept an upcall from the tftp server
when the transfer is complete, to display a message on line 25
indicating success or failure of that transfer, and to leave the
line-25 message "closing connection" displayed indefinitely, 12/23/83.
F10/A toggles TCP tracing, 12/28/83.
Line 25 message for tftp now gives name of file and host, 1/2/84.
					<J. H. Saltzer>
2/3/84 - changed to allow the status line (25th line) display to be
	turned off. <John Romkey>
2/8/84 - commented out call to scr_close() and _curse() because the
	emulator's stdne() already does it.	<John Romkey>
2/24/84 - changed code to use new printf internet address fields
	instead of having duplicated code all over the place.
						<John Romkey>
8/12/84 - added a space in the new printf() calls after the IP address.
						<John Romkey>
8/30/84 - added F10A to turn off TFTP server asking.
						<John Romkey>
6/2/85 - added F10/control menu and commands to toggle all debugging
        switches.
					      	<J. H. Saltzer>
10/14/85 - changed putchar("$") to putchar('$').  Made conditional changes
	for use with Microsoft C V3.00.
						<Drew D. Perkins>
11/14/85 - merged in changes for IBM 3278 emulation from Jacob Rekhter
	IBM/ACIS.
						<Drew D. Perkins>
1/9/86 - Send IAC DO ECHO upon opening of the connection.
						<Drew D. Perkins>
3/21/86	- Merge in color support for IBM 3279 emulation from Jacob Rekhter
	IBM/ACIS.
						<Drew D. Perkins>
3/32/86 - Break up gt_usr routine so MSC can optimize it.  It got too big.
						<Drew D. Perkins>
--------------------------------------------------------------------------
6/21/87 - Strip down to naked TELNET and prepare for external terminal
	emulation (via INT14 catcher).
						<Markku Savela>
*/

#include <stdio.h>
#include <types.h>
#include <task.h>
#include <q.h>
#include <netq.h>
#include <net.h>
#include <custom.h>
#include <netbuf.h>
#include <icmp.h>
#include <ip.h>
#include "telnet.h"
#include <em.h>
#include <tftp.h>
#ifdef MSC			/* DDP */
#include <process.h>		/* DDP */
#endif				/* DDP */

extern long cticks;	/* number of clock ticks since program start */
extern in_name tnhost;
extern int TIMERDEBUG;
extern int NBUF;

int chartest;
int scrntest;
int ct1time;
int ct2time;
int ctcount;
int st1time;
int st2time;

char buf1[80];
char numchar[10];

static char *term_types[] = {
	"ZENITH-H19",
	NULL
};

/*
 *	INT14 Interface area
 */

#define int14_high	2000

int int14_count = 0;			/* Number of characters in buffer */
int int14_tcpfull = 0;			/* Copied here for INT14TN access */
int int14_channel = 1;			/* Channel to intercept */

static char int14_buffer[int14_high];	/* Received data from telnet */
static char *int14_sp = &int14_buffer[1]; /* Next position to store */
static char *int14_fp = &int14_buffer[0]; /* Last position fetched */


tel_init() {
	register struct ucb *pucb;

	pucb = &ucb;

	pucb->u_state = ESTAB;
	pucb->u_tftp = TFUNKNOWN;
	pucb->u_tcpfull = 0;
	pucb->u_rstate = NORMALMODE;
	pucb->u_rspecial = NORMALMODE;
	pucb->u_wstate = NORMALMODE;
	pucb->u_wspecial = NORMALMODE;
	pucb->u_sendm = custom.c_1custom & NLSET ? NEWLINE : EVERYC;
	pucb->u_echom = REMOTE;
	pucb->u_echongo = NORMALMODE;
	pucb->u_mode = TRUE;

/*ms	pucb->u_ask = custom.c_1custom & TN_TFTP_ASK ? FALSE : TRUE; */
	pucb->u_ask = FALSE;
	
	chartest = 0;
	scrntest = 0;
	ct1time = 0;
	ct2time = 0;
	st1time = 0;
	st2time = 0;

	}

tel_exit() {
	}

/* Return true if telnet must run; false otherwise. */

mst_run() {
	return 1;
	}

bfr() {
	ucb.u_tcpfull = 0;
	int14_tcpfull = 0;
	}

/* gt_usr  Read nch chars from user's terminal
* When prompt char is encountered, go into
*  SPECIAL read mode and handle char following
*  prompt specially.
* Tc_put puts telnet chars into an output
*  to net packet.
*/

#define	int_stack_size	2000

gt_usr() {
	register struct ucb	*pucb;
	int	c;
	int	i;
	char	*stk;
	
	extern char *sys_errlist[];
	extern int errno;
	int retcode;

	if (!(stk = (char *)stk_alloc(int_stack_size))) {
		printf("\nCould not allocate internal stack\n");
		return(0);
	}
	_stk_fill(int_stack_size,stk);

	int14_enter(&stk[int_stack_size]);

	pucb = &ucb;

	tk_yield();

	if (tnsemulate[0])
		system(tnsemulate);
	else {
		printf("\nEntering inferior command interpreter. Do not execute any network programs.\n");
		printf("Use the EXIT command to return to telnet\n");
#ifdef MSC		/* DDP */
		retcode = spawnlp(P_WAIT, getenv("COMSPEC"), getenv("COMSPEC"), NULL); /* DDP */
#else			/* DDP */
		retcode = system(0);
#endif			/* DDP */
	};
	if(retcode < 0)
		printf("Can't exec command interpreter: %s\n", sys_errlist[errno]);
	else puts("Exiting Telnet\n");
	int14_exit();
}

/*
 *	This is called from INT14h to give a chance to the TCP/IP drivers...
 */
int14_yield () {
	tk_yield();
}

/*
 *	This is called from INT14h handler to retrieve the next character
 *	from the int14_buffer
 */
char int14_fetch() {
	int14_count--;
	if (int14_fp == &int14_buffer[int14_high])
		int14_fp = &int14_buffer[0];
	else
		int14_fp++;

	return *int14_fp;
}
/*
 *	Store character into int14_buffer (ignored, if the buffer is
 *	already full).
 */
int14_store(c)
register char c;
{
	if (int14_count <= int14_high) {
		*int14_sp = c & 0177;
		if (int14_sp == &int14_buffer[int14_high])
			int14_sp = &int14_buffer[0];
		else
			int14_sp++;
		int14_count++;
}
}
		
/*
 *	This routine is called from INT14h-catcher, when the external
 *	emulation wants to output a character to the communication line.
 */
int14_write(c)
register char c;
{
	register struct ucb	*pucb;

	pucb = &ucb;

	if(pucb->u_tcpfull) {
		tcpfull();
		return;
		}

	if(c == IAC) tc_put(IAC);
	else if(c == C_BREAK) {
		tc_put(IAC);
		tc_put(INTP);
		tc_put(IAC);
		tc_put(DM);
		tcpurgent();
		return;
		}

	if(pucb->u_sendm == EVERYC) {
		if(tc_fput(c)) tcpfull();
		}
	else {
		if(tc_put(c)) {
			tcpfull();
			return;
			}
		if(c == '\n') tcp_ex();
		}
}
/*
 *	wr_local is to be used for writing locally generated messages
 *	and texts to the local screen. Currently this just fills the
 *	same buffer as telnet connection (wr_usr). A separate window
 *	for these messages would be nice...
 */
wr_local(s)
	char	*s; {
	register char *p;
	for (p = s; *p != 0; p++) {
		if (*p == '\n') int14_store('\r');
		int14_store(*p);
	}
}

/* wr_usr  manage chars coming from net and
*   going to user
* Process received telnet special chars and
*  option negotiation.  When wstate is URGENTM,
*  only process special chars.
* All interrupts should be turned off
*  when in this routine - write to terminal
*  may block; an interrupt would cause
*  an error return from write with resulting
*  loss of chars to terminal
*/
wr_usr(buf, len, urg)
	char *buf;
	int len;
	int urg; {
	register struct ucb	*pucb;
	register char	*p;
	int c;
/* DDP - Begin changes */
	int i;
	static char **terminal = term_types;
	char *cp;

	pucb = &ucb;

	for(p = buf; p < buf+len; p++) {
		c = (*p & 0377);
		switch(pucb->u_wspecial) {
		case NORMALMODE:
			switch(c) {
			case IAC:
				pucb->u_wspecial = IAC;
				break;
			default:
				if(pucb->u_wstate != URGENTM)
					int14_store(c);

			}
			break;

		case IAC:
			switch(c) {
			case IAC:
				if(pucb->u_wstate != URGENTM)
					putchar(c);
				pucb->u_wspecial = NORMALMODE;
				break;

			case AO:
				tc_put(IAC);
				tc_put(DM);
				tcpurgent();
				pucb->u_wspecial = NORMALMODE;
				break;

			case WILL:
			case WONT:
			case DO:
			case DONT:
				pucb->u_wspecial = c;
				break;

/* DDP - Begin changes */
			case SBNVT:
				pucb->u_wspecial = c;
				break;

			case SENVT:
				tc_put(IAC);
				tc_put(SBNVT);
				tc_put(TERMTYPE);
				tc_put(IS);

				if(NDEBUG & APTRACE)
					wr_local("Telnet: Sending terminal type %s\n", *terminal);

				for (cp = *terminal; *cp; cp++)
					tc_put(*cp);
				if(terminal[1] != NULL)
					terminal++;
				tc_put(IAC);
				tc_fput(SENVT);
				pucb->u_wspecial = NORMALMODE;
				break;

		/* Ignore IAC x */
			default:
				pucb->u_wspecial = NORMALMODE;
				break;
				}
			break;

		case WILL:
			switch(c) {
			case OPTECHO:
				switch(pucb->u_echongo) {
		/* This host did not initiate echo negot - so respond */
				case NORMALMODE:
					if(pucb->u_echom != REMOTE)
						echoremote(pucb);
					break;
		/* Rejecting my IAC DONT ECHO  (illegit) */
				case LECHOREQ:
					ttechoremote(pucb);
					break;
					}

				pucb->u_echongo = NORMALMODE;
				break;

			case OPTSPGA:	/* suppress GA's */
				tc_put(IAC);
				tc_put(DO);
				tc_fput(c);
				break;

			default:
				tc_put(IAC);
				tc_put(DONT);
				tc_fput(c);
				break;
				}

			pucb->u_wspecial = NORMALMODE;
			break;

		case WONT:
			switch(c) {
			case OPTECHO:
				switch(pucb->u_echongo) {
		/* This host did not initiate echo negot - so respond */
				case NORMALMODE:
					if(pucb->u_echom != LOCAL)
						echolocal(pucb);
					break;
		/* Rejecting my IAC DO ECHO */
				case RECHOREQ:
					ttecholocal(pucb);
					break;
					}

				pucb->u_echongo = NORMALMODE;
				break;
				}

			pucb->u_wspecial = NORMALMODE;
			break;

		case DO:
/* DDP - Begin changes */
			switch (c) {
			case TERMTYPE:
				tc_put(IAC);
				tc_put(WILL);
				tc_fput(c);
				break;
			default:
				tc_put(IAC);
				tc_put(WONT);
				tc_fput(c);
				pucb->u_wspecial = NORMALMODE;
				break;
			}
/* DDP - End changes */

		case DONT:
			pucb->u_wspecial = NORMALMODE;
			break;

/* DDP - Begin changes */
		case SBNVT:
			if ( c != TERMTYPE)
				printf(" SBNVT c = %x\n", c & 0xff);
			pucb->u_wspecial = c;
			break;

		case TERMTYPE:
			if (c != SEND)
				printf(" TERMTYPE c = %x\n", c& 0xff);
			pucb->u_wspecial = c;
			break;
		case SEND:
			if (c != IAC)
				printf(" SEND c = %x\n", c & 0xff);
			pucb->u_wspecial = c;
			break;
/* DDP - End changes */
			}
		}
}


echolocal(pucb)
register struct ucb	*pucb;
{
	tc_put(IAC);
	tc_put(DONT);
	tc_fput(OPTECHO);
	pucb->u_echom = LOCAL;
/*	foptions(STECHO);	*/
}

ttecholocal(pucb)
	register struct ucb	*pucb; {

	pucb->u_echom = LOCAL;
/*	foptions(STECHO);	*/
	}

echoremote(pucb)
	register struct ucb	*pucb; {

	tc_put(IAC);
	tc_put(DO);
	tc_fput(OPTECHO);
	pucb->u_echom = REMOTE;
/*	foptions(STNECHO);		*/
	}

ttechoremote(pucb)
	register struct ucb	*pucb; {

	pucb->u_echom = REMOTE;
/*	foptions(STNECHO);		*/
	}

opn_usr() {
	echoremote();		/* DDP - Attempt to change to REMOTE echo */
	wr_local("Open\n"); }

cls_usr() {
	wr_local("Closed\n");
/*	tel_exit();	*/
	exit(); }

du_usr() {
	wr_local("Destination Unreachable\n");
/*	tel_exit();	*/
	exit(); }

tmo_usr() {
	wr_local("Host not responding\n");
/*	tel_exit();	let exit_hook do the work */
	exit(); }

pr_dot() {
	wr_local(".");
	}

tcpfull() {
	ucb.u_tcpfull = 1;
	int14_tcpfull = 1;
/*	fullbell();	*/
	}


tntftp(host, file, dir)
	in_name host;
	char *file;
	unsigned dir; {
	char buffer[80];
	char c;

	ring();

	if(host == tnhost){
	sprintf(buffer,"Host %s wants to %s file %s; OK? [F10/y or F10/n]",
			tnshost,  dir == PUT ? "read" : "write",file);
	sprintf(buf1,"Host %s is %s file %s\n",
			tnshost, dir == PUT ? "reading" : "writing", file);
			}
	else		{
	sprintf(buffer, "Host %a wants to %s file %s; OK? [F10/y or F10/n]",
				host, dir == PUT ? "read" : "write",file);
	sprintf(buf1, "Host %a is %s file %s\n",
			host, dir == PUT ? "reading" : "writing", file);
			}
	if(ucb.u_ask)
		wr_local(buffer);
	else
		wr_local(buf1);

/*if(FALSE)return true;*/	/*TEMPORARY DEBUGGING AID*/

	if(ucb.u_ask) {
		ucb.u_tftp = TFWAITING;

		while(ucb.u_tftp == TFWAITING) tk_yield();

		if(ucb.u_tftp == TFYES)
			return TRUE;
		else
			return FALSE;
		}
	else return TRUE;

	}  /*  end of tntftp()  */

/*  function called when file transfer is done.  */

tntfdn(success)
	int	success;
	{
	if (success) wr_local("File transfer successful.\n");
	    else     wr_local("File transfer failed.\n");
	ring();
	*buf1 = '\0';
	}

-*cut here*------------ \pc-ip\srccmd\btn\btn.c --------------------

/*  Copyright 1986 by Carnegie Mellon  */
/*  See permission and disclaimer notice in file "cmu-note.h"  */
#include	<cmu-note.h>
/*  Copyright 1984 by the Massachusetts Institute of Technology  */
/*  See permission and disclaimer notice in file "notice.h"  */
#include	<notice.h>

#include <stdio.h>
#include <string.h>
#include <types.h>
#include <task.h>
#include <q.h>
#include <netq.h>
#include <net.h>
#include <custom.h>
#include <netbuf.h>
#include <icmp.h>
#include	<ip.h>
#include	"telnet.h"

/*  Modified 12/23/83 to include upcalled "done" function in initialization
    of tftp server.  <J. H. Saltzer>
    Modified 1/2/84 to get window and low window sizes from the custom
    structure. <John Romkey>
    11/15/84 - fixed screen condition on error exit.
					<John Romkey>
    3/21/85 - Decreased initial stack size in tcp_init.  We no longer need as
    	much stack becuase the large array in rst_screen was made static
	instead of auto, saving 2000 bytes.
    					<Drew D. Perkins>
   10/30/86 - Added destination unreachable upcall.
    					<Drew D. Perkins>
   6/21/87  - Made a new version of the original tn.c for "naked" telnet
   	connection. Terminal emulation is done outside this utility.
					<Markku Savela>
   10/20/87 - Program argument handling made more robust.
   					<Markku Savela>
*/

#define	WAITCLS		5		/* close wait time */


struct ucb	ucb;
struct	task		*TNsend;	/* telnet data sending task */
int	speed;
in_name tnhost;

extern int wr_usr(), mst_run(), opn_usr(), cls_usr(), tmo_usr(), pr_dot();
extern int du_usr();			/* DDP */
extern int bfr();
extern int tn_flash();

extern int tntftp();
extern int tntfdn();

char usage[] = "usage: telnet [-p port] host [-e emulator command list]\n";
char tnshost[40];		/* Host Name string */
char tnsemulate[80];		/* Terminal Emulation Program */

main(argc, argv)
	int	argc;
	char	*argv[]; {

	if(!main_init(argc, argv))
		exit(1);

	tel_init();
	gt_usr();
	}

int tel_exit();

main_init(argc, argv)
	int	argc;
	char	*argv[]; {
	in_name	fhost;
	unsigned sock;
	unsigned fsock = TELNETSOCK;
	char **temp = argv;
	char *s;

	exit_hook(tel_exit);

	while (--argc > 0) {
		if ((*++temp)[0] == '-')
			for (s = temp[0]+1; *s != '\0'; s++) {
				switch (*s) {
				case 'p':
					if (--argc > 0)
						fsock = atoi(*++temp);
					else {
				printf("telnet: port number expected.\n");
				printf(usage);
				return FALSE;
					};
					break;
				case 'd':
					if (--argc > 0)
						NDEBUG = atoi(*++temp);
					else {
						printf("telnet: debug parameter expected.\n");
						printf(usage);
						return FALSE;
					};
					break;
				case 'e':
					s = tnsemulate;
					*s = '\0';
					while (--argc > 0) {
						*s++ = ' ';
						strcpy(s,*++temp);
						s = strchr(s,'\0');
					};
					s--;
					break;
						
				default:
					printf("telnet: unknow flag.\n");
					printf(usage);
					return FALSE;
				};
			}
		else {
			if (tnshost[0]) {
				printf("telnet: improper arguments.\n");
				printf(usage);
				return FALSE;
			};
			strcpy(tnshost,*temp);
		};

	};
			
	/* Initialize tasking and save our task's name. */
	NBUF = 14;

	/* need lots of stack because of terminal emulator */
#ifndef MSC				/* DDP - No longer true for MSC. */
	tcp_init(5500, opn_usr, wr_usr, mst_run, cls_usr, tmo_usr, pr_dot, bfr);
#else					/* DDP */
	tcp_init(2000, opn_usr, wr_usr, mst_run, cls_usr, tmo_usr, pr_dot, bfr); /* DDP */
#endif					/* DDP */
	tcp_duinit(du_usr);		/* DDP */

	fhost = resolve_name(tnshost);
	if(fhost == 0) {
		printf("Foreign host %s not known.\n", tnshost);
		return FALSE;
		}

	if(fhost == 1) {
		printf("Name servers not responding.\n");
		return FALSE;
		}

	tnhost = fhost;

	/* start the tftp server and turn it on with full buffering*/

/*ms	tfsinit(tntftp, tntfdn, FALSE); */
	tfsinit(tntftp, tntfdn, TRUE);
	tfs_on();

	printf("Trying...");

	sock = tcp_sock();	/* DDP */
	tcp_open(&fhost, fsock, sock, custom.c_telwin, custom.c_tellowwin);

	tk_yield();	/* let it start */

	return(TRUE);
	}