[BACK]Return to ttymodes.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/ttymodes.c, Revision 1.6.2.2

1.1       deraadt     1: /*
1.4       deraadt     2:  * Author: Tatu Ylonen <ylo@cs.hut.fi>
                      3:  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                      4:  *                    All rights reserved
                      5:  * Encoding and decoding of terminal modes in a portable way.
                      6:  * Much of the format is defined in ttymodes.h; it is included multiple times
                      7:  * into this file with the appropriate macro definitions to generate the
                      8:  * suitable code.
1.6.2.2 ! jason       9:  *
        !            10:  * As far as I am concerned, the code I have written for this software
        !            11:  * can be used freely for any purpose.  Any derived versions of this
        !            12:  * software must be clearly marked as such, and if the derived work is
        !            13:  * incompatible with the protocol description in the RFC file, it must be
        !            14:  * called by a name other than "ssh" or "Secure Shell".
1.4       deraadt    15:  */
1.1       deraadt    16:
                     17: #include "includes.h"
1.6.2.2 ! jason      18: RCSID("$OpenBSD: ttymodes.c,v 1.8 2000/09/07 20:27:55 deraadt Exp $");
1.1       deraadt    19:
                     20: #include "packet.h"
                     21: #include "ssh.h"
                     22:
                     23: #define TTY_OP_END     0
1.3       markus     24: #define TTY_OP_ISPEED  192     /* int follows */
                     25: #define TTY_OP_OSPEED  193     /* int follows */
1.1       deraadt    26:
1.4       deraadt    27: /*
                     28:  * Converts POSIX speed_t to a baud rate.  The values of the
                     29:  * constants for speed_t are not themselves portable.
                     30:  */
1.6       markus     31: static int
1.3       markus     32: speed_to_baud(speed_t speed)
1.1       deraadt    33: {
1.3       markus     34:        switch (speed) {
                     35:        case B0:
                     36:                return 0;
                     37:        case B50:
                     38:                return 50;
                     39:        case B75:
                     40:                return 75;
                     41:        case B110:
                     42:                return 110;
                     43:        case B134:
                     44:                return 134;
                     45:        case B150:
                     46:                return 150;
                     47:        case B200:
                     48:                return 200;
                     49:        case B300:
                     50:                return 300;
                     51:        case B600:
                     52:                return 600;
                     53:        case B1200:
                     54:                return 1200;
                     55:        case B1800:
                     56:                return 1800;
                     57:        case B2400:
                     58:                return 2400;
                     59:        case B4800:
                     60:                return 4800;
                     61:        case B9600:
                     62:                return 9600;
1.1       deraadt    63:
                     64: #ifdef B19200
1.3       markus     65:        case B19200:
                     66:                return 19200;
1.1       deraadt    67: #else /* B19200 */
                     68: #ifdef EXTA
1.3       markus     69:        case EXTA:
                     70:                return 19200;
1.1       deraadt    71: #endif /* EXTA */
                     72: #endif /* B19200 */
                     73:
                     74: #ifdef B38400
1.3       markus     75:        case B38400:
                     76:                return 38400;
1.1       deraadt    77: #else /* B38400 */
                     78: #ifdef EXTB
1.3       markus     79:        case EXTB:
                     80:                return 38400;
1.1       deraadt    81: #endif /* EXTB */
                     82: #endif /* B38400 */
                     83:
                     84: #ifdef B7200
1.3       markus     85:        case B7200:
                     86:                return 7200;
1.1       deraadt    87: #endif /* B7200 */
                     88: #ifdef B14400
1.3       markus     89:        case B14400:
                     90:                return 14400;
1.1       deraadt    91: #endif /* B14400 */
                     92: #ifdef B28800
1.3       markus     93:        case B28800:
                     94:                return 28800;
1.1       deraadt    95: #endif /* B28800 */
                     96: #ifdef B57600
1.3       markus     97:        case B57600:
                     98:                return 57600;
1.1       deraadt    99: #endif /* B57600 */
                    100: #ifdef B76800
1.3       markus    101:        case B76800:
                    102:                return 76800;
1.1       deraadt   103: #endif /* B76800 */
                    104: #ifdef B115200
1.3       markus    105:        case B115200:
                    106:                return 115200;
1.1       deraadt   107: #endif /* B115200 */
                    108: #ifdef B230400
1.3       markus    109:        case B230400:
                    110:                return 230400;
1.1       deraadt   111: #endif /* B230400 */
1.3       markus    112:        default:
                    113:                return 9600;
                    114:        }
1.1       deraadt   115: }
                    116:
