

/*
 *    RDERXRT.C
 *      routines in C for testrh
 *      (C) Copyright 1989 by Vidyanath Rao
 *              All rights reserved.
 *
 * These routines may be used in freely redistributable software for
 * the Amiga (TM of Commodore-Amiga) computer, provided that credit
 * is given and this notice appears in the software or the documentation.
 */

#include <exec/exec.h>
#include <rexx/storage.h>
#include "defs.h"

#define SRMF_ASYNCH 1L<<16
#define SRMF_HOSTNM 1L<<17

extern char *RHUsrPassWd, *RHMcrPassWd;
extern char *rxerrmsg(), *breakout();
extern UWORD RMSeqNo;

/*
 * do_rxc() is a synchronous call to ARexx.
 * do_rximpl(s1, s2) is a synchronous call to ARexx that sends
 * s1 concatenated with s2 as the command.
 * In both cases the call is simply
 *      rxend(sendrxmsg(RXCOMM, xxx, ptr to command str, 0), 0)
 *                        ^ string arg,          ^ no id.
 *                          synchronous
 *                          Host nmae variable
 *
 * do_rxc()
 * {
 *     return(rxend(sendrxmsg(RXCOMM, 0, &av[1], 0)));
 * }
 *
 * do_rximpl(s1, s2)
 *     char *s1, *s2;
 *
 * {
 *     char store[256], *str = store;
 *
 *     strcpy(str, s1);
 *     strcat(str, s2);
 *     return(rxend(sendrxmsg(RXCOMM, SRMF_HOSTNM, &str, 0)));
 * }
 *
 */


#asm
        public  _do_rxc

_do_rxc:
        link    a5,#0
        clr.l   -(sp) ; push the arguments; id = 0
        pea     _av+4 ; cmd str = av[1]
        clr.l   -(sp) ; sync, and string args
        bra.s   dril05

SRMF_HOSTNM     EQU     1L<<17

        public  _do_rximpld
_do_rximpld:
        link    a5,#-260 ; space for local variables
        lea     -256(a5),a0 ; -256(a5) = local storage
        move.l  a0,-260(a5) ; -260(a5) will point at it.
        move.l  8(a5),a1 ; copy the first string into the storage
dril01: move.b  (a1)+,(a0)+
        bne     dril01
        move.b  #$20,-1(a0) ; seperate the strings with space.
        move.l  12(a5),a1; now concat the second string
dril02: move.b  (a1)+,(a0)+
        bne     dril02

        clr.l   -(sp) ; push the args: id = 0
        pea     -260(a5) ; cmd str = store
        move.l  #SRMF_HOSTNM,-(sp) ; str arg and sync call
dril05: pea     16777216 ; action = RXCOMM
        jsr     _sendrxmsg
        addq.l  #8,sp
        clr.l   4(sp) ; id = 0
        move.l  d0,(sp)
        jsr     _rxend
        addq.l  #8,sp
        unlk    a5
        rts
#endasm


rxend(n, id)
    long n, id;
{
    switch(n) {
      case 0:
        return(1);
      case 1:
        puts("Too many outstanding Rexx commands.");
        CmdErr |= RDE_RXBAD;
        break;
      case 2:
        puts("Unable to create/fill Rexx message");
        CmdErr |= RDE_NOMEM;
        break;
      case 3:
        puts("No public Rexx port.");
        CmdErr |= RDE_RXBAD;
        break;
      default:
        ;
    }
/* The clean-up code for the id goes here */
    CmdErr |= RDE_CMDERR;
    return(0);
}


