home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / getenv.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  8KB  |  318 lines

  1. /***
  2. *getenv.c - get the value of an environment variable
  3. *
  4. *       Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       defines getenv() - searches the environment for a string variable
  8. *       and returns the value of it.
  9. *
  10. *******************************************************************************/
  11.  
  12. #ifdef _WIN32
  13.  
  14. #include <cruntime.h>
  15. #include <internal.h>
  16. #include <mtdll.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <tchar.h>
  20.  
  21. #ifndef CRTDLL
  22.  
  23. /*
  24.  * Flag checked by getenv() and _putenv() to determine if the environment has
  25.  * been initialized.
  26.  */
  27. extern int __env_initialized;
  28.  
  29. #endif  /* CRTDLL */
  30.  
  31. /***
  32. *char *getenv(option) - search environment for a string
  33. *
  34. *Purpose:
  35. *       searches the environment for a string of the form "option=value",
  36. *       if found, return value, otherwise NULL.
  37. *
  38. *Entry:
  39. *       const char *option - variable to search for in environment
  40. *
  41. *Exit:
  42. *       returns the value part of the environment string if found,
  43. *       otherwise NULL
  44. *
  45. *Exceptions:
  46. *
  47. *******************************************************************************/
  48.  
  49. #ifdef _MT
  50.  
  51.  
  52. #ifdef WPRFLAG
  53. wchar_t * __cdecl _wgetenv (
  54. #else  /* WPRFLAG */
  55. char * __cdecl getenv (
  56. #endif  /* WPRFLAG */
  57.         const _TSCHAR *option
  58.         )
  59. {
  60.         _TSCHAR *retval;
  61.  
  62.         _mlock(_ENV_LOCK);
  63.  
  64. #ifdef WPRFLAG
  65.         retval = _wgetenv_lk(option);
  66. #else  /* WPRFLAG */
  67.         retval = _getenv_lk(option);
  68. #endif  /* WPRFLAG */
  69.  
  70.         _munlock(_ENV_LOCK);
  71.  
  72.         return(retval);
  73.  
  74. }
  75.  
  76.  
  77. #ifdef WPRFLAG
  78. wchar_t * __cdecl _wgetenv_lk (
  79. #else  /* WPRFLAG */
  80. char * __cdecl _getenv_lk (
  81. #endif  /* WPRFLAG */
  82.         const _TSCHAR *option
  83.         )
  84.  
  85. #else  /* _MT */
  86.  
  87. #ifdef WPRFLAG
  88. wchar_t * __cdecl _wgetenv (
  89. #else  /* WPRFLAG */
  90. char * __cdecl getenv (
  91. #endif  /* WPRFLAG */
  92.         const _TSCHAR *option
  93.         )
  94.  
  95. #endif  /* _MT */
  96.  
  97. {
  98.         _TSCHAR **search = _tenviron;
  99.         unsigned int length;
  100.  
  101. #ifndef CRTDLL
  102.         /*
  103.          * Make sure the environment is initialized.
  104.          */
  105.         if ( !__env_initialized )
  106.             return NULL;
  107. #endif  /* CRTDLL */
  108.  
  109.         /*
  110.          * At startup, we obtain the 'native' flavor of environment strings
  111.          * from the OS. So a "main" program has _environ and a "wmain" has
  112.          * _wenviron loaded at startup. Only when the user gets or puts the
  113.          * 'other' flavor do we convert it.
  114.          */
  115.  
  116.  
  117. #ifdef WPRFLAG
  118.         if (!search && _environ)
  119.         {
  120.             /* don't have requested type, but other exists, so convert it */
  121.             if (__mbtow_environ() != 0)
  122.                 return NULL;
  123.  
  124.             /* now requested type exists */
  125.             search = _wenviron;
  126.         }
  127. #else  /* WPRFLAG */
  128.         if (!search && _wenviron)
  129.         {
  130.             /* don't have requested type, but other exists, so convert it */
  131.             if (__wtomb_environ() != 0)
  132.                 return NULL;
  133.  
  134.             /* now requested type exists */
  135.             search = _environ;
  136.         }
  137. #endif  /* WPRFLAG */
  138.  
  139.  
  140.         if (search && option)
  141.         {
  142.                 length = _tcslen(option);
  143.  
  144.                 /*
  145.                 ** Make sure `*search' is long enough to be a candidate
  146.                 ** (We must NOT index past the '\0' at the end of `*search'!)
  147.                 ** and that it has an equal sign (`=') in the correct spot.
  148.                 ** If both of these requirements are met, compare the strings.
  149.                 */
  150.                 while (*search)
  151.                 {
  152.                         if (_tcslen(*search) > length && (*(*search + length)
  153.                         == _T('=')) && (_tcsnicoll(*search, option, length) == 0)) {
  154.                                 return(*search + length + 1);
  155.                         }
  156.  
  157.                         search++;
  158.                 }
  159.         }
  160.  
  161.         return(NULL);
  162. }
  163.  
  164. #else  /* _WIN32 */
  165.  
  166.  
  167. #include <cruntime.h>
  168. #include <stdlib.h>
  169. #include <string.h>
  170. #include <mtdll.h>
  171. #include <dbgint.h>
  172.  
  173. /***
  174. *char *getenv(option) - search environment for a string
  175. *
  176. *Purpose:
  177. *       searches the environment for a string of the form "option=value",
  178. *       if found, return value, otherwise NULL.
  179. *
  180. *Entry:
  181. *       const char *option - variable to search for in environment
  182. *
  183. *Exit:
  184. *       returns the value part of the environment string if found,
  185. *       otherwise NULL
  186. *
  187. *Exceptions:
  188. *
  189. *******************************************************************************/
  190.  
  191. #ifdef _MT
  192.  
  193.  
  194. char * __cdecl getenv (
  195.         const char *option
  196.         )
  197. {
  198.         char *retval;
  199.  
  200.         _mlock(_ENV_LOCK);
  201.  
  202.         retval = _getenv_lk(option);
  203.  
  204.         _munlock(_ENV_LOCK);
  205.  
  206.         return(retval);
  207.  
  208. }
  209.  
  210.  
  211. char * __cdecl _getenv_lk (
  212.         const char *option
  213.         )
  214.  
  215. #else  /* _MT */
  216.  
  217. char * __cdecl getenv (
  218.         const char *option
  219.         )
  220.  
  221. #endif  /* _MT */
  222. {
  223.         char **search = _environ;
  224.         unsigned int length;
  225.  
  226.         if (search && option)
  227.         {
  228.  
  229.                 length = strlen(option);
  230.  
  231.                 /*
  232.                 ** Make sure `*search' is long enough to be a candidate
  233.                 ** (We must NOT index past the '\0' at the end of `*search'!)
  234.                 ** and that it has an equal sign (`=') in the correct spot.
  235.                 ** If both of these requirements are met, compare the strings.
  236.                 */
  237.                 while (*search)
  238.                 {
  239.                         if (strlen(*search) > length && (*(*search + length)
  240.                         == '=') && (_strnicmp(*search, option, length) == 0)) {
  241.                                 return(*search + length + 1);
  242.                         }
  243.  
  244.                         search++;
  245.                 }
  246.         }
  247.  
  248.         return(NULL);
  249. }
  250.  
  251.  
  252. /***
  253. * void _envinit(void) - initialization routine for the env table  This code
  254. *                                                               is here rather than crt0 so that the env malloc is
  255. *                                                               only done if absolutely necessary.
  256. *
  257. *Purpose:
  258. *       If the user has used getenv() then copy the MPW environment
  259. *
  260. *Entry:
  261. *       None.
  262. *
  263. *Exit:
  264. *
  265. *Exceptions:
  266. *
  267. *******************************************************************************/
  268.  
  269. #include <mpw.h>
  270. #include <fltintrn.h>
  271.  
  272. extern MPWBLOCK *_pMPWBlock;
  273.  
  274. void __cdecl _envinit (
  275.         void
  276.         )
  277. {
  278.  
  279.         if (_pMPWBlock != NULL && _pMPWBlock->env != NULL)
  280.                 {
  281.                 char **ppch;
  282.                 char **ppchNew;
  283.                 char *pch;
  284.                 int cb;
  285.  
  286.  
  287.                 /* Calculate and allocate a block for env pointers */
  288.                 for (ppch = _pMPWBlock->env; *ppch != NULL; ppch++);
  289.                 _environ = _malloc_crt((char *)(ppch + 1) - (char *)_pMPWBlock->env);
  290.  
  291.                 /* Copy the env strings */
  292.                 ppchNew = _environ;
  293.                 for (ppch = _pMPWBlock->env; *ppch != NULL; ppch++)
  294.                         {
  295.                         cb = strlen(*ppch) + 1;
  296.                         *ppchNew = _malloc_crt(cb + strlen(*ppch + cb) + 1);
  297.                         pch = *ppchNew++;
  298.                         strcpy(pch,*ppch);
  299.                         pch += cb - 1;
  300.                         *pch++ = '=';
  301.                         strcpy(pch, *ppch + cb);
  302.                         }
  303.                 *ppchNew = NULL;
  304.                 }
  305.  
  306. }
  307.  
  308. /* define the entry in initializer table */
  309.  
  310. #pragma data_seg(".CRT$XIC")
  311.  
  312. static PFV __penvinit = _envinit;
  313.  
  314. #pragma data_seg()
  315.  
  316. #endif  /* _WIN32 */
  317.  
  318.