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 extension).
55 * Before command would to execute any file with any extension (opps!)
57 * 03-Dec-1998 (Eric Kohl)
58 * Changed find_which().
60 * 07-Dec-1998 (Eric Kohl)
61 * Added ".CMD" extension.
62 * Replaced numeric constant by _NR_OF_EXTENSIONS.
64 * 26-Feb-1999 (Eric Kohl)
65 * Replaced find_which() by SearchForExecutable().
66 * Now files are searched using the right extension order.
68 * 20-Apr-1999 (Eric Kohl)
69 * Some minor changes and improvements.
71 * 10-Jul-2004 (Jens Collin <jens.collin@lakhei.com>)
72 * Fixed searching for files with specific extensions in PATHEXT order.
79 /* initial size of environment variable buffer */
80 #define ENV_BUFFER_SIZE 1024
83 /* searches for file using path info. */
86 SearchForExecutableSingle (LPCTSTR pFileName
, LPTSTR pFullName
, LPTSTR pPathExt
, LPTSTR pDirectory
)
88 TCHAR szPathBuffer
[CMDLINE_LENGTH
], *pszPathEnd
;
90 /* initialize full name buffer */
91 *pFullName
= _T('\0');
93 TRACE ("SearchForExecutableSingle: \'%s\' in dir: \'%s\'\n",
94 debugstr_aw(pFileName
), debugstr_aw(pDirectory
));
96 pszPathEnd
= szPathBuffer
;
97 if (pDirectory
!= NULL
)
99 _tcscpy(szPathBuffer
, pDirectory
);
100 pszPathEnd
+= _tcslen(pszPathEnd
);
101 *pszPathEnd
++ = _T('\\');
103 _tcscpy(pszPathEnd
, pFileName
);
104 pszPathEnd
+= _tcslen(pszPathEnd
);
106 if (IsExistingFile (szPathBuffer
))
108 TRACE ("Found: \'%s\'\n", debugstr_aw(szPathBuffer
));
109 _tcscpy (pFullName
, szPathBuffer
);
116 f
= _tcschr (s
, _T(';'));
120 _tcsncpy (pszPathEnd
, s
, (size_t)(f
-s
));
121 pszPathEnd
[f
-s
] = _T('\0');
126 _tcscpy (pszPathEnd
, s
);
130 if (IsExistingFile (szPathBuffer
))
132 TRACE ("Found: \'%s\'\n", debugstr_aw(szPathBuffer
));
133 _tcscpy (pFullName
, szPathBuffer
);
142 SearchForExecutable (LPCTSTR pFileName
, LPTSTR pFullName
)
144 static TCHAR pszDefaultPathExt
[] = _T(".com;.exe;.bat;.cmd");
145 LPTSTR pszPathExt
, pszPath
;
148 TRACE ("SearchForExecutable: \'%s\'\n", debugstr_aw(pFileName
));
150 /* load environment variable PATHEXT */
151 pszPathExt
= (LPTSTR
)cmd_alloc (ENV_BUFFER_SIZE
* sizeof(TCHAR
));
152 dwBuffer
= GetEnvironmentVariable (_T("PATHEXT"), pszPathExt
, ENV_BUFFER_SIZE
);
153 if (dwBuffer
> ENV_BUFFER_SIZE
)
155 LPTSTR pszOldPathExt
= pszPathExt
;
156 pszPathExt
= (LPTSTR
)cmd_realloc (pszPathExt
, dwBuffer
* sizeof (TCHAR
));
157 if (pszPathExt
== NULL
)
159 cmd_free(pszOldPathExt
);
162 GetEnvironmentVariable (_T("PATHEXT"), pszPathExt
, dwBuffer
);
165 else if (0 == dwBuffer
)
167 _tcscpy(pszPathExt
, pszDefaultPathExt
);
174 /* Check if valid directly on specified path */
175 if (SearchForExecutableSingle(pFileName
, pFullName
, pszPathExt
, NULL
))
177 cmd_free(pszPathExt
);
181 /* If an explicit directory was given, stop here - no need to search PATH. */
182 if (pFileName
[1] == _T(':') || _tcschr(pFileName
, _T('\\')))
184 cmd_free(pszPathExt
);
188 /* load environment variable PATH into buffer */
189 pszPath
= (LPTSTR
)cmd_alloc (ENV_BUFFER_SIZE
* sizeof(TCHAR
));
190 dwBuffer
= GetEnvironmentVariable (_T("PATH"), pszPath
, ENV_BUFFER_SIZE
);
191 if (dwBuffer
> ENV_BUFFER_SIZE
)
193 LPTSTR pszOldPath
= pszPath
;
194 pszPath
= (LPTSTR
)cmd_realloc (pszPath
, dwBuffer
* sizeof (TCHAR
));
197 cmd_free(pszOldPath
);
198 cmd_free(pszPathExt
);
201 GetEnvironmentVariable (_T("PATH"), pszPath
, dwBuffer
);
204 TRACE ("SearchForExecutable(): Loaded PATH: %s\n", debugstr_aw(pszPath
));
207 pCh
= _tcstok(pszPath
, _T(";"));
210 if (SearchForExecutableSingle(pFileName
, pFullName
, pszPathExt
, pCh
))
213 cmd_free(pszPathExt
);
216 pCh
= _tcstok(NULL
, _T(";"));
220 cmd_free(pszPathExt
);