/*
 * $Id: tel_opt.c,v 3.1 1994/05/14 14:17:07 ppessi Exp $
 *
 * Author: Tomi Ollila <too@ajk.tele.fi>
 *
 * Copyright © 1993, 1994   AmiTCP/IP Group, <amitcp-group@hut.fi>
 *			    Helsinki University of Technology, Finland.
 *			    All rights reserved.
 *
 * Created: Thu Apr  7 15:33:19 1994 too
 * Last modified: Fri May 13 02:37:51 1994 ppessi
 *
 * HISTORY
 * $Log: tel_opt.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_iacout.h"

static long telnet_flags;	/* telnet state information */

#define TF_ECHO  (1<<0)
#define TF_SGA	 (1<<1)
#define TF_TTYPE (1<<2)

static void to_echo(u_char wwdd, u_char c);
static void to_sga(u_char wwdd, u_char c);
static void to_naws(u_char wwdd, u_char c);
static void to_ttype(u_char wwdd, u_char c);
static void to_notsup(u_char wwdd, u_char c);

void telopt(u_char wwdd, u_char c)
{
  switch (c) {
  case TELOPT_ECHO:
    to_echo(wwdd, c);
    break;
  case TELOPT_SGA:
    to_sga(wwdd, c);
    break;
  case TELOPT_NAWS:
    to_naws(wwdd, c);
    break;
  case TELOPT_TTYPE:
    to_ttype(wwdd, c);
    break;
  default:
    to_notsup(wwdd, c);
    break;
  }
}

static void to_notsup(u_char wwdd, u_char c)
{
  if (wwdd == WILL)
    putiac2(DONT, c);
  else if (wwdd == DO)
    putiac2(WONT, c);
}

/*
 * Handle local echo
 */
static void to_echo(u_char wwdd, u_char c)
{
  if (wwdd == DO) {
    putiac2(WONT, c);
    return;
  }
  else if (wwdd == DONT)
    return;
  
  if (telnet_flags & TF_ECHO) {
    if (wwdd == WILL) {
      return;
    }
  }
  else
    if (wwdd == WONT) {
      return;
    }

#ifdef notyet
  /* XXX if somebody will someday implement linemode for Napsaterm... */
  if (unit->u_charmode != CHM_OFF)
    telnet_flags ^= TF_ECHO;
#endif

  if ((telnet_flags ^= TF_ECHO) & TF_ECHO)
    putiac2(DO, c);
  else
    putiac2(DONT, c);
}

/*
 * Handle suppress-go-ahead
 */
static void to_sga(u_char wwdd, u_char c)
{
  if (telnet_flags & TF_SGA) {
    if (wwdd == WILL)
      return;
  }
  else
    if (wwdd == WONT)
      return;
  
  if ((telnet_flags ^= TF_SGA) & TF_SGA)
    putiac2(DO, c);
  else
    putiac2(DONT, c);
}

/*
 * Handle window size
 */
static void to_naws(u_char wwdd, u_char c)
{
  if (okwinch) {
    if (wwdd == DO)
      return;
  }
  else
    if (wwdd == DONT)
      return;

  okwinch = (wwdd == DO);

  if (okwinch) {
    putiac2(WILL, c);
    do_naws();			/* Send the initial size */
  } else {
    putiac2(WONT, c);
  }
}


/*
 * Handle terminal type
 */
static void to_ttype(u_char wwdd, u_char c)
{
  if (telnet_flags & TF_TTYPE) {
    if (wwdd == DO)
      return;
  }
  else
    if (wwdd == DONT)
      return;

  /* Flip the flag and send WILL/WONT */
  if ((telnet_flags ^= TF_TTYPE) & TF_TTYPE) {
    putiac2(WILL, c);
  } else {
    putiac2(WONT, c);
  }
}



