/*
**	$Id: termTransfer.c,v 1.7 92/08/18 16:13:17 olsen Sta Locker: olsen $
**	$Revision: 1.7 $
**	$Date: 92/08/18 16:13:17 $
**
**	File transfer routines
**
**	Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
**		All Rights Reserved
*/

#include "termGlobal.h"

	/* The action strings to display. */

STATIC UBYTE *SendQuery[3] =
{
	NULL,
	NULL,
	NULL
};

STATIC UBYTE *ReceiveQuery[3] =
{
	NULL,
	NULL,
	NULL
};

	/* The transfer types to display. */

STATIC UBYTE *TransferTypes[3] =
{
	NULL,
	NULL,
	NULL
};

	/* SendTextFile(UBYTE *TheFile):
	 *
	 *	Send a single text file via xpr.
	 */

VOID
SendTextFile(UBYTE *TheFile)
{
	BYTE OldStatus = Status;

	Uploading	= TRUE;
	MultipleFiles	= FALSE;

	LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
	LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);

		/* If not initialized, try to set up a new
		 * external transfer protocol.
		 */

	if(!XProtocolBase)
	{
		NewLibrary = FALSE;

		xpr_options(0,NULL);

		if(NewLibrary)
		{
			if(ProtocolSetup())
			{
				SaveProtocolOpts();

				strcpy(Config . Protocol,LastXprLibrary);
			}
		}
	}

	if(XProtocolBase)
	{
		XprIO -> xpr_filename = TheFile;

		if(TransferPanel(SendQuery[TRANSFER_TEXT]))
		{
			BYTE Aborted;

			Status = STATUS_UPLOAD;

			ClearSerial();

			LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[TRANSFER_TEXT]);

			if(!XProtocolSend(XprIO))
				Aborted = TRUE;
			else
				Aborted = FALSE;

			if(TransferWindow)
			{
				WakeUp(TransferWindow);

				WaitTime(2,0);
			}

			if(Aborted)
				Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
			else
				Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));

			Status = OldStatus;

			DeleteTransferPanel();

			if(ReadRequest)
			{
				ReadRequest -> IOSer . io_Command	= CMD_READ;
				ReadRequest -> IOSer . io_Data		= ReadBuffer;
				ReadRequest -> IOSer . io_Length	= 1;

				SetSignal(0,SIG_SERIAL);

				SendIO(ReadRequest);
			}
		}
	}

	if(SendAbort && UsesZModem)
		SerWrite(ZModemCancel,20);

	SendAbort = FALSE;

	Uploading = FALSE;

	if(Config . UploadMacro[0])
		SerialCommand(Config . UploadMacro);

	DidTransfer = FALSE;
}

	/* StartXprReceive():
	 *
	 *	Receive files via xpr.
	 */

