SYSTEM_TIME_ZONE_INFORMATION added.
[reactos.git] / rosapps / 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
25 #include "config.h"
26
27 #ifdef FEATURE_REDIRECTION
28
29 #include <windows.h>
30 #include <tchar.h>
31 #include <string.h>
32 #include <ctype.h>
33
34 #include "cmd.h"
35
36
37 static BOOL
38 IsRedirection (TCHAR c)
39 {
40 return (c == _T('<')) || (c == _T('>')) || (c == _T('|'));
41 }
42
43
44 /*
45 * Gets the redirection info from the command line and copies the
46 * file names into ifn, ofn and efn removing them from the command
47 * line.
48 *
49 * Converts remaining command line into a series of null terminated
50 * strings defined by the pipe char '|'. Each string corresponds
51 * to a single executable command. A double null terminates the
52 * command strings.
53 *
54 * Return number of command strings found.
55 *
56 */
57
58 INT GetRedirection (LPTSTR s, LPTSTR ifn, LPTSTR ofn, LPTSTR efn, LPINT lpnFlags)
59 {
60 INT num = 1;
61 LPTSTR dp = s;
62 LPTSTR sp = s;
63
64 /* find and remove all the redirections first */
65 while (*sp)
66 {
67 if ((*sp == _T('"')) || (*sp == _T('\'')))
68 {
69 /* No redirects inside quotes */
70 TCHAR qc = *sp;
71
72 do
73 *dp++ = *sp++;
74 while (*sp && *sp != qc);
75
76 *dp++ = *sp++;
77 }
78 else if ((*sp == _T('<')) || (*sp == _T('>')) ||
79 (*sp == _T('2')) || (*sp == _T('&')))
80 {
81 /* MS-DOS ignores multiple redirection symbols and uses the last */
82 /* redirection, so we'll emulate that and not check */
83
84 if (*sp == _T('<'))
85 {
86 /* input redirection */
87 *lpnFlags |= INPUT_REDIRECTION;
88 while (_istspace (*sp))
89 sp++;
90
91 /* copy file name */
92 while (*sp && !IsRedirection (*sp) && !_istspace (*sp))
93 *ifn++ = *sp++;
94 *ifn = _T('\0');
95 }
96 else if (*sp == _T('>'))
97 {
98 /* output redirection */
99 *lpnFlags |= OUTPUT_REDIRECTION;
100 sp++;
101
102 /* append request ? */
103 if (*sp == _T('>'))
104 {
105 *lpnFlags |= OUTPUT_APPEND;
106 sp++;
107 }
108
109 while (_istspace (*sp))
110 sp++;
111
112 /* copy file name */
113 while (*sp && !IsRedirection (*sp) && !_istspace (*sp))
114 *ofn++ = *sp++;
115 *ofn = _T('\0');
116 }
117 else if (*sp == _T('2'))
118 {
119 /* error redirection */
120 sp++;
121
122 if (*sp == _T('>'))
123 {
124 *lpnFlags |= ERROR_REDIRECTION;
125 sp++;
126
127 /* append request ? */
128 if (*sp == _T('>'))
129 {
130 *lpnFlags |= ERROR_APPEND;
131 sp++;
132 }
133 }
134 else
135 {
136 /* no redirection!! copy the '2' character! */
137 sp--;
138 *dp++ = *sp++;
139 continue;
140 }
141
142 while (_istspace (*sp))
143 sp++;
144
145 /* copy file name */
146 while (*sp && !IsRedirection (*sp) && !_istspace (*sp))
147 *efn++ = *sp++;
148 *efn = _T('\0');
149 }
150 else if (*sp == _T('&'))
151 {
152 /* output AND error redirection */
153 sp++;
154
155 if (*sp == _T('>'))
156 {
157 *lpnFlags |= (ERROR_REDIRECTION | OUTPUT_REDIRECTION);
158 sp++;
159
160 /* append request ? */
161 if (*sp == _T('>'))
162 {
163 *lpnFlags |= (ERROR_APPEND | OUTPUT_APPEND);
164 sp++;
165 }
166 }
167 else
168 {
169 /* no redirection!! copy the '&' character! */
170 sp--;
171 *dp++ = *sp++;
172 continue;
173 }
174
175 while (_istspace (*sp))
176 sp++;
177
178 /* copy file name */
179 while (*sp && !IsRedirection (*sp) && !_istspace (*sp))
180 *ofn++ = *efn++ = *sp++;
181 *ofn = *efn = _T('\0');
182 }
183 }
184 else
185 *dp++ = *sp++;
186 }
187 *dp++ = _T('\0');
188 *dp = _T('\0');
189
190 /* now go for the pipes */
191 sp = s;
192 while (*sp)
193 {
194 if ((*sp == _T('"')) || (*sp == _T('\'')))
195 {
196 TCHAR qc = *sp;
197
198 do
199 sp++;
200 while (*sp && *sp != qc);
201
202 sp++;
203 }
204 else if (*sp == _T('|'))
205 {
206 *sp++ = _T('\0');
207 num++;
208 }
209 else
210 sp++;
211 }
212
213 return num;
214 }
215
216 #endif /* FEATURE_REDIRECTION */