/* vi: set sw=4 ts=4: */
/*
 * telnet implementation for busybox
 *
 * Author: Tomi Ollila <too@iki.fi>
 * Copyright (C) 1994-2000 by Tomi Ollila
 *
 * Created: Thu Apr  7 13:29:41 1994 too
 * Last modified: Fri Jun  9 14:34:24 2000 too
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * HISTORY
 * Revision 3.1  1994/04/17  11:31:54  too
 * initial revision
 * Modified 2000/06/13 for inclusion into BusyBox by Erik Andersen
 * <andersen@lineo.com> 
 *
 */


#include "internal.h"
#include <termios.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <signal.h>
#include <arpa/telnet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#if 0
#define DOTRACE 1
#endif

#if DOTRACE
#include <arpa/inet.h> /* for inet_ntoa()... */
#define TRACE(x, y) do { if (x) printf y; } while (0)
#else
#define TRACE(x, y) 
#endif

#if 0
#define USE_POLL
#include <sys/poll.h>
#else
#include <sys/time.h>
#endif

#define DATABUFSIZE 128
#define IACBUFSIZE 128

#define CHM_TRY 0
#define CHM_ON	1
#define CHM_OFF	2

#define UF_ECHO	0x01
#define UF_SGA	0x02

#define TS_0	1
#define TS_IAC	2
#define TS_OPT	3
#define TS_SUB1 4
#define TS_SUB2	5

#define WriteCS(fd, str) write(fd, str, sizeof str -1)

typedef unsigned char byte;

/* use globals to reduce size ??? */ /* test this hypothesis later */
struct Globalvars {
	int		netfd; /* console fd:s are 0 and 1 (and 2) */
    /* same buffer used both for network and console read/write */
	char *	buf; /* allocating so static size is smaller */
	short	len;
	byte	telstate; /* telnet negotiation state from network input */
	byte	telwish;  /* DO, DONT, WILL, WONT */
	byte    charmode;
	byte    telflags;
	byte	gotsig;
	/* buffer to handle telnet negotiations */
	char *	iacbuf;
	short	iaclen; /* could even use byte */
	struct termios termios_def;	
	struct termios termios_raw;	
} G;

#define xUSE_GLOBALVAR_PTR /* xUSE... -> don't use :D (makes smaller code) */

#ifdef USE_GLOBALVAR_PTR
struct Globalvars * Gptr;
#define G (*Gptr)
#else
struct Globalvars G;
#endif

static inline void iacflush()
{
	write(G.netfd, G.iacbuf, G.iaclen);
	G.iaclen = 0;
}

/* Function prototypes */
static int getport(char * p);
static struct in_addr getserver(char * p);
static int create_socket();
static void setup_sockaddr_in(struct sockaddr_in * addr, int port);
static int remote_connect(struct in_addr addr, int port);
static void rawmode();
static void cookmode();
static void do_linemode();
static void will_charmode();
static void telopt(byte c);
static int subneg(byte c);
#if 0
static int local_bind(int port);
#endif

/* Some globals */
static int one = 1;
static const char telnet_usage[] =
	"telnet host [port]\n"
#ifndef BB_FEATURE_TRIVIAL_HELP
	"\nTelnet is used to establish interactive communication with another\n"
	"computer over a network using the TELNET protocol.\n"
#endif
	;


static void doexit(int ev)
{
	cookmode();
	exit(ev);
}	

static void conescape()
{
	char b;

	if (G.gotsig)	/* came from line  mode... go raw */
		rawmode();

	WriteCS(1, "\r\nConsole escape. Commands are:\r\n\n"
			" l	go to line mode\r\n"
			" c	go to character mode\r\n"
			" z	suspend telnet\r\n"
			" e	exit telnet\r\n");

	if (read(0, &b, 1) <= 0)
		doexit(1);

	switch (b)
	{
	case 'l':
		if (!G.gotsig)
		{
			do_linemode();
			goto rrturn;
		}
		break;
	case 'c':
		if (G.gotsig)
		{
			will_charmode();
			goto rrturn;
		}
		break;
	case 'z':
		cookmode();
		kill(0, SIGTSTP);
		rawmode();
		break;
	case 'e':
		doexit(0);
	}

	WriteCS(1, "continuing...\r\n");

	if (G.gotsig)
		cookmode();
	
 rrturn:
	G.gotsig = 0;
	
}
static void handlenetoutput()
{
	/*	here we could do smart tricks how to handle 0xFF:s in output
	 *	stream  like writing twice every sequence of FF:s (thus doing
	 *	many write()s. But I think interactive telnet application does
	 *	not need to be 100% 8-bit clean, so changing every 0xff:s to
	 *	0x7f:s */

	int i;
	byte * p = G.buf;

	for (i = G.len; i > 0; i--, p++)
	{
		if (*p == 0x1d)
		{
			conescape();
			return;
		}
		if (*p == 0xff)
			*p = 0x7f;
	}
	write(G.netfd, G.buf, G.len);
}


