static void pwrite(unsigned char c) { if ((c >= 32 && c <= 126) || (c >= 160)) { c_write1(c); } else if (c < 128) { char cc[2]; cc[1] = (c == 127 ? '?' : c + 0x40); cc[0] = '^'; c_write(cc, 2); } else { char cc[5]; sprintf(cc, "<%02X>", c); c_write(cc, 4); } }
static void do_telnet_read(Telnet telnet, char *buf, int len) { while (len--) { int c = (unsigned char) *buf++; switch (telnet->state) { case TOP_LEVEL: case SEENCR: if (c == NUL && telnet->state == SEENCR) telnet->state = TOP_LEVEL; else if (c == IAC) telnet->state = SEENIAC; else { if (!telnet->in_synch) c_write1(telnet, c); #if 1 /* I can't get the F***ing winsock to insert the urgent IAC * into the right position! Even with SO_OOBINLINE it gives * it to recv too soon. And of course the DM byte (that * arrives in the same packet!) appears several K later!! * * Oh well, we do get the DM in the right place so I'll * just stop hiding on the next 0xf2 and hope for the best. */ else if (c == DM) telnet->in_synch = 0; #endif if (c == CR && telnet->opt_states[o_they_bin.index] != ACTIVE) telnet->state = SEENCR; else telnet->state = TOP_LEVEL; } break; case SEENIAC: if (c == DO) telnet->state = SEENDO; else if (c == DONT) telnet->state = SEENDONT; else if (c == WILL) telnet->state = SEENWILL; else if (c == WONT) telnet->state = SEENWONT; else if (c == SB) telnet->state = SEENSB; else if (c == DM) { telnet->in_synch = 0; telnet->state = TOP_LEVEL; } else { /* ignore everything else; print it if it's IAC */ if (c == IAC) { c_write1(telnet, c); } telnet->state = TOP_LEVEL; } break; case SEENWILL: proc_rec_opt(telnet, WILL, c); telnet->state = TOP_LEVEL; break; case SEENWONT: proc_rec_opt(telnet, WONT, c); telnet->state = TOP_LEVEL; break; case SEENDO: proc_rec_opt(telnet, DO, c); telnet->state = TOP_LEVEL; break; case SEENDONT: proc_rec_opt(telnet, DONT, c); telnet->state = TOP_LEVEL; break; case SEENSB: telnet->sb_opt = c; telnet->sb_len = 0; telnet->state = SUBNEGOT; break; case SUBNEGOT: if (c == IAC) telnet->state = SUBNEG_IAC; else { subneg_addchar: if (telnet->sb_len >= telnet->sb_size) { telnet->sb_size += SB_DELTA; telnet->sb_buf = sresize(telnet->sb_buf, telnet->sb_size, unsigned char); } telnet->sb_buf[telnet->sb_len++] = c; telnet->state = SUBNEGOT; /* in case we came here by goto */ } break; case SUBNEG_IAC: if (c != SE) goto subneg_addchar; /* yes, it's a hack, I know, but... */ else { process_subneg(telnet); telnet->state = TOP_LEVEL; } break; } }
static void c_write (char *buf, int len) { while (len--) c_write1(*buf++); }