1.4       deraadt   117: /*
                    118:  * Converts a numeric baud rate to a POSIX speed_t.
                    119:  */
1.6       markus    120: static speed_t
1.3       markus    121: baud_to_speed(int baud)
1.1       deraadt   122: {
1.3       markus    123:        switch (baud) {
                    124:                case 0:
                    125:                return B0;
                    126:        case 50:
                    127:                return B50;
                    128:        case 75:
                    129:                return B75;
                    130:        case 110:
                    131:                return B110;
                    132:        case 134:
                    133:                return B134;
                    134:        case 150:
                    135:                return B150;
                    136:        case 200:
                    137:                return B200;
                    138:        case 300:
                    139:                return B300;
                    140:        case 600:
                    141:                return B600;
                    142:        case 1200:
                    143:                return B1200;
                    144:        case 1800:
                    145:                return B1800;
                    146:        case 2400:
                    147:                return B2400;
                    148:        case 4800:
                    149:                return B4800;
                    150:        case 9600:
                    151:                return B9600;
1.1       deraadt   152:
                    153: #ifdef B19200
1.3       markus    154:        case 19200:
                    155:                return B19200;
1.1       deraadt   156: #else /* B19200 */
                    157: #ifdef EXTA
1.3       markus    158:        case 19200:
                    159:                return EXTA;
1.1       deraadt   160: #endif /* EXTA */
                    161: #endif /* B19200 */
                    162:
                    163: #ifdef B38400
1.3       markus    164:        case 38400:
                    165:                return B38400;
1.1       deraadt   166: #else /* B38400 */
                    167: #ifdef EXTB
1.3       markus    168:        case 38400:
                    169:                return EXTB;
1.1       deraadt   170: #endif /* EXTB */
                    171: #endif /* B38400 */
                    172:
                    173: #ifdef B7200
1.3       markus    174:        case 7200:
                    175:                return B7200;
1.1       deraadt   176: #endif /* B7200 */
                    177: #ifdef B14400
1.3       markus    178:        case 14400:
                    179:                return B14400;
1.1       deraadt   180: #endif /* B14400 */
                    181: #ifdef B28800
1.3       markus    182:        case 28800:
                    183:                return B28800;
1.1       deraadt   184: #endif /* B28800 */
                    185: #ifdef B57600
1.3       markus    186:        case 57600:
                    187:                return B57600;
1.1       deraadt   188: #endif /* B57600 */
                    189: #ifdef B76800
1.3       markus    190:        case 76800:
                    191:                return B76800;
1.1       deraadt   192: #endif /* B76800 */
                    193: #ifdef B115200
1.3       markus    194:        case 115200:
                    195:                return B115200;
1.1       deraadt   196: #endif /* B115200 */
                    197: #ifdef B230400
1.3       markus    198:        case 230400:
                    199:                return B230400;
1.1       deraadt   200: #endif /* B230400 */
1.3       markus    201:        default:
                    202:                return B9600;
                    203:        }
1.1       deraadt   204: }
                    205:
1.4       deraadt   206: /*
                    207:  * Encodes terminal modes for the terminal referenced by fd
                    208:  * in a portable manner, and appends the modes to a packet
                    209:  * being constructed.
                    210:  */
1.6       markus    211: void
1.3       markus    212: tty_make_modes(int fd)
1.1       deraadt   213: {
1.3       markus    214:        struct termios tio;
                    215:        int baud;
1.1       deraadt   216:
1.3       markus    217:        if (tcgetattr(fd, &tio) < 0) {
                    218:                packet_put_char(TTY_OP_END);
                    219:                log("tcgetattr: %.100s", strerror(errno));
                    220:                return;
                    221:        }
                    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);
1.1       deraadt   229:
1.3       markus    230:        /* Store values of mode flags. */
1.1       deraadt   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)
                    238:
                    239: #include "ttymodes.h"
                    240:
                    241: #undef TTYCHAR
                    242: #undef TTYMODE
                    243: #undef SGTTYCHAR
                    244: #undef SGTTYMODE
                    245: #undef SGTTYMODEN
                    246:
1.3       markus    247:        /* Mark end of mode data. */
                    248:        packet_put_char(TTY_OP_END);
1.1       deraadt   249: }
                    250:
1.4       deraadt   251: /*
                    252:  * Decodes terminal modes for the terminal referenced by fd in a portable
                    253:  * manner from a packet being read.
                    254:  */