static void handlenetinput()
{
	int i;
	int cstart = 0;

	for (i = 0; i < G.len; i++)
	{
		byte c = G.buf[i];

		if (G.telstate == 0) /* most of the time state == 0 */
		{
			if (c == IAC)
			{
				cstart = i;
				G.telstate = TS_IAC;
			}
		}
		else
			switch (G.telstate)
			 {
			 case TS_0:
				 if (c == IAC)
					 G.telstate = TS_IAC;
				 else
					 G.buf[cstart++] = c;
				 break;

			 case TS_IAC:
				 if (c == IAC) /* IAC IAC -> 0xFF */
				 {
					 G.buf[cstart++] = c;
					 G.telstate = TS_0;
					 break;
				 }
				 /* else */
				 switch (c)
				 {
				 case SB:
					 G.telstate = TS_SUB1;
					 break;
				 case DO:
				 case DONT:
				 case WILL:
				 case WONT:
					 G.telwish =  c;
					 G.telstate = TS_OPT;
					 break;
				 default:
					 G.telstate = TS_0;	/* DATA MARK must be added later */
				 }
				 break;
			 case TS_OPT: /* WILL, WONT, DO, DONT */
				 telopt(c);
				 G.telstate = TS_0;
				 break;
			 case TS_SUB1: /* Subnegotiation */
			 case TS_SUB2: /* Subnegotiation */
				 if (subneg(c) == TRUE)
					 G.telstate = TS_0;
				 break;
			 }
	}
	if (G.telstate)
	{
		if (G.iaclen)			iacflush();
		if (G.telstate == TS_0)	G.telstate = 0;

		G.len = cstart;
	}

	if (G.len)
		write(1, G.buf, G.len);
}


/* ******************************* */

static inline void putiac(int c)
{
	G.iacbuf[G.iaclen++] = c;
}


static void putiac2(byte wwdd, byte c)
{
	if (G.iaclen + 3 > IACBUFSIZE)
		iacflush();

	putiac(IAC);
	putiac(wwdd);
	putiac(c);
}

#if 0
static void putiac1(byte c)
{
	if (G.iaclen + 2 > IACBUFSIZE)
		iacflush();

	putiac(IAC);
	putiac(c);
}
#endif

/* void putiacstring (subneg strings) */

/* ******************************* */

char const escapecharis[] = "\r\nEscape character is ";

static void setConMode()
{
	if (G.telflags & UF_ECHO)
	{
		if (G.charmode == CHM_TRY) {
			G.charmode = CHM_ON;
			fprintf(stdout, "\r\nEntering character mode%s'^]'.\r\n", escapecharis);
			rawmode();
		}
	}
	else
	{
		if (G.charmode != CHM_OFF) {
			G.charmode = CHM_OFF;
			fprintf(stdout, "\r\nEntering line mode%s'^C'.\r\n", escapecharis);
			cookmode();
		}
	}
}

/* ******************************* */

static void will_charmode()
{
	G.charmode = CHM_TRY;
	G.telflags |= (UF_ECHO | UF_SGA);
	setConMode();
  
	putiac2(DO, TELOPT_ECHO);
	putiac2(DO, TELOPT_SGA);
	iacflush();
}

static void do_linemode()
{
	G.charmode = CHM_TRY;
	G.telflags &= ~(UF_ECHO | UF_SGA);
	setConMode();

	putiac2(DONT, TELOPT_ECHO);
	putiac2(DONT, TELOPT_SGA);
	iacflush();
}

/* ******************************* */

static inline void to_notsup(char c)
{
	if      (G.telwish == WILL)	putiac2(DONT, c);
	else if (G.telwish == DO)	putiac2(WONT, c);
}

static inline void to_echo()
{
	/* if server requests ECHO, don't agree */
	if      (G.telwish == DO) {	putiac2(WONT, TELOPT_ECHO);	return; }
	else if (G.telwish == DONT)	return;
  
	if (G.telflags & UF_ECHO)
	{
		if (G.telwish == WILL)
			return;
	}
	else
		if (G.telwish == WONT)
			return;

	if (G.charmode != CHM_OFF)
		G.telflags ^= UF_ECHO;

	if (G.telflags & UF_ECHO)
		putiac2(DO, TELOPT_ECHO);
	else
		putiac2(DONT, TELOPT_ECHO);

	setConMode();
	WriteCS(1, "\r\n");  /* sudden modec */
}

static inline void to_sga()
{
	/* daemon always sends will/wont, client do/dont */

	if (G.telflags & UF_SGA)
	{
		if (G.telwish == WILL)
			return;
	}
	else
		if (G.telwish == WONT)
			return;
  
	if ((G.telflags ^= UF_SGA) & UF_SGA) /* toggle */
		putiac2(DO, TELOPT_SGA);
	else
		putiac2(DONT, TELOPT_SGA);

	return;
}

static void telopt(byte c)
{
	switch (c)
	{
	case TELOPT_ECHO:		to_echo(c);		break;
	case TELOPT_SGA:		to_sga(c);		break;
	default:				to_notsup(c);	break;
	}
}


