home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / snip1091.arj / MCB_ENV.C < prev    next >
C/C++ Source or Header  |  1991-10-03  |  5KB  |  167 lines

  1. #include <stdio.h>
  2. #include <dos.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5.  
  6. #ifdef __TURBOC__
  7.  #include <alloc.h>
  8.  #define FAR far
  9. #else
  10.  #include <stdlib.h>
  11.  #define FAR _far
  12. #endif
  13.  
  14. #if !defined(MK_FP)
  15.     #define MK_FP(seg,off) ((void FAR *)(((long)(seg) << 16)|(unsigned)(off)))
  16. #endif
  17.  
  18. struct EnvRec {
  19.               unsigned EnvSeg;  /*Segment of the environment*/
  20.               unsigned EnvLen;  /*Usable length of the environment*/
  21.               } EnvRec;
  22.  
  23. struct EnvRec *MasterEnv(void)
  24. {
  25.       unsigned owner;
  26.       unsigned mcb;
  27.       unsigned eseg;
  28.       static struct EnvRec env;
  29.  
  30.       env.EnvSeg = env.EnvLen = 0;
  31.       owner = * ((unsigned FAR *) MK_FP(0, (2+4*0x2e)));
  32.  
  33.       /* int 0x2e points to command.com */
  34.  
  35.       mcb = owner -1;
  36.  
  37.       /*Mcb points to memory control block for COMMAND */
  38.  
  39.       if ( (*((char FAR *) MK_FP(mcb, 0)) != 'M') &&
  40.            (*((unsigned FAR *) MK_FP(mcb, 1)) != owner) )
  41.                  return (struct EnvRec *) 0;
  42.  
  43.       eseg = *((unsigned FAR *) MK_FP(owner, 0x2c));
  44.  
  45.       /* Read segment of environment from PSP of COMMAND} */
  46.       /* Earlier versions of DOS don't store environment segment there */
  47.  
  48.       if ( !eseg )
  49.       {
  50.  
  51.             /* Master environment is next block past COMMAND */
  52.  
  53.             mcb = owner + *((unsigned FAR *) MK_FP(mcb, 3));
  54.             if ( (*((char FAR *) MK_FP(mcb, 0)) != 'M') &&
  55.                  (*((unsigned FAR *) MK_FP(mcb, 1)) != owner) )
  56.                        return (struct EnvRec *) 0;
  57.             eseg = mcb + 1;
  58.       }
  59.       else  mcb = eseg-1;
  60.  
  61.       /* Return segment and length of environment */
  62.  
  63.       env.EnvSeg = eseg;
  64.       env.EnvLen = *((unsigned FAR *) MK_FP(mcb, 3)) << 4 ;
  65.       return &env;
  66. }
  67.  
  68. /*
  69. ** Then a function to find the string to be replaced.   This one'll
  70. ** return a pointer to the string, or a pointer to the first (of 2)
  71. ** NUL byte at the end of the environment.
  72. */
  73.  
  74. char FAR *SearchEnv( char FAR *eptr, char *search )
  75. {
  76.       char FAR *e;
  77.       char *s;
  78.       while ( *eptr )
  79.       {
  80.             for ( s=search, e=eptr; *e && *s && (*e == *s); e++, s++ )
  81.                   ;  /* NULL STATEMENT */
  82.             if ( !*s )
  83.                   break;
  84.             while ( *eptr )
  85.                   eptr++;           /* position to the NUL byte */
  86.             eptr++;                      /* next string */
  87.       }
  88.       return eptr;
  89. }
  90.  
  91. /*
  92. ** Now, the function to replace, add or delete.  If a value is not
  93. ** given, the string is deleted.
  94. */
  95.  
  96. int SetEnvStr( struct EnvRec *env, char *search, char *value )
  97. {
  98.       /* -Set environment string, returning true if successful */
  99.  
  100.       char FAR *envptr;
  101.       register char FAR *p;
  102.       char *s;
  103.       int newlen;
  104.       int oldlen;
  105.       int i;
  106.  
  107.       if ( !env->EnvSeg || !search )
  108.             return 0;
  109.  
  110.       /* get some memory for complete environment string */
  111.  
  112.       newlen = strlen(search) + sizeof((char) '\0') + strlen(value) + 2;
  113.       if ( (s = (char *) malloc( newlen)) == NULL )
  114.             return 0;
  115.       for ( i = 0; *search; search++, i++ )
  116.             s[i] = *search;
  117.       s[i++] = '=';
  118.       s[i] = '\0';
  119.       envptr = SearchEnv((char FAR *) MK_FP(env->EnvSeg, 0), s );
  120.       if ( *envptr )
  121.       {
  122.             for ( p = envptr, oldlen = 0; *p; oldlen++, p++ )
  123.                   ;     /* can't use strlen() because of far pointer */
  124.       }                 /* will set p to point to terminating NUL */
  125.  
  126.       if ( *value && (newlen > (int)env->EnvLen) ) /* not a deletion */
  127.       {
  128.             free( s );
  129.             return 0;                           /* won't fit */
  130.       }
  131.  
  132.       if ( *envptr )                            /* shift it down */
  133.       {
  134.             for ( ++p; (*p || *(p+1)); envptr++, p++ )
  135.                   *envptr = *p;
  136.             *envptr++ = '\0';
  137.             *envptr = '\0';
  138.       }
  139.       if ( *value )                             /* append it */
  140.       {
  141.             strcat(s, value);
  142.             while ( *s )
  143.                   *(envptr++) = *s++;
  144.             *envptr++ = '\0';
  145.             *envptr = '\0';
  146.       }
  147.       free(s);
  148.       return 1;
  149. }
  150.  
  151. /*
  152. ** Ok, just to show you that I tested it :
  153. */
  154.  
  155. void main(void)
  156. {
  157.       char vn[80];
  158.       char va[80];
  159.       struct EnvRec *p = MasterEnv();
  160.  
  161.       puts("enter variable name:");
  162.       gets(vn);
  163.       puts("enter value:");
  164.       gets(va);
  165.       printf("SetEnvStr returned %d\n", SetEnvStr( p, strupr(vn), va) );
  166. }
  167.