VOID
StartXprReceive(BYTE Type)
{
	struct FileRequester	*FileRequest;
	UBYTE			 DummyBuffer[256];
	BYTE			 OldStatus = Status;

	LocalizeString(ReceiveQuery,MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT,MSG_TERMTRANSFER_DOWNLOAD_ASCII_TXT);
	LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);

		/* Select the download path. */

	switch(Type)
	{
		case TRANSFER_BINARY:	DownloadPath = &Config . BinaryDownloadPath[0];
					break;

		case TRANSFER_TEXT:	DownloadPath = &Config . TextDownloadPath[0];
					break;

		case TRANSFER_ASCII:	DownloadPath = &Config . ASCIIDownloadPath[0];
					break;
	}

	BlockWindows();

		/* Set up the library if necessary. */

	if(!XProtocolBase)
	{
		NewLibrary = FALSE;

		xpr_options(0,NULL);

		if(NewLibrary)
		{
			if(ProtocolSetup())
			{
				SaveProtocolOpts();

				strcpy(Config . Protocol,LastXprLibrary);
			}
		}
	}

	if(XProtocolBase)
	{
			/* Do we need to ask the user for
			 * the destination file name?
			 */

		if(TransferBits & XPRS_NORECREQ)
		{
				/* Obviously not, let's open
				 * the transfer info window as
				 * usual and download the file(s).
				 */

			if(TransferPanel(ReceiveQuery[Type]))
			{
				Status = STATUS_DOWNLOAD;

				ClearSerial();

				LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_DOWNLOAD_TXT),TransferTypes[Type]);

					/* Receive the data. */

				if(!XProtocolReceive(XprIO))
					TransferAborted = TRUE;

					/* In case the transfer has been aborted,
					 * flush the input buffer of dirty data.
					 */

				if(TransferAborted)
					xpr_sflush();

					/* Wake the user up. */

				if(TransferWindow)
				{
					WakeUp(TransferWindow);

					WaitTime(2,0);
				}

				if(TransferAborted)
				{
					TransferAborted = FALSE;

					Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
				}
				else
					Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));

				Status = OldStatus;

					/* Queue another read request. */

				if(ReadRequest)
				{
					ReadRequest -> IOSer . io_Command	= CMD_READ;
					ReadRequest -> IOSer . io_Data		= ReadBuffer;
					ReadRequest -> IOSer . io_Length	= 1;

					SetSignal(0,SIG_SERIAL);

					SendIO(ReadRequest);
				}

				DeleteTransferPanel();
			}
		}
		else
		{
				/* Download the file(s). */

			if(FileRequest = GetFile(ReceiveQuery[Type],DownloadPath,"",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT)))
			{
					/* Save the download path. */

				strcpy(DownloadPath,FileRequest -> rf_Dir);

					/* Install the name of the file to receive. */

				XprIO -> xpr_filename = DummyBuffer;

					/* Open the transfer panel. */

				if(TransferPanel(ReceiveQuery[Type]))
				{
					Status = STATUS_DOWNLOAD;

					ClearSerial();

					LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_DOWNLOAD_TXT),TransferTypes[Type]);

						/* Receive the file. */

					if(!XProtocolReceive(XprIO))
						TransferAborted = TRUE;

						/* In case the transfer has been aborted,
						 * flush the input buffer of dirty data.
						 */

					if(TransferAborted)
						xpr_sflush();

						/* Wake the user up. */

					if(TransferWindow)
					{
						WakeUp(TransferWindow);

						WaitTime(2,0);
					}

					if(TransferAborted)
					{
						TransferAborted = FALSE;

						Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
					}
					else
						Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));

					Status = OldStatus;

						/* Close the transfer panel. */

					DeleteTransferPanel();

						/* Queue another read
						 * request.
						 */

					if(ReadRequest)
					{
						ReadRequest -> IOSer . io_Command	= CMD_READ;
						ReadRequest -> IOSer . io_Data		= ReadBuffer;
						ReadRequest -> IOSer . io_Length	= 1;

						SetSignal(0,SIG_SERIAL);

						SendIO(ReadRequest);
					}
				}

				FreeAslRequest(FileRequest);
			}
		}
	}

	if(SendAbort && UsesZModem)
		SerWrite(ZModemCancel,20);

	SendAbort = FALSE;

	ReleaseWindows();

	DownloadPath = NULL;

	DidTransfer = FALSE;

	if(Config . DownloadMacro[0])
		SerialCommand(Config . DownloadMacro);
}

	/* StartXprSend():
	 *
	 *	Send files via xpr.
	 */

