/* rmspkt.c - include me in rrms packet bashers */

#include	<stdio.h>
#include	<cx.h>
#include	<algol68.h>
#include	<rms200.h>

/*	in:	opco	opcode
		wrds	number of words of fixed data
		txts	number of bytes of text
		packet	[0],[1],[2],[3]	don't care
			[4:4+wrds-1]	fixed data
			[4+wrds:4+wrds+txts+txts-1]	text
		server	name of the server task
		efn	event flag number to synch on
			(all transactions are synchronous: I won't
			return to you until all is done)
		id	your ID - I just pass it on
	do:	build the request packet, send it to 'server' task
		unstop 'server', receive reply into packet, unpack
		status and rab and number of reply bytes
	out:	packet[8...] reply data
		*stat	RMS status
		*stva	RMS status value
		*ra	file handle
		*nrb	number of reply bytes (in packet[8...])
	error:	*stat	ER$LIB
		*stva	$dsw of failed DIR$
		*ra	-1 to catch anything that looks at a RAB
			Don't EVER peer into RABs: they may live at
			the other end of a network (or beyond your
			capabilities) and you could hurt yourself.
		*nrb	0
*/

/*
		E D I T   H I S T O R Y

15jun85 DLE	If we can't find remote RMS task: try to RQST$ it.
		If this still fails, return ER$LIB in stat.
		Also return $dsw in stva. Doesn't return which DIR$ failed.
		This is better than bitching binary to a user.

		I know it isn't nice structure to do it this way.
		However: office politics say kludge it in here,
		since I "own" this module & others "own" its callers.
		Also, think of it as programming by assertion. If this
		mother returns OK, the job was done (somehow).

		RQST$ normally works, because server is normally rad50 /...rrt/

15jun85 DLE	Shit! RRMST/task=...rrt will give a RRTTnn> prompt rather
		than start running after RQST$. I want to keep that so
		I can trace things when I run RRT. So lets use spawn instead.
		I already use cspawn(task,command,efn) so I will try that.

		I put cspawn.obj into LB:[1,1]RRMS.OLB so rmspkt can find it.

16jun85 DLE	Tax! Vsda returns IS.SUC after it queues a var-packet to
		...RRT but it does not request RRT for my TI:. Because
		it returns IS_SUC, my cspawn code never executes.

		So try vsrc to send to ...rrt=>RRTTnn .
*/



rmspkt(opco,wrds,txts,id,packet,efn,server,stat,stva,ra,nrb)
int	opco;			/* opcode */
int	wrds;			/* words fixed */
int	txts;			/* bytes text */
int	id;			/* your word */
int	packet[];		/* the packet buffer */
int	efn;			/* which Event Flag Number i may use */
rad50	server[2];		/* RMS server task */
int	*stat;			/* returns RMS status */
int	*stva;			/* returns o$stv */
int	*ra;			/* returns rab */
int	*nrb;			/* returns number of reply bytes */
BEGIN
register int	dsw;		/* directive status word */
char * bungle;			/* points to what failed */
int	esb;			/* emmitted status */

	bungle = "";
	packet[0] = (opco << 8) | 1;	/* protocol # 1 */
	packet[1] = id;
	packet[2] = wrds;
	packet[3] = txts;
	/* assume packet[4...] set up */
	dsw = vsrc(server,packet,4+wrds+((txts+1)>>1),efn,0,&esb) &0xFF;
	IF	(dsw != IS_SUC)
	THEN	bungle = "vsrc";
	ELSE	dsw = ustp(server) & 0xFF;
		IF	(dsw != IS_SUC && dsw != IE_ITS)
		THEN	bungle = "ustp";
		ELSE	WHILE	((dsw=vrcs(NULL,packet,256))==IS_SET)
			DO	/* ignore false alarms */
			OD
			/* here with reply packet in packet[] */
			IF	(dsw<0)	/* +ve: # words got */
			THEN	bungle = "vrcs";
			FI
		FI
	FI

	IF	(*bungle)
	THEN	packet[5] = ER$LIB;
		fprintf(stderr,"\7rmspkt-%s-dsw=%oo server=%oo%oo efn=%o esb=%o\n\
Call a programmer; strike [RETURN] to continue"
				,bungle,dsw,server[0],server[1],efn,esb);
		getchar();
		packet[6] = dsw;
		packet[4] = -1;
		packet[7] = 0;
	FI
	*ra = packet[4];
	*stat = packet[5];
	*stva = packet[6];
	*nrb = packet[7];
END

/* end: rmspkt.c */

