2 * Copyright (C) 2012, The AROS Development Team. All rights reserved.
3 * Author: Jason S. McMullan <jason.mcmullan@gmail.com>
5 * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1
7 /******************************************************************************
23 Uses the _pchar and _mchar environment variables to split
24 the COMMAND into fragments.
26 Where _pchar is seen, the commands on either side are connected
27 with a PIPE: from the left side's Output() to the right side's Input().
29 Where _mchar is seen, the commands are executed in sequence, with
30 no PIPE: between them, and Input() and Output() comes from the
35 COMMAND -- the command to execute
41 The "_pchar" and "_mchar" environment variables are used to determine
42 where to split the command, and what action to perform.
48 > echo Hello ; echo World
51 > Type S:Startup-Sequence | Sort
55 Note that _pchar and _mchar are limited to 2 characters - any
56 additional characters will be silently ignored.
64 ******************************************************************************/
68 #include <aros/debug.h>
69 #include <exec/execbase.h>
70 #include <exec/libraries.h>
71 #include <proto/exec.h>
73 #include <proto/dos.h>
75 #include <aros/shcommands.h>
77 static inline STRPTR
NextToken(STRPTR
*pstr
, CONST_STRPTR tok
)
79 STRPTR str
, ostr
= *pstr
;
80 int toklen
= strlen(tok
);
85 for (str
= ostr
; *str
; str
++) {
86 if (strncmp(str
, tok
, toklen
) == 0) {
94 /* Token not found? */
95 *pstr
= ostr
+ strlen(ostr
);
99 static BOOL
Pipe(struct Library
*DOSBase
, BPTR pipe
[2])
101 pipe
[1]=Open("PIPE:*", MODE_NEWFILE
);
104 if (NameFromFH(pipe
[1], buff
, sizeof(buff
)) != 0) {
105 pipe
[0] = Open(buff
, MODE_OLDFILE
);
114 static LONG
pcharExecute(struct Library
*DOSBase
, STRPTR cmd
, CONST_STRPTR pchar
, BPTR in
, BPTR out
)
116 STRPTR leftcmd
, rightcmd
;
119 LONG ret
= RETURN_FAIL
;
121 leftcmd
= NextToken(&cmd
, pchar
);
126 if (*rightcmd
== 0) {
127 /* No pipe character? */
128 return SystemTags(leftcmd
, SYS_Input
, in
, SYS_Output
, out
, TAG_END
);
131 if (Pipe(DOSBase
, pipe
)) {
132 BPTR cis
= OpenFromLock(DupLockFromFH(in
));
134 struct TagItem tags
[] = {
135 { SYS_Input
, (IPTR
)cis
},
136 { SYS_Output
, (IPTR
)pipe
[1] },
137 { SYS_Asynch
, TRUE
},
141 if (SystemTagList(leftcmd
, tags
) == -1) {
142 PrintFault(IoErr(), leftcmd
);
149 ret
= pcharExecute(DOSBase
, rightcmd
, pchar
, pipe
[0], out
);
151 while (FGets(pipe
[0], buff
, sizeof buff
) != NULL
);
160 AROS_SHA(STRPTR
, , , /F
, ""))
163 CONST_STRPTR cmd
= SHArg( );
164 struct CommandLineInterface
*cli
= Cli();
166 TEXT pchar
[3], mchar
[3];
167 LONG len
, ret
= RETURN_FAIL
;
168 STRPTR tcmd
, subcmd
, cp
;
170 len
= GetVar("_pchar", pchar
, sizeof pchar
, GVF_LOCAL_ONLY
| LV_VAR
);
175 len
= GetVar("_mchar", mchar
, sizeof mchar
, GVF_LOCAL_ONLY
| LV_VAR
);
180 /* Tokenize by mchar, if needed */
181 len
= strlen(cmd
) + 1;
182 if ((tcmd
= AllocVec(len
, MEMF_ANY
))) {
183 CopyMem(cmd
, tcmd
, len
);
186 for (subcmd
= NextToken(&cp
, mchar
); subcmd
; subcmd
= NextToken(&cp
, mchar
)) {
187 ret
= pcharExecute((struct Library
*)DOSBase
, subcmd
, pchar
, Input(), Output());
188 if (ret
>= cli
->cli_FailLevel
)