Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
5.4 KiB

  1. /***
  2. *searchenv.c - find a file using paths from an environment variable
  3. *
  4. * Copyright (c) 1987-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * to search a set a directories specified by an environment variable
  8. * for a specified file name. If found the full path name is returned.
  9. *
  10. *Revision History:
  11. * 06-15-87 DFW initial implementation
  12. * 08-06-87 JCR Changed directory delimeter from '/' to '\'.
  13. * 09-24-87 JCR Removed 'const' from declarations (caused cl warnings).
  14. * 12-11-87 JCR Added "_LOAD_DS" to declaration
  15. * 02-17-88 JCR Added 'const' copy_path local to get rid of cl warning.
  16. * 07-19-88 SKS Fixed bug if root directory is current directory
  17. * 08-03-89 JCR Allow quoted strings in file/path names
  18. * 08-29-89 GJF Changed copy_path() to _getpath() and moved it to it's
  19. * own source file. Also fixed handling of multiple semi-
  20. * colons.
  21. * 11-20-89 GJF Added const attribute to types of fname and env_var.
  22. * 03-15-90 GJF Replaced _LOAD_DS with _CALLTYPE1 and added #include
  23. * <cruntime.h>. Also, cleaned up the formatting a bit.
  24. * 07-25-90 SBM Removed redundant include (stdio.h)
  25. * 10-04-90 GJF New-style function declarator.
  26. * 01-22-91 GJF ANSI naming.
  27. * 08-26-92 GJF Include unistd.h for POSIX build.
  28. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  29. * 12-07-93 CFW Wide char enable.
  30. * 01-31-95 GJF Use _fullpath instead of _getcwd, to convert a file
  31. * that exists relative to the current directory, to a
  32. * fully qualified path.
  33. * 02-16-95 JWM Mac merge.
  34. * 03-29-95 BWT Fix POSIX build by sticking with getcwd.
  35. * 10-20-95 GJF Use local buffer instead of the caller's buffer to
  36. * build the pathname (Olympus0 9336).
  37. * 05-17-99 PML Remove all Macintosh support.
  38. *
  39. *******************************************************************************/
  40. #include <cruntime.h>
  41. #ifdef _POSIX_
  42. #include <unistd.h>
  43. #else
  44. #include <direct.h>
  45. #endif
  46. #include <stdlib.h>
  47. #include <string.h>
  48. #include <io.h>
  49. #include <internal.h>
  50. #include <tchar.h>
  51. /***
  52. *_searchenv() - search for file along paths from environment variable
  53. *
  54. *Purpose:
  55. * to search for a specified file in the directory(ies) specified by
  56. * a given environment variable, and, if found, to return the full
  57. * path name of the file. The file is first looked for in the current
  58. * working directory, prior to looking in the paths specified by env_var.
  59. *
  60. *Entry:
  61. * fname - name of file to search for
  62. * env_var - name of environment variable to use for paths
  63. * path - pointer to storage for the constructed path name
  64. *
  65. *Exit:
  66. * path - pointer to constructed path name, if the file is found, otherwise
  67. * it points to the empty string.
  68. *
  69. *Exceptions:
  70. *
  71. *******************************************************************************/
  72. void __cdecl _tsearchenv (
  73. const _TSCHAR *fname,
  74. const _TSCHAR *env_var,
  75. _TSCHAR *path
  76. )
  77. {
  78. register _TSCHAR *p;
  79. register int c;
  80. _TSCHAR *env_p;
  81. size_t len;
  82. _TSCHAR pathbuf[_MAX_PATH + 4];
  83. if (_taccess(fname, 0) == 0) {
  84. #if !defined(_POSIX_)
  85. /* exists, convert it to a fully qualified pathname and
  86. return */
  87. if ( _tfullpath(path, fname, _MAX_PATH) == NULL )
  88. *path = _T('\0');
  89. #else /* !_POSIX_ */
  90. /* exists in this directory - get cwd and concatenate file
  91. name */
  92. #if defined(_POSIX_)
  93. if (getcwd(path, _MAX_PATH))
  94. #else
  95. if (_tgetcwd(path, _MAX_PATH))
  96. #endif
  97. {
  98. _tcscat(path, fname);
  99. }
  100. #endif /* !_POSIX_ */
  101. return;
  102. }
  103. if ((env_p = _tgetenv(env_var)) == NULL) {
  104. /* no such environment var. and not in cwd, so return empty
  105. string */
  106. *path = _T('\0');
  107. return;
  108. }
  109. #ifdef _UNICODE
  110. while ( (env_p = _wgetpath(env_p, pathbuf, _MAX_PATH)) && *pathbuf ) {
  111. #else
  112. while ( (env_p = _getpath(env_p, pathbuf, _MAX_PATH)) && *pathbuf ) {
  113. #endif
  114. /* path now holds nonempty pathname from env_p, concatenate
  115. the file name and go */
  116. len = _tcslen(pathbuf);
  117. p = pathbuf + len;
  118. if ( ((c = *(p - 1)) != _T('/')) && (c != _T('\\')) &&
  119. (c != _T(':')) )
  120. {
  121. /* add a trailing '\' */
  122. *p++ = _T('\\');
  123. len++;
  124. }
  125. /* p now points to character following trailing '/', '\'
  126. or ':' */
  127. if ( (len + _tcslen(fname)) <= _MAX_PATH ) {
  128. _tcscpy(p, fname);
  129. if ( _taccess(pathbuf, 0) == 0 ) {
  130. /* found a match, copy the full pathname into the caller's
  131. buffer */
  132. _tcscpy(path, pathbuf);
  133. return;
  134. }
  135. }
  136. }
  137. /* if we get here, we never found it, return empty string */
  138. *path = _T('\0');
  139. }