/*
 * libnqs/comms/getsockch.c
 * 
 * DESCRIPTION:
 *
 *	Routines for reading from a socket.
 *
 *	Author:
 *	-------
 *	Brent A. Kingsbury, Sterling Software Incorporated.
 *	April 21, 1986.
 */

#include <libnqs/license.h>
#include <libnqs/proto.h>

#include <libsal/license.h>
#include <libsal/proto.h>
#include <libsal/defines.h>

#include <errno.h>
#include <unistd.h>

/*
 *	Internal variables.
 */
static int sockfd;			/* Socket file descriptor */
static char buffer [MAX_PACKET];	/* Receive buffer */
static int bufptr = 0;			/* Index of next char in buffer */
static int n_read = 0;			/* Index of 1st empty slot in buffer */


/*** bufsockch
 *
 *
 *	char *bufsockch():
 *
 *	Return a pointer to the characters that
 *	1) this module has read from the socket, and
 *	2) have not yet been turned over with getsockch().
 *
 */
char *bufsockch (void)
{
	return (&buffer[bufptr]);
}


/*** extrasockch
 *
 *
 *	int extrasockch():
 *
 *	Report the number of characters that
 *	1) this module has read from the socket, and
 *	2) have not yet been turned over with getsockch().
 */
int extrasockch (void)
{
	return (n_read - bufptr);
}


/*** getsockch
 *
 *
 *	int getsockch():
 *
 *	Return a character from a socket.
 */
int getsockch (void)
{
	register int no_packet_yet;

	if (bufptr < n_read) {
		return (buffer [bufptr++] & 0377);
	}
	bufptr = 1;			/* Return buffer [1] NEXT time */
	no_packet_yet = 1;
	do {
		if ((n_read = read (sockfd, buffer, MAX_PACKET)) == -1) {
			if (errno != EINTR) {
			  	sal_dprintf(SAL_DEBUG_INFO, SAL_DEBUG_MSG_WARNING, "getsockch: Unable to read on socket, errno is %d\n", errno);
				return (-1);
			}
		}
		else no_packet_yet = 0;
	} while (no_packet_yet);
	if (n_read == 0) {
		return (-1);
	}
	return (buffer [0] & 0377);
}


/*** setsockfd
 *
 *
 *	void setsockfd():
 *
 *	Notify this module which socket it is that it should read on.
 */
void setsockfd (int fd)
{
	sockfd = fd;
}
