void sendnaws() { long rows, cols; unsigned char tmp[16]; unsigned char *cp; if (my_state_is_wont(TELOPT_NAWS)) return; #undef PUTSHORT #define PUTSHORT(cp, x) { if ((*cp++ = ((x)>>8)&0xff) == IAC) *cp++ = IAC; \ if ((*cp++ = ((x))&0xff) == IAC) *cp++ = IAC; } if (TerminalWindowSize(&rows, &cols) == 0) { /* Failed */ return; } cp = tmp; *cp++ = IAC; *cp++ = SB; *cp++ = TELOPT_NAWS; PUTSHORT(cp, cols); PUTSHORT(cp, rows); *cp++ = IAC; *cp++ = SE; if (NETROOM() >= cp - tmp) { ring_supply_data(&netoring, tmp, cp-tmp); printsub('>', tmp+2, cp - tmp - 2); } }
static void dontoption(int option) { if (will_wont_resp[option]) { --will_wont_resp[option]; if (will_wont_resp[option] && my_state_is_wont(option)) --will_wont_resp[option]; } if ((will_wont_resp[option] == 0) && my_want_state_is_will(option)) { switch (option) { case TELOPT_LINEMODE: linemode = 0; /* put us back to the default state */ break; #ifdef OLD_ENVIRON case TELOPT_NEW_ENVIRON: /* * The new environ option wasn't recognized, try * the old one. */ send_will(TELOPT_OLD_ENVIRON, 1); telopt_environ = TELOPT_OLD_ENVIRON; break; #endif } /* we always accept a DONT */ set_my_want_state_wont(option); if (my_state_is_will(option)) send_wont(option, 0); setconnmode(0); /* Set new tty mode */ } set_my_state_wont(option); }
void send_wont(int option, int init) { if (init) { if ((will_wont_resp[option] == 0 && my_state_is_wont(option)) || my_want_state_is_wont(option)) return; set_my_want_state_wont(option); will_wont_resp[option]++; } netoprintf((char *)wont, option); DIAG(TD_OPTIONS, printoption("td: send wont", option)); }
void send_wont(int c, int init) { if (init) { if (((will_wont_resp[c] == 0) && my_state_is_wont(c)) || my_want_state_is_wont(c)) return; set_my_want_state_wont(c); will_wont_resp[c]++; } NET2ADD(IAC, WONT); NETADD(c); printoption("SENT", WONT, c); }
static void dontoption(int option) { if (will_wont_resp[option]) { --will_wont_resp[option]; if (will_wont_resp[option] && my_state_is_wont(option)) --will_wont_resp[option]; } if ((will_wont_resp[option] == 0) && my_want_state_is_will(option)) { switch (option) { case TELOPT_LINEMODE: linemode = 0; /* put us back to the default state */ break; } /* we always accept a DONT */ set_my_want_state_wont(option); if (my_state_is_will(option)) send_wont(option, 0); setconnmode(0); /* Set new tty mode */ } set_my_state_wont(option); }
void dontoption(int option) { /* * Process client input. */ DIAG(TD_OPTIONS, printoption("td: recv dont", option)); if (will_wont_resp[option]) { will_wont_resp[option]--; if (will_wont_resp[option] && my_state_is_wont(option)) will_wont_resp[option]--; } if ((will_wont_resp[option] == 0) && (my_want_state_is_will(option))) { switch (option) { case TELOPT_BINARY: init_termbuf(); tty_binaryout(0); set_termbuf(); break; case TELOPT_ECHO: /* we should stop echoing */ #ifdef LINEMODE #ifdef KLUDGELINEMODE if (lmodetype == NO_LINEMODE) #else if (his_state_is_wont(TELOPT_LINEMODE)) #endif #endif { init_termbuf(); tty_setecho(0); set_termbuf(); } break; case TELOPT_SGA: #if defined(LINEMODE) && defined(KLUDGELINEMODE) /* * If kludge linemode is in use, then we * must process an incoming do SGA for * linemode purposes. */ if (lmodetype == KLUDGE_LINEMODE) { /* * The client is asking us to turn * linemode on. */ clientstat(TELOPT_LINEMODE, WILL, 0); /* * If we did not turn line mode on, * then what do we say? Will SGA? * This violates design of telnet. * Gross. Very Gross. */ } break; #else set_my_want_state_wont(option); if (my_state_is_will(option)) send_wont(option, 0); set_my_state_wont(option); if (turn_on_sga ^= 1) send_will(option,1); return; #endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */ default: break; } set_my_want_state_wont(option); if (my_state_is_will(option)) send_wont(option, 0); } set_my_state_wont(option); }
/* * Main loop. Select from pty and network, and * hand data to telnet receiver finite state machine. */ void telnet(int f, int p) { int on = 1; char *HE; const char *IM; /* * Initialize the slc mapping table. */ get_slc_defaults(); /* * Do some tests where it is desireable to wait for a response. * Rather than doing them slowly, one at a time, do them all * at once. */ if (my_state_is_wont(TELOPT_SGA)) send_will(TELOPT_SGA, 1); /* * Is the client side a 4.2 (NOT 4.3) system? We need to know this * because 4.2 clients are unable to deal with TCP urgent data. * * To find out, we send out a "DO ECHO". If the remote system * answers "WILL ECHO" it is probably a 4.2 client, and we note * that fact ("WILL ECHO" ==> that the client will echo what * WE, the server, sends it; it does NOT mean that the client will * echo the terminal input). */ send_do(TELOPT_ECHO, 1); #ifdef LINEMODE if (his_state_is_wont(TELOPT_LINEMODE)) { /* * Query the peer for linemode support by trying to negotiate * the linemode option. */ linemode = 0; editmode = 0; send_do(TELOPT_LINEMODE, 1); /* send do linemode */ } #endif /* LINEMODE */ /* * Send along a couple of other options that we wish to negotiate. */ send_do(TELOPT_NAWS, 1); send_will(TELOPT_STATUS, 1); flowmode = 1; /* default flow control state */ send_do(TELOPT_LFLOW, 1); /* * Spin, waiting for a response from the DO ECHO. However, * some REALLY DUMB telnets out there might not respond * to the DO ECHO. So, we spin looking for NAWS, (most dumb * telnets so far seem to respond with WONT for a DO that * they don't understand...) because by the time we get the * response, it will already have processed the DO ECHO. * Kludge upon kludge. */ while (his_will_wont_is_changing(TELOPT_NAWS)) { ttloop(); } /* * But... * The client might have sent a WILL NAWS as part of its * startup code; if so, we'll be here before we get the * response to the DO ECHO. We'll make the assumption * that any implementation that understands about NAWS * is a modern enough implementation that it will respond * to our DO ECHO request; hence we'll do another spin * waiting for the ECHO option to settle down, which is * what we wanted to do in the first place... */ if (his_want_state_is_will(TELOPT_ECHO) && his_state_is_will(TELOPT_NAWS)) { while (his_will_wont_is_changing(TELOPT_ECHO)) ttloop(); } /* * On the off chance that the telnet client is broken and does not * respond to the DO ECHO we sent, (after all, we did send the * DO NAWS negotiation after the DO ECHO, and we won't get here * until a response to the DO NAWS comes back) simulate the * receipt of a will echo. This will also send a WONT ECHO * to the client, since we assume that the client failed to * respond because it believes that it is already in DO ECHO * mode, which we do not want. */ if (his_want_state_is_will(TELOPT_ECHO)) { DIAG(TD_OPTIONS, netoprintf("td: simulating recv\r\n");); willoption(TELOPT_ECHO); }