/* ioutil.c
   Input/Output and file copy utility routines. */

     /*---------------------------------------------------------------*/
     /* Xgopher        version 1.2     20 November 1991               */
     /*                version 1.1     20 April 1991                  */
     /*                version 1.0     04 March 1991                  */
     /* X window system client for the University of Minnesota        */
     /*                                Internet Gopher System.        */
     /* Allan Tuchman, University of Illinois at Urbana-Champaign     */
     /*                Computing and Communications Services Office   */
     /* Copyright 1992 by                                             */
     /*           the Board of Trustees of the University of Illinois */
     /* Permission is granted to freely copy and redistribute this    */
     /* software with the copyright notice intact.                    */
     /*---------------------------------------------------------------*/


#include <stdio.h>

#include "ioutil.h"
#include "conf.h"
#include "gopher.h"
#include "net.h"


#define MIN_OF(a,b)	((a)<(b) ? (a) : (b))
#define BIN_BUFFER_SIZE	1400

/* copyBin
   Binary copy the contents of one open file descriptor to another.
   If the length is less than 0, copy until EOF, otherwise copy length
   bytes.

   Either file descriptor may reference a file or a socket connection. 
   For sockets, we will assume blocking I/O, so a read will always
   return something if it's not yet eof, and a write will write everything. */

void
copyBin(inFD, outFD, nBytes)
int	inFD, outFD;
int	nBytes;
{
	char	buf[BIN_BUFFER_SIZE];
	int	nr, nw;

	if (nBytes == -1) {
	    while (TRUE) {
		nr = read(inFD, buf, BIN_BUFFER_SIZE);

		if (nr <= 0) {
			if (nr == -1) {
			    fprintf (stderr,
				"Error copying binary data - input.\n");
			    perror("copyBin");
			}
			break;
		}

		nw = write(outFD, buf, nr);
		if (nw != nr  ||  nw < 0) {
			fprintf (stderr,
				"Error copying binary data - output.\n");
			perror("copyBin");
			break;
		}
	    }
	} else {
	    while (nBytes > 0) {
		nr = read(inFD, buf, MIN_OF(nBytes, BIN_BUFFER_SIZE));

		if (nr <= 0) {
			if (nr == -1) {
			    fprintf (stderr,
				"Error copying binary data - input.\n");
			    perror("copyBin");
			}
			break;
		}

		nBytes -= nr;

		nw = write(outFD, buf, nr);
		if (nw != nr  ||  nw < 0) {
			fprintf (stderr,
				"Error copying binary data - output.\n");
			perror("copyBin");
			break;
		}
	    }
	}
}


/* copyAscii
   Copy the contents of one open text file descriptor to another.  Copy
   until a line with a single period in column one or an end of file.

   Change "network ASCII" with CR-LF ending each line to standard
   Unix text files with a NL at the end of each line.

   Either file descriptor may reference a file or a socket connection. 
   For sockets, we will assume blocking I/O, so a read will always
   return something if it's not yet eof, and a write will write everything. */

static char	newLine[1] = {NL};

void
copyAscii(inFD, outFD, unused)
int	inFD, outFD;
int	unused;
{
	char	line[FILE_LINE_LEN];
	int	len;

	if (readLine(inFD, line, FILE_LINE_LEN) <= 0) return;
	zapCRLF(line);


	while ( line[0] != '.'  ||  line[1] != '\0') {

		len = strlen(line);
		write(outFD, line, len);
		write(outFD, newLine, 1);

		if (readLine(inFD, line, FILE_LINE_LEN) <= 0) break;
		zapCRLF(line);
	}

	return;
}
