Added MORE command.
[reactos.git] / rosapps / cmd / where.c
1 /*
2 * WHERE.C - file search functions.
3 *
4 *
5 * History:
6 *
7 * 07/15/95 (Tim Norman)
8 * started.
9 *
10 * 08/08/95 (Matt Rains)
11 * i have cleaned up the source code. changes now bring this source
12 * into guidelines for recommended programming practice.
13 *
14 * 12/12/95 (Steffan Kaiser & Tim Norman)
15 * added some patches to fix some things and make more efficient
16 *
17 * 1/6/96 (Tim Norman)
18 * fixed a stupid pointer mistake...
19 * Thanks to everyone who noticed it!
20 *
21 * 8/1/96 (Tim Norman)
22 * fixed a bug when getenv returns NULL
23 *
24 * 8/7/96 (Steffan Kaiser and Tim Norman)
25 * speed improvements and bug fixes
26 *
27 * 8/27/96 (Tim Norman)
28 * changed code to use pointers directly into PATH environment
29 * variable rather than making our own copy. This saves some memory,
30 * but requires we write our own function to copy pathnames out of
31 * the variable.
32 *
33 * 12/23/96 (Aaron Kaufman)
34 * Fixed a bug in get_paths() that did not point to the first PATH
35 * in the environment variable.
36 *
37 * 7/12/97 (Tim Norman)
38 * Apparently, Aaron's bugfix got lost, so I fixed it again.
39 *
40 * 16 July 1998 (John P. Price)
41 * Added stand alone code.
42 *
43 * 17 July 1998 (John P. Price)
44 * Rewrote find_which to use searchpath function
45 *
46 * 24-Jul-1998 (John P Price <linux-guru@gcfl.net>)
47 * fixed bug where didn't check all extensions when path was specified
48 *
49 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
50 * added config.h include
51 *
52 * 30-Jul-1998 (John P Price <linux-guru@gcfl.net>)
53 * fixed so that it find_which returns NULL if filename is not
54 * executable (does not have .bat, .com, or .exe extention).
55 * Before command would to execute any file with any extension (opps!)
56 *
57 * 03-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
58 * Changed find_which().
59 *
60 * 07-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
61 * Added ".CMD" extension.
62 * Replaced numeric constant by _NR_OF_EXTENSIONS.
63 *
64 * 26-Feb-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
65 * Replaced find_which() by SearchForExecutable().
66 * Now files are searched using the right extension order.
67 *
68 * 20-Apr-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
69 * Some minor changes and improvements.
70 */
71
72 #include "config.h"
73
74 #include <windows.h>
75 #include <string.h>
76 #include <stdlib.h>
77
78 #include "cmd.h"
79
80
81 /* initial size of environment variable buffer */
82 #define ENV_BUFFER_SIZE 1024
83
84
85 static LPTSTR ext[] = {".bat", ".cmd", ".com", ".exe"};
86 static INT nExtCount = sizeof(ext) / sizeof(LPTSTR);
87
88
89 /* searches for file using path info. */
90
91 BOOL
92 SearchForExecutable (LPCTSTR pFileName, LPTSTR pFullName)
93 {
94 TCHAR szPathBuffer[MAX_PATH];
95 LPTSTR pszBuffer = NULL;
96 DWORD dwBuffer, len;
97 INT n;
98 LPTSTR p,s,f;
99
100 /* load environment varable PATH into buffer */
101 pszBuffer = (LPTSTR)malloc (ENV_BUFFER_SIZE * sizeof(TCHAR));
102 dwBuffer = GetEnvironmentVariable (_T("PATH"), pszBuffer, ENV_BUFFER_SIZE);
103 if (dwBuffer > ENV_BUFFER_SIZE)
104 {
105 pszBuffer = (LPTSTR)realloc (pszBuffer, dwBuffer * sizeof (TCHAR));
106 GetEnvironmentVariable (_T("PATH"), pszBuffer, dwBuffer * sizeof (TCHAR));
107 }
108
109 /* initialize full name buffer */
110 *pFullName = _T('\0');
111
112 if (!(p = _tcsrchr (pFileName, _T('.'))) ||
113 _tcschr (p + 1, _T('\\')))
114 {
115 /* There is no extension ==> test all the extensions. */
116 #ifdef _DEBUG
117 DebugPrintf (_T("No filename extension!\n"));
118 #endif
119
120 /* search in current directory */
121 len = GetCurrentDirectory (MAX_PATH, szPathBuffer);
122 if (szPathBuffer[len - 1] != _T('\\'))
123 {
124 szPathBuffer[len] = _T('\\');
125 szPathBuffer[len + 1] = _T('\0');
126 }
127 _tcscat (szPathBuffer, pFileName);
128
129 p = szPathBuffer + _tcslen (szPathBuffer);
130
131 for (n = 0; n < nExtCount; n++)
132 {
133 _tcscpy (p, ext[n]);
134
135 #ifdef _DEBUG
136 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer);
137 #endif
138
139 if (IsValidFileName (szPathBuffer))
140 {
141 #ifdef _DEBUG
142 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer);
143 #endif
144 free (pszBuffer);
145 _tcscpy (pFullName, szPathBuffer);
146 return TRUE;
147 }
148 }
149
150 /* search in PATH */
151 s = pszBuffer;
152 while (s && *s)
153 {
154 f = _tcschr (s, _T(';'));
155
156 if (f)
157 {
158 _tcsncpy (szPathBuffer, s, (size_t)(f-s));
159 szPathBuffer[f-s] = _T('\0');
160 s = f + 1;
161 }
162 else
163 {
164 _tcscpy (szPathBuffer, s);
165 s = NULL;
166 }
167
168 len = _tcslen(szPathBuffer);
169 if (szPathBuffer[len - 1] != _T('\\'))
170 {
171 szPathBuffer[len] = _T('\\');
172 szPathBuffer[len + 1] = _T('\0');
173 }
174 _tcscat (szPathBuffer, pFileName);
175
176 p = szPathBuffer + _tcslen (szPathBuffer);
177
178 for (n = 0; n < nExtCount; n++)
179 {
180 _tcscpy (p, ext[n]);
181
182 #ifdef _DEBUG
183 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer);
184 #endif
185
186 if (IsValidFileName (szPathBuffer))
187 {
188 #ifdef _DEBUG
189 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer);
190 #endif
191 free (pszBuffer);
192 _tcscpy (pFullName, szPathBuffer);
193 return TRUE;
194 }
195 }
196 }
197 }
198 else
199 {
200 /* There is an extension and it is in the last path component, */
201 /* so don't test all the extensions. */
202 #ifdef _DEBUG
203 DebugPrintf (_T("Filename extension!\n"));
204 #endif
205
206 /* search in current directory */
207 len = GetCurrentDirectory (MAX_PATH, szPathBuffer);
208 if (szPathBuffer[len - 1] != _T('\\'))
209 {
210 szPathBuffer[len] = _T('\\');
211 szPathBuffer[len + 1] = _T('\0');
212 }
213 _tcscat (szPathBuffer, pFileName);
214
215 #ifdef _DEBUG
216 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer);
217 #endif
218 if (IsValidFileName (szPathBuffer))
219 {
220 #ifdef _DEBUG
221 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer);
222 #endif
223 free (pszBuffer);
224 _tcscpy (pFullName, szPathBuffer);
225 return TRUE;
226 }
227
228
229 /* search in PATH */
230 s = pszBuffer;
231 while (s && *s)
232 {
233 f = _tcschr (s, _T(';'));
234
235 if (f)
236 {
237 _tcsncpy (szPathBuffer, s, (size_t)(f-s));
238 szPathBuffer[f-s] = _T('\0');
239 s = f + 1;
240 }
241 else
242 {
243 _tcscpy (szPathBuffer, s);
244 s = NULL;
245 }
246
247 len = _tcslen(szPathBuffer);
248 if (szPathBuffer[len - 1] != _T('\\'))
249 {
250 szPathBuffer[len] = _T('\\');
251 szPathBuffer[len + 1] = _T('\0');
252 }
253 _tcscat (szPathBuffer, pFileName);
254
255 #ifdef _DEBUG
256 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer);
257 #endif
258 if (IsValidFileName (szPathBuffer))
259 {
260 #ifdef _DEBUG
261 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer);
262 #endif
263 free (pszBuffer);
264 _tcscpy (pFullName, szPathBuffer);
265 return TRUE;
266 }
267 }
268 }
269
270 free (pszBuffer);
271
272 return FALSE;
273 }