BYTE
StartXprSend(BYTE Type)
{
	struct FileRequester	*FileRequest;
	UBYTE			 DummyBuffer[256];
	BYTE			 OldStatus = Status;
	UBYTE			*UploadPath;
	BYTE			 DidSend = TRUE;

	LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
	LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);

		/* We are uploading data. */

	Uploading = TRUE;

		/* Select the upload path. */

	switch(Type)
	{
		case TRANSFER_BINARY:	UploadPath = &Config . BinaryUploadPath[0];
					break;

		case TRANSFER_TEXT:	UploadPath = &Config . TextUploadPath[0];
					break;

		case TRANSFER_ASCII:	UploadPath = &Config . ASCIIUploadPath[0];
					break;
	}

	BlockWindows();

		/* If not initialized, try to set up a new
		 * external transfer protocol.
		 */

	if(!XProtocolBase)
	{
		NewLibrary = FALSE;

		xpr_options(0,NULL);

		if(NewLibrary)
		{
			if(ProtocolSetup())
			{
				SaveProtocolOpts();

				strcpy(Config . Protocol,LastXprLibrary);
			}
		}
	}

	if(XProtocolBase)
	{
			/* Clear the pattern match anchor structure. */

		memset(FileAnchor,0,sizeof(struct AnchorPath));

		FileMatch = FALSE;

			/* Do we need to use our own file requester or
			 * will xpr handle this job for us?
			 */

		if(TransferBits & XPRS_NOSNDREQ)
		{
				/* Open the transfer info window. */

			if(TransferPanel(SendQuery[Type]))
			{
				BYTE Aborted;

				Status = STATUS_UPLOAD;

					/* Shut up the serial line. */

				ClearSerial();

				LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);

					/* Perform upload. */

				if(!XProtocolSend(XprIO))
					Aborted = TRUE;
				else
					Aborted = FALSE;

				if(TransferWindow)
				{
					WakeUp(TransferWindow);

					WaitTime(2,0);
				}

				if(Aborted)
					Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
				else
					Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));

				Status = OldStatus;

					/* Close the info window. */

				DeleteTransferPanel();

					/* And request another character. */

				if(ReadRequest)
				{
					ReadRequest -> IOSer . io_Command	= CMD_READ;
					ReadRequest -> IOSer . io_Data		= ReadBuffer;
					ReadRequest -> IOSer . io_Length	= 1;

					SetSignal(0,SIG_SERIAL);

					SendIO(ReadRequest);
				}
			}
		}
		else
		{
				/* We will need the file requester to find
				 * out which file(s) are to be transferred.
				 * Multiple files and wildcards are
				 * supported as well as plain file names.
				 */

			if(FileRequest = GetFile(SendQuery[Type],UploadPath,"",DummyBuffer,"",FALSE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT)))
			{
				strcpy(UploadPath,FileRequest -> rf_Dir);

				if(FileRequest -> rf_NumArgs <= 1)
				{
					BPTR OldLock,NewLock;

					MultipleFiles = FALSE;

						/* Put the name of the first selected
						 * file into the buffer.
						 */

					if(FileRequest -> rf_NumArgs == 1)
						strcpy(DummyBuffer,FileRequest -> rf_ArgList[0] . wa_Name);

					XprIO -> xpr_filename = DummyBuffer;

						/* To have a valid directory to
						 * read the files from we'll jump
						 * to the directory given in the file
						 * requester. This is due to the fact
						 * that all xpr protocols have referenced
						 * files by their file names (sans path)
						 * yet.
						 */

					if(NewLock = Lock(FileRequest -> rf_Dir,ACCESS_READ))
					{
						OldLock = CurrentDir(NewLock);

						if(TransferPanel(SendQuery[Type]))
						{
							BYTE Aborted;

							Status = STATUS_UPLOAD;

							ClearSerial();

							LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);

							if(!XProtocolSend(XprIO))
								Aborted = TRUE;
							else
								Aborted = FALSE;

							if(TransferWindow)
							{
								WakeUp(TransferWindow);

								WaitTime(2,0);
							}

							if(Aborted)
								Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
							else
								Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));

							Status = OldStatus;

							DeleteTransferPanel();

							if(ReadRequest)
							{
								ReadRequest -> IOSer . io_Command	= CMD_READ;
								ReadRequest -> IOSer . io_Data		= ReadBuffer;
								ReadRequest -> IOSer . io_Length	= 1;

								SetSignal(0,SIG_SERIAL);

								SendIO(ReadRequest);
							}
						}
						else
							MyEasyRequest(Window,LocaleString(MSG_TERMTRANSFER_FAILED_TO_LOCATE_DIRECTORY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FileRequest -> rf_Dir);

						CurrentDir(OldLock);

						UnLock(NewLock);
					}
				}
				else
				{
						/* This looks like a batch file request. */

					if(FileRequest -> rf_NumArgs > 1)
					{
						BPTR OldLock,NewLock;

							/* Set up the array of file names. */

						FileCountMax	= FileRequest -> rf_NumArgs;
						FileArg		= FileRequest -> rf_ArgList;

						MultipleFiles	= TRUE;

							/* If this protocol doesn't support
							 * batch file upload, make sure that
							 * at least the first selected file
							 * is transferred.
							 */

						XprIO -> xpr_filename = FileRequest -> rf_ArgList[0] . wa_Name;

						if(NewLock = Lock(FileRequest -> rf_Dir,ACCESS_READ))
						{
							OldLock = CurrentDir(NewLock);

							if(TransferPanel(SendQuery[Type]))
							{
								BYTE Aborted;

								Status = STATUS_UPLOAD;

								ClearSerial();

								LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);

								if(!XProtocolSend(XprIO))
									Aborted = TRUE;
								else
									Aborted = FALSE;

								if(TransferWindow)
								{
									WakeUp(TransferWindow);

									WaitTime(2,0);
								}

								if(Aborted)
									Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
								else
									Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));

								Status = OldStatus;

								DeleteTransferPanel();

								if(ReadRequest)
								{
									ReadRequest -> IOSer . io_Command	= CMD_READ;
									ReadRequest -> IOSer . io_Data		= ReadBuffer;
									ReadRequest -> IOSer . io_Length	= 1;

									SetSignal(0,SIG_SERIAL);

									SendIO(ReadRequest);
								}
							}
							else
								MyEasyRequest(Window,LocaleString(MSG_TERMTRANSFER_FAILED_TO_LOCATE_DIRECTORY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FileRequest -> rf_Dir);

							CurrentDir(OldLock);

							UnLock(NewLock);
						}
					}
				}

				FreeAslRequest(FileRequest);
			}
			else
				DidSend = FALSE;
		}

		if(FileMatch)
			MatchEnd(FileAnchor);
	}

	if(SendAbort && UsesZModem)
		SerWrite(ZModemCancel,20);

	SendAbort = FALSE;

	ReleaseWindows();

	Uploading = FALSE;

	if(Config . UploadMacro[0])
		SerialCommand(Config . UploadMacro);

	DidTransfer = FALSE;

	return(DidSend);
}

	/* ASCIISetup():
	 *
	 *	Set up xprascii.library for plain ASCII file
	 *	transfer. This routine temporarily selects a
	 *	different protocol than currently set.
	 */

