/*
 * $Id: tel_main.c,v 3.1 1994/05/14 14:17:07 ppessi Exp $
 *
 * Author: Tomi Ollila <too@cs.hut.fi>
 *
 * Copyright © 1993, 1994   AmiTCP/IP Group, <amitcp-group@hut.fi>
 *			    Helsinki University of Technology, Finland.
 *			    All rights reserved.
 *
 * Created: Thu Apr  7 13:29:41 1994 too
 * Last modified: Fri May 13 02:42:42 1994 ppessi
 *
 * HISTORY
 * $Log: tel_main.c,v $
 * Revision 3.1  1994/05/14  14:17:07  ppessi
 * initial revision
 *
 * Revision 3.1  1994/04/17  11:31:54  too
 * initial revision
 *
 */

#include "telnet.h"
#include <arpa/telnet.h>
#include "tel_opt.h"
#include "tel_subneg.h"
#include "tel_iacout.h"

long telnetdo(u_char *netbuf, long len)
{
  static u_char prevc;
  static u_char state = 0;

  long netlen, i;

#define touser(c) do { netbuf[netlen++] = c; } while (0)

  for (i = 0; i < len; i++) {
    u_char c = netbuf[i];
    
    switch (state) {
    case 0:
      if (c == IAC) {
	netlen = i;
	state = 2;
      }
      break;
    case 1:
      if (c == IAC)
	state = 2;
      else
	touser(c);
      break;
    case 2:
      if (c == IAC) {
	touser(IAC);
	state = 1;
      }
      else {
	switch (c) {
	case SB:
	  state = 4;
	  break;
	case DO:
	case DONT:
	case WILL:
	case WONT:
	  prevc = c;
	  state = 3;
	  break;
	default:
	  state = 0;	/* DATA MARK must be added later */
	}
      }
      break;
    case 3: /* WILL, WONT, DO, DONT */
      telopt(prevc, c);
      state = 1;
      break;
    case 4: /* Subnegotiation */
      if (subneg(c) == TRUE)
	state = 1;
      break;
    }
  }
  iacflush();
  
  if (state != 0) {
    if (state == 1)
      state = 0;

    return netlen;
  }

  return len;
}

