home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / compress / xfh132.lzh / XFH / src / arexx.c next >
C/C++ Source or Header  |  1993-01-19  |  6KB  |  192 lines

  1. /* arexx.c - handling of the arexx interface to the handler.
  2.    Copyright (C) 1991, 1992, 1993 Kristian Nielsen.
  3.  
  4.    This file is part of XFH, the compressing file system handler.
  5.  
  6.    This program is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2 of the License, or
  9.    (at your option) any later version.
  10.  
  11.    This program is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.            */
  19.  
  20. /* $Log:    arexx.c,v $
  21.  * Revision 1.2  93/01/14  15:28:49  Kristian
  22.  * Added RCS keywords.
  23.  * 
  24.  */
  25.  
  26. /* Some of this code is taken from the 'fancydemo.c' AREXX example.
  27.  *
  28.  * NOTE: There's no code to facilitate returning result strings yet.
  29.  * Some code is commented out, and there is no lib open.
  30.  */
  31.  
  32. #include "CFS.h"
  33.  
  34. #include <rexx/storage.h>
  35. #include <rexx/rxslib.h>
  36. #include <exec/ports.h>
  37.  
  38. #include <proto/exec.h>
  39.  
  40. #ifdef __GNUC__
  41. #include "my_alib_protos.h"    /* Because of bug in inline/exec.h */
  42. #else
  43. #include <clib/alib_protos.h>
  44. #endif
  45.  
  46. #include <ctype.h>
  47. #include <string.h>
  48.  
  49. #include <dossupport.h>
  50.  
  51. #ifdef GIVE_AREXX_RESULT_STRINGS
  52. /* THIS NAME MUST BE RexxSysBase FOR THE GLUE ROUTINES */
  53. struct RxsLib *RexxSysBase = NULL;   /* this is the rexx library base */
  54. #endif
  55.  
  56. /* Replies a REXX message, filling in the appropriate codes.  If the macro
  57.  * program has requested a result string, the return argstring is allocated
  58.  * and installed in the rm_Result2 slot.
  59.  *
  60.  * A result is returned ONLY IF REQUESTED AND THE PRIMARY RESULT == 0.
  61.  */
  62.  
  63. static void reply_rexx_command(struct RexxMsg *rexxmessage,
  64.                             LONG primary,LONG secondary,char *result){
  65.    /* set an error code */
  66.    if (primary == 0 && (rexxmessage->rm_Action & 1L<<RXFB_RESULT)){
  67. #ifdef GIVE_AREXX_RESULT_STRINGS
  68.       secondary = result ? (long) CreateArgstring(result,strlen(result))
  69.                          : (long) NULL;
  70. #else
  71.       if(result) debug(("***PANIC: Internal / attempt to return AREXX result string.\n"));
  72.       secondary = (long) NULL;
  73. #endif
  74.    }
  75.    rexxmessage->rm_Result1 = primary;
  76.    rexxmessage->rm_Result2 = secondary;
  77.    ReplyMsg(&rexxmessage->rm_Node);
  78. }
  79.  
  80.  
  81. #define SETOPTION_CMD "SETOPTION"
  82.  
  83. static void execute_command(glb glob, struct RexxMsg *msg){
  84.    LONG primary = 0L,secondary = 0L;
  85.    char *p,*q,*r;
  86.    
  87.    debug(("AREXX command received: \"%s\".\n",msg->rm_Args[0]));
  88.  
  89.    /* ToDo: Have some real command parsing. This bit test for just a
  90.     * single command: SETOPTION.
  91.     */
  92.    p = msg->rm_Args[0];
  93.    while(*p && isspace(*p)) p++;  /* Skip white space. */
  94.    q=p;
  95.    while(*p && !isspace(*p)) p++; /* Find end of cmd name. */
  96.    r=p;
  97.    while(*p && isspace(*p)) p++;  /* Skip white space. */
  98.    
  99.    /* At this point, q points to command, r to command end, p to args. */
  100.    if(r-q==strlen(SETOPTION_CMD) && !strnicmp(q,SETOPTION_CMD,r-q)){
  101.       primary = set_option(glob,p) ? 0L : 10L;
  102.    }else{
  103.       /* Unrecognised command. */
  104.       primary = 10L;   /* Return error. */
  105.    }
  106.  
  107.    reply_rexx_command(msg,primary,secondary,NULL);
  108. }
  109.  
  110.  
  111. void checkarexxmsg(glb glob){
  112.    struct RexxMsg *msg;   /* incoming rexx messages */
  113.  
  114.   /* did we get something from rexx? */
  115.   while(msg = (struct RexxMsg *)GetMsg(glob->arexxport)){
  116.       /* a rexx macro has sent us a command, deal with it */
  117.       /* THE MESSAGE WILL HAVE BEEN REPLIED INSIDE OF execute_command */
  118.       execute_command(glob, msg);
  119.   }
  120. }
  121.  
  122.  
  123. ULONG arexxsigmask(glb glob){
  124.    return (ULONG)1 << glob->arexxport->mp_SigBit;
  125. }
  126.  
  127.  
  128. BOOL InitArexx(glb glob){
  129.   struct MsgPort *port;
  130.   char *portname;
  131.   
  132.   if(!glob->userarexxportname){
  133.     /* Find a suitable name for the port. */
  134.     if(!(portname=dosalloc(AREXXPORTMAXLEN+strlen(glob->devname)))){
  135.       debug(("Error: InitArexx(): No memory for port name.\n"));
  136.       OUTOFMEM;
  137.       return FALSE;
  138.     }
  139.     sprintf(portname,AREXXPORTTEMPLATE,glob->devname);
  140.   }else{
  141.     if(!(portname=dosalloc(1+strlen(glob->userarexxportname)))){
  142.       debug(("Error: InitArexx(): No memory for port name.\n"));
  143.       OUTOFMEM;
  144.       return FALSE;
  145.     }
  146.     strcpy(portname, glob->userarexxportname);
  147.   }  
  148.   Forbid();
  149.   /* look for someone else that looks just like us! */
  150.   if (FindPort(portname)){
  151.     Permit();
  152.     debug(("A public port called '%s' already exists!\n",portname));
  153.     dosfree(portname);
  154.     glob->ioerr = ERROR_OBJECT_EXISTS;
  155.     return FALSE;
  156.   }
  157.   
  158.   /* allocate the port */
  159.   if(!(port = CreatePort(portname,AREXXPORTPRI))){
  160.     debug(("Error: InitArexx(): Unable to CreatePort().\n"));
  161.     dosfree(portname);
  162.     OUTOFMEM;
  163.     return FALSE;
  164.   }
  165.   Permit();
  166.   
  167.   glob->arexxportname = portname;
  168.   glob->arexxport = port;
  169.   return TRUE;
  170. }
  171.  
  172. void CleanupArexx(glb glob){
  173.  
  174.    debug(("Cleaning up Arexx resources..."));   
  175.    if(glob->arexxport){
  176.       struct RexxMsg *msg;
  177.       
  178.       /* Careful: reply any pending messages. */
  179.       Forbid();
  180.       while(msg=(struct RexxMsg *)GetMsg(glob->arexxport)){
  181.          reply_rexx_command(msg,20,0,NULL);
  182.       }
  183.       DeletePort(glob->arexxport);
  184.       Permit();
  185.       glob->arexxport = NULL;
  186.    }
  187.    if(glob->arexxportname) dosfree(glob->arexxportname);
  188.    debug(("all cleaned up.\n"));
  189. }
  190.  
  191. /* End of arexx.c */
  192.