home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / YADME10.LHA / YADME10 / src / rexx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-19  |  9.3 KB  |  369 lines

  1.  
  2. /*
  3.  *  REXX.C
  4.  *
  5.  *      (c) Copyright 1987 by Kim DeVaughn, All Rights Reserved
  6.  *
  7.  *  ARexx interface code, etc.
  8.  *
  9.  */
  10.  
  11. #include "defs.h"
  12. #include <ctype.h>
  13.  
  14.  
  15.  
  16.  
  17. #include <rexx/storage.h>
  18. #include <rexx/rxslib.h>
  19. #include <rexx/rexxio.h>
  20. #include <rexx/errors.h>
  21. #include "rexx.h"
  22.  
  23. #include <clib/rexxsyslib_protos.h>
  24.  
  25. int foundcmd;       /* control for implicit ARexx macro invocation   */
  26. int cmderr;         /* global command error flag for do_rexx()'s use */
  27. short InRxCmd;       /* main loop rexx processing inhibit */
  28.  
  29.  
  30. struct RxsLib *RexxSysBase;
  31. struct MsgPort *RexxPort;
  32. char RexxHostName[16];
  33. struct MacArray {
  34.     struct NameArray *Next;
  35.     struct RexxMsg *macs[16];
  36.     struct RexxMsg *replies[16];
  37. } *RexxPending = NULL;
  38. static char macbuf[256];
  39.  
  40. static char RexBuf[256];
  41. char RexBufUsed;
  42.  
  43. /*
  44.  * initialization for ARexx ... just open rexsyslib.library (& open port ... TJM)
  45.  */
  46.  
  47. void openrexx(void)
  48. {
  49.     int DmeNum = 0;
  50. /*     struct RexxArg *macarg;
  51.        struct RexxMsg *macptr; */
  52.  
  53.     if(!(RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", (ULONG)RXSVERS)))
  54.         return;
  55.     if(RexxPort = AllocMem(sizeof(struct MsgPort),MEMF_PUBLIC|MEMF_CLEAR)){
  56.         strcpy(RexxHostName,"DME");
  57.         Forbid();
  58.         if(!FindPort(RexxHostName)) {
  59.             InitPort(RexxPort, RexxHostName); /* error checking? */
  60.             AddPort(RexxPort);
  61.             Permit();
  62.             NewDME = 1;
  63.         }
  64.         else {
  65.             if(NewDME) {
  66.                 do {
  67.                     sprintf(RexxHostName, "DME%d", DmeNum++);
  68.                 } while(FindPort(RexxHostName));
  69.                 InitPort(RexxPort, RexxHostName); /* error checking ? */
  70.                 AddPort(RexxPort);
  71.             }
  72.             Permit();
  73.             if(!NewDME){ /* try to make sure user doesn't hit close gadget on old dme */
  74.                 FreeMem(RexxPort,sizeof(struct MsgPort));
  75.                 RexxPort = CreatePort(NULL,0);
  76.                 do_rrexx("\"'rxblock'\"");  /* if this doesn't succeed, then it's the user's own stupid fault.. */
  77.             }
  78.         }
  79.     }
  80.     else {
  81.         CloseLibrary((struct Library *)RexxSysBase);
  82.         RexxSysBase = NULL;
  83.     }
  84.     return;
  85. }
  86.  
  87.  
  88.  
  89. /*
  90.  * cleanup any open ARexx stuff ...  just close rexsyslib.library for now (& close port ... TJM)
  91.  */
  92.  
  93. void closerexx(void)
  94. {
  95.     if(RexxPort){
  96.         if(!NewDME) {
  97.             do_rrexx("\"'rxunblock'\"");
  98.             DeletePort(RexxPort);
  99.         }
  100.         else {
  101.             RemPort(RexxPort);
  102.             FreePort(RexxPort);
  103.         }
  104.     }
  105.     if (RexxSysBase)
  106.         CloseLibrary((struct Library *)RexxSysBase);
  107. }
  108.  
  109.  
  110.  
  111. /*
  112.  *  explicit invocation interface between do_command() and do_rexx
  113.  *  for ARexx macros having NO arguments (i.e., for the "rx" command)
  114.  */
  115.  
  116. void do_rx(void)
  117. {
  118.     do_rexx(av[1],RexxHostName);
  119. }
  120.  
  121.  
  122.  
  123. /*
  124.  *  explicit invocation interface between do_command() and do_rexx
  125.  *  for ARexx macros having ONE argument (i.e., for the "rx1" command)
  126.  */
  127.  
  128. void do_rx1(void)
  129. {
  130.  
  131.     strcpy(macbuf, av[1]);
  132.     strcat(macbuf, " ");
  133.     strcat(macbuf, av[2]);
  134.     do_rexx(macbuf,RexxHostName);
  135. }
  136.  
  137.  
  138.  
  139. /*
  140.  *  explicit invocation interface between do_command() and do_rexx
  141.  *  for ARexx macros having TWO arguments (i.e., for the "rx2" command)
  142.  */
  143.  
  144. void do_rx2(void)
  145. {
  146.     strcpy(macbuf, av[1]);
  147.     strcat(macbuf, " ");
  148.     strcat(macbuf, av[2]);
  149.     strcat(macbuf, " ");
  150.     strcat(macbuf, av[3]);
  151.     do_rexx(macbuf,RexxHostName);
  152. }
  153.  
  154.  
  155.  
  156. /*
  157.  *  implicit invocation interface between do_command() and do_rexx
  158.  *  for ARexx macros implicitly called; arbitrary number of arguments
  159.  */
  160.  
  161. void do_rxImplied(char *cmd, char *args)
  162. {
  163.     strcpy(macbuf, cmd);
  164.     strcat(macbuf, " ");
  165.     strcat(macbuf, args);
  166.     do_rexx(macbuf,RexxHostName);
  167. }
  168.  
  169. void do_rrexx(char *mac)
  170. {
  171.     do_rexx(mac,"DME");
  172.     WaitPort(RexxPort);
  173.     GetMsg(RexxPort);
  174. }
  175.  
  176. /*
  177.  *  issue a command to ARexx ...
  178.  */
  179.  
  180. static struct RexxMsg *CurRxMac;
  181.  
  182. int do_rexx(char *macstr, char *hostname)
  183. {
  184.     struct RexxArg *macarg;
  185.  
  186.     struct MsgPort *ARexxPort;
  187.  
  188.     struct RexxMsg *macptr;
  189. /*  struct RexxMsg *cmdptr;
  190.  
  191.     int  err;
  192.     long oldLock;    */
  193.     int  ret;
  194.  
  195.  
  196.     if (RexxSysBase == 0) {
  197.         title("Unknown Command   -   No Macros:  ARexx Not Installed ");   /* no rexxsyslib */
  198.         return(0);
  199.     }
  200.  
  201.     if (macarg = (struct RexxArg *)CreateArgstring(macstr, strlen(macstr))) {
  202.         if (macptr = (struct RexxMsg *)CreateRexxMsg(RexxPort, "dme", hostname)) {
  203.             ACTION(macptr) = RXCOMM;
  204.             ARG0(macptr)   = (STRPTR)macarg;
  205.  
  206.             Forbid();
  207.             if (ARexxPort = (struct MsgPort *)FindPort("REXX")) {
  208.                 PutMsg(ARexxPort, (MSG *)macptr);
  209.                 Permit();
  210.                 CurRxMac = macptr;
  211. /*              title("Calling ARexx Macro ... "); */
  212.             } else {
  213.                 Permit();
  214.                 title("Unknown Command   -   No Macros:  ARexx Not Active ");   /* no REXX port */
  215.                 DeleteRexxMsg(macptr);
  216.                 DeleteArgstring((UBYTE *)macarg);
  217.  
  218.                 ret = -1;
  219.             }
  220.         } else {
  221.             title("CreateRexxMsg() Failed ");   /* may be overkill, and not need to ckeck this */
  222.             DeleteArgstring((UBYTE *)macarg);
  223.             ret = -1;
  224.         }
  225.     } else {
  226.         title("CreateArgstring() Failed ");     /* may be overkill, and not need to check this */
  227.         ret = -1;
  228.     }
  229.     return(ret);
  230. }
  231.  
  232. int Process_Rexx(void)
  233. {
  234.     char errmsg[80];        /* don't build a larger error message */
  235.  
  236.     int  ret;
  237.     int  err;
  238.     struct RexxMsg *cmdptr;
  239.  
  240.     while(cmdptr = (struct RexxMsg *)GetMsg(RexxPort)){
  241.  
  242.         if (IsRexxMsg(cmdptr)) {
  243.             char *arg0 = ARG0((cmdptr));
  244.             short i;
  245.             char *str, *aux, quoted;
  246.  
  247.             CurRxMac = NULL;
  248.             cmderr = CMD_INITIAL;
  249.             RESULT1(cmdptr) = RESULT2(cmdptr) = 0;
  250.             for (i = 0;i < 10 && arg0[i] > ' ' ; i++ )
  251.                 RexBuf[i] = isupper(arg0[i])?tolower(arg0[i]):arg0[i];
  252.  
  253.             RexBuf[i] = 0;
  254.             if (!strcmp(RexBuf, "getval")) {
  255.                 foundcmd = 1;
  256.                 ret = 1;
  257.                 err = cmderr;
  258.                 strncpy(RexBuf, ARG0(cmdptr) + 6, 255),
  259.                 RexBuf[255] = 0;
  260.                 if (cmdptr->rm_Action & RXFF_RESULT) {
  261.                     str = RexBuf;
  262.                     if (str = breakout(&str, "ed, &aux))
  263.                         RESULT2(cmdptr) = (long) CreateArgstring(str, strlen(str));
  264.                     if (aux)
  265.                         free(aux);
  266.                 }
  267.             }
  268.  
  269.             else if (!strcmp(RexBuf, "rxblock")) {
  270.                 foundcmd = 1;
  271.                 ret = 1;
  272.                 err = cmderr;
  273.                 RxBlock = 1;
  274.             }
  275.  
  276.             else if (!strcmp(RexBuf, "rxunblock")) {
  277.                 foundcmd = 1;
  278.                 ret = 1;
  279.                 err = cmderr;
  280.                 RxBlock = 0;
  281.             }
  282.  
  283.             else {
  284.                 ret = do_command(arg0);
  285.                 err = cmderr;
  286.             }
  287.  
  288.             if (foundcmd) {
  289.                 ret = (ret == 1) ? 0 : 5;       /* cmd error:  RC = 5  */
  290.             } else {
  291.                 ret = do_rexx(ARG0(cmdptr),RexxHostName);  /* another macro?   */
  292.             }
  293.  
  294.             if(CurRxMac)
  295.                 PushMsg(cmdptr,CurRxMac);
  296.             else {
  297.                 RESULT1(cmdptr) = ret;
  298.                 ReplyMsg((MSG *)cmdptr);
  299.             }
  300.  
  301.             foundcmd = 1;
  302.             /* do_command("null");   */  /* a kludge to set "foundcmd" */
  303.         } else {
  304.             if (ret = RESULT1(cmdptr)) {
  305.                 if (RESULT2(cmdptr)) {
  306.                     if (RESULT2(cmdptr) == 1) {
  307.                         title("Unknown Command ");
  308.                     } else {
  309.                         sprintf(errmsg, "ARexx Macro Error:  Code = %d  Severity = %d ", RESULT2(cmdptr), ret);
  310.                         title(errmsg);
  311.                     }
  312.                 } else {
  313.                     sprintf(errmsg, "User Specified Macro Error:  RC = %d ", ret);
  314.                     title(errmsg);
  315.                 }
  316.             } else {
  317.                 /*
  318.                 * if (err <= TITLE_THRESHHOLD) {
  319.                 *     title("OK ");
  320.                 * }
  321.                 */
  322.             }
  323.             ret = ret + err;
  324.             PopMsg(cmdptr,ret);
  325.         }
  326.     }
  327.     return err;
  328. }
  329.  
  330. void PushMsg(struct RexxMsg *source, struct RexxMsg *wait)
  331. {
  332.     struct MacArray *tmp;
  333.     int i;
  334.  
  335.     for(tmp = RexxPending;tmp;tmp = (struct MacArray *)tmp->Next){
  336.         for(i=0;i<16;i++)
  337.             if(!tmp->macs[i])
  338.                 break;
  339.         if(i!=16)
  340.             break;
  341.     }
  342.     if(!tmp){
  343.         tmp = RexxPending;
  344.         RexxPending = malloc(sizeof(struct MacArray));
  345.         memset(RexxPending,sizeof(struct MacArray),0);
  346.         RexxPending->Next = (struct NameArray *)tmp;
  347.         tmp = RexxPending;
  348.         i = 0;
  349.     }
  350.     tmp->macs[i] = wait;
  351.     tmp->replies[i] = source;
  352. }
  353.  
  354. void PopMsg(struct RexxMsg *signal, int ret)
  355. {
  356.     struct MacArray *tmp;
  357.     int i;
  358.  
  359.     for(tmp = RexxPending;tmp;tmp = (struct MacArray *)tmp->Next)
  360.         for(i=0;i<16;i++)
  361.             if(tmp->macs[i] == signal){
  362.                 tmp->macs[i] = NULL;                /* could actually try to free MacArray here, but it'll */
  363.                 RESULT1(tmp->replies[i]) = ret;     /* eventually free itself (upon exit), so why bother? */
  364.                 ReplyMsg((MSG *)tmp->replies[i]);   /* ^^^ assuming malloc tacks mem onto Task->MemList...*/
  365.                 return;
  366.             }
  367. }
  368.  
  369.