/* MRBackup: File Copy Routine.
 * Date:		09/04/87
 * Notes:
 *		To enhance the performance of MRBackup, this package was copied
 * from my Misc library and modified to couple it more tightly with
 * MRBackup.  It now uses a global buffer area allocated during
 * initialization.
 *
 * History:		(most recent change first)
 *
 * 09/04/87 -MRR- CopyFile, upon failure, now returns the error status
 *                code from IoErr().
 */

#include "MRBackup.h"

/* 
 * Copy file, preserving date.  
 * Depends upon file date routines in FileMisc.c 
 * Original author: Jeff Lydiatt, Vancouver, Canada
 */

#include <stdio.h>
#include <exec/types.h>
#include <libraries/dos.h>
#include <exec/memory.h>
#include <functions.h>

#define MAXSTR 127
 
extern long Chk_Abort();
extern BOOL GetFileDate(), SetFileDate();
extern long IoErr();

/* Copy the last modified date from one file to another.
 * Called with:
 *		from:		name of source file
 *		to:			name of destination file
 * Returns:
 *		0 => success, 1 => failure
 * Note:
 *		Dynamic memory allocation of the DateStamp struction is
 *		necessary to insure longword alignment.
 */

BOOL 
CopyFileDate(from,to)
	char *from, *to;
{
	struct DateStamp *date;
	int status = 1;				/* default is fail code */

	if (date = (struct DateStamp *) 
		AllocMem((long) sizeof(struct DateStamp), MEMF_PUBLIC)) {
		if (GetFileDate(from,date))
			if (SetFileDate(to,date))
				status = 0;
		FreeMem(date, (long) sizeof(struct DateStamp));
	}
	return status;
}

int     
CopyFile(from, to)
	char *from, *to;
{
	long status, count;
	struct FileHandle *fin = NULL, *fout = NULL;

#ifdef DEBUG
	char	errmsg[256];
	static char *errfmt = "CopyFile I/O error %ld, file %s\n";
#endif

	if (! (fin = Open(from, MODE_OLDFILE) ) ) {
badcopy:
		status = IoErr();
#ifdef DEBUG
		sprintf(errmsg, errfmt, status, from);
print_err:
		DebugWrite(errmsg);
#endif
		if (fin) Close(fin);
		if (fout) {
			Close(fout);
			unlink(to);				/* delete the bad copy */
		}
		return (int) status;
	}

	if ( !(fout = Open(to, MODE_NEWFILE)) ) goto badcopy;

	status = 0;
	while ( !status && (count = Read( fin, buffer, bufSize )) == bufSize )
		if ( Write(fout, buffer, count) != count)
				status = IoErr();

	if (!status && count > 0 ) {
		if (Write(fout, buffer, count) != count)
			status = IoErr();
	}

	if (status) goto badcopy;

	Close(fin);
	Close(fout);

	return CopyFileDate(from, to);
}
