// retrieve an environment or alias list entry TCHAR _far * PASCAL get_list( LPTSTR pszName, TCHAR _far *pchList ) { LPTSTR pszArg; register int fWild; TCHAR _far *pchEnv; TCHAR _far *pchStart; if ( pchList == 0L ) pchList = glpEnvironment; for ( pchEnv = pchList; *pchEnv; ) { // aliases allow "wher*eis" ; so collapse the '*', and // only match to the length of the varname pszArg = pszName; fWild = 0; pchStart = pchEnv; do { if (( pchList == glpAliasList ) && ( *pchEnv == _TEXT('*') )) { pchEnv++; fWild++; // allow entry of "ab*cd=def" if ( *pszArg == _TEXT('*') ) pszArg++; } if ((( *pszArg == _TEXT('\0') ) || ( *pszArg == _TEXT('=') )) && ((( *pchEnv == _TEXT('=') ) && ( pchEnv != pchStart )) || ( fWild ))) { for ( ; ( *pchEnv ); pchEnv++ ) { if ( *pchEnv == _TEXT('=') ) return ++pchEnv; } return 0L; } } while ( _ctoupper( *pchEnv++ ) == _ctoupper( *pszArg++ )); while ( *pchEnv++ != _TEXT('\0') ) ; } return 0L; }
static int _fmtin(char *source, const char *fmt, va_list arg) { char *base, *fptr; char ignore, reject, using_table, sign_flag; int n, fields = 0, width, value; char table[256]; // ASCII table for %[^...] // save start point (for %n) base = source; while (*fmt != '\0') { if (*fmt == '%') { ignore = reject = using_table = sign_flag = 0; if (*(++fmt) == '*') { fmt++; ignore++; } // get max field width if ((*fmt >= '0') && (*fmt <= '9')) { for (width = atoi(fmt); ((*fmt >= '0') && (*fmt <= '9')); fmt++) ; } else width = INT_MAX; next_fmt: switch (*fmt) { case 'l': // long int case 'F': // far pointer fmt++; goto next_fmt; case '[': using_table++; if (*(++fmt) == '^') { reject++; fmt++; } memset( table, reject, 256 ); for ( ; ((*fmt) && (*fmt != ']')); fmt++) table[*fmt] ^= 1; case 'c': case 's': if ((*fmt == 'c') && (width == INT_MAX)) width = 1; else if (*fmt == 's') { // skip leading whitespace while ((*source == ' ') || (*source == '\t')) source++; } if (ignore == 0) fptr = (char *)(va_arg(arg, char *)); for ( ; ((width > 0) && (*source)); source++, width--) { if (using_table) { if (table[*source] == 0) break; } else if ((*fmt == 's') && ((*source == ' ') || (*source == '\t'))) break; if (ignore == 0) *fptr++ = *source; } if (ignore == 0) { if (*fmt != 'c') *fptr = '\0'; fields++; } break; case 'd': case 'u': case 'x': // skip leading whitespace while ((*source == ' ') || (*source == '\t')) source++; if (*fmt == 'x') { for (fptr = source, value = 0; ((width > 0) && (isxdigit(*source))); source++, width--) { n = ((isdigit(*source)) ? *source - '0' : (_ctoupper(*source) - 'A') + 10); value = (value * 16) + n; } } else { // check for leading sign if (*source == '-') { sign_flag++; source++; } else if (*source == '+') source++; for (fptr = source, value = 0; ((width > 0) && (*source >= '0') && (*source <= '9')); source++, width--) value = (value * 10) + (*source - '0'); if (sign_flag) value = -value; } case 'n': // number of characters read so far if (*fmt == 'n') value = (int)(source - base); if (ignore == 0) { *(va_arg(arg,unsigned int *)) = (unsigned int)value; // if start was a digit, inc field count if ((*fmt == 'n') || ((*fptr >= '0') && (*fptr <= '9'))) fields++; } break; default: if (*fmt != *source++) return fields; } fmt++; } else if (iswhite(*fmt)) {
// draw a horizontal or vertical line directly to the display int drawline_cmd( int argc, char **argv ) { int attribute = -1; int row, col, len, width; // get the arguments & colors if (( argc >= 6 ) && ( sscanf( argv[1], "%d%d%d%d", &row, &col, &len, &width ) == 4 )) attribute = GetColors( argv[5], 0 ); return ((( attribute == -1 ) || ( verify_row_col( row, col )) || ( _line( row, col, len, width,(_ctoupper( argv[0][4] ) == 'V' ), attribute, 1 ) != 0 )) ? usage( DRAWLINE_USAGE ) : 0 ); }
// 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; }
// retrieve an environment or alias list entry char * get_list( char *varname, PCH pchList ) { char *arg; int wildflag; PCH pchEnv; PCH pchStart; static char szLibPath[512]; if ( pchList == 0L ) pchList = glpEnvironment; // special case for BeginLIBPATH and EndLIBPATH if ( pchList == glpEnvironment ) { szLibPath[0] = '\0'; if ( stricmp( varname, BEGINLIBPATH ) == 0 ) { if ((DosQueryExtLIBPATH( szLibPath, BEGIN_LIBPATH ) == NO_ERROR ) && ( szLibPath[0] != '\0' )) return szLibPath; return 0L; } if ( stricmp( varname, ENDLIBPATH ) == 0 ) { if ((DosQueryExtLIBPATH( szLibPath, END_LIBPATH ) == NO_ERROR ) && ( szLibPath[0] != '\0' )) return szLibPath; return 0L; } } for ( pchEnv = pchList; *pchEnv; ) { // aliases allow "wher*eis" ; so collapse the '*', and // only match to the length of the varname arg = varname; wildflag = 0; pchStart = pchEnv; do { if (( pchList == glpAliasList ) && ( *pchEnv == '*' )) { pchEnv++; wildflag++; // allow entry of "ab*cd=def" if ( *arg == '*' ) arg++; } if ((( *arg == '\0' ) || ( *arg == '=' )) && ((( *pchEnv == '=' ) && ( pchEnv != pchStart )) || ( wildflag ))) { for ( ; ( *pchEnv ); pchEnv++ ) { if ( *pchEnv == '=' ) return ++pchEnv; } return NULL; } } while ( _ctoupper( *pchEnv++ ) == _ctoupper( *arg++ )); while ( *pchEnv++ != '\0' ) ; } return 0L; }
// 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; }