Source code of Windows XP (NT5)
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.

183 lines
5.7 KiB

  1. /***
  2. *getpath.c - extract a pathname from an environment variable
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Extract pathnames from a string of semicolon delimited pathnames
  8. * (generally the value of an environment variable such as PATH).
  9. *
  10. *Revision History:
  11. * 08-25-89 GJF Module created (taken from SEARCHEN.C and revised)
  12. * 03-14-90 GJF Replaced near with _CALLTYPE1 and added #include
  13. * <cruntime.h>
  14. * 07-25-90 SBM Replaced <stdio.h> by <stddef.h>
  15. * 10-04-90 GJF New-style function declarator.
  16. * 04-26-91 SRW Removed level 3 warnings
  17. * 09-18-91 JCR Strip off leading semi-colons (bug fix)
  18. * 09-25-91 JCR Changed ifdef "OS2" to "_HPFS_" and defined it
  19. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  20. * 12-07-93 CFW Wide char enable.
  21. * 02-16-95 JWM Mac merge.
  22. * 05-17-99 PML Remove all Macintosh support.
  23. *
  24. *******************************************************************************/
  25. #include <cruntime.h>
  26. #include <stddef.h>
  27. #include <internal.h>
  28. #include <tchar.h>
  29. /* support HPFS file system */
  30. #define _HPFS_ 1
  31. /***
  32. *_getpath() - extract a pathname from a semicolon-delimited list of pathnames
  33. *
  34. *Purpose:
  35. * To extract the next pathname from a semicolon-delimited list of
  36. * pathnames (usually the value on an environment variable) and copy
  37. * it to a caller-specified buffer. No check is done to see if the path
  38. * is valid. The maximum number of characters copied to the buffer is
  39. * maxlen - 1 (and then a '\0' is appended).
  40. *
  41. *ifdef _HPFS_
  42. * If we hit a quoted string, then allow any characters inside.
  43. * For example, to put a semi-colon in a path, the user could have
  44. * an environment variable that looks like:
  45. *
  46. * PATH=C:\BIN;"D:\CRT\TOOLS;B1";C:\BINP
  47. *endif
  48. *
  49. * NOTE: Semi-colons in sequence are skipped over; pointers to 0-length
  50. * pathnames are NOT returned (this includes leading semi-colons).
  51. *
  52. * NOTE: If this routine is made user-callable, the near attribute
  53. * must be replaced by _LOAD_DS and the prototype moved from INTERNAL.H
  54. * to STDLIB.H. The source files MISC\SEARCHEN.C and EXEC\SPAWNVPE.C
  55. * will need to be recompiled, but should not require any changes.
  56. *
  57. *Entry:
  58. * src - Pointer to a string of 0 or more path specificiations,
  59. * delimited by semicolons (';'), and terminated by a null
  60. * character
  61. * dst - Pointer to the buffer where the next path specification is to
  62. * be copied
  63. * maxlen - Maximum number of characters to be copied, counting the
  64. * terminating null character. Note that a value of 0 is treated
  65. * as UINT_MAX + 1.
  66. *
  67. *Exit:
  68. * If a pathname is successfully extracted and copied, a pointer to the
  69. * first character of next pathname is returned (intervening semicolons
  70. * are skipped over). If the pathname is too long, as much as possible
  71. * is copied to the user-specified buffer and NULL is returned.
  72. *
  73. * Note that the no check is made of the validity of the copied pathname.
  74. *
  75. *Exceptions:
  76. *
  77. *******************************************************************************/
  78. #ifdef WPRFLAG
  79. wchar_t * __cdecl _wgetpath (
  80. #else
  81. char * __cdecl _getpath (
  82. #endif
  83. register const _TSCHAR *src,
  84. register _TSCHAR *dst,
  85. unsigned maxlen
  86. )
  87. {
  88. const _TSCHAR *save_src;
  89. /*
  90. * strip off leading semi colons
  91. */
  92. while ( *src == _T(';') )
  93. src++;
  94. /*
  95. * Save original src pointer
  96. */
  97. save_src = src;
  98. /*
  99. * Decrement maxlen to allow for the terminating _T('\0')
  100. */
  101. if ( --maxlen == 0 )
  102. goto appendnull;
  103. /*
  104. * Get the next path in src string
  105. */
  106. while (*src && (*src != _T(';'))) {
  107. #if defined(_HPFS_)
  108. /*
  109. * Check for quote char
  110. */
  111. if (*src != _T('"')) {
  112. *dst++ = *src++;
  113. if ( --maxlen == 0 ) {
  114. save_src = src; /* ensure NULL return */
  115. goto appendnull;
  116. }
  117. }
  118. else {
  119. /*
  120. * Found a quote. Copy all chars until we hit the
  121. * final quote or the end of the string.
  122. */
  123. src++; /* skip over opening quote */
  124. while (*src && (*src != _T('"'))) {
  125. *dst++ = *src++;
  126. if ( --maxlen == 0 ) {
  127. save_src = src; /* ensure NULL return */
  128. goto appendnull;
  129. }
  130. }
  131. if (*src)
  132. src++; /* skip over closing quote */
  133. }
  134. #else
  135. *dst++ = *src++;
  136. if ( --maxlen == 0 ) {
  137. save_src = src; /* ensure NULL return */
  138. goto appendnull;
  139. }
  140. #endif
  141. }
  142. /*
  143. * If we copied something and stopped because of a _T(';'),
  144. * skip the _T(';') before returning
  145. */
  146. while ( *src == _T(';') )
  147. src++;
  148. /*
  149. * Store a terminating null
  150. */
  151. appendnull:
  152. *dst = _T('\0');
  153. return((save_src != src) ? (_TSCHAR *)src : NULL);
  154. }