/***********************************************************
 * Gotcha ADDMONITOR demo. (c)1995 Thomas Bickel
 * Freely distributable. Do with this as you please.
 * Written with SAS C.
 * (excuse the chaos, but this was written in a hurry.
 *  I want to put it on AmiNet tomorrow)
 ***********************************************************/

#include <stdio.h>
#include <strings.h>
#include <stdlib.h>

#include <exec/types.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <proto/rexxsyslib.h>
#include <rexx/rexxio.h>
#include <rexx/rxslib.h>
#include <rexx/errors.h>
#include <rexx/storage.h>

extern struct Library* DOSBase;
struct Library *RexxSysBase=0;

struct RexxContext {
struct	MsgPort		*port;
struct	RexxMsg		*msg;
long	unconfirmed;
};

#define	ER_SIGNAL(c)	(1L<<c.port->mp_SigBit)
struct RexxContext rcontext;
ULONG	signals,n;
BOOL	done=FALSE;

/*********************************************
 * send a rexx msg
 *********************************************/
long sendrexxmsg(char *rexxhost, char *command, long flags, struct RexxContext *r)
{
	struct RexxMsg *rexxmsg;
	struct MsgPort *rexxport;

	if (rexxmsg=CreateRexxMsg((struct MsgPort *)r->port,"rexx",r->port->mp_Node.ln_Name)) {
		if (rexxmsg->rm_Args[0]=CreateArgstring(command,strlen(command))) {
			rexxmsg->rm_Action = RXCOMM | flags;
			Forbid();
			if (rexxport=FindPort(rexxhost)) PutMsg(rexxport,(struct Message *)rexxmsg);
			Permit();
			if (rexxport) {
				r->unconfirmed++;
				return(TRUE);
			}
		DeleteArgstring(rexxmsg->rm_Args[0]);
		}
	DeleteRexxMsg(rexxmsg);
	}

return(FALSE);
}
/************************************
 * get a rexx message
 ***********************************/
BOOL getrexxmsg(struct RexxContext *r)
{
	if (r->msg=(struct RexxMsg *)GetMsg(r->port)) {

		if (r->msg->rm_Node.ln_Type==NT_REPLYMSG) {
			if (r->msg->rm_Args[0]) DeleteArgstring(r->msg->rm_Args[0]);
			DeleteRexxMsg(r->msg);
			r->unconfirmed--;
		} else {		// a brand new message
			if (r->msg->rm_Args[0]) { 
				puts(r->msg->rm_Args[0]);
				if (0==strnicmp("GRX_QUIT",r->msg->rm_Args[0],8)) done=TRUE;
			}

			r->msg->rm_Result1=RC_OK;
			r->msg->rm_Result2=NULL;
			ReplyMsg((struct Message *)r->msg);
		}
		return(TRUE);
	}
return(FALSE);
}
/***********************************
 * main
 **********************************/
int main(long argc, char *argv[])
{
	if (argc!=2) {
		printf("Usage: %s <Gotcha-portname>\n"
		"This is a little demonstration program to show what kind of ARexx messages\n"
		"Gotcha will send if a port is added via ADDMONITOR.\n"
		"First start Gotcha then this program, then make a call with Gotcha or\n"
		"start some other action. Press Ctrl-C to exit.\n"
		,argv[0]);
		exit(5);
	}

	if (!FindPort(argv[1])) {
		puts("Gotcha port not found!");
		exit(20);
	}

	if (RexxSysBase = OpenLibrary("rexxsyslib.library",0)) {

		if ((!FindPort("GOTCHA_MONITOR_DEMO")) && (rcontext.port=CreateMsgPort())) {
			rcontext.port->mp_Node.ln_Name="GOTCHA_MONITOR_DEMO";
			rcontext.port->mp_Node.ln_Pri=0;
			AddPort(rcontext.port);

			sendrexxmsg(argv[1],"ADDMONITOR GOTCHA_MONITOR_DEMO",RXFF_RESULT,&rcontext);

			do {
				signals=Wait((ER_SIGNAL(rcontext)) | SIGBREAKF_CTRL_C);
				while (getrexxmsg(&rcontext));
            } while ((!done) && (!(signals & SIGBREAKF_CTRL_C)));

			RemPort(rcontext.port);
			n=10; while ((n) && (rcontext.unconfirmed)) {
				puts("Waiting for unconfirmed messages!");
				while (getrexxmsg(&rcontext));
				Delay(50);
                n--;
			}

			Forbid();
			if (rcontext.unconfirmed) while (getrexxmsg(&rcontext));
			DeleteMsgPort(rcontext.port);
			Permit();

		} else
			puts("Could not create REXX port!");

		CloseLibrary(RexxSysBase);
	} else
		puts("Could not open 'rexxsyslib.library'");
}
