#include <stdio.h>
#include "global.h"
#include "mbuf.h"
#include "timer.h"
#include "icmp.h"
#include "netuser.h"
#include "tcp.h"
#include "telnet.h"
#include "session.h"

struct tcb *tnet_tcb;
tn1(argc,argv)
char *argv[];
{
	struct socket lsocket;
	extern int32 ip_addr;
	void tnet_state();
	void t_state(),rcv_char();
	char tos = 0;

	/* Incoming Telnet */
	lsocket.address = ip_addr;
	if(argc < 2)
		lsocket.port = TELNET_PORT;
	else {
		if ((lsocket.port = atoi(argv[1])) == 0)
			lsocket.port = TELNET_PORT;
		tos = get_tos(argv[2]);
	}
	tnet_tcb = open_tcp(&lsocket,NULLSOCK,TCP_SERVER,0,rcv_char,NULLVFP,tnet_state,tos,(char *)NULL);
	return 0;
}
/* Handle incoming Telnet connect requests by creating a Telnet session,
 * then change upcall vector so it behaves like an ordinary Telnet session.
 *
 */
static void
tnet_state(tcb,old,new)
struct tcb *tcb;
char old,new;
{
	struct telnet *tn;
	struct session *s,*newsession();
	long tloc;
	void t_state(),tn_tx();
	char *a;

	switch(new){
	case ESTABLISHED:
		log_tcp(tcb,"open Telnet");
		time(&tloc);
		/* Allocate a session descriptor */
		if((s = newsession()) == NULLSESSION){
			printf("\007%.15s Incoming Telnet call from %s refused; too many sessions\n",
			 ctime(&tloc) + 4,phsocket(&tcb->conn.remote));
			fflush(stdout);
			sndmsg(tcb,"Call rejected; too many sessions on remote system\n");
			close_tcp(tcb);
			return;
		}
		a = inet_n2h(tcb->conn.remote.address);
		if((s->name = malloc((unsigned)strlen(a)+1)) != NULLCHAR)
			strcpy(s->name,a);
		s->type = TELNET;
		s->parse = send_tel;
		/* Create and initialize a Telnet protocol descriptor */
		if((tn = (struct telnet *)calloc(1,sizeof(struct telnet))) == NULLTN){
			printf("\007%.15s Incoming Telnet call refused; no space\n",
				ctime(&tloc) + 4);
			fflush(stdout);
			sndmsg(tcb,"Call rejected; no space on remote system\n");
			close_tcp(tcb);
			s->type = FREE;
			return;
		}
		tn->session = s;	/* Upward pointer */
		tn->state = TS_DATA;
		s->cb.telnet = tn;	/* Downward pointer */

		tcb->user = (char *)tn; /* Upward pointer */
		tn->tcb = tcb;		/* Downward pointer */
		printf("\007%.15s Incoming Telnet session %lu from %s\n",
		 ctime(&tloc) + 4,(long)(s - sessions),phsocket(&tcb->conn.remote));
		fflush(stdout);
		tcb->s_upcall = t_state;
		tcb->t_upcall = tn_tx;
		return;
	case CLOSED:
		/* This will only happen if the connection closed before
		 * the session was set up, e.g., if we refused it because
		 * there were too many sessions, or if the server is being
		 * shut down.
		 */
		if(tcb == tnet_tcb)
			tnet_tcb = NULLTCB;
		del_tcp(tcb);
		break;
	}
}
tn0()
{
	if(tnet_tcb != NULLTCB)
		close_tcp(tnet_tcb);
	return 0;
}
static
sndmsg(tcb,msg)
struct tcb *tcb;
char *msg;
{
	struct mbuf *bp;

	bp = qstring(msg);
	send_tcp(tcb,bp);
}
