#include	"multix.h"

#include	<stdio.h>
#include	<stdlib.h>

#include	<string.h>
#include	<time.h>


#include	"appl.h"
TMdxProcId		MyId;
Int8			SourceFile[25];
Int8			TargetFile[25];
Int8			ServerName[25];
TFileTransferInfo	FtpFileInfo;

TResult SetFtpMsg(
Int8Ptr	Source,
Int8Ptr Target
)
{
	memset(&FtpFileInfo,0,sizeof(FtpFileInfo));

	strcpy(FtpFileInfo.SrcFileName,Source);
	strcpy(FtpFileInfo.TgtFileName,Target);

	return(Success);

}


void	ApplPutFile(
TMdxSRMsgInfo  *MsgInfo
)
{
	TFileTransferInfo	FileInfo;
	FILE	*File;


	MdxMsgRead(MsgInfo->Received.Msg,&FileInfo,sizeof(FileInfo));


	printf("(%ld)File %s ( Size = %ld)Received and ",MdxGetCurrTimerValue(),
													FileInfo.TgtFileName,
													MdxMsgSizeGet(MsgInfo->Received.Msg)-sizeof(FileInfo)
													);

	File	=	fopen(FileInfo.TgtFileName,"wb");
	if ( (File) == (void *)0 )
	{
		printf("Failed Creating It\n");
	} else
	{
		TBufSize	CountRead;
		UInt8		Buf[500];
		while (	(CountRead	=	MdxMsgRead(	MsgInfo->Received.Msg,
												Buf,
												sizeof(Buf)
												))	>	0	)
		{
			if (	fwrite(Buf,1,CountRead,File)	!=	CountRead	)
			{
				fclose(File);
				remove(FileInfo.TgtFileName);
				printf("Failed Storing It\n");
				return;
			}
		}
		fclose(File);
		printf("stored Successfuly\n");
	}
}


void	ApplDataReplyReceived(
TMdxEvent	*Event
)
{
	TMdxSRMsgInfo	*MsgInfo;

	/*
	"Event->Data"	holds the information abount the new message.
	*/

	MsgInfo =	(TMdxSRMsgInfo	*)Event->Data;

	/*	First	thing is to check MsgCode of the new message	*/

	switch(MsgInfo->Received.MsgCode)
	{
		case	ApplGetFileMsgCode	:
		{
			ApplPutFile(MsgInfo);
			ApplShutdown	=	True;
		}
		break;
		default 					:	break;
	}
}

void	ApplSendGetFileReq(
TMdxProcId	ProcId
)
{
	TMdxError	Result;
	Result	=	MdxSendData( ProcId,
								&FtpFileInfo,					/*	Msg				*/
								sizeof(FtpFileInfo),
								ApplGetFileMsgCode,	/*	Msg Code		*/
								10,						/*	Lowest Priority	*/
								MdxSendReliable,		/*	Send Attributes	*/
														/*	Success/Failure	*/
														/*	Report			*/
								0,						/*	No ReqSeq		*/
								12000					/*	10 Secs Timeout	*/
														/*	for the other side*/
														/*	to confirm message*/
								);
	if (	Result	!=	MdErrNoError	)
	{
		printf("(%ld) Send Req Failed With Error - %d\n",
				MdxGetCurrTimerValue(),Result);

	}
}



