| Commit | Line | Data |
|---|---|---|
| 984263bc MD |
1 | /* |
| 2 | * Copyright (c) 1989, 1993 | |
| 3 | * The Regents of the University of California. All rights reserved. | |
| 4 | * | |
| 5 | * Redistribution and use in source and binary forms, with or without | |
| 6 | * modification, are permitted provided that the following conditions | |
| 7 | * are met: | |
| 8 | * 1. Redistributions of source code must retain the above copyright | |
| 9 | * notice, this list of conditions and the following disclaimer. | |
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 11 | * notice, this list of conditions and the following disclaimer in the | |
| 12 | * documentation and/or other materials provided with the distribution. | |
| 13 | * 3. All advertising materials mentioning features or use of this software | |
| 14 | * must display the following acknowledgement: | |
| 15 | * This product includes software developed by the University of | |
| 16 | * California, Berkeley and its contributors. | |
| 17 | * 4. Neither the name of the University nor the names of its contributors | |
| 18 | * may be used to endorse or promote products derived from this software | |
| 19 | * without specific prior written permission. | |
| 20 | * | |
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
| 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 31 | * SUCH DAMAGE. | |
| 1de703da MD |
32 | * |
| 33 | * @(#)termstat.c 8.2 (Berkeley) 5/30/95 | |
| 34 | * $FreeBSD: src/libexec/telnetd/termstat.c,v 1.9.2.4 2002/04/13 11:07:12 markm Exp $ | |
| 35 | * $DragonFly: src/libexec/telnetd/termstat.c,v 1.2 2003/06/17 04:27:08 dillon Exp $ | |
| 984263bc MD |
36 | */ |
| 37 | ||
| 984263bc MD |
38 | #include "telnetd.h" |
| 39 | ||
| 40 | ||
| 41 | /* | |
| 42 | * local variables | |
| 43 | */ | |
| 44 | int def_tspeed = -1, def_rspeed = -1; | |
| 45 | #ifdef TIOCSWINSZ | |
| 46 | int def_row = 0, def_col = 0; | |
| 47 | #endif | |
| 48 | #ifdef LINEMODE | |
| 49 | static int _terminit = 0; | |
| 50 | #endif /* LINEMODE */ | |
| 51 | ||
| 52 | #ifdef LINEMODE | |
| 53 | /* | |
| 54 | * localstat | |
| 55 | * | |
| 56 | * This function handles all management of linemode. | |
| 57 | * | |
| 58 | * Linemode allows the client to do the local editing of data | |
| 59 | * and send only complete lines to the server. Linemode state is | |
| 60 | * based on the state of the pty driver. If the pty is set for | |
| 61 | * external processing, then we can use linemode. Further, if we | |
| 62 | * can use real linemode, then we can look at the edit control bits | |
| 63 | * in the pty to determine what editing the client should do. | |
| 64 | * | |
| 65 | * Linemode support uses the following state flags to keep track of | |
| 66 | * current and desired linemode state. | |
| 67 | * alwayslinemode : true if -l was specified on the telnetd | |
| 68 | * command line. It means to have linemode on as much as | |
| 69 | * possible. | |
| 70 | * | |
| 71 | * lmodetype: signifies whether the client can | |
| 72 | * handle real linemode, or if use of kludgeomatic linemode | |
| 73 | * is preferred. It will be set to one of the following: | |
| 74 | * REAL_LINEMODE : use linemode option | |
| 75 | * NO_KLUDGE : don't initiate kludge linemode. | |
| 76 | * KLUDGE_LINEMODE : use kludge linemode | |
| 77 | * NO_LINEMODE : client is ignorant of linemode | |
| 78 | * | |
| 79 | * linemode, uselinemode : linemode is true if linemode | |
| 80 | * is currently on, uselinemode is the state that we wish | |
| 81 | * to be in. If another function wishes to turn linemode | |
| 82 | * on or off, it sets or clears uselinemode. | |
| 83 | * | |
| 84 | * editmode, useeditmode : like linemode/uselinemode, but | |
| 85 | * these contain the edit mode states (edit and trapsig). | |
| 86 | * | |
| 87 | * The state variables correspond to some of the state information | |
| 88 | * in the pty. | |
| 89 | * linemode: | |
| 90 | * In real linemode, this corresponds to whether the pty | |
| 91 | * expects external processing of incoming data. | |
| 92 | * In kludge linemode, this more closely corresponds to the | |
| 93 | * whether normal processing is on or not. (ICANON in | |
| 94 | * system V, or COOKED mode in BSD.) | |
| 95 | * If the -l option was specified (alwayslinemode), then | |
| 96 | * an attempt is made to force external processing on at | |
| 97 | * all times. | |
| 98 | * | |
| 99 | * The following heuristics are applied to determine linemode | |
| 100 | * handling within the server. | |
| 101 | * 1) Early on in starting up the server, an attempt is made | |
| 102 | * to negotiate the linemode option. If this succeeds | |
| 103 | * then lmodetype is set to REAL_LINEMODE and all linemode | |
| 104 | * processing occurs in the context of the linemode option. | |
| 105 | * 2) If the attempt to negotiate the linemode option failed, | |
| 106 | * and the "-k" (don't initiate kludge linemode) isn't set, | |
| 107 | * then we try to use kludge linemode. We test for this | |
| 108 | * capability by sending "do Timing Mark". If a positive | |
| 109 | * response comes back, then we assume that the client | |
| 110 | * understands kludge linemode (ech!) and the | |
| 111 | * lmodetype flag is set to KLUDGE_LINEMODE. | |
| 112 | * 3) Otherwise, linemode is not supported at all and | |
| 113 | * lmodetype remains set to NO_LINEMODE (which happens | |
| 114 | * to be 0 for convenience). | |
| 115 | * 4) At any time a command arrives that implies a higher | |
| 116 | * state of linemode support in the client, we move to that | |
| 117 | * linemode support. | |
| 118 | * | |
| 119 | * A short explanation of kludge linemode is in order here. | |
| 120 | * 1) The heuristic to determine support for kludge linemode | |
| 121 | * is to send a do timing mark. We assume that a client | |
| 122 | * that supports timing marks also supports kludge linemode. | |
| 123 | * A risky proposition at best. | |
| 124 | * 2) Further negotiation of linemode is done by changing the | |
| 125 | * the server's state regarding SGA. If server will SGA, | |
| 126 | * then linemode is off, if server won't SGA, then linemode | |
| 127 | * is on. | |
| 128 | */ | |
| 129 | void | |
| 130 | localstat(void) | |
| 131 | { | |
| 132 | int need_will_echo = 0; | |
| 133 | ||
| 134 | /* | |
| 135 | * Check for changes to flow control if client supports it. | |
| 136 | */ | |
| 137 | flowstat(); | |
| 138 | ||
| 139 | /* | |
| 140 | * Check linemode on/off state | |
| 141 | */ | |
| 142 | uselinemode = tty_linemode(); | |
| 143 | ||
| 144 | /* | |
| 145 | * If alwayslinemode is on, and pty is changing to turn it off, then | |
| 146 | * force linemode back on. | |
| 147 | */ | |
| 148 | if (alwayslinemode && linemode && !uselinemode) { | |
| 149 | uselinemode = 1; | |
| 150 | tty_setlinemode(uselinemode); | |
| 151 | } | |
| 152 | ||
| 153 | if (uselinemode) { | |
| 154 | /* | |
| 155 | * Check for state of BINARY options. | |
| 156 | * | |
| 157 | * We only need to do the binary dance if we are actually going | |
| 158 | * to use linemode. As this confuses some telnet clients | |
| 159 | * that don't support linemode, and doesn't gain us | |
| 160 | * anything, we don't do it unless we're doing linemode. | |
| 161 | * -Crh (henrich@msu.edu) | |
| 162 | */ | |
| 163 | ||
| 164 | if (tty_isbinaryin()) { | |
| 165 | if (his_want_state_is_wont(TELOPT_BINARY)) | |
| 166 | send_do(TELOPT_BINARY, 1); | |
| 167 | } else { | |
| 168 | if (his_want_state_is_will(TELOPT_BINARY)) | |
| 169 | send_dont(TELOPT_BINARY, 1); | |
| 170 | } | |
| 171 | ||
| 172 | if (tty_isbinaryout()) { | |
| 173 | if (my_want_state_is_wont(TELOPT_BINARY)) | |
| 174 | send_will(TELOPT_BINARY, 1); | |
| 175 | } else { | |
| 176 | if (my_want_state_is_will(TELOPT_BINARY)) | |
| 177 | send_wont(TELOPT_BINARY, 1); | |
| 178 | } | |
| 179 | } | |
| 180 | ||
| 181 | ||
| 182 | /* | |
| 183 | * Do echo mode handling as soon as we know what the | |
| 184 | * linemode is going to be. | |
| 185 | * If the pty has echo turned off, then tell the client that | |
| 186 | * the server will echo. If echo is on, then the server | |
| 187 | * will echo if in character mode, but in linemode the | |
| 188 | * client should do local echoing. The state machine will | |
| 189 | * not send anything if it is unnecessary, so don't worry | |
| 190 | * about that here. | |
| 191 | * | |
| 192 | * If we need to send the WILL ECHO (because echo is off), | |
| 193 | * then delay that until after we have changed the MODE. | |
| 194 | * This way, when the user is turning off both editing | |
| 195 | * and echo, the client will get editing turned off first. | |
| 196 | * This keeps the client from going into encryption mode | |
| 197 | * and then right back out if it is doing auto-encryption | |
| 198 | * when passwords are being typed. | |
| 199 | */ | |
| 200 | if (uselinemode) { | |
| 201 | if (tty_isecho()) | |
| 202 | send_wont(TELOPT_ECHO, 1); | |
| 203 | else | |
| 204 | need_will_echo = 1; | |
| 205 | #ifdef KLUDGELINEMODE | |
| 206 | if (lmodetype == KLUDGE_OK) | |
| 207 | lmodetype = KLUDGE_LINEMODE; | |
| 208 | #endif | |
| 209 | } | |
| 210 | ||
| 211 | /* | |
| 212 | * If linemode is being turned off, send appropriate | |
| 213 | * command and then we're all done. | |
| 214 | */ | |
| 215 | if (!uselinemode && linemode) { | |
| 216 | # ifdef KLUDGELINEMODE | |
| 217 | if (lmodetype == REAL_LINEMODE) { | |
| 218 | # endif /* KLUDGELINEMODE */ | |
| 219 | send_dont(TELOPT_LINEMODE, 1); | |
| 220 | # ifdef KLUDGELINEMODE | |
| 221 | } else if (lmodetype == KLUDGE_LINEMODE) | |
| 222 | send_will(TELOPT_SGA, 1); | |
| 223 | # endif /* KLUDGELINEMODE */ | |
| 224 | send_will(TELOPT_ECHO, 1); | |
| 225 | linemode = uselinemode; | |
| 226 | goto done; | |
| 227 | } | |
| 228 | ||
| 229 | # ifdef KLUDGELINEMODE | |
| 230 | /* | |
| 231 | * If using real linemode check edit modes for possible later use. | |
| 232 | * If we are in kludge linemode, do the SGA negotiation. | |
| 233 | */ | |
| 234 | if (lmodetype == REAL_LINEMODE) { | |
| 235 | # endif /* KLUDGELINEMODE */ | |
| 236 | useeditmode = 0; | |
| 237 | if (tty_isediting()) | |
| 238 | useeditmode |= MODE_EDIT; | |
| 239 | if (tty_istrapsig()) | |
| 240 | useeditmode |= MODE_TRAPSIG; | |
| 241 | if (tty_issofttab()) | |
| 242 | useeditmode |= MODE_SOFT_TAB; | |
| 243 | if (tty_islitecho()) | |
| 244 | useeditmode |= MODE_LIT_ECHO; | |
| 245 | # ifdef KLUDGELINEMODE | |
| 246 | } else if (lmodetype == KLUDGE_LINEMODE) { | |
| 247 | if (tty_isediting() && uselinemode) | |
| 248 | send_wont(TELOPT_SGA, 1); | |
| 249 | else | |
| 250 | send_will(TELOPT_SGA, 1); | |
| 251 | } | |
| 252 | # endif /* KLUDGELINEMODE */ | |
| 253 | ||
| 254 | /* | |
| 255 | * Negotiate linemode on if pty state has changed to turn it on. | |
| 256 | * Send appropriate command and send along edit mode, then all done. | |
| 257 | */ | |
| 258 | if (uselinemode && !linemode) { | |
| 259 | # ifdef KLUDGELINEMODE | |
| 260 | if (lmodetype == KLUDGE_LINEMODE) { | |
| 261 | send_wont(TELOPT_SGA, 1); | |
| 262 | } else if (lmodetype == REAL_LINEMODE) { | |
| 263 | # endif /* KLUDGELINEMODE */ | |
| 264 | send_do(TELOPT_LINEMODE, 1); | |
| 265 | /* send along edit modes */ | |
| 266 | output_data("%c%c%c%c%c%c%c", IAC, SB, | |
| 267 | TELOPT_LINEMODE, LM_MODE, useeditmode, | |
| 268 | IAC, SE); | |
| 269 | editmode = useeditmode; | |
| 270 | # ifdef KLUDGELINEMODE | |
| 271 | } | |
| 272 | # endif /* KLUDGELINEMODE */ | |
| 273 | linemode = uselinemode; | |
| 274 | goto done; | |
| 275 | } | |
| 276 | ||
| 277 | # ifdef KLUDGELINEMODE | |
| 278 | /* | |
| 279 | * None of what follows is of any value if not using | |
| 280 | * real linemode. | |
| 281 | */ | |
| 282 | if (lmodetype < REAL_LINEMODE) | |
| 283 | goto done; | |
| 284 | # endif /* KLUDGELINEMODE */ | |
| 285 | ||
| 286 | if (linemode && his_state_is_will(TELOPT_LINEMODE)) { | |
| 287 | /* | |
| 288 | * If edit mode changed, send edit mode. | |
| 289 | */ | |
| 290 | if (useeditmode != editmode) { | |
| 291 | /* | |
| 292 | * Send along appropriate edit mode mask. | |
| 293 | */ | |
| 294 | output_data("%c%c%c%c%c%c%c", IAC, SB, | |
| 295 | TELOPT_LINEMODE, LM_MODE, useeditmode, | |
| 296 | IAC, SE); | |
| 297 | editmode = useeditmode; | |
| 298 | } | |
| 299 | ||
| 300 | ||
| 301 | /* | |
| 302 | * Check for changes to special characters in use. | |
| 303 | */ | |
| 304 | start_slc(0); | |
| 305 | check_slc(); | |
| 306 | (void) end_slc(0); | |
| 307 | } | |
| 308 | ||
| 309 | done: | |
| 310 | if (need_will_echo) | |
| 311 | send_will(TELOPT_ECHO, 1); | |
| 312 | /* | |
| 313 | * Some things should be deferred until after the pty state has | |
| 314 | * been set by the local process. Do those things that have been | |
| 315 | * deferred now. This only happens once. | |
| 316 | */ | |
| 317 | if (_terminit == 0) { | |
| 318 | _terminit = 1; | |
| 319 | defer_terminit(); | |
| 320 | } | |
| 321 | ||
| 322 | netflush(); | |
| 323 | set_termbuf(); | |
| 324 | return; | |
| 325 | ||
| 326 | } /* end of localstat */ | |
| 327 | #endif /* LINEMODE */ | |
| 328 | ||
| 329 | /* | |
| 330 | * flowstat | |
| 331 | * | |
| 332 | * Check for changes to flow control | |
| 333 | */ | |
| 334 | void | |
| 335 | flowstat(void) | |
| 336 | { | |
| 337 | if (his_state_is_will(TELOPT_LFLOW)) { | |
| 338 | if (tty_flowmode() != flowmode) { | |
| 339 | flowmode = tty_flowmode(); | |
| 340 | output_data("%c%c%c%c%c%c", | |
| 341 | IAC, SB, TELOPT_LFLOW, | |
| 342 | flowmode ? LFLOW_ON : LFLOW_OFF, | |
| 343 | IAC, SE); | |
| 344 | } | |
| 345 | if (tty_restartany() != restartany) { | |
| 346 | restartany = tty_restartany(); | |
| 347 | output_data("%c%c%c%c%c%c", | |
| 348 | IAC, SB, TELOPT_LFLOW, | |
| 349 | restartany ? LFLOW_RESTART_ANY | |
| 350 | : LFLOW_RESTART_XON, | |
| 351 | IAC, SE); | |
| 352 | } | |
| 353 | } | |
| 354 | } | |
| 355 | ||
| 356 | /* | |
| 357 | * clientstat | |
| 358 | * | |
| 359 | * Process linemode related requests from the client. | |
| 360 | * Client can request a change to only one of linemode, editmode or slc's | |
| 361 | * at a time, and if using kludge linemode, then only linemode may be | |
| 362 | * affected. | |
| 363 | */ | |
| 364 | void | |
| 365 | clientstat(int code, int parm1, int parm2) | |
| 366 | { | |
| 367 | ||
| 368 | /* | |
| 369 | * Get a copy of terminal characteristics. | |
| 370 | */ | |
| 371 | init_termbuf(); | |
| 372 | ||
| 373 | /* | |
| 374 | * Process request from client. code tells what it is. | |
| 375 | */ | |
| 376 | switch (code) { | |
| 377 | #ifdef LINEMODE | |
| 378 | case TELOPT_LINEMODE: | |
| 379 | /* | |
| 380 | * Don't do anything unless client is asking us to change | |
| 381 | * modes. | |
| 382 | */ | |
| 383 | uselinemode = (parm1 == WILL); | |
| 384 | if (uselinemode != linemode) { | |
| 385 | # ifdef KLUDGELINEMODE | |
| 386 | /* | |
| 387 | * If using kludge linemode, make sure that | |
| 388 | * we can do what the client asks. | |
| 389 | * We can not turn off linemode if alwayslinemode | |
| 390 | * and the ICANON bit is set. | |
| 391 | */ | |
| 392 | if (lmodetype == KLUDGE_LINEMODE) { | |
| 393 | if (alwayslinemode && tty_isediting()) { | |
| 394 | uselinemode = 1; | |
| 395 | } | |
| 396 | } | |
| 397 | ||
| 398 | /* | |
| 399 | * Quit now if we can't do it. | |
| 400 | */ | |
| 401 | if (uselinemode == linemode) | |
| 402 | return; | |
| 403 | ||
| 404 | /* | |
| 405 | * If using real linemode and linemode is being | |
| 406 | * turned on, send along the edit mode mask. | |
| 407 | */ | |
| 408 | if (lmodetype == REAL_LINEMODE && uselinemode) | |
| 409 | # else /* KLUDGELINEMODE */ | |
| 410 | if (uselinemode) | |
| 411 | # endif /* KLUDGELINEMODE */ | |
| 412 | { | |
| 413 | useeditmode = 0; | |
| 414 | if (tty_isediting()) | |
| 415 | useeditmode |= MODE_EDIT; | |
| e310e7bc | 416 | if (tty_istrapsig()) |
| 984263bc MD |
417 | useeditmode |= MODE_TRAPSIG; |
| 418 | if (tty_issofttab()) | |
| 419 | useeditmode |= MODE_SOFT_TAB; | |
| 420 | if (tty_islitecho()) | |
| 421 | useeditmode |= MODE_LIT_ECHO; | |
| 422 | output_data("%c%c%c%c%c%c%c", IAC, | |
| 423 | SB, TELOPT_LINEMODE, LM_MODE, | |
| 424 | useeditmode, IAC, SE); | |
| 425 | editmode = useeditmode; | |
| 426 | } | |
| 427 | ||
| 428 | ||
| 429 | tty_setlinemode(uselinemode); | |
| 430 | ||
| 431 | linemode = uselinemode; | |
| 432 | ||
| 433 | if (!linemode) | |
| 434 | send_will(TELOPT_ECHO, 1); | |
| 435 | } | |
| 436 | break; | |
| 437 | ||
| 438 | case LM_MODE: | |
| 439 | { | |
| 440 | int ack, changed; | |
| 441 | ||
| 442 | /* | |
| 443 | * Client has sent along a mode mask. If it agrees with | |
| 444 | * what we are currently doing, ignore it; if not, it could | |
| 445 | * be viewed as a request to change. Note that the server | |
| 446 | * will change to the modes in an ack if it is different from | |
| 447 | * what we currently have, but we will not ack the ack. | |
| 448 | */ | |
| 449 | useeditmode &= MODE_MASK; | |
| 450 | ack = (useeditmode & MODE_ACK); | |
| 451 | useeditmode &= ~MODE_ACK; | |
| 452 | ||
| 453 | if ((changed = (useeditmode ^ editmode))) { | |
| 454 | /* | |
| 455 | * This check is for a timing problem. If the | |
| 456 | * state of the tty has changed (due to the user | |
| 457 | * application) we need to process that info | |
| 458 | * before we write in the state contained in the | |
| 459 | * ack!!! This gets out the new MODE request, | |
| 460 | * and when the ack to that command comes back | |
| 461 | * we'll set it and be in the right mode. | |
| 462 | */ | |
| 463 | if (ack) | |
| 464 | localstat(); | |
| 465 | if (changed & MODE_EDIT) | |
| 466 | tty_setedit(useeditmode & MODE_EDIT); | |
| 467 | ||
| 468 | if (changed & MODE_TRAPSIG) | |
| 469 | tty_setsig(useeditmode & MODE_TRAPSIG); | |
| 470 | ||
| 471 | if (changed & MODE_SOFT_TAB) | |
| 472 | tty_setsofttab(useeditmode & MODE_SOFT_TAB); | |
| 473 | ||
| 474 | if (changed & MODE_LIT_ECHO) | |
| 475 | tty_setlitecho(useeditmode & MODE_LIT_ECHO); | |
| 476 | ||
| 477 | set_termbuf(); | |
| 478 | ||
| 479 | if (!ack) { | |
| 480 | output_data("%c%c%c%c%c%c%c", IAC, | |
| 481 | SB, TELOPT_LINEMODE, LM_MODE, | |
| 482 | useeditmode|MODE_ACK, | |
| 483 | IAC, SE); | |
| 484 | } | |
| 485 | ||
| 486 | editmode = useeditmode; | |
| 487 | } | |
| 488 | ||
| 489 | break; | |
| 490 | ||
| 491 | } /* end of case LM_MODE */ | |
| 492 | #endif /* LINEMODE */ | |
| 493 | ||
| 494 | case TELOPT_NAWS: | |
| 495 | #ifdef TIOCSWINSZ | |
| 496 | { | |
| 497 | struct winsize ws; | |
| 498 | ||
| 499 | def_col = parm1; | |
| 500 | def_row = parm2; | |
| 501 | #ifdef LINEMODE | |
| 502 | /* | |
| 503 | * Defer changing window size until after terminal is | |
| 504 | * initialized. | |
| 505 | */ | |
| 506 | if (terminit() == 0) | |
| 507 | return; | |
| 508 | #endif /* LINEMODE */ | |
| 509 | ||
| 510 | /* | |
| 511 | * Change window size as requested by client. | |
| 512 | */ | |
| 513 | ||
| 514 | ws.ws_col = parm1; | |
| 515 | ws.ws_row = parm2; | |
| 516 | (void) ioctl(pty, TIOCSWINSZ, (char *)&ws); | |
| 517 | } | |
| 518 | #endif /* TIOCSWINSZ */ | |
| 519 | ||
| 520 | break; | |
| 521 | ||
| 522 | case TELOPT_TSPEED: | |
| 523 | { | |
| 524 | def_tspeed = parm1; | |
| 525 | def_rspeed = parm2; | |
| 526 | #ifdef LINEMODE | |
| 527 | /* | |
| 528 | * Defer changing the terminal speed. | |
| 529 | */ | |
| 530 | if (terminit() == 0) | |
| 531 | return; | |
| 532 | #endif /* LINEMODE */ | |
| 533 | /* | |
| 534 | * Change terminal speed as requested by client. | |
| 535 | * We set the receive speed first, so that if we can't | |
| 536 | * store separate receive and transmit speeds, the transmit | |
| 537 | * speed will take precedence. | |
| 538 | */ | |
| 539 | tty_rspeed(parm2); | |
| 540 | tty_tspeed(parm1); | |
| 541 | set_termbuf(); | |
| 542 | ||
| 543 | break; | |
| 544 | ||
| 545 | } /* end of case TELOPT_TSPEED */ | |
| 546 | ||
| 547 | default: | |
| 548 | /* What? */ | |
| 549 | break; | |
| 550 | } /* end of switch */ | |
| 551 | ||
| 552 | netflush(); | |
| 553 | ||
| 554 | } /* end of clientstat */ | |
| 555 | ||
| 556 | #ifdef LINEMODE | |
| 557 | /* | |
| 558 | * defer_terminit | |
| 559 | * | |
| 560 | * Some things should not be done until after the login process has started | |
| 561 | * and all the pty modes are set to what they are supposed to be. This | |
| 562 | * function is called when the pty state has been processed for the first time. | |
| 563 | * It calls other functions that do things that were deferred in each module. | |
| 564 | */ | |
| 565 | void | |
| 566 | defer_terminit(void) | |
| 567 | { | |
| 568 | ||
| 569 | /* | |
| 570 | * local stuff that got deferred. | |
| 571 | */ | |
| 572 | if (def_tspeed != -1) { | |
| 573 | clientstat(TELOPT_TSPEED, def_tspeed, def_rspeed); | |
| 574 | def_tspeed = def_rspeed = 0; | |
| 575 | } | |
| 576 | ||
| 577 | #ifdef TIOCSWINSZ | |
| 578 | if (def_col || def_row) { | |
| 579 | struct winsize ws; | |
| 580 | ||
| 581 | memset((char *)&ws, 0, sizeof(ws)); | |
| 582 | ws.ws_col = def_col; | |
| 583 | ws.ws_row = def_row; | |
| 584 | (void) ioctl(pty, TIOCSWINSZ, (char *)&ws); | |
| 585 | } | |
| 586 | #endif | |
| 587 | ||
| 588 | /* | |
| 589 | * The only other module that currently defers anything. | |
| 590 | */ | |
| 591 | deferslc(); | |
| 592 | ||
| 593 | } /* end of defer_terminit */ | |
| 594 | ||
| 595 | /* | |
| 596 | * terminit | |
| 597 | * | |
| 598 | * Returns true if the pty state has been processed yet. | |
| 599 | */ | |
| 600 | int | |
| 601 | terminit(void) | |
| 602 | { | |
| 603 | return(_terminit); | |
| 604 | ||
| 605 | } /* end of terminit */ | |
| 606 | #endif /* LINEMODE */ |