#include	"multix.h"
#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<time.h>


#include	"appl.h"
TMdxProcId	MyId;

void	ApplGetFileReqReceived(
TMdxSRMsgInfo  *MsgInfo
)
{
	TFileTransferInfo	FileInfo;
	TMdxMsg *Msg;

	MdxMsgRead(MsgInfo->Received.Msg,(UInt8Ptr)&FileInfo,sizeof(FileInfo));

	Msg =	MdxMsgNewFile(	FileInfo.SrcFileName,
								(UInt8Ptr)&FileInfo,sizeof(FileInfo));

	if ( (Msg) == (void *)0 )
	{
		MdxReply(MsgInfo,ApplErrFileNotFound);
	} else
	{
		MdxReplyWithMsg(MsgInfo,	/*	Original Msg	*/
						MdErrNoError,			/*	No Error Reply	*/
						Msg,					/*	Msg				*/
						MsgInfo->Received.MsgCode,
						MsgInfo->Received.MsgPri,	/*	Lowest Priority	*/
						0,							/*	Send Attributes	*/
						0,							/*	No ReqSeq		*/
						0);
	}
}


void	ApplPutFileReqReceived(
TMdxSRMsgInfo  *MsgInfo
)
{
	TFileTransferInfo	FileInfo;
	FILE	*File;


	MdxMsgRead(MsgInfo->Received.Msg,(UInt8Ptr)&FileInfo,sizeof(FileInfo));
	if (	FileInfo.ReplaceFile	==	True	)
	{
		File	=	fopen(FileInfo.TgtFileName,"wb");
	} else
	{
		File	=	fopen(FileInfo.TgtFileName,"r");
		if ( (File) != (void *)0 )
		{
			fclose(File);
			MdxReply(MsgInfo,ApplErrFileExists);
			return;
		} else
		{
			File	=	fopen(FileInfo.TgtFileName,"wb");
		}
	}
	if ( (File) == (void *)0 )
	{
		MdxReply(MsgInfo,ApplErrCreateFileError);
	} 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);
				MdxReply(MsgInfo,ApplErrWriteFileError);
				return;
			}
		}
		fclose(File);
		MdxReply(MsgInfo,MdErrNoError);
	}
}


void	ApplNewMsgReceived(
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	ApplPutFileMsgCode	:
		{
			ApplPutFileReqReceived(MsgInfo);
		}
		break;
		case	ApplGetFileMsgCode	:
		{
			ApplGetFileReqReceived(MsgInfo);
		}
		break;
		default 					:	break;
	}
}


void	ApplCallReqReceived(
TMdxEvent	*Event
)
{
	/*
	Event->ProcId	-	Holds the calling process id.
	Event->Data		-	Holds the password used.
	*/

	MdxAcceptProcess(Event->ProcId,(void *)0);
}


void	ApplInitReceived(void)
{
	/*
	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.
	*/


	TMdxLinkParams	LinkParams;
	memset(&LinkParams,0,sizeof(LinkParams));
	strcpy(LinkParams.LinkName.Byte,"com2");
	LinkParams.LinkType				=	MdxLinkTypeAsyncLocal;
	LinkParams.ConnectMode			=	MdxConnectModeListen;
	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			=	MdxConnectModeListen;
	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			=	MdxConnectModeListen;
	LinkParams.ConnectTimeout		=	0x7fffffffl;
	LinkParams.ConnectRetriesDelay	=	300l;
	LinkParams.L1MaxSendSize		=	1024;
	LinkParams.MaxConnectRetries	=	-1l;
	/*
	MdxOpenLink(&LinkParams);
	*/
}


void	cdecl	ApplEventHandler(
TMdxEvent	*Event
)
{
	switch(Event->Code)
	{
		case	MdxEventApplInit				:
		{
			ApplInitReceived();
		}
		break;
		case	MdxEvCallReqReceived		:
		{
			ApplCallReqReceived(Event);
		}
		break;
		case	MdxEvDataMsgReceived		:
		{
			ApplNewMsgReceived(Event);
		}
		break;
		case	MdxStdInAvailable				:
		{
			exit(0);
		}
		break;
		default 								:	break;
	}
}


Int cdecl	main(
Int 	Argc,
Int8Ptr *Argv
)
{
	if (	Argc	<	2	)
	{
		printf("Usage : mdxfs <Proccess Id>\n");
		return(5);
	}
	MyId	=	(TMdxProcId)atol(Argv[1]);
	if (	MyId	<=	0	)
	{
		printf("Node Id Should be between 1 - %ld\n",0x7fffffffl);
		return(0);
	}

	MultiXStart(MyId,"MultiX File Server",0,ApplEventHandler);

	printf("Type any key to stop the program...\n");

	while (	ApplShutdown	==	False	)
	{
		MultiXWaitEvent();
	}
	return(0);
}
