/* +++Date last modified: 05-Jul-1997 */ #include #include #include #include #include #include #define far _far struct __environrec { unsigned environseg; /*Segment of the environment*/ unsigned environlen; /*Usable length of the environment*/ } __environrec; struct __environrec *_getmastenv(void) { unsigned owner; unsigned mcb; unsigned eseg; static struct __environrec env; env.environseg = env.environlen = 0; owner = * ((unsigned far *) MK_FP(0, (2+4*0x2e))); /* int 0x2e points to command.com */ mcb = owner -1; /* Mcb points to memory control block for COMMAND */ if ( (*((char far *) MK_FP(mcb, 0)) != 'M') && (*((unsigned far *) MK_FP(mcb, 1)) != owner) ) return (struct __environrec *) 0; eseg = *((unsigned far *) MK_FP(owner, 0x2c)); /* Read segment of environment from PSP of COMMAND} */ /* Earlier versions of DOS don't store environment segment there */ if( !eseg ) { /* Master environment is next block past COMMAND */ mcb = owner + *((unsigned far *) MK_FP(mcb, 3)); if ( (*((char far *) MK_FP(mcb, 0)) != 'M') && (*((unsigned far *) MK_FP(mcb, 1)) != owner) ) return (struct __environrec *) 0; eseg = mcb + 1; } else mcb = eseg-1; /* Return segment and length of environment */ env.environseg = eseg; env.environlen = *((unsigned far *) MK_FP(mcb, 3)) << 4 ; return &env; } /* ** Then a function to find the string to be replaced. This one'll ** return a pointer to the string, or a pointer to the first (of 2) ** NUL byte at the end of the environment. */ char far *_mastersearchenv( char far *eptr, char *search ) { char far *e; char *s; while( *eptr ) { for ( s=search, e=eptr; *e && *s && (*e == *s); e++, s++ ) ; /* NULL STATEMENT */ if( !*s ) break; while ( *eptr ) eptr++; /* position to the NUL byte */ eptr++; /* next string */ } return eptr; } /* ** Now, the function to replace, add or delete. If a value is not ** given, the string is deleted. */ int _masterputenv( struct __environrec *env, char *search, char *value ) { /* -Set environment string, returning true if successful */ char far *envptr; register char far *p; char *s; int newlen; int oldlen; int i; if( !env->environseg || !search ) return 0; /* get some memory for complete environment string */ newlen = strlen( search ) + sizeof( ( char )'\0') + strlen( value ) + 2; if( ( s = ( char * )malloc( newlen ) ) == NULL ) return 0; for( i = 0; *search; search++, i++ ) s[i] = *search; s[i++] = '='; s[i] = '\0'; envptr = _mastersearchenv((char far *) MK_FP(env->environseg, 0), s ); if( *envptr ) { for( p = envptr, oldlen = 0; *p; oldlen++, p++ ) ; /* can't use strlen() because of far pointer */ } /* will set p to point to terminating NUL */ if( *value && (newlen > (int)env->environlen) ) /* not a deletion */ { free( s ); return 0; /* won't fit */ } if( *envptr ) /* shift it down */ { for( ++p; (*p || *(p+1)); envptr++, p++ ) *envptr = *p; *envptr++ = '\0'; *envptr = '\0'; } if( *value ) /* append it */ { strcat( s, value ); while( *s ) *(envptr++) = *s++; *envptr++ = '\0'; *envptr = '\0'; } free( s ); return 1; } /* ** Ok, just to show you that I tested it : */ void writeout( char *string ) { write( 1, string, strlen( string ) ); } void help( void ) { writeout( "MSET 1.0 - Sets the Parental COMMAND.COM environment\r\n" ); writeout( "Syntax: MSET [/C] [/U] [/P] [/E] =\r\n" ); writeout( "Options:\r\n" ); writeout( "\t/C\tKeep case of (default is uppercase)\r\n" ); writeout( "\t/U\tUppercase \r\n" ); writeout( "\t/P\tPrompt the user for the value, print \r\n" ); writeout( "\t/E\tSet the variable to the first line of output of the\r\n" ); writeout( "\t\tcommand pointed to by \r\n" ); } #define KEEPCA 0x01 #define PROMPT 0x02 #define EXECUT 0x04 #define UPCASE 0x08 int main( int argc, char **argv ) { char varname[80], varval[80], *ptr; char optflags = 0; struct __environrec *p = _getmastenv(); int i = 1; if( argc < 1 ) { help(); return( 1 ); } for( ; i < argc && argv[i][0] == '/'; i++ ) { switch( toupper( argv[i][1] ) ) { case '?': case 'H': help(); return( 1 ); case 'C': optflags |= KEEPCA; break; case 'P': optflags |= PROMPT; break; case 'E': optflags |= EXECUT; break; case 'U': optflags |= UPCASE; break; } } if( !*argv[i] ) { help(); return( 1 ); } ptr = strchr( argv[i], '=' ); if( ptr == NULL && !( optflags & PROMPT ) ) { help(); return( 1 ); } *ptr++; strcpy( varval, &*ptr ); *ptr--; *ptr-- = NULL; strcpy( varname, argv[i] ); if( optflags & PROMPT ) { if( varval[0] != '\0' ) write( 1, varval, strlen( varval ) ); fgets( varval, 80, stdin ); if( varval[ strlen( varval ) - 1 ] == '\n' ) varval[ strlen( varval ) - 1 ] = '\0'; } if( !( optflags & KEEPCA ) ) strupr( varname ); if( optflags & UPCASE ) strupr( varval ); i = _masterputenv( p, varname, varval ); i = _masterputenv( p, varname, varval ); return( ( i == 1 ) ? 0 : 1 ); }