BYTE
ASCIISetup()
{
	UBYTE	Options[256];
	STRPTR	Index;

		/* Close the currently opened xpr.library. */

	if(XProtocolBase)
	{
		XProtocolCleanup(XprIO);

		CloseLibrary(XProtocolBase);
	}

		/* Use the same path name as the
		 * default protocol.
		 */

	strcpy(Options,Config . Protocol);

	if(Index = PathPart(Options))
	{
		*Index = 0;

		if(!AddPart(Options,"xprascii.library",256))
			strcpy(Options,"xprascii.library");
	}
	else
		strcpy(Options,"xprascii.library");

		/* Open xprascii.library... */

	if(!(XProtocolBase = (struct Library *)OpenLibrary(Options,0)))
		XProtocolBase = (struct Library *)OpenLibrary("xprascii.library",0);

	if(XProtocolBase)
	{
			/* Clear the interface buffer. */

		memset(XprIO,0,sizeof(struct XPR_IO));

			/* Try to obtain the ASCII settings. */

		if(!GetEnvDOS("xprascii",Options))
			Options[0] = 0;

			/* Initialize the interface buffer. */

		XprIO -> xpr_filename	= Options;
		XprIO -> xpr_fopen	= (APTR)xpr_fopen;
		XprIO -> xpr_fclose	= (APTR)xpr_fclose;
		XprIO -> xpr_fread	= (APTR)xpr_fread;
		XprIO -> xpr_fwrite	= (APTR)xpr_fwrite;
		XprIO -> xpr_sread	= (APTR)xpr_sread;
		XprIO -> xpr_swrite	= (APTR)xpr_swrite;
		XprIO -> xpr_sflush	= (APTR)xpr_sflush;
		XprIO -> xpr_update	= (APTR)xpr_update;
		XprIO -> xpr_chkabort	= (APTR)xpr_chkabort;
		XprIO -> xpr_gets	= (APTR)xpr_gets;
		XprIO -> xpr_setserial	= (APTR)xpr_setserial;
		XprIO -> xpr_ffirst	= (APTR)xpr_ffirst;
		XprIO -> xpr_fnext	= (APTR)xpr_fnext;
		XprIO -> xpr_finfo	= (APTR)xpr_finfo;
		XprIO -> xpr_fseek	= (APTR)xpr_fseek;
		XprIO -> xpr_extension	= 4;
		XprIO -> xpr_options	= (APTR)xpr_options;
		XprIO -> xpr_unlink	= (APTR)xpr_unlink;
		XprIO -> xpr_squery	= (APTR)xpr_squery;
		XprIO -> xpr_getptr	= (APTR)xpr_getptr;

			/* Initialize it. */

		TransferBits = XProtocolSetup(XprIO);

			/* Successful initialization? */

		if(!(TransferBits & XPRS_SUCCESS))
		{
			MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),"xprascii.library");

			CloseLibrary(XProtocolBase);

			XProtocolBase = NULL;

			ProtocolSetup();

			return(FALSE);
		}
	}
	else
	{
		MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_OPEN_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),"xprascii.library");

		ProtocolSetup();

		return(FALSE);
	}

	BinaryTransfer = FALSE;

	return(TRUE);
}

	/* ASCIIShutdown():
	 *
	 *	Close down xprascii.library and reopen the library
	 *	set in the current configuration.
	 */

VOID
ASCIIShutdown()
{
	XProtocolCleanup(XprIO);

	CloseLibrary(XProtocolBase);

	XProtocolBase = NULL;

	BinaryTransfer = TRUE;

	ProtocolSetup();
}
