2 * Source generated with ARexxBox 1.12 (May 18 1993)
3 * which is Copyright (c) 1992,1993 Michael Balzer
6 #include <exec/types.h>
7 #include <exec/memory.h>
9 #include <rexx/storage.h>
10 #include <rexx/rxslib.h>
13 /* GCC needs all struct defs */
14 #include <dos/exall.h>
15 #include <graphics/graphint.h>
16 #include <intuition/classes.h>
17 #include <devices/keymap.h>
18 #include <exec/semaphores.h>
21 #include <clib/alib_protos.h>
22 #include <clib/exec_protos.h>
23 #include <clib/dos_protos.h>
24 #include <clib/rexxsyslib_protos.h>
29 #include <pragmas/exec_lib.h>
30 #include <pragmas/dos_lib.h>
31 #include <pragmas/rexxsyslib_lib.h>
35 #include <pragmas/exec_pragmas.h>
36 #include <pragmas/dos_pragmas.h>
37 #include <pragmas/rexxsyslib_pragmas.h>
40 #endif /* __NO_PRAGMAS */
49 #define inline __inline
54 static inline int toupper( int c
)
56 return( islower(c
) ? c
- 'a' + 'A' : c
);
64 #include <dos/rdargs.h>
66 #include "MultiView.h"
70 struct rxs_stemnode
*succ
;
76 extern struct ExecBase
*SysBase
;
77 extern struct DosLibrary
*DOSBase
;
78 extern struct RxsLib
*RexxSysBase
;
80 void (*ARexxResultHook
)( struct RexxHost
*, struct RexxMsg
* ) = NULL
;
84 void ReplyRexxCommand(
85 struct RexxMsg
*rexxmessage
,
90 if( rexxmessage
->rm_Action
& RXFF_RESULT
)
95 ? (long) CreateArgstring( result
, strlen(result
) )
104 sprintf( buf
, "%ld", secondary
);
110 result
= (char *) secondary
;
113 SetRexxVar( (struct Message
*) rexxmessage
,
114 "RC2", result
, strlen(result
) );
119 else if( primary
< 0 )
122 rexxmessage
->rm_Result1
= primary
;
123 rexxmessage
->rm_Result2
= secondary
;
124 ReplyMsg( (struct Message
*) rexxmessage
);
128 void FreeRexxCommand( struct RexxMsg
*rexxmessage
)
130 if( !rexxmessage
->rm_Result1
&& rexxmessage
->rm_Result2
)
131 DeleteArgstring( (char *) rexxmessage
->rm_Result2
);
133 if( rexxmessage
->rm_Stdin
&&
134 rexxmessage
->rm_Stdin
!= Input() )
135 Close( rexxmessage
->rm_Stdin
);
137 if( rexxmessage
->rm_Stdout
&&
138 rexxmessage
->rm_Stdout
!= rexxmessage
->rm_Stdin
&&
139 rexxmessage
->rm_Stdout
!= Output() )
140 Close( rexxmessage
->rm_Stdout
);
142 DeleteArgstring( (char *) ARG0(rexxmessage
) );
143 DeleteRexxMsg( rexxmessage
);
147 struct RexxMsg
*CreateRexxCommand( struct RexxHost
*host
, char *buff
, BPTR fh
)
149 struct RexxMsg
*rexx_command_message
;
151 if( (rexx_command_message
= CreateRexxMsg( host
->port
,
152 rexx_extension
, host
->port
->mp_Node
.ln_Name
)) == NULL
)
157 if( (rexx_command_message
->rm_Args
[0] =
158 CreateArgstring(buff
,strlen(buff
))) == NULL
)
160 DeleteRexxMsg(rexx_command_message
);
164 rexx_command_message
->rm_Action
= RXCOMM
| RXFF_RESULT
;
165 rexx_command_message
->rm_Stdin
= fh
;
166 rexx_command_message
->rm_Stdout
= fh
;
168 return( rexx_command_message
);
172 struct RexxMsg
*CommandToRexx( struct RexxHost
*host
, struct RexxMsg
*rexx_command_message
)
174 struct MsgPort
*rexxport
;
178 if( (rexxport
= FindPort(RXSDIR
)) == NULL
)
184 PutMsg( rexxport
, &rexx_command_message
->rm_Node
);
189 return( rexx_command_message
);
193 struct RexxMsg
*SendRexxCommand( struct RexxHost
*host
, char *buff
, BPTR fh
)
197 if( rcm
= CreateRexxCommand(host
, buff
, fh
) )
198 return CommandToRexx( host
, rcm
);
204 void CloseDownARexxHost( struct RexxHost
*host
)
206 struct RexxMsg
*rexxmsg
;
211 RemPort( host
->port
);
213 /* Auf noch ausstehende Replies warten */
214 while( host
->replies
> 0 )
216 WaitPort( host
->port
);
218 while( rexxmsg
= (struct RexxMsg
*) GetMsg(host
->port
) )
220 if( rexxmsg
->rm_Node
.mn_Node
.ln_Type
== NT_REPLYMSG
)
222 if( !rexxmsg
->rm_Args
[15] )
224 /* Reply zu einem SendRexxCommand()-Call */
225 if( ARexxResultHook
)
226 ARexxResultHook( host
, rexxmsg
);
229 FreeRexxCommand( rexxmsg
);
233 ReplyRexxCommand( rexxmsg
, -20, (long) "Host closing down", NULL
);
238 while( rexxmsg
= (struct RexxMsg
*) GetMsg(host
->port
) )
239 ReplyRexxCommand( rexxmsg
, -20, (long) "Host closing down", NULL
);
241 if( !(host
->flags
& ARB_HF_USRMSGPORT
) )
242 DeleteMsgPort( host
->port
);
245 if( host
->rdargs
) FreeDosObject( DOS_RDARGS
, host
->rdargs
);
250 struct RexxHost
*SetupARexxHost( char *basename
, struct MsgPort
*usrport
)
252 struct RexxHost
*host
;
256 basename
= RexxPortBaseName
;
257 else if( !*basename
)
258 basename
= RexxPortBaseName
;
260 if( !(host
= AllocVec(sizeof *host
, MEMF_CLEAR
)) )
263 strcpy( host
->portname
, basename
);
267 host
->port
= usrport
;
268 host
->flags
|= ARB_HF_USRMSGPORT
;
270 else if( !(host
->port
= CreateMsgPort()) )
277 host
->port
->mp_Node
.ln_Pri
= 0;
282 while( FindPort(host
->portname
) )
283 sprintf( host
->portname
, "%s.%d", basename
, ++ext
);
285 host
->port
->mp_Node
.ln_Name
= host
->portname
;
286 AddPort( host
->port
);
290 if( !(host
->rdargs
= AllocDosObject(DOS_RDARGS
, NULL
)) )
292 RemPort( host
->port
);
293 if( !usrport
) DeleteMsgPort( host
->port
);
298 host
->rdargs
->RDA_Flags
= RDAF_NOPROMPT
;
304 /* StateMachine für FindRXCommand() */
306 static inline char *scmp( char *inp
, char *str
)
308 while( *str
&& *inp
)
309 if( *inp
++ != *str
++ )
312 /* Reststring zurückgeben */
316 static int find( char *input
)
318 struct arb_p_state
*st
= arb_p_state
;
319 struct arb_p_link
*ad
;
320 char *ni
, tmp
[36], *s
;
323 while( *input
&& ni
-tmp
< 32 )
324 *ni
++ = toupper( *input
++ );
330 /* Terminalzustand erreicht? */
339 /* Wo geht's weiter? */
341 for( ad
= st
->pa
; s
= ad
->str
; ad
++ )
343 /* die Links sind absteigend sortiert */
348 if( ni
= scmp(input
+1, s
+1) )
356 /* Zustandsüberführung */
357 st
= arb_p_state
+ ad
->dst
;
364 struct rxs_command
*FindRXCommand( char *com
)
373 return( rxs_commandlist
+ cmd
);
377 static struct rxs_command
*ParseRXCommand( char **arg
)
379 char com
[256], *s
, *t
;
384 while( *s
&& *s
!= ' ' && *s
!= '\n' )
388 while( *s
== ' ' ) ++s
;
391 return( FindRXCommand( com
) );
395 static char *CreateVAR( struct rxs_stemnode
*stem
)
398 struct rxs_stemnode
*s
;
401 if( !stem
|| stem
== (struct rxs_stemnode
*) -1L )
402 return( (char *) stem
);
404 for( s
= stem
; s
; s
= s
->succ
)
405 size
+= strlen( s
->value
) + 1;
407 if( !(var
= AllocVec( size
+ 1, MEMF_ANY
)) )
408 return( (char *) -1 );
412 for( s
= stem
; s
; s
= s
->succ
)
414 strcat( var
, s
->value
);
423 static struct rxs_stemnode
*new_stemnode( struct rxs_stemnode
**first
, struct rxs_stemnode
**old
)
425 struct rxs_stemnode
*new;
427 if( !(new = AllocVec(sizeof(struct rxs_stemnode
), MEMF_CLEAR
)) )
448 static void free_stemlist( struct rxs_stemnode
*first
)
450 struct rxs_stemnode
*next
;
452 if( (long) first
== -1 )
455 for( ; first
; first
= next
)
458 if( first
->name
) FreeVec( first
->name
);
459 if( first
->value
) FreeVec( first
->value
);
465 char *StrDup( char *s
)
467 char *t
= AllocVec( strlen(s
)+1, MEMF_ANY
);
468 if( t
) strcpy( t
, s
);
473 static struct rxs_stemnode
*CreateSTEM( struct rxs_command
*rxc
, LONG
*resarray
, char *stembase
)
475 struct rxs_stemnode
*first
= NULL
, *old
= NULL
, *new;
476 char resb
[512], *rs
, *rb
;
483 *rb
++ = toupper( *stembase
++ );
487 rb
= resb
+ strlen(resb
);
493 BOOL optn
= FALSE
, optm
= FALSE
;
495 while( *rs
&& *rs
!= ',' )
500 if( *rs
== 'N' ) optn
= TRUE
;
501 else if( *rs
== 'M' ) optm
= TRUE
;
509 if( *rs
== ',' ) ++rs
;
513 * Resultat(e) erzeugen
525 LONG
**subarray
= (LONG
**) *resarray
++;
526 struct rxs_stemnode
*countnd
;
528 /* Anzahl der Elemente */
530 if( !(new = new_stemnode(&first
, &old
)) )
532 free_stemlist( first
);
533 return( (struct rxs_stemnode
*) -1L );
537 /* Die Elemente selbst */
539 while( r
= *subarray
++ )
541 if( !(new = new_stemnode(&first
, &old
)) )
543 free_stemlist( first
);
544 return( (struct rxs_stemnode
*) -1L );
547 sprintf( t
, ".%ld", index
++ );
548 new->name
= StrDup( resb
);
552 sprintf( longbuff
, "%ld", *r
);
553 new->value
= StrDup( longbuff
);
557 new->value
= StrDup( (char *) r
);
563 strcpy( t
, ".COUNT" );
564 countnd
->name
= StrDup( resb
);
566 sprintf( longbuff
, "%ld", index
);
567 countnd
->value
= StrDup( longbuff
);
571 /* Neue Node anlegen */
572 if( !(new = new_stemnode(&first
, &old
)) )
574 free_stemlist( first
);
575 return( (struct rxs_stemnode
*) -1L );
578 new->name
= StrDup( resb
);
582 sprintf( longbuff
, "%ld", *((long *) *resarray
) );
583 new->value
= StrDup( longbuff
);
588 new->value
= StrDup( (char *) (*resarray
++) );
597 static void DoRXCommand( struct RexxHost
*host
, struct RexxMsg
*rexxmsg
)
599 struct rxs_command
*rxc
;
606 char *cargstr
= NULL
;
610 if( !(argb
= AllocVec(strlen((char *) ARG0(rexxmsg
)) + 2, MEMF_ANY
)) )
612 rc2
= ERROR_NO_FREE_STORE
;
616 /* welches Kommando? */
618 strcpy( argb
, (char *) ARG0(rexxmsg
) );
619 strcat( argb
, "\n" );
622 if( !( rxc
= ParseRXCommand( &arg
) ) )
624 if( arg
= ExpandRXCommand( host
, (char *) ARG0(rexxmsg
) ) )
627 if( !(argb
= AllocVec( strlen(arg
) + 2, MEMF_ANY
)) )
629 rc2
= ERROR_NO_FREE_STORE
;
634 strcat( argb
, "\n" );
638 rxc
= ParseRXCommand( &arg
);
644 /* Msg an ARexx schicken, vielleicht existiert ein Skript */
647 if( rm
= CreateRexxCommand(host
, (char *) ARG0(rexxmsg
), NULL
) )
649 /* Original-Msg merken */
650 rm
->rm_Args
[15] = (STRPTR
) rexxmsg
;
652 if( CommandToRexx(host
, rm
) )
654 /* Reply wird später vom Dispatcher gemacht */
655 if( argb
) FreeVec( argb
);
659 rc2
= ERROR_NOT_IMPLEMENTED
;
662 rc2
= ERROR_NO_FREE_STORE
;
667 if( !(rxc
->flags
& ARB_CF_ENABLED
) )
670 rc2
= (long) "Command disabled";
674 /* Speicher für Argumente etc. holen */
676 (rxc
->function
)( host
, (void **) &array
, RXIF_INIT
, rexxmsg
);
677 cargstr
= AllocVec( rxc
->args
? 15+strlen(rxc
->args
) : 15, MEMF_ANY
);
679 if( !array
|| !cargstr
)
681 rc2
= ERROR_NO_FREE_STORE
;
685 argarray
= array
+ 2;
686 resarray
= array
+ rxc
->resindex
;
688 /* Argumente parsen */
691 strcpy( cargstr
, "VAR/K,STEM/K" );
698 strcat( cargstr
, "," );
699 strcat( cargstr
, rxc
->args
);
704 host
->rdargs
->RDA_Source
.CS_Buffer
= arg
;
705 host
->rdargs
->RDA_Source
.CS_Length
= strlen(arg
);
706 host
->rdargs
->RDA_Source
.CS_CurChr
= 0;
707 host
->rdargs
->RDA_DAList
= NULL
;
708 host
->rdargs
->RDA_Buffer
= NULL
;
710 if( !ReadArgs(cargstr
, argarray
, host
->rdargs
) )
718 /* Funktion aufrufen */
720 (rxc
->function
)( host
, (void **) &array
, RXIF_ACTION
, rexxmsg
);
725 /* Resultat(e) auswerten */
727 if( rxc
->results
&& rc
==0 &&
728 (rexxmsg
->rm_Action
& RXFF_RESULT
) )
730 struct rxs_stemnode
*stem
, *s
;
732 stem
= CreateSTEM( rxc
, resarray
, (char *)argarray
[1] );
733 result
= CreateVAR( stem
);
740 if( (long) result
== -1 )
743 rc2
= ERROR_NO_FREE_STORE
;
749 for( rb
= (char *) argarray
[0]; *rb
; ++rb
)
750 *rb
= toupper( *rb
);
752 if( SetRexxVar( (struct Message
*) rexxmsg
,
753 *((char *)argarray
[0]) ? (char *)argarray
[0] : "RESULT",
754 result
, strlen(result
) ) )
757 rc2
= (long) "Unable to set Rexx variable";
766 if( !rc
&& argarray
[1] )
769 if( (long) stem
== -1 )
772 rc2
= ERROR_NO_FREE_STORE
;
776 for( s
= stem
; s
; s
= s
->succ
)
777 rc
|= SetRexxVar( (struct Message
*) rexxmsg
, s
->name
, s
->value
, strlen(s
->value
) );
782 rc2
= (long) "Unable to set Rexx variable";
785 if( result
&& (long) result
!= -1 )
792 /* Normales Resultat: Möglich? */
794 if( (long) result
== -1 )
798 rc2
= ERROR_NO_FREE_STORE
;
803 free_stemlist( stem
);
808 /* Nur RESULT, wenn weder VAR noch STEM */
810 ReplyRexxCommand( rexxmsg
, rc
, rc2
, result
);
812 /* benutzten Speicher freigeben */
814 if( result
) FreeVec( result
);
815 FreeArgs( host
->rdargs
);
816 if( cargstr
) FreeVec( cargstr
);
817 if( array
) (rxc
->function
)( host
, (void **) &array
, RXIF_FREE
, rexxmsg
);
818 if( argb
) FreeVec( argb
);
822 void ARexxDispatch( struct RexxHost
*host
)
824 struct RexxMsg
*rexxmsg
;
826 while( rexxmsg
= (struct RexxMsg
*) GetMsg(host
->port
) )
828 if( (rexxmsg
->rm_Action
& RXCODEMASK
) != RXCOMM
)
830 /* Keine Rexx-Message */
831 ReplyMsg( (struct Message
*) rexxmsg
);
833 else if( rexxmsg
->rm_Node
.mn_Node
.ln_Type
== NT_REPLYMSG
)
835 struct RexxMsg
*org
= (struct RexxMsg
*) rexxmsg
->rm_Args
[15];
839 /* Reply zu durchgereichter Msg */
840 if( rexxmsg
->rm_Result1
!= 0 )
842 /* Befehl unbekannt */
843 ReplyRexxCommand( org
, 20, ERROR_NOT_IMPLEMENTED
, NULL
);
847 ReplyRexxCommand( org
, 0, 0, (char *) rexxmsg
->rm_Result2
);
852 /* Reply zu einem SendRexxCommand()-Call */
853 if( ARexxResultHook
)
854 ARexxResultHook( host
, rexxmsg
);
857 FreeRexxCommand( rexxmsg
);
860 else if( ARG0(rexxmsg
) )
862 DoRXCommand( host
, rexxmsg
);
866 ReplyMsg( (struct Message
*) rexxmsg
);