home *** CD-ROM | disk | FTP | other *** search
- @echo off
- REM PathSubs.bat - Compact the PATH statement by using SUBST for the paths in
- REM the list. Also allow to add or delete a path. See the
- REM Instructions() function for a description of how to use
-
- subst | cenvi %0.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
- GOTO CENVI_EXIT
-
- Instructions()
- {
- printf("\a\n")
- printf("PathSubs - Keep the PATH environment variable as short as possible buy using\n")
- printf(" DOS's SUBST command to replace PATH directories with drive letters.\n")
- printf("\n")
- printf("SYNTAX: PathSubs [ < + | - > d:\\path ]\n")
- printf("\n")
- printf("Where: + Add a path to the PATH variable, if not already there.\n")
- printf(" - Remove a path from the PATH variable, if it is there.\n")
- printf(" d:\\path The FULL directory to add or remove from PATH.\n")
- printf("\n")
- printf("The following table shows examples of the SUBST command.\n");
- printf("\n")
- printf("PathSubs Compacts the current path using drive substitutions\n")
- printf("PathSubs + D:\\UTL Add D:\UTL to the current PATH\n")
- printf("PathSubs - D:\\UTL Remove D:\UTL from the current PATH\n")
- printf("\n")
- }
-
- // The following code uses the path structure which has the elements:
- // Count : number of directories in the path
- // path[Count].Dir : array of Count strings, each containing a full directory
- // path[Count].Drive : drive letter substituted here, else 0 for not subst
- // and also the Subs structure which has the elements
- // Count : number of drives Substituted
- // sub[Count].Drive : array of Count drive letters substituted for Dir
- // sub[Count].Dir : array of Count strings for the path of each substituted driev
-
- main(ArgCount,ArgStrings)
- {
- // Decide what to do from input
- if ( ArgCount == 3 ) {
- Command = ArgStrings[1]
- CommandPath = ArgStrings[2]
- if ( Command[1] != 0 || ( Command[0] != '+' && Command[0] != '-' ) ) {
- // Invalid input, so just show how to use and quit
- Instructions()
- return(1)
- }
- } else if ( ArgCount != 1 ) {
- // Invalid input, so just show how to use and quit
- Instructions()
- return(1)
- }
- // Build lists of substituted drives and of paths
- Subs = BuildSubsArray()
- Paths = SeparatePATHIntoDirs(Subs)
- // implement new command based on input arguments
- if ( ArgCount == 3 ) {
- if ( Command[0] == '+' )
- AddPath(CommandPath,Paths)
- else
- RemovePath(CommandPath,Paths,Subs)
- }
- CompactPaths(Paths,Subs)
- ShowCurrentPath(Paths)
- return(0)
- }
-
- ShowCurrentPath(p)
- {
- printf("PATH=")
- for ( i = 0, count = 0; i < p.Count; i++ ) {
- if ( p.path[i].Dir != NULL ) {
- if ( count++ ) printf(";")
- printf("%s",p.path[i].Dir)
- }
- }
- printf("\n")
- }
-
- AddPath(Dir,p)
- {
- // First check if this directory is already in the path
- for ( i = 0; i < p.Count; i++ ) {
- if ( 0 == stricmp(Dir,p.path[i].Dir) ) {
- printf("Directory \"%s\" is already in the PATH\n",p.path[i].Dir)
- return
- }
- }
- // was not found above in the path, and so add to end of path list
- strcpy(p.path[p.Count].Dir,Dir)
- p.path[p.Count].Drive = 0 // assume it is not substituted
- p.Count++
- }
-
- RemovePath(Dir,p,s)
- {
- // First check that this directory is already in the path
- for ( i = 0; i < p.Count; i++ ) {
- if ( 0 == stricmp(Dir,p.path[i].Dir) ) {
- break
- }
- }
- if ( i == p.Count )
- printf("Directory \"%s\" is not in the PATH\n",Dir)
- else {
- // remove this directory from the path, and remove its SUBST
- if ( (drive = toupper(p.path[i].Drive)) != 0 ) {
- // this path has a SUBSTITUTED drive, and so remove that subst drive
- for ( j = 0; j < s.Count; j++ ) {
- if ( s.sub[j].Drive == drive )
- break;
- }
- s.sub[j].Drive = 0;
- // use DOS's SUBST utility to un-substitute this drive
- system("SUBST %c: /D",drive)
- }
- // set path structure to know this path is no longer there
- p.path[i].Drive = 0;
- p.path[i].Dir = NULL
- }
- }
-
- BuildSubsArray() // Subst output was piped to this program, and so use that output
- // to build list of substituted drives and paths they point to.
- // output line is of the form "G: is substituted for C:\OS2"
- {
- for ( s.Count = 0; NULL != (line=gets()); s.Count++ ) {
- // first letter of SUBST is the drive letter
- s.sub[s.Count].Drive = toupper(line[0]);
- // last string before whitespace is the path
- for ( d = line + strlen(line); d[-1] != ' '; d-- ) ;
- strcpy(s.sub[s.Count].Dir,d)
- }
- return(s)
- }
-
-
- SeparatePATHIntoDirs(subs) // Separate the PATH environment variable into
- // individual paths, return element Count to how many
- // paths, and setting each Dir[] element to a path.
- // any paths that fit into the subst array will be
- // replaced by their full subst path
- {
- Paths.Count = 0
- p = PATH
- while ( NULL != p && 0 != p[0] ) {
- if ( ';' == p[0] )
- p++ // skip semi-colons
- else {
- strcpy(NewDir,p)
- if ( NULL != (c = strchr(NewDir,';')) )
- c[0] = 0;
- // check if this is a "A:\" type path and if it is substituted
- Paths.path[Paths.Count].Drive = 0 // assume it is not substituted
- if ( 0 == strcmp(NewDir+1,":\\") ) {
- // loop through subst to see if this is one of those
- for ( i = 0; i < subs.Count; i++ ) {
- if ( toupper(NewDir[0]) == subs.sub[i].Drive ) {
- // put in the real path for this substituted one
- NewDir = subs.sub[i].Dir
- Paths.path[Paths.Count].Drive = subs.sub[i].Drive
- break
- }
- }
- }
- strcpy(Paths.path[Paths.Count++].Dir,NewDir)
- p = strchr(p,';')
- }
- }
- return(Paths)
- }
-
- CompactPaths(p,s) // this writes the PATH statement in compacted form, substituting
- // all drives for a path whenever it can. It assumes that it will
- // Subst on any drive letter that isn't used already.
- {
- TempPath[0] = '\0' // restart directories from scratch
- SubstDir = "A:\\" // template for what a subdir looks like
- for ( i = 0; i < p.Count; i++ ) {
- if ( p.path[i].Dir != NULL ) {
- if ( p.path[i].Drive != 0 ) {
- // this path already has a drive letter substituted, and so keep it
- SubstDir[0] = p.path[i].Drive
- strcat(TempPath,SubstDir)
- } else if ( strlen(p.path[i].dir) <= 3 ) {
- // path can't get any shorter by substituting, and so keep it as it is
- strcat(TempPath,p.path[i].Dir)
- } else {
- // get the next drive letter for substituting
- drive = NextFreeDrive()
- if ( drive != 0 ) {
- // create a new SUBST drive for this path
- system("SUBST %c: %s",drive,p.path[i].Dir)
- SubstDir[0] = p.path[i].Drive = drive
- strcat(TempPath,SubstDir)
- // add this new drive to list of substituted drives
- strcpy(s.sub[s.Count].Dir,p.path[i].Dir)
- s.sub[s.Count].Drive = drive
- s.Count++
- } else {
- // there are no more available free drives, and so simply add this dir
- strcat(TempPath,p.path[i].Dir)
- }
- }
- strcat(TempPath,";")
- }
- }
- // remove the final semi-colon
- TempPath[strlen(TempPath)-1] = 0
- PATH=TempPath
- }
-
- NextSubstDrive = 'D' // this global is incremented for each drive to test
-
- NextFreeDrive() // return a character for the next available free drive letter
- // or '\0' if no drive available. Check if a drive is available
- // by seeing if there's a current path for that drive
- {
- CurDir = "C:." // this string, with drive letter substituted tested for curdir
- while ( NextSubstDrive <= 'Z' ) {
- CurDir[0] = NextSubstDrive++
- if ( NULL == FullPath(CurDir) ) {
- return( NextSubstDrive - 1 )
- }
- }
- // no free drive was found; indicate by returning 0
- return '\0'
- }
-
- :CENVI_EXIT