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"));
118 if (GetFullPathName (pFileName
,
130 if (_tcschr (pFilePart
, _T('.')) != NULL
)
133 DebugPrintf (_T("Filename extension!\n"));
135 _tcscpy (pFullName
, szPathBuffer
);
142 DebugPrintf (_T("No filename extension!\n"));
145 p
= szPathBuffer
+ _tcslen (szPathBuffer
);
147 for (n
= 0; n
< nExtCount
; n
++)
152 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer
);
155 if (IsValidFileName (szPathBuffer
))
158 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer
);
160 _tcscpy (pFullName
, szPathBuffer
);
168 /* load environment varable PATH into buffer */
169 pszBuffer
= (LPTSTR
)malloc (ENV_BUFFER_SIZE
* sizeof(TCHAR
));
170 dwBuffer
= GetEnvironmentVariable (_T("PATH"), pszBuffer
, ENV_BUFFER_SIZE
);
171 if (dwBuffer
> ENV_BUFFER_SIZE
)
173 pszBuffer
= (LPTSTR
)realloc (pszBuffer
, dwBuffer
* sizeof (TCHAR
));
174 GetEnvironmentVariable (_T("PATH"), pszBuffer
, dwBuffer
* sizeof (TCHAR
));
177 if (!(p
= _tcsrchr (pFileName
, _T('.'))) ||
178 _tcschr (p
+ 1, _T('\\')))
180 /* There is no extension ==> test all the extensions. */
182 DebugPrintf (_T("No filename extension!\n"));
185 /* search in current directory */
186 len
= GetCurrentDirectory (MAX_PATH
, szPathBuffer
);
187 if (szPathBuffer
[len
- 1] != _T('\\'))
189 szPathBuffer
[len
] = _T('\\');
190 szPathBuffer
[len
+ 1] = _T('\0');
192 _tcscat (szPathBuffer
, pFileName
);
194 p
= szPathBuffer
+ _tcslen (szPathBuffer
);
196 for (n
= 0; n
< nExtCount
; n
++)
201 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer
);
204 if (IsValidFileName (szPathBuffer
))
207 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer
);
210 _tcscpy (pFullName
, szPathBuffer
);
219 f
= _tcschr (s
, _T(';'));
223 _tcsncpy (szPathBuffer
, s
, (size_t)(f
-s
));
224 szPathBuffer
[f
-s
] = _T('\0');
229 _tcscpy (szPathBuffer
, s
);
233 len
= _tcslen(szPathBuffer
);
234 if (szPathBuffer
[len
- 1] != _T('\\'))
236 szPathBuffer
[len
] = _T('\\');
237 szPathBuffer
[len
+ 1] = _T('\0');
239 _tcscat (szPathBuffer
, pFileName
);
241 p
= szPathBuffer
+ _tcslen (szPathBuffer
);
243 for (n
= 0; n
< nExtCount
; n
++)
248 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer
);
251 if (IsValidFileName (szPathBuffer
))
254 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer
);
257 _tcscpy (pFullName
, szPathBuffer
);
265 /* There is an extension and it is in the last path component, */
266 /* so don't test all the extensions. */
268 DebugPrintf (_T("Filename extension!\n"));
271 /* search in current directory */
272 len
= GetCurrentDirectory (MAX_PATH
, szPathBuffer
);
273 if (szPathBuffer
[len
- 1] != _T('\\'))
275 szPathBuffer
[len
] = _T('\\');
276 szPathBuffer
[len
+ 1] = _T('\0');
278 _tcscat (szPathBuffer
, pFileName
);
281 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer
);
283 if (IsValidFileName (szPathBuffer
))
286 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer
);
289 _tcscpy (pFullName
, szPathBuffer
);
298 f
= _tcschr (s
, _T(';'));
302 _tcsncpy (szPathBuffer
, s
, (size_t)(f
-s
));
303 szPathBuffer
[f
-s
] = _T('\0');
308 _tcscpy (szPathBuffer
, s
);
312 len
= _tcslen(szPathBuffer
);
313 if (szPathBuffer
[len
- 1] != _T('\\'))
315 szPathBuffer
[len
] = _T('\\');
316 szPathBuffer
[len
+ 1] = _T('\0');
318 _tcscat (szPathBuffer
, pFileName
);
321 DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer
);
323 if (IsValidFileName (szPathBuffer
))
326 DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer
);
329 _tcscpy (pFullName
, szPathBuffer
);