/*
 * Author: Tatu Ylonen <ylo@cs.hut.fi>
 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 *                    All rights reserved
 * Created: Tue Mar 21 15:59:15 1995 ylo
 * Encoding and decoding of terminal modes in a portable way.
 * Much of the format is defined in ttymodes.h; it is included multiple times
 * into this file with the appropriate macro definitions to generate the
 * suitable code.
 */

#include "includes.h"
RCSID("$Id: ttymodes.c,v 1.3 1999/11/25 00:54:59 damien Exp $");

#include "packet.h"
#include "ssh.h"

#define TTY_OP_END	0
#define TTY_OP_ISPEED	192	/* int follows */
#define TTY_OP_OSPEED	193	/* int follows */

/*
 * Converts POSIX speed_t to a baud rate.  The values of the
 * constants for speed_t are not themselves portable.
 */
static int 
speed_to_baud(speed_t speed)
{
	switch (speed) {
	case B0:
		return 0;
	case B50:
		return 50;
	case B75:
		return 75;
	case B110:
		return 110;
	case B134:
		return 134;
	case B150:
		return 150;
	case B200:
		return 200;
	case B300:
		return 300;
	case B600:
		return 600;
	case B1200:
		return 1200;
	case B1800:
		return 1800;
	case B2400:
		return 2400;
	case B4800:
		return 4800;
	case B9600:
		return 9600;

#ifdef B19200
	case B19200:
		return 19200;
#else /* B19200 */
#ifdef EXTA
	case EXTA:
		return 19200;
#endif /* EXTA */
#endif /* B19200 */

#ifdef B38400
	case B38400:
		return 38400;
#else /* B38400 */
#ifdef EXTB
	case EXTB:
		return 38400;
#endif /* EXTB */
#endif /* B38400 */

#ifdef B7200
	case B7200:
		return 7200;
#endif /* B7200 */
#ifdef B14400
	case B14400:
		return 14400;
#endif /* B14400 */
#ifdef B28800
	case B28800:
		return 28800;
#endif /* B28800 */
#ifdef B57600
	case B57600:
		return 57600;
#endif /* B57600 */
#ifdef B76800
	case B76800:
		return 76800;
#endif /* B76800 */
#ifdef B115200
	case B115200:
		return 115200;
#endif /* B115200 */
#ifdef B230400
	case B230400:
		return 230400;
#endif /* B230400 */
	default:
		return 9600;
	}
}

/*
 * Converts a numeric baud rate to a POSIX speed_t.
 */
static speed_t 
baud_to_speed(int baud)
{
	switch (baud) {
		case 0:
		return B0;
	case 50:
		return B50;
	case 75:
		return B75;
	case 110:
		return B110;
	case 134:
		return B134;
	case 150:
		return B150;
	case 200:
		return B200;
	case 300:
		return B300;
	case 600:
		return B600;
	case 1200:
		return B1200;
	case 1800:
		return B1800;
	case 2400:
		return B2400;
	case 4800:
		return B4800;
	case 9600:
		return B9600;

#ifdef B19200
	case 19200:
		return B19200;
#else /* B19200 */
#ifdef EXTA
	case 19200:
		return EXTA;
#endif /* EXTA */
#endif /* B19200 */

#ifdef B38400
	case 38400:
		return B38400;
#else /* B38400 */
#ifdef EXTB
	case 38400:
		return EXTB;
#endif /* EXTB */
#endif /* B38400 */

#ifdef B7200
	case 7200:
		return B7200;
#endif /* B7200 */
#ifdef B14400
	case 14400:
		return B14400;
#endif /* B14400 */
#ifdef B28800
	case 28800:
		return B28800;
#endif /* B28800 */
#ifdef B57600
	case 57600:
		return B57600;
#endif /* B57600 */
#ifdef B76800
	case 76800:
		return B76800;
#endif /* B76800 */
#ifdef B115200
	case 115200:
		return B115200;
#endif /* B115200 */
#ifdef B230400
	case 230400:
		return B230400;
#endif /* B230400 */
	default:
		return B9600;
	}
}

/*
 * Encodes terminal modes for the terminal referenced by fd
 * in a portable manner, and appends the modes to a packet
 * being constructed.
 */
