Added usage, MorphOS port
[AROS.git] / workbench / rexxc / RX.c
blobc355d1ade4a218019e5692eff42dad6868a67596
1 /*
2 Copyright © 2007-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Run rexx scripts
6 */
8 #include <dos/dos.h>
9 #include <dos/dosextens.h>
10 #include <dos/dostags.h>
11 #include <rexx/storage.h>
12 #include <rexx/errors.h>
13 #include <workbench/startup.h>
15 #include <proto/exec.h>
16 #include <proto/dos.h>
17 #include <proto/rexxsyslib.h>
18 #include <proto/alib.h>
20 #include <string.h>
21 #include <ctype.h>
23 #ifndef __AROS__
24 #define IPTR void *
25 #endif
27 static struct RexxMsg *msg = NULL;
28 static struct MsgPort *rexxport = NULL, *replyport = NULL;
29 static BPTR out;
30 static BOOL closestdout = FALSE;
31 static BPTR olddir = (BPTR)-1;
33 static BOOL init(void)
35 #ifdef __AROS__
36 out = ErrorOutput();
37 #else
38 out = Output();
39 #endif
41 rexxport = FindPort("REXX");
42 if (rexxport == NULL)
44 if (SystemTags("RexxMast", SYS_Asynch, TRUE, TAG_DONE) >= 0)
46 SystemTags("WaitForPort REXX", TAG_DONE);
49 rexxport = FindPort("REXX");
50 if (rexxport == NULL)
52 FPuts(out, "Could not start RexxMast\n");
53 return FALSE;
56 replyport = CreatePort(NULL, 0);
57 if (replyport == NULL)
59 FPuts(out, "Could not create a port\n");
60 return FALSE;
63 msg = CreateRexxMsg(replyport, NULL, NULL);
64 if (msg == NULL)
66 FPuts(out, "Could not create RexxMsg\n");
67 return FALSE;
69 msg->rm_Action = RXCOMM | RXFF_RESULT;
70 msg->rm_Stdin = Input();
71 msg->rm_Stdout = Output();
73 return TRUE;
76 void cleanup(void)
78 if (closestdout)
79 Close(msg->rm_Stdout);
80 if (msg)
81 DeleteRexxMsg(msg);
82 if (replyport)
83 DeletePort(replyport);
84 if (olddir != (BPTR)-1)
85 CurrentDir(olddir);
88 int main(int argc, char **argv)
90 struct RexxMsg *reply;
91 int ret;
93 if (!init())
95 cleanup();
96 return RC_ERROR;
99 if (argc == 1)
101 FPuts(out, "Usage: RX <filename> [arguments]\n"
102 " RX \"commands\"\n");
103 cleanup();
104 return RC_ERROR;
107 if (argc == 0)
109 struct WBStartup *startup = (struct WBStartup *) argv;
110 char *s = startup->sm_ArgList[1].wa_Name;
112 if (startup->sm_NumArgs < 2)
114 cleanup();
115 return RC_ERROR;
118 olddir = CurrentDir(startup->sm_ArgList[1].wa_Lock);
119 out = msg->rm_Stdout = Open("CON:////RX Output/CLOSE/WAIT/AUTO", MODE_READWRITE);
120 closestdout = TRUE;
122 msg->rm_Args[0] = (IPTR)CreateArgstring(s, strlen(s));
123 msg->rm_Action |= 1;
125 else
127 UBYTE *s;
128 struct Process *me = (struct Process *)FindTask(NULL);
129 ULONG length = 0;
131 s = me->pr_Arguments;
132 while(isspace(*s)) s++;
134 if (*s == '"')
136 s++;
137 while((s[length] != '"') && (s[length] != '\0')) length++;
138 if (length == 0)
140 FPuts(out, "Empty command\n");
141 cleanup();
142 return RC_ERROR;
144 if (s[length] == '\0')
146 FPuts(out, "Unterminated string\n");
147 cleanup();
148 return RC_ERROR;
151 msg->rm_Args[0] = (IPTR)CreateArgstring(s, length);
152 /* It is a literal command with 1 argument */
153 msg->rm_Action |= (RXFF_STRING | 1);
155 else if (*s == '\'')
157 s++;
158 while((s[length] != '\'')
159 && (s[length] != '\0')
160 && (s[length] != '\n')
162 length++;
164 msg->rm_Args[0] = (IPTR)CreateArgstring(s, length);
165 /* It is a literal command with 1 argument */
166 msg->rm_Action |= (RXFF_STRING | 1);
168 else
170 if (s[strlen(s)-1] == '\n')
171 s[strlen(s)-1] = '\0';
173 msg->rm_Args[0] = (IPTR)CreateArgstring(s, strlen(s));
174 msg->rm_Action |= 1;
179 PutMsg(rexxport, (struct Message *)msg);
180 do {
181 reply = (struct RexxMsg *)WaitPort(replyport);
182 } while (reply != msg);
184 ret = msg->rm_Result1;
185 if (msg->rm_Result1 == RC_OK)
186 FPrintf(out, "Script executed and returned: %ld\n", msg->rm_Result2);
187 else
188 FPrintf(out, "Error executing script %ld/%ld\n",
189 msg->rm_Result1, msg->rm_Result2
192 ClearRexxMsg(msg, msg->rm_Action & RXARGMASK);
193 cleanup();
195 return ret;