/*
 * 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.4 2000/04/16 01:18:49 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;
}
