Ejemplo n.º 1
0
 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);
            }
        }
Ejemplo n.º 4
0
 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;
 }