void	ApplInitReceived(void)
{
	TMdxProcessParams	ProcessParams;
	TMdxLinkParams	LinkParams;

	/*
	You may choose to use onw or more links of the types specified.
	Un comment the relevent "MdxOpenLink()".

	You may change the parameters for the links.
	*/


	memset(&LinkParams,0,sizeof(LinkParams));
	strcpy(LinkParams.LinkName.Byte,"com2");
	LinkParams.LinkType				=	MdxLinkTypeAsyncLocal;
	LinkParams.ConnectMode			=	MdxConnectModeCall;
	LinkParams.ConnectTimeout		=	0x7fffffff;
	LinkParams.MaxConnectRetries	=	-1;
	LinkParams.ConnectRetriesDelay	=	200;
	LinkParams.LinkBaud 			=	19200;
	LinkParams.UseDlcFraming		=	True;
	LinkParams.ImAliveInterval		=	400l;
	LinkParams.MaxPollRetries		=	2;
	LinkParams.L1MaxSendSize		=	256;
	/*
	MdxOpenLink(&LinkParams);
	*/
	memset(&LinkParams,0,sizeof(LinkParams));
	strcpy(LinkParams.LinkName.Byte,"MdxFs");
	LinkParams.LinkType				=	MdxLinkTypeSpxIpx;
	LinkParams.ConnectMode			=	MdxConnectModeCall;
	LinkParams.ConnectTimeout		=	1000;
	LinkParams.MaxConnectRetries	=	-1;
	LinkParams.ConnectRetriesDelay	=	200;
	LinkParams.UseDlcFraming		=	True;
	LinkParams.MaxPollRetries		=	10;
	LinkParams.L1MaxSendSize		=	500;
	/*
	MdxOpenLink(&LinkParams);
	*/

	memset(&LinkParams,0,sizeof(LinkParams));
	strcpy(LinkParams.LinkName.Byte,"MdxFs");
	LinkParams.LinkType				=	MdxLinkTypeNetBios;
	LinkParams.ConnectMode			=	MdxConnectModeCall;
	LinkParams.ConnectTimeout		=	0x7fffffffl;
	LinkParams.ConnectRetriesDelay	=	300l;
	LinkParams.L1MaxSendSize		=	1024;
	LinkParams.MaxConnectRetries	=	-1l;
	/*
	MdxOpenLink(&LinkParams);
	*/


	memset(&ProcessParams,0,sizeof(ProcessParams));
	ProcessParams.ProcId					=	CallId;
	ProcessParams.InactivityTimer			=	6000;
	ProcessParams.ConnectRetriesInterval	=	200;
	MdxConnectProcess(&ProcessParams);
	printf("(%ld) Calling %ld\n",MdxGetCurrTimerValue(),ProcessParams.ProcId);
	ApplSendGetFileReq(CallId);
}


void	ApplSendMsgCompleted(
TMdxEvent	*Event
)
{
	TMdxSRMsgInfo		*MsgInfo;
	TFileTransferInfo	FileInfo;

	/*
	"Event->Data"	holds the information abount the Message we sent.
	*/

	MsgInfo =	(TMdxSRMsgInfo	*)Event->Data;
	switch(MsgInfo->Sent.MsgCode)
	{
		case	ApplGetFileMsgCode	:
		{
			MdxMsgRead(MsgInfo->Sent.Msg,(UInt8Ptr)&FileInfo,sizeof(FileInfo));
			printf("Get File (%s):%s To %s  ",
			ServerName,
			FileInfo.SrcFileName,
			FileInfo.TgtFileName);
			printf("Failed : Error = %d\n",Event->Error);
			ApplShutdown	=	True;
		}
		break;
		default 					:	break;
	}
}


void	ApplCallCompleted(
TMdxEvent	*Event
)
{
	printf("(%ld) Call Completed to Process (%ld)\n",
			MdxGetCurrTimerValue(),Event->ProcId);
}


void	cdecl	ApplEventHandler(
TMdxEvent	*Event
)
{
	switch(Event->Code)
	{
		case	MdxEvCallCompleted			:
		case	MdxEvCallRejected			:
		{
			ApplCallCompleted(Event);
		}
		break;
		case	MdxEvSendMsgCompleted		:
		{
			ApplSendMsgCompleted(Event);
		}
		break;
		case	MdxEventApplInit				:
		{
			ApplInitReceived();
		}
		break;
		case	MdxEvDataReplyReceived		:
		{
			ApplDataReplyReceived(Event);
		}
		break;
		case	MdxStdInAvailable				:
		{
			ApplShutdown	=	True;
		}
		break;
		default 								:	break;
	}
}


Int cdecl	main(
Int 	Argc,
Int8Ptr *Argv
)
{
	TSIndex CallIndex;
	MyId	=	9999998;
	if (	Argc	<	3	)
	{
		printf("Usage : mdxget SourceFile [TargetFile] <Node Id To Call>\n");
		return(5);
	}

	strcpy(SourceFile,Argv[1]);
	if (	Argc	>	3	)
	{
		strcpy(TargetFile,Argv[2]);
		CallIndex	=	3;
	} else
	{
		strcpy(TargetFile,SourceFile);
		CallIndex	=	2;
	}
	if ( (getenv(Argv[CallIndex])) != (void *)0 )
	{
		CallId	=	atol(getenv(Argv[CallIndex]));
		strcpy(ServerName,getenv(Argv[CallIndex]));
	} else
	{
		CallId	=	atol(Argv[CallIndex]);
		strcpy(ServerName,Argv[CallIndex]);
	}

	if (	CallId	==	0	)
	{
		printf("Invalid Value For Id To Call\n");
		exit(0);
	}


	MultiXStart(MyId,"Mdx File Copy",0,ApplEventHandler);

	if (	SetFtpMsg(SourceFile,TargetFile)	!=	Success )
	{
		printf("Invalid File To Copy\n");
		exit(0);

	}
	printf("Type any key to stop the program...\n");
	while (	ApplShutdown	==	False	)
	{
		MultiXWaitEvent();
	}
	return(0);
}
