//************************************************************************** // // 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 #include #include #include #include #ifdef NT #include #endif /* NT */ #ifndef NT #define INCL_BASE #define ExitProcess(x) exit(x) #define MAX_PATH _MAX_PATH #include 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 */