static void put_iac_subopt_autologin(void) { int len = strlen(G.autologin) + 6; // (2 + 1 + 1 + strlen + 2) const char *p = "USER"; if (G.iaclen + len > IACBUFSIZE) iac_flush(); put_iac(IAC); put_iac(SB); put_iac(TELOPT_NEW_ENVIRON); put_iac(TELQUAL_IS); put_iac(NEW_ENV_VAR); while (*p) put_iac(*p++); put_iac(NEW_ENV_VALUE); p = G.autologin; while (*p) put_iac(*p++); put_iac(IAC); put_iac(SE); }
static void put_iac2(byte wwdd, byte c) { if (G.iaclen + 3 > IACBUFSIZE) iac_flush(); put_iac(IAC); put_iac(wwdd); put_iac(c); }
static void do_linemode(void) { G.charmode = CHM_TRY; G.telflags &= ~(UF_ECHO | UF_SGA); setConMode(); put_iac2(DONT, TELOPT_ECHO); put_iac2(DONT, TELOPT_SGA); iac_flush(); }
static void will_charmode(void) { G.charmode = CHM_TRY; G.telflags |= (UF_ECHO | UF_SGA); setConMode(); put_iac2(DO, TELOPT_ECHO); put_iac2(DO, TELOPT_SGA); iac_flush(); }
static void put_iac_naws(byte c, int x, int y) { if (G.iaclen + 9 > IACBUFSIZE) iac_flush(); put_iac(IAC); put_iac(SB); put_iac(c); put_iac((x >> 8) & 0xff); put_iac(x & 0xff); put_iac((y >> 8) & 0xff); put_iac(y & 0xff); put_iac(IAC); put_iac(SE); }
static void put_iac_subopt(byte c, char *str) { int len = strlen(str) + 6; // ( 2 + 1 + 1 + strlen + 2 ) if (G.iaclen + len > IACBUFSIZE) iac_flush(); put_iac(IAC); put_iac(SB); put_iac(c); put_iac(0); while (*str) put_iac(*str++); put_iac(IAC); put_iac(SE); }
static void put_iac_naws(byte c, int x, int y) { if (G.iaclen + 9 > IACBUFSIZE) iac_flush(); put_iac(IAC); put_iac(SB); put_iac(c); /* "... & 0xff" implicitly done below */ put_iac(x >> 8); put_iac(x); put_iac(y >> 8); put_iac(y); put_iac(IAC); put_iac(SE); }
static void handle_net_input(int len) { int i; int cstart = 0; for (i = 0; i < len; i++) { byte c = G.buf[i]; if (G.telstate == 0) { /* most of the time state == 0 */ if (c == IAC) { cstart = i; G.telstate = TS_IAC; } continue; } switch (G.telstate) { case TS_0: if (c == IAC) G.telstate = TS_IAC; else G.buf[cstart++] = c; break; case TS_IAC: if (c == IAC) { /* IAC IAC -> 0xFF */ G.buf[cstart++] = c; G.telstate = TS_0; break; } /* else */ switch (c) { case SB: G.telstate = TS_SUB1; break; case DO: case DONT: case WILL: case WONT: G.telwish = c; G.telstate = TS_OPT; break; default: G.telstate = TS_0; /* DATA MARK must be added later */ } break; case TS_OPT: /* WILL, WONT, DO, DONT */ telopt(c); G.telstate = TS_0; break; case TS_SUB1: /* Subnegotiation */ case TS_SUB2: /* Subnegotiation */ if (subneg(c)) G.telstate = TS_0; break; } } if (G.telstate) { if (G.iaclen) iac_flush(); if (G.telstate == TS_0) G.telstate = 0; len = cstart; } if (len) write(STDOUT_FILENO, G.buf, len); }
static void handle_net_input(int len) { int i; int cstart = 0; for (i = 0; i < len; i++) { byte c = G.buf[i]; if (G.telstate == TS_NORMAL) { /* most typical state */ if (c == IAC) { cstart = i; G.telstate = TS_IAC; } else if (c == '\r') { cstart = i + 1; G.telstate = TS_CR; } /* No IACs were seen so far, no need to copy * bytes within G.buf: */ continue; } switch (G.telstate) { case TS_CR: /* Prev char was CR. If cur one is NUL, ignore it. * See RFC 1123 section 3.3.1 for discussion of telnet EOL handling. */ G.telstate = TS_COPY; if (c == '\0') break; /* else: fall through - need to handle CR IAC ... properly */ case TS_COPY: /* Prev char was ordinary */ /* Similar to NORMAL, but in TS_COPY we need to copy bytes */ if (c == IAC) G.telstate = TS_IAC; else G.buf[cstart++] = c; if (c == '\r') G.telstate = TS_CR; break; case TS_IAC: /* Prev char was IAC */ if (c == IAC) { /* IAC IAC -> one IAC */ G.buf[cstart++] = c; G.telstate = TS_COPY; break; } /* else */ switch (c) { case SB: G.telstate = TS_SUB1; break; case DO: case DONT: case WILL: case WONT: G.telwish = c; G.telstate = TS_OPT; break; /* DATA MARK must be added later */ default: G.telstate = TS_COPY; } break; case TS_OPT: /* Prev chars were IAC WILL/WONT/DO/DONT */ telopt(c); G.telstate = TS_COPY; break; case TS_SUB1: /* Subnegotiation */ case TS_SUB2: /* Subnegotiation */ subneg(c); /* can change G.telstate */ break; } } if (G.telstate != TS_NORMAL) { /* We had some IACs, or CR */ if (G.iaclen) iac_flush(); if (G.telstate == TS_COPY) /* we aren't in the middle of IAC */ G.telstate = TS_NORMAL; len = cstart; } if (len) full_write(STDOUT_FILENO, G.buf, len); }