home *** CD-ROM | disk | FTP | other *** search
- /* Program to change the environment path string. This program only
- changes the environment of the first copy of command.com and not
- subsequent ones (the actual active one). This situation can
- be easily remedied by modifying the assembly function findEnv().
- For further reference on how to find the master environment and
- memory control block, refer to Dr Dobb's Journal #145 Nov, 1988
- "Mapping DOS Memory Allocations", page 56, by Robert J. Moore.
- This program has been tested under PC-DOS 3.2 and compiled with
- Turbo C 2.0, (small/tiny model). Assembly support routines has
- been tested with Turbo Assembler 1.0.
- Written by Goh King Hwa, 19 Dec 1989.
- Bug Fix : 27 Jan 1990
- */
- #include <stdio.h>
- #include <string.h>
- #include <dos.h>
- #include <dir.h>
- #include <alloc.h>
- #include <ctype.h>
-
- #define TRUE 1
- #define FALSE 0
-
- /* ------ function prototype for assembly support routines ------- */
- /* locate and find the size of the master environment block */
- char far *findEnv(unsigned int *);
- /* locate a string in the master environment block ("PATH") */
- char far *findstr(char far *, char *);
- /* locate the existence of a pathname in the path string */
- char *findNstr(char *, char *);
- /* check for the actual presence of a drive */
- int drivePresent(int);
- /* move or shuffle data in the master environment block */
- void movLblk(char far *, char far *, int);
- /* copy a string into the master environment block */
- void strXcpy(char far *, char *);
-
- /* check for the physical presence of a pathname */
- int pathPresent(char *);
- void exit(int);
-
- /* global variables */
- char far *envAddr; /* the starting address of the master environment */
- unsigned int envSize; /* the size of the master environment */
- char *path; /* scrap string for working on the path */
-
- main(int argc, char** argv)
- {
- register int i;
- unsigned int envUsed = 0; /* size of environment space actually used */
- char *endOfPath; /* trace the end of variable path */
- char far *pathEStart = 0; /* start of path string in environment */
- char far *pathEEnd = 0; /* end of path string in environment */
- int pathNotFound = TRUE; /* did we find "PATH=" in the environment? */
- int fFirstPath = FALSE; /* the very first pathname to be added */
- int fPathChange = FALSE; /* indicate that path has been changed */
- int movSize; /* size of path string if present */
- char *scrap, *hit;
- int pLen;
-
- /* make sure we have sufficient number of parameters */
- if (argc < 3)
- {
- printf("xp a [pathname] [pathname]...\t"
- "Add new path to environment.\n"
- "xp r [pathname] [pathname]...\t"
- "Delete path from environment.\n");
- exit(1);
- }
-
- /* check to see the correct option is used */
- i = *argv[1] = toupper(*argv[1]);
- if (i != 'A' && i != 'D' && i != 'R')
- {
- printf("Illegal options [Use a/r/d].\n");
- exit(2);
- }
-
- /* convert subsequent parameters (pathnames) entered into upcase
- and strip of any terminating '\' character */
- for (i = 2; i < argc; i++)
- {
- for (path = argv[i]; *path; path++)
- *path = toupper(*path); /* find the end of string */
- --path; /* go back one character */
- /* dump the last '\' so that findfirst can work */
- if (*path == '\\') *path = 0; /* does string end with '\' ? */
- }
-
- /* locate the master environment address and size */
- envAddr = findEnv(&envSize);
-
- /* allocate enough scrap space to work on the path string */
- path = malloc(envSize);
- if (!path)
- {
- printf("Not enough memory!\n");
- exit(3);
- }
-
- /* The environment is arranged as a series of ASCIIZ strings.
- It is terminated by a null string. The next section of code
- will attempt to do a couple of things.
- 1. Find the path string in the master environment (if it is
- present) and copy it into the path variable for easily
- manipulation later on.
- 2. Indicate the presence of a path string by pathNotFound.
- 3. Count the number of bytes actually used in the environment.
- 4. Note down the starting and ending address [pathEStart, pathEEnd]
- of the path string in the master environment (if it is present).
- 5. Make sure path is in uppercase.
- */
- endOfPath = path; /* trace the end of path variable */
- /* we will exit when we hit 2 consecutive zeros */
- while(envAddr[envUsed])
- {
- /* at beginning of each environment string, check to see
- whether it's the "PATH=" string we want */
- if (pathNotFound && (pathEStart=findstr(&envAddr[envUsed],"PATH")))
- {
- pathNotFound = FALSE; /* indicate "PATH= has been found */
- while (envAddr[envUsed]) /* copy it into path */
- *endOfPath++ = envAddr[envUsed++];
- pathEEnd = &envAddr[envUsed+1];
- }
- while (envAddr[envUsed++]); /* goto the next environment string */
- }
- /* If "PATH=" is found, movSize = length of the path string
- else movSize = size of the master environment - 1 */
- movSize = (unsigned) (&envAddr[envUsed] - pathEEnd);
- envUsed++; /* remember to count the last zero */
- *endOfPath = 0; /* close the string */
- strupr(path); /* convert the path into uppercase */
-
- /* ------- this is the path adding part --------- */
- if (*argv[1] == 'A')
- {
- /* if there is no "PATH=" in the environment, we must
- add in ourselves */
- if (pathNotFound)
- {
- *endOfPath++ = 'P'; *endOfPath++ = 'A';
- *endOfPath++ = 'T'; *endOfPath++ = 'H';
- *endOfPath++ = '='; *endOfPath = 0;
- fFirstPath = TRUE;
- }
-
- /* next block of code reads in the pathnames entered
- on the command-line, verify it and start building
- the environment path string */
- for (i = 2; i < argc; i++) /* for each pathname entered */
- {
- if (findNstr(path,argv[i]))
- printf("%s is already defined.\n", argv[i]);
- else if (!pathPresent(argv[i]))
- printf("%s does not exist.\n", argv[i]);
- else
- {
- /* find the length of the path, plus 1 for ';' added */
- pLen = strlen(argv[i]) + 1;
- /* make sure the path will fit the environment */
- if (pLen + envUsed > envSize)
- printf("%s is too large for the environment space.\n",
- argv[i]);
- else /* all else checks out, so add to path */
- {
- fPathChange = TRUE; /* flag path has been changed */
- envUsed += pLen; /* indicate the amount used */
- scrap = argv[i];
- if (fFirstPath) /* the very first pathname */
- fFirstPath = FALSE; /* no need to add a ';' */
- else
- *endOfPath++ = ';'; /* add ';' to path */
- while (*scrap) /* copy pathname into variable path */
- *endOfPath++ = *scrap++;
- }
- }
- }
- *endOfPath = 0; /* end the path string */
-
- /* if there is any changes in path, the path string
- is then copied into the actual environment space */
- if (fPathChange)
- {
- /* did we find the "PATH=" in the environment? */
- if (pathNotFound)
- /* no, copy path to the end of the environment */
- pathEStart = envAddr + movSize;
- else
- {
- /* yes, destroy current path string in environment */
- movLblk(pathEStart, pathEEnd, movSize);
- /* get ready to copy path to the end of the environment */
- pathEStart += movSize;
- }
-
- strXcpy(pathEStart,path);
- printf("\nEnvironment has been changed.\n");
- }
- }
-
- /* -------- this is the path deletion part ---------- */
- if (*argv[1] == 'D' || *argv[1] == 'R')
- {
- if (pathNotFound) /* if the no path has been defined before */
- {
- printf("There is no path to delete.\n");
- exit(4);
- }
-
- /* next block of code reads in the pathname from the
- command-line, verify it and delete the unwanted
- pathname from path */
- for (i = 2; i < argc; i++) /* for each pathname entered */
- {
- if (!(hit = findNstr(path,argv[i])))
- printf("%s has not been defined.\n", argv[i]);
- else
- {
- scrap = hit; /* start from the current match point */
- while (*scrap != 0 && *scrap != ';')
- scrap++; /* find the start of the next pathname */
- /* pathname is sandwiched between 2 pathnames */
- if (*scrap == ';') scrap++;
- /* pathname is found right at the end */
- if (*scrap == 0 && *(hit-1) == ';') hit--;
- strcpy(hit,scrap); /* overlay the unwanted path */
- fPathChange = TRUE;
- }
- }
-
- /* if there is any changes in path, the path string
- is then copied into the actual environment space */
- if (fPathChange)
- {
- /* rub out the existence of the old path from the environment */
- movLblk(pathEStart, pathEEnd, movSize);
- pathEStart += movSize;
-
- if (path[5] == 0) /* did we delete all the pathnames? */
- *pathEStart = 0; /* yes, just terminated the environment */
- else
- strXcpy(pathEStart,path); /* no, copy in the new path */
-
- printf("\nEnvironment has been changed.\n");
- }
- }
- }
-
- /* check the physical existence of a pathname */
- int pathPresent(char *path)
- {
- struct ffblk ffblk;
-
- /* drive specification: check to see whether drive is present */
- if (path[1] == ':' && path[2] == 0)
- return(drivePresent(path[0]-'A'));
-
- /* find the path, must be a directory type */
- if (!findfirst(path,&ffblk,FA_DIREC) && (ffblk.ff_attrib & FA_DIREC))
- return(TRUE);
- else
- return(FALSE);
- }