Пример #1
0
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;
	}
    }
Пример #2
0
static void do_telnet_read (char *buf, int len) {
    static enum {
	TOPLEVEL, SEENIAC, SEENWILL, SEENWONT, SEENDO, SEENDONT,
	SEENSB, SUBNEGOT, SUBNEG_IAC, SEENCR
    } state = TOPLEVEL;
    char b[10];

    while (len--) {
	int c = (unsigned char) *buf++;
	switch (state) {
          case TOPLEVEL:
          case SEENCR:
            if (c == 0 && state == SEENCR)
                state = TOPLEVEL;
            else if (c == IAC)
                state = SEENIAC;
            else {
                b[0] = c;
                if (!in_synch)
                    c_write (b, 1);
                if (c == 13)
                    state = SEENCR;
                else
                    state = TOPLEVEL;
            }
            break;
	  case SEENIAC:
	    if (c == DO) state = SEENDO;
	    else if (c == DONT) state = SEENDONT;
	    else if (c == WILL) state = SEENWILL;
	    else if (c == WONT) state = SEENWONT;
	    else if (c == SB) state = SEENSB;
	    else state = TOPLEVEL;   /* we really ignore _everything_ else! */
	    break;
	  case SEENWILL:
	    proc_rec_opt (WILL, c);
	    state = TOPLEVEL;
	    break;
	  case SEENWONT:
	    proc_rec_opt (WONT, c);
	    state = TOPLEVEL;
	    break;
	  case SEENDO:
	    proc_rec_opt (DO, c);
	    state = TOPLEVEL;
	    break;
	  case SEENDONT:
	    proc_rec_opt (DONT, c);
	    state = TOPLEVEL;
	    break;
	  case SEENSB:
	    sb_opt = c;
	    sb_len = 0;
	    state = SUBNEGOT;
	    break;
	  case SUBNEGOT:
	    if (c == IAC)
		state = SUBNEG_IAC;
	    else {
		subneg_addchar:
		if (sb_len >= sb_size) {
		    char *newbuf;
		    sb_size += SB_DELTA;
		    newbuf = (sb_buf ?
			      realloc(sb_buf, sb_size) :
			      malloc(sb_size));
		    if (newbuf)
			sb_buf = newbuf;
		    else
			sb_size -= SB_DELTA;
		}
		if (sb_len < sb_size)
		    sb_buf[sb_len++] = c;
		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();
		state = TOPLEVEL;
	    }
	    break;
	}
    }
}