5 Author: Tatu Ylonen <ylo@cs.hut.fi>
7 Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
10 Created: Tue Mar 21 15:59:15 1995 ylo
12 Encoding and decoding of terminal modes in a portable way.
13 Much of the format is defined in ttymodes.h; it is included multiple times
14 into this file with the appropriate macro definitions to generate the
26 #define TTY_OP_ISPEED 192 /* int follows */
27 #define TTY_OP_OSPEED 193 /* int follows */
29 /* Converts POSIX speed_t to a baud rate. The values of the constants
30 for speed_t are not themselves portable. */
32 static int speed_to_baud(speed_t speed)
118 /* Converts a numeric baud rate to a POSIX speed_t. */
120 static speed_t baud_to_speed(int baud)
206 /* Encodes terminal modes for the terminal referenced by fd in a portable
207 manner, and appends the modes to a packet being constructed. */
209 void tty_make_modes(int fd)
215 if (tcgetattr(fd, &tio) < 0)
217 packet_put_char(TTY_OP_END);
218 log("tcgetattr: %.100s", strerror(errno));
222 /* Store input and output baud rates. */
223 baud = speed_to_baud(cfgetospeed(&tio));
224 packet_put_char(TTY_OP_OSPEED);
225 packet_put_int(baud);
226 baud = speed_to_baud(cfgetispeed(&tio));
227 packet_put_char(TTY_OP_ISPEED);
228 packet_put_int(baud);
230 /* Store values of mode flags. */
231 #define TTYCHAR(NAME, OP) \
232 packet_put_char(OP); packet_put_char(tio.c_cc[NAME]);
233 #define TTYMODE(NAME, FIELD, OP) \
234 packet_put_char(OP); packet_put_char((tio.FIELD & NAME) != 0);
235 #define SGTTYCHAR(NAME, OP)
236 #define SGTTYMODE(NAME, FIELD, OP)
237 #define SGTTYMODEN(NAME, FIELD, OP)
239 #include "ttymodes.h"
247 /* Mark end of mode data. */
248 packet_put_char(TTY_OP_END);
251 /* Decodes terminal modes for the terminal referenced by fd in a portable
252 manner from a packet being read. */
254 void tty_parse_modes(int fd, int *n_bytes_ptr)
261 /* Get old attributes for the terminal. We will modify these flags.
262 I am hoping that if there are any machine-specific modes, they will
263 initially have reasonable values. */
264 if (tcgetattr(fd, &tio) < 0)
270 opcode = packet_get_char();
278 baud = packet_get_int();
279 if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) < 0)
280 error("cfsetispeed failed for %d", baud);
285 baud = packet_get_int();
286 if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) < 0)
287 error("cfsetospeed failed for %d", baud);
290 #define TTYCHAR(NAME, OP) \
293 tio.c_cc[NAME] = packet_get_char(); \
295 #define TTYMODE(NAME, FIELD, OP) \
298 if (packet_get_char()) \
301 tio.FIELD &= ~NAME; \
303 #define SGTTYCHAR(NAME, OP)
304 #define SGTTYMODE(NAME, FIELD, OP)
305 #define SGTTYMODEN(NAME, FIELD, OP)
307 #include "ttymodes.h"
316 debug("Ignoring unsupported tty mode opcode %d (0x%x)",
318 /* Opcodes 0 to 127 are defined to have a one-byte argument. */
319 if (opcode >= 0 && opcode < 128)
322 (void)packet_get_char();
327 /* Opcodes 128 to 159 are defined to have an integer argument. */
328 if (opcode >= 128 && opcode < 160)
331 (void)packet_get_int();
335 /* It is a truly undefined opcode (160 to 255). We have no idea
336 about its arguments. So we must stop parsing. Note that some
337 data may be left in the packet; hopefully there is nothing more
338 coming after the mode data. */
339 log("parse_tty_modes: unknown opcode %d", opcode);
340 packet_integrity_check(0, 1, SSH_CMSG_REQUEST_PTY);
346 if (*n_bytes_ptr != n_bytes)
348 *n_bytes_ptr = n_bytes;
349 return; /* Don't process bytes passed */
353 return; /* Packet parsed ok but tty stuff failed */
355 /* Set the new modes for the terminal. */
356 if (tcsetattr(fd, TCSANOW, &tio) < 0)
357 log("Setting tty modes failed: %.100s", strerror(errno));