/* 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 "busybox.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

#ifdef 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 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: Unknown 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:
*/

