#include "precomp.h" -> #include <precomp.h>
[reactos.git] / reactos / subsys / system / cmd / redir.c
1 /*
2 * REDIR.C - redirection handling.
3 *
4 *
5 * History:
6 *
7 * 12/15/95 (Tim Norman)
8 * started.
9 *
10 * 12 Jul 98 (Hans B Pufal)
11 * Rewrote to make more efficient and to conform to new command.c
12 * and batch.c processing.
13 *
14 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
15 * Added config.h include
16 *
17 * 22-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
18 * Unicode safe!
19 * Added new error redirection "2>" and "2>>".
20 *
21 * 26-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
22 * Added new error AND output redirection "&>" and "&>>".
23 *
24 * 24-Jun-2005 (Brandon Turner <turnerb7@msu.edu>)
25 * simple check to fix > and | bug with 'rem'
26 */
27
28 #include <precomp.h>
29
30 #ifdef FEATURE_REDIRECTION
31
32
33 static BOOL
34 IsRedirection (TCHAR c)
35 {
36 return (c == _T('<')) || (c == _T('>')) || (c == _T('|'));
37 }
38
39
40 /*
41 * Gets the redirection info from the command line and copies the
42 * file names into ifn, ofn and efn removing them from the command
43 * line.
44 *
45 * Converts remaining command line into a series of null terminated
46 * strings defined by the pipe char '|'. Each string corresponds
47 * to a single executable command. A double null terminates the
48 * command strings.
49 *
50 * Return number of command strings found.
51 *
52 */
53
54 INT GetRedirection (LPTSTR s, LPTSTR ifn, LPTSTR ofn, LPTSTR efn, LPINT lpnFlags)
55 {
56 INT num = 1;
57 LPTSTR dp = s;
58 LPTSTR sp = s;
59
60 #ifdef INCLUDE_CMD_REM
61
62 TCHAR * line = s;
63
64
65 while (_istspace (*line))
66 line++;
67
68 /*first thing first. check to see if this is "rem" and hope out*/
69 if(!_tcsncmp (line, _T("rem "), 4))
70 {
71 lpnFlags = 0;
72 *ifn=('\0');
73 *ofn=('\0');
74 *efn=_T('\0');
75 return 1;
76 }
77 #endif
78 /* find and remove all the redirections first */
79 while (*sp)
80 {
81 if ((*sp == _T('"')) || (*sp == _T('\'')))
82 {
83 /* No redirects inside quotes */
84 TCHAR qc = *sp;
85
86 do
87 *dp++ = *sp++;
88 while (*sp && *sp != qc);
89
90 *dp++ = *sp++;
91 }
92 else if ((*sp == _T('<')) || (*sp == _T('>')) ||
93 (*sp == _T('2')) || (*sp == _T('&')))
94 {
95 /* MS-DOS ignores multiple redirection symbols and uses the last */
96 /* redirection, so we'll emulate that and not check */
97
98 if (*sp == _T('<'))
99 {
100 /* input redirection */
101 *lpnFlags |= INPUT_REDIRECTION;
102 do sp++;
103 while( _istspace (*sp) );
104
105 /* copy file name */
106 while (*sp && !IsRedirection (*sp) && !_istspace (*sp))
107 *ifn++ = *sp++;
108 *ifn = _T('\0');
109 }
110 else if (*sp == _T('>'))
111 {
112 /* output redirection */
113 *lpnFlags |= OUTPUT_REDIRECTION;
114 sp++;
115
116 /* append request ? */
117 if (*sp == _T('>'))
118 {
119 *lpnFlags |= OUTPUT_APPEND;
120 sp++;
121 }
122
123 while (_istspace (*sp))
124 sp++;
125
126 /* copy file name */
127 while (*sp && !IsRedirection (*sp) && !_istspace (*sp))
128 *ofn++ = *sp++;
129 *ofn = _T('\0');
130 }
131 else if (*sp == _T('2'))
132 {
133 /* error redirection */
134 sp++;
135
136 if (*sp == _T('>'))
137 {
138 *lpnFlags |= ERROR_REDIRECTION;
139 sp++;
140
141 /* append request ? */
142 if (*sp == _T('>'))
143 {
144 *lpnFlags |= ERROR_APPEND;
145 sp++;
146 }
147 }
148 else
149 {
150 /* no redirection!! copy the '2' character! */
151 sp--;
152 *dp++ = *sp++;
153 continue;
154 }
155
156 while (_istspace (*sp))
157 sp++;
158
159 /* copy file name */
160 while (*sp && !IsRedirection (*sp) && !_istspace (*sp))
161 *efn++ = *sp++;
162 *efn = _T('\0');
163 }
164 else if (*sp == _T('&'))
165 {
166 /* output AND error redirection */
167 sp++;
168
169 if (*sp == _T('>'))
170 {
171 *lpnFlags |= (ERROR_REDIRECTION | OUTPUT_REDIRECTION);
172 sp++;
173
174 /* append request ? */
175 if (*sp == _T('>'))
176 {
177 *lpnFlags |= (ERROR_APPEND | OUTPUT_APPEND);
178 sp++;
179 }
180 }
181 else
182 {
183 /* no redirection!! copy the '&' character! */
184 sp--;
185 *dp++ = *sp++;
186 continue;
187 }
188
189 while (_istspace (*sp))
190 sp++;
191
192 /* copy file name */
193 while (*sp && !IsRedirection (*sp) && !_istspace (*sp))
194 *ofn++ = *efn++ = *sp++;
195 *ofn = *efn = _T('\0');
196 }
197 }
198 else
199 *dp++ = *sp++;
200 }
201 *dp++ = _T('\0');
202 *dp = _T('\0');
203
204 /* now go for the pipes */
205 sp = s;
206 while (*sp)
207 {
208 if ((*sp == _T('"')) || (*sp == _T('\'')))
209 {
210 TCHAR qc = *sp;
211
212 do
213 sp++;
214 while (*sp && *sp != qc);
215
216 sp++;
217 }
218 else if (*sp == _T('|'))
219 {
220 *sp++ = _T('\0');
221 num++;
222 }
223 else
224 sp++;
225 }
226
227 return num;
228 }
229
230 #endif /* FEATURE_REDIRECTION */