RCS_ID_C="$Id: _write.c,v 1.4 1994/04/04 01:27:59 jraja Exp $";
/*
 * _write.c --- write() for both files and sockets.
 *
 * Author: jraja <Jarno.Rajahalme@hut.fi>
 *
 * This file is part of the AmiTCP/IP Network Support Library.
 *
 * Copyright © 1994 AmiTCP/IP Group, <amitcp-group@hut.fi>
 *                  Helsinki University of Technology, Finland.
 *                  All rights reserved.
 *
 * Created      : Tue Mar  8 22:43:57 1994 jraja
 * Last modified: Wed Mar 30 10:17:32 1994 jraja
 *
 */

#include <ios1.h>
#include <fcntl.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>
#include <errno.h>
#include <dos/dos.h>
#include <proto/dos.h>

#include <bsdsocket.h>

extern int __io2errno(long);

int
__write(int fd, const void *buffer, unsigned int length)
{
  struct UFB *ufb;
  int         count, totcount;
  char       *ptr;

  /*
   * Check for the break signals
   */
  __chkabort();
  /*
   * find the ufb *
   */
  if ((ufb = __chkufb(fd)) == NULL) {
    errno = EINVAL;
    return -1;
  }
  /*
   * Check if write is allowed
   */
  if (!(ufb->ufbflg & UFB_WA)) {
    _OSERR = ERROR_WRITE_PROTECTED;
    errno = EIO;
    return -1;
  }

  /*
   * Seek to end of the file if necessary
   */
  if (ufb->ufbflg & UFB_APP)
    __lseek(fd, 0, 2);

  /*
   * Check if translation is not needed
   */
  if (!(ufb->ufbflg & UFB_XLAT) ||
      (ptr = memchr(buffer, 0x0A, length)) == NULL) {
    if (ufb->ufbflg & UFB_SOCK) {
      if ((count = send(fd, (char *)buffer, length, 0)) < 0)
	return -1;
    }
    else {
      if ((count = Write(ufb->ufbfh, (void *)buffer, length)) == -1)
	goto osfail;
    }
    return count;
  }

  totcount = length;

  /*
   * Translate, ie., append CR before each LF
   */
  do {
    count = ptr - (char *)buffer;
    if (ufb->ufbflg & UFB_SOCK) {
      if (send(fd, (char *)buffer, count, 0) < 0)
	return -1;
      if (send(fd, "\015"/* CR */, 1, 0) < 0)
	return -1;
    }
    else {
      if (Write(ufb->ufbfh, (void *)buffer, count) == -1)
	goto osfail;
      if (Write(ufb->ufbfh, "\015"/* CR */, 1) == -1)
	goto osfail;
    }
    length -= count;
    
    buffer = ptr;
  } while ((ptr = memchr((char *)buffer + 1, 0x0A, length)) != NULL);
  
  if (ufb->ufbflg & UFB_SOCK) {
    if ((count = send(fd, (char *)buffer, length, 0)) < 0)
      return -1;
  }
  else {
    if (Write(ufb->ufbfh, (void *)buffer, length) == -1)
      goto osfail;
  }

  return totcount;

osfail:
  errno = __io2errno(_OSERR = IoErr());
  return -1;
}
