home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!wupost!sdd.hp.com!nigel.msen.com!yale.edu!yale!news.wesleyan.edu!albatross.wcc.wesleyan.edu!hdtodd
- Newsgroups: comp.os.msdos.programmer
- Subject: Re: How can you set an environment variable in a program?
- Message-ID: <hdtodd.3.714836531@wccnet.wcc.wesleyan.edu>
- From: hdtodd@wccnet.wcc.wesleyan.edu (H. D. Todd)
- Date: Wed, 26 Aug 1992 13:42:11 GMT
- References: <690@aardvark.Rain.COM> <7923PB2w164w@jaflrn.UUCP>
- Organization: Wesleyan University, Middletown, CT USA
- Keywords: variable, C
- Nntp-Posting-Host: albatross.wcc.wesleyan.edu
- Lines: 169
-
- In article <7923PB2w164w@jaflrn.UUCP> Jon Freivald <jaf@jaflrn.UUCP> writes:
- >Subject: Re: How can you set an environment variable in a program?
-
- >OK, I don't have TC 2.0, but I do have TC++ 1.0 & 2.0 -- no such critter
- >as "setenv()" and "putenv()" only changes the environment for the
- >current process -- as soon as you exit, the variable is gone...
-
- I sent this out a couple of weeks ago in response to a similar
- inquiry. I should submit it to one of the archives (is SIMTEL the best
- starting point?). It's a Turbo C program to modify the path (hence "mp") in
- the root DOS command.com process. You could modify it to do whatever else
- you needed to do (though it's pretty handy on its own merits!).
-
- David Todd
-
-
- MP -- Modify Path
- USAGE
- MP [-{p|a} newpathnode | -r oldpathnode [newpathnode] ]*
- FUNCTION
- MP modifies the working path for MS DOS environments by
- prepending ("-p") or appending ("-a") a new path node to an existing path
- environment or by replacing ("-r") an old path node ("oldpathnode") with
- a new path node ("newpathnode") within the existing path. For the -r
- option, the field specifying "newpathnode" can be empty, thus deleting
- "oldpathnode" from the search path entirely.
- Note that for the -r switch, the new path node that might replace
- the old path node in the PATH list may be omitted: if so, the old path node
- is removed from the PATH list but is not replaced. Since switches are
- processed in the order entered, a -r followed by a -p or -a can be used
- to move a node from the interior of a PATH list to the beginning or end
- of that list.
- This program operates on the PARENT process environment, thus
- eliminating the requirement to use a batch file or enter a complete new
- path specification to make minor modifications to the working path.
- IMPLEMENTATION
- MP copies the environment block from the parent process to local
- strings, modifies the local string for PATH, then copies the complete
- set of environment strings back to the parent environment block.
- ERROR CONDITIONS
- MP will report an error and leave the path unmodified if there
- is insufficient room in the environment block for the modified PATH
- environment variable. In this situation, the path could not be
- modified even at the command level. To prepare for future use of MP or
- changes to the path by other methods in this case, increase the size of
- the environment block by modifying the CONFIG.SYS file line specifying
- COMSPEC=dd:COMMAND.COM/e:nnn
- to increase (or specify) the /e: parameter for the size of the
- environment block.
- MP also reports if a switch is given with no nodename to process, if
- an invalid switch is given, or if switches are not prefixed with '-'.
- LANGUAGE AND COMPATIBILITY
- MP is written in TURBOC and has been tested with DOS 3.3 and DOS
- 4.01. Since it does not use DOS systems calls to effect the
- modifications (and cannot, since DOS does not provide a mechanism for a
- child process to change the environment block of its parent), MP may be
- incompatible with future versions of DOS.
- AUTHOR
- MP was written by H. D. Todd, Wesleyan University, December,
- 1990 and is supplied in source-code form. The author would appreciate
- receiving bug reports and modifications (send to
- HDTodd@eagle.wesleyan.edu or HDTodd@wesleyan.bitnet).
-
- /* mp.c
- Program to modify the path environment for MS-DOS.
- Written by H. D. Todd, Wesleyan University, 12/26/90 */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
- #define MAXSTRS 100 /* increase this if you have more env strings */
- #define MAXPATH 500 /* max size of path string */
- #define PATHSEP ";" /* separates node names in path */
- void main(int argc, char *argv[])
- {
- int i, num, envsize, len, nstrs=0, nextra, pathindex;
- char dowhat, varstg[MAXPATH], tmpstr[MAXPATH],
- *strptr[MAXSTRS], far *envp, far *envptr, *subloc;
- unsigned far *p_psp, far *p_env;
- struct {
- char link;
- unsigned int owner_psp;
- unsigned int blk_len;
- } far *envmcb;
- if (argc < 2) {
- fprintf(stderr, "Usage: mp [ -{p|a} newnodename | -r oldnodename newnodename]*\n");
- exit(1); }
- /* Construct the PSP pointers */
- p_psp = MK_FP(_psp,0x16); /*pointer to parent's PSP*/
- p_env = MK_FP(*p_psp,0x2c); /*pointer to parent's environment ptr*/
- envptr = MK_FP(*p_env,0x00); /*pointer to parent's environment */
- envmcb = MK_FP(*p_env-1,0x00); /* pointer to parent env MCB */
- envsize = (*envmcb).blk_len<<4;
- /* copy strings from parent's environment (FAR) to local strings */
- envp = envptr;
- while (*envp) { /* env strings terminated by second null */
- int len;
- char far *fp;
- char *lp;
- for (len=0, fp=envp; *fp; fp++) len++;
- lp = strptr[nstrs++] = malloc(len+1);
- for ( ; (*lp++=*envp++); );
- }
- /* find the PATH= string among the env vars */
- for (pathindex=0; pathindex<nstrs; pathindex++) if (strnicmp(strptr[pathindex],"PATH=",5) ==0 ) break;
- if (pathindex>=nstrs) {
- fprintf(stderr, "MP: Can't find path var!\n");
- exit(1);
- }
- strcpy(varstg,strptr[pathindex]);
- /* now do what the switches tell us to do */
- while (--argc > 0 ) {
- if ( ( (dowhat=(*++argv)[0])) != '-') {
- fprintf(stderr, "MP: begin switches with '-', as in '-%c'\n", dowhat);
- exit(1);
- }
- dowhat = tolower(*++argv[0]);
- if (dowhat!='p' && dowhat!='a' && dowhat!='r') {
- fprintf(stderr, "MP: invalid switch -%c\n", dowhat);
- exit(1);
- };
- if (--argc <=0) {
- fprintf(stderr, "MP: switch -%c missing node name\n", dowhat);
- exit(1);
- }
- switch (dowhat) {
- case 'a': strcat(varstg,PATHSEP);
- strcat(varstg,*++argv);
- break;
- case 'p': strcpy(tmpstr,"PATH=");
- strcat(tmpstr,*++argv);
- strcat(tmpstr,PATHSEP);
- strcat(tmpstr,strpbrk(varstg,"=")+1);
- strcpy(varstg,tmpstr);
- break;
- case 'r': if ( (subloc=strstr(varstg,*++argv)) == NULL) {
- fprintf(stderr,"MP: pathnode %s not found in current path\n", *argv);
- fprintf(stderr," replacement ignored");
- while ( *(argv+1)[0] != '-') {
- ++argv;
- argc--;
- }
- break;
- };
- strcpy(tmpstr,subloc+strlen(*argv));
- if (*(argv+1)[0] != '-') {
- strcpy(subloc,*++argv);
- --argc;
- }
- else subloc = '\0';
- strcat(varstg,tmpstr);
- break;
- };
- }
- /* make sure we can copy it all back into the parent's env block */
- strptr[pathindex] = &varstg;
- for (i=0, len=0; i<nstrs; i++) len += strlen(strptr[i]) + 1;
- if (len+1>envsize) {
- fprintf(stderr,"MP: Env block too small to store updated PATH string\n");
- exit(1);
- }
- else {
- /* OK, do it */
- for (i=0; i<nstrs; i++) {
- for ( ; (*envptr++ = *strptr[i]++) ; ) ;
- *envptr = '\0';
- }
- }
- }
-