65231823c97dbba26a4c4c85cb9ca546b831cc13
[reactos.git] / rosapps / cmd / misc.c
1 /*
2 * MISC.C - misc. functions.
3 *
4 *
5 * History:
6 *
7 * 07/12/98 (Rob Lake)
8 * started
9 *
10 * 07/13/98 (Rob Lake)
11 * moved functions in here
12 *
13 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
14 * added config.h include
15 *
16 * 18-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
17 * Changed split() to accept quoted arguments.
18 * Removed parse_firstarg().
19 *
20 * 23-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
21 * Fixed an ugly bug in split(). In rare cases (last character
22 * of the string is a space) it ignored the NULL character and
23 * tried to add the following to the argument list.
24 *
25 * 28-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
26 * FileGetString() seems to be working now.
27 */
28
29 #include "config.h"
30
31 #include <windows.h>
32 #include <tchar.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <ctype.h>
36
37 #include "cmd.h"
38
39
40 /*
41 * get a character out-of-band and honor Ctrl-Break characters
42 */
43 TCHAR cgetchar (VOID)
44 {
45 HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
46 INPUT_RECORD irBuffer;
47 DWORD dwRead;
48
49 do
50 {
51 ReadConsoleInput (hInput, &irBuffer, 1, &dwRead);
52 if ((irBuffer.EventType == KEY_EVENT) &&
53 (irBuffer.Event.KeyEvent.bKeyDown == TRUE))
54 {
55 if ((irBuffer.Event.KeyEvent.dwControlKeyState &
56 (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) &
57 (irBuffer.Event.KeyEvent.wVirtualKeyCode == 'C'))
58 bCtrlBreak = TRUE;
59
60 break;
61 }
62 }
63 while (TRUE);
64
65 #ifndef _UNICODE
66 return irBuffer.Event.KeyEvent.uChar.AsciiChar;
67 #else
68 return irBuffer.Event.KeyEvent.uChar.UnicodeChar;
69 #endif /* _UNICODE */
70 }
71
72
73 /*
74 * Check if Ctrl-Break was pressed during the last calls
75 */
76
77 BOOL CheckCtrlBreak (INT mode)
78 {
79 static BOOL bLeaveAll = FALSE; /* leave all batch files */
80 TCHAR c;
81
82 switch (mode)
83 {
84 case BREAK_OUTOFBATCH:
85 bLeaveAll = 0;
86 return FALSE;
87
88 case BREAK_BATCHFILE:
89 if (bLeaveAll)
90 return TRUE;
91
92 if (!bCtrlBreak)
93 return FALSE;
94
95 /* we need to be sure the string arrives on the screen! */
96 do
97 ConOutPuts (_T("\r\nCtrl-Break pressed. Cancel batch file? (Yes/No/All) "));
98 while (!_tcschr ("YNA\3", c = _totupper (cgetchar())) || !c);
99
100 ConOutPuts (_T("\r\n"));
101
102 if (c == _T('N'))
103 return bCtrlBreak = FALSE; /* ignore */
104
105 /* leave all batch files */
106 bLeaveAll = ((c == _T('A')) || (c == _T('\3')));
107 break;
108
109 case BREAK_INPUT:
110 if (!bCtrlBreak)
111 return FALSE;
112 break;
113 }
114
115 /* state processed */
116 bCtrlBreak = FALSE;
117 return TRUE;
118 }
119
120
121 /*
122 * split - splits a line up into separate arguments, deliminators
123 * are spaces and slashes ('/').
124 */
125
126 LPTSTR *split (LPTSTR s, LPINT args)
127 {
128 LPTSTR *arg;
129 LPTSTR *p;
130 LPTSTR start;
131 LPTSTR q;
132 INT ac;
133 INT len;
134 BOOL bQuoted = FALSE;
135
136 arg = malloc (sizeof (LPTSTR));
137 if (!arg)
138 return NULL;
139 *arg = NULL;
140
141 ac = 0;
142 while (*s)
143 {
144 /* skip leading spaces */
145 while (*s && (_istspace (*s) || _istcntrl (*s)))
146 ++s;
147
148 /* if quote (") then set bQuoted */
149 if (*s == _T('\"'))
150 {
151 ++s;
152 bQuoted = TRUE;
153 }
154
155 start = s;
156
157 /* the first character can be '/' */
158 if (*s == _T('/'))
159 ++s;
160
161 /* skip to next word delimiter or start of next option */
162 if (bQuoted)
163 {
164 while (_istprint (*s) && (*s != _T('\"')) && (*s != _T('/')))
165 ++s;
166 }
167 else
168 {
169 while (_istprint (*s) && !_istspace (*s) && (*s != _T('/')))
170 ++s;
171 }
172
173 /* a word was found */
174 if (s != start)
175 {
176 /* add new entry for new argument */
177 arg = realloc (p = arg, (ac + 2) * sizeof (LPTSTR));
178 if (!arg)
179 {
180 freep (p);
181 return NULL;
182 }
183
184 /* create new entry */
185 q = arg[ac] = malloc (((len = s - start) + 1) * sizeof (TCHAR));
186 arg[++ac] = NULL;
187 if (!q)
188 {
189 freep (arg);
190 return NULL;
191 }
192 memcpy (q, start, len * sizeof (TCHAR));
193 q[len] = _T('\0');
194 }
195
196 /* adjust string pointer if quoted (") */
197 if (bQuoted)
198 {
199 ++s;
200 bQuoted = FALSE;
201 }
202 }
203
204 *args = ac;
205
206 return arg;
207 }
208
209
210 /*
211 * freep -- frees memory used for a call to split
212 *
213 */
214 VOID freep (LPTSTR *p)
215 {
216 LPTSTR *q;
217
218 if (!p)
219 return;
220
221 q = p;
222 while (*q)
223 free(*q++);
224
225 free(p);
226 }
227
228
229 LPTSTR stpcpy (LPTSTR dest, LPTSTR src)
230 {
231 _tcscpy (dest, src);
232 return (dest + _tcslen (src));
233 }
234
235
236
237 /*
238 * Checks if a path is valid (accessible)
239 */
240
241 BOOL IsValidPathName (LPCTSTR pszPath)
242 {
243 TCHAR szOldPath[MAX_PATH];
244 BOOL bResult;
245
246 GetCurrentDirectory (MAX_PATH, szOldPath);
247 bResult = SetCurrentDirectory (pszPath);
248
249 SetCurrentDirectory (szOldPath);
250
251 return bResult;
252 }
253
254
255 /*
256 * Checks if a file exists (accessible)
257 */
258
259 BOOL IsValidFileName (LPCTSTR pszPath)
260 {
261 return (GetFileAttributes (pszPath) != 0xFFFFFFFF);
262 }
263
264
265 BOOL IsValidDirectory (LPCTSTR pszPath)
266 {
267 return (GetFileAttributes (pszPath) & FILE_ATTRIBUTE_DIRECTORY);
268 }
269
270
271 BOOL FileGetString (HANDLE hFile, LPTSTR lpBuffer, INT nBufferLength)
272 {
273 LPTSTR lpString;
274 TCHAR ch;
275 DWORD dwRead;
276
277 lpString = lpBuffer;
278
279 while ((--nBufferLength > 0) &&
280 ReadFile(hFile, &ch, 1, &dwRead, NULL) && dwRead)
281 {
282 *lpString++ = ch;
283 if (ch == _T('\r'))
284 {
285 /* overread '\n' */
286 ReadFile (hFile, &ch, 1, &dwRead, NULL);
287 break;
288 }
289 }
290
291 if (!dwRead && lpString == lpBuffer)
292 return FALSE;
293
294 *lpString++ = _T('\0');
295
296 return TRUE;
297 }
298
299 #ifndef __REACTOS__
300 /*
301 * GetConsoleWindow - returns the handle to the current console window
302 */
303 HWND GetConsoleWindow(VOID)
304 {
305 TCHAR original[256]; /* stores original title*/
306 TCHAR temp[256]; /* stores temp title*/
307
308 HWND h=0;
309
310 GetConsoleTitle(original,sizeof(original));
311
312 _tcscpy(temp,original);
313 _tcscat(temp,_T("-xxx "));
314
315 if((h = FindWindow("tty",temp)) == NULL )
316 {
317 SetConsoleTitle(temp);
318 h=FindWindow("tty",temp);
319 SetConsoleTitle(original);
320 }
321
322 return h;
323 }
324 #endif
325
326 /* EOF */