186530481Sborman /* 286530481Sborman * Copyright (c) 1989 Regents of the University of California. 386530481Sborman * All rights reserved. 486530481Sborman * 5540a81dfSbostic * %sccs.include.redist.c% 686530481Sborman */ 786530481Sborman 886530481Sborman #ifndef lint 9*c6f32291Sdab static char sccsid[] = "@(#)termstat.c 5.13 (Berkeley) 04/05/93"; 1086530481Sborman #endif /* not lint */ 1186530481Sborman 1286530481Sborman #include "telnetd.h" 1386530481Sborman 1486530481Sborman /* 1586530481Sborman * local variables 1686530481Sborman */ 17f9a01b3eSdab int def_tspeed = -1, def_rspeed = -1; 18f9a01b3eSdab #ifdef TIOCSWINSZ 19f9a01b3eSdab int def_row = 0, def_col = 0; 20f9a01b3eSdab #endif 2186530481Sborman #ifdef LINEMODE 2286530481Sborman static int _terminit = 0; 23f9a01b3eSdab #endif /* LINEMODE */ 2486530481Sborman 2517cc352bSborman #if defined(CRAY2) && defined(UNICOS5) 2686530481Sborman int newmap = 1; /* nonzero if \n maps to ^M^J */ 2786530481Sborman #endif 2886530481Sborman 2986530481Sborman #ifdef LINEMODE 3086530481Sborman /* 3186530481Sborman * localstat 3286530481Sborman * 3386530481Sborman * This function handles all management of linemode. 3486530481Sborman * 3586530481Sborman * Linemode allows the client to do the local editing of data 3686530481Sborman * and send only complete lines to the server. Linemode state is 3786530481Sborman * based on the state of the pty driver. If the pty is set for 3886530481Sborman * external processing, then we can use linemode. Further, if we 3986530481Sborman * can use real linemode, then we can look at the edit control bits 4086530481Sborman * in the pty to determine what editing the client should do. 4186530481Sborman * 4286530481Sborman * Linemode support uses the following state flags to keep track of 4386530481Sborman * current and desired linemode state. 4486530481Sborman * alwayslinemode : true if -l was specified on the telnetd 4586530481Sborman * command line. It means to have linemode on as much as 4686530481Sborman * possible. 4786530481Sborman * 4886530481Sborman * lmodetype: signifies whether the client can 4986530481Sborman * handle real linemode, or if use of kludgeomatic linemode 5086530481Sborman * is preferred. It will be set to one of the following: 5186530481Sborman * REAL_LINEMODE : use linemode option 52a2574097Sdab * NO_KLUDGE : don't initiate kludge linemode. 5386530481Sborman * KLUDGE_LINEMODE : use kludge linemode 5486530481Sborman * NO_LINEMODE : client is ignorant of linemode 5586530481Sborman * 5686530481Sborman * linemode, uselinemode : linemode is true if linemode 5786530481Sborman * is currently on, uselinemode is the state that we wish 5886530481Sborman * to be in. If another function wishes to turn linemode 5986530481Sborman * on or off, it sets or clears uselinemode. 6086530481Sborman * 6186530481Sborman * editmode, useeditmode : like linemode/uselinemode, but 6286530481Sborman * these contain the edit mode states (edit and trapsig). 6386530481Sborman * 6486530481Sborman * The state variables correspond to some of the state information 6586530481Sborman * in the pty. 6686530481Sborman * linemode: 6786530481Sborman * In real linemode, this corresponds to whether the pty 6886530481Sborman * expects external processing of incoming data. 6986530481Sborman * In kludge linemode, this more closely corresponds to the 7086530481Sborman * whether normal processing is on or not. (ICANON in 7186530481Sborman * system V, or COOKED mode in BSD.) 7286530481Sborman * If the -l option was specified (alwayslinemode), then 7386530481Sborman * an attempt is made to force external processing on at 7486530481Sborman * all times. 7586530481Sborman * 7686530481Sborman * The following heuristics are applied to determine linemode 7786530481Sborman * handling within the server. 7886530481Sborman * 1) Early on in starting up the server, an attempt is made 7986530481Sborman * to negotiate the linemode option. If this succeeds 8086530481Sborman * then lmodetype is set to REAL_LINEMODE and all linemode 8186530481Sborman * processing occurs in the context of the linemode option. 8286530481Sborman * 2) If the attempt to negotiate the linemode option failed, 83a2574097Sdab * and the "-k" (don't initiate kludge linemode) isn't set, 8486530481Sborman * then we try to use kludge linemode. We test for this 8586530481Sborman * capability by sending "do Timing Mark". If a positive 8686530481Sborman * response comes back, then we assume that the client 8786530481Sborman * understands kludge linemode (ech!) and the 8886530481Sborman * lmodetype flag is set to KLUDGE_LINEMODE. 8986530481Sborman * 3) Otherwise, linemode is not supported at all and 9086530481Sborman * lmodetype remains set to NO_LINEMODE (which happens 9186530481Sborman * to be 0 for convenience). 9286530481Sborman * 4) At any time a command arrives that implies a higher 9386530481Sborman * state of linemode support in the client, we move to that 9486530481Sborman * linemode support. 9586530481Sborman * 9686530481Sborman * A short explanation of kludge linemode is in order here. 9786530481Sborman * 1) The heuristic to determine support for kludge linemode 9886530481Sborman * is to send a do timing mark. We assume that a client 9986530481Sborman * that supports timing marks also supports kludge linemode. 10086530481Sborman * A risky proposition at best. 10186530481Sborman * 2) Further negotiation of linemode is done by changing the 10286530481Sborman * the server's state regarding SGA. If server will SGA, 10386530481Sborman * then linemode is off, if server won't SGA, then linemode 10486530481Sborman * is on. 10586530481Sborman */ 106f9a01b3eSdab void 10786530481Sborman localstat() 10886530481Sborman { 10986530481Sborman void netflush(); 110f9a01b3eSdab int need_will_echo = 0; 11186530481Sborman 112658176a6Sborman #if defined(CRAY2) && defined(UNICOS5) 11386530481Sborman /* 11486530481Sborman * Keep track of that ol' CR/NL mapping while we're in the 11586530481Sborman * neighborhood. 11686530481Sborman */ 11786530481Sborman newmap = tty_isnewmap(); 118f9a01b3eSdab #endif /* defined(CRAY2) && defined(UNICOS5) */ 11986530481Sborman 12086530481Sborman /* 12186530481Sborman * Check for state of BINARY options. 12286530481Sborman */ 12386530481Sborman if (tty_isbinaryin()) { 124658176a6Sborman if (his_want_state_is_wont(TELOPT_BINARY)) 125a09b88c8Sborman send_do(TELOPT_BINARY, 1); 12686530481Sborman } else { 127658176a6Sborman if (his_want_state_is_will(TELOPT_BINARY)) 128a09b88c8Sborman send_dont(TELOPT_BINARY, 1); 12986530481Sborman } 13086530481Sborman 13186530481Sborman if (tty_isbinaryout()) { 132658176a6Sborman if (my_want_state_is_wont(TELOPT_BINARY)) 133a09b88c8Sborman send_will(TELOPT_BINARY, 1); 13486530481Sborman } else { 135658176a6Sborman if (my_want_state_is_will(TELOPT_BINARY)) 136a09b88c8Sborman send_wont(TELOPT_BINARY, 1); 13786530481Sborman } 13886530481Sborman 13986530481Sborman /* 14086530481Sborman * Check for changes to flow control if client supports it. 14186530481Sborman */ 142*c6f32291Sdab flowstat(); 14386530481Sborman 14486530481Sborman /* 14586530481Sborman * Check linemode on/off state 14686530481Sborman */ 14786530481Sborman uselinemode = tty_linemode(); 14886530481Sborman 14986530481Sborman /* 15086530481Sborman * If alwayslinemode is on, and pty is changing to turn it off, then 15186530481Sborman * force linemode back on. 15286530481Sborman */ 15386530481Sborman if (alwayslinemode && linemode && !uselinemode) { 15486530481Sborman uselinemode = 1; 15586530481Sborman tty_setlinemode(uselinemode); 15686530481Sborman } 15786530481Sborman 158a2574097Sdab #if defined(ENCRYPTION) 159a94793f7Sdab /* 160a94793f7Sdab * If the terminal is not echoing, but editing is enabled, 161a94793f7Sdab * something like password input is going to happen, so 162a94793f7Sdab * if we the other side is not currently sending encrypted 163a94793f7Sdab * data, ask the other side to start encrypting. 164a94793f7Sdab */ 165a94793f7Sdab if (his_state_is_will(TELOPT_ENCRYPT)) { 166a94793f7Sdab static int enc_passwd = 0; 167a94793f7Sdab if (uselinemode && !tty_isecho() && tty_isediting() 168a94793f7Sdab && (enc_passwd == 0) && !decrypt_input) { 169a94793f7Sdab encrypt_send_request_start(); 170a94793f7Sdab enc_passwd = 1; 171a94793f7Sdab } else if (enc_passwd) { 172a94793f7Sdab encrypt_send_request_end(); 173a94793f7Sdab enc_passwd = 0; 174a94793f7Sdab } 175a94793f7Sdab } 176a94793f7Sdab #endif 177a94793f7Sdab 17886530481Sborman /* 17986530481Sborman * Do echo mode handling as soon as we know what the 18086530481Sborman * linemode is going to be. 18186530481Sborman * If the pty has echo turned off, then tell the client that 18286530481Sborman * the server will echo. If echo is on, then the server 18386530481Sborman * will echo if in character mode, but in linemode the 18486530481Sborman * client should do local echoing. The state machine will 18586530481Sborman * not send anything if it is unnecessary, so don't worry 18686530481Sborman * about that here. 187f9a01b3eSdab * 188f9a01b3eSdab * If we need to send the WILL ECHO (because echo is off), 189f9a01b3eSdab * then delay that until after we have changed the MODE. 190f9a01b3eSdab * This way, when the user is turning off both editing 191f9a01b3eSdab * and echo, the client will get editing turned off first. 192f9a01b3eSdab * This keeps the client from going into encryption mode 193f9a01b3eSdab * and then right back out if it is doing auto-encryption 194f9a01b3eSdab * when passwords are being typed. 19586530481Sborman */ 1968e4bde26Sborman if (uselinemode) { 1978e4bde26Sborman if (tty_isecho()) 198a09b88c8Sborman send_wont(TELOPT_ECHO, 1); 19986530481Sborman else 200f9a01b3eSdab need_will_echo = 1; 201a2574097Sdab #ifdef KLUDGELINEMODE 202a2574097Sdab if (lmodetype == KLUDGE_OK) 203a2574097Sdab lmodetype = KLUDGE_LINEMODE; 204a2574097Sdab #endif 2058e4bde26Sborman } 20686530481Sborman 20786530481Sborman /* 20886530481Sborman * If linemode is being turned off, send appropriate 20986530481Sborman * command and then we're all done. 21086530481Sborman */ 21186530481Sborman if (!uselinemode && linemode) { 21286530481Sborman # ifdef KLUDGELINEMODE 213f9a01b3eSdab if (lmodetype == REAL_LINEMODE) { 21486530481Sborman # endif /* KLUDGELINEMODE */ 215a09b88c8Sborman send_dont(TELOPT_LINEMODE, 1); 21686530481Sborman # ifdef KLUDGELINEMODE 217f9a01b3eSdab } else if (lmodetype == KLUDGE_LINEMODE) 218e2235ae6Sborman send_will(TELOPT_SGA, 1); 21986530481Sborman # endif /* KLUDGELINEMODE */ 220f9a01b3eSdab send_will(TELOPT_ECHO, 1); 22186530481Sborman linemode = uselinemode; 22286530481Sborman goto done; 22386530481Sborman } 22486530481Sborman 22586530481Sborman # ifdef KLUDGELINEMODE 22686530481Sborman /* 22786530481Sborman * If using real linemode check edit modes for possible later use. 228658176a6Sborman * If we are in kludge linemode, do the SGA negotiation. 22986530481Sborman */ 23086530481Sborman if (lmodetype == REAL_LINEMODE) { 23186530481Sborman # endif /* KLUDGELINEMODE */ 23286530481Sborman useeditmode = 0; 23386530481Sborman if (tty_isediting()) 23486530481Sborman useeditmode |= MODE_EDIT; 23586530481Sborman if (tty_istrapsig()) 23686530481Sborman useeditmode |= MODE_TRAPSIG; 237658176a6Sborman if (tty_issofttab()) 238658176a6Sborman useeditmode |= MODE_SOFT_TAB; 239658176a6Sborman if (tty_islitecho()) 240658176a6Sborman useeditmode |= MODE_LIT_ECHO; 24186530481Sborman # ifdef KLUDGELINEMODE 242658176a6Sborman } else if (lmodetype == KLUDGE_LINEMODE) { 243658176a6Sborman if (tty_isediting() && uselinemode) 244658176a6Sborman send_wont(TELOPT_SGA, 1); 245658176a6Sborman else 246658176a6Sborman send_will(TELOPT_SGA, 1); 24786530481Sborman } 24886530481Sborman # endif /* KLUDGELINEMODE */ 24986530481Sborman 25086530481Sborman /* 25186530481Sborman * Negotiate linemode on if pty state has changed to turn it on. 25286530481Sborman * Send appropriate command and send along edit mode, then all done. 25386530481Sborman */ 25486530481Sborman if (uselinemode && !linemode) { 25586530481Sborman # ifdef KLUDGELINEMODE 25686530481Sborman if (lmodetype == KLUDGE_LINEMODE) { 257a09b88c8Sborman send_wont(TELOPT_SGA, 1); 25886530481Sborman } else if (lmodetype == REAL_LINEMODE) { 25986530481Sborman # endif /* KLUDGELINEMODE */ 260a09b88c8Sborman send_do(TELOPT_LINEMODE, 1); 26186530481Sborman /* send along edit modes */ 26286530481Sborman (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB, 26386530481Sborman TELOPT_LINEMODE, LM_MODE, useeditmode, 26486530481Sborman IAC, SE); 26586530481Sborman nfrontp += 7; 26686530481Sborman editmode = useeditmode; 26786530481Sborman # ifdef KLUDGELINEMODE 26886530481Sborman } 26986530481Sborman # endif /* KLUDGELINEMODE */ 27086530481Sborman linemode = uselinemode; 27186530481Sborman goto done; 27286530481Sborman } 27386530481Sborman 27486530481Sborman # ifdef KLUDGELINEMODE 27586530481Sborman /* 27686530481Sborman * None of what follows is of any value if not using 27786530481Sborman * real linemode. 27886530481Sborman */ 27986530481Sborman if (lmodetype < REAL_LINEMODE) 28086530481Sborman goto done; 28186530481Sborman # endif /* KLUDGELINEMODE */ 28286530481Sborman 2838e4bde26Sborman if (linemode && his_state_is_will(TELOPT_LINEMODE)) { 28486530481Sborman /* 28586530481Sborman * If edit mode changed, send edit mode. 28686530481Sborman */ 28786530481Sborman if (useeditmode != editmode) { 28886530481Sborman /* 28986530481Sborman * Send along appropriate edit mode mask. 29086530481Sborman */ 29186530481Sborman (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB, 29286530481Sborman TELOPT_LINEMODE, LM_MODE, useeditmode, 29386530481Sborman IAC, SE); 29486530481Sborman nfrontp += 7; 29586530481Sborman editmode = useeditmode; 29686530481Sborman } 29786530481Sborman 29886530481Sborman 29986530481Sborman /* 30086530481Sborman * Check for changes to special characters in use. 30186530481Sborman */ 30286530481Sborman start_slc(0); 30386530481Sborman check_slc(); 304f9a01b3eSdab (void) end_slc(0); 30586530481Sborman } 30686530481Sborman 30786530481Sborman done: 308f9a01b3eSdab if (need_will_echo) 309f9a01b3eSdab send_will(TELOPT_ECHO, 1); 31086530481Sborman /* 31186530481Sborman * Some things should be deferred until after the pty state has 31286530481Sborman * been set by the local process. Do those things that have been 31386530481Sborman * deferred now. This only happens once. 31486530481Sborman */ 31586530481Sborman if (_terminit == 0) { 31686530481Sborman _terminit = 1; 31786530481Sborman defer_terminit(); 31886530481Sborman } 31986530481Sborman 32086530481Sborman netflush(); 32186530481Sborman set_termbuf(); 32286530481Sborman return; 32386530481Sborman 32486530481Sborman } /* end of localstat */ 32586530481Sborman #endif /* LINEMODE */ 32686530481Sborman 327*c6f32291Sdab /* 328*c6f32291Sdab * flowstat 329*c6f32291Sdab * 330*c6f32291Sdab * Check for changes to flow control 331*c6f32291Sdab */ 332*c6f32291Sdab void 333*c6f32291Sdab flowstat() 334*c6f32291Sdab { 335*c6f32291Sdab if (his_state_is_will(TELOPT_LFLOW)) { 336*c6f32291Sdab if (tty_flowmode() != flowmode) { 337*c6f32291Sdab flowmode = tty_flowmode(); 338*c6f32291Sdab (void) sprintf(nfrontp, "%c%c%c%c%c%c", 339*c6f32291Sdab IAC, SB, TELOPT_LFLOW, 340*c6f32291Sdab flowmode ? LFLOW_ON : LFLOW_OFF, 341*c6f32291Sdab IAC, SE); 342*c6f32291Sdab nfrontp += 6; 343*c6f32291Sdab } 344*c6f32291Sdab if (tty_restartany() != restartany) { 345*c6f32291Sdab restartany = tty_restartany(); 346*c6f32291Sdab (void) sprintf(nfrontp, "%c%c%c%c%c%c", 347*c6f32291Sdab IAC, SB, TELOPT_LFLOW, 348*c6f32291Sdab restartany ? LFLOW_RESTART_ANY 349*c6f32291Sdab : LFLOW_RESTART_XON, 350*c6f32291Sdab IAC, SE); 351*c6f32291Sdab nfrontp += 6; 352*c6f32291Sdab } 353*c6f32291Sdab } 354*c6f32291Sdab } 35586530481Sborman 35686530481Sborman /* 35786530481Sborman * clientstat 35886530481Sborman * 35986530481Sborman * Process linemode related requests from the client. 36086530481Sborman * Client can request a change to only one of linemode, editmode or slc's 36186530481Sborman * at a time, and if using kludge linemode, then only linemode may be 36286530481Sborman * affected. 36386530481Sborman */ 364f9a01b3eSdab void 36586530481Sborman clientstat(code, parm1, parm2) 36686530481Sborman register int code, parm1, parm2; 36786530481Sborman { 36886530481Sborman void netflush(); 36986530481Sborman 37086530481Sborman /* 37186530481Sborman * Get a copy of terminal characteristics. 37286530481Sborman */ 37386530481Sborman init_termbuf(); 37486530481Sborman 37586530481Sborman /* 37686530481Sborman * Process request from client. code tells what it is. 37786530481Sborman */ 37886530481Sborman switch (code) { 37986530481Sborman #ifdef LINEMODE 38086530481Sborman case TELOPT_LINEMODE: 38186530481Sborman /* 38286530481Sborman * Don't do anything unless client is asking us to change 38386530481Sborman * modes. 38486530481Sborman */ 38586530481Sborman uselinemode = (parm1 == WILL); 38686530481Sborman if (uselinemode != linemode) { 38786530481Sborman # ifdef KLUDGELINEMODE 38886530481Sborman /* 38986530481Sborman * If using kludge linemode, make sure that 39086530481Sborman * we can do what the client asks. 39186530481Sborman * We can not turn off linemode if alwayslinemode 392a09b88c8Sborman * and the ICANON bit is set. 39386530481Sborman */ 39486530481Sborman if (lmodetype == KLUDGE_LINEMODE) { 395a09b88c8Sborman if (alwayslinemode && tty_isediting()) { 39686530481Sborman uselinemode = 1; 39786530481Sborman } 39886530481Sborman } 39986530481Sborman 40086530481Sborman /* 40186530481Sborman * Quit now if we can't do it. 40286530481Sborman */ 40386530481Sborman if (uselinemode == linemode) 40486530481Sborman return; 40586530481Sborman 40686530481Sborman /* 40786530481Sborman * If using real linemode and linemode is being 40886530481Sborman * turned on, send along the edit mode mask. 40986530481Sborman */ 41086530481Sborman if (lmodetype == REAL_LINEMODE && uselinemode) 41186530481Sborman # else /* KLUDGELINEMODE */ 41286530481Sborman if (uselinemode) 41386530481Sborman # endif /* KLUDGELINEMODE */ 41486530481Sborman { 41586530481Sborman useeditmode = 0; 41686530481Sborman if (tty_isediting()) 41786530481Sborman useeditmode |= MODE_EDIT; 418f9a01b3eSdab if (tty_istrapsig) 41986530481Sborman useeditmode |= MODE_TRAPSIG; 420658176a6Sborman if (tty_issofttab()) 421658176a6Sborman useeditmode |= MODE_SOFT_TAB; 422658176a6Sborman if (tty_islitecho()) 423658176a6Sborman useeditmode |= MODE_LIT_ECHO; 42486530481Sborman (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, 42586530481Sborman SB, TELOPT_LINEMODE, LM_MODE, 42686530481Sborman useeditmode, IAC, SE); 42786530481Sborman nfrontp += 7; 42886530481Sborman editmode = useeditmode; 42986530481Sborman } 43086530481Sborman 43186530481Sborman 43286530481Sborman tty_setlinemode(uselinemode); 43386530481Sborman 43486530481Sborman linemode = uselinemode; 43586530481Sborman 436a2574097Sdab if (!linemode) 437a2574097Sdab send_will(TELOPT_ECHO, 1); 43886530481Sborman } 43986530481Sborman break; 44086530481Sborman 44186530481Sborman case LM_MODE: 44286530481Sborman { 443658176a6Sborman register int ack, changed; 44486530481Sborman 44586530481Sborman /* 44686530481Sborman * Client has sent along a mode mask. If it agrees with 44786530481Sborman * what we are currently doing, ignore it; if not, it could 44886530481Sborman * be viewed as a request to change. Note that the server 44986530481Sborman * will change to the modes in an ack if it is different from 45086530481Sborman * what we currently have, but we will not ack the ack. 45186530481Sborman */ 45286530481Sborman useeditmode &= MODE_MASK; 45386530481Sborman ack = (useeditmode & MODE_ACK); 45486530481Sborman useeditmode &= ~MODE_ACK; 45586530481Sborman 456658176a6Sborman if (changed = (useeditmode ^ editmode)) { 457f9a01b3eSdab /* 458f9a01b3eSdab * This check is for a timing problem. If the 459f9a01b3eSdab * state of the tty has changed (due to the user 460f9a01b3eSdab * application) we need to process that info 461f9a01b3eSdab * before we write in the state contained in the 462f9a01b3eSdab * ack!!! This gets out the new MODE request, 463f9a01b3eSdab * and when the ack to that command comes back 464f9a01b3eSdab * we'll set it and be in the right mode. 465f9a01b3eSdab */ 466f9a01b3eSdab if (ack) 467f9a01b3eSdab localstat(); 468658176a6Sborman if (changed & MODE_EDIT) 469658176a6Sborman tty_setedit(useeditmode & MODE_EDIT); 47086530481Sborman 471658176a6Sborman if (changed & MODE_TRAPSIG) 472658176a6Sborman tty_setsig(useeditmode & MODE_TRAPSIG); 473658176a6Sborman 474658176a6Sborman if (changed & MODE_SOFT_TAB) 475658176a6Sborman tty_setsofttab(useeditmode & MODE_SOFT_TAB); 476658176a6Sborman 477658176a6Sborman if (changed & MODE_LIT_ECHO) 478658176a6Sborman tty_setlitecho(useeditmode & MODE_LIT_ECHO); 47986530481Sborman 48086530481Sborman set_termbuf(); 48186530481Sborman 48286530481Sborman if (!ack) { 48386530481Sborman (void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, 48486530481Sborman SB, TELOPT_LINEMODE, LM_MODE, 48586530481Sborman useeditmode|MODE_ACK, 48686530481Sborman IAC, SE); 48786530481Sborman nfrontp += 7; 48886530481Sborman } 48986530481Sborman 49086530481Sborman editmode = useeditmode; 49186530481Sborman } 49286530481Sborman 49386530481Sborman break; 49486530481Sborman 49586530481Sborman } /* end of case LM_MODE */ 49686530481Sborman #endif /* LINEMODE */ 49786530481Sborman 49886530481Sborman case TELOPT_NAWS: 49986530481Sborman #ifdef TIOCSWINSZ 50086530481Sborman { 50186530481Sborman struct winsize ws; 50286530481Sborman 503f9a01b3eSdab def_col = parm1; 504f9a01b3eSdab def_row = parm2; 50586530481Sborman #ifdef LINEMODE 50686530481Sborman /* 50786530481Sborman * Defer changing window size until after terminal is 50886530481Sborman * initialized. 50986530481Sborman */ 510f9a01b3eSdab if (terminit() == 0) 51186530481Sborman return; 51286530481Sborman #endif /* LINEMODE */ 51386530481Sborman 51486530481Sborman /* 51586530481Sborman * Change window size as requested by client. 51686530481Sborman */ 51786530481Sborman 51886530481Sborman ws.ws_col = parm1; 51986530481Sborman ws.ws_row = parm2; 52086530481Sborman (void) ioctl(pty, TIOCSWINSZ, (char *)&ws); 52186530481Sborman } 52286530481Sborman #endif /* TIOCSWINSZ */ 52386530481Sborman 52486530481Sborman break; 52586530481Sborman 52686530481Sborman case TELOPT_TSPEED: 52786530481Sborman { 528f9a01b3eSdab def_tspeed = parm1; 529f9a01b3eSdab def_rspeed = parm2; 53086530481Sborman #ifdef LINEMODE 53186530481Sborman /* 53286530481Sborman * Defer changing the terminal speed. 53386530481Sborman */ 534f9a01b3eSdab if (terminit() == 0) 53586530481Sborman return; 53686530481Sborman #endif /* LINEMODE */ 53786530481Sborman /* 53886530481Sborman * Change terminal speed as requested by client. 539f9a01b3eSdab * We set the receive speed first, so that if we can't 540f9a01b3eSdab * store seperate receive and transmit speeds, the transmit 541f9a01b3eSdab * speed will take precedence. 54286530481Sborman */ 54386530481Sborman tty_rspeed(parm2); 544f9a01b3eSdab tty_tspeed(parm1); 54586530481Sborman set_termbuf(); 54686530481Sborman 54786530481Sborman break; 54886530481Sborman 54986530481Sborman } /* end of case TELOPT_TSPEED */ 55086530481Sborman 55186530481Sborman default: 55286530481Sborman /* What? */ 55386530481Sborman break; 55486530481Sborman } /* end of switch */ 55586530481Sborman 55617cc352bSborman #if defined(CRAY2) && defined(UNICOS5) 55786530481Sborman /* 55886530481Sborman * Just in case of the likely event that we changed the pty state. 55986530481Sborman */ 56086530481Sborman rcv_ioctl(); 56117cc352bSborman #endif /* defined(CRAY2) && defined(UNICOS5) */ 56286530481Sborman 56386530481Sborman netflush(); 56486530481Sborman 56586530481Sborman } /* end of clientstat */ 56686530481Sborman 56717cc352bSborman #if defined(CRAY2) && defined(UNICOS5) 568f9a01b3eSdab void 56986530481Sborman termstat() 57086530481Sborman { 57186530481Sborman needtermstat = 1; 57286530481Sborman } 57386530481Sborman 574f9a01b3eSdab void 57586530481Sborman _termstat() 57686530481Sborman { 57786530481Sborman needtermstat = 0; 57886530481Sborman init_termbuf(); 57986530481Sborman localstat(); 58086530481Sborman rcv_ioctl(); 58186530481Sborman } 58217cc352bSborman #endif /* defined(CRAY2) && defined(UNICOS5) */ 58386530481Sborman 58486530481Sborman #ifdef LINEMODE 58586530481Sborman /* 58686530481Sborman * defer_terminit 58786530481Sborman * 58886530481Sborman * Some things should not be done until after the login process has started 58986530481Sborman * and all the pty modes are set to what they are supposed to be. This 59086530481Sborman * function is called when the pty state has been processed for the first time. 59186530481Sborman * It calls other functions that do things that were deferred in each module. 59286530481Sborman */ 593f9a01b3eSdab void 59486530481Sborman defer_terminit() 59586530481Sborman { 59686530481Sborman 59786530481Sborman /* 59886530481Sborman * local stuff that got deferred. 59986530481Sborman */ 60086530481Sborman if (def_tspeed != -1) { 60186530481Sborman clientstat(TELOPT_TSPEED, def_tspeed, def_rspeed); 60286530481Sborman def_tspeed = def_rspeed = 0; 60386530481Sborman } 60486530481Sborman 60586530481Sborman #ifdef TIOCSWINSZ 60686530481Sborman if (def_col || def_row) { 60786530481Sborman struct winsize ws; 60886530481Sborman 609f9a01b3eSdab bzero((char *)&ws, sizeof(ws)); 61086530481Sborman ws.ws_col = def_col; 61186530481Sborman ws.ws_row = def_row; 61286530481Sborman (void) ioctl(pty, TIOCSWINSZ, (char *)&ws); 61386530481Sborman } 61486530481Sborman #endif 61586530481Sborman 61686530481Sborman /* 61786530481Sborman * The only other module that currently defers anything. 61886530481Sborman */ 61986530481Sborman deferslc(); 62086530481Sborman 62186530481Sborman } /* end of defer_terminit */ 62286530481Sborman 62386530481Sborman /* 62486530481Sborman * terminit 62586530481Sborman * 62686530481Sborman * Returns true if the pty state has been processed yet. 62786530481Sborman */ 628f9a01b3eSdab int 629f9a01b3eSdab terminit() 63086530481Sborman { 631a2574097Sdab return(_terminit); 63286530481Sborman 63386530481Sborman } /* end of terminit */ 63486530481Sborman #endif /* LINEMODE */ 635