129088Smarkm/* 229088Smarkm * Copyright (c) 1989, 1993 329088Smarkm * The Regents of the University of California. All rights reserved. 429088Smarkm * 529088Smarkm * Redistribution and use in source and binary forms, with or without 629088Smarkm * modification, are permitted provided that the following conditions 729088Smarkm * are met: 829088Smarkm * 1. Redistributions of source code must retain the above copyright 929088Smarkm * notice, this list of conditions and the following disclaimer. 1029088Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1129088Smarkm * notice, this list of conditions and the following disclaimer in the 1229088Smarkm * documentation and/or other materials provided with the distribution. 1329088Smarkm * 3. All advertising materials mentioning features or use of this software 1429088Smarkm * must display the following acknowledgement: 1529088Smarkm * This product includes software developed by the University of 1629088Smarkm * California, Berkeley and its contributors. 1729088Smarkm * 4. Neither the name of the University nor the names of its contributors 1829088Smarkm * may be used to endorse or promote products derived from this software 1929088Smarkm * without specific prior written permission. 2029088Smarkm * 2129088Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2229088Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2329088Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2429088Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2529088Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2629088Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2729088Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2829088Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2929088Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3029088Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3129088Smarkm * SUCH DAMAGE. 3229088Smarkm */ 3329088Smarkm 34114630Sobrien#if 0 3529088Smarkm#ifndef lint 3629181Smarkmstatic const char sccsid[] = "@(#)termstat.c 8.2 (Berkeley) 5/30/95"; 3731622Scharnier#endif 38114630Sobrien#endif 39114630Sobrien#include <sys/cdefs.h> 40114630Sobrien__FBSDID("$FreeBSD$"); 4129088Smarkm 4229088Smarkm#include "telnetd.h" 4329088Smarkm 4487139Smarkm#ifdef ENCRYPTION 4529181Smarkm#include <libtelnet/encrypt.h> 4629181Smarkm#endif 4729181Smarkm 4829088Smarkm/* 4929088Smarkm * local variables 5029088Smarkm */ 5129088Smarkmint def_tspeed = -1, def_rspeed = -1; 5229088Smarkm#ifdef TIOCSWINSZ 5329088Smarkmint def_row = 0, def_col = 0; 5429088Smarkm#endif 5529088Smarkm#ifdef LINEMODE 5629088Smarkmstatic int _terminit = 0; 5729088Smarkm#endif /* LINEMODE */ 5829088Smarkm 5929088Smarkm#ifdef LINEMODE 6029088Smarkm/* 6129088Smarkm * localstat 6229088Smarkm * 6329088Smarkm * This function handles all management of linemode. 6429088Smarkm * 6529088Smarkm * Linemode allows the client to do the local editing of data 6629088Smarkm * and send only complete lines to the server. Linemode state is 6729088Smarkm * based on the state of the pty driver. If the pty is set for 6829088Smarkm * external processing, then we can use linemode. Further, if we 6929088Smarkm * can use real linemode, then we can look at the edit control bits 7029088Smarkm * in the pty to determine what editing the client should do. 7129088Smarkm * 7229088Smarkm * Linemode support uses the following state flags to keep track of 7329088Smarkm * current and desired linemode state. 7429088Smarkm * alwayslinemode : true if -l was specified on the telnetd 7529088Smarkm * command line. It means to have linemode on as much as 7629088Smarkm * possible. 7729088Smarkm * 7829088Smarkm * lmodetype: signifies whether the client can 7929088Smarkm * handle real linemode, or if use of kludgeomatic linemode 8029088Smarkm * is preferred. It will be set to one of the following: 8129088Smarkm * REAL_LINEMODE : use linemode option 8229088Smarkm * NO_KLUDGE : don't initiate kludge linemode. 8329088Smarkm * KLUDGE_LINEMODE : use kludge linemode 8429088Smarkm * NO_LINEMODE : client is ignorant of linemode 8529088Smarkm * 8629088Smarkm * linemode, uselinemode : linemode is true if linemode 8729088Smarkm * is currently on, uselinemode is the state that we wish 8829088Smarkm * to be in. If another function wishes to turn linemode 8929088Smarkm * on or off, it sets or clears uselinemode. 9029088Smarkm * 9129088Smarkm * editmode, useeditmode : like linemode/uselinemode, but 9229088Smarkm * these contain the edit mode states (edit and trapsig). 9329088Smarkm * 9429088Smarkm * The state variables correspond to some of the state information 9529088Smarkm * in the pty. 9629088Smarkm * linemode: 9729088Smarkm * In real linemode, this corresponds to whether the pty 9829088Smarkm * expects external processing of incoming data. 9929088Smarkm * In kludge linemode, this more closely corresponds to the 10029088Smarkm * whether normal processing is on or not. (ICANON in 10129088Smarkm * system V, or COOKED mode in BSD.) 10229088Smarkm * If the -l option was specified (alwayslinemode), then 10329088Smarkm * an attempt is made to force external processing on at 10429088Smarkm * all times. 10529088Smarkm * 10629088Smarkm * The following heuristics are applied to determine linemode 10729088Smarkm * handling within the server. 10829088Smarkm * 1) Early on in starting up the server, an attempt is made 10929088Smarkm * to negotiate the linemode option. If this succeeds 11029088Smarkm * then lmodetype is set to REAL_LINEMODE and all linemode 11129088Smarkm * processing occurs in the context of the linemode option. 11229088Smarkm * 2) If the attempt to negotiate the linemode option failed, 11329088Smarkm * and the "-k" (don't initiate kludge linemode) isn't set, 11429088Smarkm * then we try to use kludge linemode. We test for this 11529088Smarkm * capability by sending "do Timing Mark". If a positive 11629088Smarkm * response comes back, then we assume that the client 11729088Smarkm * understands kludge linemode (ech!) and the 11829088Smarkm * lmodetype flag is set to KLUDGE_LINEMODE. 11929088Smarkm * 3) Otherwise, linemode is not supported at all and 12029088Smarkm * lmodetype remains set to NO_LINEMODE (which happens 12129088Smarkm * to be 0 for convenience). 12229088Smarkm * 4) At any time a command arrives that implies a higher 12329088Smarkm * state of linemode support in the client, we move to that 12429088Smarkm * linemode support. 12529088Smarkm * 12629088Smarkm * A short explanation of kludge linemode is in order here. 12729088Smarkm * 1) The heuristic to determine support for kludge linemode 12829088Smarkm * is to send a do timing mark. We assume that a client 12929088Smarkm * that supports timing marks also supports kludge linemode. 13029088Smarkm * A risky proposition at best. 13129088Smarkm * 2) Further negotiation of linemode is done by changing the 13229088Smarkm * the server's state regarding SGA. If server will SGA, 13329088Smarkm * then linemode is off, if server won't SGA, then linemode 13429088Smarkm * is on. 13529088Smarkm */ 13687139Smarkmvoid 13787139Smarkmlocalstat(void) 13829088Smarkm{ 13929088Smarkm int need_will_echo = 0; 14029088Smarkm 14129088Smarkm /* 14229181Smarkm * Check for changes to flow control if client supports it. 14329181Smarkm */ 14429181Smarkm flowstat(); 14529181Smarkm 14629181Smarkm /* 14729181Smarkm * Check linemode on/off state 14829181Smarkm */ 14929181Smarkm uselinemode = tty_linemode(); 15029181Smarkm 15129181Smarkm /* 15229181Smarkm * If alwayslinemode is on, and pty is changing to turn it off, then 15329181Smarkm * force linemode back on. 15429181Smarkm */ 15529181Smarkm if (alwayslinemode && linemode && !uselinemode) { 15629181Smarkm uselinemode = 1; 15729181Smarkm tty_setlinemode(uselinemode); 15829181Smarkm } 15929181Smarkm 16029181Smarkm if (uselinemode) { 16129181Smarkm /* 16281965Smarkm * Check for state of BINARY options. 16329181Smarkm * 16429181Smarkm * We only need to do the binary dance if we are actually going 16529181Smarkm * to use linemode. As this confuses some telnet clients 16629181Smarkm * that don't support linemode, and doesn't gain us 16729181Smarkm * anything, we don't do it unless we're doing linemode. 16829181Smarkm * -Crh (henrich@msu.edu) 16981965Smarkm */ 17029181Smarkm 17181965Smarkm if (tty_isbinaryin()) { 17281965Smarkm if (his_want_state_is_wont(TELOPT_BINARY)) 17381965Smarkm send_do(TELOPT_BINARY, 1); 17481965Smarkm } else { 17581965Smarkm if (his_want_state_is_will(TELOPT_BINARY)) 17681965Smarkm send_dont(TELOPT_BINARY, 1); 17781965Smarkm } 17829088Smarkm 17981965Smarkm if (tty_isbinaryout()) { 18081965Smarkm if (my_want_state_is_wont(TELOPT_BINARY)) 18181965Smarkm send_will(TELOPT_BINARY, 1); 18281965Smarkm } else { 18381965Smarkm if (my_want_state_is_will(TELOPT_BINARY)) 18481965Smarkm send_wont(TELOPT_BINARY, 1); 18581965Smarkm } 18629088Smarkm } 18729088Smarkm 18829088Smarkm#ifdef ENCRYPTION 18929088Smarkm /* 19029088Smarkm * If the terminal is not echoing, but editing is enabled, 19129088Smarkm * something like password input is going to happen, so 19229088Smarkm * if we the other side is not currently sending encrypted 19329088Smarkm * data, ask the other side to start encrypting. 19429088Smarkm */ 19529088Smarkm if (his_state_is_will(TELOPT_ENCRYPT)) { 19629088Smarkm static int enc_passwd = 0; 19729088Smarkm if (uselinemode && !tty_isecho() && tty_isediting() 19829088Smarkm && (enc_passwd == 0) && !decrypt_input) { 19929088Smarkm encrypt_send_request_start(); 20029088Smarkm enc_passwd = 1; 20129088Smarkm } else if (enc_passwd) { 20229088Smarkm encrypt_send_request_end(); 20329088Smarkm enc_passwd = 0; 20429088Smarkm } 20529088Smarkm } 20629088Smarkm#endif /* ENCRYPTION */ 20729088Smarkm 20829088Smarkm /* 20929088Smarkm * Do echo mode handling as soon as we know what the 21029088Smarkm * linemode is going to be. 21129088Smarkm * If the pty has echo turned off, then tell the client that 21229088Smarkm * the server will echo. If echo is on, then the server 21329088Smarkm * will echo if in character mode, but in linemode the 21429088Smarkm * client should do local echoing. The state machine will 21529088Smarkm * not send anything if it is unnecessary, so don't worry 21629088Smarkm * about that here. 21729088Smarkm * 21829088Smarkm * If we need to send the WILL ECHO (because echo is off), 21929088Smarkm * then delay that until after we have changed the MODE. 22029088Smarkm * This way, when the user is turning off both editing 22129088Smarkm * and echo, the client will get editing turned off first. 22229088Smarkm * This keeps the client from going into encryption mode 22329088Smarkm * and then right back out if it is doing auto-encryption 22429088Smarkm * when passwords are being typed. 22529088Smarkm */ 22629088Smarkm if (uselinemode) { 22729088Smarkm if (tty_isecho()) 22829088Smarkm send_wont(TELOPT_ECHO, 1); 22929088Smarkm else 23029088Smarkm need_will_echo = 1; 23129088Smarkm#ifdef KLUDGELINEMODE 23229088Smarkm if (lmodetype == KLUDGE_OK) 23329088Smarkm lmodetype = KLUDGE_LINEMODE; 23429088Smarkm#endif 23529088Smarkm } 23629088Smarkm 23729088Smarkm /* 23829088Smarkm * If linemode is being turned off, send appropriate 23929088Smarkm * command and then we're all done. 24029088Smarkm */ 24129088Smarkm if (!uselinemode && linemode) { 24229088Smarkm# ifdef KLUDGELINEMODE 24329088Smarkm if (lmodetype == REAL_LINEMODE) { 24429088Smarkm# endif /* KLUDGELINEMODE */ 24529088Smarkm send_dont(TELOPT_LINEMODE, 1); 24629088Smarkm# ifdef KLUDGELINEMODE 24729088Smarkm } else if (lmodetype == KLUDGE_LINEMODE) 24829088Smarkm send_will(TELOPT_SGA, 1); 24929088Smarkm# endif /* KLUDGELINEMODE */ 25029088Smarkm send_will(TELOPT_ECHO, 1); 25129088Smarkm linemode = uselinemode; 25229088Smarkm goto done; 25329088Smarkm } 25429088Smarkm 25529088Smarkm# ifdef KLUDGELINEMODE 25629088Smarkm /* 25729088Smarkm * If using real linemode check edit modes for possible later use. 25829088Smarkm * If we are in kludge linemode, do the SGA negotiation. 25929088Smarkm */ 26029088Smarkm if (lmodetype == REAL_LINEMODE) { 26129088Smarkm# endif /* KLUDGELINEMODE */ 26229088Smarkm useeditmode = 0; 26329088Smarkm if (tty_isediting()) 26429088Smarkm useeditmode |= MODE_EDIT; 26529088Smarkm if (tty_istrapsig()) 26629088Smarkm useeditmode |= MODE_TRAPSIG; 26729088Smarkm if (tty_issofttab()) 26829088Smarkm useeditmode |= MODE_SOFT_TAB; 26929088Smarkm if (tty_islitecho()) 27029088Smarkm useeditmode |= MODE_LIT_ECHO; 27129088Smarkm# ifdef KLUDGELINEMODE 27229088Smarkm } else if (lmodetype == KLUDGE_LINEMODE) { 27329088Smarkm if (tty_isediting() && uselinemode) 27429088Smarkm send_wont(TELOPT_SGA, 1); 27529088Smarkm else 27629088Smarkm send_will(TELOPT_SGA, 1); 27729088Smarkm } 27829088Smarkm# endif /* KLUDGELINEMODE */ 27929088Smarkm 28029088Smarkm /* 28129088Smarkm * Negotiate linemode on if pty state has changed to turn it on. 28229088Smarkm * Send appropriate command and send along edit mode, then all done. 28329088Smarkm */ 28429088Smarkm if (uselinemode && !linemode) { 28529088Smarkm# ifdef KLUDGELINEMODE 28629088Smarkm if (lmodetype == KLUDGE_LINEMODE) { 28729088Smarkm send_wont(TELOPT_SGA, 1); 28829088Smarkm } else if (lmodetype == REAL_LINEMODE) { 28929088Smarkm# endif /* KLUDGELINEMODE */ 29029088Smarkm send_do(TELOPT_LINEMODE, 1); 29129088Smarkm /* send along edit modes */ 29279981Sru output_data("%c%c%c%c%c%c%c", IAC, SB, 29329088Smarkm TELOPT_LINEMODE, LM_MODE, useeditmode, 29429088Smarkm IAC, SE); 29529088Smarkm editmode = useeditmode; 29629088Smarkm# ifdef KLUDGELINEMODE 29729088Smarkm } 29829088Smarkm# endif /* KLUDGELINEMODE */ 29929088Smarkm linemode = uselinemode; 30029088Smarkm goto done; 30129088Smarkm } 30229088Smarkm 30329088Smarkm# ifdef KLUDGELINEMODE 30429088Smarkm /* 30529088Smarkm * None of what follows is of any value if not using 30629088Smarkm * real linemode. 30729088Smarkm */ 30829088Smarkm if (lmodetype < REAL_LINEMODE) 30929088Smarkm goto done; 31029088Smarkm# endif /* KLUDGELINEMODE */ 31129088Smarkm 31229088Smarkm if (linemode && his_state_is_will(TELOPT_LINEMODE)) { 31329088Smarkm /* 31429088Smarkm * If edit mode changed, send edit mode. 31529088Smarkm */ 31629088Smarkm if (useeditmode != editmode) { 31729088Smarkm /* 31829088Smarkm * Send along appropriate edit mode mask. 31929088Smarkm */ 32079981Sru output_data("%c%c%c%c%c%c%c", IAC, SB, 32129088Smarkm TELOPT_LINEMODE, LM_MODE, useeditmode, 32229088Smarkm IAC, SE); 32329088Smarkm editmode = useeditmode; 32429088Smarkm } 32529088Smarkm 32629088Smarkm 32729088Smarkm /* 32829088Smarkm * Check for changes to special characters in use. 32929088Smarkm */ 33029088Smarkm start_slc(0); 33129088Smarkm check_slc(); 33229088Smarkm (void) end_slc(0); 33329088Smarkm } 33429088Smarkm 33529088Smarkmdone: 33629088Smarkm if (need_will_echo) 33729088Smarkm send_will(TELOPT_ECHO, 1); 33829088Smarkm /* 33929088Smarkm * Some things should be deferred until after the pty state has 34029088Smarkm * been set by the local process. Do those things that have been 34129088Smarkm * deferred now. This only happens once. 34229088Smarkm */ 34329088Smarkm if (_terminit == 0) { 34429088Smarkm _terminit = 1; 34529088Smarkm defer_terminit(); 34629088Smarkm } 34729088Smarkm 34829088Smarkm netflush(); 34929088Smarkm set_termbuf(); 35029088Smarkm return; 35129088Smarkm 35229088Smarkm} /* end of localstat */ 35329088Smarkm#endif /* LINEMODE */ 35429088Smarkm 35529088Smarkm/* 35629088Smarkm * flowstat 35729088Smarkm * 35829088Smarkm * Check for changes to flow control 35929088Smarkm */ 36087139Smarkmvoid 36187139Smarkmflowstat(void) 36229088Smarkm{ 36329088Smarkm if (his_state_is_will(TELOPT_LFLOW)) { 36429088Smarkm if (tty_flowmode() != flowmode) { 36529088Smarkm flowmode = tty_flowmode(); 36679981Sru output_data("%c%c%c%c%c%c", 36729088Smarkm IAC, SB, TELOPT_LFLOW, 36829088Smarkm flowmode ? LFLOW_ON : LFLOW_OFF, 36929088Smarkm IAC, SE); 37029088Smarkm } 37129088Smarkm if (tty_restartany() != restartany) { 37229088Smarkm restartany = tty_restartany(); 37379981Sru output_data("%c%c%c%c%c%c", 37429088Smarkm IAC, SB, TELOPT_LFLOW, 37529088Smarkm restartany ? LFLOW_RESTART_ANY 37629088Smarkm : LFLOW_RESTART_XON, 37729088Smarkm IAC, SE); 37829088Smarkm } 37929088Smarkm } 38029088Smarkm} 38129088Smarkm 38229088Smarkm/* 38329088Smarkm * clientstat 38429088Smarkm * 38529088Smarkm * Process linemode related requests from the client. 38629088Smarkm * Client can request a change to only one of linemode, editmode or slc's 38729088Smarkm * at a time, and if using kludge linemode, then only linemode may be 38829088Smarkm * affected. 38929088Smarkm */ 39087139Smarkmvoid 39187139Smarkmclientstat(int code, int parm1, int parm2) 39229088Smarkm{ 39329088Smarkm 39429088Smarkm /* 39529088Smarkm * Get a copy of terminal characteristics. 39629088Smarkm */ 39729088Smarkm init_termbuf(); 39829088Smarkm 39929088Smarkm /* 40029088Smarkm * Process request from client. code tells what it is. 40129088Smarkm */ 40229088Smarkm switch (code) { 40329088Smarkm#ifdef LINEMODE 40429088Smarkm case TELOPT_LINEMODE: 40529088Smarkm /* 40629088Smarkm * Don't do anything unless client is asking us to change 40729088Smarkm * modes. 40829088Smarkm */ 40929088Smarkm uselinemode = (parm1 == WILL); 41029088Smarkm if (uselinemode != linemode) { 41129088Smarkm# ifdef KLUDGELINEMODE 41229088Smarkm /* 41329088Smarkm * If using kludge linemode, make sure that 41429088Smarkm * we can do what the client asks. 41529088Smarkm * We can not turn off linemode if alwayslinemode 41629088Smarkm * and the ICANON bit is set. 41729088Smarkm */ 41829088Smarkm if (lmodetype == KLUDGE_LINEMODE) { 41929088Smarkm if (alwayslinemode && tty_isediting()) { 42029088Smarkm uselinemode = 1; 42129088Smarkm } 42229088Smarkm } 42329088Smarkm 42429088Smarkm /* 42529088Smarkm * Quit now if we can't do it. 42629088Smarkm */ 42729088Smarkm if (uselinemode == linemode) 42829088Smarkm return; 42929088Smarkm 43029088Smarkm /* 43129088Smarkm * If using real linemode and linemode is being 43229088Smarkm * turned on, send along the edit mode mask. 43329088Smarkm */ 43429088Smarkm if (lmodetype == REAL_LINEMODE && uselinemode) 43529088Smarkm# else /* KLUDGELINEMODE */ 43629088Smarkm if (uselinemode) 43729088Smarkm# endif /* KLUDGELINEMODE */ 43829088Smarkm { 43929088Smarkm useeditmode = 0; 44029088Smarkm if (tty_isediting()) 44129088Smarkm useeditmode |= MODE_EDIT; 442132753Skan if (tty_istrapsig()) 44329088Smarkm useeditmode |= MODE_TRAPSIG; 44429088Smarkm if (tty_issofttab()) 44529088Smarkm useeditmode |= MODE_SOFT_TAB; 44629088Smarkm if (tty_islitecho()) 44729088Smarkm useeditmode |= MODE_LIT_ECHO; 44879981Sru output_data("%c%c%c%c%c%c%c", IAC, 44929088Smarkm SB, TELOPT_LINEMODE, LM_MODE, 45029088Smarkm useeditmode, IAC, SE); 45129088Smarkm editmode = useeditmode; 45229088Smarkm } 45329088Smarkm 45429088Smarkm 45529088Smarkm tty_setlinemode(uselinemode); 45629088Smarkm 45729088Smarkm linemode = uselinemode; 45829088Smarkm 45929088Smarkm if (!linemode) 46029088Smarkm send_will(TELOPT_ECHO, 1); 46129088Smarkm } 46229088Smarkm break; 46329088Smarkm 46429088Smarkm case LM_MODE: 46529088Smarkm { 46687139Smarkm int ack, changed; 46729088Smarkm 46829088Smarkm /* 46929088Smarkm * Client has sent along a mode mask. If it agrees with 47029088Smarkm * what we are currently doing, ignore it; if not, it could 47129088Smarkm * be viewed as a request to change. Note that the server 47229088Smarkm * will change to the modes in an ack if it is different from 47329088Smarkm * what we currently have, but we will not ack the ack. 47429088Smarkm */ 47529088Smarkm useeditmode &= MODE_MASK; 47629088Smarkm ack = (useeditmode & MODE_ACK); 47729088Smarkm useeditmode &= ~MODE_ACK; 47829088Smarkm 47929181Smarkm if ((changed = (useeditmode ^ editmode))) { 48029088Smarkm /* 48129088Smarkm * This check is for a timing problem. If the 48229088Smarkm * state of the tty has changed (due to the user 48329088Smarkm * application) we need to process that info 48429088Smarkm * before we write in the state contained in the 48529088Smarkm * ack!!! This gets out the new MODE request, 48629088Smarkm * and when the ack to that command comes back 48729088Smarkm * we'll set it and be in the right mode. 48829088Smarkm */ 48929088Smarkm if (ack) 49029088Smarkm localstat(); 49129088Smarkm if (changed & MODE_EDIT) 49229088Smarkm tty_setedit(useeditmode & MODE_EDIT); 49329088Smarkm 49429088Smarkm if (changed & MODE_TRAPSIG) 49529088Smarkm tty_setsig(useeditmode & MODE_TRAPSIG); 49629088Smarkm 49729088Smarkm if (changed & MODE_SOFT_TAB) 49829088Smarkm tty_setsofttab(useeditmode & MODE_SOFT_TAB); 49929088Smarkm 50029088Smarkm if (changed & MODE_LIT_ECHO) 50129088Smarkm tty_setlitecho(useeditmode & MODE_LIT_ECHO); 50229088Smarkm 50329088Smarkm set_termbuf(); 50429088Smarkm 50529088Smarkm if (!ack) { 50679981Sru output_data("%c%c%c%c%c%c%c", IAC, 50729088Smarkm SB, TELOPT_LINEMODE, LM_MODE, 50829088Smarkm useeditmode|MODE_ACK, 50929088Smarkm IAC, SE); 51029088Smarkm } 51129088Smarkm 51229088Smarkm editmode = useeditmode; 51329088Smarkm } 51429088Smarkm 51529088Smarkm break; 51629088Smarkm 51729088Smarkm } /* end of case LM_MODE */ 51829088Smarkm#endif /* LINEMODE */ 51929088Smarkm 52029088Smarkm case TELOPT_NAWS: 52129088Smarkm#ifdef TIOCSWINSZ 52229088Smarkm { 52329088Smarkm struct winsize ws; 52429088Smarkm 52529088Smarkm def_col = parm1; 52629088Smarkm def_row = parm2; 52729088Smarkm#ifdef LINEMODE 52829088Smarkm /* 52929088Smarkm * Defer changing window size until after terminal is 53029088Smarkm * initialized. 53129088Smarkm */ 53229088Smarkm if (terminit() == 0) 53329088Smarkm return; 53429088Smarkm#endif /* LINEMODE */ 53529088Smarkm 53629088Smarkm /* 53729088Smarkm * Change window size as requested by client. 53829088Smarkm */ 53929088Smarkm 54029088Smarkm ws.ws_col = parm1; 54129088Smarkm ws.ws_row = parm2; 54229088Smarkm (void) ioctl(pty, TIOCSWINSZ, (char *)&ws); 54329088Smarkm } 54429088Smarkm#endif /* TIOCSWINSZ */ 54529088Smarkm 54629088Smarkm break; 54729088Smarkm 54829088Smarkm case TELOPT_TSPEED: 54929088Smarkm { 55029088Smarkm def_tspeed = parm1; 55129088Smarkm def_rspeed = parm2; 55229088Smarkm#ifdef LINEMODE 55329088Smarkm /* 55429088Smarkm * Defer changing the terminal speed. 55529088Smarkm */ 55629088Smarkm if (terminit() == 0) 55729088Smarkm return; 55829088Smarkm#endif /* LINEMODE */ 55929088Smarkm /* 56029088Smarkm * Change terminal speed as requested by client. 56129088Smarkm * We set the receive speed first, so that if we can't 56272089Sasmodai * store separate receive and transmit speeds, the transmit 56329088Smarkm * speed will take precedence. 56429088Smarkm */ 56529088Smarkm tty_rspeed(parm2); 56629088Smarkm tty_tspeed(parm1); 56729088Smarkm set_termbuf(); 56829088Smarkm 56929088Smarkm break; 57029088Smarkm 57129088Smarkm } /* end of case TELOPT_TSPEED */ 57229088Smarkm 57329088Smarkm default: 57429088Smarkm /* What? */ 57529088Smarkm break; 57629088Smarkm } /* end of switch */ 57729088Smarkm 57829088Smarkm netflush(); 57929088Smarkm 58029088Smarkm} /* end of clientstat */ 58129088Smarkm 58229088Smarkm#ifdef LINEMODE 58329088Smarkm/* 58429088Smarkm * defer_terminit 58529088Smarkm * 58629088Smarkm * Some things should not be done until after the login process has started 58729088Smarkm * and all the pty modes are set to what they are supposed to be. This 58829088Smarkm * function is called when the pty state has been processed for the first time. 58929088Smarkm * It calls other functions that do things that were deferred in each module. 59029088Smarkm */ 59187139Smarkmvoid 59287139Smarkmdefer_terminit(void) 59329088Smarkm{ 59429088Smarkm 59529088Smarkm /* 59629088Smarkm * local stuff that got deferred. 59729088Smarkm */ 59829088Smarkm if (def_tspeed != -1) { 59929088Smarkm clientstat(TELOPT_TSPEED, def_tspeed, def_rspeed); 60029088Smarkm def_tspeed = def_rspeed = 0; 60129088Smarkm } 60229088Smarkm 60329088Smarkm#ifdef TIOCSWINSZ 60429088Smarkm if (def_col || def_row) { 60529088Smarkm struct winsize ws; 60629088Smarkm 60729088Smarkm memset((char *)&ws, 0, sizeof(ws)); 60829088Smarkm ws.ws_col = def_col; 60929088Smarkm ws.ws_row = def_row; 61029088Smarkm (void) ioctl(pty, TIOCSWINSZ, (char *)&ws); 61129088Smarkm } 61229088Smarkm#endif 61329088Smarkm 61429088Smarkm /* 61529088Smarkm * The only other module that currently defers anything. 61629088Smarkm */ 61729088Smarkm deferslc(); 61829088Smarkm 61929088Smarkm} /* end of defer_terminit */ 62029088Smarkm 62129088Smarkm/* 62229088Smarkm * terminit 62329088Smarkm * 62429088Smarkm * Returns true if the pty state has been processed yet. 62529088Smarkm */ 62687139Smarkmint 62787139Smarkmterminit(void) 62829088Smarkm{ 62929088Smarkm return(_terminit); 63029088Smarkm 63129088Smarkm} /* end of terminit */ 63229088Smarkm#endif /* LINEMODE */ 633