static const char *RCS="$Id: _read.c,v 4.1 1994/09/29 23:09:02 jraja Exp $";
/*
 *	_read.c - read() for both files and sockets (SAS/C)
 *
 *	Copyright © 1994 AmiTCP/IP Group,
 *			 Network Solutions Development Inc.
 *			 All rights reserved.
 */
#define _INTERNAL_FILE
#define KERNEL
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <dos/dos.h>
#include <proto/dos.h>
#include <sys/file.h>
#include <bsdsocket.h>
#include <sys/syslog.h>

extern int errno;
extern int __ioerr_to_errno(long);

int
__tcpread(struct file *ufb, char *buffer, unsigned int length)
{
  int	      count;
  char	      ch, *ptr, *nextptr, *endptr;

    if (ufb->f_type != DTYPE_SOCKET) {
	syslog(LOG_ERR,"__tcpread found a nonsocket.");
	errno = EBADF;
	return -1;
    }

    /*
     * Check if read is allowed
     */
    if (!(ufb->f_flags & FREAD)) {
	syslog(LOG_ERR, "socket is not readable");
	errno = EIO;
	return -1;
    }

    /*
     * Do the Actual read
     */
    if ((count = TCP_Recv((LONG)ufb->f_so, (UBYTE *)buffer, length, 0)) < 0) {
	return -1;
    }

    /*
     * Check if translation is not needed
     */
    if (count == 0 || !(ufb->f_flags & O_XLATE))
	return count;

    endptr = (char *)buffer + count;    /* first point NOT in buffer */

    if (endptr[-1] == 0x0D) {      /* checks last char */
	count--;
	endptr--;
    }

    /*
     * Remove 0x0D's (CR) (This doesn't remove a CR at the end of the buffer).
     */
    if ((ptr = memchr(buffer, 0x0D, count)) != NULL) {
	nextptr = ptr + 1;
	while (nextptr < endptr) {
	    if ((ch = *nextptr) != 0x0D)
		*ptr++ = ch;
	    nextptr++;
	}
	count = ptr - (char *)buffer;
    }

    /*
     * Test for CTRL-Z (end of file)
     */
    if ((ptr = memchr(buffer, 0x1A, count)) == NULL)
	return count;

    return ptr - (char *)buffer;
}
