changes to make cmd compile (not link)
[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 serched with the right order of extensions.
67 */
68
69 #include "config.h"
70
71 #include <windows.h>
72 #include <string.h>
73 #include <stdlib.h>
74
75 #include "cmd.h"
76
77
78 /* initial size of environment variable buffer */
79 #define ENV_BUFFER_SIZE 1024
80
81
82 static LPTSTR ext[] = {".BAT", ".CMD", ".COM", ".EXE"};
83 static INT nExtCount = sizeof(ext) / sizeof(LPTSTR);
84
85
86 /* searches for file using path info. */
87
88 BOOL
89 SearchForExecutable (LPCTSTR pFileName, LPTSTR pFullName)
90 {
91 TCHAR szPathBuffer[MAX_PATH];
92 LPTSTR pszBuffer;
93 DWORD dwBuffer;
94 INT n;
95 LPTSTR p,s,f;
96
97 /* load environment varable PATH into buffer */
98 pszBuffer = (LPTSTR)malloc (ENV_BUFFER_SIZE * sizeof(TCHAR));
99 dwBuffer = GetEnvironmentVariable (_T("PATH"), pszBuffer, ENV_BUFFER_SIZE);
100 if (dwBuffer == 0)
101 {
102 ConErrPrintf (_T("Not PATH environment variable found!\n"));
103 return 0;
104 }
105 else if (dwBuffer > ENV_BUFFER_SIZE)
106 {
107 pszBuffer = (LPTSTR)realloc (pszBuffer, dwBuffer * sizeof (TCHAR));
108 GetEnvironmentVariable (_T("PATH"), pszBuffer, dwBuffer * sizeof (TCHAR));
109 }
110
111
112 /* initialize full name buffer */
113 *pFullName = _T('\0');
114
115 if (!(p = _tcsrchr (pFileName, _T('.'))) ||
116 _tcschr (p + 1, _T('\\')))
117 {
118 /* There is no extension ==> test all the extensions. */
119 #ifdef _DEBUG
120 DebugPrintf (_T("No filename extension!\n"));
121 #endif
122
123 /* search in current directory */
124 GetCurrentDirectory (MAX_PATH, szPathBuffer);
125 if (szPathBuffer[_tcslen(szPathBuffer)-1] != _T('\\'))
126 _tcscat (szPathBuffer, _T("\\"));
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 if (szPathBuffer[_tcslen(szPathBuffer)-1] != _T('\\'))
169 _tcscat (szPathBuffer, _T("\\"));
170 _tcscat (szPathBuffer, pFileName);
171
172 p = szPathBuffer + _tcslen (szPathBuffer);
173
174 for (n = 0; n < nExtCount; n++)
175 {
176 _tcscpy (p, ext[n]);
177
178 #ifdef _DEBUG
179 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer);
180 #endif
181
182 if (IsValidFileName (szPathBuffer))
183 {
184 #ifdef _DEBUG
185 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer);
186 #endif
187 free (pszBuffer);
188 _tcscpy (pFullName, szPathBuffer);
189 return TRUE;
190 }
191 }
192 }
193 }
194 else
195 {
196 /* There is an extension and it is in the last path component, */
197 /* so don't test all the extensions. */
198 #ifdef _DEBUG
199 DebugPrintf (_T("Filename extension!\n"));
200 #endif
201
202 /* search in current directory */
203 GetCurrentDirectory (MAX_PATH, szPathBuffer);
204 if (szPathBuffer[_tcslen(szPathBuffer)-1] != _T('\\'))
205 _tcscat (szPathBuffer, _T("\\"));
206 _tcscat (szPathBuffer, pFileName);
207
208 #ifdef _DEBUG
209 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer);
210 #endif
211 if (IsValidFileName (szPathBuffer))
212 {
213 #ifdef _DEBUG
214 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer);
215 #endif
216 free (pszBuffer);
217 _tcscpy (pFullName, szPathBuffer);
218 return TRUE;
219 }
220
221
222 /* search in PATH */
223 s = pszBuffer;
224 while (s && *s)
225 {
226 f = _tcschr (s, _T(';'));
227
228 if (f)
229 {
230 _tcsncpy (szPathBuffer, s, (size_t)(f-s));
231 szPathBuffer[f-s] = _T('\0');
232 s = f + 1;
233 }
234 else
235 {
236 _tcscpy (szPathBuffer, s);
237 s = NULL;
238 }
239
240 if (szPathBuffer[_tcslen(szPathBuffer)-1] != _T('\\'))
241 _tcscat (szPathBuffer, _T("\\"));
242 _tcscat (szPathBuffer, pFileName);
243
244 #ifdef _DEBUG
245 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer);
246 #endif
247 if (IsValidFileName (szPathBuffer))
248 {
249 #ifdef _DEBUG
250 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer);
251 #endif
252 free (pszBuffer);
253 _tcscpy (pFullName, szPathBuffer);
254 return TRUE;
255 }
256 }
257 }
258
259 free (pszBuffer);
260
261 return FALSE;
262 }