/* tncore.c */

/* Copyright 1997 by Eberhard Mattes <mattes@azu.informatik.uni-stuttgart.de>
   Donated to the public domain.  No warranty.

   1997-01-04 Initial version
   1997-01-17 Rename flags, add flag arg to tn_init()
   1997-01-18 Fix various bugs
   1997-04-05 Reorganize library, don't trap SIGALRM
   1007-07-19 Fixed typo which caused repeating output */

/* Poor man's TELNET.  TODO: This should use buffers and select() for
   input _and_ output to avoid deadlock. */

/* TODO: OOB */

#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include <arpa/telnet.h>
#include "firewall.h"
#include "libemtn.h"
#include "tnint.h"

tnconn *tn_init (int fd, unsigned flags)
{
  tnconn *t;
  unsigned char cmdbuf[12];

  errno = 0;
  t = (tnconn *)malloc (sizeof (*t));
  if (t == NULL)
    {
      syslog (LLEV, "tn_init: %s", strerror(errno));
      exit (1);
    }
  t->fd = fd;
  t->suppress_go_ahead = 0;
  t->init_flags = flags;
  t->dfa = DFA_INIT;
  if (flags & TN_INIT_TELNET)
    {
      cmdbuf[0]  = IAC; cmdbuf[1]  = WILL; cmdbuf[2]  = TELOPT_ECHO;
      cmdbuf[3]  = IAC; cmdbuf[4]  = WILL; cmdbuf[5]  = TELOPT_SGA;
      cmdbuf[6]  = IAC; cmdbuf[7]  = WILL; cmdbuf[8]  = TELOPT_BINARY;
      cmdbuf[9]  = IAC; cmdbuf[10] = DO;   cmdbuf[11] = TELOPT_BINARY;
      tn_write (t, (char*) cmdbuf, 12);
    }
  return t;
}


void tn_write (tnconn *t, const char *s, size_t len)
{
  int n;

  do
    {
      n = write (t->fd, s, len);
    } while (n == -1 && errno == EINTR);
  if (n == -1)
    {
      syslog (LLEV, "tn_write: %s", strerror(errno));
      exit (1);
    }
  else if (n != len)
    {
      syslog (LLEV, "tn_write: short write");
      exit (1);
    }
}
