2 * WHERE.C - file search functions.
7 * 07/15/95 (Tim Norman)
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.
14 * 12/12/95 (Steffan Kaiser & Tim Norman)
15 * added some patches to fix some things and make more efficient
18 * fixed a stupid pointer mistake...
19 * Thanks to everyone who noticed it!
22 * fixed a bug when getenv returns NULL
24 * 8/7/96 (Steffan Kaiser and Tim Norman)
25 * speed improvements and bug fixes
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
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.
37 * 7/12/97 (Tim Norman)
38 * Apparently, Aaron's bugfix got lost, so I fixed it again.
40 * 16 July 1998 (John P. Price)
41 * Added stand alone code.
43 * 17 July 1998 (John P. Price)
44 * Rewrote find_which to use searchpath function
46 * 24-Jul-1998 (John P Price <linux-guru@gcfl.net>)
47 * fixed bug where didn't check all extensions when path was specified
49 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
50 * added config.h include
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!)
57 * 03-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
58 * Changed find_which().
60 * 07-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
61 * Added ".CMD" extension.
62 * Replaced numeric constant by _NR_OF_EXTENSIONS.
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.
68 * 20-Apr-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
69 * Some minor changes and improvements.
81 /* initial size of environment variable buffer */
82 #define ENV_BUFFER_SIZE 1024
85 static LPTSTR ext[] = {".bat", ".cmd", ".com", ".exe"};
86 static INT nExtCount = sizeof(ext) / sizeof(LPTSTR);
89 /* searches for file using path info. */
92 SearchForExecutable (LPCTSTR pFileName, LPTSTR pFullName)
94 TCHAR szPathBuffer[MAX_PATH];
95 LPTSTR pszBuffer = NULL;
101 /* initialize full name buffer */
102 *pFullName = _T('\0');
105 DebugPrintf (_T("SearchForExecutable: \'%s\'\n"), pFileName);
108 if (_tcschr (pFileName, _T('\\')) != NULL)
112 DebugPrintf (_T("Absolute or relative path is given.\n"));
115 if (GetFullPathName (pFileName,
125 if (_tcschr (pFilePart, _T('.')) != NULL)
128 DebugPrintf (_T("Filename extension!\n"));
130 _tcscpy (pFullName, szPathBuffer);
137 DebugPrintf (_T("No filename extension!\n"));
140 p = szPathBuffer + _tcslen (szPathBuffer);
142 for (n = 0; n < nExtCount; n++)
147 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer);
150 if (IsValidFileName (szPathBuffer))
153 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer);
155 _tcscpy (pFullName, szPathBuffer);
163 /* load environment varable PATH into buffer */
164 pszBuffer = (LPTSTR)malloc (ENV_BUFFER_SIZE * sizeof(TCHAR));
165 dwBuffer = GetEnvironmentVariable (_T("PATH"), pszBuffer, ENV_BUFFER_SIZE);
166 if (dwBuffer > ENV_BUFFER_SIZE)
168 pszBuffer = (LPTSTR)realloc (pszBuffer, dwBuffer * sizeof (TCHAR));
169 GetEnvironmentVariable (_T("PATH"), pszBuffer, dwBuffer * sizeof (TCHAR));
172 if (!(p = _tcsrchr (pFileName, _T('.'))) ||
173 _tcschr (p + 1, _T('\\')))
175 /* There is no extension ==> test all the extensions. */
177 DebugPrintf (_T("No filename extension!\n"));
180 /* search in current directory */
181 len = GetCurrentDirectory (MAX_PATH, szPathBuffer);
182 if (szPathBuffer[len - 1] != _T('\\'))
184 szPathBuffer[len] = _T('\\');
185 szPathBuffer[len + 1] = _T('\0');
187 _tcscat (szPathBuffer, pFileName);
189 p = szPathBuffer + _tcslen (szPathBuffer);
191 for (n = 0; n < nExtCount; n++)
196 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer);
199 if (IsValidFileName (szPathBuffer))
202 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer);
205 _tcscpy (pFullName, szPathBuffer);
214 f = _tcschr (s, _T(';'));
218 _tcsncpy (szPathBuffer, s, (size_t)(f-s));
219 szPathBuffer[f-s] = _T('\0');
224 _tcscpy (szPathBuffer, s);
228 len = _tcslen(szPathBuffer);
229 if (szPathBuffer[len - 1] != _T('\\'))
231 szPathBuffer[len] = _T('\\');
232 szPathBuffer[len + 1] = _T('\0');
234 _tcscat (szPathBuffer, pFileName);
236 p = szPathBuffer + _tcslen (szPathBuffer);
238 for (n = 0; n < nExtCount; n++)
243 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer);
246 if (IsValidFileName (szPathBuffer))
249 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer);
252 _tcscpy (pFullName, szPathBuffer);
260 /* There is an extension and it is in the last path component, */
261 /* so don't test all the extensions. */
263 DebugPrintf (_T("Filename extension!\n"));
266 /* search in current directory */
267 len = GetCurrentDirectory (MAX_PATH, szPathBuffer);
268 if (szPathBuffer[len - 1] != _T('\\'))
270 szPathBuffer[len] = _T('\\');
271 szPathBuffer[len + 1] = _T('\0');
273 _tcscat (szPathBuffer, pFileName);
276 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer);
278 if (IsValidFileName (szPathBuffer))
281 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer);
284 _tcscpy (pFullName, szPathBuffer);
293 f = _tcschr (s, _T(';'));
297 _tcsncpy (szPathBuffer, s, (size_t)(f-s));
298 szPathBuffer[f-s] = _T('\0');
303 _tcscpy (szPathBuffer, s);
307 len = _tcslen(szPathBuffer);
308 if (szPathBuffer[len - 1] != _T('\\'))
310 szPathBuffer[len] = _T('\\');
311 szPathBuffer[len + 1] = _T('\0');
313 _tcscat (szPathBuffer, pFileName);
316 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer);
318 if (IsValidFileName (szPathBuffer))
321 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer);
324 _tcscpy (pFullName, szPathBuffer);