1 #include <proto/alib.h>
3 #include <proto/exec.h>
4 #include <proto/intuition.h>
5 #include <proto/regina.h>
6 #include <proto/rexxsyslib.h>
8 #include <rexx/rexxcall.h>
9 #include <exec/ports.h>
10 #include <exec/memory.h>
11 #include <intuition/intuition.h>
12 #include <dos/dosextens.h>
13 #include <dos/dostags.h>
14 #include <rexx/storage.h>
15 #include <rexx/errors.h>
16 #include <rexx/rxslib.h>
24 #include <aros/debug.h>
26 static LONG
StartFile(struct RexxMsg
*);
27 static void StartFileSlave(struct RexxMsg
*);
28 static void AddLib(struct RexxMsg
*);
29 static void RemLib(struct RexxMsg
*);
30 static void AddCon(struct RexxMsg
*);
31 static void RemCon(struct RexxMsg
*);
33 static UBYTE progdir
[256];
35 int main(int argc
, char **argv
)
42 struct EasyStruct es
=
44 sizeof(struct EasyStruct
),
51 if (argc
==3 && strcmp("SUBTASK", argv
[1])==0)
55 sscanf(argv
[2], "%p", &msg
);
57 ReplyMsg((struct Message
*)msg
);
62 lock
= Lock("PROGDIR:", SHARED_LOCK
);
63 NameFromLock(lock
, progdir
, sizeof(progdir
));
64 D(bug("Got PROGDIR:='%s'\n", progdir
));
67 port
= CreatePort("REXX", 0);
68 es
.es_Title
= "RexxMast message";
69 mask
= SIGBREAKF_CTRL_C
| (1<<port
->mp_SigBit
);
73 if (signals
& SIGBREAKF_CTRL_C
)
75 if (signals
& (1<<port
->mp_SigBit
))
77 while ((msg
= (struct RexxMsg
*)GetMsg(port
)) != NULL
)
84 es
.es_TextFormat
= "Received message that is not a Rexx message";
85 EasyRequest(NULL
, &es
, NULL
);
89 static UBYTE
*text
[] =
90 { "RXCOMM", "RXFUNC", "RXCLOSE", "RXQUERY", "UNKNOWN1",
91 "UNKNOWN2", "RXADDFH", "RXADDLIB", "RXREMLIB",
92 "RXADDCON", "RXREMCON", "RXTCOPN", "RXTCCLS",
95 LONG action
= msg
->rm_Action
& RXCODEMASK
;
96 D(bug("Got message with action %x\n", action
));
101 if (StartFile(msg
) < 0)
103 D(bug("Error executing command '%s'\n", (char *)msg
->rm_Args
[0]));
104 msg
->rm_Result1
= RC_ERROR
;
105 msg
->rm_Result2
= (IPTR
)ERR10_100
;
109 D(bug("Command '%s' executed\n", (char *)msg
->rm_Args
[0]));
136 if (!IsReginaMsg(msg
))
138 msg
->rm_Result1
= RC_ERROR
;
139 msg
->rm_Result2
= (IPTR
)ERR10_010
;
141 else if (action
==RXCHECKMSG
)
143 msg
->rm_Result1
= RC_OK
;
147 /* Forward to the appropriate port */
148 PutMsg( (struct MsgPort
*)msg
->rm_Private1
, (struct Message
*)msg
);
156 es
.es_TextFormat
= "Rexx message with command \"%s\" received";
157 if (action
<= RXTCCLS
)
158 EasyRequest(NULL
, &es
, NULL
, text
[(action
>> 24) - 1]);
160 EasyRequest(NULL
, &es
, NULL
, text
[(RXTCCLS
>> 24)]);
166 D(bug("Replying message\n"));
167 ReplyMsg((struct Message
*)msg
);
170 D(bug("Not replying to message\n"));
180 static LONG
StartFile(struct RexxMsg
*msg
)
184 sprintf(text
, "\"%s%sRexxMast\" SUBTASK %p", progdir
,
185 progdir
[strlen(progdir
)-1] == ':' ? "" : "/",
189 /* FIXME: thread should be used to handle more then one message at a time, not SystemTags */
190 return SystemTags(text
, SYS_Asynch
, TRUE
, SYS_Input
, NULL
,
191 SYS_Output
, NULL
, TAG_DONE
195 static void StartFileSlave(struct RexxMsg
*msg
)
197 UBYTE
*comm
= (UBYTE
*)msg
->rm_Args
[0];
198 BPTR lock
, oldlock
= BNULL
;
199 unsigned int len
=0, extlen
, commlen
= LengthArgstring(comm
);
200 BPTR input
= BNULL
, output
= BNULL
, error
= BNULL
;
201 struct Process
*process
= (struct Process
*)msg
->rm_Node
.mn_ReplyPort
->mp_SigTask
;
203 /* Input arguments for calling the RexxStart procedure */
205 RXSTRING rxargs
[15], rxresult
;
207 PRXSTRING instore
= NULL
;
210 /* Set input/output to the task that sent the message */
211 if (!(msg
->rm_Action
& RXFF_NOIO
))
215 if (process
->pr_Task
.tc_Node
.ln_Type
== NT_PROCESS
)
217 input
= process
->pr_CIS
;
218 output
= process
->pr_COS
;
219 error
= process
->pr_CES
;
220 lock
= DupLock(process
->pr_CurrentDir
);
223 lock
= CurrentDir(lock
);
224 oldlock
= DupLock(lock
);
228 if (msg
->rm_Stdin
!= BNULL
)
229 input
= msg
->rm_Stdin
;
230 if (msg
->rm_Stdout
!= BNULL
)
231 output
= msg
->rm_Stdout
;
233 input
= SelectInput(input
);
234 output
= SelectOutput(output
);
235 error
= SelectErrorOutput(error
);
239 if ((msg
->rm_Action
& RXFF_STRING
))
243 progname
= strdup("intern");
244 instore
= malloc(2*sizeof(RXSTRING
));
246 memcpy(t
, comm
, commlen
);
247 MAKERXSTRING(instore
[0], t
, commlen
);
248 MAKERXSTRING(instore
[1], NULL
, 0);
250 else if (comm
[0] == '\'' || comm
[0] == '"')
256 for (i
= 1; comm
[i
] != c
&& i
< commlen
; i
++)
259 progname
= strdup("intern");
260 instore
= malloc(2*sizeof(RXSTRING
));
262 memcpy(t
, comm
+ 1, i
- 1);
263 MAKERXSTRING(instore
[0], t
, i
-1);
264 MAKERXSTRING(instore
[1], NULL
, 0);
268 BOOL iscommand
= ((msg
->rm_Action
& RXCODEMASK
) == RXCOMM
);
273 /* For a command the characters up to the first space is the progname */
274 while (*s
!= 0 && !isspace(*s
)) s
++;
279 /* For a function whole ARG0 is the progname */
280 len
= LengthArgstring((UBYTE
*)msg
->rm_Args
[0]);
283 extlen
= msg
->rm_FileExt
==NULL
? 5 : strlen(msg
->rm_FileExt
);
284 progname
= malloc(len
+ 6 + extlen
);
286 memcpy(progname
, (char *)msg
->rm_Args
[0], len
);
288 lock
= Lock(progname
, ACCESS_READ
);
291 strcat(progname
, msg
->rm_FileExt
==NULL
? ".rexx" : (const char *)msg
->rm_FileExt
);
292 lock
= Lock(progname
, ACCESS_READ
);
294 if (lock
== BNULL
&& strchr(progname
, ':') == NULL
)
296 strcpy(progname
, "REXX:");
297 strncat(progname
, (char *)msg
->rm_Args
[0], len
);
298 lock
= Lock(progname
, ACCESS_READ
);
302 strcat(progname
, msg
->rm_FileExt
==NULL
? ".rexx" : (const char *)msg
->rm_FileExt
);
303 lock
= Lock(progname
, ACCESS_READ
);
310 if (oldlock
!= BNULL
)
311 UnLock(CurrentDir(oldlock
));
321 if (!(msg
->rm_Action
& RXFF_TOKEN
))
328 len
= LengthArgstring((UBYTE
*)msg
->rm_Args
[0]) - (s
- (UBYTE
*)msg
->rm_Args
[0]);
329 MAKERXSTRING(rxargs
[0], s
, len
);
338 while((*s2
!= 0) && !isspace(*s2
)) s2
++;
339 MAKERXSTRING(rxargs
[argcount
], s
, s2
-s
);
341 while((*s2
!= 0) && isspace(*s2
) ) s2
++;
347 else /* is a function call */
349 int arguments
= msg
->rm_Action
& RXARGMASK
;
351 for (argcount
= 0; argcount
< arguments
; argcount
++)
353 UBYTE
*argstr
= (UBYTE
*)msg
->rm_Args
[1+argcount
];
355 MAKERXSTRING(rxargs
[argcount
], NULL
, 0);
357 MAKERXSTRING(rxargs
[argcount
], argstr
, LengthArgstring(argstr
));
362 MAKERXSTRING(rxresult
, NULL
, 0);
363 D(bug("[RexxMast/StartFileSlave()] Executing '%s'\n", progname
));
364 RexxStart(argcount
, rxargs
, progname
, instore
, msg
->rm_CommAddr
, RXFUNCTION
, NULL
, &rc
, &rxresult
);
365 D(bug("[RexxMast/StartFileSlave()] Return rc=%d, rxresult='%s'\n",
368 /* Return to the old input/output if it was changed */
369 if (!(msg
->rm_Action
& RXFF_NOIO
))
374 SelectOutput(output
);
376 SelectErrorOutput(error
);
378 if (oldlock
!= BNULL
)
379 UnLock(CurrentDir(oldlock
));
383 msg
->rm_Result1
= rc
;
384 if (rc
==0 && (msg
->rm_Action
& RXFF_RESULT
) && RXVALIDSTRING(rxresult
))
385 msg
->rm_Result2
= (IPTR
)CreateArgstring(RXSTRPTR(rxresult
), RXSTRLEN(rxresult
));
389 if (RXSTRPTR(rxresult
) != NULL
)
390 free(RXSTRPTR(rxresult
));
391 if (progname
!= NULL
)
395 free(RXSTRPTR(instore
[0]));
400 static void AddLib(struct RexxMsg
*msg
)
402 struct RexxRsrc
*rsrc
;
404 if (msg
->rm_Args
[0] == 0 || msg
->rm_Args
[1] == 0)
406 msg
->rm_Result1
= 20;
411 rsrc
= (struct RexxRsrc
*)AllocMem(sizeof(struct RexxRsrc
), MEMF_ANY
| MEMF_CLEAR
);
412 rsrc
->rr_Size
= sizeof(struct RexxRsrc
);
413 rsrc
->rr_Node
.ln_Pri
= atoi((char *)msg
->rm_Args
[1]);
414 rsrc
->rr_Node
.ln_Name
= CreateArgstring((UBYTE
*)msg
->rm_Args
[0], strlen((char *)msg
->rm_Args
[0]));
416 if ((msg
->rm_Action
& RXCODEMASK
) == RXADDLIB
)
418 rsrc
->rr_Node
.ln_Type
= RRT_LIB
;
419 if (msg
->rm_Args
[2] == 0)
421 msg
->rm_Result1
= 20;
423 FreeMem(rsrc
, rsrc
->rr_Size
);
426 rsrc
->rr_Arg1
= (LONG
)atoi((char *)msg
->rm_Args
[2]);
427 rsrc
->rr_Arg2
= (msg
->rm_Args
[3] == 0) ? (LONG
)0 : (LONG
)atoi((char *)msg
->rm_Args
[3]);
430 rsrc
->rr_Node
.ln_Type
= RRT_HOST
;
433 if (FindName(&RexxSysBase
->rl_LibList
, rsrc
->rr_Node
.ln_Name
))
437 FreeMem(rsrc
, rsrc
->rr_Size
);
441 Enqueue(&RexxSysBase
->rl_LibList
, (struct Node
*)rsrc
);
444 RexxSysBase
->rl_NumLib
++;
449 static void RemLib(struct RexxMsg
*msg
)
451 struct RexxRsrc
*rsrc
;
453 if (msg
->rm_Args
[0] == 0)
455 msg
->rm_Result1
= 20;
461 rsrc
= (struct RexxRsrc
*)FindName(&RexxSysBase
->rl_LibList
, (STRPTR
)msg
->rm_Args
[0]);
469 Remove((struct Node
*)rsrc
);
470 RexxSysBase
->rl_NumLib
--;
471 DeleteArgstring(rsrc
->rr_Node
.ln_Name
);
472 FreeMem(rsrc
, rsrc
->rr_Size
);
479 static void AddCon(struct RexxMsg
*msg
)
481 struct RexxRsrc
*rsrc
;
484 rsrc
= (struct RexxRsrc
*)FindName(&RexxSysBase
->rl_ClipList
, (char *)msg
->rm_Args
[0]);
487 rsrc
= (struct RexxRsrc
*)AllocMem(sizeof(struct RexxRsrc
), MEMF_ANY
| MEMF_CLEAR
);
488 rsrc
->rr_Node
.ln_Type
= RRT_CLIP
;
489 rsrc
->rr_Node
.ln_Name
= CreateArgstring((UBYTE
*)msg
->rm_Args
[0], strlen((char *)msg
->rm_Args
[0]));
490 rsrc
->rr_Size
= sizeof(struct RexxRsrc
);
491 rsrc
->rr_Arg1
= (IPTR
)CreateArgstring((UBYTE
*)msg
->rm_Args
[1], (ULONG
)msg
->rm_Args
[2]);
493 AddTail(&RexxSysBase
->rl_ClipList
, (struct Node
*)rsrc
);
497 DeleteArgstring((UBYTE
*)rsrc
->rr_Arg1
);
498 rsrc
->rr_Arg1
= (IPTR
)CreateArgstring((UBYTE
*)msg
->rm_Args
[1], (ULONG
)msg
->rm_Args
[2]);
507 static void RemCon(struct RexxMsg
*msg
)
509 struct RexxRsrc
*rsrc
;
512 rsrc
= (struct RexxRsrc
*)FindName(&RexxSysBase
->rl_ClipList
, (STRPTR
)msg
->rm_Args
[0]);
519 Remove(&rsrc
->rr_Node
);
520 DeleteArgstring(rsrc
->rr_Node
.ln_Name
);
521 DeleteArgstring((UBYTE
*)rsrc
->rr_Arg1
);
522 FreeMem(rsrc
, rsrc
->rr_Size
);