home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 December / simtel1292_SIMTEL_1292_Walnut_Creek.iso / msdos / pcmag / vol6n07.arc / READENV.C < prev    next >
Text File  |  1987-12-13  |  10KB  |  260 lines

  1. /* readenv.c RHS 12/15/86 rev.
  2.  *
  3.  * This program demonstrates how to:
  4.  
  5.         1. Read the Environment strings from a C program.
  6.         2. Find a specific environment variable and copy it and its string to a
  7.             local buffer for further use.
  8.  */
  9.  
  10. #include<stdio.h>   /* include standard C header file */
  11.  
  12. #ifndef TRUE
  13. #define TRUE 1
  14. #define FALSE 0
  15. #endif
  16.  
  17. /* This code was written utilizing the DeSmet C library functions.
  18.  * For compatibility with some C compilers, some of the source code here may
  19.  * have to be changed.  For immediate compatibility with Microsoft C 4.0,
  20.  * change the word FALSE on the following line to read TRUE.
  21.  */
  22. #define MSC FALSE
  23.  /* This will insure compatibility with Microsoft C 4.0.
  24.  */
  25.  
  26. #if MSC
  27. #include<memory.h>
  28. #include<ctype.h>
  29. #include<dos.h>
  30. #define _lmove(num,soff,sseg,doff,dseg)     movedata(sseg,soff,dseg,doff,num)
  31. #define _pcb _psp
  32. #endif
  33.  
  34. char *getvar();     /* declare functions returning pointers to characters */
  35. extern unsigned _pcb;   /* declare external variable that holds PSP value */
  36.  
  37. main()              /* Our program begins here. */
  38. {
  39.     /* If the Environment variable passed to getvar() is found, this pointer
  40.      * will receive from getvar() the address of a buffer where the entire
  41.      * string will be placed.  If the variable is NOT found, the pointer will
  42.      * be set by getvar() to NULL.
  43.      */
  44.     char *path_string;      /* declare the local pointer */
  45.  
  46.         /* Now, call SET() a function that imitates the DOS SET command by
  47.          * reading the Environment strings one-by-one and printing them on
  48.          * the console.  It's code is included below.
  49.          */
  50.     set();                  /* print the environment strings on the console */
  51.  
  52.         /* Next, call GETVAR() to find the PATH variable.  If PATH is found,
  53.          * the entire path string will be copied by GETVAR() to a buffer.
  54.          * Then GETVAR() will return the address of the buffer, and place it in
  55.          * path_string.
  56.          */
  57.     if(path_string = getvar("PATH"))
  58.         /* So, if path_string is NOT NULL, it will point to the full PATH
  59.          * variable, and we can print it on the console.  We do this by
  60.          * calling PRINTF(), a standard library function, to print the string
  61.          * pointed to by path_string.
  62.          */
  63.         printf("\n%s",path_string);
  64.  
  65.     exit(0);        /* Exit this program */
  66. }
  67.  
  68.     /************************* SUBROUTINES: *******************/
  69.  
  70.     /*********************** Subroutine Data *****************/
  71.  
  72. #define ENVIRONMENT_OFFSET 0x2C   /* Offset address of Environ. Copy in PSP */
  73. #define MAXIMUM_ENV_STRING 127    /* macro for max. Environ. string length */
  74.  
  75.         /* macros for controlling find_env_string() */
  76. #define FIRST 1                   /* find first string */
  77. #define NEXT 0                    /* find next string */
  78.  
  79.     /* Buffer in which to copy an Environment string - includes 2 extra
  80.      * spaces for NULL-terminators at end of string or end of Environment.
  81.      */
  82. char env_string_buffer[MAXIMUM_ENV_STRING+2];
  83.  
  84. int env_offset = 0;             /* variable for offset into the Environment */
  85. unsigned Environment = 0;       /* variable for Environment segment address */
  86.  
  87.     /* SET() ***************************************************/
  88.     /* calls FIND_ENV_STRING() successively in a loop and prints each
  89.      * environment string found, until the End of the Environment is found.
  90.      */
  91. set()
  92. {
  93.     int restart;        /* restart variable */
  94.  
  95.         /* Initialize restart to find FIRST string.
  96.          * Call FIND_ENV_STRING() as long as it returns TRUE.
  97.          * Set restart to find NEXT string after the first call.
  98.          */
  99.     for( restart = FIRST ; find_env_string(restart); restart = NEXT)
  100.  
  101.             /* Call PRINTF() to print contents of buffer */
  102.         printf("\n%s",env_string_buffer);
  103. }
  104.  
  105.     /* GETVAR() ************************************************/
  106.     /* Calls FIND_ENV_STRING() repeatedly until an Environment string
  107.      * with "name" as the variable name is found, or until FIND_ENV_STRING()
  108.      * returns FALSE, signaling that the end of the Environment was reached.
  109.      * If the string with the right variable name is found, GETVAR() returns
  110.      * a pointer to the Environment string buffer, otherwise it returns a
  111.  
  112.      * NULL.
  113.      */
  114. char *getvar(name)
  115. char *name;
  116. {
  117.     int len;                        /* variable to hold length of name */
  118.     int restart;                    /* variable to hold search control */
  119.  
  120.                 /* Call standard library function STRLEN() to get the
  121.                  * length of name and place it in len.
  122.                  */
  123.     len = strlen(name);
  124.  
  125.                 /* Call function UPPER() to force name to upper case, since
  126.                  * DOS forces all Environment variable names to upper case.
  127.                  */
  128.     upper(name);
  129.  
  130.         /* Main search loop:
  131.          * Set restart for search for 1st environment string.
  132.          * Loop while FIND_ENV_STRING() returns TRUE.
  133.          * Reset restart for search for further environment strings.
  134.          */
  135.     for( restart = FIRST ; find_env_string(restart); restart = NEXT)
  136.  
  137.         /* Try to match the variable name with the 1st characters in the
  138.          * Environment string found.  Make sure that the 1st character past
  139.          * the end of the name in the string is a '=' so we really have the
  140.          * whole string.  This way we don't confuse PATH, for instance, with
  141.          * some other string like PATH1.
  142.          */
  143.     if(!strncmp(name,env_string_buffer,len) && env_string_buffer[len] == '=')
  144.  
  145.                 /* if a match, return the address of the buffer */
  146.             return env_string_buffer;
  147.  
  148.         /* Otherwise, we broke out of the loop which means we didn't find the
  149.          * string.  So return a NULL.
  150.          */
  151.     return (char *)NULL;
  152. }
  153.  
  154.     /* FIND_ENV_STRING() ****************************************/
  155.     /* Finds the Environment strings, and copies the 1st one into
  156.      * env_string_buffer, as long as restart is equal to FIRST.  If
  157.      * NOT, finds the next sucessive string and copies IT into the buffer.
  158.      * Returns TRUE if a string is found, or FALSE if end of Environment is
  159.      * found.
  160.      */
  161.  
  162. find_env_string(restart)
  163. int restart;
  164.  
  165. {
  166.     int buffer_offset;        /* variable for offset into env_string_buffer */
  167.     unsigned _showds();
  168.  
  169.         /* If the Environment address has NOT already been obtained, */
  170.     if(!Environment)
  171.  
  172.  /* Get the Segment address of the current DOS Environment copy into the
  173.   * variable Environment.  _SHOWCS() and _SHOWDS() are DeSmet C functions
  174.   * that return the current Code and Data segment register values respectively.
  175.   * _LMOVE() is a DeSmet C function that moves a variable number of bytes
  176.   * from an offset in one segment to an offset in other segment.  Here we
  177.   * move 2 bytes from offset 2Ch in the PSP (which is at Code Segment-0x10
  178.   * in C), to the address of "Environment" in the current Data Segment.
  179.   */
  180.         _lmove( 2, ENVIRONMENT_OFFSET, _pcb,  &Environment, _showds());
  181.  
  182.         /* If we want to start with the 1st string, reset env_offset to Zero.
  183.          */
  184.     if(restart)
  185.         env_offset = 0;
  186.  
  187.             /* Initialize Buffer offset to zero.
  188.              * Loop continuously until the end an Environment string is found.
  189.              * Increment the Environment Offset by 1 at the end of every loop.
  190.              */
  191.     for( buffer_offset = 0; TRUE ; env_offset++ ){
  192.  
  193.             /* Copy 2 bytes from the environment offset in the Environment
  194.              * segment, to the buffer_offset in the Environment string buffer.
  195.              */
  196.         _lmove( 2, env_offset, Environment,
  197.             env_string_buffer[buffer_offset], _showds());
  198.  
  199.             /* If a Non-zero character was found and placed in the current
  200.              * offset in the buffer, loop back for another one.
  201.              */
  202.         if(env_string_buffer[buffer_offset]){
  203.             buffer_offset++;
  204.             continue;
  205.         }
  206.  
  207.             /* We must have found a Zero to get this far without looping back.
  208.              * If buffer_offset is Zero, the 1st character found was a Zero and
  209.              * we are at the end of the Environment strings - return FALSE.
  210.              */
  211.         if( !buffer_offset)
  212.             return FALSE;
  213.  
  214.             /* Otherwise, We have found the end of a string, so increment the
  215.              * Environment offset by one to point to the next one for next time.
  216.              * Then return TRUE (TRUE that we did NOT find the end of the
  217.              * Environment strings.
  218.              */
  219.         env_offset++;
  220.         return TRUE;
  221.     }
  222. }
  223.  
  224.     /* UPPER() *******************************************/
  225.     /* Uppercases the string passed by calling the standard library function,
  226.      * TOUPPER(), which returns the uppercase version of a single character.
  227.      */
  228. upper(string)
  229. char *string;
  230. {
  231.         /* A simple "FOR" loop in C:
  232.          * Nothing is initialized.
  233.          * Loop as long as the character pointed to by string is not a Zero
  234.          * (a NULL-terminator).
  235.          * Then increment the pointer to point to the next character.
  236.          */
  237.     for( ; *string; string++)
  238.             /* For each character, call TOUPPER() to return the uppercase
  239.              * version of the character, and set the character to it.
  240.              */
  241.         *string = toupper(*string);
  242.  
  243. }
  244.  
  245. #if MSC
  246.     /* _SHOWDS() ********************************************/
  247.     /* Returns DS register value.
  248.      */
  249.  
  250. unsigned _showds()
  251. {
  252.     struct SREGS segregs;
  253.  
  254.     segread(&segregs);
  255.     return segregs.ds;
  256. }
  257. #endif
  258.  
  259.      /*********************** End of Readenv.c ****************/
  260.