home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
-
- PATHADD.C Add to the existing DOS PATH
- Paul Mazurk 74726,252 February 6, 1989
-
- I wrote main() which simply uses two functions uploaded by Clay Davis
- (76346,101 on CompuServe) which he "translated" from Turbo-C
- routines written by David Dubois. These two functions are the
- real work of this program. The upload containing these and other
- environment-modifying functions is an ARChive containing GLBL_ENV.C.
-
- This was written for two reasons:
- 1. For its usefulness.
- 2. Because everything I read said the Master Environment
- could not be modified by a program.
-
- ************************************************************************
- As David Dubois says:
-
- I hereby dedicate this knowledge to the public domain. Feel free to use
- it, but if you do, please mention my name. There are no guarantees, and
- in fact, I wouldn't bet a dollar that it will work every time.
-
- That this works at all is based on experimental, rather than properly
- documented, evidence. There are no guarantees. But then, its free.
-
- *****************************************************************************/
-
- #include <dos.h>
- #include <stdio.h> /* MS-C requires this */
- #include <stdlib.h> /* MS-C requires this */
- #include <string.h>
- #include <malloc.h> /* MS-C uses this instead of alloc.h */
-
- /*
- * Mstr_FindEnvironment:
- * Scans for the "Master" Environment area, and returns
- * a pointer to it, and the size of the environment.
- */
- void Mstr_FindEnvironment ( char far **Env , unsigned *EnvSize )
- {
- unsigned int far *CommandSeg;
- unsigned int far *TempSeg ;
- char far *BlockSeg ;
-
- /*
- * Scan through PSP's looking for a block that is its own father.
- * This block is the PSP of COMMAND.COM
- */
- TempSeg = _psp * 0x10000; /* Convert to a far pointer, replaces MK_FP */
- do
- {
- CommandSeg = TempSeg ;
- TempSeg = *(TempSeg+8)*0x10000; /* Replaces MK_FP in turbo C */
- }
- while ( TempSeg != CommandSeg ) ;
-
- /*
- * Scan forward through memory looking for the correct MSB.
- * This will have COMMAND.COM's PSP as owner, and begin with
- * the character M
- */
- BlockSeg = (char far *)CommandSeg ;
- do
- {
- BlockSeg = (FP_SEG(BlockSeg)+1)*0x10000; /* Replaces MK_FP */
- }
- while ( ( *(unsigned int far *)(BlockSeg+1) != FP_SEG ( CommandSeg ) ) ||
- ( *BlockSeg != 'M' ) ) ;
-
- /*
- * The environment is the NEXT segment of memory
- * and bytes 4 and 5 are the size in paragraphs
- */
- *Env = (FP_SEG(BlockSeg)+1)*0x10000; /* Replaces MK_FP */
- *EnvSize = 16 * *(unsigned int far *)(BlockSeg+3) ;
- }
-
- /*
- * Mstr_getenv:
- * Scans the "Master" Environment for a given "sub string"
- * and returns a pointer to it.
- * Similar to Turbo routine "getenv" but uses the Master copy of the
- * environment table.
- */
- char far *Mstr_getenv (char far *Env , char far *name)
- {
- char far *Sub_Env, far *str1, far *str2 ;
-
- /*
- * Start at the beginning of the environment
- */
- Sub_Env = Env ;
-
- /*
- * While the "sub string" we're looking at is non-zero
- */
- for ( ; *Sub_Env ; )
- {
- /*
- * Simulate a "strcmp" on the "sub string" of the environment
- * and the string we're looking for
- */
- for ( str1 = Sub_Env , str2 = name ;
- (*str1) && (*str2) && ( *str1 == *str2) ;
- str1++ , str2++ ) ;
- /*
- * If we reached the end of the string we're looing for
- * we've found the correct portion of the environment.
- * Return the ptr to the start of this "sub string"
- */
- if ( !*str2 )
- return ( Sub_Env ) ;
-
- /*
- * Otherwise, advance to the next "sub string" in the environment
- * by performing a "strchr" function
- */
- for ( ; *(Sub_Env++) ; ) ;
- }
-
- /*
- * Obviously, the string is not present in the environment.
- * Return this fact.
- */
- return ( NULL ) ;
- }
-
-
-
-
- main(int argc, char *argv[])
- {
- char far *Env;
- char far *EndOfPath;
- char far *EndOfEnv;
- char ch,ch1;
- char *scratchcopy;
- int i,j ;
- unsigned EnvSize ;
-
- /** Display proper syntax if required **/
- if (argc < 2) {
- printf("╔══════════════════════════════════════════════════════════════════════╗\n");
- printf("║ Usage: pathadd X \(X = new path to be added to existing path\). ║ \n");
- printf("║ ║\n");
- printf("║ Example - If the current path is c:\\;c:\\dos and you wish to ║ \n");
- printf("║ add c:\\utilities, the syntax would be \"pathadd c:\\utilities\" . ║\n");
- printf("║ ║\n");
- printf("║ Semi-colons will be added to the end of the existing path if ║ \n");
- printf("║ required. No check is made as to the validity of the new path name. ║ \n");
- printf("╚══════════════════════════════════════════════════════════════════════╝\n\n");
- exit(1);
- }
-
- /* Locate the Master Table */
- Mstr_FindEnvironment ( &Env, &EnvSize ) ;
-
- /**** Find the End of the Existing Environment strings ***/
- /*** It will be marked by two consecutive nulls ***/
- i = 0; ch = ch1 = 'x';
- EndOfEnv = Env;
- while ( ch1 ) {
- ch = *(Env + i++);
- if ( !ch ) ch1 = *(Env + i);
- EndOfEnv++;
- }
-
- if ( (EndOfPath = Mstr_getenv( Env, "PATH=")) == NULL)
- { /** Install the new Path **/
- /* Set up the Scratch Copy */
- scratchcopy = (char *) malloc(EnvSize);
- *scratchcopy = '\0';
- strcat(scratchcopy,"PATH=");
- strcat(scratchcopy,strupr(argv[1]));
-
- for( i = 0; i <= strlen(scratchcopy); i++)
- *(EndOfEnv + i) = *(scratchcopy + i);
- printf("%s has been installed and is currently the only PATH.\n",strupr(argv[1]));
- exit(2);
- }
- while ( *(EndOfPath) ) EndOfPath++; /* Find the End of the Current Path */
-
- /* Set up the Scratch Copy */
- scratchcopy = (char *) malloc(EnvSize);
-
- /* Fill the scratch copy with current environment contents, replacing
- nulls with tildes so the whole scratch copy can be dealt with as
- a string */
- i = 0;
- while ( (Env + i) < EndOfPath)
- {
- *(scratchcopy + i) = ( *(Env + i) ? *(Env + i) : '~' );
- i += 1;
- }
- *(scratchcopy + i) = '\0';
-
- /* Add a semi-colon to the end of the current path if necessary */
- /* It is not necessary if all we have is "PATH=" */
- ch = *(scratchcopy + strlen(scratchcopy) - 1);
- if ( (ch != ';') && (ch != '=') ) strcat(scratchcopy,";");
-
- /* Add the additional path to the scratch copy */
- /* Convert to upper case for asthetic reasons */
- strcat(scratchcopy,strupr(argv[1]));
-
- /**** Add the rest of the environment to the new path ***/
- strcat(scratchcopy,"~");
- for (i = strlen(scratchcopy + 1),j = 0; j <= EndOfEnv - EndOfPath; j++)
- *(scratchcopy + i++) = ( *(EndOfPath + j) ? *(EndOfPath + j) : '~' );
- *(scratchcopy + i) = '\0';
-
- /** Change the Environment **/
- i = 0;
- while (i < strlen(scratchcopy))
- {
- *(Env + i) = ( *(scratchcopy + i) == '~' ? 0 : *(scratchcopy + i) );
- i += 1;
- }
-
- /** Free allocated memory **/
- free(scratchcopy);
-
- /** Final word of advice **/
- printf("Use the SET command to view the new environment.\n\n");
-
- exit(0);
- } /** End of MAIN() **/
-