public RemotePath[] GetFiles(string path) { RemotePath[] list = RemotePath.FromFTPFileArray(path, DirDetails(path)); int filecount = 0; foreach (RemotePath rpath in list) { if (rpath.IsFile) { filecount++; } } if (filecount==0) { RemotePath[] result = {}; return result; } else { RemotePath[] result = new RemotePath[filecount]; int z=0; foreach(RemotePath rpath in list) { if (rpath.IsFile) { result[z++] = rpath; // result[z].File = rpath.File; // result[z++].Path = rpath.Path; } } return result; } }
/// <summary> /// Given a NAnt search pattern returns a search directory and an regex /// search pattern. /// </summary> /// <param name="isInclude">Whether this pattern is an include or exclude pattern</param> /// <param name="originalNAntPattern">NAnt searh pattern (relative to the Basedirectory OR absolute, relative paths refering to parent directories ( ../ ) also supported)</param> /// <param name="searchDirectory">Out. Absolute canonical path to the directory to be searched</param> /// <param name="recursive">Out. Whether the pattern is potentially recursive or not</param> /// <param name="isRegex">Out. Whether this is a regex pattern or not</param> /// <param name="regexPattern">Out. Regex search pattern (absolute canonical path)</param> /// <history> /// <change date="20020220" author="Ari Hännikäinen">Created</change> /// <change date="20020221" author="Ari Hännikäinen">Returning absolute regex patterns instead of relative nant patterns</change> /// <change date="20030224" author="Brian Deacon (bdeacon at vidya dot com)"> /// Added replacing of slashes with Path.DirectorySeparatorChar to make this OS-agnostic. Also added the Path.IsPathRooted check /// to support absolute pathnames to prevent basedir = "/foo/bar" and pattern="/fudge/nugget" from being incorrectly turned into /// "/foo/bar/fudge/nugget". (pattern = "fudge/nugget" would still be treated as relative to basedir) /// </change> /// </history> private void ParseSearchDirectoryAndPattern(bool isInclude, string originalNAntPattern, out string searchDirectory, out bool recursive, out bool isRegex, out string regexPattern) { string s = originalNAntPattern; s = s.Replace('\\', RPath.DirectorySeparatorChar); s = s.Replace('/', RPath.DirectorySeparatorChar); // Get indices of pieces used for recursive check only int indexOfFirstDirectoryWildcard = s.IndexOf("**"); int indexOfLastOriginalDirectorySeparator = s.LastIndexOf(RPath.DirectorySeparatorChar); // search for the first wildcard character (if any) and exclude the rest of the string beginnning from the character char[] wildcards = {'?', '*'}; int indexOfFirstWildcard = s.IndexOfAny(wildcards); if (indexOfFirstWildcard != -1) { // if found any wildcard characters s = s.Substring(0, indexOfFirstWildcard); } // find the last DirectorySeparatorChar (if any) and exclude the rest of the string int indexOfLastDirectorySeparator = s.LastIndexOf(RPath.DirectorySeparatorChar); // The pattern is potentially recursive if and only if more than one base directory could be matched. // ie: // ** // **/*.txt // foo*/xxx // x/y/z?/www // This condition is true if and only if: // - The first wildcard is before the last directory separator, or // - The pattern contains a directory wildcard ("**") recursive = (indexOfFirstWildcard != -1 && (indexOfFirstWildcard < indexOfLastOriginalDirectorySeparator )) || indexOfFirstDirectoryWildcard != -1; // substring preceding the separator represents our search directory // and the part following it represents nant search pattern relative // to it if (indexOfLastDirectorySeparator != -1) { s = originalNAntPattern.Substring(0, indexOfLastDirectorySeparator); if (s.Length == 2 && s[1] == RPath.VolumeSeparatorChar) { s += RPath.DirectorySeparatorChar; } } else { s = ""; } //We only prepend BaseDirectory when s represents a relative path. if (RPath.IsPathRooted(s)) { searchDirectory = new RemotePath(s, true).FullPath; } else { //We also (correctly) get to this branch of code when s.Length == 0 // Note that I tried setting the base directory of unrooted exclude patterns to "" but this ends up // matching base directories where it shouldn't. // if (isInclude || indexOfFirstWildcard == -1) // // David Alpert ([email protected]) // Wednesday, December 22, 2004 // let's try simplifying this because i keep getting the search directory appended to the base direcotry (i.e. /net/test + test/ does not exist because we're already in test!) // searchDirectory = new RemotePath(RPath.Combine( // BaseDirectory, s), true).FullPath; searchDirectory = s; // else // searchDirectory = String.Empty; if (searchDirectory==String.Empty) { searchDirectory = "."; } } string modifiedNAntPattern = originalNAntPattern.Substring(indexOfLastDirectorySeparator + 1); // if it's not a wildcard, just return if (indexOfFirstWildcard == -1) { regexPattern = CleanPath(BaseDirectory, originalNAntPattern); isRegex = false; #if DEBUG_REGEXES Console.WriteLine( "Convert name: {0} -> {1}", originalNAntPattern, regexPattern ); #endif return; } //if the fs in case insensitive, make all the regex directories lowercase. regexPattern = ToRegexPattern(modifiedNAntPattern); #if DEBUG_REGEXES Console.WriteLine( "Convert pattern: {0} -> [{1}]{2}", originalNAntPattern, searchDirectory, regexPattern ); #endif isRegex = true; }
/// <summary> /// Searches a directory recursively for files and directories matching /// the search criteria. /// </summary> /// <param name="path">Directory in which to search (absolute canonical path)</param> /// <param name="recursive">Whether to scan recursively or not</param> /// <history> /// <change date="20020221" author="Ari Hännikäinen">Checking if the directory has already been scanned</change> /// </history> private void ScanDirectory(string path, bool recursive) { // scan each directory only once if (_scannedDirectories.Contains(path)) { return; } // add directory to list of scanned directories _scannedDirectories.Add(path); // if the path doesn't exist, return. if (!_conn.remoteDirExists(path)) { return; } // get info for the current directory RemotePath currentDir = new RemotePath(path, true); // check whether directory is on case-sensitive volume bool caseSensitive = IsCaseSensitiveFileSystem(path); string pathCompare = path; if (!caseSensitive) pathCompare = pathCompare.ToLower(); CompareOptions compareOptions = CompareOptions.None; CompareInfo compare = CultureInfo.InvariantCulture.CompareInfo; if (!caseSensitive) compareOptions |= CompareOptions.IgnoreCase; ArrayList includedPatterns = new ArrayList(); ArrayList excludedPatterns = new ArrayList(); // Only include the valid patterns for this path foreach (RegexEntry entry in _includePatterns) { string baseDirectory = (caseSensitive ? entry.BaseDirectory : entry.BaseDirectory.ToLower()); // check if the directory being searched is equal to the // basedirectory of the RegexEntry if (compare.Compare(path, baseDirectory, compareOptions) == 0) { includedPatterns.Add(entry); } else { // check if the directory being searched is subdirectory of // basedirectory of RegexEntry if (!entry.IsRecursive) { continue; } // make sure basedirectory ends with directory separator if (!StringUtils.EndsWith(baseDirectory, RPath.DirectorySeparatorChar)) { baseDirectory += RPath.DirectorySeparatorChar; } if (pathCompare.StartsWith(baseDirectory)) { includedPatterns.Add(entry); } } } foreach (RegexEntry entry in _excludePatterns) { string baseDirectory = (caseSensitive ? entry.BaseDirectory : entry.BaseDirectory.ToLower()); if (entry.BaseDirectory.Length == 0 || compare.Compare(path, baseDirectory, compareOptions) == 0) { excludedPatterns.Add(entry); } else { // check if the directory being searched is subdirectory of // basedirectory of RegexEntry if (!entry.IsRecursive) { continue; } // make sure basedirectory ends with directory separator if (!StringUtils.EndsWith(baseDirectory, RPath.DirectorySeparatorChar)) { baseDirectory += RPath.DirectorySeparatorChar; } if (pathCompare.StartsWith(baseDirectory)) { excludedPatterns.Add(entry); } } } // grab the directory listing and sort into dirs and files // // int dirCount = 0; // int fileCount = 0; RemotePath[] list = RemotePath.FromFTPFileArray(path, _conn.Connection.DirDetails(path)); //foreach (RemotePath dir in _conn.GetDirs(currentDir.FullPath)) foreach (RemotePath dir in list) { if (dir.IsDir) { if (recursive) { // scan subfolders if we are running recursively ScanDirectory(dir.FullPath, true); } else { // otherwise just test to see if the subdirectories are included if (IsPathIncluded(dir.FullPath, caseSensitive, includedPatterns, excludedPatterns)) { _directoryNames.Add(dir.FullPath); } } } } // scan files //foreach (RemotePath file in _conn.GetFiles(currentDir.FullPath)) { foreach (RemotePath file in list) { if (file.IsFile) { string filename = file.FullPath; if (!caseSensitive) filename = filename.ToLower(); if (IsPathIncluded(filename, caseSensitive, includedPatterns, excludedPatterns)) { _conn.Log(_conn.LevelExec, " + -- including {0}", file.FullPath); _fileNames.Add(file); } } } // check current path last so that delete task will correctly // delete empty directories. This may *seem* like a special case // but it is more like formalizing something in a way that makes // writing the delete task easier :) if (IsPathIncluded(currentDir.FullPath, caseSensitive, includedPatterns, excludedPatterns)) { _directoryNames.Add(currentDir.Path); } }
public static RemotePath[] FromFTPFileArray(string basepath, FTPFile[] files) { RemotePath[] result = new RemotePath[files.GetUpperBound(0)+1]; int z = 0; foreach(FTPFile file in files) { result[z] = new RemotePath(file); result[z++].Path = basepath; // result[z++].File = file; } return result; }