//**************************************************************************
//
// RANDOM
//
// Performs random SLM operations against a server to test the network.
//
// Syntax:
//
// random [-i | -k] [-s start_dir] [-r slm_root] [-p project]
// [-d delay_seconds] [-h | -?] [-c iteration count]
//
// Modifications:
//
// 06.03.91 Joe Holman Changed case items.
// 06.07.91 Arden White Added current path printf to run()
// 06.10.91 Joe Holman Added \n to printf.
// 07.01.91 Lyle Corbin Added -l option and time printout
// 07.02.91 Lyle Corbin General cleanup
// 07.12.91 Lyle Corbin Changed -l to -k and -i.
// 07.17.91 Lyle Corbin Limited InEditOut to 5 files max
// 11.20.91 Joe Holman Typedef -1 with HANDLE.
// 06.15.92 Joe Holman Added -$ switch so things won't
// block forever on blocked slm status
// files.
// 01.06.93 Sanjeev Katariya Included a run time iteration count
// control
//
//
//**************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include <string.h>
#ifdef NT
#include <windows.h>
#endif /* NT */
#ifndef NT
#define INCL_BASE
#define ExitProcess(x) exit(x)
#define MAX_PATH _MAX_PATH
#include <os2.h>
typedef char *LPSTR;
USHORT GetCurrentDirectory(USHORT, PSZ);
BOOL SetCurrentDirectory(PSZ);
USHORT GetEnvironmentVariable(PSZ, PBYTE, USHORT);
#endif /* ndef NT */
#define TIMELEN 26 // Length of time string returned by ctime().
#define NUMWAYS 4 // UP, DOWN, or SAME directory.
#define FOREVER 1
#define BUFSZ MAX_PATH
#define DEFAULT_PROJECT "public"
#define RANDOMPROJECT "RANDOMPROJECT"
#define DEFAULT_SLMTOP "c:\\slmtest"
#define RANDOMSLMTOP "RANDOMSLMTOP"
#define DEFAULT_SLMROOT "\\\\ntsrv1\\slmtest"
#define RANDOMSLMROOT "RANDOMSLMROOT"
#define SLMININAME "slm.ini"
#define MAX_PROJECT 256
#define ALLFILES "*"
#define DEFAULTDELAY 5 // Seconds
#define NUMATOMICS 13
#if 0
#define TIMESTAMPFILE "IWasHere.ran"
#endif /* 0 */
// For the directory routines:
#define DIRSONLY 1 // Include only dirs.
#define FILESONLY 2 // Include only files.
#define FILESANDDIRS 3 // Include both files and dirs.
// Flag values for -i and -k
#define IN_NORMAL 1 // neither -i or -k (default)
#define IN_IGNORE 2 // -i
#define IN_BINARY 3 // -k
int direction;
char strBuf[BUFSZ];
int InFlag=IN_NORMAL;
int FileVerifyOn = 0;
unsigned long ul_iterationcount = 0xffffffff; // Default value is 4 Tera
char strStartTime[BUFSZ];
time_t curtime;
void EditFile( char * );
void run( char * );
void randslm ( void );
void SetProject( char *, int, int, char ** );
void SetSlmTop( char *, int, int, char ** );
void SetSlmRoot( char *, int, int, char ** );
void Usage( char * );
int OutEditIn( void );
int PatternCountFiles( char *, int );
BOOL DirExists( char * );
BOOL MoveDown ( void );
BOOL RandomPickFile( char *, int );
BOOL FindNthFile( char *, char *, int, int );
BOOL ExistsFile( char * );
BOOL MakeSlmINI( char *, char * );
char *sbMakeString( char *, char * );
#define DisposeString(str) free(str);
void main ( int argc, char ** argv ) {
int zero, one, two;
int argi = 1; // Argument index.
char sbSlmTop[MAX_PATH];
char sbSlmRoot[MAX_PATH];
char sbProject[MAX_PROJECT];
int secDelay = DEFAULTDELAY;
BOOL bAtTop = TRUE;
unsigned long ul_Counter = 0;
//
// Process any arguments and initialize some variables
//
for (argi = 1; argi < argc; argi++) {
if (argv[argi][0] == '-') {
switch (argv[argi][1]) {
case 'd':
argi++;
if (argi >= argc)
// No return from Usage.
Usage("Missing delay value with -d option\n");
else
secDelay = atoi(argv[argi]);
printf("New delay value set to %d seconds.\n", secDelay);
break;
case 'i':
if (InFlag == IN_BINARY)
Usage("-i and -k cannot be used together.\n");
// Usage doesn't return
InFlag = IN_IGNORE;
printf("Using -i on check in's.\n");
break;
case 'k':
if (InFlag == IN_IGNORE)
Usage("-i and -k cannot be used together.\n");
// Usage doesn't return
InFlag = IN_BINARY;
printf("Using -k on check in's.\n");
break;
case 'c': // Introduce iteration count to control execution
argi++;
if (argi >= argc)
// No return from Usage.
Usage("Missing iteration count value with -c option\n");
else
ul_iterationcount = atol(argv[argi]);
if ( ul_iterationcount == 0 )
ul_iterationcount = 0xffffffff;
else
printf("New iteration count value set to %ld.\n", ul_iterationcount);
break;
case 'v': // Turn file verification on
FileVerifyOn = 1;
break;
case 's':
case 'r':
case 'p':
// These are taken care of below.
break;
case 'h': // Usage
case '?':
default:
Usage("\n"); // Does not return.
break;
}
}
}
SetSlmTop(sbSlmTop, MAX_PATH, argc, argv); // Get the SLM top directory
printf("Starting dir is %s\n", sbSlmTop);
if (!DirExists(sbSlmTop)) {
printf("%s: does not exist.\n", sbSlmTop);
ExitProcess(1);
}
// Set to top os tree and convert sbSlmTop to standard format.
SetCurrentDirectory(sbSlmTop);
GetCurrentDirectory(MAX_PATH, (LPSTR)sbSlmTop);
SetSlmRoot(sbSlmRoot, MAX_PATH, argc, argv);
printf("SLM root dir is %s\n", sbSlmRoot);
SetProject(sbProject, MAX_PROJECT, argc, argv);
printf("SLM project is %s\n", sbProject);
// seed the random-number generator with the current
// time so that the numbers will be different
// every time.
zero = 0; one = 0; two = 0;
srand ( (unsigned) time ( NULL ) );
(void) time( &curtime ); // Store the Start Time
strcpy( strStartTime, ctime( &curtime ));
printf( "Starting at %s\n", strStartTime );
while ( ul_iterationcount ) {
// If at the top of the slm tree then move down one directory.
GetCurrentDirectory ( BUFSZ, (LPSTR) strBuf );
if ( _stricmp ( strBuf, sbSlmTop ) == 0 ) {
bAtTop = TRUE;
direction = 1; // Force a move down.
} else {
bAtTop = FALSE;
direction = rand() % NUMWAYS;
}
printf ("**********************************************************\n");
printf ("* New Variation Beginning *\n");
printf ("**********************************************************\n");
if ( ul_iterationcount != 0xffffffff ) {
printf("\n\n**********************************************************\n");
printf(" Random.exe Iteration level: %ld \n", ul_Counter );
printf("**********************************************************\n");
}
switch ( direction ) {
case 0 : // Go up one level.
++zero;
printf ( "%5d UP : \n", zero );
if (SetCurrentDirectory("..")) {
GetCurrentDirectory ( BUFSZ, (LPSTR) strBuf );
if ( _stricmp ( strBuf, sbSlmTop ) == 0 ) {
printf("WARNING: at top of slm tree...going back down.\n");
continue;
} else {
#ifdef TIMESTAMPFILE
EditFile(TIMESTAMPFILE);
#endif /* TIMESTAMPFILE */
}
}
break;
case 1 : // Randomly go down one level.
case 3 :
++one;
printf ( "%5d DOWN: \n", one );
if (MoveDown()) {
#ifdef TIMESTAMPFILE
EditFile(TIMESTAMPFILE);
#endif /* TIMESTAMPFILE */
} else if (bAtTop) {
printf("No directorys in slm tree.\n");
printf("Bailing out.\n");
ExitProcess(1);
}
break;
case 2 : // Randomly stay here ;-)
++two;
printf ( "%5d SAME: \n", two );
break;
default :
printf ( "main: illegal case in switch...\n" );
exit (1);
break;
} // switch
GetCurrentDirectory ( BUFSZ, (LPSTR) strBuf );
printf ( "NOW IN %s.\n", (LPSTR) strBuf );
randslm();
GetCurrentDirectory ( BUFSZ, (LPSTR) strBuf );
if (!ExistsFile(SLMININAME)) {
printf("Looks like there is no slm.ini in this directory.\n");
printf("Trying to create one. One moment please....\n");
if (!MakeSlmINI(sbSlmRoot, sbProject)) {
printf("Couldn't create a slm.ini! Giving up!\n");
ExitProcess(1);
}
}
#ifdef NT
Sleep ( (LONG)(DEFAULTDELAY * 1000) );
#else
DosSleep ( (LONG)(DEFAULTDELAY * 1000) );
#endif /* NT */
if ( ul_iterationcount != 0xffffffff ) {
ul_iterationcount--;
ul_Counter++;
}
} // while
ExitProcess( 0 );
}
//**************************************************************************
//
// MoveDown
// Randomly pick a directory from the current directory and
// change (move down) into that directory. Returns TRUE if cd
// worked.
//
//**************************************************************************
BOOL MoveDown ( void ) {
char sbFileName[MAX_PATH];
if (!RandomPickFile(sbFileName, DIRSONLY)) {
printf ( "**** No sub-directories here!!!\n" );
return(FALSE);
}
return(SetCurrentDirectory (sbFileName));
}
//**************************************************************************
// randslm
// Randomly picks a sequence of operations to perform and performs them.
//
//**************************************************************************
void randslm () {
int atom;
atom = rand() % NUMATOMICS;
printf ( "*** Running ATOM #%d ***\n", atom );
switch ( atom ) {
case 0 :
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
run ( "ssync -$ -f -v -u *.*" );
run ( "out -$ -f -v *.*" );
switch ( InFlag ) {
case IN_IGNORE : run ( "in -$ -f -v -i *.*" );
break;
case IN_BINARY : run ( "in -$ -f -v -k *.*" );
break;
default : run ( "in -$ -f -v *.*" );
break;
}
run ( "ssync -$ -f -v -g *.*" );
break;
case 6 :
// run ( "log -f -v -i -5" );
// break;
case 7 :
// run ( "log -f -v -7" );
// break;
case 8 :
case 9 :
case 10:
case 11:
case 12:
OutEditIn();
break;
default :
printf ("main: illegal case in switch, atom # == %d...\n", atom);
break;
}
}
//**************************************************************************
//
// OutEditIn
//
// Randomly selects N of M file(s) in the directory to checkout,
// edit and check in.
//
//**************************************************************************
int OutEditIn() {
char sbEditFile[MAX_PATH]; // File name of file to edit.
char *sbRun;
int FileNum, numTimes, NthFile, i;
HANDLE pv_FileHandle;
int RandomFileVerifyOn = 0;
printf("\n\n**********************************************************\n");
printf("* Editing Files Randomly *\n");
printf("**********************************************************\n\n");
/*
* Unghost all the files in the directory.
*/
run ("ssync -$ -u -f -v *.*");
/*
* Get # of normal source files in directory.
*/
FileNum = PatternCountFiles(ALLFILES, FILESONLY);
if ( FileNum == 0 ) {
printf ( "OutEditIn: no files found...\n" );
return(1);
}
printf ( "Found %d files...\n", FileNum );
/*
* Calculate N of M files we want to change.
* A maximum of 5 files will be selected for modification
*/
numTimes = rand() % ((FileNum < 5) ? FileNum : 5);
for ( i = 0; i < numTimes; ++i ) {
printf ( "Editing file %d of %d file(s) to modify...\n", i, numTimes );
/*
* Pick one of the files in the
* directory.
*/
NthFile = (rand() % FileNum) + 1;
FindNthFile(ALLFILES, sbEditFile, NthFile, FILESONLY);
/*
* Check the file out. A random number is generated to check files
* out synchronously. These files are modified and verified by
* by only one process
*/
if ( FileVerifyOn || (rand()==0) ) {
sbRun = sbMakeString("out -$ -f -v -n %s", sbEditFile);
RandomFileVerifyOn = 1;
} else {
sbRun = sbMakeString("out -$ -f -v %s", sbEditFile);
}
run (sbRun);
DisposeString(sbRun);
/*
* Modify the file.
*/
EditFile(sbEditFile);
/*
* Check the file back in but in a fashion that the master sources are
* updated but the file still stays checked out. This is done for the
* verification step.
*/
switch ( InFlag ) {
case IN_IGNORE : sbRun = sbMakeString("in -$ -f -v -i %s", sbEditFile);
break;
case IN_BINARY : sbRun = sbMakeString("in -$ -f -v -k %s", sbEditFile);
break;
default : if ( FileVerifyOn || RandomFileVerifyOn ) {
sbRun = sbMakeString("in -$ -f -v -u %s", sbEditFile);
} else {
sbRun = sbMakeString("in -$ -f -v %s", sbEditFile);
}
break;
}
run (sbRun);
DisposeString(sbRun);
//
// If File verification is on or Random File Verification is on
//
if ( FileVerifyOn || RandomFileVerifyOn ) {
printf("\n\n**********************************************************\n");
printf("* Commencing File Verification *\n");
printf("**********************************************************\n\n");
//
// At this point we have checked out the file, made changes to it
// and have updated the master sources. Now is the time to verify that the current
// local file and the current master file are the same. In the event of
// a difference(this is crucial) we will exit the program and report a
// possible corruption bug
//
//
// Generate the string which will compare the current local file
// and the current master file
//
sbRun = sbMakeString("scomp -f -v %s", sbEditFile );
run( sbRun );
DisposeString(sbRun);
//
// This would have created the file slm.dif\xxx where xxx = sbEditFile
// Make sure that the file size is zero. If it is greater than zero,
// we have encountered trouble
//
printf("Initiate data integrity check on file %s\n", sbEditFile );
sbRun = sbMakeString(".\\slm.dif\\%s", sbEditFile );
pv_FileHandle = CreateFile( (LPCTSTR)sbRun, GENERIC_READ, 0,
(LPSECURITY_ATTRIBUTES)0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,(HANDLE)0 );
if ( pv_FileHandle == INVALID_HANDLE_VALUE ) {
printf("An error has occurred during data validation while attempting to open %s\007\007\n", sbRun );
printf("The return code for failure is : %d\n", GetLastError() );
} else {
DWORD ul_HighOrderSize = 0, ul_LowOrderSize = 0;
//
// We now perform the data file validation
//
SetLastError( ERROR_SUCCESS );
ul_LowOrderSize = GetFileSize( pv_FileHandle, &ul_HighOrderSize );
if ( GetLastError() == NO_ERROR ) {
if ( ul_LowOrderSize ) {
printf("\n\nThere is possible file corruption in %s. Please verify data integrity\007\007\n", sbEditFile );
} else {
printf("Completed successful data validation on %s\n", sbEditFile );
}
} else {
printf("An error has occurred during data validation while attempting to determine the file differences in %s\n", sbEditFile );
}
}
//
// Remove the read attribute on the slm.dif\xx file and then delete it.
// Finally remove the directory slm.dif and continue
//
CloseHandle( pv_FileHandle );
SetFileAttributes( (LPTSTR)sbRun, FILE_ATTRIBUTE_ARCHIVE );
DeleteFile( sbRun );
DisposeString( sbRun );
RemoveDirectory( (LPTSTR)".\\SLM.DIF" );
//
// And finally check the file back in
//
sbRun = sbMakeString("in -$ -f -v %s", sbEditFile);
run (sbRun);
DisposeString(sbRun);
}
}
/*
* Ghost all the files in the directory.
*/
run ("ssync -$ -g -f -v *.*");
}
//**************************************************************************
// run
// Execute a system call
//
//**************************************************************************
void run ( char * string ) {
int rc;
char strBuf[BUFSZ];
time ( &curtime );
printf("\n-------------- Current Time: %s", ctime( &curtime ));
printf("This session was started at: %s\n", strStartTime );
GetCurrentDirectory ( BUFSZ, (LPSTR) strBuf );
printf ( "STARTING: %s in %s.\n", string, strBuf);
rc = 0;
rc = system ( string );
if ( rc == -1 ) {
printf ( "run: system() FAILed...\n" );
exit (1);
}
printf ( "DONE WITH: %s in %s.\n\n", string, strBuf);
}
//**************************************************************************
//
// SetProject
// Determines the desired slm project based on one of three criteria:
// 1) the project passed as an argument to the program,
// 2) an environment variable called RANDOMPROJECT,
// 3) the default project DEFAULT_PROJECT.
//
//**************************************************************************
void SetProject(char *sbProject, int sbLength, int argc, char **argv) {
int argi;
argi = 1;
while ((argi < argc) && (strcmp("-p", argv[argi]) != 0)) {
argi++;
}
/*
* Stopped before the end of arguments?
*/
if (argi < argc) {
argi++;
if (argi == argc) {
Usage("Missing project argument for -p option.\n");
// No return from Usage.
}
strncpy(sbProject, argv[argi], sbLength);
return;
}
/*
* Try for an environment variable.
*/
if (GetEnvironmentVariable(RANDOMPROJECT, sbProject, sbLength) != 0) {
return;
}
/*
* Just use the default variable.
*/
strncpy(sbProject, DEFAULT_PROJECT, sbLength);
}
//**************************************************************************
//
// SetSlmTop
// Determines the desired top of the slm tree based on one of
// three criteria:
// 1) the path passed as an argument to the program,
// 2) an environment variable called RANDOMSLMTOP,
// 3) the current directory.
//
//**************************************************************************
void SetSlmTop(char *sbSlmTop, int sbLength, int argc, char **argv) {
int argi;
argi = 1;
while ((argi < argc) && (strcmp("-s", argv[argi]) != 0)) {
argi++;
}
/*
* Stopped before the end of arguments?
*/
if (argi < argc) {
argi++;
if (argi == argc) {
Usage("Missing starting directory argument for -s option.\n");
// No return from Usage.
}
strncpy(sbSlmTop, argv[argi], sbLength);
return;
}
/*
* Try for an environment variable.
*/
if (GetEnvironmentVariable(RANDOMSLMTOP, sbSlmTop, sbLength) != 0) {
return;
}
/*
* Just use the default variable.
*/
GetCurrentDirectory(sbLength, sbSlmTop);
}
//**************************************************************************
//
// SetSlmRoot
// Determines the desired root of the slm tree based on one of
// three criteria:
// 1) the path passed as an argument to the program,
// 2) an environment variable called RANDOMSLMROOT,
// 3) the default root "\\earth\slmtest".
//
//**************************************************************************
void SetSlmRoot(char *sbSlmRoot, int sbLength, int argc, char **argv) {
int argi;
argi = 1;
while ((argi < argc) && (strcmp("-r", argv[argi]) != 0)) {
argi++;
}
/*
* Stopped before the end of arguments?
*/
if (argi < argc) {
argi++;
if (argi == argc) {
Usage("Missing root directory argument for -r option.\n");
// No return from Usage.
}
strncpy(sbSlmRoot, argv[argi], sbLength);
return;
}
/*
* Try for an environment variable.
*/
if (GetEnvironmentVariable(RANDOMSLMROOT, sbSlmRoot, sbLength) != 0) {
return;
}
/*
* Just use the default variable.
*/
strncpy(sbSlmRoot, DEFAULT_SLMROOT, sbLength);
}
//**************************************************************************
//
// Usage
// Prints the command syntax for this commmand.
//
//**************************************************************************
void Usage(char *errString) {
printf("%s", errString);
printf("Usage: random [-i | -k] [-s start_dir] [-r slm_root] ");
printf("[-p project] [-d delay] [-c IterationCount] [-v]\n");
printf(" or use the following environment variables:\n");
printf(" %s=current_dir (default value)\n", RANDOMSLMTOP);
printf(" %s=%s (default value)\n", RANDOMSLMROOT, DEFAULT_SLMROOT);
printf(" %s=%s (default value)\n", RANDOMPROJECT, DEFAULT_PROJECT);
printf(" %d sec delay (default)\n", DEFAULTDELAY);
printf(" -i causes random to use -i option with 'in'\n");
printf(" -k causes random to use -k option with 'in'\n");
printf(" -v turns on file verification for the operation 'in'\n");
ExitProcess(1);
}
//**************************************************************************
//
// DirExists
// Checks to see if the given directory exists.
//
//**************************************************************************
BOOL DirExists(char *sbDirName) {
char sbCurPath[MAX_PATH];
// Save current directory.
if (GetCurrentDirectory(MAX_PATH, sbCurPath) == 0) {
printf("GetCurrentDirectory failed.\n");
ExitProcess(1);
}
// Try to change to the directory in question.
if (!SetCurrentDirectory((LPSTR)sbDirName)) {
return(0);
}
// There's no place like home.
if (!SetCurrentDirectory((LPSTR)sbCurPath)) {
printf("SetCurrentDirectory failed.\n");
ExitProcess(1);
}
return(1);
}
//**************************************************************************
//
// EditFile
// Edit the given file. We really just add a time string at
// the end of the file.
//
//**************************************************************************
void EditFile(char *sbFileName) {
FILE *fp;
time_t ltime;
char sbTime[TIMELEN];
printf("Editing file: %s\n", sbFileName);
// Open file to be edited.
if ((fp = fopen(sbFileName, "ab")) == NULL) {
printf("EditFile: unable to open file %s\n", sbFileName);
return;
}
// Just add a new time line at the end of the file.
(void) time(<ime);
strcpy(sbTime, ctime(<ime));
sbTime[strlen(sbTime) - 1] = '\0'; // Eliminate newline char.
fprintf(fp, "===> Last edit date: %s\r\n", sbTime);
// Don't forget to close.
if (fclose(fp) == EOF) {
printf("EditFile: unable to close file %s\n", sbFileName);
return;
}
return;
}
//**************************************************************************
//
// sbMakeString
// Combine two strings using sprintf. The format string must contain
// a %s that indicates the position for inserting the second string.
// Note: only one %s is allowed in the format string.
// Use DisposeString to free the space allocated by this routine.
//
//**************************************************************************
char *sbMakeString(char *sbFormat, char *sbSubstitute) {
int MaxLen; // Length of entire string after substitution.
char *sbNewString; // Pointer to newly allocated string
// Calculate length of new string (will always be longer
// than necessary by 1 character).
MaxLen = strlen(sbFormat) + strlen(sbSubstitute) + 1;
if ((sbNewString = malloc(MaxLen)) == NULL) {
printf("sbMakeString: malloc failed (size = %d)\n", MaxLen);
ExitProcess(1);
}
memset( sbNewString, 0, MaxLen*sizeof( char ) );
sprintf(sbNewString, sbFormat, sbSubstitute);
return(sbNewString);
}
//**************************************************************************
//
// RandomPickFile
// Randomly chooses one of the files from the current directory.
// Returns TRUE if it succeeds and FALSE otherwise.
//
//**************************************************************************
BOOL RandomPickFile(char *sbFileName, int FileType) {
int FileNum;
FileNum = PatternCountFiles(ALLFILES, FileType);
if (FileNum == 0) {
return(FALSE);
}
FileNum = (rand() % FileNum) + 1;
if (!FindNthFile(ALLFILES, sbFileName, FileNum, FileType)) {
return(FALSE);
}
return(TRUE);
}
#ifdef NT // ------------------ USED FOR NT BUILDS ONLY -------------
//**************************************************************************
//
// PatternCountFiles
// Return the number of files that match the given pattern.
// If, for some unknown reason, the FindFirstFile fails, we just
// return 0. Hidden files are ignored.
// If FileType is FILESONLY then only files will be counted,
// If FileType is DIRSONLY, then only directories will be
// counted (except . and ..)
// If FileType is DIRSANDFILES then files & dirs are counted (not . & ..).
//
//**************************************************************************
int PatternCountFiles(char *pattern, int FileType) {
HANDLE fh;
WIN32_FIND_DATA FindFileData;
int fCount = 0;
if ((fh = FindFirstFile((LPSTR)pattern,
(LPWIN32_FIND_DATA)&FindFileData)) == (HANDLE) -1) {
// Close in any case, may return an error (but, so what?)
(void)FindClose(fh);
return(fCount);
}
while (FOREVER) {
if (((strcmp(FindFileData.cFileName, ".") != 0) &&
(strcmp(FindFileData.cFileName, "..") != 0)) &&
((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0)) {
switch (FileType) {
case DIRSONLY:
if (FindFileData.dwFileAttributes &
FILE_ATTRIBUTE_DIRECTORY) {
fCount++;
}
break;
case FILESONLY:
if (!(FindFileData.dwFileAttributes &
FILE_ATTRIBUTE_DIRECTORY)) {
fCount++;
}
break;
case FILESANDDIRS:
if (FileType == FILESANDDIRS) {
fCount++;
}
break;
default:
printf("PatternCountFiles: Bad FileType (%d).\n", FileType);
break;
}
}
if (!FindNextFile(fh, (LPWIN32_FIND_DATA)&FindFileData)) {
break;
}
}
if (!FindClose(fh)) {
printf("PatternCountFiles: FindClose failed\n");
printf("PatternCountFiles: pattern=%s\n", pattern);
ExitProcess(1);
}
return(fCount);
}
#else // ------------------ USED FOR NON-NT BUILDS --------------------
//**************************************************************************
//
// PatternCountFiles
// Return the number of files that match the given pattern.
// If, for some unknown reason, the FindFirstFile fails, we just
// return 0. Hidden files are ignored.
// If FileType is FILESONLY then only files will be counted,
// If FileType is DIRSONLY, then only directories will be
// counted (except . and ..)
// If FileType is DIRSANDFILES then files & dirs are counted (not . & ..).
//
//**************************************************************************
int PatternCountFiles(char *pattern, int FileType) {
USHORT rc; // Return code.
HDIR fh; // Directory file handle
USHORT usAttribute;
FILEFINDBUF FindFileData;
USHORT usSearchCount;
int fCount = 0;
if (FileType == FILESONLY) {
usAttribute = FILE_NORMAL|FILE_READONLY|FILE_SYSTEM|FILE_ARCHIVED;
} else if (FileType == DIRSONLY) {
usAttribute = FILE_DIRECTORY|FILE_READONLY|FILE_SYSTEM|FILE_ARCHIVED;
} else if (FileType == FILESANDDIRS) {
usAttribute = FILE_NORMAL|FILE_DIRECTORY|FILE_READONLY|FILE_SYSTEM|
FILE_ARCHIVED;
} else {
printf("PatternCountFiles: Bad FileType %d\n", FileType);
ExitProcess(1);
}
fh = HDIR_CREATE;
usSearchCount = 1;
if ((rc = DosFindFirst((PSZ)pattern,
(PHDIR)&fh,
usAttribute,
(PFILEFINDBUF)&FindFileData,
(USHORT)sizeof(FindFileData),
(PUSHORT)&usSearchCount, 0L)) != 0) {
// Close in any case, may return an error (but, so what?)
(void)DosFindClose(fh);
return(fCount);
}
while (FOREVER) {
if (((strcmp(FindFileData.achName, ".") != 0) &&
(strcmp(FindFileData.achName, "..") != 0)) &&
((FindFileData.attrFile & FILE_HIDDEN) == 0)) {
switch (FileType) {
case DIRSONLY:
if (FindFileData.attrFile & FILE_DIRECTORY) {
fCount++;
}
break;
case FILESONLY:
if (!(FindFileData.attrFile & FILE_DIRECTORY)) {
fCount++;
}
break;
case FILESANDDIRS:
if (FileType == FILESANDDIRS) {
fCount++;
}
break;
default:
printf("PatternCountFiles: Bad FileType (%d).\n", FileType);
break;
}
}
if (DosFindNext(fh, (PFILEFINDBUF)&FindFileData,
sizeof(FindFileData), &usSearchCount) != 0) {
break;
}
}
if ((rc = DosFindClose(fh)) != 0) {
printf("PatternCountFiles: FindClose failed (%d)\n", rc);
printf("PatternCountFiles: pattern=%s\n", pattern);
ExitProcess(1);
}
return(fCount);
}
#endif /* NT */
#ifdef NT // --------------------- USED FOR NT BUILDS ONLY ----------
//**************************************************************************
//
// FindNthFile
// Find the Nth file name in the current directory (starting from 1).
// If there are less than N files in the current directory, then return
// an error (FALSE), otherwise return TRUE. Hidden files are ignored.
// Pattern is used to limit the count to files names that match the pattern.
// Use FileType to determine which files to count.
//
//**************************************************************************
BOOL FindNthFile(char *pattern, char *sbFileName, int FileNum, int FileType) {
HANDLE fh;
WIN32_FIND_DATA FindFileData;
int fCount = 0;
BOOL rc; // Return code.
if ((fh = FindFirstFile((LPSTR)pattern,
(LPWIN32_FIND_DATA)&FindFileData)) == (HANDLE) -1) {
// Close in any case, may return an error (but, so what?)
(void)FindClose(fh);
return(FALSE);
}
while (FOREVER) {
if (((strcmp(FindFileData.cFileName, ".") != 0) &&
(strcmp(FindFileData.cFileName, "..") != 0)) &&
((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0)) {
switch (FileType) {
case DIRSONLY:
if (FindFileData.dwFileAttributes &
FILE_ATTRIBUTE_DIRECTORY) {
fCount++;
}
break;
case FILESONLY:
if (!(FindFileData.dwFileAttributes &
FILE_ATTRIBUTE_DIRECTORY)) {
fCount++;
}
break;
case FILESANDDIRS:
if (FileType == FILESANDDIRS) {
fCount++;
}
break;
default:
printf("FindNthFile: Bad FileType (%d).\n", FileType);
break;
}
}
if (fCount == FileNum) {
strncpy(sbFileName, FindFileData.cFileName, MAX_PATH);
rc = TRUE;
break;
}
if (!FindNextFile(fh, (LPWIN32_FIND_DATA)&FindFileData)) {
rc = FALSE;
break;
}
}
if (!FindClose(fh)) {
printf("PatternCountFiles: FindClose failed\n");
printf("PatternCountFiles: pattern=%s\n", pattern);
ExitProcess(1);
}
return(rc);
}
#else // -------------- USED FOR NON-NT BUILDS ----------------------
//**************************************************************************
//
// FindNthFile
// Find the Nth file name in the current directory (starting from 1).
// If there are less than N files in the current directory, then return
// an error (FALSE), otherwise return TRUE. Hidden files are ignored.
// Pattern is used to limit the count to files names that match the pattern.
// Use FileType to determine which files to count.
//
//**************************************************************************
BOOL FindNthFile(char *pattern, char *sbFileName, int FileNum, int FileType) {
USHORT rc; // Return code.
USHORT result;
HDIR fh; // Directory file handle
USHORT usAttribute;
FILEFINDBUF FindFileData;
USHORT usSearchCount;
int fCount = 0;
if (FileType == FILESONLY) {
usAttribute = FILE_NORMAL|FILE_READONLY|FILE_SYSTEM|FILE_ARCHIVED;
} else if (FileType == DIRSONLY) {
usAttribute = FILE_DIRECTORY|FILE_READONLY|FILE_SYSTEM|FILE_ARCHIVED;
} else if (FileType == FILESANDDIRS) {
usAttribute = FILE_NORMAL|FILE_DIRECTORY|FILE_READONLY|FILE_SYSTEM|
FILE_ARCHIVED;
} else {
printf("FindNthFile: Bad FileType %d\n", FileType);
ExitProcess(1);
}
fh = HDIR_CREATE;
usSearchCount = 1;
if ((rc = DosFindFirst((PSZ)pattern,
(PHDIR)&fh,
usAttribute,
(PFILEFINDBUF)&FindFileData,
(USHORT)sizeof(FindFileData),
(PUSHORT)&usSearchCount, 0L)) != 0) {
// Close in any case, may return an error (but, so what?)
(void)DosFindClose(fh);
return(fCount);
}
while (FOREVER) {
if (((strcmp(FindFileData.achName, ".") != 0) &&
(strcmp(FindFileData.achName, "..") != 0)) &&
((FindFileData.attrFile & FILE_HIDDEN) == 0)) {
switch (FileType) {
case DIRSONLY:
if (FindFileData.attrFile & FILE_DIRECTORY) {
fCount++;
}
break;
case FILESONLY:
if (!(FindFileData.attrFile & FILE_DIRECTORY)) {
fCount++;
}
break;
case FILESANDDIRS:
if (FileType == FILESANDDIRS) {
fCount++;
}
break;
default:
printf("PatternCountFiles: Bad FileType (%d).\n", FileType);
break;
}
}
if (fCount == FileNum) {
strncpy(sbFileName, FindFileData.achName, MAX_PATH);
result = TRUE;
break;
}
if (DosFindNext(fh, (PFILEFINDBUF)&FindFileData,
sizeof(FindFileData), &usSearchCount) != 0) {
result = FALSE;
break;
}
}
if ((rc = DosFindClose(fh)) != 0) {
printf("PatternCountFiles: FindClose failed (%d)\n", rc);
printf("PatternCountFiles: pattern=%s\n", pattern);
ExitProcess(1);
}
return(result);
}
#endif /* NT */
//**************************************************************************
//
// ExistsFile
// Checks for a file in the current directory.
// Returns TRUE is one is found, FALSE otherwise.
//
//**************************************************************************
BOOL ExistsFile(char *sbFile) {
FILE *fp;
if ((fp = fopen(sbFile, "r")) == NULL) {
return(FALSE);
}
if (fclose(fp) == EOF) {
printf("ExistsFile: fclose on %s failed.\n", sbFile);
ExitProcess(1);
}
return(TRUE);
}
//**************************************************************************
//
// MakeSlmINI
// Try to make the SLM ini file in the current directory.
// Returns TRUE if it succeeds, FALSE otherwise.
//
//**************************************************************************
BOOL MakeSlmINI(char *sbSlmRoot, char *sbProject) {
FILE *fp;
char *sbTemp;
char *sbRun;
// Hack alert.
sbTemp = sbMakeString("slmck -$ -f -i -u -v -s %s -p %%s", sbSlmRoot);
sbRun = sbMakeString(sbTemp, sbProject);
run(sbRun);
DisposeString(sbRun);
DisposeString(sbTemp);
// See if it exists.
if ((fp = fopen(SLMININAME, "r")) == NULL) {
return(FALSE);
}
if (fclose(fp) == EOF) {
printf("MakeSlmINI: fclose on %s failed.\n", SLMININAME);
ExitProcess(1);
}
return(TRUE);
}
#ifndef NT // ---------------- USED FOR NON-NT BUILDS ---------------
//**************************************************************************
//
// These routines were added to make compiling this program easier under
// plain OS/2. These routines should be functionally compatable with
// their namesakes on NT OS/2. See WIN32 API Spec.
//
//**************************************************************************
USHORT GetCurrentDirectory(USHORT BufferLen, PSZ Buffer) {
USHORT usDriveNumber;
USHORT rc;
usDriveNumber = 0;
Buffer[0] = '\\';
--BufferLen;
if ((rc = DosQCurDir(usDriveNumber, Buffer + 1,
(PUSHORT)&BufferLen)) != 0) {
return(0);
}
return(BufferLen);
}
//**************************************************************************
BOOL SetCurrentDirectory(PSZ PathName) {
USHORT rc;
if ((rc = DosChDir(PathName, 0L)) != 0) {
return(0);
} else {
return(1);
}
}
//**************************************************************************
USHORT GetEnvironmentVariable(PSZ Name, PBYTE Buffer, USHORT Size) {
USHORT rc;
USHORT len;
PSZ pszResult;
if ((rc = DosScanEnv(Name, (PSZ FAR *)&pszResult)) != 0) {
return(0);
}
len = strlen(pszResult);
strncpy(Buffer, pszResult, Size);
if (len < Size) {
return(len);
} else {
Buffer[Size] = '\0';
return(Size-1);
}
}
#endif /* NT */