/*
 * libnqs/misc/filecopy.c
 * 
 * DESCRIPTION:
 *
 *	Copy a file.
 *
 *	Original Author:
 *	-------
 *	Brent A. Kingsbury, Sterling Software Incorporated.
 *	August 12, 1985.
 */

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

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

#include <unistd.h>

#include <errno.h>

/*** filecopyentire
 *
 *
 *	int filecopyentire():
 *	Copy a file from one open file descriptor to another.
 *	Don't stop until EOF.
 *
 *	Returns:
 *	      >=0: if successful (number of bytes transferred);
 *	       -1: if an error occurs (in which case errno is set).
 *		   Errno will equal zero, if we simply ran out of
 *		   file space writing the copy.
 */
long filecopyentire (int from, int to)
{
	char buffer [8192];		/* Copy buffer */
	register int nread;		/* One time number of bytes read */
	register int nwritten;		/* One time number of bytes written */
	register long cumulative;	/* Sum of nwritten's */

	errno = 0;			/* So that file limit returns 0 errno */
	cumulative = 0;
	while ((nread = read (from, buffer, sizeof (buffer))) != 0) {
		if (nread < 0) return (-1L);
		if ((nwritten = write (to, buffer, nread)) != nread)
                {
                        sal_dprintf(SAL_DEBUG_INFO, SAL_DEBUG_MSG_WARNING, "INTERGRAPH nread=%d, nwritten=%d, errno=%d\n", nread, nwritten, errno);
                        return(-1L);
                }
		cumulative += nwritten;
	}
	return (cumulative);
}


/*** filecopysized
 *
 *
 *	int filecopysized():
 *	Copy a file from one open file descriptor to another.
 *	Stop as soon as the specified number of bytes have been moved.
 *
 *	Returns:
 *	      >=0: if successful, or if it reached a premature EOF
 *		   (number of bytes transferred);
 *	       -1: if an error occurs (in which case errno is set).
 *		   Errno will equal zero, if we simply ran out of
 *		   file space writing the copy.
 */
long filecopysized (int from, int to, long bytes)
{
	char buffer [8192];		/* Copy buffer */
	register int nread;		/* One time number of bytes read */
	register int nwritten;		/* One time number of bytes written */
	register long need;		/* Number of bytes still needed */

	errno = 0;			/* So that file limit returns 0 errno */
	for (need = bytes; need > 0; need -= nwritten) {
		if ((nread = read (from, buffer,
			need < sizeof buffer ? need : sizeof buffer)) != 0) {
			if (nread < 0) return (-1L);
			if ((nwritten = write (to, buffer, nread)) != nread)
				return (-1L);
		}
		else return (bytes - need);
	}
	return (bytes);
}
