/*************************************************************
 * vt100 terminal emulator - AREXX support
 *				:ts=8
 *
 *	v2.9 ACS - New with this version.
 *
 *************************************************************/

#ifdef AREXX

#include "vt100.h"

int RexxReplies = 0;			/* # outstanding replies */

extern int doing_init;			/* in init.c		*/

extern char *extension;			/* in vt100.c		*/

#define AREXXCOMMAND 2
/*   Derived from:
 *
 *  REXX.C
 *
 *	(c) Copyright 1987 by Kim DeVaughn, All Rights Reserved
 *
 *  ARexx interface code, etc.
 *
 */

do_rx(cmd, implied)
char *cmd;
int implied;
{
    int	len, ret = 0;
    char *p;
    register struct RexxMsg *RexxMsg;
    struct MsgPort *RexxPort;

    if(cmd == NULL || *cmd == '\0')
	return ret;

    if(RexxSysBase == NULL) {
        if((RexxSysBase = (struct RxsLib *)OpenLibrary(RXSNAME, 0L)) == NULL)
            return NORXLIB;
        if( (ret = makerexxport()) != 0)
	    return ret;
    }

    for(len = 0, p = cmd; *p != '\n' && *p != '\0'; p++, len++)
	;

    Forbid();
    if((RexxPort = FindPort(RXSDIR))) {
	if((RexxMsg = CreateRexxMsg(FromRexxPort, extension, HostName)) &&
	   (ARG0(RexxMsg) = (STRPTR)CreateArgstring(cmd, (LONG)len)) ) {
	    ARG1(RexxMsg) = (STRPTR)AREXXCOMMAND;
	    RexxMsg->rm_Action = RXCOMM;
	    PutMsg(RexxPort, (struct Message *)RexxMsg);
	    RexxReplies++;
	} else
	    ret = NORXMSG;
    } else
	ret = NORXPORT;
    Permit();
    return ret;
}

void
processrexxmsg(RexxMsg)
register struct RexxMsg *RexxMsg;
{
    extern char *next_wrd();
    register char *arg0 = NULL, *arg1 = NULL;
    char *command = NULL,
	 *message = NULL,
	 *errmsg = "AREXX macro not found: ",
	 *MacDone = "AREXX macro complete: ",
	 *NoMem = "processrexxmsg: Can't allocate memory for message.";
    int len = 0;

    arg0 = (char *)ARG0(RexxMsg);
    arg1 = (char *)ARG1(RexxMsg);
    if(arg0 && *arg0)
	command = next_wrd(arg0, &len);

    if(RexxMsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG) {
	/*   Got some kind of reply so we'll assume that the AREXX lib is
	** available.  If it's a "command not found" then tell the user.  If
	** it's a command FROM VT100 (marked by AREXXCOMMAND in ARG1) and we
	** have no outstanding replies then it must mean that a previously
	** issued AREXX command FROM VT100 has completed, tell the user.
	** Otherwise, we can just toss the reply.
	**/

	if(--RexxReplies <= 0)
	    RexxReplies = 0;

	if(RexxMsg->rm_Result1 == 5 && RexxMsg->rm_Result2 == 1) {
	    LONG memlen = strlen(errmsg) + len + 1;

	    if(message = AllocMem(memlen, MEMF_PUBLIC | MEMF_CLEAR)) {
		strcpy(message, errmsg);
		strncat(message, command, len);
		if(doing_init) {
		    puts("Init:");
		    puts(message);
		} else
		    InfoMsg2Line("Script:", message);
		FreeMem(message, memlen);
	    } else {
		if(doing_init) {
		    puts("Init:");
		    puts(NoMem);
		} else
		    InfoMsg2Line("Script:", NoMem);
	    }
	}

	if(arg1 == (char *)AREXXCOMMAND) {
	    if(RexxReplies == 0 && command) {
		LONG memlen = strlen(MacDone) + strlen(command) + 1;

		if(message = AllocMem(memlen, MEMF_PUBLIC | MEMF_CLEAR)) {
		    strcpy(message, MacDone);
		    strcat(message, command);
		    if(doing_init) {
			puts("Init:");
			puts(message);
		    } else
			InfoMsg1Line(message);
		    FreeMem(message, memlen);
		} else {
		    if(doing_init) {
			puts("Init:");
			puts(NoMem);
		    } else
			InfoMsg2Line("Script:", NoMem);
		}
	    }
	}

	DeleteArgstring(arg0);
	ARG0(RexxMsg) = NULL;
	ARG1(RexxMsg) = NULL;
	DeleteRexxMsg(RexxMsg);

	return;
    } else if(RexxMsg->rm_Action == RXCOMM) {
	int ret;
	LONG memlen = strlen(arg0) + 1;

	CmdFromRexx = 1;	/* Tell everyone from whence it came */
	command = AllocMem(memlen, MEMF_PUBLIC | MEMF_CLEAR);
	strcpy(command, arg0);
	next_wrd(command, &len);

	RexxMsg->rm_Result1 = exe_cmd(command, len);
	CmdFromRexx = 0;
	FreeMem(command, memlen);
    } else {
	RexxMsg->rm_Result1 = 5;
	RexxMsg->rm_Result2 = 1;
    }
    ReplyMsg((struct Message *)RexxMsg);
}
#endif /* AREXX */
