
/*
 *  REX.C
 *
 *      (c) Copyright 1987, 1988 by Kim DeVaughn, All Rights Reserved
 *
 *      This program is freely redistributable for non-commercial purposes.
 *
 *      For commercial use, you may contact the author via USENET at:
 *          kim@amdahl.amdahl.com
 *
 *
 *  Example of ARexx interface code, etc.
 *
 */

#include <stdio.h>
#include "defs.h"
#include "rexx.h"


APTR OpenLibrary();
APTR FindPort();
APTR GetMsg();
APTR CreateRexxMsg();
APTR CreateArgstring();


/*
struct RexxArg *cmdarg;

struct MsgPort  RexxPort;
struct MsgPort *ARexxPort;

struct RexxMsg *cmdptr;
struct RexxMsg *retptr;
*/


struct RxsLib  *RexxSysBase;



/*
 *  issue a command to ARexx ...
 */

do_rexx(cmdstr)
char *cmdstr;
{
    struct RexxArg *cmdarg;

    struct MsgPort  RexxPort;
    struct MsgPort *ARexxPort;

    struct RexxMsg *cmdptr;
    struct RexxMsg *retptr;

    char host[16];
    char hexbuf[12];      /* should only need 9 bytes */

    int ret, testcmd, i;


    ClearMem(&RexxPort, sizeof(struct MsgPort));
    strcpy(host, "DME");
    sprintf(hexbuf, "%08x", &RexxPort);
    strcat(host, hexbuf);
    InitPort(&RexxPort, host);      /* need to error check this */
    AddPort(&RexxPort);
    /* return here if InitPort failed */


    if (cmdarg = (struct RexxArg *)CreateArgstring(cmdstr, strlen(cmdstr))) {
        if (cmdptr = (struct RexxMsg *)CreateRexxMsg(&RexxPort, "dme", host)) {
            ACTION(cmdptr) = RXCOMM;
            ARG0(cmdptr)   = (STRPTR)cmdarg;

            Forbid();
            if (ARexxPort = (struct MsgPort *)FindPort("REXX")) {
                PutMsg(ARexxPort, cmdptr);
                Permit();

                i = 0;
                for (;;) {
                    WaitPort(&RexxPort);
                    retptr = (struct RexxMsg *)GetMsg(&RexxPort);

                    printf("\nMessage = %d   Host = %s\n", i+1, host);
                    if (IsRexxMsg(retptr)) printf("IsRexxMsg() says it be a REXX msg!\n");
                    printf("rm_Args[0] = %s\n", ARG0(retptr));
                    printf("rm_Result1 = %d\nrm_Result2 = %d\n", RESULT1(retptr), RESULT2(retptr));
                    printf("rm_Action  = %08x\n", ACTION(retptr));
                    printf("ln_Name    = %s\n", retptr->rm_Node.mn_Node.ln_Name);

                    if (IsRexxMsg(retptr)) {

                        /* here's where you process the command the ARexx macro issued */
                        testcmd = strcmp(ARG0(retptr), "SECOND");
                        if (testcmd == 0) do_rexx("second");
                        testcmd = strcmp(ARG0(retptr), "CAT");
                        if (testcmd == 0) do_rexx("cat");

                        RESULT1(retptr) = i;
                        RESULT2(retptr) = 0;
                        i++;

                        ReplyMsg(retptr);
                    }
                    if (cmdptr == retptr) break;
                }
                if (ret = RESULT1(retptr)) {
                    if (RESULT2(retptr)) {
                        if (RESULT2(retptr) == 1) {
                            printf("Unknown Command\n");
                        } else {
                            printf("ARexx macro error:  Code = %d   Severity = %d\n", RESULT2(retptr), ret);
                        }
                    } else {
                        printf("User specified macro error.  RC = %d\n", ret);
                    }
                } else {
                    printf("Normal macro termination.\n");
                }
            } else {
                printf("ARexx not available - REXX port not found\n");
                ret = -1;
            }
            DeleteRexxMsg(cmdptr);
        } else {
            printf("CreateRexxMsg() Failed\n");     /* this may be overkill, and not need to be checked */
            ret = -1;
        }
        DeleteArgstring(cmdarg);
    } else {
        printf("CreateArgstring() Failed\n");       /* this may be overkill, and not need to be checked */
        ret = -1;
    }
    RemPort(&RexxPort);
    FreePort(&RexxPort);
    return(ret);
}



/*
 * initializion of our port to talk to ARexx
 */

void
rexxinit()
{
    char hexbuf[12];  /* should only need 9 bytes */

    /* need to add error checking */

/*  ClearMem(&RexxPort, sizeof(struct MsgPort));
    strcpy(host, "DME");
    sprintf(hexbuf, "%08x", &RexxPort);
    strcat(host, hexbuf);
    printf("\n\nhost = %s\n", host);

    InitPort(&RexxPort, host);
    AddPort(&RexxPort);
*/  return();
}



/*
 * cleanup of our ARexx port
 */

void
rexxclose()
{
/*  RemPort(&RexxPort);
    FreePort(&RexxPort);
*/  return();
}



/* ......... test prog ........... */

main (argc, argv)
int   argc;
char *argv[];
{
    if (argc < 2) exit(5);

    if (RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", (ULONG)RXSVERS)) {
        /* rexxinit();  */
        do_rexx(argv[1]);
        /* rexxclose(); */
        CloseLibrary(RexxSysBase);
    }
    exit(0);
}

