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. 32 */ 33 34#ifndef lint 35#if 0 36static const char sccsid[] = "@(#)termstat.c 8.2 (Berkeley) 5/30/95"; 37#endif 38static const char rcsid[] =
| 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. 32 */ 33 34#ifndef lint 35#if 0 36static const char sccsid[] = "@(#)termstat.c 8.2 (Berkeley) 5/30/95"; 37#endif 38static const char rcsid[] =
|
40#endif /* not lint */ 41 42#include "telnetd.h" 43 44#if defined(ENCRYPTION) 45#include <libtelnet/encrypt.h> 46#endif 47 48/* 49 * local variables 50 */ 51int def_tspeed = -1, def_rspeed = -1; 52#ifdef TIOCSWINSZ 53int def_row = 0, def_col = 0; 54#endif 55#ifdef LINEMODE 56static int _terminit = 0; 57#endif /* LINEMODE */ 58 59#if defined(CRAY2) && defined(UNICOS5) 60int newmap = 1; /* nonzero if \n maps to ^M^J */ 61#endif 62 63#ifdef LINEMODE 64/* 65 * localstat 66 * 67 * This function handles all management of linemode. 68 * 69 * Linemode allows the client to do the local editing of data 70 * and send only complete lines to the server. Linemode state is 71 * based on the state of the pty driver. If the pty is set for 72 * external processing, then we can use linemode. Further, if we 73 * can use real linemode, then we can look at the edit control bits 74 * in the pty to determine what editing the client should do. 75 * 76 * Linemode support uses the following state flags to keep track of 77 * current and desired linemode state. 78 * alwayslinemode : true if -l was specified on the telnetd 79 * command line. It means to have linemode on as much as 80 * possible. 81 * 82 * lmodetype: signifies whether the client can 83 * handle real linemode, or if use of kludgeomatic linemode 84 * is preferred. It will be set to one of the following: 85 * REAL_LINEMODE : use linemode option 86 * NO_KLUDGE : don't initiate kludge linemode. 87 * KLUDGE_LINEMODE : use kludge linemode 88 * NO_LINEMODE : client is ignorant of linemode 89 * 90 * linemode, uselinemode : linemode is true if linemode 91 * is currently on, uselinemode is the state that we wish 92 * to be in. If another function wishes to turn linemode 93 * on or off, it sets or clears uselinemode. 94 * 95 * editmode, useeditmode : like linemode/uselinemode, but 96 * these contain the edit mode states (edit and trapsig). 97 * 98 * The state variables correspond to some of the state information 99 * in the pty. 100 * linemode: 101 * In real linemode, this corresponds to whether the pty 102 * expects external processing of incoming data. 103 * In kludge linemode, this more closely corresponds to the 104 * whether normal processing is on or not. (ICANON in 105 * system V, or COOKED mode in BSD.) 106 * If the -l option was specified (alwayslinemode), then 107 * an attempt is made to force external processing on at 108 * all times. 109 * 110 * The following heuristics are applied to determine linemode 111 * handling within the server. 112 * 1) Early on in starting up the server, an attempt is made 113 * to negotiate the linemode option. If this succeeds 114 * then lmodetype is set to REAL_LINEMODE and all linemode 115 * processing occurs in the context of the linemode option. 116 * 2) If the attempt to negotiate the linemode option failed, 117 * and the "-k" (don't initiate kludge linemode) isn't set, 118 * then we try to use kludge linemode. We test for this 119 * capability by sending "do Timing Mark". If a positive 120 * response comes back, then we assume that the client 121 * understands kludge linemode (ech!) and the 122 * lmodetype flag is set to KLUDGE_LINEMODE. 123 * 3) Otherwise, linemode is not supported at all and 124 * lmodetype remains set to NO_LINEMODE (which happens 125 * to be 0 for convenience). 126 * 4) At any time a command arrives that implies a higher 127 * state of linemode support in the client, we move to that 128 * linemode support. 129 * 130 * A short explanation of kludge linemode is in order here. 131 * 1) The heuristic to determine support for kludge linemode 132 * is to send a do timing mark. We assume that a client 133 * that supports timing marks also supports kludge linemode. 134 * A risky proposition at best. 135 * 2) Further negotiation of linemode is done by changing the 136 * the server's state regarding SGA. If server will SGA, 137 * then linemode is off, if server won't SGA, then linemode 138 * is on. 139 */ 140 void 141localstat() 142{ 143 int need_will_echo = 0; 144 145#if defined(CRAY2) && defined(UNICOS5) 146 /* 147 * Keep track of that ol' CR/NL mapping while we're in the 148 * neighborhood. 149 */ 150 newmap = tty_isnewmap(); 151#endif /* defined(CRAY2) && defined(UNICOS5) */ 152 153 /* 154 * Check for changes to flow control if client supports it. 155 */ 156 flowstat(); 157 158 /* 159 * Check linemode on/off state 160 */ 161 uselinemode = tty_linemode(); 162 163 /* 164 * If alwayslinemode is on, and pty is changing to turn it off, then 165 * force linemode back on. 166 */ 167 if (alwayslinemode && linemode && !uselinemode) { 168 uselinemode = 1; 169 tty_setlinemode(uselinemode); 170 } 171 172 if (uselinemode) { 173 /*
| 40#endif /* not lint */ 41 42#include "telnetd.h" 43 44#if defined(ENCRYPTION) 45#include <libtelnet/encrypt.h> 46#endif 47 48/* 49 * local variables 50 */ 51int def_tspeed = -1, def_rspeed = -1; 52#ifdef TIOCSWINSZ 53int def_row = 0, def_col = 0; 54#endif 55#ifdef LINEMODE 56static int _terminit = 0; 57#endif /* LINEMODE */ 58 59#if defined(CRAY2) && defined(UNICOS5) 60int newmap = 1; /* nonzero if \n maps to ^M^J */ 61#endif 62 63#ifdef LINEMODE 64/* 65 * localstat 66 * 67 * This function handles all management of linemode. 68 * 69 * Linemode allows the client to do the local editing of data 70 * and send only complete lines to the server. Linemode state is 71 * based on the state of the pty driver. If the pty is set for 72 * external processing, then we can use linemode. Further, if we 73 * can use real linemode, then we can look at the edit control bits 74 * in the pty to determine what editing the client should do. 75 * 76 * Linemode support uses the following state flags to keep track of 77 * current and desired linemode state. 78 * alwayslinemode : true if -l was specified on the telnetd 79 * command line. It means to have linemode on as much as 80 * possible. 81 * 82 * lmodetype: signifies whether the client can 83 * handle real linemode, or if use of kludgeomatic linemode 84 * is preferred. It will be set to one of the following: 85 * REAL_LINEMODE : use linemode option 86 * NO_KLUDGE : don't initiate kludge linemode. 87 * KLUDGE_LINEMODE : use kludge linemode 88 * NO_LINEMODE : client is ignorant of linemode 89 * 90 * linemode, uselinemode : linemode is true if linemode 91 * is currently on, uselinemode is the state that we wish 92 * to be in. If another function wishes to turn linemode 93 * on or off, it sets or clears uselinemode. 94 * 95 * editmode, useeditmode : like linemode/uselinemode, but 96 * these contain the edit mode states (edit and trapsig). 97 * 98 * The state variables correspond to some of the state information 99 * in the pty. 100 * linemode: 101 * In real linemode, this corresponds to whether the pty 102 * expects external processing of incoming data. 103 * In kludge linemode, this more closely corresponds to the 104 * whether normal processing is on or not. (ICANON in 105 * system V, or COOKED mode in BSD.) 106 * If the -l option was specified (alwayslinemode), then 107 * an attempt is made to force external processing on at 108 * all times. 109 * 110 * The following heuristics are applied to determine linemode 111 * handling within the server. 112 * 1) Early on in starting up the server, an attempt is made 113 * to negotiate the linemode option. If this succeeds 114 * then lmodetype is set to REAL_LINEMODE and all linemode 115 * processing occurs in the context of the linemode option. 116 * 2) If the attempt to negotiate the linemode option failed, 117 * and the "-k" (don't initiate kludge linemode) isn't set, 118 * then we try to use kludge linemode. We test for this 119 * capability by sending "do Timing Mark". If a positive 120 * response comes back, then we assume that the client 121 * understands kludge linemode (ech!) and the 122 * lmodetype flag is set to KLUDGE_LINEMODE. 123 * 3) Otherwise, linemode is not supported at all and 124 * lmodetype remains set to NO_LINEMODE (which happens 125 * to be 0 for convenience). 126 * 4) At any time a command arrives that implies a higher 127 * state of linemode support in the client, we move to that 128 * linemode support. 129 * 130 * A short explanation of kludge linemode is in order here. 131 * 1) The heuristic to determine support for kludge linemode 132 * is to send a do timing mark. We assume that a client 133 * that supports timing marks also supports kludge linemode. 134 * A risky proposition at best. 135 * 2) Further negotiation of linemode is done by changing the 136 * the server's state regarding SGA. If server will SGA, 137 * then linemode is off, if server won't SGA, then linemode 138 * is on. 139 */ 140 void 141localstat() 142{ 143 int need_will_echo = 0; 144 145#if defined(CRAY2) && defined(UNICOS5) 146 /* 147 * Keep track of that ol' CR/NL mapping while we're in the 148 * neighborhood. 149 */ 150 newmap = tty_isnewmap(); 151#endif /* defined(CRAY2) && defined(UNICOS5) */ 152 153 /* 154 * Check for changes to flow control if client supports it. 155 */ 156 flowstat(); 157 158 /* 159 * Check linemode on/off state 160 */ 161 uselinemode = tty_linemode(); 162 163 /* 164 * If alwayslinemode is on, and pty is changing to turn it off, then 165 * force linemode back on. 166 */ 167 if (alwayslinemode && linemode && !uselinemode) { 168 uselinemode = 1; 169 tty_setlinemode(uselinemode); 170 } 171 172 if (uselinemode) { 173 /*
|
199 200#ifdef ENCRYPTION 201 /* 202 * If the terminal is not echoing, but editing is enabled, 203 * something like password input is going to happen, so 204 * if we the other side is not currently sending encrypted 205 * data, ask the other side to start encrypting. 206 */ 207 if (his_state_is_will(TELOPT_ENCRYPT)) { 208 static int enc_passwd = 0; 209 if (uselinemode && !tty_isecho() && tty_isediting() 210 && (enc_passwd == 0) && !decrypt_input) { 211 encrypt_send_request_start(); 212 enc_passwd = 1; 213 } else if (enc_passwd) { 214 encrypt_send_request_end(); 215 enc_passwd = 0; 216 } 217 } 218#endif /* ENCRYPTION */ 219 220 /* 221 * Do echo mode handling as soon as we know what the 222 * linemode is going to be. 223 * If the pty has echo turned off, then tell the client that 224 * the server will echo. If echo is on, then the server 225 * will echo if in character mode, but in linemode the 226 * client should do local echoing. The state machine will 227 * not send anything if it is unnecessary, so don't worry 228 * about that here. 229 * 230 * If we need to send the WILL ECHO (because echo is off), 231 * then delay that until after we have changed the MODE. 232 * This way, when the user is turning off both editing 233 * and echo, the client will get editing turned off first. 234 * This keeps the client from going into encryption mode 235 * and then right back out if it is doing auto-encryption 236 * when passwords are being typed. 237 */ 238 if (uselinemode) { 239 if (tty_isecho()) 240 send_wont(TELOPT_ECHO, 1); 241 else 242 need_will_echo = 1; 243#ifdef KLUDGELINEMODE 244 if (lmodetype == KLUDGE_OK) 245 lmodetype = KLUDGE_LINEMODE; 246#endif 247 } 248 249 /* 250 * If linemode is being turned off, send appropriate 251 * command and then we're all done. 252 */ 253 if (!uselinemode && linemode) { 254# ifdef KLUDGELINEMODE 255 if (lmodetype == REAL_LINEMODE) { 256# endif /* KLUDGELINEMODE */ 257 send_dont(TELOPT_LINEMODE, 1); 258# ifdef KLUDGELINEMODE 259 } else if (lmodetype == KLUDGE_LINEMODE) 260 send_will(TELOPT_SGA, 1); 261# endif /* KLUDGELINEMODE */ 262 send_will(TELOPT_ECHO, 1); 263 linemode = uselinemode; 264 goto done; 265 } 266 267# ifdef KLUDGELINEMODE 268 /* 269 * If using real linemode check edit modes for possible later use. 270 * If we are in kludge linemode, do the SGA negotiation. 271 */ 272 if (lmodetype == REAL_LINEMODE) { 273# endif /* KLUDGELINEMODE */ 274 useeditmode = 0; 275 if (tty_isediting()) 276 useeditmode |= MODE_EDIT; 277 if (tty_istrapsig()) 278 useeditmode |= MODE_TRAPSIG; 279 if (tty_issofttab()) 280 useeditmode |= MODE_SOFT_TAB; 281 if (tty_islitecho()) 282 useeditmode |= MODE_LIT_ECHO; 283# ifdef KLUDGELINEMODE 284 } else if (lmodetype == KLUDGE_LINEMODE) { 285 if (tty_isediting() && uselinemode) 286 send_wont(TELOPT_SGA, 1); 287 else 288 send_will(TELOPT_SGA, 1); 289 } 290# endif /* KLUDGELINEMODE */ 291 292 /* 293 * Negotiate linemode on if pty state has changed to turn it on. 294 * Send appropriate command and send along edit mode, then all done. 295 */ 296 if (uselinemode && !linemode) { 297# ifdef KLUDGELINEMODE 298 if (lmodetype == KLUDGE_LINEMODE) { 299 send_wont(TELOPT_SGA, 1); 300 } else if (lmodetype == REAL_LINEMODE) { 301# endif /* KLUDGELINEMODE */ 302 send_do(TELOPT_LINEMODE, 1); 303 /* send along edit modes */ 304 output_data("%c%c%c%c%c%c%c", IAC, SB, 305 TELOPT_LINEMODE, LM_MODE, useeditmode, 306 IAC, SE); 307 editmode = useeditmode; 308# ifdef KLUDGELINEMODE 309 } 310# endif /* KLUDGELINEMODE */ 311 linemode = uselinemode; 312 goto done; 313 } 314 315# ifdef KLUDGELINEMODE 316 /* 317 * None of what follows is of any value if not using 318 * real linemode. 319 */ 320 if (lmodetype < REAL_LINEMODE) 321 goto done; 322# endif /* KLUDGELINEMODE */ 323 324 if (linemode && his_state_is_will(TELOPT_LINEMODE)) { 325 /* 326 * If edit mode changed, send edit mode. 327 */ 328 if (useeditmode != editmode) { 329 /* 330 * Send along appropriate edit mode mask. 331 */ 332 output_data("%c%c%c%c%c%c%c", IAC, SB, 333 TELOPT_LINEMODE, LM_MODE, useeditmode, 334 IAC, SE); 335 editmode = useeditmode; 336 } 337 338 339 /* 340 * Check for changes to special characters in use. 341 */ 342 start_slc(0); 343 check_slc(); 344 (void) end_slc(0); 345 } 346 347done: 348 if (need_will_echo) 349 send_will(TELOPT_ECHO, 1); 350 /* 351 * Some things should be deferred until after the pty state has 352 * been set by the local process. Do those things that have been 353 * deferred now. This only happens once. 354 */ 355 if (_terminit == 0) { 356 _terminit = 1; 357 defer_terminit(); 358 } 359 360 netflush(); 361 set_termbuf(); 362 return; 363 364} /* end of localstat */ 365#endif /* LINEMODE */ 366 367/* 368 * flowstat 369 * 370 * Check for changes to flow control 371 */ 372 void 373flowstat() 374{ 375 if (his_state_is_will(TELOPT_LFLOW)) { 376 if (tty_flowmode() != flowmode) { 377 flowmode = tty_flowmode(); 378 output_data("%c%c%c%c%c%c", 379 IAC, SB, TELOPT_LFLOW, 380 flowmode ? LFLOW_ON : LFLOW_OFF, 381 IAC, SE); 382 } 383 if (tty_restartany() != restartany) { 384 restartany = tty_restartany(); 385 output_data("%c%c%c%c%c%c", 386 IAC, SB, TELOPT_LFLOW, 387 restartany ? LFLOW_RESTART_ANY 388 : LFLOW_RESTART_XON, 389 IAC, SE); 390 } 391 } 392} 393 394/* 395 * clientstat 396 * 397 * Process linemode related requests from the client. 398 * Client can request a change to only one of linemode, editmode or slc's 399 * at a time, and if using kludge linemode, then only linemode may be 400 * affected. 401 */ 402 void 403clientstat(code, parm1, parm2) 404 register int code, parm1, parm2; 405{ 406 407 /* 408 * Get a copy of terminal characteristics. 409 */ 410 init_termbuf(); 411 412 /* 413 * Process request from client. code tells what it is. 414 */ 415 switch (code) { 416#ifdef LINEMODE 417 case TELOPT_LINEMODE: 418 /* 419 * Don't do anything unless client is asking us to change 420 * modes. 421 */ 422 uselinemode = (parm1 == WILL); 423 if (uselinemode != linemode) { 424# ifdef KLUDGELINEMODE 425 /* 426 * If using kludge linemode, make sure that 427 * we can do what the client asks. 428 * We can not turn off linemode if alwayslinemode 429 * and the ICANON bit is set. 430 */ 431 if (lmodetype == KLUDGE_LINEMODE) { 432 if (alwayslinemode && tty_isediting()) { 433 uselinemode = 1; 434 } 435 } 436 437 /* 438 * Quit now if we can't do it. 439 */ 440 if (uselinemode == linemode) 441 return; 442 443 /* 444 * If using real linemode and linemode is being 445 * turned on, send along the edit mode mask. 446 */ 447 if (lmodetype == REAL_LINEMODE && uselinemode) 448# else /* KLUDGELINEMODE */ 449 if (uselinemode) 450# endif /* KLUDGELINEMODE */ 451 { 452 useeditmode = 0; 453 if (tty_isediting()) 454 useeditmode |= MODE_EDIT; 455 if (tty_istrapsig) 456 useeditmode |= MODE_TRAPSIG; 457 if (tty_issofttab()) 458 useeditmode |= MODE_SOFT_TAB; 459 if (tty_islitecho()) 460 useeditmode |= MODE_LIT_ECHO; 461 output_data("%c%c%c%c%c%c%c", IAC, 462 SB, TELOPT_LINEMODE, LM_MODE, 463 useeditmode, IAC, SE); 464 editmode = useeditmode; 465 } 466 467 468 tty_setlinemode(uselinemode); 469 470 linemode = uselinemode; 471 472 if (!linemode) 473 send_will(TELOPT_ECHO, 1); 474 } 475 break; 476 477 case LM_MODE: 478 { 479 register int ack, changed; 480 481 /* 482 * Client has sent along a mode mask. If it agrees with 483 * what we are currently doing, ignore it; if not, it could 484 * be viewed as a request to change. Note that the server 485 * will change to the modes in an ack if it is different from 486 * what we currently have, but we will not ack the ack. 487 */ 488 useeditmode &= MODE_MASK; 489 ack = (useeditmode & MODE_ACK); 490 useeditmode &= ~MODE_ACK; 491 492 if ((changed = (useeditmode ^ editmode))) { 493 /* 494 * This check is for a timing problem. If the 495 * state of the tty has changed (due to the user 496 * application) we need to process that info 497 * before we write in the state contained in the 498 * ack!!! This gets out the new MODE request, 499 * and when the ack to that command comes back 500 * we'll set it and be in the right mode. 501 */ 502 if (ack) 503 localstat(); 504 if (changed & MODE_EDIT) 505 tty_setedit(useeditmode & MODE_EDIT); 506 507 if (changed & MODE_TRAPSIG) 508 tty_setsig(useeditmode & MODE_TRAPSIG); 509 510 if (changed & MODE_SOFT_TAB) 511 tty_setsofttab(useeditmode & MODE_SOFT_TAB); 512 513 if (changed & MODE_LIT_ECHO) 514 tty_setlitecho(useeditmode & MODE_LIT_ECHO); 515 516 set_termbuf(); 517 518 if (!ack) { 519 output_data("%c%c%c%c%c%c%c", IAC, 520 SB, TELOPT_LINEMODE, LM_MODE, 521 useeditmode|MODE_ACK, 522 IAC, SE); 523 } 524 525 editmode = useeditmode; 526 } 527 528 break; 529 530 } /* end of case LM_MODE */ 531#endif /* LINEMODE */ 532 533 case TELOPT_NAWS: 534#ifdef TIOCSWINSZ 535 { 536 struct winsize ws; 537 538 def_col = parm1; 539 def_row = parm2; 540#ifdef LINEMODE 541 /* 542 * Defer changing window size until after terminal is 543 * initialized. 544 */ 545 if (terminit() == 0) 546 return; 547#endif /* LINEMODE */ 548 549 /* 550 * Change window size as requested by client. 551 */ 552 553 ws.ws_col = parm1; 554 ws.ws_row = parm2; 555 (void) ioctl(pty, TIOCSWINSZ, (char *)&ws); 556 } 557#endif /* TIOCSWINSZ */ 558 559 break; 560 561 case TELOPT_TSPEED: 562 { 563 def_tspeed = parm1; 564 def_rspeed = parm2; 565#ifdef LINEMODE 566 /* 567 * Defer changing the terminal speed. 568 */ 569 if (terminit() == 0) 570 return; 571#endif /* LINEMODE */ 572 /* 573 * Change terminal speed as requested by client. 574 * We set the receive speed first, so that if we can't 575 * store separate receive and transmit speeds, the transmit 576 * speed will take precedence. 577 */ 578 tty_rspeed(parm2); 579 tty_tspeed(parm1); 580 set_termbuf(); 581 582 break; 583 584 } /* end of case TELOPT_TSPEED */ 585 586 default: 587 /* What? */ 588 break; 589 } /* end of switch */ 590 591#if defined(CRAY2) && defined(UNICOS5) 592 /* 593 * Just in case of the likely event that we changed the pty state. 594 */ 595 rcv_ioctl(); 596#endif /* defined(CRAY2) && defined(UNICOS5) */ 597 598 netflush(); 599 600} /* end of clientstat */ 601 602#if defined(CRAY2) && defined(UNICOS5) 603 void 604termstat() 605{ 606 needtermstat = 1; 607} 608 609 void 610_termstat() 611{ 612 needtermstat = 0; 613 init_termbuf(); 614 localstat(); 615 rcv_ioctl(); 616} 617#endif /* defined(CRAY2) && defined(UNICOS5) */ 618 619#ifdef LINEMODE 620/* 621 * defer_terminit 622 * 623 * Some things should not be done until after the login process has started 624 * and all the pty modes are set to what they are supposed to be. This 625 * function is called when the pty state has been processed for the first time. 626 * It calls other functions that do things that were deferred in each module. 627 */ 628 void 629defer_terminit() 630{ 631 632 /* 633 * local stuff that got deferred. 634 */ 635 if (def_tspeed != -1) { 636 clientstat(TELOPT_TSPEED, def_tspeed, def_rspeed); 637 def_tspeed = def_rspeed = 0; 638 } 639 640#ifdef TIOCSWINSZ 641 if (def_col || def_row) { 642 struct winsize ws; 643 644 memset((char *)&ws, 0, sizeof(ws)); 645 ws.ws_col = def_col; 646 ws.ws_row = def_row; 647 (void) ioctl(pty, TIOCSWINSZ, (char *)&ws); 648 } 649#endif 650 651 /* 652 * The only other module that currently defers anything. 653 */ 654 deferslc(); 655 656} /* end of defer_terminit */ 657 658/* 659 * terminit 660 * 661 * Returns true if the pty state has been processed yet. 662 */ 663 int 664terminit() 665{ 666 return(_terminit); 667 668} /* end of terminit */ 669#endif /* LINEMODE */
| 199 200#ifdef ENCRYPTION 201 /* 202 * If the terminal is not echoing, but editing is enabled, 203 * something like password input is going to happen, so 204 * if we the other side is not currently sending encrypted 205 * data, ask the other side to start encrypting. 206 */ 207 if (his_state_is_will(TELOPT_ENCRYPT)) { 208 static int enc_passwd = 0; 209 if (uselinemode && !tty_isecho() && tty_isediting() 210 && (enc_passwd == 0) && !decrypt_input) { 211 encrypt_send_request_start(); 212 enc_passwd = 1; 213 } else if (enc_passwd) { 214 encrypt_send_request_end(); 215 enc_passwd = 0; 216 } 217 } 218#endif /* ENCRYPTION */ 219 220 /* 221 * Do echo mode handling as soon as we know what the 222 * linemode is going to be. 223 * If the pty has echo turned off, then tell the client that 224 * the server will echo. If echo is on, then the server 225 * will echo if in character mode, but in linemode the 226 * client should do local echoing. The state machine will 227 * not send anything if it is unnecessary, so don't worry 228 * about that here. 229 * 230 * If we need to send the WILL ECHO (because echo is off), 231 * then delay that until after we have changed the MODE. 232 * This way, when the user is turning off both editing 233 * and echo, the client will get editing turned off first. 234 * This keeps the client from going into encryption mode 235 * and then right back out if it is doing auto-encryption 236 * when passwords are being typed. 237 */ 238 if (uselinemode) { 239 if (tty_isecho()) 240 send_wont(TELOPT_ECHO, 1); 241 else 242 need_will_echo = 1; 243#ifdef KLUDGELINEMODE 244 if (lmodetype == KLUDGE_OK) 245 lmodetype = KLUDGE_LINEMODE; 246#endif 247 } 248 249 /* 250 * If linemode is being turned off, send appropriate 251 * command and then we're all done. 252 */ 253 if (!uselinemode && linemode) { 254# ifdef KLUDGELINEMODE 255 if (lmodetype == REAL_LINEMODE) { 256# endif /* KLUDGELINEMODE */ 257 send_dont(TELOPT_LINEMODE, 1); 258# ifdef KLUDGELINEMODE 259 } else if (lmodetype == KLUDGE_LINEMODE) 260 send_will(TELOPT_SGA, 1); 261# endif /* KLUDGELINEMODE */ 262 send_will(TELOPT_ECHO, 1); 263 linemode = uselinemode; 264 goto done; 265 } 266 267# ifdef KLUDGELINEMODE 268 /* 269 * If using real linemode check edit modes for possible later use. 270 * If we are in kludge linemode, do the SGA negotiation. 271 */ 272 if (lmodetype == REAL_LINEMODE) { 273# endif /* KLUDGELINEMODE */ 274 useeditmode = 0; 275 if (tty_isediting()) 276 useeditmode |= MODE_EDIT; 277 if (tty_istrapsig()) 278 useeditmode |= MODE_TRAPSIG; 279 if (tty_issofttab()) 280 useeditmode |= MODE_SOFT_TAB; 281 if (tty_islitecho()) 282 useeditmode |= MODE_LIT_ECHO; 283# ifdef KLUDGELINEMODE 284 } else if (lmodetype == KLUDGE_LINEMODE) { 285 if (tty_isediting() && uselinemode) 286 send_wont(TELOPT_SGA, 1); 287 else 288 send_will(TELOPT_SGA, 1); 289 } 290# endif /* KLUDGELINEMODE */ 291 292 /* 293 * Negotiate linemode on if pty state has changed to turn it on. 294 * Send appropriate command and send along edit mode, then all done. 295 */ 296 if (uselinemode && !linemode) { 297# ifdef KLUDGELINEMODE 298 if (lmodetype == KLUDGE_LINEMODE) { 299 send_wont(TELOPT_SGA, 1); 300 } else if (lmodetype == REAL_LINEMODE) { 301# endif /* KLUDGELINEMODE */ 302 send_do(TELOPT_LINEMODE, 1); 303 /* send along edit modes */ 304 output_data("%c%c%c%c%c%c%c", IAC, SB, 305 TELOPT_LINEMODE, LM_MODE, useeditmode, 306 IAC, SE); 307 editmode = useeditmode; 308# ifdef KLUDGELINEMODE 309 } 310# endif /* KLUDGELINEMODE */ 311 linemode = uselinemode; 312 goto done; 313 } 314 315# ifdef KLUDGELINEMODE 316 /* 317 * None of what follows is of any value if not using 318 * real linemode. 319 */ 320 if (lmodetype < REAL_LINEMODE) 321 goto done; 322# endif /* KLUDGELINEMODE */ 323 324 if (linemode && his_state_is_will(TELOPT_LINEMODE)) { 325 /* 326 * If edit mode changed, send edit mode. 327 */ 328 if (useeditmode != editmode) { 329 /* 330 * Send along appropriate edit mode mask. 331 */ 332 output_data("%c%c%c%c%c%c%c", IAC, SB, 333 TELOPT_LINEMODE, LM_MODE, useeditmode, 334 IAC, SE); 335 editmode = useeditmode; 336 } 337 338 339 /* 340 * Check for changes to special characters in use. 341 */ 342 start_slc(0); 343 check_slc(); 344 (void) end_slc(0); 345 } 346 347done: 348 if (need_will_echo) 349 send_will(TELOPT_ECHO, 1); 350 /* 351 * Some things should be deferred until after the pty state has 352 * been set by the local process. Do those things that have been 353 * deferred now. This only happens once. 354 */ 355 if (_terminit == 0) { 356 _terminit = 1; 357 defer_terminit(); 358 } 359 360 netflush(); 361 set_termbuf(); 362 return; 363 364} /* end of localstat */ 365#endif /* LINEMODE */ 366 367/* 368 * flowstat 369 * 370 * Check for changes to flow control 371 */ 372 void 373flowstat() 374{ 375 if (his_state_is_will(TELOPT_LFLOW)) { 376 if (tty_flowmode() != flowmode) { 377 flowmode = tty_flowmode(); 378 output_data("%c%c%c%c%c%c", 379 IAC, SB, TELOPT_LFLOW, 380 flowmode ? LFLOW_ON : LFLOW_OFF, 381 IAC, SE); 382 } 383 if (tty_restartany() != restartany) { 384 restartany = tty_restartany(); 385 output_data("%c%c%c%c%c%c", 386 IAC, SB, TELOPT_LFLOW, 387 restartany ? LFLOW_RESTART_ANY 388 : LFLOW_RESTART_XON, 389 IAC, SE); 390 } 391 } 392} 393 394/* 395 * clientstat 396 * 397 * Process linemode related requests from the client. 398 * Client can request a change to only one of linemode, editmode or slc's 399 * at a time, and if using kludge linemode, then only linemode may be 400 * affected. 401 */ 402 void 403clientstat(code, parm1, parm2) 404 register int code, parm1, parm2; 405{ 406 407 /* 408 * Get a copy of terminal characteristics. 409 */ 410 init_termbuf(); 411 412 /* 413 * Process request from client. code tells what it is. 414 */ 415 switch (code) { 416#ifdef LINEMODE 417 case TELOPT_LINEMODE: 418 /* 419 * Don't do anything unless client is asking us to change 420 * modes. 421 */ 422 uselinemode = (parm1 == WILL); 423 if (uselinemode != linemode) { 424# ifdef KLUDGELINEMODE 425 /* 426 * If using kludge linemode, make sure that 427 * we can do what the client asks. 428 * We can not turn off linemode if alwayslinemode 429 * and the ICANON bit is set. 430 */ 431 if (lmodetype == KLUDGE_LINEMODE) { 432 if (alwayslinemode && tty_isediting()) { 433 uselinemode = 1; 434 } 435 } 436 437 /* 438 * Quit now if we can't do it. 439 */ 440 if (uselinemode == linemode) 441 return; 442 443 /* 444 * If using real linemode and linemode is being 445 * turned on, send along the edit mode mask. 446 */ 447 if (lmodetype == REAL_LINEMODE && uselinemode) 448# else /* KLUDGELINEMODE */ 449 if (uselinemode) 450# endif /* KLUDGELINEMODE */ 451 { 452 useeditmode = 0; 453 if (tty_isediting()) 454 useeditmode |= MODE_EDIT; 455 if (tty_istrapsig) 456 useeditmode |= MODE_TRAPSIG; 457 if (tty_issofttab()) 458 useeditmode |= MODE_SOFT_TAB; 459 if (tty_islitecho()) 460 useeditmode |= MODE_LIT_ECHO; 461 output_data("%c%c%c%c%c%c%c", IAC, 462 SB, TELOPT_LINEMODE, LM_MODE, 463 useeditmode, IAC, SE); 464 editmode = useeditmode; 465 } 466 467 468 tty_setlinemode(uselinemode); 469 470 linemode = uselinemode; 471 472 if (!linemode) 473 send_will(TELOPT_ECHO, 1); 474 } 475 break; 476 477 case LM_MODE: 478 { 479 register int ack, changed; 480 481 /* 482 * Client has sent along a mode mask. If it agrees with 483 * what we are currently doing, ignore it; if not, it could 484 * be viewed as a request to change. Note that the server 485 * will change to the modes in an ack if it is different from 486 * what we currently have, but we will not ack the ack. 487 */ 488 useeditmode &= MODE_MASK; 489 ack = (useeditmode & MODE_ACK); 490 useeditmode &= ~MODE_ACK; 491 492 if ((changed = (useeditmode ^ editmode))) { 493 /* 494 * This check is for a timing problem. If the 495 * state of the tty has changed (due to the user 496 * application) we need to process that info 497 * before we write in the state contained in the 498 * ack!!! This gets out the new MODE request, 499 * and when the ack to that command comes back 500 * we'll set it and be in the right mode. 501 */ 502 if (ack) 503 localstat(); 504 if (changed & MODE_EDIT) 505 tty_setedit(useeditmode & MODE_EDIT); 506 507 if (changed & MODE_TRAPSIG) 508 tty_setsig(useeditmode & MODE_TRAPSIG); 509 510 if (changed & MODE_SOFT_TAB) 511 tty_setsofttab(useeditmode & MODE_SOFT_TAB); 512 513 if (changed & MODE_LIT_ECHO) 514 tty_setlitecho(useeditmode & MODE_LIT_ECHO); 515 516 set_termbuf(); 517 518 if (!ack) { 519 output_data("%c%c%c%c%c%c%c", IAC, 520 SB, TELOPT_LINEMODE, LM_MODE, 521 useeditmode|MODE_ACK, 522 IAC, SE); 523 } 524 525 editmode = useeditmode; 526 } 527 528 break; 529 530 } /* end of case LM_MODE */ 531#endif /* LINEMODE */ 532 533 case TELOPT_NAWS: 534#ifdef TIOCSWINSZ 535 { 536 struct winsize ws; 537 538 def_col = parm1; 539 def_row = parm2; 540#ifdef LINEMODE 541 /* 542 * Defer changing window size until after terminal is 543 * initialized. 544 */ 545 if (terminit() == 0) 546 return; 547#endif /* LINEMODE */ 548 549 /* 550 * Change window size as requested by client. 551 */ 552 553 ws.ws_col = parm1; 554 ws.ws_row = parm2; 555 (void) ioctl(pty, TIOCSWINSZ, (char *)&ws); 556 } 557#endif /* TIOCSWINSZ */ 558 559 break; 560 561 case TELOPT_TSPEED: 562 { 563 def_tspeed = parm1; 564 def_rspeed = parm2; 565#ifdef LINEMODE 566 /* 567 * Defer changing the terminal speed. 568 */ 569 if (terminit() == 0) 570 return; 571#endif /* LINEMODE */ 572 /* 573 * Change terminal speed as requested by client. 574 * We set the receive speed first, so that if we can't 575 * store separate receive and transmit speeds, the transmit 576 * speed will take precedence. 577 */ 578 tty_rspeed(parm2); 579 tty_tspeed(parm1); 580 set_termbuf(); 581 582 break; 583 584 } /* end of case TELOPT_TSPEED */ 585 586 default: 587 /* What? */ 588 break; 589 } /* end of switch */ 590 591#if defined(CRAY2) && defined(UNICOS5) 592 /* 593 * Just in case of the likely event that we changed the pty state. 594 */ 595 rcv_ioctl(); 596#endif /* defined(CRAY2) && defined(UNICOS5) */ 597 598 netflush(); 599 600} /* end of clientstat */ 601 602#if defined(CRAY2) && defined(UNICOS5) 603 void 604termstat() 605{ 606 needtermstat = 1; 607} 608 609 void 610_termstat() 611{ 612 needtermstat = 0; 613 init_termbuf(); 614 localstat(); 615 rcv_ioctl(); 616} 617#endif /* defined(CRAY2) && defined(UNICOS5) */ 618 619#ifdef LINEMODE 620/* 621 * defer_terminit 622 * 623 * Some things should not be done until after the login process has started 624 * and all the pty modes are set to what they are supposed to be. This 625 * function is called when the pty state has been processed for the first time. 626 * It calls other functions that do things that were deferred in each module. 627 */ 628 void 629defer_terminit() 630{ 631 632 /* 633 * local stuff that got deferred. 634 */ 635 if (def_tspeed != -1) { 636 clientstat(TELOPT_TSPEED, def_tspeed, def_rspeed); 637 def_tspeed = def_rspeed = 0; 638 } 639 640#ifdef TIOCSWINSZ 641 if (def_col || def_row) { 642 struct winsize ws; 643 644 memset((char *)&ws, 0, sizeof(ws)); 645 ws.ws_col = def_col; 646 ws.ws_row = def_row; 647 (void) ioctl(pty, TIOCSWINSZ, (char *)&ws); 648 } 649#endif 650 651 /* 652 * The only other module that currently defers anything. 653 */ 654 deferslc(); 655 656} /* end of defer_terminit */ 657 658/* 659 * terminit 660 * 661 * Returns true if the pty state has been processed yet. 662 */ 663 int 664terminit() 665{ 666 return(_terminit); 667 668} /* end of terminit */ 669#endif /* LINEMODE */
|