do_rxo()
{
    register long act, flags;
    char *args[15];
    long id = 0;
    register int count = 0;
    UWORD rc;
    char qut, pad;

    flags = 0;
{
#asm
        move.l  4+_av,a0
        bra     drxol1
drxol2: bset    #5,(a0)+
drxol1: tst.b   (a0)
        bne     drxol2
#endasm
};

    if ( av[1][0] == 'f') {
        for (count = 0, qut = 0; (count <= 14); count++) {
            if ( (args[count] = breakout(&av[2], &qut)) == NULL) {
                break;
            }
        }
        if ( (qut >= 2) || (count == 0) ) {
            for(--count; count >= 0; --count) {
                free(args[count]);
            }
            return(0);
        }
        act = RXFUNC | (count-1);
    } else {
        args[0] = av[2];
        act = RXCOMM;
    }

    if ( av[1][1] == 'r') {
        act |= RXFF_RESULT;
    }
    if (av[1][2] == 's') {
        act |= RXFF_STRING;
        flags |= SRMF_HOSTNM;
    }
    if ( av[1][3] == 't') {
        act |= RXFF_TOKEN;
    }

    if ( av[1][4] == 'a') {
        id = 0x00010000 | ( (long) RMSeqNo) ;
        flags |= SRMF_ASYNCH;
    }

    rc = sendrxmsg(act, flags, args, id);
    for (--count; count >= 0; --count) {
        free(args[count]);
    }
    return(rxend(rc, id));

}

drm_end(r2, r1, id)
    union {long err; char *res;} r2;
    long r1, id;

{
    char store[128];

    if (id == 0) {
        strcpy(store, "Rexx Macro ");
    } else {
        sprintf(store, "RM# %6d ", 0xffff & id);
        store[11] = '\0';
    }

    if (r1 == 0) {
        if (r2.res != NULL) {
            if (String != NULL) {
                free(String);
            }
            String = r2.res;
        }
        strcpy(&store[11], "completed successfully");
    } else if (r1 > 0) {
        sprintf(&store[11], "error (sev %d): %s", r1, rxerrmsg(r2.err));
        if (id == 0) { /* synchornous msg. set CmdErr */
            CmdErr |= RDE_RXBAD;
        }
    } else if (r1 == -1) {
        strcpy(&store[11], "no memory for result");
        CmdErr |= RDE_NOMEM;
    }

/* Clean-up routine for the id goes here */
    puts(store);
}

do_rhlocks()

{
    switch (av[0][0]) {
      case 'c' :
        if (RHMcrPassWd != NULL) {
            free(RHMcrPassWd);
            RHMcrPassWd == NULL;
        }
        RHFlags &= ~(RHF_USRLCK | RHF_MCRLCK);
        puts("Rexx Host locks cleared");
        break;
      case 'l' :
        if (RHUsrPassWd == NULL) {
            puts("No password set");
            return(0);
        } else {
            puts("Rexx Host locked");
            RHFlags |= RHF_USRLCK;
            break;
        }
      case 'u' :
        RHFlags &= ~RHF_USRLCK;
        puts("Rexx Host unlocked");
        break;
    }
    return(1);
}

rh_lock(arg, str, len)
    long len;
    char *str, *arg;

{
    if (RHFlags & RHF_MCRLCK) {
        return(5);
    }
    if ( (len = strlen(arg)) == 0) {
        return(5);
    }

    if ( (RHMcrPassWd = malloc(len+1)) == NULL) {
        return(10);
    }

    strcpy (RHMcrPassWd, arg);
    len = 0;
    RHFlags |= RHF_MCRLCK;
    return(0);
}

rh_unlock(arg, str, len)
    long len;
    char *str, *arg;

{
    if (RHFlags & RHF_MCRLCK == 0) {
        return(5);
    }
    free(RHMcrPassWd);
    RHMcrPassWd == NULL;
    RHFlags &= ~RHF_MCRLCK;
    return(0);
}

rh_string(arg, str, len)
    long len;
    char *str, *arg;

{
    if ( (len = strlen(String)) == 0) {
        len = 1;
    }
    if ( (str = malloc(len+1)) == NULL) {
        return(10);
    } else {
        strcpy(str, String);
        str[len] = '\0';
        return(0);
    }
}

rh_msg2usr(arg, str, len)
    long len;
    char *str, *arg;

{
    puts(arg);
    return(0);
}

/*
noname(arg, str, len)
    long len;
    char *str, *arg;

{
    return(0);
}
*/
