home *** CD-ROM | disk | FTP | other *** search
- /* arexx.c - handling of the arexx interface to the handler.
- Copyright (C) 1991, 1992, 1993 Kristian Nielsen.
-
- This file is part of XFH, the compressing file system handler.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* Some of this code is taken from the 'fancydemo.c' AREXX example.
- *
- * NOTE: There's no code to facilitate returning result strings yet.
- * Some code is commented out, and there is no lib open.
- */
-
- #include "CFS.h"
-
- #include <rexx/storage.h>
- #include <rexx/rxslib.h>
- #include <exec/ports.h>
-
- #include <proto/exec.h>
-
- #include <clib/alib_protos.h>
-
- #include <ctype.h>
- #include <string.h>
-
- #include <dossupport.h>
-
- #ifdef GIVE_AREXX_RESULT_STRINGS
- /* THIS NAME MUST BE RexxSysBase FOR THE GLUE ROUTINES */
- struct RxsLib *RexxSysBase = NULL; /* this is the rexx library base */
- #endif
-
- /* Replies a REXX message, filling in the appropriate codes. If the macro
- * program has requested a result string, the return argstring is allocated
- * and installed in the rm_Result2 slot.
- *
- * A result is returned ONLY IF REQUESTED AND THE PRIMARY RESULT == 0.
- */
-
- static void reply_rexx_command(struct RexxMsg *rexxmessage,
- LONG primary,LONG secondary,char *result){
- /* set an error code */
- if (primary == 0 && (rexxmessage->rm_Action & 1L<<RXFB_RESULT)){
- #ifdef GIVE_AREXX_RESULT_STRINGS
- secondary = result ? (long) CreateArgstring(result,strlen(result))
- : (long) NULL;
- #else
- if(result) debug(("***PANIC: Internal / attempt to return AREXX result string.\n"));
- secondary = (long) NULL;
- #endif
- }
- rexxmessage->rm_Result1 = primary;
- rexxmessage->rm_Result2 = secondary;
- ReplyMsg(&rexxmessage->rm_Node);
- }
-
-
- #define SETOPTION_CMD "SETOPTION"
-
- static void execute_command(glb glob, struct RexxMsg *msg){
- LONG primary, secondary = 0L;
- char *p,*q,*r;
-
- debug(("AREXX command received: \"%s\".\n",msg->rm_Args[0]));
-
- /* ToDo: Have some real command parsing. This bit test for just a
- * single command: SETOPTION.
- */
- p = msg->rm_Args[0];
- while(*p && isspace(*p)) p++; /* Skip white space. */
- q=p;
- while(*p && !isspace(*p)) p++; /* Find end of cmd name. */
- r=p;
- while(*p && isspace(*p)) p++; /* Skip white space. */
-
- /* At this point, q points to command, r to command end, p to args. */
- if(r-q==strlen(SETOPTION_CMD) && !strnicmp(q,SETOPTION_CMD,r-q)){
- primary = set_option(glob,p) ? 0L : 10L;
- }else{
- /* Unrecognised command. */
- primary = 10L; /* Return error. */
- }
-
- reply_rexx_command(msg,primary,secondary,NULL);
- }
-
-
- void checkarexxmsg(glb glob){
- struct RexxMsg *msg; /* incoming rexx messages */
-
- /* did we get something from rexx? */
- while(msg = (struct RexxMsg *)GetMsg(glob->arexxport)){
- /* a rexx macro has sent us a command, deal with it */
- /* THE MESSAGE WILL HAVE BEEN REPLIED INSIDE OF execute_command */
- execute_command(glob, msg);
- }
- }
-
-
- ULONG arexxsigmask(glb glob){
- return (ULONG)1 << glob->arexxport->mp_SigBit;
- }
-
-
- BOOL InitArexx(glb glob){
- struct MsgPort *port;
- char *portname;
-
- if(!glob->userarexxportname){
- /* Find a suitable name for the port. */
- if(!(portname=dosalloc(AREXXPORTMAXLEN+strlen(glob->devname)))){
- debug(("Error: InitArexx(): No memory for port name.\n"));
- OUTOFMEM;
- return FALSE;
- }
- sprintf(portname,AREXXPORTTEMPLATE,glob->devname);
- }else{
- if(!(portname=dosalloc(1+strlen(glob->userarexxportname)))){
- debug(("Error: InitArexx(): No memory for port name.\n"));
- OUTOFMEM;
- return FALSE;
- }
- strcpy(portname, glob->userarexxportname);
- }
- Forbid();
- /* look for someone else that looks just like us! */
- if (FindPort(portname)){
- Permit();
- debug(("A public port called '%s' already exists!\n",portname));
- dosfree(portname);
- glob->ioerr = ERROR_OBJECT_EXISTS;
- return FALSE;
- }
-
- /* allocate the port */
- if(!(port = CreatePort(portname,AREXXPORTPRI))){
- debug(("Error: InitArexx(): Unable to CreatePort().\n"));
- dosfree(portname);
- OUTOFMEM;
- return FALSE;
- }
- Permit();
-
- glob->arexxportname = portname;
- glob->arexxport = port;
- return TRUE;
- }
-
- void CleanupArexx(glb glob){
-
- debug(("Cleaning up Arexx resources..."));
- if(glob->arexxport){
- struct RexxMsg *msg;
-
- /* Careful: reply any pending messages. */
- Forbid();
- while(msg=(struct RexxMsg *)GetMsg(glob->arexxport)){
- reply_rexx_command(msg,20,0,NULL);
- }
- DeletePort(glob->arexxport);
- Permit();
- glob->arexxport = NULL;
- }
- if(glob->arexxportname) dosfree(glob->arexxportname);
- debug(("all cleaned up.\n"));
- }
-
- /* End of arexx.c */
-