*= Create NudelRexxMsg (NORMAL) =**************************************= 11-Aug-1995 =*
*  Inputs: CRexxPort(a5) - Ptr to null-term, case-sensitive name of host to talk to.  *
*          NudelPort(a5) - Ptr to our MsgPort.					      *
* Outputs: NudelRexxMsg(a5) - Ptr to our RexxMsg structure.			      *
***************************************************************************************
CreateNudelRexxMsg
	Tst.l	NudelPort(a5)			-._ If our port hasn't been created yet
	Beq	Internal			-'  generate "Internal" error.
	Tst.l	CRexxPort(a5)			-._ Make sure the port to talk to
	Beq	Internal			-'  has been defined, else "internal".

	Move.w	#0,a1				Use default extension ".REXX"
	Move.l	CRexxPort(a5),d0		Port we want to talk to.
	Move.l	NudelPort(a5),a0		Our MsgPort.
	N_CallRexSysLib	CreateRexxMsg
	Move.l	d0,NudelRexxMsg(a5)
	Beq_ErrorE	ErrAct_CreateRexxMsg(pc),#0
	RTS

ErrAct_CreateRexxMsg
	Dc.b	"Could not create RexxMsg",0
	Even

*= Delete NudelRexxMsg (NORMAL) =**************************************= 11-Aug-1995 =*
*  Inputs: NudelRexxMsg(a5) - Ptr to our RexxMsg structure.			      *
* Outputs: NudelRexxMsg(a5) - Null.						      *
*=====================================================================================*
*   Notes: This routine also clears/frees all argument pointers.		      *
***************************************************************************************
DeleteNudelRexxMsg
	Tst.l	NudelRexxMsg(a5)		-._ Skip routine if there
	Beq.s	DeleteNudelRexxMsg_Skip		-'  is no RexxMsg structure.
	Bsr.s	ClearNudelRexxMsg		Clear argument pointers, if any.
	Move.l	NudelRexxMsg(a5),a0		RexxMsg to a0 for Deletion
	N_JumpRexSysLib	DeleteRexxMsg		Delete it.
;;;;;;;	RTS for us.
DeleteNudelRexxMsg_Skip
	RTS

*= Clear NudelRexxMsg (NORMAL) =***************************************= 12-Aug-1995 =*
*  Inputs: NudelRexxMsg(a5) - Ptr to our RexxMsg structure.			      *
* Outputs: NudelRexxMsg(a5)->rm_Args - all cleared.				      *
*=====================================================================================*
*   Notes: This routine will count the number of arguments to clear automatically.    *
*          Does not support empty arguments in-between filled ones (nor does ARexx).  *
***************************************************************************************
ClearNudelRexxMsg
	Tst.l	NudelRexxMsg(a5)		-._ Skip routine if there
	Beq.s	ClearNudelRexxMsg_Skip2		-'  is no RexxMsg structure.

	Move.l	NudelRexxMsg(a5),a0		Point to RexxMsg
	Tst.l	rm_Result2(a0)			-._ If there is no result
	Beq.s	ClearNudelRexxMsg_Skip1		-'  string to clear, skip.
	Move.l	rm_Result2(a0),a0		ArgString -> a0 for DeleteArgString()
	N_CallRexSysLib	DeleteArgstring		Free the rm_Result2 string.
ClearNudelRexxMsg_Skip1
	Move.l	NudelRexxMsg(a5),a0		-._ Ensure rm_Result2 now
	Move.l	#0,rm_Result2(a0)		-'  has a NULL pointer.

;;;;;;;	Move.l	NudelRexxMsg(a5),a0		-._ Point to
	Lea	rm_Args(a0),a0			-'  RexxMsg->rm_Args
	Moveq	#-1,d0				d0 counts how many args to clear.
	Moveq	#MAXRMARG-1,d7			Maximum number of args to loop counter.
;;;;;;; d0,d7 adjusted for DBxx loop entered from the top.

