home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / sysutl / pathadd.arc / PATHADD.C next >
Encoding:
C/C++ Source or Header  |  1989-02-09  |  7.4 KB  |  229 lines

  1. /*****************************************************************************
  2.  
  3.    PATHADD.C    Add to the existing DOS PATH
  4.    Paul Mazurk  74726,252          February 6, 1989
  5.  
  6.    I wrote main() which simply uses two functions uploaded by Clay Davis
  7.    (76346,101 on CompuServe) which he "translated" from Turbo-C
  8.    routines written by David Dubois. These two functions are the
  9.    real work of this program. The upload containing these and other
  10.    environment-modifying functions is an ARChive containing GLBL_ENV.C.
  11.  
  12.    This was written for two reasons:
  13.     1. For its usefulness.
  14.     2. Because everything I read said the Master Environment
  15.        could not be modified by a program.
  16.  
  17.    ************************************************************************
  18.    As David Dubois says:
  19.  
  20.   I hereby dedicate this knowledge to the public domain. Feel free to use
  21.   it, but if you do, please mention my name. There are no guarantees, and
  22.   in fact, I wouldn't bet a dollar that it will work every time.
  23.  
  24.   That this works at all is based on experimental, rather than properly
  25.   documented, evidence. There are no guarantees. But then, its free.
  26.  
  27. *****************************************************************************/
  28.  
  29. #include <dos.h>
  30. #include <stdio.h> /* MS-C requires this */
  31. #include <stdlib.h> /* MS-C requires this */
  32. #include <string.h>
  33. #include <malloc.h> /* MS-C uses this instead of alloc.h */
  34.  
  35. /*
  36.  *   Mstr_FindEnvironment:
  37.  *     Scans for the "Master" Environment area, and returns
  38.  *     a pointer to it, and the size of the environment.
  39. */
  40. void Mstr_FindEnvironment ( char far **Env , unsigned *EnvSize )
  41. {
  42.    unsigned int far *CommandSeg;
  43.    unsigned int far *TempSeg ;
  44.    char far *BlockSeg ;
  45.  
  46.    /*
  47.     *  Scan through PSP's looking for a block that is its own father.
  48.     *  This block is the PSP of COMMAND.COM
  49.    */
  50.   TempSeg = _psp * 0x10000; /* Convert to a far pointer, replaces MK_FP */
  51.    do
  52.    {
  53.      CommandSeg = TempSeg ;
  54.      TempSeg = *(TempSeg+8)*0x10000; /* Replaces MK_FP in turbo C */
  55.    }
  56.    while ( TempSeg != CommandSeg ) ;
  57.  
  58.    /*
  59.     *  Scan forward through memory looking for the correct MSB.
  60.     *  This will have COMMAND.COM's PSP as owner, and begin with
  61.     *  the character M
  62.    */
  63.    BlockSeg = (char far *)CommandSeg ;
  64.    do
  65.    {
  66.     BlockSeg = (FP_SEG(BlockSeg)+1)*0x10000; /* Replaces MK_FP */
  67.    }
  68.    while ( ( *(unsigned int far *)(BlockSeg+1) != FP_SEG ( CommandSeg ) ) ||
  69.            ( *BlockSeg != 'M' ) ) ;
  70.  
  71.    /*
  72.     *  The environment is the NEXT segment of memory
  73.     *  and bytes 4 and 5 are the size in paragraphs
  74.    */
  75.    *Env = (FP_SEG(BlockSeg)+1)*0x10000; /* Replaces MK_FP */
  76.    *EnvSize = 16 * *(unsigned int far *)(BlockSeg+3) ;
  77. }
  78.  
  79. /*
  80.  *   Mstr_getenv:
  81.  *     Scans the "Master" Environment for a given "sub string"
  82.  *     and returns a pointer to it.
  83.  *     Similar to Turbo routine "getenv" but uses the Master copy of the
  84.  *     environment table.
  85. */
  86. char far *Mstr_getenv (char far *Env , char far *name)
  87. {
  88.    char far *Sub_Env, far *str1, far *str2 ;
  89.  
  90.    /*
  91.     *  Start at the beginning of the environment
  92.    */
  93.    Sub_Env = Env ;
  94.  
  95.    /*
  96.     *  While the "sub string" we're looking at is non-zero
  97.    */
  98.    for ( ; *Sub_Env ; )
  99.    {
  100.      /*
  101.       *  Simulate a "strcmp" on the "sub string" of the environment
  102.       *  and the string we're looking for
  103.      */
  104.      for ( str1 = Sub_Env , str2 = name ;
  105.            (*str1) && (*str2) && ( *str1 == *str2) ;
  106.            str1++ , str2++ ) ;
  107.      /*
  108.       *  If we reached the end of the string we're looing for
  109.       *  we've found the correct portion of the environment.
  110.       *  Return the ptr to the start of this "sub string"
  111.      */
  112.      if ( !*str2 )
  113.        return ( Sub_Env ) ;
  114.  
  115.      /*
  116.       *  Otherwise, advance to the next "sub string" in the environment
  117.       *  by performing a "strchr" function
  118.      */
  119.      for ( ; *(Sub_Env++) ; ) ;
  120.    }
  121.  
  122.    /*
  123.     *  Obviously, the string is not present in the environment.
  124.     *  Return this fact.
  125.    */
  126.   return ( NULL ) ;
  127. }
  128.  
  129.  
  130.  
  131.  
  132. main(int argc, char *argv[])
  133. {
  134.   char far *Env;
  135.   char far *EndOfPath;
  136.   char far *EndOfEnv;
  137.   char ch,ch1;
  138.   char *scratchcopy;
  139.   int i,j ;
  140.   unsigned EnvSize ;
  141.  
  142.   /** Display proper syntax if required **/
  143.   if (argc < 2) {
  144.   printf("╔══════════════════════════════════════════════════════════════════════╗\n");
  145.   printf("║  Usage: pathadd X  \(X = new path to be added to existing path\).      ║ \n");
  146.   printf("║                                                                      ║\n");
  147.   printf("║  Example - If the current path is c:\\;c:\\dos  and you wish to        ║ \n");
  148.   printf("║  add  c:\\utilities, the syntax would be \"pathadd c:\\utilities\" .     ║\n");
  149.   printf("║                                                                      ║\n");
  150.   printf("║  Semi-colons will be added to the end of the existing path if        ║      \n");
  151.   printf("║  required. No check is made as to the validity of the new path name. ║ \n");
  152.   printf("╚══════════════════════════════════════════════════════════════════════╝\n\n");
  153.   exit(1);
  154.         }
  155.  
  156.   /*  Locate the Master Table */
  157.    Mstr_FindEnvironment ( &Env, &EnvSize ) ;
  158.  
  159.    /**** Find the End of the Existing Environment strings ***/
  160.    /*** It will be marked by two consecutive nulls ***/
  161.    i = 0; ch = ch1 = 'x';
  162.    EndOfEnv = Env;
  163.    while ( ch1 ) {
  164.           ch = *(Env + i++);
  165.           if ( !ch ) ch1 = *(Env + i);
  166.           EndOfEnv++;
  167.           }
  168.  
  169.    if ( (EndOfPath = Mstr_getenv( Env, "PATH=")) == NULL)
  170.         {    /** Install the new Path **/
  171.         /* Set up the Scratch Copy */
  172.         scratchcopy = (char *) malloc(EnvSize);
  173.         *scratchcopy = '\0';
  174.         strcat(scratchcopy,"PATH=");
  175.         strcat(scratchcopy,strupr(argv[1]));
  176.  
  177.         for( i = 0; i <= strlen(scratchcopy); i++)
  178.         *(EndOfEnv + i) = *(scratchcopy + i);
  179.         printf("%s has been installed and is currently the only PATH.\n",strupr(argv[1]));
  180.         exit(2);
  181.         }
  182.    while ( *(EndOfPath) ) EndOfPath++; /* Find the End of the Current Path */
  183.  
  184.    /* Set up the Scratch Copy */
  185.    scratchcopy = (char *) malloc(EnvSize);
  186.  
  187.    /* Fill the scratch copy with current environment contents, replacing
  188.       nulls with tildes so the whole scratch copy can be dealt with as
  189.       a string */
  190.    i = 0;
  191.       while ( (Env + i) < EndOfPath)
  192.       {
  193.       *(scratchcopy + i) = ( *(Env + i) ? *(Env + i) : '~' );
  194.       i += 1;
  195.       }
  196.    *(scratchcopy + i) = '\0';
  197.  
  198.    /* Add a semi-colon to the end of the current path if necessary */
  199.    /* It is not necessary if all we have is "PATH=" */
  200.    ch = *(scratchcopy + strlen(scratchcopy) - 1);
  201.    if ( (ch != ';') && (ch != '=') ) strcat(scratchcopy,";");
  202.  
  203.    /* Add the additional path to the scratch copy */
  204.    /* Convert to upper case for asthetic reasons */
  205.    strcat(scratchcopy,strupr(argv[1]));
  206.  
  207.    /**** Add the rest of the environment to the new path ***/
  208.    strcat(scratchcopy,"~");
  209.    for (i = strlen(scratchcopy + 1),j = 0; j <= EndOfEnv - EndOfPath; j++)
  210.    *(scratchcopy + i++) = ( *(EndOfPath + j) ? *(EndOfPath + j) : '~' );
  211.    *(scratchcopy + i) = '\0';
  212.  
  213.    /** Change the Environment **/
  214.    i = 0;
  215.    while (i < strlen(scratchcopy))
  216.       {
  217.       *(Env + i) = ( *(scratchcopy + i) == '~' ? 0 : *(scratchcopy + i) );
  218.       i += 1;
  219.       }
  220.  
  221.    /** Free allocated memory **/
  222.    free(scratchcopy);
  223.  
  224.    /** Final word of advice **/
  225.    printf("Use the   SET   command to view the new environment.\n\n");
  226.  
  227.    exit(0);
  228.    } /** End of MAIN() **/
  229.