#if !defined(lint) && !defined(__INSIGHT__)
static char sos__rcsid[] = "util.c,v 1.1.1.1 1995/06/16 17:42:44 seth Exp";
static char sos__copyright[] = "Copyright (c) 1994, 1995 SOS Corporation";
static char sos__contact[] = "SOS Corporation <sos-info@soscorp.com> +1 800 SOS UNIX";
#endif /* not lint */

/*
 * ++Copyright Released Product++
 *
 * Copyright (c) 1994, 1995 Sources of Supply Corporation ("SOS").
 * All rights reserved.
 *
 * The SOS Released Product License Agreement specifies the terms and
 * conditions for redistribution.  You may find the License Agreement
 * in the file LICENSE.
 *
 * SOS Corporation
 * 461 5th Ave.; 16th floor
 * New York, NY 10017
 *
 * +1 800 SOS UNIX
 * <sos-info@soscorp.com>
 *
 * --Copyright Released Product--
 */

/*
 * I/O utilities for client server
 *
 * Should be rethought, cleaned up, and moved to libsos
 */

#include "sos.h"



/*
 * Static I/O timout value
 */
static int sos_io_timeout = 0;
static struct sigaction old_sigaction;	/* Caches old signal vec. */

static int sos_io_with_timeout(int fd, char *addr, int len, int (*ior) (int, caddr_t, __SIZE_TYPE__));


static void
sos_ioTimeout()
/*
 * This function exists for no purpose but to prevent the program from aborting
 * on a SIGALRM (default behavior). 
 */

{
  /* Restore old signal behavior */
  sigaction(SIGALRM, (struct sigaction *)&old_sigaction,
	    (struct sigaction *)NULL);
  return;
}

static struct sigaction iotimeout = SIGACTIONDEFINE( sos_ioTimeout, 0, _INTERRUPT_SYSCALLS_ );


/* Read the data raw from the net.  Possibly decrypt.
 * non-encrypted is short-cut immediately
 */

int
sosRawRead(int fd, caddr_t addr, __SIZE_TYPE__ len)

{
  int nbytes;

#if defined ( SOS_RAW_DEBUG )
  printf("sosRawRead: Entering\n");
#endif				/* SOS_RAW_DEBUG */


      return (sos_io_with_timeout(fd, addr, len, (int (*)(int, caddr_t, __SIZE_TYPE__))read));
}

/****************************************************************************
 **
 ** sosRawWrite
 **
 ** Perform a write with Brimstone options:
 **
 ** io timeouts
 ** encryption
 **
 ** We are encrypting in a stream cipher, so we don't need to worry
 ** about the encryption block-size.  However, we are encrypting the
 ** data in the user's supplied buffer, so the user must NOT change
 ** the data in the event of a partial write, and must NOT look at
 ** the data in any event.
 **
 ***************************************************************************/

int
sosRawWrite(int fd, caddr_t addr, __SIZE_TYPE__ len)
{
  int c;
  static int fdsavebytes[NOFILE];	/* Number of already encrypted bye */
  static int inited = 0;
  int nbytes;			/* Number of bytes acutally written */
  int plainlen = len;


      return (sos_io_with_timeout(fd, addr, len, (int (*)(int, caddr_t, __SIZE_TYPE__))write));
}

/****************************************************************************/

static int
sos_io_with_timeout(int fd, char *addr, int len, int (*ior) (int fd, caddr_t addr, __SIZE_TYPE__ len))
{
  int save_errno;
  int nbytes;

  sigaction(SIGALRM, (struct sigaction *)&iotimeout,
	    (struct sigaction *)&old_sigaction);
  alarm(sos_io_timeout);
  nbytes = (*ior) (fd, addr, len);
#if defined SOS_IO_DEBUG
  /* Use with caution! At least don't have encryption turned on. */
  {
    int i;
    char *p;

    printf("sos_io_with_timeout(): performed I/0: addr: *-*");
    for (p = addr, i = 0; i < len; i++, p++)
      printf("%c", *p);
    printf("*-*\n");
  }
#endif	/* SOS_IO_DEBUG */
  save_errno = errno;
  alarm(0);
  sigaction(SIGALRM, (struct sigaction *)&old_sigaction,
	    (struct sigaction *)NULL);

  errno = save_errno;
  return (nbytes);
}



void
sos_set_io_timeout(int timeout)
{
  sos_io_timeout = timeout;
}

/***************************************************************************/

/*
 * Initialize encryption on both sides
 *
 * fd: socket to send initial message. 
 */

int
sos_encrypt_init(char *key,int fd)
{
}
/***************************************************************************/


/*
 * Call sosRawRead while making sure we read the number of bytes we wanted to read
 */
int
sosBIOread(int fd, caddr_t addr, __SIZE_TYPE__ len)
{
  int width = fd + 1;
  fd_set fds;
  int nbytes = 0;
  int curlen = len;


  FD_ZERO(&fds);
  FD_SET(fd, &fds);

  while (curlen > 0)
    {
      if (select(width, &fds, NULL, NULL, NULL) < 0)
	return -1;

      if ((nbytes = sosRawRead(fd, addr, curlen)) < 0)
	return -1;

      curlen -= nbytes;
      addr += nbytes;
    }

  return (len);
}

/*
 * Call sosRawWrite while making sure we write the number of bytes we wanted to write
 */
int
sosBIOwrite(int fd, caddr_t addr, __SIZE_TYPE__ len)
{
  int width = fd + 1;
  fd_set fds;
  int curlen = len;
  int nbytes = 0;


  FD_ZERO(&fds);
  FD_SET(fd, &fds);

  while (curlen > 0)
    {
      if (select(width, NULL, &fds, NULL, NULL) < 0)
	return -1;

      if ((nbytes = sosRawWrite(fd, addr, curlen)) < 0)
	return -1;

      curlen -= nbytes;
      addr += nbytes;
    }

  return (len);
}

/*
 * Call sosRawRead then rip off the CR/LF stuff
 */
int
sosRead(int fd, caddr_t addr, __SIZE_TYPE__ len)

{
  int nbytes = sosRawRead(fd, addr, len);

#if defined SOS_COOKED_DEBUG
  printf("sosRead(): Entering: addr: **%s**\n", addr);
#endif

  if (nbytes <= 0)
    return nbytes;

  /* Null out first CR/LF.  Note this means and data on the 2nd - nth
   * lines has just been lost.  Ach, poor lassie.
   */
  sos_rip(addr);

  return nbytes;
}

/*
 * Call sosRawWrite then do nothing
 */
int
sosWrite(int fd, caddr_t addr, __SIZE_TYPE__ len)

{
  int nbytes;

#if defined SOS_COOKED_DEBUG
  printf("sosWrite(): Entering: addr: **%s**\n", addr);
#endif

  /*
   * For compatibility. Sigh...
   */
  if ((nbytes = sosRawWrite(fd, addr, len)) < 0)
    return -1;

  return nbytes;
}


void
sos_encrypt_on_init_fun()
{
}