void 
tty_make_modes(int fd)
{
	struct termios tio;
	int baud;

	if (tcgetattr(fd, &tio) < 0) {
		packet_put_char(TTY_OP_END);
		log("tcgetattr: %.100s", strerror(errno));
		return;
	}
	/* Store input and output baud rates. */
	baud = speed_to_baud(cfgetospeed(&tio));
	packet_put_char(TTY_OP_OSPEED);
	packet_put_int(baud);
	baud = speed_to_baud(cfgetispeed(&tio));
	packet_put_char(TTY_OP_ISPEED);
	packet_put_int(baud);

	/* Store values of mode flags. */
#define TTYCHAR(NAME, OP) \
  packet_put_char(OP); packet_put_char(tio.c_cc[NAME]);
#define TTYMODE(NAME, FIELD, OP) \
  packet_put_char(OP); packet_put_char((tio.FIELD & NAME) != 0);
#define SGTTYCHAR(NAME, OP)
#define SGTTYMODE(NAME, FIELD, OP)
#define SGTTYMODEN(NAME, FIELD, OP)

#include "ttymodes.h"

#undef TTYCHAR
#undef TTYMODE
#undef SGTTYCHAR
#undef SGTTYMODE
#undef SGTTYMODEN

	/* Mark end of mode data. */
	packet_put_char(TTY_OP_END);
}

/*
 * Decodes terminal modes for the terminal referenced by fd in a portable
 * manner from a packet being read.
 */
void 
tty_parse_modes(int fd, int *n_bytes_ptr)
{
	struct termios tio;
	int opcode, baud;
	int n_bytes = 0;
	int failure = 0;

	/*
	 * Get old attributes for the terminal.  We will modify these
	 * flags. I am hoping that if there are any machine-specific
	 * modes, they will initially have reasonable values.
	 */
	if (tcgetattr(fd, &tio) < 0)
		failure = -1;

	for (;;) {
		n_bytes += 1;
		opcode = packet_get_char();
		switch (opcode) {
		case TTY_OP_END:
			goto set;

		case TTY_OP_ISPEED:
			n_bytes += 4;
			baud = packet_get_int();
			if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) < 0)
				error("cfsetispeed failed for %d", baud);
			break;

		case TTY_OP_OSPEED:
			n_bytes += 4;
			baud = packet_get_int();
			if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) < 0)
				error("cfsetospeed failed for %d", baud);
			break;

#define TTYCHAR(NAME, OP) 				\
	case OP:					\
	  n_bytes += 1;					\
	  tio.c_cc[NAME] = packet_get_char();		\
	  break;
#define TTYMODE(NAME, FIELD, OP)		       	\
	case OP:					\
	  n_bytes += 1;					\
	  if (packet_get_char())			\
	    tio.FIELD |= NAME;				\
	  else						\
	    tio.FIELD &= ~NAME;				\
	  break;
#define SGTTYCHAR(NAME, OP)
#define SGTTYMODE(NAME, FIELD, OP)
#define SGTTYMODEN(NAME, FIELD, OP)

#include "ttymodes.h"

#undef TTYCHAR
#undef TTYMODE
#undef SGTTYCHAR
#undef SGTTYMODE
#undef SGTTYMODEN

		default:
			debug("Ignoring unsupported tty mode opcode %d (0x%x)",
			      opcode, opcode);
			/*
			 * Opcodes 0 to 127 are defined to have
			 * a one-byte argument.
			 */
			if (opcode >= 0 && opcode < 128) {
				n_bytes += 1;
				(void) packet_get_char();
				break;
			} else {
				/*
				 * Opcodes 128 to 159 are defined to have
				 * an integer argument.
				 */
				if (opcode >= 128 && opcode < 160) {
					n_bytes += 4;
					(void) packet_get_int();
					break;
				}
			}
			/*
			 * It is a truly undefined opcode (160 to 255).
			 * We have no idea about its arguments.  So we
			 * must stop parsing.  Note that some data may be
			 * left in the packet; hopefully there is nothing
			 * more coming after the mode data.
			 */
			log("parse_tty_modes: unknown opcode %d", opcode);
			packet_integrity_check(0, 1, SSH_CMSG_REQUEST_PTY);
			goto set;
		}
	}

set:
	if (*n_bytes_ptr != n_bytes) {
		*n_bytes_ptr = n_bytes;
		return;		/* Don't process bytes passed */
	}
	if (failure == -1)
		return;		/* Packet parsed ok but tty stuff failed */

	/* Set the new modes for the terminal. */
	if (tcsetattr(fd, TCSANOW, &tio) < 0)
		log("Setting tty modes failed: %.100s", strerror(errno));
	return;
}