1.6       markus    255: void
1.3       markus    256: tty_parse_modes(int fd, int *n_bytes_ptr)
1.1       deraadt   257: {
1.3       markus    258:        struct termios tio;
                    259:        int opcode, baud;
                    260:        int n_bytes = 0;
                    261:        int failure = 0;
                    262:
1.4       deraadt   263:        /*
                    264:         * Get old attributes for the terminal.  We will modify these
                    265:         * flags. I am hoping that if there are any machine-specific
                    266:         * modes, they will initially have reasonable values.
                    267:         */
1.3       markus    268:        if (tcgetattr(fd, &tio) < 0)
                    269:                failure = -1;
                    270:
                    271:        for (;;) {
                    272:                n_bytes += 1;
                    273:                opcode = packet_get_char();
                    274:                switch (opcode) {
                    275:                case TTY_OP_END:
                    276:                        goto set;
                    277:
                    278:                case TTY_OP_ISPEED:
                    279:                        n_bytes += 4;
                    280:                        baud = packet_get_int();
                    281:                        if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) < 0)
                    282:                                error("cfsetispeed failed for %d", baud);
                    283:                        break;
                    284:
                    285:                case TTY_OP_OSPEED:
                    286:                        n_bytes += 4;
                    287:                        baud = packet_get_int();
                    288:                        if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) < 0)
                    289:                                error("cfsetospeed failed for %d", baud);
                    290:                        break;
1.1       deraadt   291:
                    292: #define TTYCHAR(NAME, OP)                              \
                    293:        case OP:                                        \
                    294:          n_bytes += 1;                                 \
                    295:          tio.c_cc[NAME] = packet_get_char();           \
                    296:          break;
                    297: #define TTYMODE(NAME, FIELD, OP)                       \
                    298:        case OP:                                        \
                    299:          n_bytes += 1;                                 \
                    300:          if (packet_get_char())                        \
                    301:            tio.FIELD |= NAME;                          \
                    302:          else                                          \
                    303:            tio.FIELD &= ~NAME;                         \
                    304:          break;
                    305: #define SGTTYCHAR(NAME, OP)
                    306: #define SGTTYMODE(NAME, FIELD, OP)
                    307: #define SGTTYMODEN(NAME, FIELD, OP)
                    308:
                    309: #include "ttymodes.h"
                    310:
                    311: #undef TTYCHAR
                    312: #undef TTYMODE
                    313: #undef SGTTYCHAR
                    314: #undef SGTTYMODE
                    315: #undef SGTTYMODEN
                    316:
1.3       markus    317:                default:
                    318:                        debug("Ignoring unsupported tty mode opcode %d (0x%x)",
                    319:                              opcode, opcode);
1.4       deraadt   320:                        /*
                    321:                         * Opcodes 0 to 127 are defined to have
                    322:                         * a one-byte argument.
                    323:                         */
1.3       markus    324:                        if (opcode >= 0 && opcode < 128) {
                    325:                                n_bytes += 1;
                    326:                                (void) packet_get_char();
                    327:                                break;
                    328:                        } else {
1.4       deraadt   329:                                /*
                    330:                                 * Opcodes 128 to 159 are defined to have
                    331:                                 * an integer argument.
                    332:                                 */
1.3       markus    333:                                if (opcode >= 128 && opcode < 160) {
                    334:                                        n_bytes += 4;
                    335:                                        (void) packet_get_int();
                    336:                                        break;
                    337:                                }
                    338:                        }
1.4       deraadt   339:                        /*
                    340:                         * It is a truly undefined opcode (160 to 255).
                    341:                         * We have no idea about its arguments.  So we
                    342:                         * must stop parsing.  Note that some data may be
                    343:                         * left in the packet; hopefully there is nothing
                    344:                         * more coming after the mode data.
                    345:                         */
1.3       markus    346:                        log("parse_tty_modes: unknown opcode %d", opcode);
                    347:                        packet_integrity_check(0, 1, SSH_CMSG_REQUEST_PTY);
                    348:                        goto set;
1.1       deraadt   349:                }
                    350:        }
                    351:
1.3       markus    352: set:
                    353:        if (*n_bytes_ptr != n_bytes) {
                    354:                *n_bytes_ptr = n_bytes;
                    355:                return;         /* Don't process bytes passed */
                    356:        }
                    357:        if (failure == -1)
                    358:                return;         /* Packet parsed ok but tty stuff failed */
                    359:
                    360:        /* Set the new modes for the terminal. */
                    361:        if (tcsetattr(fd, TCSANOW, &tio) < 0)
                    362:                log("Setting tty modes failed: %.100s", strerror(errno));
                    363:        return;
1.1       deraadt   364: }