|
Version 1.4.1 contains nine test programs.
test/C
directory is a test program C.c that exercises the recls C API (for Win32)test/Cpp
directory is a test program Cpp.cpp that exercises the recls/C++ mapping (for Win32)test/CS
directory is a test program WinForm.cs that exercises the recls/C# mappingtest/COM
directory is a test program COM.cpp that exercises the recls/COM mapping (for C++)test/COM/VBClient
directory is a test program VBClient.frm that exercises the recls/COM mapping (for Visual Basic)test/D
directory are two test programs recls_test_1.d and recls_test_2.d that exercise the recls/D mappingtest/Java
directory is a test program recls_test.java that exercises the recls/Java mappingtest/Python
directory is a test program recls_test.py that exercises the recls/Python mappingtest/Ruby
directory is a test program recls_test.py that exercises the recls/Ruby mappingtest/STL
directory is a test program STL.cpp that exercises the recls/STL mapping (for Win32)This program uses the raw recls C API functions, implementing a recursive search for a given pattern, from a given directory
/* * File: C.c * * Purpose: Implementation file for the C project. * * Created: 15th August 2003 * Updated: 17th March 2005 * * Status: Wizard-generated * * License: (Licensed under the Synesis Software Open License) * * Copyright 2003-2004, Synesis Software Pty Ltd. * All rights reserved. * * www: http://www.synesis.com.au/software * * email: software@synesis.com.au * * This source code is placed into the public domain 2003 * by Synesis Software Pty Ltd. There are no restrictions * whatsoever to your use of the software. * * This source code is provided by Synesis Software Pty Ltd "as is" * and any warranties, whether expressed or implied, including, but * not limited to, the implied warranties of merchantability and * fitness for a particular purpose are disclaimed. In no event * shall the Synesis Software Pty Ltd be liable for any direct, * indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or * business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort * (including negligence or otherwise) arising in any way out of * the use of this software, even if advised of the possibility of * such damage. * * Neither the name of Synesis Software Pty Ltd nor the names of * any subdivisions, employees or agents of Synesis Software Pty * Ltd, nor the names of any other contributors to this software * may be used to endorse or promote products derived from this * software without specific prior written permission. * */ /* Remove this definition to use platform-specific aspects of the API */ /* #define RECLS_PURE_API */ /* Open-RJ Header Files */ #include <recls.h> #include <recls_alloca.h> #include <recls_assert.h> #include <recls_minmax.h> #if RECLS_VER < RECLS_VER_1_6_1 # error This file now requires version 1.6.1 or later of the recls C API #endif /* RECLS_VER < 1.6.1 */ /* Standard C Library Files */ #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef RECLS_PLATFORM_IS_UNIX # include <unistd.h> #endif /* RECLS_PLATFORM_IS_UNIX */ #ifdef _MSC_VER # include <crtdbg.h> #endif /* _MSC_VER */ /* * Compiler compatibility */ #if defined(RECLS_COMPILER_IS_MSVC) # if _MSC_VER < 1300 # pragma warning(disable : 4127) # endif /* _MSC_VER < 1300 */ #endif /* compiler */ /* * Macros */ #ifndef NUM_ELEMENTS # ifdef __DMC__ # define NUM_ELEMENTS(x) (sizeof(x) / sizeof((x)[0])) # else /* ? compiler */ # define NUM_ELEMENTS(x) (sizeof(x) / sizeof(0[(x)])) # endif /* compiler */ #endif /* !NUM_ELEMENTS */ /* * Constants and definitions */ static size_t path_max(void) { #if defined(WIN32) return 1 + _MAX_PATH; #elif defined(PATH_MAX) return 1 + PATH_MAX; #else /* ? PATH_MAX */ return 1 + 1 + pathconf("/", _PC_PATH_MAX); #endif /* PATH_MAX */ } #define alloca_path() ((recls_char_t*)recls_alloca(path_max())) /* * Forward declarations */ static void usage(int bExit, char const *reason); static int processDirectory(char const *rootDir, char const *pattern, long flags, int bSuccinct); /* * Main */ int main(int argc, char *argv[]) { #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemState memState; #endif /* _MSC_VER && _MSC_VER */ int iRet = 0; int i; int totalFound = 0; int bAllHardDrives = 0; char const *host = NULL; char const *username = NULL; char const *password = NULL; char const *pattern = NULL; char const *rootDir = NULL; recls_uint32_t flags = RECLS_F_RECURSIVE; int bSuccinct = 0; for(i = 1; i < argc; ++i) { const char *arg = argv[i]; if(arg[0] == '-') { if(arg[1] == '-') { /* -- arguments */ } else { /* - arguments */ switch(arg[1]) { case '?': usage(1, NULL); break; case 'R': /* Do not recurse */ flags &= ~(RECLS_F_RECURSIVE); break; case 'p': /* Show directory parts */ flags |= RECLS_F_DIRECTORY_PARTS; break; case 'f': /* Find files */ flags |= RECLS_F_FILES; break; case 'd': /* Find directories */ flags |= RECLS_F_DIRECTORIES; break; case 'h': /* Searches from hard drives */ bAllHardDrives = 1; break; case 's': /* Show only the full path; WHEREIS functionality */ bSuccinct = 1; break; case 'H': /* FTP host */ host = arg + 2; break; case 'U': /* FTP username */ username = arg + 2; break; case 'P': /* FTP password */ password = arg + 2; break; default: usage(1, "Invalid argument(s) specified"); break; } } } else { /* other arguments */ if(NULL == pattern) { pattern = arg; } else if(NULL == rootDir) { rootDir = arg; } else { usage(1, "Invalid argument(s) specified"); } } } if( NULL != password && ( NULL == host || NULL == username)) { usage(1, "Must specify host and username if specifying password"); } if( NULL != username && NULL == host) { usage(1, "Must specify host if specifying username"); } if( NULL != host && bAllHardDrives) { usage(1, "-h flag meaningless to FTP searches"); } if( NULL != host && NULL == rootDir) { usage(1, "Must specify a root directory for FTP searches"); } #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemCheckpoint(&memState); #endif /* _MSC_VER && _MSC_VER */ /* Search for files if neither files or directories specified/ * * Even though this is not necessary, because the recls API provides the * same interpretation, it's best to be explicit. */ if(0 == (flags & (RECLS_F_FILES | RECLS_F_DIRECTORIES))) { flags |= RECLS_F_FILES; } if(NULL == pattern) { pattern = Recls_GetWildcardsAll(); } if(NULL == rootDir) { rootDir = "."; } /* Check the size of rootDir */ #if 1 { recls_info_t entry; /* recls_rc_t rc2 = Recls_Stat(".", flags & ~(RECLS_F_TYPEMASK), &entry); */ recls_rc_t rc2 = Recls_Stat("\\", flags & ~(RECLS_F_TYPEMASK), &entry); if(RECLS_SUCCEEDED(rc2)) { Recls_CloseDetails(entry); } } #endif /* 0 */ #ifdef x_DEBUG { recls_bool_t bEmpty = Recls_IsDirectoryEmpty(rootDir); recls_filesize_t size = Recls_CalcDirectorySize(rootDir); ((void)bEmpty); ((void)size); } { recls_info_t info; hrecls_t hSrch; recls_rc_t rc = Recls_Search(".", ".", RECLS_F_DIRECTORIES, &hSrch); Recls_GetDetails(hSrch, &info); Recls_IsDirectoryEntryEmpty(info); Recls_CloseDetails(info); Recls_SearchClose(hSrch); } #endif /* _DEBUG */ /* Initiate the search. */ if(bAllHardDrives) { recls_root_t roots[26]; size_t cRoots = Recls_GetRoots(roots, NUM_ELEMENTS(roots)); for(i = 0; i < (int)cRoots; ++i) { totalFound += processDirectory(roots[i].name, pattern, flags, bSuccinct); } } else { totalFound = processDirectory(rootDir, pattern, flags, bSuccinct); } fprintf(stdout, "Total found: %d\n", totalFound); #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemDumpAllObjectsSince(&memState); #endif /* _MSC_VER && _MSC_VER */ return iRet; } /* * Function implementations */ void usage(int bExit, char const *reason) { fprintf(stderr, "recls C Test Program\n\n"); if(NULL != reason) { fprintf(stderr, " Error: %s\n\n", reason); } fprintf(stderr, "Usage: C++ [-d] [-f] [-h] [-p] [-R] [-s] [-H<host>] [-U<username>] [-P<password>] [<pattern>] [<root-dir>]\n"); fprintf(stderr, "\t-R - does not recurse; recursive search is the default\n"); fprintf(stderr, "\t-p - evaluate and display directory parts\n"); fprintf(stderr, "\t-d - search for directories\n"); fprintf(stderr, "\t-f - search for files (this is the default, if -d is not specified)\n"); fprintf(stderr, "\t-h - searches from hard drive roots. (Ignore <root-dir>.)\n"); fprintf(stderr, "\t-s - succinct; shows only the path\n"); fprintf(stderr, "\t-H<host> - performs an FTP search on the given host\n"); fprintf(stderr, "\t-U<username> - username to use to log on to <host>\n"); fprintf(stderr, "\t-P<password> - password to use to log on to <host>\n"); fprintf(stderr, "\t<pattern> - search pattern, e.g. \"*.cpp\" (default is to search for all files)\n"); fprintf(stderr, "\t<root-dir> - root directory of search; default is current working directory\n"); if(bExit) { exit(EXIT_FAILURE); } } static int processDirectory(char const *rootDir, char const *pattern, long flags, int bSuccinct) { hrecls_t hSrch; recls_rc_t rc = Recls_Search(rootDir, pattern, flags, &hSrch); int totalFound = 0; if(RECLS_FAILED(rc)) { recls_char_t err[100]; Recls_GetErrorString(rc, err, 100); fprintf(stderr, "Failed to start search, with pattern \"%s\"; recls error: %s\n", pattern, err); } else { /* Iterate through the items, until done */ recls_info_t info; rc = Recls_GetDetails(hSrch, &info); for(; RECLS_SUCCEEDED(rc); rc = Recls_GetNextDetails(hSrch, &info)) { int i; int off; int extLen; int cDirParts; recls_char_t *path = alloca_path(); #ifdef RECLS_PLATFORM_API_WIN32 recls_char_t drive = '\0'; #endif /* RECLS_PLATFORM_API_WIN32 */ recls_char_t *dir = alloca_path(); recls_char_t *dirPath = alloca_path(); recls_char_t *file = alloca_path(); recls_char_t *fileName = alloca_path(); recls_char_t *fileExt = alloca_path(); recls_char_t *pathCheck = alloca_path(); recls_char_t *dirCheck = alloca_path(); recls_char_t *fileCheck = alloca_path(); ++totalFound; pathCheck[0] = '\0'; dirCheck[0] = '\0'; fileCheck[0] = '\0'; #ifdef x_DEBUG { recls_uint32_t cBlocks; Recls_OutstandingDetails(hSrch, &cBlocks); printf("\n%d outstanding blocks\n", cBlocks); } #endif /* _DEBUG */ Recls_GetPathProperty(info, path, path_max()); printf(" %s\n", path); if(!bSuccinct) { Recls_GetDirectoryPathProperty(info, dirPath, path_max()); printf(" %s\n", dirPath); if(Recls_IsFileUNC(info)) { /* If the drive is '\0', then the path must be UNC. We access it * via the first part of the dirPath, using the dirPath length * and the dir length */ const size_t dirPathLen = Recls_GetDirectoryPathProperty(info, NULL, 0); const size_t dirLen = Recls_GetDirectoryProperty(info, NULL, 0); const size_t UNCLen = dirPathLen - dirLen; printf(" %.*s\n", UNCLen, dirPath); sprintf(pathCheck, "%.*s", UNCLen, dirPath); off = UNCLen; } else { #ifdef RECLS_PLATFORM_API_WIN32 Recls_GetDriveProperty(info, &drive); if(isupper(path[0])) { drive = (recls_char_t)toupper(drive); } else { drive = (recls_char_t)tolower(drive); } printf(" %c\n", drive); sprintf(pathCheck, "%c:", drive); off = 2; #elif defined(RECLS_PLATFORM_IS_WIN32) off = 2; #else /* platform */ off = 0; #endif /* RECLS_PLATFORM_API_WIN32 */ } Recls_GetDirectoryProperty(info, dir, path_max()); printf(" %*s\n", off + (int)strlen(dir), dir); if((flags & RECLS_F_DIRECTORY_PARTS) == RECLS_F_DIRECTORY_PARTS) { for(i = 0, cDirParts = Recls_GetDirectoryPartProperty(info, -1, NULL, 0); i < cDirParts; ++i) { recls_char_t *dirPart = alloca_path(); off += Recls_GetDirectoryPartProperty(info, i, dirPart, path_max()); printf(" %*s\n", off, dirPart); strcat(pathCheck, dirPart); strcat(dirCheck, dirPart); } } else { off += strlen(dir); strcat(pathCheck, dir); } off += Recls_GetFileProperty(info, file, path_max()); Recls_GetFileNameProperty(info, fileName, path_max()); extLen = Recls_GetFileExtProperty(info, fileExt, path_max()); printf(" %*s\n", off, file); printf(" %*s\n", off - (0 != extLen ? 1 + extLen : 0), fileName); printf(" %*s\n", off, fileExt); strcpy(fileCheck, fileName); if(0 < extLen) { strcat(fileCheck, "."); strcat(fileCheck, fileExt); } strcat(pathCheck, file); /* Now validate the components */ /* path === pathCheck */ #if defined(RECLS_PLATFORM_IS_WIN32) && \ !defined(RECLS_PLATFORM_API_WIN32) recls_assert(0 == strcmp(path + (Recls_IsFileUNC(info) ? 0 : 2), pathCheck)); if(0 != strcmp(path + (Recls_IsFileUNC(info) ? 0 : 2), pathCheck)) #else /* ? RECLS_PLATFORM_API_WIN32 */ recls_assert(0 == strcmp(path, pathCheck)); if(0 != strcmp(path, pathCheck)) #endif /* RECLS_PLATFORM_API_WIN32 || !RECLS_PLATFORM_IS_WIN32 */ { fprintf(stderr, "Path is different from path components\n\tpath: %s\n\tparts: %s\n\n", path, pathCheck); abort(); } /* dir === dirPath */ #if defined(RECLS_PLATFORM_API_WIN32) recls_assert(Recls_IsFileUNC(info) || (dirPath[0] == drive && 0 == strcmp(dir, dirPath + 2))); if( !Recls_IsFileUNC(info) && ( dirPath[0] != drive || 0 != strcmp(dir, dirPath + 2))) #elif defined(RECLS_PLATFORM_IS_WIN32) recls_assert(Recls_IsFileUNC(info) || 0 == strcmp(dir, dirPath + 2)); if( !Recls_IsFileUNC(info) && 0 != strcmp(dir, dirPath + 2)) #else recls_assert(0 == strcmp(dir, dirPath)); if(0 != strcmp(dir, dirPath)) #endif /* RECLS_PLATFORM_API_WIN32 || !RECLS_PLATFORM_IS_WIN32 */ { fprintf(stderr, "DirectoryPath is different from Directory\n\tdirPath: %s\n\tdir: %s\n\n", dirPath, dir); abort(); } if((flags & RECLS_F_DIRECTORY_PARTS) == RECLS_F_DIRECTORY_PARTS) { recls_assert(0 == strcmp(dir, dirCheck)); if(0 != strcmp(dir, dirCheck)) { fprintf(stderr, "Directory is different from directory components\n\tpath: %s\n\tparts: %s\n\n", dir, dirCheck); abort(); } } recls_assert(0 == strcmp(file, fileCheck)); if(0 != strcmp(file, fileCheck)) { fprintf(stderr, "File is different from file components\n\tpath: %s\n\tparts: %s\n\n", file, fileCheck); abort(); } if(Recls_IsFileReadOnly(info)) { printf(" - Read-only\n"); } if(Recls_IsFileDirectory(info)) { printf(" - Directory\n"); } else { printf(" - File\n"); } if(Recls_IsFileLink(info)) { printf(" - Link\n"); } if(Recls_IsFileUNC(info)) { printf(" - UNC\n"); } } Recls_CloseDetails(info); } if(rc != RECLS_RC_NO_MORE_DATA) { recls_char_t err[100]; Recls_GetErrorString(rc, err, 100); fprintf(stderr, "Search terminated prematurely; recls error: %s\n", err); } Recls_SearchClose(hSrch); } return totalFound; } /* * End of file */
This program uses the recls/C++ mapping classes, implementing a recursive search for a given pattern, from a given directory (Win32 platform)
/* * File: Cpp.cpp * * Purpose: Implementation file for the Cpp project. * * Created: 16th August 2003 * Updated: 15th March 2005 * * Status: Wizard-generated * * License: (Licensed under the Synesis Software Open License) * * Copyright 2003-2005, Synesis Software Pty Ltd. * All rights reserved. * * www: http://www.synesis.com.au/software * * email: software@synesis.com.au * * This source code is placed into the public domain 2003 * by Synesis Software Pty Ltd. There are no restrictions * whatsoever to your use of the software. * * This source code is provided by Synesis Software Pty Ltd "as is" * and any warranties, whether expressed or implied, including, but * not limited to, the implied warranties of merchantability and * fitness for a particular purpose are disclaimed. In no event * shall the Synesis Software Pty Ltd be liable for any direct, * indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or * business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort * (including negligence or otherwise) arising in any way out of * the use of this software, even if advised of the possibility of * such damage. * * Neither the name of Synesis Software Pty Ltd nor the names of * any subdivisions, employees or agents of Synesis Software Pty * Ltd, nor the names of any other contributors to this software * may be used to endorse or promote products derived from this * software without specific prior written permission. * */ /* Define this definition to retrict use to platform-independent aspects of the API */ //#define RECLS_PURE_API #include <stdio.h> #include <recls.h> #if RECLS_VER < RECLS_VER_1_6_1 # error This file now requires version 1.6.1 or later of the recls C API #endif /* RECLS_VER < 1.6.1 */ #if defined(RECLS_STRICT) && \ !defined(RECLS_COMPILER_IS_DMC) # include <stlsoft_nulldef.h> #endif /* RECLS_STRICT && !RECLS_COMPILER_IS_DMC */ #ifdef RECLS_COMPILER_IS_MSVC # include <crtdbg.h> # pragma warning(disable : 4530) #endif /* _MSC_VER */ #if RECLS_VER >= RECLS_VER_1_5_1 && \ defined(RECLS_PLATFORM_IS_WIN32) # define RECLS_TEST_CPP_USING_FTP #endif /* RECLS_VER >= RECLS_VER_1_5_1 && RECLS_PLATFORM_IS_WIN32 */ #include <recls_assert.h> #include <recls/cpp/filesearch.hpp> #if defined(RECLS_TEST_CPP_USING_FTP) # include <recls/cpp/ftpsearch.hpp> #endif /* RECLS_TEST_CPP_USING_FTP */ /* * Namespace */ using recls::recls_uint32_t; using recls::recls_char_t; using recls::RECLS_F_FILES; using recls::RECLS_F_DIRECTORIES; using recls::RECLS_F_RECURSIVE; using recls::RECLS_F_DIRECTORY_PARTS; /* * Forward declarations */ static void usage(int bExit, char const *reason); static int processSearch(reclspp::Search &search, int bSuccinct, recls_uint32_t flags); /* * Main */ int main(int argc, char *argv[]) { #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemState memState; #endif /* _MSC_VER && _MSC_VER */ int iRet = 0; int i; int totalFound; int bAllHardDrives = 0; char const *host = NULL; char const *username = NULL; char const *password = NULL; char const *pattern = NULL; char const *rootDir = NULL; recls_uint32_t flags = RECLS_F_RECURSIVE; int bSuccinct = false; for(i = 1; i < argc; ++i) { const char *arg = argv[i]; if(arg[0] == '-') { if(arg[1] == '-') { /* -- arguments */ } else { /* - arguments */ switch(arg[1]) { case '?': usage(1, NULL); break; case 'R': /* Do not recurse */ flags &= ~(RECLS_F_RECURSIVE); break; case 'p': /* Show directory parts */ flags |= RECLS_F_DIRECTORY_PARTS; break; case 'f': /* Find files */ flags |= RECLS_F_FILES; break; case 'd': /* Find directories */ flags |= RECLS_F_DIRECTORIES; break; case 'h': /* Searches from hard drives */ bAllHardDrives = true; break; case 's': /* Show only the full path; WHEREIS functionality */ bSuccinct = true; break; case 'H': /* FTP host */ host = arg + 2; break; case 'U': /* FTP username */ username = arg + 2; break; case 'P': /* FTP password */ password = arg + 2; break; default: usage(1, "Invalid argument(s) specified"); break; } } } else { /* other arguments */ if(NULL == pattern) { pattern = arg; } else if(NULL == rootDir) { rootDir = arg; } else { usage(1, "Invalid argument(s) specified"); } } } if( NULL != password && ( NULL == host || NULL == username)) { usage(1, "Must specify host and username if specifying password"); } if( NULL != username && NULL == host) { usage(1, "Must specify host if specifying username"); } if( NULL != host && bAllHardDrives) { usage(1, "-h flag meaningless to FTP searches"); } if( NULL != host && NULL == rootDir) { usage(1, "Must specify a root directory for FTP searches"); } #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemCheckpoint(&memState); #endif /* _MSC_VER && _MSC_VER */ // Search for files if neither files or directories specified // // Even though this is not necessary, because the recls API provides the // same interpretation, it's best to be explicit. if(0 == (flags & (RECLS_F_FILES | RECLS_F_DIRECTORIES))) { flags |= RECLS_F_FILES; } /* Now conduct the search */ #if defined(RECLS_TEST_CPP_USING_FTP) if(NULL != host) { if(NULL == pattern) { pattern = recls::Recls_GetWildcardsAll(); } if(NULL == rootDir) { rootDir = "/"; } reclspp::FtpSearch search(host, username, password, rootDir, pattern, flags); totalFound = processSearch(search, bSuccinct, flags); } else #endif /* RECLS_TEST_CPP_USING_FTP */ { if(NULL == pattern) { pattern = recls::Recls_GetWildcardsAll(); } if(NULL == rootDir) { rootDir = "."; } reclspp::FileSearch search(rootDir, pattern, flags); totalFound = processSearch(search, bSuccinct, flags); } fprintf(stdout, "Total found: %d\n", totalFound); #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemDumpAllObjectsSince(&memState); #endif /* _MSC_VER && _MSC_VER */ return iRet; } /* * Function implementations */ static void usage(int bExit, char const *reason) { fprintf(stderr, "recls C++ Test Program\n\n"); if(NULL != reason) { fprintf(stderr, " Error: %s\n\n", reason); } fprintf(stderr, "Usage: Cpp [-d] [-f] [-h] [-p] [-R] [-s] [-H<host>] [-U<username>] [-P<password>] [<pattern>] [<root-dir>]\n"); fprintf(stderr, "\t-R - does not recurse; recursive search is the default\n"); fprintf(stderr, "\t-p - evaluate and display directory parts\n"); fprintf(stderr, "\t-d - search for directories\n"); fprintf(stderr, "\t-f - search for files (this is the default, if -d is not specified)\n"); fprintf(stderr, "\t-h - searches from hard drive roots. (Ignore <root-dir>.)\n"); fprintf(stderr, "\t-s - succinct; shows only the path\n"); fprintf(stderr, "\t-H<host> - performs an FTP search on the given host\n"); fprintf(stderr, "\t-U<username> - username to use to log on to <host>\n"); fprintf(stderr, "\t-P<password> - password to use to log on to <host>\n"); fprintf(stderr, "\t<pattern> - search pattern, e.g. \"*.cpp\"; default is to search for all files\n"); fprintf(stderr, "\t<root-dir> - root directory of search; default is current working directory\n"); if(bExit) { exit(EXIT_FAILURE); } } /* * Function implementations */ static int processSearch(reclspp::Search &search, int bSuccinct, recls_uint32_t flags) { int totalFound = 0; for(; search.HasMoreElements(); search.GetNext()) { using reclspp::string_t; ++totalFound; reclspp::FileEntry fileEntry = search.GetCurrentEntry(); #ifdef RECLS_PLATFORM_API_WIN32 recls_char_t drive = fileEntry.GetDrive(); #endif /* RECLS_PLATFORM_API_WIN32 */ string_t uncDrive = fileEntry.GetUNCDrive(); string_t path = fileEntry.GetPath(); string_t dir = fileEntry.GetDirectory(); string_t dirPath = fileEntry.GetDirectoryPath(); reclspp::DirectoryParts dirParts = fileEntry.GetDirectoryParts(); string_t file = fileEntry.GetFile(); string_t fileName = fileEntry.GetFileName(); string_t fileExt = fileEntry.GetFileExt(); string_t pathCheck; string_t dirPartsCheck; string_t fileCheck; #ifdef x_DEBUG reclspp::FileEntry entry2; if( fileEntry && !entry2) { fprintf(stderr, "Good entry\n"); } if(!fileEntry) { fprintf(stderr, "Bad entry\n"); } #endif /* _DEBUG */ #ifdef _DEBUG { recls_uint32_t cBlocks = search.GetNumOutstandingDetails(); printf("\n%lu outstanding block(s)\n", cBlocks); } #endif /* _DEBUG */ printf(" %s\n", path.c_str()); if(!bSuccinct) { int off = 0; printf(" %s\n", dirPath.c_str()); if(fileEntry.IsUNC()) { printf(" %s\n", uncDrive.c_str()); pathCheck += uncDrive; off += uncDrive.length(); } else { #ifdef RECLS_PLATFORM_API_WIN32 if(isupper(path[0])) { drive = (recls_char_t)toupper(drive); } else { drive = (recls_char_t)tolower(drive); } printf(" %c\n", drive); pathCheck += drive; pathCheck += ':'; off += 2; #elif defined(RECLS_PLATFORM_IS_WIN32) off += 2; #else /* platform */ off += 0; #endif /* RECLS_PLATFORM_API_WIN32 */ } printf(" %*s\n", off + dir.length(), dir.c_str()); if((flags & RECLS_F_DIRECTORY_PARTS) == RECLS_F_DIRECTORY_PARTS) { int i; int cDirParts; for(i = 0, cDirParts = dirParts.size(); i < cDirParts; ++i) { string_t dirPart = dirParts[i]; off += dirPart.length(); printf(" %*s\n", off, dirPart.c_str()); #ifndef RECLS_PURE_API pathCheck += dirPart; #endif /* !RECLS_PURE_API */ dirPartsCheck += dirPart; } #ifdef RECLS_PURE_API pathCheck += dirPath; #endif /* RECLS_PURE_API */ } else { off += dir.length(); pathCheck += dir; } off += file.length(); printf(" %*s\n", off, file.c_str()); if(fileExt.length() > 0) { printf(" %*s\n", off - (1 + fileExt.length()), fileName.c_str()); printf(" %*s\n", off, fileExt.c_str()); } else { printf(" %*s\n", off, fileName.c_str()); } fileCheck = fileName; if(0 < fileExt.length()) { fileCheck += '.'; fileCheck += fileExt; } pathCheck += file; // Now validate the components recls_assert(path == pathCheck); if(path != pathCheck) { fprintf(stderr, "Path is different from path components\n\tpath: %s\n\tparts: %s\n\n", path.c_str(), pathCheck.c_str()); abort(); } #ifdef RECLS_PLATFORM_API_WIN32 recls_assert(0 == drive || (dirPath[0] == drive && dir == dirPath.c_str() + 2)); recls_assert(fileEntry.IsUNC() || 0 != drive || dir == dirPath); if( ( 0 != drive && ( dirPath[0] != drive || dir != dirPath.c_str() + 2)) || ( 0 == drive && dir != dirPath)) #else recls_assert(fileEntry.IsUNC() || dirPath == dir); if( !fileEntry.IsUNC() && dirPath != dir) #endif /* RECLS_PLATFORM_API_WIN32 */ { fprintf(stderr, "DirectoryPath is different from Directory\n\tdirPath: %s\n\tdir: %s\n\n", dirPath.c_str(), dir.c_str()); abort(); } if((flags & RECLS_F_DIRECTORY_PARTS) == RECLS_F_DIRECTORY_PARTS) { recls_assert(dir == dirPartsCheck); if(dir != dirPartsCheck) { fprintf(stderr, "Directory is different from directory components\n\tpath: %s\n\tparts: %s\n\n", dir.c_str(), dirPartsCheck.c_str()); abort(); } } recls_assert(file == fileCheck); if(file != fileCheck) { fprintf(stderr, "File is different from file components\n\tpath: %s\n\tparts: %s\n\n", file.c_str(), fileCheck.c_str()); abort(); } if(fileEntry.IsReadOnly()) { printf(" - Read-only\n"); } if(fileEntry.IsDirectory()) { printf(" - Directory\n"); } else { printf(" - File\n"); } if(fileEntry.IsLink()) { printf(" - Link\n"); } if(fileEntry.IsUNC()) { printf(" - UNC\n"); } } } return totalFound; } /* * End of file */
This program uses the recls/C# mapping classes, implementing a recursive search for a given pattern, and other flags, from a given directory
namespace CS { using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using recls; public class WinForm : System.Windows.Forms.Form { private System.ComponentModel.Container components = null; private System.Windows.Forms.Label label1; private System.Windows.Forms.TextBox searchRoot; private System.Windows.Forms.Label label2; private System.Windows.Forms.TextBox pattern; private System.Windows.Forms.Button btnSearch; private System.Windows.Forms.ListView listFiles; private System.Windows.Forms.ListView listProperties; private System.Windows.Forms.Label label4; private System.Windows.Forms.ListBox listDirectoryParts; private System.Windows.Forms.CheckBox chkRecursive; private System.Windows.Forms.CheckBox chkDirectoryParts; private System.Windows.Forms.Label lblDirectoryParts; private System.Windows.Forms.ProgressBar progbar; private System.Windows.Forms.RadioButton rbtnFiles; private System.Windows.Forms.RadioButton rbtnDirectories; private System.Windows.Forms.RadioButton rbtnBoth; private System.Windows.Forms.Label label5; private System.Windows.Forms.Label label6; private System.Windows.Forms.Label label7; private System.Windows.Forms.TextBox host; private System.Windows.Forms.TextBox username; private System.Windows.Forms.TextBox password; private System.Windows.Forms.Label label3; public WinForm() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // } protected override void Dispose (bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); } #region Windows Form Designer generated code private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); this.searchRoot = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label(); this.pattern = new System.Windows.Forms.TextBox(); this.btnSearch = new System.Windows.Forms.Button(); this.label3 = new System.Windows.Forms.Label(); this.listFiles = new System.Windows.Forms.ListView(); this.listProperties = new System.Windows.Forms.ListView(); this.label4 = new System.Windows.Forms.Label(); this.lblDirectoryParts = new System.Windows.Forms.Label(); this.listDirectoryParts = new System.Windows.Forms.ListBox(); this.chkRecursive = new System.Windows.Forms.CheckBox(); this.chkDirectoryParts = new System.Windows.Forms.CheckBox(); this.progbar = new System.Windows.Forms.ProgressBar(); this.rbtnFiles = new System.Windows.Forms.RadioButton(); this.rbtnDirectories = new System.Windows.Forms.RadioButton(); this.rbtnBoth = new System.Windows.Forms.RadioButton(); this.label5 = new System.Windows.Forms.Label(); this.host = new System.Windows.Forms.TextBox(); this.label6 = new System.Windows.Forms.Label(); this.username = new System.Windows.Forms.TextBox(); this.label7 = new System.Windows.Forms.Label(); this.password = new System.Windows.Forms.TextBox(); this.SuspendLayout(); // // label1 // this.label1.Location = new System.Drawing.Point(8, 48); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(100, 16); this.label1.TabIndex = 6; this.label1.Text = "Search &root:"; // // searchRoot // this.searchRoot.Location = new System.Drawing.Point(112, 48); this.searchRoot.Name = "searchRoot"; this.searchRoot.Size = new System.Drawing.Size(632, 20); this.searchRoot.TabIndex = 7; this.searchRoot.Text = ""; // // label2 // this.label2.Location = new System.Drawing.Point(8, 88); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(100, 16); this.label2.TabIndex = 8; this.label2.Text = "&Pattern:"; // // pattern // this.pattern.Location = new System.Drawing.Point(112, 80); this.pattern.Name = "pattern"; this.pattern.TabIndex = 9; this.pattern.Text = "*.*"; // // btnSearch // this.btnSearch.Location = new System.Drawing.Point(664, 80); this.btnSearch.Name = "btnSearch"; this.btnSearch.Size = new System.Drawing.Size(80, 23); this.btnSearch.TabIndex = 15; this.btnSearch.Text = "&Search"; this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click); // // label3 // this.label3.Location = new System.Drawing.Point(8, 120); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(100, 16); this.label3.TabIndex = 16; this.label3.Text = "F&iles:"; // // listFiles // this.listFiles.Location = new System.Drawing.Point(8, 136); this.listFiles.MultiSelect = false; this.listFiles.Name = "listFiles"; this.listFiles.Size = new System.Drawing.Size(384, 368); this.listFiles.TabIndex = 17; this.listFiles.View = System.Windows.Forms.View.Details; this.listFiles.SelectedIndexChanged += new System.EventHandler(this.listFiles_SelectedIndexChanged); // // listProperties // this.listProperties.Location = new System.Drawing.Point(400, 136); this.listProperties.Name = "listProperties"; this.listProperties.Size = new System.Drawing.Size(344, 224); this.listProperties.TabIndex = 19; this.listProperties.View = System.Windows.Forms.View.Details; // // label4 // this.label4.Location = new System.Drawing.Point(408, 120); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(100, 16); this.label4.TabIndex = 18; this.label4.Text = "Pr&operties"; // // lblDirectoryParts // this.lblDirectoryParts.Location = new System.Drawing.Point(400, 368); this.lblDirectoryParts.Name = "lblDirectoryParts"; this.lblDirectoryParts.Size = new System.Drawing.Size(120, 16); this.lblDirectoryParts.TabIndex = 20; this.lblDirectoryParts.Text = "Directory par&ts:"; // // listDirectoryParts // this.listDirectoryParts.Location = new System.Drawing.Point(400, 384); this.listDirectoryParts.Name = "listDirectoryParts"; this.listDirectoryParts.Size = new System.Drawing.Size(344, 121); this.listDirectoryParts.TabIndex = 21; // // chkRecursive // this.chkRecursive.Checked = true; this.chkRecursive.CheckState = System.Windows.Forms.CheckState.Checked; this.chkRecursive.Location = new System.Drawing.Point(224, 88); this.chkRecursive.Name = "chkRecursive"; this.chkRecursive.Size = new System.Drawing.Size(96, 16); this.chkRecursive.TabIndex = 10; this.chkRecursive.Text = "Recursi&ve"; // // chkDirectoryParts // this.chkDirectoryParts.Checked = true; this.chkDirectoryParts.CheckState = System.Windows.Forms.CheckState.Checked; this.chkDirectoryParts.Location = new System.Drawing.Point(328, 88); this.chkDirectoryParts.Name = "chkDirectoryParts"; this.chkDirectoryParts.Size = new System.Drawing.Size(104, 16); this.chkDirectoryParts.TabIndex = 11; this.chkDirectoryParts.Text = "Directory P&arts"; // // progbar // this.progbar.Location = new System.Drawing.Point(8, 512); this.progbar.Name = "progbar"; this.progbar.Size = new System.Drawing.Size(736, 16); this.progbar.TabIndex = 11; // // rbtnFiles // this.rbtnFiles.Appearance = System.Windows.Forms.Appearance.Button; this.rbtnFiles.Checked = true; this.rbtnFiles.Location = new System.Drawing.Point(440, 80); this.rbtnFiles.Name = "rbtnFiles"; this.rbtnFiles.Size = new System.Drawing.Size(48, 24); this.rbtnFiles.TabIndex = 12; this.rbtnFiles.TabStop = true; this.rbtnFiles.Text = "&Files"; // // rbtnDirectories // this.rbtnDirectories.Appearance = System.Windows.Forms.Appearance.Button; this.rbtnDirectories.Location = new System.Drawing.Point(496, 80); this.rbtnDirectories.Name = "rbtnDirectories"; this.rbtnDirectories.Size = new System.Drawing.Size(72, 24); this.rbtnDirectories.TabIndex = 13; this.rbtnDirectories.Text = "&Directories"; // // rbtnBoth // this.rbtnBoth.Appearance = System.Windows.Forms.Appearance.Button; this.rbtnBoth.Location = new System.Drawing.Point(576, 80); this.rbtnBoth.Name = "rbtnBoth"; this.rbtnBoth.Size = new System.Drawing.Size(48, 24); this.rbtnBoth.TabIndex = 14; this.rbtnBoth.Text = "&Both"; // // label5 // this.label5.Location = new System.Drawing.Point(8, 16); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(96, 23); this.label5.TabIndex = 0; this.label5.Text = "&Host:"; // // host // this.host.Location = new System.Drawing.Point(112, 16); this.host.Name = "host"; this.host.Size = new System.Drawing.Size(128, 20); this.host.TabIndex = 1; this.host.Text = ""; // // label6 // this.label6.Location = new System.Drawing.Point(248, 16); this.label6.Name = "label6"; this.label6.TabIndex = 2; this.label6.Text = "&Username:"; // // username // this.username.Location = new System.Drawing.Point(360, 16); this.username.Name = "username"; this.username.Size = new System.Drawing.Size(144, 20); this.username.TabIndex = 3; this.username.Text = ""; // // label7 // this.label7.Location = new System.Drawing.Point(512, 16); this.label7.Name = "label7"; this.label7.Size = new System.Drawing.Size(80, 23); this.label7.TabIndex = 4; this.label7.Text = "&Password:"; // // password // this.password.Location = new System.Drawing.Point(600, 16); this.password.Name = "password"; this.password.PasswordChar = '*'; this.password.Size = new System.Drawing.Size(144, 20); this.password.TabIndex = 5; this.password.Text = ""; // // WinForm // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(752, 531); this.Controls.AddRange(new System.Windows.Forms.Control[] { this.password, this.label7, this.username, this.label6, this.host, this.label5, this.rbtnFiles, this.progbar, this.chkDirectoryParts, this.chkRecursive, this.listDirectoryParts, this.lblDirectoryParts, this.label4, this.listProperties, this.listFiles, this.label3, this.btnSearch, this.pattern, this.label2, this.searchRoot, this.label1, this.rbtnDirectories, this.rbtnBoth}); this.Name = "WinForm"; this.Text = "recls C# mapping test"; this.Load += new System.EventHandler(this.WinForm_Load); this.ResumeLayout(false); } #endregion [STAThread] static void Main() { Application.Run(new WinForm()); } private void btnSearch_Click(object sender, System.EventArgs e) { progbar.Maximum = 1000; RECLS_FLAG flags = 0; if(rbtnBoth.Checked) { flags |= RECLS_FLAG.RECLS_F_DIRECTORIES | RECLS_FLAG.RECLS_F_FILES; } else if(rbtnFiles.Checked) { flags |= RECLS_FLAG.RECLS_F_FILES; } else if(rbtnDirectories.Checked) { flags |= RECLS_FLAG.RECLS_F_DIRECTORIES; } if(chkRecursive.Checked) { flags |= RECLS_FLAG.RECLS_F_RECURSIVE; } if(chkDirectoryParts.Checked) { flags |= RECLS_FLAG.RECLS_F_DIRECTORY_PARTS; } listDirectoryParts.Enabled = chkDirectoryParts.Checked; lblDirectoryParts.Enabled = chkDirectoryParts.Checked; Search fs; if(host.Text.Length > 0) { fs = new FtpSearch(host.Text, username.Text, password.Text, searchRoot.Text, pattern.Text, flags); } else { fs = new FileSearch(searchRoot.Text, pattern.Text, flags); } listFiles.Items.Clear(); listProperties.Items.Clear(); listDirectoryParts.Items.Clear(); foreach(FileEntry fe in fs) { ListViewItem lvi = new ListViewItem(fe.Path); lvi.Tag = fe; listFiles.Items.Add(lvi); if(1 + progbar.Value == progbar.Maximum) { progbar.Value = 0; } else { progbar.Value = 1 + progbar.Value; } progbar.Update(); listFiles.Update(); } progbar.Value = 0; } private void WinForm_Load(object sender, System.EventArgs e) { int cx; cx = listFiles.Width - 4; listFiles.Columns.Add("Filename", cx, HorizontalAlignment.Left); cx = listProperties.Width - 4; listProperties.Columns.Add("Property", cx * 2 / 5, HorizontalAlignment.Left); listProperties.Columns.Add("Value", cx * 3 / 5, HorizontalAlignment.Left); } private void listFiles_SelectedIndexChanged(object sender, System.EventArgs e) { ListView.SelectedListViewItemCollection items = listFiles.SelectedItems; if(items.Count == 1) { PopulateProperties((FileEntry)items[0].Tag); } } private string TranslateEntryAttributes(FileEntry fe) { string s = ""; if(fe.IsDirectory) { if(s.Length > 0) { s += " "; } s += "[Directory]"; } if(fe.IsLink) { if(s.Length > 0) { s += " "; } s += "[Link]"; } if(fe.IsReadOnly) { if(s.Length > 0) { s += " "; } s += "[Read only]"; } return s; } private void PopulateProperties(FileEntry entry) { listProperties.Items.Clear(); listDirectoryParts.Items.Clear(); listProperties.Items.Add("Path").SubItems.Add(entry.Path); listProperties.Items.Add("Drive").SubItems.Add(entry.Drive.ToString()); listProperties.Items.Add("Directory").SubItems.Add(entry.Directory); listProperties.Items.Add("DirectoryPath").SubItems.Add(entry.DirectoryPath); listProperties.Items.Add("File").SubItems.Add(entry.File); listProperties.Items.Add("ShortFile").SubItems.Add(entry.ShortFile); listProperties.Items.Add("FileName").SubItems.Add(entry.FileName); listProperties.Items.Add("FileExt").SubItems.Add(entry.FileExt); listProperties.Items.Add("CreationTime").SubItems.Add(entry.CreationTime.ToString()); listProperties.Items.Add("ModificationTime").SubItems.Add(entry.ModificationTime.ToString()); listProperties.Items.Add("LastAccessTime").SubItems.Add(entry.LastAccessTime.ToString()); listProperties.Items.Add("LastStatusChangeTime").SubItems.Add(entry.LastStatusChangeTime.ToString()); listProperties.Items.Add("Attributes").SubItems.Add(TranslateEntryAttributes(entry)); foreach(string part in entry.DirectoryParts) { listDirectoryParts.Items.Add(part); } } } }
This program uses the recls/COM mapping coclasses, implementing a recursive search for a given pattern, and other flags, from a given directory
/* * File: COM.cpp * * Purpose: Implementation file for the COM project. * * Created: 19th December 2003 * Updated: 15th March 2005 * * Status: Wizard-generated * * License: (Licensed under the Synesis Software Open License) * * Copyright 2003-2005, Synesis Software Pty Ltd. * All rights reserved. * * www: http://www.synesis.com.au/software * * email: software@synesis.com.au * * This source code is placed into the public domain 2003 * by Synesis Software Pty Ltd. There are no restrictions * whatsoever to your use of the software. * * This source code is provided by Synesis Software Pty Ltd "as is" * and any warranties, whether expressed or implied, including, but * not limited to, the implied warranties of merchantability and * fitness for a particular purpose are disclaimed. In no event * shall the Synesis Software Pty Ltd be liable for any direct, * indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or * business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort * (including negligence or otherwise) arising in any way out of * the use of this software, even if advised of the possibility of * such damage. * * Neither the name of Synesis Software Pty Ltd nor the names of * any subdivisions, employees or agents of Synesis Software Pty * Ltd, nor the names of any other contributors to this software * may be used to endorse or promote products derived from this * software without specific prior written permission. * * #include <windows.h> #include <stdio.h> #if defined(__DMC__) # include <iostream.h> #else /* ? __DMC__ */ # include <iostream> # include <iomanip> using std::cout; using std::wcout; using std::cerr; using std::endl; #endif /* __DMC__ */ #include <stdlib.h> #include <stlsoft.h> #include <atlstl.h> #include <comstl.h> #include <comstl_enumerator_policies.h> #include <comstl_initialisers.h> #include <comstl_interface_cast.h> #include <comstl_value_policies.h> #include <comstl_enum_sequence.h> #include <comstl_coll_sequence.h> // This version of recls has been released at the same time as STLSoft 1.7.1 beta 3, in which // comstl_method_cast.h resides in the "inprogress" sub-directory. #include <inprogress/comstl_method_cast.h> // // Once STLSoft 1.7.1 is released, this file will reside in the main directory, so you should // comment out the include above, and uncomment the one below //#include <comstl_method_cast.h> #include <winstl.h> #include <winstl_char_conversions.h> #include <recls_com.h> #include <recls_com_i.c> #ifdef _MSC_VER # include <CrtDbg.h> #endif /* _MSC_VER */ //#define USE_ENUMVARIANT #define USE_ENUMENTRY /* * Helper functions */ template<typename S> S &operator <<(S &s, CComBSTR const &bstr) { wchar_t const *str = bstr; return s << str; } namespace comstl { inline CComBSTR &transfer_resource(CComBSTR &r, BSTR v) { comstl_message_assert("Resource destination not empty!", NULL == r.m_str); r.m_str = v; return r; } } /* * Forward declarations */ static void usage(int bExit, char const *reason); int processRoot(IFileSearch *search, CComBSTR const &rootDir, CComBSTR const &pattern, long flags, int bSuccinct, int bFTP); int processRoot(IFtpSearch *search, CComBSTR const &host, CComBSTR const &username, CComBSTR const &password, CComBSTR const &rootDir, CComBSTR const &pattern, long flags, int bSuccinct, int bFTP); int processCollection(ISearchCollection *psc, long flags, int bSuccinct, int bFTP); /* * Main */ int main(int argc, char *argv[]) { #if 0 ::Sleep(100000); #endif /* 0 */ #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemState memState; #endif /* _MSC_VER && _MSC_VER */ int iRet = 0; int i; int totalFound = 0; int bAllHardDrives = false; char const *host = NULL; char const *username = NULL; char const *password = NULL; char const *pattern = NULL; char const *rootDir = NULL; long flags = RECLS_F_RECURSIVE; int bSuccinct = false; for(i = 1; i < argc; ++i) { const char *arg = argv[i]; if(arg[0] == '-') { if(arg[1] == '-') { /* -- arguments */ } else { /* - arguments */ switch(arg[1]) { case '?': usage(1, NULL); break; case 'R': /* Do not recurse */ flags &= ~(RECLS_F_RECURSIVE); break; case 'p': /* Show directory parts */ flags |= RECLS_F_DIRECTORY_PARTS; break; case 'f': /* Find files */ flags |= RECLS_F_FILES; break; case 'd': /* Find directories */ flags |= RECLS_F_DIRECTORIES; break; case 'h': /* Searches from hard drives */ bAllHardDrives = true; break; case 's': /* Show only the full path; WHEREIS functionality */ bSuccinct = true; break; case 'H': /* FTP host */ host = arg + 2; break; case 'U': /* FTP username */ username = arg + 2; break; case 'P': /* FTP password */ password = arg + 2; break; default: usage(1, "Invalid argument(s) specified"); break; } } } else { /* other arguments */ if(NULL == pattern) { pattern = arg; } else if(NULL == rootDir) { rootDir = arg; } else { usage(1, "Invalid argument(s) specified"); } } } if( NULL != password && ( NULL == host || NULL == username)) { usage(1, "Must specify host and username if specifying password"); } if( NULL != username && NULL == host) { usage(1, "Must specify host if specifying username"); } if( NULL != host && bAllHardDrives) { usage(1, "-h flag meaningless to FTP searches"); } if( NULL != host && NULL == rootDir) { usage(1, "Must specify a root directory for FTP searches"); } #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemCheckpoint(&memState); #endif /* _MSC_VER && _MSC_VER */ // Search for files if neither files or directories specified // // Even though this is not necessary, because the recls API provides the // same interpretation, it's best to be explicit. if(0 == (flags & (RECLS_F_FILES | RECLS_F_DIRECTORIES))) { flags |= RECLS_F_FILES; } #if 0 if(NULL == pattern) { pattern = Recls_GetWildcardsAll(); } #endif /* 0 */ if(NULL == rootDir) { rootDir = "."; } if(NULL != host) { IFtpSearch *search; comstl::com_initialiser init; HRESULT hr = ::CoCreateInstance(CLSID_FileSearch, NULL, CLSCTX_ALL, IID_IFtpSearch, (void**)&search); if(FAILED(hr)) { cerr << "Failed to load the recls COM server! Please check your installation" << endl; } else { // CComBSTR bstrPattern = comstl::method_cast<CComBSTR>(search, &IFileSearch::get_WildcardsAll); // The ATL conversion is not to be trusted for early versions, so we do it here. winstl::a2w host_(host); winstl::a2w username_(username); winstl::a2w password_(password); winstl::a2w rootDir_(rootDir); winstl::a2w pattern_(pattern); CComBSTR bstrHost(stlsoft::c_str_ptr(host)); CComBSTR bstrUsername(stlsoft::c_str_ptr(username)); CComBSTR bstrPassword(stlsoft::c_str_ptr(password)); CComBSTR bstrRootDir(stlsoft::c_str_ptr(rootDir)); CComBSTR bstrPattern(stlsoft::c_str_ptr(pattern)); if(0 == stlsoft::c_str_len(bstrPattern)) { bstrPattern = L"*"; } totalFound = processRoot(search, bstrHost, bstrUsername, bstrPassword, bstrRootDir, bstrPattern, flags, bSuccinct, true); search->Release(); } } else { IFileSearch *search; comstl::com_initialiser init; HRESULT hr = ::CoCreateInstance(CLSID_FileSearch, NULL, CLSCTX_ALL, IID_IFileSearch, (void**)&search); if(FAILED(hr)) { cerr << "Failed to load the recls COM server! Please check your installation" << endl; } else { winstl::a2w pattern_(pattern); CComBSTR bstrPattern(stlsoft::c_str_ptr(pattern)); if(0 == stlsoft::c_str_len(bstrPattern)) { bstrPattern = comstl::method_cast<CComBSTR>(search, &IFileSearch::get_WildcardsAll);; } if(bAllHardDrives) { LPUNKNOWN punkRoots; hr = search->get_Roots(&punkRoots); if(SUCCEEDED(hr)) { typedef comstl::enumerator_sequence<IEnumString, LPOLESTR, comstl::LPOLESTR_policy> enum_sequence_t; enum_sequence_t roots(comstl::interface_cast_addref<LPENUMSTRING>(punkRoots), false); enum_sequence_t::iterator begin = roots.begin(); enum_sequence_t::iterator end = roots.end(); for(; begin != end; ++begin) { totalFound += processRoot(search, *begin, bstrPattern, flags, bSuccinct, false); } punkRoots->Release(); } } else { winstl::a2w rootDir_(rootDir); CComBSTR bstrRootDir(stlsoft::c_str_ptr(rootDir)); totalFound = processRoot(search, bstrRootDir, bstrPattern, flags, bSuccinct, false); } search->Release(); } } fprintf(stdout, "Total found: %d\n", totalFound); #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemDumpAllObjectsSince(&memState); #endif /* _MSC_VER && _MSC_VER */ return iRet; } /* * Function implementations */ void usage(int bExit, char const *reason) { cerr << "recls COM (C++) Test Program: COM" << endl << endl; if(NULL != reason) { cerr << " Error: " << reason << endl << endl; } cerr << "Usage: COM [-d] [-f] [-h] [-p] [-R] [-s] [-H<host>] [-U<username>] [-P<password>] [<pattern>] [<root-dir>]" << endl; cerr << "\t-R - does not recurse; recursive search is the default" << endl; cerr << "\t-p - evaluate and display directory parts" << endl; cerr << "\t-d - search for directories" << endl; cerr << "\t-f - search for files (this is the default, if -d is not specified" << endl; cerr << "\t-h - searches from hard drive roots. (Ignore <root-dir>.)" << endl; cerr << "\t-s - succinct; shows only the path" << endl; cerr << "\t-H<host> - performs an FTP search on the given host" << endl; cerr << "\t-U<username> - username to use to log on to <host>" << endl; cerr << "\t-P<password> - password to use to log on to <host>" << endl; cerr << "\t<pattern> - search pattern, e.g. \"*.cpp\"; default is to search for all files" << endl; cerr << "\t<root-dir> - root directory of search; default is current working directory" << endl; if(bExit) { exit(EXIT_FAILURE); } } int processRoot(IFtpSearch *search, CComBSTR const &host, CComBSTR const &username, CComBSTR const &password, CComBSTR const &rootDir, CComBSTR const &pattern, long flags, int bSuccinct, int bFTP) { int totalFound = 0; IUnknown *punkResults; HRESULT hr = search->Search(host, username, password, rootDir, pattern, flags, &punkResults); if(SUCCEEDED(hr)) { ISearchCollection *psc = comstl::interface_cast_addref<ISearchCollection*>(punkResults); if(NULL != psc) { totalFound = processCollection(psc, flags, bSuccinct, bFTP); psc->Release(); } punkResults->Release(); } return totalFound; } int processRoot(IFileSearch *search, CComBSTR const &rootDir, CComBSTR const &pattern, long flags, int bSuccinct, int bFTP) { int totalFound = 0; IUnknown *punkResults; HRESULT hr = search->Search(rootDir, pattern, flags, &punkResults); if(SUCCEEDED(hr)) { ISearchCollection *psc = comstl::interface_cast_addref<ISearchCollection*>(punkResults); if(NULL != psc) { totalFound = processCollection(psc, flags, bSuccinct, bFTP); psc->Release(); } punkResults->Release(); } return totalFound; } int processCollection(ISearchCollection *psc, long flags, int bSuccinct, int bFTP) { int totalFound = 0; #if defined(USE_ENUMVARIANT) typedef comstl::collection_sequence< ISearchCollection , IEnumVARIANT , VARIANT , comstl::VARIANT_policy > coll_seq_t; #elif defined(USE_ENUMENTRY) typedef comstl::collection_sequence< ISearchCollection , IEnumFileEntry , IFileEntry* , comstl::interface_policy<IFileEntry> > coll_seq_t; #else # error Must specify USE_ENUMVARIANT or USE_ENUMENTRY #endif /* 0 */ coll_seq_t collection(psc, true, bFTP ? 1 : 0); coll_seq_t::iterator b = collection.begin(); coll_seq_t::iterator e = collection.end(); for(; b != e; ++b) { ++totalFound; #if defined(USE_ENUMVARIANT) IFileEntry *pfe = comstl::interface_cast_addref<IFileEntry*>((*b).punkVal); #elif defined(USE_ENUMENTRY) IFileEntry *pfe = *b; #else # error Must specify USE_ENUMVARIANT or USE_ENUMENTRY #endif /* 0 */ CComBSTR path = ::comstl::method_cast<CComBSTR>(pfe, &IFileEntry::get_Path); OLECHAR drive = ::comstl::method_cast<OLECHAR>(pfe, &IFileEntry::get_Drive); CComBSTR directory = ::comstl::method_cast<CComBSTR>(pfe, &IFileEntry::get_Directory); CComBSTR directoryPath = ::comstl::method_cast<CComBSTR>(pfe, &IFileEntry::get_DirectoryPath); CComBSTR uncDrive; LPUNKNOWN directoryParts = ::comstl::method_cast<LPUNKNOWN>(pfe, &IFileEntry::get_DirectoryParts); CComBSTR file = ::comstl::method_cast<CComBSTR>(pfe, &IFileEntry::get_File); CComBSTR shortFile = ::comstl::method_cast<CComBSTR>(pfe, &IFileEntry::get_ShortFile); CComBSTR fileName = ::comstl::method_cast<CComBSTR>(pfe, &IFileEntry::get_FileName); CComBSTR fileExt = ::comstl::method_cast<CComBSTR>(pfe, &IFileEntry::get_FileExt); DATE creationTime = ::comstl::method_cast<DATE>(pfe, &IFileEntry::get_CreationTime); DATE modificationTime = ::comstl::method_cast<DATE>(pfe, &IFileEntry::get_ModificationTime); DATE lastAccessTime = ::comstl::method_cast<DATE>(pfe, &IFileEntry::get_LastAccessTime); DATE lastStatusChangeTime = ::comstl::method_cast<DATE>(pfe, &IFileEntry::get_LastStatusChangeTime); long size = ::comstl::method_cast<long>(pfe, &IFileEntry::get_Size); BOOL isReadOnly = ::comstl::method_cast<BOOL>(pfe, &IFileEntry::get_IsReadOnly); BOOL isDirectory = ::comstl::method_cast<BOOL>(pfe, &IFileEntry::get_IsDirectory); BOOL isLink = FALSE; BOOL isUNC = FALSE; if(::comstl::interface_cast_test<IFileEntry2*>(pfe)) { IFileEntry2 *pfe2 = ::comstl::interface_cast_addref<IFileEntry2*>(pfe); if(NULL != pfe2) { uncDrive = ::comstl::method_cast<CComBSTR>(pfe2, &IFileEntry2::get_UNCDrive); isLink = ::comstl::method_cast<BOOL>(pfe2, &IFileEntry2::get_IsLink); isUNC = ::comstl::method_cast<BOOL>(pfe2, &IFileEntry2::get_IsUNC); pfe2->Release(); } } wcout << L" " << path << endl; if(!bSuccinct) { int off = 0; wcout << L" " << directoryPath << endl; if(isUNC) { wcout << L" " << uncDrive << endl; off += uncDrive.Length(); } else { wcout << L" " << (wchar_t const *)winstl::a2w((char const*)&drive, 1) << endl; off += 2; } wcout << L" " << std::setw(off + directory.Length()) << directory << std::setw(1) << endl; if( (flags & RECLS_F_DIRECTORY_PARTS) == RECLS_F_DIRECTORY_PARTS && NULL != directoryParts) { typedef comstl::collection_sequence< IDirectoryPartsCollection , IEnumVARIANT , VARIANT , comstl::VARIANT_policy , VARIANT const & , comstl::forward_cloning_policy<IEnumVARIANT> , 2 > parts_seq_t; parts_seq_t dirParts(comstl::interface_cast_addref<IDirectoryPartsCollection*>(directoryParts), false); parts_seq_t::iterator b = dirParts.begin(); parts_seq_t::iterator e = dirParts.end(); for(; b != e; ++b) { CComVariant vPart(*b); vPart.ChangeType(VT_BSTR); CComBSTR dirPart(vPart.bstrVal); off += dirPart.Length(); wcout << L" " << std::setw(off) << dirPart << std::setw(1) << endl; } directoryParts->Release(); } else { off += directory.Length(); } off += file.Length(); wcout << L" " << std::setw(off) << file << std::setw(1) << endl; if(fileExt.Length() > 0) { wcout << L" " << std::setw(off - (1 + fileExt.Length())) << fileName << std::setw(1) << endl; wcout << L" " << std::setw(off) << fileExt << std::setw(1) << endl; } else { wcout << L" " << std::setw(off) << fileName << std::setw(1) << endl; } if(isReadOnly) { wcout << L" - Read-only" << endl; } if(isDirectory) { wcout << L" - Directory" << endl; } else { wcout << L" - File" << endl; } if(isLink) { wcout << L" - Link" << endl; } if(isUNC) { wcout << L" - UNC" << endl; } } #if defined(USE_ENUMVARIANT) pfe->Release(); #endif /* USE_ENUMVARIANT */ } return totalFound; } /* * End of file */
This program uses the recls/COM mapping coclasses, implementing a recursive search for a given pattern, and other flags, from a given directory
VERSION 5.00 Begin VB.Form Form1 BorderStyle = 3 'Fixed Dialog Caption = "Form1" ClientHeight = 7320 ClientLeft = 45 ClientTop = 360 ClientWidth = 11550 LinkTopic = "Form1" MaxButton = 0 'False MinButton = 0 'False ScaleHeight = 7320 ScaleWidth = 11550 ShowInTaskbar = 0 'False StartUpPosition = 3 'Windows Default Begin VB.ListBox lstDirectoryParts Height = 2010 Left = 6360 TabIndex = 15 Top = 5040 Width = 5055 End Begin VB.ListBox lstProperties Height = 2790 Left = 6360 TabIndex = 13 Top = 1800 Width = 5055 End Begin VB.OptionButton rdoBoth Caption = "&Both" Height = 375 Left = 8160 Style = 1 'Graphical TabIndex = 11 Top = 720 Width = 975 End Begin VB.OptionButton rdoDirectories Caption = "&Directories" Height = 375 Left = 7080 Style = 1 'Graphical TabIndex = 10 Top = 720 Width = 975 End Begin VB.OptionButton rdoFiles Caption = "&Files" Height = 375 Left = 6120 Style = 1 'Graphical TabIndex = 9 Top = 720 Width = 855 End Begin VB.CheckBox chkRecursive Caption = "Recursi&ve" Height = 375 Left = 3360 TabIndex = 8 Top = 720 Width = 1215 End Begin VB.CheckBox chkDirParts Caption = "Directory P&arts" Height = 375 Left = 4680 TabIndex = 7 Top = 720 Width = 1335 End Begin VB.TextBox txtPattern Height = 375 Left = 1320 TabIndex = 5 Text = "*.*" Top = 720 Width = 1935 End Begin VB.ListBox lstFiles Height = 5325 Left = 120 TabIndex = 3 Top = 1800 Width = 6135 End Begin VB.CommandButton btnSearch Caption = "&Search" Height = 375 Left = 10080 TabIndex = 2 Top = 600 Width = 1335 End Begin VB.TextBox txtSearchRoot Height = 375 Left = 1320 TabIndex = 1 Text = "." Top = 240 Width = 10095 End Begin VB.Label Label5 Caption = "Directory pa&rts:" Height = 255 Left = 6360 TabIndex = 14 Top = 4680 Width = 1815 End Begin VB.Label Label4 Caption = "P&roperties:" Height = 255 Left = 6360 TabIndex = 12 Top = 1440 Width = 1575 End Begin VB.Label Label3 Caption = "F&iles:" Height = 255 Left = 120 TabIndex = 6 Top = 1440 Width = 1335 End Begin VB.Label Label2 Caption = "&Pattern:" Height = 255 Left = 120 TabIndex = 4 Top = 840 Width = 975 End Begin VB.Label Label1 Caption = "Search &root:" Height = 255 Left = 120 TabIndex = 0 Top = 240 Width = 1095 End End Attribute VB_Name = "Form1" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False Private g_index As Integer Private g_entries As Collection Private Sub btnSearch_Click() Dim fs As New RECLS_COMLib.FileSearch Dim searchRoot As String Dim pattern As String Dim flags As Long Dim srch As Object ' Reset the collection Set g_entries = New Collection g_index = 0 searchRoot = txtSearchRoot.Text pattern = txtPattern.Text flags = 0 If chkRecursive.Value Then flags = flags Or RECLS_FLAG.RECLS_F_RECURSIVE End If If chkDirParts.Value Then flags = flags Or RECLS_FLAG.RECLS_F_DIRECTORY_PARTS End If If rdoBoth.Value = True Then flags = flags Or RECLS_FLAG.RECLS_F_FILES flags = flags Or RECLS_FLAG.RECLS_F_DIRECTORIES ElseIf rdoDirectories = True Then flags = flags Or RECLS_FLAG.RECLS_F_DIRECTORIES ElseIf rdoFiles = True Then flags = flags Or RECLS_FLAG.RECLS_F_FILES Else flags = flags Or RECLS_FLAG.RECLS_F_FILES End If Set srch = fs.Search(searchRoot, pattern, flags) lstFiles.Clear lstProperties.Clear lstDirectoryParts.Clear For Each entry In srch lstFiles.AddItem (entry) lstFiles.ItemData(lstFiles.NewIndex) = g_index g_entries.Add entry, CStr(g_index) g_index = g_index + 1 Next End Sub Private Sub Form_Load() chkRecursive.Value = 1 rdoFiles.Value = True End Sub Private Sub lstFiles_Click() Dim entry As RECLS_COMLib.FileEntry Dim index As Integer Dim dirParts As Object index = lstFiles.ItemData(lstFiles.ListIndex) Set entry = g_entries.Item(CStr(index)) ' Do the properties lstProperties.Clear lstProperties.AddItem ("Drive: " & entry.Drive) lstProperties.AddItem ("Directory: " & entry.Directory) lstProperties.AddItem ("DirectoryPath: " & entry.DirectoryPath) lstProperties.AddItem ("File: " & entry.File) lstProperties.AddItem ("ShortFile: " & entry.ShortFile) lstProperties.AddItem ("FileName: " & entry.FileName) lstProperties.AddItem ("FileExt: " & entry.FileExt) lstProperties.AddItem ("CreationTime: " & entry.CreationTime) lstProperties.AddItem ("ModificationTime: " & entry.ModificationTime) lstProperties.AddItem ("LastAccessTime: " & entry.LastAccessTime) lstProperties.AddItem ("LastStatusChangeTime: " & entry.LastStatusChangeTime) lstProperties.AddItem ("Size: " & entry.Size) ' Do the directory parts Set dirParts = entry.DirectoryParts lstDirectoryParts.Clear For Each dirPart In dirParts lstDirectoryParts.AddItem (dirPart) Next End Sub
This program uses the free API functions in the recls/D mapping, implementing a recursive search for a given pattern, and other flags, from a given directory
/* * File: recls_test_1.d * * Purpose: Test program for the D mapping of recls. (Now the std.recls * module in the D standard library). Test free-functions. * * Created 24th November 2003 * Updated: 30th September 2004 * * Status: Wizard-generated * * License: (Licensed under the Synesis Software Open License) * * Copyright (C) 2003-2004, Matthew Wilson. * All rights reserved. * * www: http://www.synesis.com.au/software * * email: software@synesis.com.au * * This source code is placed into the public domain 2004 * by Matthew Wilson. There are no restrictions * whatsoever to your use of the software. * * This source code is provided by Matthew Wilson "as is" * and any warranties, whether expressed or implied, including, but * not limited to, the implied warranties of merchantability and * fitness for a particular purpose are disclaimed. In no event * shall the Matthew Wilson be liable for any direct, * indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or * business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort * (including negligence or otherwise) arising in any way out of * the use of this software, even if advised of the possibility of * such damage. * * Neither the name of Matthew Wilson nor the names of * any subdivisions, employees or agents of Matthew Wilson, nor the * names of any other contributors to this software * may be used to endorse or promote products derived from this * software without specific prior written permission. * * import std.recls; import std.string; import std.c.stdio; import std.c.stdlib; int main(char[][] args) { int iRet = 0; int i; char[] host = null; char[] username = null; char[] password = null; char[] pattern = null; char[] searchRoot = null; recls_rc_t rc; recls_uint32_t flags = RECLS_FLAG.RECLS_F_RECURSIVE; int bSuccinct = false; for(i = 1; i < args.length; ++i) { char[] arg = args[i]; if(arg[0] == '-') { if(arg[1] == '-') { /* -- arguments */ } else { /* - arguments */ switch(arg[1]) { case 'd': /* Find directories */ flags |= RECLS_FLAG.RECLS_F_DIRECTORIES; break; case 'f': /* Find files */ flags |= RECLS_FLAG.RECLS_F_FILES; break; case 'p': /* Show directory parts */ flags |= RECLS_FLAG.RECLS_F_DIRECTORY_PARTS; break; case 'R': /* Do not recurse */ flags &= ~(RECLS_FLAG.RECLS_F_RECURSIVE); break; case 's': /* Show only the full path; WHEREIS functionality */ bSuccinct = true; break; case 'H': host = arg[2 .. arg.length]; break; case 'U': username = arg[2 .. arg.length]; break; case 'P': password = arg[2 .. arg.length]; break; default: usage(1); break; } } } else { /* other arguments */ if(null == pattern) { pattern = arg; } else if(null == searchRoot) { searchRoot = arg; } else { usage(1); } } } /* Search for files if neither files or directories specified/ * * Even though this is not necessary, because the recls API provides the * same interpretation, it's best to be explicit. */ if(0 == (flags & (RECLS_FLAG.RECLS_F_FILES | RECLS_FLAG.RECLS_F_DIRECTORIES))) { flags |= RECLS_FLAG.RECLS_F_FILES; } if(null == pattern) { pattern = "*"; if(null === host) { pattern = std.recls.wildcardsAll(); } } /* Initiate the search. */ hrecls_t hSrch; if(null === host) { if(null == searchRoot) { searchRoot = "."; } rc = Search_Create(searchRoot, pattern, flags, hSrch); } else { if(null == searchRoot) { searchRoot = "/"; } rc = Search_CreateFtp(host, username, password, searchRoot, pattern, flags, hSrch); } if(RECLS_FAILED(rc)) { char[] err = Search_GetErrorString(rc); fprintf(stderr, "Failed to start search, with pattern \"%.*s\"; recls error: %.*s\n", pattern, err); } else { /* Iterate through the items, until done */ recls_info_t entry; rc = Search_GetEntry(hSrch, entry); for(; RECLS_SUCCEEDED(rc); rc = Search_GetNextEntry(hSrch, entry)) { int i; int off; int extLen; int cDirParts; char[] path = Search_GetEntryPath(entry); version(Windows) { char drive = Search_GetEntryDrive(entry); if('\0' != drive) { // This complex dance is necessitated because string and ctype seem // unable to coexist (with v0.74, anyway) if(drive != path[0]) { char p0upper = toupper(path[0 .. 1])[0]; char p0lower = tolower(path[0 .. 1])[0]; if(drive == p0upper) { drive = p0lower; } else { drive = p0upper; } } } } char[] dir = Search_GetEntryDirectory(entry); char[] dirPath = Search_GetEntryDirectoryPath(entry); char[] file = Search_GetEntryFile(entry); char[] fileName = Search_GetEntryFileName(entry); char[] fileExt = Search_GetEntryFileExt(entry); char[] pathCheck = ""; char[] dirCheck = ""; char[] fileCheck; recls_filesize_t size = Search_GetEntrySize(entry); version(Debug) { recls_uint32_t cBlocks; Search_OutstandingEntry(hSrch, &cBlocks); printf("\n%d outstanding blocks\n", cBlocks); } printf(" %.*s\n", path); if(!bSuccinct) { printf(" %.*s\n", dirPath); version(Windows) { if('\0' != drive) { printf(" %c\n", drive); pathCheck ~= drive; pathCheck ~= ':'; } } printf(" %.*s%.*s\n", (drive != '\0') * 2, cast(char*)" ", dir); off = 0; if((flags & RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) == RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) { char[][] parts = Search_GetEntryDirectoryParts(entry); foreach(char[] part; parts) { printf(" %*s", off, cast(char*)""); printf("%.*s\n", part); off += part.length; pathCheck ~= part; dirCheck ~= part; } } else { off += dir.length; pathCheck ~= dir; } printf(" %*s%.*s\n", off, cast(char*)"", file); printf(" %*s%.*s\n", off, cast(char*)"", fileName); off += file.length; extLen = fileExt.length; printf(" %*s%.*s\n", off - extLen, cast(char*)"", fileExt); fileCheck = fileName; if(0 < extLen) { fileCheck ~= '.'; fileCheck ~= fileExt; } pathCheck ~= file; /* Now validate the components */ version(Windows) { if(path != pathCheck) { fprintf(stderr, "Path is different from path components\n\tpath: %.*s\n\tpathCheck: %.*s\n\n", path, pathCheck); } assert(path == pathCheck); } else { if(path != pathCheck) { fprintf(stderr, "Path is different from path components\n\tpath: %.*s\n\tpathCheck: %.*s\n\n", path, pathCheck); } assert(path == pathCheck); } version(Windows) { if( ( '\0' != drive && (dirPath[0] != drive || dir != dirPath[2 .. dirPath.length])) || ( '\0' == drive && dirPath != dir)) { fprintf(stderr, "DirectoryPath is different from Directory\n\tdirPath: %.*s (%d)\n\tdir: %c:%.*s (%d)\n\n", dirPath, dirPath.length - 2, drive, dir, dir.length); } assert( ( '\0' != drive && dirPath[0] == drive && dir == dirPath[2 .. dirPath.length]) || ( '\0' == drive && dirPath == dir)); } else { if(dirPath != dir) { fprintf(stderr, "DirectoryPath is different from Directory\n\tdirPath: %.*s\n\tdir: %.*s\n\n", dirPath, dir); } assert(dirPath == dir); } if((flags & RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) == RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) { if(dir != dirCheck) { fprintf(stderr, "Directory is different from directory components\n\tdir: %.*s\n\tdirCheck: %.*s\n\n", dir, dirCheck); } assert(dir == dirCheck); } if(file != fileCheck) { fprintf(stderr, "File is different from file components\n\tfile: %d:%.*s\n\tfileCheck: %d:%.*s\n\n", file.length, file, fileCheck.length, fileCheck); } assert(file == fileCheck); if(Search_IsEntryDirectory(entry)) { printf(" - Directory\n"); } else { printf(" - File\n"); } if(Search_IsEntryReadOnly(entry)) { printf(" - Read-only\n"); } if(Search_IsEntryLink(entry)) { printf(" - Link\n"); } printf(" %lu\n", size); } Search_CloseEntry(entry); } if(rc != RECLS_RC_NO_MORE_DATA) { char[] err = Search_GetErrorString(rc); fprintf(stderr, "Search terminated prematurely; recls error: %.*s\n", err); } Search_Close(hSrch); } return iRet; } /* * Function implementations */ void usage(int bExit) { fprintf(stderr, "recls D Test Program: recls_test_1\n\n"); fprintf(stderr, "Usage: recls_test_1 [-d] [-f] [-p] [-R] [-s] [-H<host>] [-U<username>] [-P<password>] [<pattern>] [<root-dir>]\n"); fprintf(stderr, "\t-d - search for directories\n"); fprintf(stderr, "\t-f - search for files. (default if neither f or d specified)\n"); fprintf(stderr, "\t-p - include directory parts in search, and display\n"); fprintf(stderr, "\t-R - does not recurse. (recursive search is the default)\n"); fprintf(stderr, "\t-s - succinct; shows only the path\n"); fprintf(stderr, "\t-H<host> - performs an FTP search on the given host\n"); fprintf(stderr, "\t-U<username> - username to use to log on to <host>\n"); fprintf(stderr, "\t-P<password> - password to use to log on to <host>\n"); fprintf(stderr, "\t<pattern> - search pattern, e.g. \"*.cpp\" (default is to search for all files)\n"); fprintf(stderr, "\t<root-dir> - root directory of search; default is current working directory\n"); if(bExit) { exit(1); } } /* * End of file */
This program uses the classes in the recls/D mapping, implementing a recursive search for a given pattern, and other flags, from a given directory
/* * File: recls_test_1.d * * Purpose: Test program for the D mapping of recls. (Now the std.recls * module in the D standard library). Test free-functions. * * Created 24th November 2003 * Updated: 30th September 2004 * * Status: Wizard-generated * * License: (Licensed under the Synesis Software Open License) * * Copyright (C) 2003-2004, Matthew Wilson. * All rights reserved. * * www: http://www.synesis.com.au/software * * email: software@synesis.com.au * * This source code is placed into the public domain 2004 * by Matthew Wilson. There are no restrictions * whatsoever to your use of the software. * * This source code is provided by Matthew Wilson "as is" * and any warranties, whether expressed or implied, including, but * not limited to, the implied warranties of merchantability and * fitness for a particular purpose are disclaimed. In no event * shall the Matthew Wilson be liable for any direct, * indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or * business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort * (including negligence or otherwise) arising in any way out of * the use of this software, even if advised of the possibility of * such damage. * * Neither the name of Matthew Wilson nor the names of * any subdivisions, employees or agents of Matthew Wilson, nor the * names of any other contributors to this software * may be used to endorse or promote products derived from this * software without specific prior written permission. * * import std.recls; import std.string; import std.c.stdio; import std.c.stdlib; int main(char[][] args) { int iRet = 0; int i; char[] host = null; char[] username = null; char[] password = null; char[] pattern = null; char[] searchRoot = null; recls_rc_t rc; recls_uint32_t flags = RECLS_FLAG.RECLS_F_RECURSIVE; int bSuccinct = false; for(i = 1; i < args.length; ++i) { char[] arg = args[i]; if(arg[0] == '-') { if(arg[1] == '-') { /* -- arguments */ } else { /* - arguments */ switch(arg[1]) { case 'd': /* Find directories */ flags |= RECLS_FLAG.RECLS_F_DIRECTORIES; break; case 'f': /* Find files */ flags |= RECLS_FLAG.RECLS_F_FILES; break; case 'p': /* Show directory parts */ flags |= RECLS_FLAG.RECLS_F_DIRECTORY_PARTS; break; case 'R': /* Do not recurse */ flags &= ~(RECLS_FLAG.RECLS_F_RECURSIVE); break; case 's': /* Show only the full path; WHEREIS functionality */ bSuccinct = true; break; case 'H': host = arg[2 .. arg.length]; break; case 'U': username = arg[2 .. arg.length]; break; case 'P': password = arg[2 .. arg.length]; break; default: usage(1); break; } } } else { /* other arguments */ if(null == pattern) { pattern = arg; } else if(null == searchRoot) { searchRoot = arg; } else { usage(1); } } } /* Search for files if neither files or directories specified/ * * Even though this is not necessary, because the recls API provides the * same interpretation, it's best to be explicit. */ if(0 == (flags & (RECLS_FLAG.RECLS_F_FILES | RECLS_FLAG.RECLS_F_DIRECTORIES))) { flags |= RECLS_FLAG.RECLS_F_FILES; } if(null == pattern) { pattern = "*"; if(null === host) { pattern = std.recls.wildcardsAll(); } } /* Initiate the search. */ hrecls_t hSrch; if(null === host) { if(null == searchRoot) { searchRoot = "."; } rc = Search_Create(searchRoot, pattern, flags, hSrch); } else { if(null == searchRoot) { searchRoot = "/"; } rc = Search_CreateFtp(host, username, password, searchRoot, pattern, flags, hSrch); } if(RECLS_FAILED(rc)) { char[] err = Search_GetErrorString(rc); fprintf(stderr, "Failed to start search, with pattern \"%.*s\"; recls error: %.*s\n", pattern, err); } else { /* Iterate through the items, until done */ recls_info_t entry; rc = Search_GetEntry(hSrch, entry); for(; RECLS_SUCCEEDED(rc); rc = Search_GetNextEntry(hSrch, entry)) { int i; int off; int extLen; int cDirParts; char[] path = Search_GetEntryPath(entry); version(Windows) { char drive = Search_GetEntryDrive(entry); if('\0' != drive) { // This complex dance is necessitated because string and ctype seem // unable to coexist (with v0.74, anyway) if(drive != path[0]) { char p0upper = toupper(path[0 .. 1])[0]; char p0lower = tolower(path[0 .. 1])[0]; if(drive == p0upper) { drive = p0lower; } else { drive = p0upper; } } } } char[] dir = Search_GetEntryDirectory(entry); char[] dirPath = Search_GetEntryDirectoryPath(entry); char[] file = Search_GetEntryFile(entry); char[] fileName = Search_GetEntryFileName(entry); char[] fileExt = Search_GetEntryFileExt(entry); char[] pathCheck = ""; char[] dirCheck = ""; char[] fileCheck; recls_filesize_t size = Search_GetEntrySize(entry); version(Debug) { recls_uint32_t cBlocks; Search_OutstandingEntry(hSrch, &cBlocks); printf("\n%d outstanding blocks\n", cBlocks); } printf(" %.*s\n", path); if(!bSuccinct) { printf(" %.*s\n", dirPath); version(Windows) { if('\0' != drive) { printf(" %c\n", drive); pathCheck ~= drive; pathCheck ~= ':'; } } printf(" %.*s%.*s\n", (drive != '\0') * 2, cast(char*)" ", dir); off = 0; if((flags & RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) == RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) { char[][] parts = Search_GetEntryDirectoryParts(entry); foreach(char[] part; parts) { printf(" %*s", off, cast(char*)""); printf("%.*s\n", part); off += part.length; pathCheck ~= part; dirCheck ~= part; } } else { off += dir.length; pathCheck ~= dir; } printf(" %*s%.*s\n", off, cast(char*)"", file); printf(" %*s%.*s\n", off, cast(char*)"", fileName); off += file.length; extLen = fileExt.length; printf(" %*s%.*s\n", off - extLen, cast(char*)"", fileExt); fileCheck = fileName; if(0 < extLen) { fileCheck ~= '.'; fileCheck ~= fileExt; } pathCheck ~= file; /* Now validate the components */ version(Windows) { if(path != pathCheck) { fprintf(stderr, "Path is different from path components\n\tpath: %.*s\n\tpathCheck: %.*s\n\n", path, pathCheck); } assert(path == pathCheck); } else { if(path != pathCheck) { fprintf(stderr, "Path is different from path components\n\tpath: %.*s\n\tpathCheck: %.*s\n\n", path, pathCheck); } assert(path == pathCheck); } version(Windows) { if( ( '\0' != drive && (dirPath[0] != drive || dir != dirPath[2 .. dirPath.length])) || ( '\0' == drive && dirPath != dir)) { fprintf(stderr, "DirectoryPath is different from Directory\n\tdirPath: %.*s (%d)\n\tdir: %c:%.*s (%d)\n\n", dirPath, dirPath.length - 2, drive, dir, dir.length); } assert( ( '\0' != drive && dirPath[0] == drive && dir == dirPath[2 .. dirPath.length]) || ( '\0' == drive && dirPath == dir)); } else { if(dirPath != dir) { fprintf(stderr, "DirectoryPath is different from Directory\n\tdirPath: %.*s\n\tdir: %.*s\n\n", dirPath, dir); } assert(dirPath == dir); } if((flags & RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) == RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) { if(dir != dirCheck) { fprintf(stderr, "Directory is different from directory components\n\tdir: %.*s\n\tdirCheck: %.*s\n\n", dir, dirCheck); } assert(dir == dirCheck); } if(file != fileCheck) { fprintf(stderr, "File is different from file components\n\tfile: %d:%.*s\n\tfileCheck: %d:%.*s\n\n", file.length, file, fileCheck.length, fileCheck); } assert(file == fileCheck); if(Search_IsEntryDirectory(entry)) { printf(" - Directory\n"); } else { printf(" - File\n"); } if(Search_IsEntryReadOnly(entry)) { printf(" - Read-only\n"); } if(Search_IsEntryLink(entry)) { printf(" - Link\n"); } printf(" %lu\n", size); } Search_CloseEntry(entry); } if(rc != RECLS_RC_NO_MORE_DATA) { char[] err = Search_GetErrorString(rc); fprintf(stderr, "Search terminated prematurely; recls error: %.*s\n", err); } Search_Close(hSrch); } return iRet; } /* * Function implementations */ void usage(int bExit) { fprintf(stderr, "recls D Test Program: recls_test_1\n\n"); fprintf(stderr, "Usage: recls_test_1 [-d] [-f] [-p] [-R] [-s] [-H<host>] [-U<username>] [-P<password>] [<pattern>] [<root-dir>]\n"); fprintf(stderr, "\t-d - search for directories\n"); fprintf(stderr, "\t-f - search for files. (default if neither f or d specified)\n"); fprintf(stderr, "\t-p - include directory parts in search, and display\n"); fprintf(stderr, "\t-R - does not recurse. (recursive search is the default)\n"); fprintf(stderr, "\t-s - succinct; shows only the path\n"); fprintf(stderr, "\t-H<host> - performs an FTP search on the given host\n"); fprintf(stderr, "\t-U<username> - username to use to log on to <host>\n"); fprintf(stderr, "\t-P<password> - password to use to log on to <host>\n"); fprintf(stderr, "\t<pattern> - search pattern, e.g. \"*.cpp\" (default is to search for all files)\n"); fprintf(stderr, "\t<root-dir> - root directory of search; default is current working directory\n"); if(bExit) { exit(1); } } /* * End of file */
This program uses the classes in the recls/Java mapping, implementing a recursive search for a given pattern, and other flags, from a given directory
/* * File: recls_test.java * * Purpose: Test file for the recls Java mapping. * * Created: 22nd November 2003 * Updated: 15th March 2005 * * Status: Wizard-generated * * License: (Licensed under the Synesis Software Open License) * * Copyright (C) 1999-2003, Synesis Software Pty Ltd. * All rights reserved. * * www: http://www.synesis.com.au/software * * email: software@synesis.com.au * * This source code is placed into the public domain 2003 * by Synesis Software Pty Ltd. There are no restrictions * whatsoever to your use of the software. * * This source code is provided by Synesis Software Pty Ltd "as is" * and any warranties, whether expressed or implied, including, but * not limited to, the implied warranties of merchantability and * fitness for a particular purpose are disclaimed. In no event * shall the Synesis Software Pty Ltd be liable for any direct, * indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or * business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort * (including negligence or otherwise) arising in any way out of * the use of this software, even if advised of the possibility of * such damage. * * Neither the name of Synesis Software Pty Ltd nor the names of * any subdivisions, employees or agents of Synesis Software Pty * Ltd, nor the names of any other contributors to this software * may be used to endorse or promote products derived from this * software without specific prior written permission. * */ import org.recls.Entry; import org.recls.ReclsException; import org.recls.Search; import org.recls.FileSearch; import org.recls.FtpSearch; import java.util.Enumeration; public class recls_test { public static void main(String[] args) { int i; String host = null; String username = null; String password = null; String pattern = null; String rootDir = null; int flags = Search.RECLS_F_RECURSIVE; boolean bSuccinct = false; /* for(i = 0; i < args.length; ++i) { String arg = args[i]; System.out.println(i + ": " + arg); } System.exit(0); */ for(i = 0; i < args.length; ++i) { String arg = args[i]; if(arg.charAt(0) == '-') { if(arg.charAt(1) == '-') { /* -- arguments */ } else { /* - arguments */ switch(arg.charAt(1)) { case 'R': /* Do not recurse */ flags &= ~(Search.RECLS_F_RECURSIVE); break; case 'p': /* Show directory parts */ flags |= Search.RECLS_F_DIRECTORY_PARTS; break; case 'f': /* Find files */ flags |= Search.RECLS_F_FILES; break; case 'd': /* Find directories */ flags |= Search.RECLS_F_DIRECTORIES; break; case 's': /* Show only the full path; WHEREIS functionality */ bSuccinct = true; break; case 'H': host = arg.substring(2); break; default: usage("Unrecognised argument: " + arg); break; } } } else { /* other arguments */ if(null == pattern) { pattern = arg; } else if(null == rootDir) { rootDir = arg; } else { usage("Unrecognised argument: " + arg); } } } /* Search for files if neither files or directories specified/ * * Even though this is not necessary, because the recls API provides the * same interpretation, it's best to be explicit. */ if(0 == (flags & (Search.RECLS_F_FILES | Search.RECLS_F_DIRECTORIES))) { flags |= Search.RECLS_F_FILES; } Entry local = FileSearch.Stat(".", 0); System.out.println("Local dir: " + local.getPath()); try { int total = 0; Search search; if(null != host) { search = new FtpSearch(host, username, password, rootDir, pattern, flags); } else { search = new FileSearch(rootDir, pattern, flags); } for(Enumeration en = search; en.hasMoreElements(); ++total) { Object el = en.nextElement(); System.out.println(el); if(!bSuccinct) { Entry entry = (Entry)el; System.out.println(" Path: " + entry.getPath()); System.out.println(" Drive: " + entry.getDrive()); System.out.println(" Directory: " + entry.getDirectory()); System.out.println(" DirectoryPath: " + entry.getDirectoryPath()); System.out.println(" UNCDrive: " + entry.getUNCDrive()); if((flags & Search.RECLS_F_DIRECTORY_PARTS) == Search.RECLS_F_DIRECTORY_PARTS) { String[] dirParts = entry.getDirectoryParts(); for(int j = 0; j < dirParts.length; ++j) { System.out.println(" " + dirParts[j]); } } System.out.println(" File: " + entry.getFile()); System.out.println(" ShortFile: " + entry.getShortFile()); System.out.println(" FileName: " + entry.getFileName()); System.out.println(" FileExt: " + entry.getFileExt()); System.out.println(" Size: " + entry.getSize()); System.out.println(" CreationTime: " + entry.getCreationTime()); System.out.println(" ModificationTime: " + entry.getModificationTime()); System.out.println(" LastAccessTime: " + entry.getLastAccessTime()); System.out.println(" LastStatusChangeTime: " + entry.getLastStatusChangeTime()); System.out.println(" isReadOnly: " + entry.isReadOnly()); System.out.println(" isDirectory: " + entry.isDirectory()); System.out.println(" isLink: " + entry.isLink()); System.out.println(" isUNC: " + entry.isUNC()); } } search.close(); System.out.println(" Total matched: " + total); } catch(ReclsException x) { System.out.println(x); } } private static void usage(String message) { System.err.println("recls Java Test Program: java_test\n"); System.err.println(""); if(message != null) { System.err.println(" Error: " + message); System.err.println(""); } System.err.println("Usage: java java_test [-d] [-f] [-d] [-R] [-H<host>] [<pattern>] [<root-dir>]"); System.err.println("\t-d - search for directories"); System.err.println("\t-f - search for files. (default if neither f or d specified)"); System.err.println("\t-H - search for files using FTP on the given <host>"); System.err.println("\t-p - include directory parts in search, and display"); System.err.println("\t-R - does not recurse. (recursive search is the default)"); System.err.println("\t-s - succinct; shows only the path"); System.err.println("\t<pattern> - search pattern, e.g. \"*.cpp\" (default is to search for all files)"); System.err.println("\t<root-dir> - root directory of search; default is current working directory"); System.exit(1); } }
This program uses the recls/Python mapping classes, implementing a recursive search for a given pattern, from a given directory
This program uses the recls/Ruby mapping classes, implementing a recursive search for a given pattern, from a given directory
This program uses the recls/STL mapping classes, implementing a recursive search for a given pattern, from a given directory
/* * File: STL.cpp * * Purpose: Implementation file for the STL project. * * Created: 16th August 2003 * Updated: 15th March 2005 * * Status: Wizard-generated * * License: (Licensed under the Synesis Software Open License) * * Copyright 2003-2005, Synesis Software Pty Ltd. * All rights reserved. * * www: http://www.synesis.com.au/software * * email: software@synesis.com.au * * This source code is placed into the public domain 2003 * by Synesis Software Pty Ltd. There are no restrictions * whatsoever to your use of the software. * * This source code is provided by Synesis Software Pty Ltd "as is" * and any warranties, whether expressed or implied, including, but * not limited to, the implied warranties of merchantability and * fitness for a particular purpose are disclaimed. In no event * shall the Synesis Software Pty Ltd be liable for any direct, * indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or * business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort * (including negligence or otherwise) arising in any way out of * the use of this software, even if advised of the possibility of * such damage. * * Neither the name of Synesis Software Pty Ltd nor the names of * any subdivisions, employees or agents of Synesis Software Pty * Ltd, nor the names of any other contributors to this software * may be used to endorse or promote products derived from this * software without specific prior written permission. * * // Define this definition to retrict use to platform-independent aspects of the API //#define RECLS_PURE_API // Define this to copy file entries into a vector, to exercise the copy semantics //#define TAKE_COPIES_IN_VECTOR #include <recls.h> #ifdef RECLS_PLATFORM_IS_WIN32 # include <recls_ftp.h> #endif /* RECLS_PLATFORM_IS_WIN32 */ #if RECLS_VER < RECLS_VER_1_6_1 # error This file now requires version 1.6.1 or later of the recls C API #endif /* RECLS_VER < 1.6.1 */ #ifdef RECLS_STRICT # include <stlsoft_nulldef.h> #endif // RECLS_STRICT #ifdef _MSC_VER # include <crtdbg.h> # pragma warning(disable : 4530) #endif /* _MSC_VER */ #include <recls/stl/recls.hpp> #include <recls/stl/root_sequence.hpp> #include <recls/stl/search_sequence.hpp> #if !defined(RECLS_COMPILER_IS_DMC) # include <iostream> # include <iomanip> #else /* ? compiler */ # include <iostream.h> # include <iomanip.h> #endif /* compiler */ #include <stdio.h> /* * Namespace */ #if !defined(RECLS_COMPILER_IS_DMC) using std::cout; using std::cerr; using std::endl; using std::setw; #endif /* compiler */ using recls::recls_info_t; using recls::recls_char_t; using recls::RECLS_F_FILES; using recls::RECLS_F_DIRECTORIES; using recls::RECLS_F_RECURSIVE; using recls::RECLS_F_DIRECTORY_PARTS; /* * Forward declarations */ static void usage(int bExit, char const *reason); int processDirectory(char const *host, char const *username, char const *password, char const *rootDir, char const *pattern, long flags, int bSuccinct); /* * Main */ int main(int argc, char *argv[]) { #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemState memState; #endif /* _MSC_VER && _MSC_VER */ int iRet = 0; int i; int totalFound = 0; char const *host = NULL; char const *username = NULL; char const *password = NULL; char const *pattern = NULL; char const *rootDir = NULL; unsigned flags = RECLS_F_RECURSIVE; int bSuccinct = false; int bAllHardDrives = false; for(i = 1; i < argc; ++i) { const char *arg = argv[i]; if(arg[0] == '-') { if(arg[1] == '-') { /* -- arguments */ } else { /* - arguments */ switch(arg[1]) { case '?': usage(1, NULL); break; case 'R': /* Do not recurse */ flags &= ~(RECLS_F_RECURSIVE); break; case 'p': /* Show directory parts */ flags |= RECLS_F_DIRECTORY_PARTS; break; case 'f': /* Find files */ flags |= RECLS_F_FILES; break; case 'd': /* Find directories */ flags |= RECLS_F_DIRECTORIES; break; case 'h': /* Searches from hard drives */ bAllHardDrives = 1; break; case 's': /* Show only the full path; WHEREIS functionality */ bSuccinct = true; break; case 'H': /* FTP host */ host = arg + 2; break; case 'U': /* FTP username */ username = arg + 2; break; case 'P': /* FTP password */ password = arg + 2; break; default: usage(1, "Invalid argument(s) specified"); break; } } } else { /* other arguments */ if(NULL == pattern) { pattern = arg; } else if(NULL == rootDir) { rootDir = arg; } else { usage(1, "Invalid argument(s) specified"); } } } if( NULL != password && ( NULL == host || NULL == username)) { usage(1, "Must specify host and username if specifying password"); } if( NULL != username && NULL == host) { usage(1, "Must specify host if specifying username"); } if( NULL != host && bAllHardDrives) { usage(1, "-h flag meaningless to FTP searches"); } if( NULL != host && NULL == rootDir) { usage(1, "Must specify a root directory for FTP searches"); } #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemCheckpoint(&memState); #endif /* _MSC_VER && _MSC_VER */ // Search for files if neither files or directories specified // // Even though this is not necessary, because the recls API provides the // same interpretation, it's best to be explicit. if(0 == (flags & (RECLS_F_FILES | RECLS_F_DIRECTORIES))) { flags |= RECLS_F_FILES; } if(NULL == pattern) { pattern = recls::Recls_GetWildcardsAll(); } if(NULL == rootDir) { rootDir = "."; } if(bAllHardDrives) { reclstl::basic_root_sequence<recls_char_t> roots; reclstl::basic_root_sequence<recls_char_t>::const_iterator begin = roots.begin(); reclstl::basic_root_sequence<recls_char_t>::const_iterator end = roots.end(); for(; begin != end; ++begin) { totalFound += processDirectory(host, username, password, *begin, pattern, flags, bSuccinct); } } else { totalFound = processDirectory(host, username, password, rootDir, pattern, flags, bSuccinct); } fprintf(stdout, "Total found: %d\n", totalFound); #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemDumpAllObjectsSince(&memState); #endif /* _MSC_VER && _MSC_VER */ return iRet; } /* * Function implementations */ void usage(int bExit, char const *reason) { cerr << "recls STL Test Program:" << endl << endl; if(NULL != reason) { fprintf(stderr, " Error: %s\n\n", reason); } cerr << "Usage: STL [-d] [-f] [-h] [-p] [-R] [-s] [-H<host>] [-U<username>] [-P<password>] [<pattern>] [<root-dir>]" << endl; cerr << "\t-R - does not recurse; recursive search is the default" << endl; cerr << "\t-p - evaluate and display directory parts" << endl; cerr << "\t-d - search for directories" << endl; cerr << "\t-f - search for files (this is the default, if -d is not specified" << endl; cerr << "\t-h - searches from hard drive roots. (Ignore <root-dir>.)" << endl; cerr << "\t-s - succinct; shows only the path" << endl; cerr << "\t-H<host> - performs an FTP search on the given host" << endl; cerr << "\t-U<username> - username to use to log on to <host>" << endl; cerr << "\t-P<password> - password to use to log on to <host>" << endl; cerr << "\t<pattern> - search pattern, e.g. \"*.cpp\"; default is to search for all files" << endl; cerr << "\t<root-dir> - root directory of search; default is current working directory" << endl; if(bExit) { exit(EXIT_FAILURE); } } int processDirectory(char const *host, char const *username, char const *password, char const *rootDir, char const *pattern, long flags, int bSuccinct) { typedef reclstl::basic_search_sequence<recls_char_t> sequence_t; int totalFound = 0; #if defined(RECLS_API_FTP) sequence_t search(host, username, password, rootDir, pattern, flags); #else /* ? RECLS_API_FTP */ STLSOFT_SUPPRESS_UNUSED(host); STLSOFT_SUPPRESS_UNUSED(username); STLSOFT_SUPPRESS_UNUSED(password); sequence_t search(rootDir, pattern, flags); #endif /* RECLS_API_FTP */ sequence_t::const_iterator begin = search.begin(); sequence_t::const_iterator end = search.end(); for(; begin != end; ++begin) { using reclstl::string_t; ++totalFound; sequence_t::value_type fileEntry = *begin; #ifdef RECLS_PLATFORM_API_WIN32 recls_char_t drive = fileEntry.get_drive(); #endif /* RECLS_PLATFORM_API_WIN32 */ string_t uncDrive = fileEntry.get_UNC_drive(); string_t path = fileEntry.get_path(); string_t dir = fileEntry.get_directory(); string_t dirPath = fileEntry.get_directory_path(); string_t file = fileEntry.get_file(); string_t fileName = fileEntry.get_filename(); string_t fileExt = fileEntry.get_fileext(); string_t pathCheck; string_t dirCheck; string_t fileCheck; cout << " " << path << endl; if(!bSuccinct) { int off = 0; cout << " " << dirPath << endl; if(fileEntry.is_UNC()) { cout << " " << uncDrive << endl; pathCheck += uncDrive; off += uncDrive.length(); } else { #ifdef RECLS_PLATFORM_API_WIN32 if(isupper(path[0])) { drive = (recls_char_t)toupper(drive); } else { drive = (recls_char_t)tolower(drive); } cout << " " << drive << endl; pathCheck += drive; pathCheck += ':'; off += 2; #elif defined(RECLS_PLATFORM_IS_WIN32) off += 2; #else /* platform */ off += 0; #endif /* RECLS_PLATFORM_API_WIN32 */ } cout << " " << setw(off + dir.length()) << dir << endl; typedef sequence_t::value_type::directory_parts_type directory_parts_type; #ifndef RECLS_PURE_API if((flags & RECLS_F_DIRECTORY_PARTS) == RECLS_F_DIRECTORY_PARTS) { directory_parts_type dirParts = fileEntry.get_directory_parts(); int i; directory_parts_type::iterator begin = dirParts.begin(); directory_parts_type::iterator end = dirParts.end(); for(i = 0; begin != end; ++begin, ++i) { string_t dirPart = *begin; off += dirPart.length(); cout << " " << setw(off) << dirPart << setw(1) << endl; pathCheck += dirPart; dirCheck += dirPart; } } else #endif /* !RECLS_PURE_API */ { off += dir.length(); pathCheck += dir; } off += file.length(); cout << " " << setw(off) << file << setw(1) << endl; if(fileExt.length() > 0) { cout << " " << setw(off - (1 + fileExt.length())) << fileName << setw(1) << endl; cout << " " << setw(off) << fileExt << setw(1) << endl; } else { cout << " " << setw(off) << fileName << setw(1) << endl; } fileCheck = fileName; if(0 < fileExt.length()) { fileCheck += '.'; fileCheck += fileExt; } pathCheck += file; // Now validate the components recls_assert(path == pathCheck); if(path != pathCheck) { cerr << "Path is different from path components" << endl << "\tpath: \"" << path << "\"" << endl << "\tparts: \"" << pathCheck << "\"" << endl << endl; abort(); } #ifdef RECLS_PLATFORM_API_WIN32 recls_assert(NULL != host || (dirPath[0] == drive && dir == dirPath.c_str() + 2)); recls_assert(NULL == host || dir == dirPath); if( ( NULL == host && ( dirPath[0] != drive || dir != dirPath.c_str() + 2)) || ( NULL != host && dir != dirPath)) #else recls_assert(fileEntry.is_UNC() || dirPath == dir); if( !fileEntry.is_UNC() && dirPath != dir) #endif /* RECLS_PLATFORM_API_WIN32 */ { cerr << "DirectoryPath is different from Directory" << endl << "\tdirPath: \"" << dirPath << "\"" << endl << "\tdir: \"" << dir << "\"" << endl << endl; abort(); } if((flags & RECLS_F_DIRECTORY_PARTS) == RECLS_F_DIRECTORY_PARTS) { recls_assert(fileEntry.is_UNC() || dir == dirCheck); if( !fileEntry.is_UNC() && dir != dirCheck) { cerr << "Directory is different from directory components" << endl << "\tpath: " << dir << "" << endl << "\tparts: " << dirCheck << endl << endl; abort(); } } recls_assert(file == fileCheck); if(file != fileCheck) { cerr << "File is different from file components" << endl << "\tpath: " << "%s" << "" << endl << "\tparts: " << "%s" << endl << endl; abort(); } if(fileEntry.is_readonly()) { cout << " - Read-only" << endl; } if(fileEntry.is_directory()) { cout << " - Directory" << endl; } else { cout << " - File" << endl; } if(fileEntry.is_link()) { cout << " - Link" << endl; } if(fileEntry.is_UNC()) { cout << " - UNC" << endl; } } } return totalFound; } /* * End of file */
|
recls Library documentation © Synesis Software Pty Ltd, 2001-2005 |