// add a variable to the environment or alias to the alias list int add_list( char *envstr, PCH pchList ) { char *line; PCH feptr, env_arg, env_end, last_var; unsigned int length; int rval = 0; ULONG size; // size of environment or alias blocks // OS/2 & NT need semaphores to keep processes from simultaneously // writing the alias list HMTX SemHandle = 0; char szVarName[32]; if ( pchList == 0L ) pchList = glpEnvironment; line = envstr; if ( *line == '=' ) { return ( error( ERROR_4DOS_BAD_SYNTAX, envstr )); } for ( ; (( *line ) && ( *line != '=' )); line++ ) { if ( pchList == glpAliasList ) { if ( iswhite( *line )) { strcpy( line, skipspace( line ) ); break; } } else // ensure environment entry is in upper case *line = (unsigned char)_ctoupper( *line ); } if ( *line == '=' ) { // point to the first char of the argument line++; // collapse whitespace around '=' in aliases, but not in env // variables, for COMMAND.COM compatibility (set abc def= ghi) if ( pchList == glpAliasList ) strcpy( line, skipspace( line )); } else if ( *line ) { // add the missing '=' strins( line, "=" ); line++; } // removing single back quotes at the beginning and end of an alias // argument (they're illegal there; the user is probably making a // mistake with ALIAS /R) if (( *line == SINGLE_QUOTE ) && ( pchList == glpAliasList )) { // remove leading single quote strcpy( line, line + 1 ); // remove trailing single quote if ((( length = strlen( line )) != 0 ) && ( line[--length] == SINGLE_QUOTE )) line[length] = '\0'; } // block other processes & threads while updating alias list if ( pchList == glpAliasList ) { // disable signals temporarily HoldSignals(); // get & lock a semaphore RequestSemaphore( &SemHandle, SEMAPHORE_NAME ); } // get pointers to beginning & end of alias/environment space size = QueryMemSize( pchList ); env_end = pchList + ( size - 4 ); // get pointer to end of environment or alias variables last_var = end_of_env( pchList ); length = strlen( envstr ) + 1; // special case for BeginLIBPATH and EndLIBPATH sscanf( envstr, "%31[^=]", szVarName ); if (stricmp( szVarName, BEGINLIBPATH ) == 0) { if ((DosSetExtLIBPATH( line, BEGIN_LIBPATH ) == NO_ERROR)) return 0; return ERROR_EXIT; } if (stricmp( szVarName, ENDLIBPATH ) == 0) { if ((DosSetExtLIBPATH( line, END_LIBPATH ) == NO_ERROR)) return 0; return ERROR_EXIT; } // check for modification or deletion of existing entry if (( env_arg = get_list( envstr, pchList )) != 0L ) { // get the start of the alias or variable name for ( feptr = env_arg; (( feptr > pchList ) && ( feptr[-1] != '\0' )); feptr-- ) ; if ( *line == '\0' ) { // delete an alias or environment variable memmove( feptr, next_env( feptr ), (unsigned int)( last_var - next_env(feptr)) + 1); } else { // get the relative length (vs. the old variable) length = strlen( line ) - strlen( env_arg ); } } if ( *line != '\0' ) { // check for out of environment space if (( last_var + length ) >= env_end ) { // boost environment or alias list size if ( ReallocMem( pchList, size + ENVIRONMENT_SIZE ) == NULL) { rval = error((( pchList == glpAliasList ) ? ERROR_4DOS_OUT_OF_ALIAS : ERROR_4DOS_OUT_OF_ENVIRONMENT), NULL); goto add_bye; } // adjust the environment / alias list size size = QueryMemSize( pchList ); if ( pchList == glpEnvironment ) gpIniptr->EnvSize = (unsigned int)size; else if ( pchList == glpAliasList ) gpIniptr->AliasSize = (unsigned int)size; } if ( env_arg != 0L ) { // modify an existing alias or environment variable // adjust the space & insert new value feptr = next_env( feptr ); memmove(( feptr + length ), feptr, (unsigned int)( last_var - feptr) + 1 ); strcpy( env_arg, line ); } else { // put it at the end & add an extra null strcpy( last_var, envstr ); last_var[length] = '\0'; } } add_bye: if ( pchList == glpAliasList ) { // clear the semaphore FreeSemaphore( SemHandle ); EnableSignals(); } return rval; }
// add a variable to the environment or alias to the alias list int PASCAL add_list( LPTSTR pszVariable, TCHAR _far *pchList ) { LPTSTR pszLine; TCHAR _far *pszVarName, _far *pszArgument, _far *pszEndOfList, _far *pszLastVariable; unsigned int uLength; int nError = 0; if ( pchList == 0L ) pchList = glpEnvironment; pszLine = pszVariable; if ( *pszLine == _TEXT('=') ) { return ( error( ERROR_4DOS_BAD_SYNTAX, pszVariable )); } for ( ; (( *pszLine ) && ( *pszLine != _TEXT('=') )); pszLine++ ) { if ( pchList != glpEnvironment ) { if ( iswhite( *pszLine )) { strcpy( pszLine, skipspace( pszLine ) ); break; } } else // ensure environment entry is in upper case *pszLine = (unsigned char)_ctoupper( *pszLine ); } // stupid kludge to strip quotes from PATH for compatibility with // COMMAND.COM if (( fWin95 ) && ( pchList == glpEnvironment )) { char szVarName[8]; if (( uLength = ( pszLine - pszVariable )) > 7 ) uLength = 7; sprintf( szVarName, "%.*s", uLength, pszVariable ); if ( stricmp( szVarName, PATH_VAR ) == 0 ) StripQuotes( pszLine ); } if ( *pszLine == _TEXT('=') ) { // point to the first char of the argument pszLine++; // collapse whitespace around '=' in aliases, but not in env // variables, for COMMAND.COM compatibility (set abc def= ghi) if ( pchList != glpEnvironment ) strcpy( pszLine, skipspace( pszLine )); } else if ( *pszLine ) { // add the missing '=' strins( pszLine, _TEXT("=") ); pszLine++; } // removing single back quotes at the beginning and end of an alias // argument (they're illegal there; the user is probably making a // mistake with ALIAS /R) if (( *pszLine == SINGLE_QUOTE ) && ( pchList != glpEnvironment )) { // remove leading single quote strcpy( pszLine, pszLine + 1 ); // remove trailing single quote if ((( uLength = strlen( pszLine )) != 0 ) && ( pszLine[--uLength] == SINGLE_QUOTE )) pszLine[uLength] = _TEXT('\0'); } // block other processes & threads while updating list if ( pchList != glpEnvironment ) { // disable task switches under Windows and DESQview CriticalSection( 1 ); } // get pointers to beginning & end of list space pszEndOfList = pchList + ((( pchList == glpAliasList ) ? gpIniptr->AliasSize : gpIniptr->EnvSize ) - 4 ); // get pointer to end of environment or alias variables pszLastVariable = end_of_env( pchList ); uLength = strlen( pszVariable ) + 1; // check for modification or deletion of existing entry if (( pszArgument = get_list( pszVariable, pchList )) != 0L ) { // get the start of the alias or variable name for ( pszVarName = pszArgument; (( pszVarName > pchList ) && ( pszVarName[-1] != _TEXT('\0') )); pszVarName-- ) ; if ( *pszLine == _TEXT('\0') ) { // delete an alias or environment variable _fmemmove( pszVarName, next_env( pszVarName ), (unsigned int)( (ULONG_PTR)pszLastVariable - (ULONG_PTR)next_env(pszVarName)) + sizeof(TCHAR)); } else { // get the relative length (vs. the old variable) uLength = strlen( pszLine ) - _fstrlen( pszArgument ); } } if ( *pszLine != _TEXT('\0') ) { // check for out of space if (( pszLastVariable + ( uLength * sizeof(TCHAR) )) >= pszEndOfList ) { if ( pchList == glpAliasList ) nError = error( ERROR_4DOS_OUT_OF_ALIAS, NULL ); else if ( pchList == glpEnvironment ) nError = error( ERROR_4DOS_OUT_OF_ENVIRONMENT, NULL); else nError = error( ERROR_NOT_ENOUGH_MEMORY, NULL ); goto add_bye; } if ( pszArgument != 0L ) { // modify an existing value // adjust the space & insert new value pszVarName = next_env( pszVarName ); _fmemmove(( pszVarName + uLength ), pszVarName, (unsigned int)(( (ULONG_PTR)pszLastVariable - (ULONG_PTR)pszVarName ) + sizeof(TCHAR) )); _fstrcpy( pszArgument, pszLine ); } else { // put it at the end & add an extra null _fstrcpy( pszLastVariable, pszVariable ); pszLastVariable[uLength] = _TEXT('\0'); } } add_bye: if ( pchList != glpEnvironment ) { // re-enable task switches under Windows and DESQview CriticalSection( 0 ); } return nError; }