CNRMCnt	Addq.l	#1,d0				Increment number of args.
	Tst.l	(a0)+				Another argument?
	DBeq	d7,CNRMCnt				Count them all.

	Tst.l	d0				-._ If nothing to clear,
	Beq.s	ClearNudelRexxMsg_Skip2		-'  skip the rest of it.

;;;;;;;	Move.l	d0,d0				Count into d0
	Move.l	NudelRexxMsg(a5),a0		RexxMsg to a0
	N_JumpRexSysLib	ClearRexxMsg		Clear all the arguments.
;;;;;;;	RTS for us.
ClearNudelRexxMsg_Skip2
	RTS

*= Fill NudelRexxMsg (NORMAL) =****************************************= 11-Aug-1995 =*
*  Inputs: NudelRexxMsg(a5) - Ptr to our RexxMsg structure.			      *
*          a1 - Ptr to Null-term, case sensitive command to put into 1st argument.    *
* Outputs: NudelRexxMsg(a5)->rm_Args[1] - Filled in argument.			      *
*          NudelRexxMsg(a5)->rm_Action - "String-file" bit set, rest cleared.	      *
*=====================================================================================*
*   Notes: This routine is _only_ for inserting a single-argument "string-file"       *
*          No checking is done to ensure that (a1) is valid.			      *
***************************************************************************************
FillNudelRexxMsg
	Move.l	a1,-(SP)		Preserve a1
	Tst.l	NudelRexxMsg(a5)	-._ If no previous RexxMsg structure,
	Beq.s	FNRM_Skp		-'  don't try and free it! :-).
	Bsr.s	DeleteNudelRexxMsg	Delete the used RexxMsg (can't re-use)
FNRM_Skp
	Bsr	CreateNudelRexxMsg	Create a new RexxMsg structure.

	Bsr.s	ClearNudelRexxMsg	Clear it first.
	Move.l	(SP)+,a1
	Move.l	NudelRexxMsg(a5),a0	RexxMsg
	Move.l	#RXCOMM!RXFF_STRING!RXFF_RESULT,rm_Action(a0)
;		Command, "string-file", results
	Move.l	a1,rm_Args(a0)		Argument
	Moveq	#1,d0			Just one message.
	Moveq	#0,d1			All args are strings.
	N_CallRexSysLib	FillRexxMsg	Fill in argument.
	Tst.l	d0
	Beq_ErrorE	ErrAct_FillRexxMsg(pc),#0
	RTS

ErrAct_FillRexxMsg
	Dc.b	"Could not fill RexxMsg",0
	Even


*= Send NudelRexxMsg (NORMAL) =****************************************= 16-Aug-1995 =*
*  Inputs: NudelRexxMsg(a5) - Fully filled-in RexxMsg for sending.		      *
*          CRexxPort(a5) - Ptr to null-term, case sensitive name of port to send to.  *
* Outputs: NudelRexxMsg(a5)->Result1 - RC, the numerical return code.		      *
*          NudelRexxMsg(a5)->Result2 - RESULT - Ptr to null-term ASCII result string. *
*=====================================================================================*
*   Notes: Assumes the first real msg received is a reply to the one it sends out,    *
*          and will send out warnings if this is not the case.			      *
*        : If Result2 is returned it must be freed (done by our Clear routine).	      *
***************************************************************************************
FillAndSendNudelRexxMsg
	Bsr.s	FillNudelRexxMsg
;;;;;;;	Bra.s	SendNudelRexxMsg

SendNudelRexxMsg
	Bsr	CkCtrlC			Check for ^C-Break and quit if sent.

	N_CallExec	Forbid		Forbid multitasking.
;					Ensures port doesn't close.
	Move.l	CRexxPort(a5),a1	Name of host port to send to.
	N_CallExec	FindPort	Find the port.
	Tst.l	d0			-._ If the port doesn't exist,
	IFND	Beta_Version_ARexx
	Beq.s	FindPort_NOT		-'  Permit() and call Error
	ELSE
	Beq	FindPort_NOT		-'  Permit() and call Error
	ENDC

	Move.l	d0,a0			Port to a0 for PutMsg()
	Move.l	NudelRexxMsg(a5),a1	RexxMsg to a1 for PutMsg()
	N_CallExec	PutMsg		Send RexxMsg to the Port.
	N_CallExec	Permit		Permit multitasking.

SNM_WP_Loop
	Move.l	NudelPort(a5),a0	-._ Wait for a msg
	N_CallExec	WaitPort	-'  to our port.

	Move.l	NudelPort(a5),a0	-._ Get the message
	N_CallExec	GetMsg		-'  sent to us.
	Tst.l	d0			-._ If there wasn't really
	Beq.s	SNM_WP_Loop		-'  a message, wait again.

	Move.l	d0,-(SP)		Preserve d0

	Move.l	NudelRexxMsg(a5),d1			-.
	Cmp.l	d0,d1					 |- Warning if this msg isn't
	Bsrne_ErrorW	ErrAct_NotOurMsg(pc),#0		-'  the same one we sent out.

	Move.l	(SP),a0					-.
	Cmpi.b	#NT_REPLYMSG,LN_TYPE(a0)		 |- Warning if this isn't
	Bsrne_ErrorW	ErrAct_NotReplyMsg(pc),#0	-'  a reply.

	Move.l	(SP)+,d0		Restore d0 and SP.

	IFD	Beta_Version_ARexx		Output debug-requester for Beta-Versions
	Move.l	d0,-(SP)

	Move.l	d0,a0				-.
	Move.l	CRexxPort(a5),RDF_1_Long(a5)	 |
	Move.l	rm_Args(a0),RDF_2_Long(a5)	 |- Setup data array
	Move.l	rm_Result1(a0),RDF_3_Long(a5)	 |  for RawDoFmt()
	Move.l	rm_Result2(a0),RDF_4_Long(a5)	-'

	Lea	RDF_Result_Input(pc),a0		Input string.
	Lea	RDF_Array(a5),a1		DataArray
	Lea	BufferA(a5),a3			-._ Output Buffer
	Move.l	a3,RDF_Adrs(a5)			-'  (Only when Beta_Version_ARexx)
	Move.l	#BufferALen,RDF_Size(a5)	Size of output buffer.
	Bsr	NudelRawDoFmt


	Move.l	#N_EasyStruct_Len,N_ES_Length(a5)	Size of structure.
	Move.l	#0,N_ES_Flags(a5)			No flags.
	Lea	ErrReq_Title(pc),a0		-.
	Move.l	a0,N_ES_Title(a5)		 |
	Lea	BufferA(a5),a0			 |_ Texts for
	Move.l	a0,N_ES_Body(a5)		 |  requester.
	Lea	ErrReq_Gads(pc),a0		 |
	Move.l	a0,N_ES_Gadgets(a5)		-'

	Lea	N_EasyStruct(a5),a1	Point to EasyRequest structure.
	Sub.l	a0,a0			Specify default public screen.
	Move.l	a0,a2			No IDCMP flags.
	Move.l	a0,a3			No arguments.
	N_CallInt	EasyRequestArgs	Put up the request.

	Move.l	(SP)+,d0
	ENDC

	RTS				Done.

	IFD	Beta_Version_ARexx

RDF_Result_Input
	Dc.b	"Results of ARexx command:",10
	Dc.b	10
	Dc.b	"Port: '%s'",10
	Dc.b	"Command: '%s'",10
	Dc.b	10
	Dc.b	"RC: %ld",10
	Dc.b	"Result: '%s'"
	Dc.b	0
	Even
	ENDC

FindPort_NOT
	N_CallExec	Permit		Permit multitasking.
	Move.l	CRexxPort(a5),NIB_NameAdrs+FakeNIB(a5)	Set pseudo-filename.
	Bra_ErrorE	ErrAct_FindPort(pc),FakeNIB_Adrs(a5)	Fatal error.

ErrAct_FindPort
	Dc.b	"Could not find port ",0
	Even

ErrAct_NotOurMsg
	Dc.b	"Received message not ours - please report to Leo",0
ErrAct_NotReplyMsg
	Dc.b	"Received message not a reply - please report to Leo",0
	Even
