/* 
 * 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 BUFMAX 32768
#define MAXSTR 127
 
extern char *malloc();
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;
{
	char   *buffer;
	char	errmsg[256];
	long    status,count,bufsize;
	struct FileHandle  *fin,*fout;
static char *errfmt = "I/O error %ld, file %s";

	if ((fin = Open(from,MODE_OLDFILE ))== NULL ){
		status = IoErr();
#ifdef DEBUG
		sprintf(errmsg,errfmt,status, from);
print_err:
		puts(errmsg);
#endif
		return status;
	}

	if ((fout = Open(to,MODE_NEWFILE ))== NULL ){
		status = IoErr();
		Close(fin );
#ifdef DEBUG
		sprintf(errmsg,errfmt,IoErr(),to);
		goto print_err;
#endif
		return status;
	}

	for (bufsize = BUFMAX; bufsize > 2048; bufsize -= 2048 )
		if ((buffer = malloc((unsigned int)bufsize))!= NULL )
			break;

	if (bufsize <= 2048 ){
		Close(fin );
		Close(fout );
#ifdef DEBUG
		puts("CopyFile: Not enough memory." );
#endif
		return ERROR_NO_FREE_STORE;
	}

	status = 1;
	while(status > 0 && (count = Read(fin,buffer,bufsize ))== bufsize )
		if (Chk_Abort())
			status = -1;
		else
			status = Write(fout,buffer,count );

	if (status > 0 && count > 0 )
		status = Write(fout,buffer,count );

	Close(fin );
	Close(fout);
	free(buffer);

	if (status < 0 || count < 0 ){
		unlink(to);
		return 1;
	}
	return CopyFileDate(from, to);
}