/* ******************************* */

/* subnegotiation -- ignore all */

static int subneg(byte c)
{
	switch (G.telstate)
	{
	case TS_SUB1:
		if (c == IAC)
			G.telstate = TS_SUB2;
		break;
	case TS_SUB2:
		if (c == SE)
			return TRUE;
		G.telstate = TS_SUB1;
		/* break; */
	}
	return FALSE;
}

/* ******************************* */

static void fgotsig(int sig)
{
	G.gotsig = sig;
}


static void rawmode()
{
	tcsetattr(0, TCSADRAIN, &G.termios_raw);
}	

static void cookmode()
{
	tcsetattr(0, TCSADRAIN, &G.termios_def);
}

extern int telnet_main(int argc, char** argv)
{
	struct in_addr host;
	int port;
#ifdef USE_POLL
	struct pollfd ufds[2];
#else	
	fd_set readfds;
	int maxfd;
#endif	


	memset(&G, 0, sizeof G);

	if (tcgetattr(0, &G.termios_def) < 0)
		exit(1);
	
	G.termios_raw = G.termios_def;

	cfmakeraw(&G.termios_raw);
	
	if (argc < 2)	usage(telnet_usage);
	port = (argc > 2)? getport(argv[2]): 23;
	
	G.buf = xmalloc(DATABUFSIZE);
	G.iacbuf = xmalloc(IACBUFSIZE);
	
	host = getserver(argv[1]);

	G.netfd = remote_connect(host, port);

	signal(SIGINT, fgotsig);

#ifdef USE_POLL
	ufds[0].fd = 0; ufds[1].fd = G.netfd;
	ufds[0].events = ufds[1].events = POLLIN;
#else	
	FD_ZERO(&readfds);
	FD_SET(0, &readfds);
	FD_SET(G.netfd, &readfds);
	maxfd = G.netfd + 1;
#endif
	
	while (1)
	{
#ifndef USE_POLL
		fd_set rfds = readfds;
		
		switch (select(maxfd, &rfds, NULL, NULL, NULL))
#else
		switch (poll(ufds, 2, -1))
#endif			
		{
		case 0:
			/* timeout */
		case -1:
			/* error, ignore and/or log something, bay go to loop */
			if (G.gotsig)
				conescape();
			else
				sleep(1);
			break;
		default:

#ifdef USE_POLL
			if (ufds[0].revents) /* well, should check POLLIN, but ... */
#else				
			if (FD_ISSET(0, &rfds))
#endif				
			{
				G.len = read(0, G.buf, DATABUFSIZE);

				if (G.len <= 0)
					doexit(0);

				TRACE(0, ("Read con: %d\n", G.len));
				
				handlenetoutput();
			}

#ifdef USE_POLL
			if (ufds[1].revents) /* well, should check POLLIN, but ... */
#else				
			if (FD_ISSET(G.netfd, &rfds))
#endif				
			{
				G.len = read(G.netfd, G.buf, DATABUFSIZE);

				if (G.len <= 0)
				{
					WriteCS(1, "Connection closed by foreign host.\r\n");
					doexit(1);
				}
				TRACE(0, ("Read netfd (%d): %d\n", G.netfd, G.len));

				handlenetinput();
			}
		}
	}
}

static int getport(char * p)
{
	unsigned int port = atoi(p);

	if ((unsigned)(port - 1 ) > 65534)
	{
		fatalError("%s: bad port number\n", p);
	}
	return port;
}

static struct in_addr getserver(char * host)
{
	struct in_addr addr;
	
	struct hostent * he;
	if ((he = gethostbyname(host)) == NULL)
	{
		fatalError("%s: Unkonwn host\n", host);
	}
	memcpy(&addr, he->h_addr, sizeof addr);

	TRACE(1, ("addr: %s\n", inet_ntoa(addr)));
	
	return addr;
}	

static int create_socket()
{
	return socket(AF_INET, SOCK_STREAM, 0);
}

static void setup_sockaddr_in(struct sockaddr_in * addr, int port)
{
	memset(addr, 0, sizeof addr);
	addr->sin_family = AF_INET;
	addr->sin_port = htons(port);
}
  
#if 0
static int local_bind(int port)
{
	struct sockaddr_in s_addr;
	int s = create_socket();
  
	setup_sockaddr_in(&s_addr, port);
  
	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
  
	if (bind(s, &s_addr, sizeof s_addr) < 0)
	{
		char * e = sys_errlist[errno];
		syserrorexit("bind");
		exit(1);
	}
	listen(s, 1);
	
	return s;
}
#endif

static int remote_connect(struct in_addr addr, int port)
{
	struct sockaddr_in s_addr;
	int s = create_socket();

	setup_sockaddr_in(&s_addr, port);
	s_addr.sin_addr = addr;

	setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof one);

	if (connect(s, (struct sockaddr *)&s_addr, sizeof s_addr) < 0)
	{
		fatalError("Unable to connect to remote host: %s\n", strerror(errno));
	}
	return s;
}

/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/

