internal FTPDirectoryListEventArgs(string dirPath, FTPFile[] files)
 {
     this.dirPath = null;
     this.files = null;
     this.dirPath = dirPath;
     this.files = files;
 }
Exemple #2
0
        //public FtpFileInfo(EnterpriseDT.Net.Ftp.FTPFile file)
        //{
        //    this.IsDirectory = file.isDir;
        //    this.IsFile = !this.IsDirectory;
        //    this.Size = file.Size;
        //    this.Name = file.Name;
        //    this.FullName = file.Path.TrimStart('/');
        //    this.LastModifiedTime = file.LastModified;
        //}

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="file"></param>
        /// <param name="path"></param>
        public FtpFileInfo(EnterpriseDT.Net.Ftp.FTPFile file, string path)
        {
            this.IsDirectory      = file.Dir;
            this.IsFile           = !this.IsDirectory;
            this.Size             = file.Size;
            this.Name             = file.Name;
            this.FullName         = (path.TrimEnd('/') + "/" + file.Name).TrimStart('/');//file.Path.TrimStart('/');
            this.LastModifiedTime = file.LastModified;
        }
        public virtual FTPFile[] Parse(string[] fileStrings)
        {
            this.log.Debug("Parse() called using culture: " + this.parserCulture.EnglishName);
            FTPFile[] sourceArray = new FTPFile[fileStrings.Length];
            if (fileStrings.Length == 0)
            {
                return(sourceArray);
            }
            if (!this.userSetParser && !this.parserDetected)
            {
                this.DetectParser(fileStrings);
            }
            int length = 0;

            for (int i = 0; i < fileStrings.Length; i++)
            {
                if ((fileStrings[i] != null) && (fileStrings[i].Trim().Length != 0))
                {
                    try
                    {
                        FTPFile file = null;
                        if (this.parser.IsMultiLine())
                        {
                            StringBuilder builder = new StringBuilder(fileStrings[i]);
                            while (((i + 1) < fileStrings.Length) && (fileStrings[i + 1].IndexOf(';') < 0))
                            {
                                builder.Append(" ").Append(fileStrings[i + 1]);
                                i++;
                            }
                            file = this.parser.Parse(builder.ToString());
                        }
                        else
                        {
                            file = this.parser.Parse(fileStrings[i]);
                        }
                        if (file != null)
                        {
                            if (this.timeDiff.Ticks != 0L)
                            {
                                file.ApplyTimeDifference(this.timeDiff);
                            }
                            sourceArray[length++] = file;
                        }
                    }
                    catch (RestartParsingException)
                    {
                        this.log.Debug("Restarting parsing from first entry in list");
                        i      = -1;
                        length = 0;
                    }
                }
            }
            FTPFile[] destinationArray = new FTPFile[length];
            Array.Copy(sourceArray, 0, destinationArray, 0, length);
            return(destinationArray);
        }
        /// <summary> Parse server supplied string</summary>
        /// <param name="raw">raw string to parse</param>
        /// <returns>FTPFile object representing the raw string</returns>
        /// <remarks>Listing look like the below:
        ///        CFT             45056 04/12/06 14:19:31 *FILE AFTFRE1.FILE
        ///        CFT                                     *MEM AFTFRE1.FILE/AFTFRE1.MBR
        ///        CFT             36864 28/11/06 15:19:30 *FILE AFTFRE2.FILE
        ///        CFT                                     *MEM AFTFRE2.FILE/AFTFRE2.MBR
        ///        CFT             45056 04/12/06 14:19:37 *FILE AFTFRE6.FILE
        ///        CFT                                     *MEM  AFTFRE6.FILE/AFTFRE6.MBR
        ///        QSYSOPR         28672 01/12/06 20:08:04 *FILE FPKI45POK5.FILE
        ///        QSYSOPR                                 *MEM FPKI45POK5.FILE/FPKI45POK5.MBR
        /// </remarks>
        public override FTPFile Parse(string raw)
        {
            string[] fields = StringSplitter.Split(raw);

            // skip blank lines
            if (fields.Length <= 0)
            {
                return(null);
            }
            // return what we can for MEM
            if (fields.Length >= 2 && fields[1].Equals(MEM))
            {
                DateTime lastModifiedm = DateTime.MinValue;
                string   ownerm        = fields[0];
                string   namem         = fields[2];
                FTPFile  filem         = new FTPFile(FTPFile.OS400, raw, namem, 0, false, ref lastModifiedm);
                filem.Owner = ownerm;
                return(filem);
            }
            if (fields.Length < MIN_EXPECTED_FIELD_COUNT)
            {
                return(null);
            }

            // first field is owner
            string owner = fields[0];

            // next is size
            long size = Int64.Parse(fields[1]);

            string   lastModifiedStr = fields[2] + " " + fields[3];
            DateTime lastModified    = GetLastModified(lastModifiedStr);

            // test is dir
            bool isDir = false;

            if (fields[4] == DIR || fields[4] == DDIR)
            {
                isDir = true;
            }

            string name = fields[5];

            if (name.EndsWith("/"))
            {
                isDir = true;
                name  = name.Substring(0, name.Length - 1);
            }

            FTPFile file = new FTPFile(FTPFile.OS400, raw, name, size, isDir, ref lastModified);

            file.Owner = owner;
            return(file);
        }
Exemple #5
0
        /// <summary> Parse server supplied string. Should be in
        /// form
        /// <![CDATA[
        /// File         Code             EOF  Last Modification    Owner  RWEP
        /// IARPTS        101            16354 18-Mar-08 15:09:12 244, 10 "nnnn"
        /// JENNYCB2      101            16384 10-Jul-08 11:44:56 244, 10 "nnnn"
        /// ]]>
        /// </summary>
        /// <param name="raw">
        /// raw string to parse
        /// </param>
        public override FTPFile Parse(string raw)
        {
            if (IsHeader(raw))
            {
                return(null);
            }

            string[] fields = StringSplitter.Split(raw);

            if (fields.Length < MIN_EXPECTED_FIELD_COUNT)
            {
                return(null);
            }

            string name = fields[0];

            // first two fields are date time
            string   lastModifiedStr = fields[3] + " " + fields[4];
            DateTime lastModified    = DateTime.MinValue;

            try
            {
                lastModified = DateTime.ParseExact(lastModifiedStr, formats,
                                                   ParsingCulture.DateTimeFormat, DateTimeStyles.None);
            }
            catch (FormatException)
            {
                log.Warn("Failed to parse date string '" + lastModifiedStr + "'");
            }

            // dir flag
            bool isDir = false;
            long size  = 0L;

            try
            {
                size = Int64.Parse(fields[2]);
            }
            catch (FormatException)
            {
                log.Warn("Failed to parse size: " + fields[2]);
            }

            string owner       = fields[5] + fields[6];
            string permissions = fields[7].Trim(trimChars);

            FTPFile file = new FTPFile(FTPFile.UNKNOWN, raw, name, size, isDir, ref lastModified);

            file.Owner       = owner;
            file.Permissions = permissions;
            return(file);
        }
 //        public RemotePath() {
 //        }
 public RemotePath(string path, bool isDir)
 {
     int sep = path.LastIndexOf(DIR_SEP);
     // store the head of the path in an FTPFile
     _file = new FTPFile(FTPFile.UNKNOWN, path.Substring(sep+1), isDir);
     // store the tail (if any) in a string
     if (sep>0) {
         _path = path.Substring(0,sep);
         if (_path==".") {
             _path=String.Empty;
         } else if (_path.Length>2 && _path[1]==DIR_SEP) {
             _path=_path.Substring(2);
         }
     }
 }
Exemple #7
0
        /// <summary> Parse an array of raw file information returned from the
        /// FTP server
        ///
        /// </summary>
        /// <param name="files">    array of strings
        /// </param>
        /// <returns> array of FTPFile objects
        /// </returns>
        internal virtual FTPFile[] Parse(string[] files)
        {
            FTPFile[] temp = new FTPFile[files.Length];

            // quick check if no files returned
            if (files.Length == 0)
            {
                return(temp);
            }

            int count = 0;

            for (int i = 0; i < files.Length; i++)
            {
                try
                {
                    FTPFile file = parser.Parse(files[i]);
                    // we skip null returns - these are duff lines we know about and don't
                    // really want to throw an exception
                    if (file != null)
                    {
                        temp[count++] = file;
                    }
                }
                catch (FormatException ex)
                {
                    log.Debug(ex.Message);
                    if (rotateParsersOnFail && count == 0)
                    {
                        // first error, let's try swapping parsers
                        RotateParsers();
                        FTPFile file = parser.Parse(files[i]);
                        if (file != null)
                        {
                            temp[count++] = file;
                        }
                    }
                    // rethrow
                    else
                    {
                        throw ex;
                    }
                }
            }
            FTPFile[] result = new FTPFile[count];
            Array.Copy(temp, 0, result, 0, count);
            return(result);
        }
Exemple #8
0
        private void FixPaths(FTPFile[] result, string path, string lastPart)
        {
            // add the last part of the supplied dirname to the path if 
            // If there is more than one result returned the last part of
            // the supplied dirname must be a wildcard or directory name
            if (result.Length > 1)
            {
                if (lastPart.Length > 0 && lastPart.IndexOf('*') < 0 && lastPart.IndexOf('?') < 0)
                {
                    // must have been a directory so add to path
                    path = PathUtil.Combine(path, lastPart);
                }
            }
            else if (result.Length == 1)
            {
                // if the one result returned *isn't* the same as the last part of supplied dirname,
                // then the last part can be added to the path
                if (result[0].Name != lastPart)
                {
                    path = PathUtil.Combine(path, lastPart);
                }
                // if the one result returned is the same, and it happens to be a file of the same
                // name, that's too bad, we'll get it wrong (e.g.  /abc/efg.txt/efg.txt)
            }

            for (int i = 0; i < result.Length; i++)
                result[i].Path = path + (path.EndsWith("/") ? "" : "/") + result[i].Name;
        }
 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;
 }
Exemple #10
0
		/// <summary> Parse server supplied string. Should be in
		/// form 
		/// <![CDATA[
		/// File         Code             EOF  Last Modification    Owner  RWEP
        /// IARPTS        101            16354 18-Mar-08 15:09:12 244, 10 "nnnn"
        /// JENNYCB2      101            16384 10-Jul-08 11:44:56 244, 10 "nnnn"
		/// ]]>
		/// </summary>
		/// <param name="raw">  
		/// raw string to parse
		/// </param>
		public override FTPFile Parse(string raw)
		{
            if (IsHeader(raw))
                return null;

            string[] fields = StringSplitter.Split(raw);

            if (fields.Length < MIN_EXPECTED_FIELD_COUNT)
                return null;

            string name = fields[0];
			
			// first two fields are date time
            string lastModifiedStr = fields[3] + " " + fields[4];
            DateTime lastModified = DateTime.MinValue;
            try
            {
                lastModified = DateTime.ParseExact(lastModifiedStr, formats,
                                    ParsingCulture.DateTimeFormat, DateTimeStyles.None);
            }
            catch (FormatException)
            {
                log.Warn("Failed to parse date string '" + lastModifiedStr + "'");
            }

			// dir flag
			bool isDir = false;
			long size = 0L;
			try
			{
				size = Int64.Parse(fields[2]);
			}
			catch (FormatException)
			{
				log.Warn("Failed to parse size: " + fields[2]);
			}

            string owner = fields[5] + fields[6];
            string permissions = fields[7].Trim(trimChars);

            FTPFile file = new FTPFile(FTPFile.UNKNOWN, raw, name, size, isDir, ref lastModified);
            file.Owner = owner;
            file.Permissions = permissions;
            return file;
		}
        /// <summary>
        /// Parse server supplied string, e.g.:
        ///
        /// -r-------- GMETECHNOLOGY 1 TSI         8 Nov 06 11:00:25 ,GMETECHNOLOGY,file02.csv,U,20071106A00001105190.txt
        ///
        /// </summary>
        /// <param name="raw">  raw string to parse
        /// </param>
        public override FTPFile Parse(string raw)
        {
            // test it is a valid line, e.g. "total 342522" is invalid
            char ch = raw[0];

            if (ch != ORDINARY_FILE_CHAR && ch != DIRECTORY_CHAR && ch != SYMLINK_CHAR)
            {
                return(null);
            }

            string[] fields = StringSplitter.Split(raw);

            if (fields.Length < MIN_FIELD_COUNT)
            {
                StringBuilder listing = new StringBuilder("Unexpected number of fields in listing '");
                listing.Append(raw).Append("' - expected minimum ").Append(MIN_FIELD_COUNT).
                Append(" fields but found ").Append(fields.Length).Append(" fields");
                throw new FormatException(listing.ToString());
            }

            // field pos
            int index = 0;

            // first field is perms
            string permissions = fields[index++];

            ch = permissions[0];
            bool isDir  = false;
            bool isLink = false;

            if (ch == DIRECTORY_CHAR)
            {
                isDir = true;
            }
            else if (ch == SYMLINK_CHAR)
            {
                isLink = true;
            }

            string group = fields[index++];

            // some servers don't supply the link count
            int linkCount = 0;

            if (Char.IsDigit(fields[index][0])) // assume it is if a digit
            {
                string linkCountStr = fields[index++];
                try
                {
                    linkCount = System.Int32.Parse(linkCountStr);
                }
                catch (FormatException)
                {
                    log.Warn("Failed to parse link count: " + linkCountStr);
                }
            }

            string owner = fields[index++];


            // size
            long   size    = 0L;
            string sizeStr = fields[index++];

            try
            {
                size = Int64.Parse(sizeStr);
            }
            catch (FormatException)
            {
                log.Warn("Failed to parse size: " + sizeStr);
            }

            // next 3 fields are the date time

            // we expect the month first on Unix.
            int           dateTimePos  = index;
            DateTime      lastModified = DateTime.MinValue;
            StringBuilder stamp        = new StringBuilder(fields[index++]);

            stamp.Append('-').Append(fields[index++]).Append('-');

            string field = fields[index++];

            if (field.IndexOf((System.Char) ':') < 0)
            {
                stamp.Append(field);                 // year
                try
                {
                    lastModified = DateTime.ParseExact(stamp.ToString(), format1,
                                                       ParsingCulture.DateTimeFormat, DateTimeStyles.None);
                }
                catch (FormatException)
                {
                    log.Warn("Failed to parse date string '" + stamp.ToString() + "'");
                }
            }
            else
            {
                // add the year ourselves as not present
                int year = ParsingCulture.Calendar.GetYear(DateTime.Now);
                stamp.Append(year).Append('-').Append(field);
                try
                {
                    lastModified = DateTime.ParseExact(stamp.ToString(), format2,
                                                       ParsingCulture.DateTimeFormat, DateTimeStyles.None);
                }
                catch (FormatException)
                {
                    log.Warn("Failed to parse date string '" + stamp.ToString() + "'");
                }

                // can't be in the future - must be the previous year
                // add 2 days for time zones (thanks hgfischer)
                if (lastModified > DateTime.Now.AddDays(2))
                {
                    lastModified = lastModified.AddYears(-1);
                }
            }

            // name of file or dir. Extract symlink if possible
            string name = null;

            // we've got to find the starting point of the name. We
            // do this by finding the pos of all the date/time fields, then
            // the name - to ensure we don't get tricked up by a userid the
            // same as the filename,for example
            int  pos = 0;
            bool ok  = true;

            for (int i = dateTimePos; i < dateTimePos + 3; i++)
            {
                pos = raw.IndexOf(fields[i], pos);
                if (pos < 0)
                {
                    ok = false;
                    break;
                }
                else
                {
                    pos += fields[i].Length;
                }
            }
            if (ok)
            {
                name = raw.Substring(pos).Trim();
            }
            else
            {
                log.Warn("Failed to retrieve name: " + raw);
            }

            FTPFile file = new FTPFile(FTPFile.UNIX, raw, name, size, isDir, ref lastModified);

            file.Group       = group;
            file.Owner       = owner;
            file.Link        = isLink;
            file.LinkCount   = linkCount;
            file.Permissions = permissions;
            return(file);
        }
Exemple #12
0
		/// <summary>
        /// Parse an array of raw file information returned from the
		/// FTP server
		/// </summary>
        /// <param name="fileStrings">    array of strings
		/// </param>
		/// <returns> array of FTPFile objects
		/// </returns>
		public virtual FTPFile[] Parse(string[] fileStrings)
		{			
            log.Debug("Parse() called using culture: " + parserCulture.EnglishName);
			FTPFile[] files = new FTPFile[fileStrings.Length];
			
			// quick check if no files returned
			if (fileStrings.Length == 0)
				return files;

            if (!userSetParser && !parserDetected)
                DetectParser(fileStrings);

			int count = 0;
			for (int i = 0; i < fileStrings.Length; i++)
			{
                if (fileStrings[i] == null || fileStrings[i].Trim().Length == 0)
                    continue;

                try
                {               
                    FTPFile file = null;
                    if (parser.IsMultiLine()) 
                    {
                        // vms uses more than 1 line for some file listings. We must keep going
                        // thru till we've got everything
                        StringBuilder filename = new StringBuilder(fileStrings[i]);
                        while (i+1 < fileStrings.Length && fileStrings[i+1].IndexOf(';') < 0) 
                        {
                            filename.Append(" ").Append(fileStrings[i+1]);
                            i++;
                        }
                        file = parser.Parse(filename.ToString());
                    }
                    else 
                    {
                        file = parser.Parse(fileStrings[i]);
                    }                
				
                    // we skip null returns - these are duff lines we know about and don't
                    // really want to throw an exception
                    if (file != null)
                    {
                        if (timeDiff.Ticks != 0)
                            file.ApplyTimeDifference(timeDiff);
                        files[count++] = file;
                    }
                }
                catch (RestartParsingException)
                {
                    log.Debug("Restarting parsing from first entry in list");
                    i = -1;
                    count = 0;
                    continue;
                }
			}
			FTPFile[] result = new FTPFile[count];
			Array.Copy(files, 0, result, 0, count);
			return result;
		}
        /// <summary> Parse an array of raw file information returned from the
        /// FTP server
        /// 
        /// </summary>
        /// <param name="files">    array of strings
        /// </param>
        /// <returns> array of FTPFile objects
        /// </returns>
        internal virtual FTPFile[] Parse(string[] files)
        {
            FTPFile[] temp = new FTPFile[files.Length];

            // quick check if no files returned
            if (files.Length == 0)
                return temp;

            int count = 0;
            for (int i = 0; i < files.Length; i++)
            {
                try
                {
                    FTPFile file = parser.Parse(files[i]);
                    // we skip null returns - these are duff lines we know about and don't
                    // really want to throw an exception
                    if (file != null)
                    {
                        temp[count++] = file;
                    }
                }
                catch (FormatException ex)
                {
                    log.Debug(ex.Message);
                    if (rotateParsersOnFail && count == 0)
                    {
                        // first error, let's try swapping parsers
                        RotateParsers();
                        FTPFile file = parser.Parse(files[i]);
                        if (file != null)
                            temp[count++] = file;
                    }
                    // rethrow
                    else
                        throw ex;
                }
            }
            FTPFile[] result = new FTPFile[count];
            Array.Copy(temp, 0, result, 0, count);
            return result;
        }
        public virtual FTPFile PartialParse(string fileString, ArrayList allFileStrings)
        {
            if (allFileStrings.Count == 1)
            {
                log.Debug("PartialParse() called using culture: " + parserCulture.EnglishName);
            }

            bool isLastLine = fileString == null;

            if (!userSetParser && !parserDetected)
            {
                DetectParser((string[])allFileStrings.ToArray(typeof(string)));
            }

            if (!userSetParser && !parserDetected)
            {
                return(null);
            }

            if (fileString == null || fileString.Trim().Length == 0)
            {
                return(null);
            }

            try
            {
                FTPFile file = null;
                if (parser.IsMultiLine())
                {
                    // vms uses more than 1 line for some file listings. We must keep going
                    // thru till we've got everything
                    if (!isLastLine)
                    {
                        if (allFileStrings.Count < 2)
                        {
                            return(null);
                        }

                        string secondLastFileString = (string)allFileStrings[allFileStrings.Count - 2];
                        string lastFileString       = (string)allFileStrings[allFileStrings.Count - 1];

                        if (lastFileString.IndexOf(';') < 0)
                        {
                            secondLastFileString += lastFileString;
                        }

                        file = parser.Parse(secondLastFileString);
                    }
                    else
                    {
                        if (allFileStrings.Count == 0)
                        {
                            return(null);
                        }
                        else
                        {
                            file = parser.Parse(allFileStrings[allFileStrings.Count - 1].ToString());
                        }
                    }
                }
                else
                {
                    file = parser.Parse(fileString);
                }

                // we skip null returns - these are duff lines we know about and don't
                // really want to throw an exception
                if (file != null)
                {
                    if (timeDiff.Ticks != 0)
                    {
                        file.ApplyTimeDifference(timeDiff);
                    }
                    return(file);
                }
                else
                {
                    return(null);
                }
            }
            catch (RestartParsingException)
            {
                throw;
            }
        }
 //public List<FileInfo> GetLocalFiles()
 //{
 //    string[] filePaths = Directory.GetFiles(localRootDir);
 //    List<FileInfo> fileList = new List<FileInfo>();
 //    foreach (string filePath in filePaths)
 //    {
 //        LocalFile file = new LocalFile();
 //        FileInfo fileInfo = new FileInfo(filePath);
 //        fileList.Add(fileInfo);
 //    }
 //    return fileList;
 //}
 public bool compareTimes(FTPFile ftpFile, FileInfo localFile)
 {
     DateTime localTime = localFile.LastWriteTime;
     DateTime ftpTime = ftpFile.LastModified;
     return (localTime < ftpTime);
 }
Exemple #16
0
 public RemotePath(FTPFile file)
 {
     _file = file;
     _path = String.Empty;
 }
Exemple #17
0
 internal FTPDirectoryListEventArgs(string dirPath, FTPFile[] files, Exception ex)
 {
     this.dirPath = dirPath;
     this.files = files;
     this.ex = ex;
 }
Exemple #18
0
 /// <summary>
 /// Called when a directory listing has been retrieved.
 /// </summary>
 /// <param name="files">File-details.</param>
 /// <param name="dir">Directory name</param>
 /// <param name="ex">Exception thrown (if failed)</param>
 protected virtual void OnDirectoryListed(string dir, FTPFile[] files, Exception ex)
 {
     if (areEventsEnabled && DirectoryListed != null)
     {
         if (!PathUtil.IsAbsolute(dir))
             dir = PathUtil.Combine(ServerDirectory, dir);
         RaiseDirectoryListed(new FTPDirectoryListEventArgs(dir, files, ex));
     }
 }
Exemple #19
0
 /// <summary>
 /// Returns the given directory's contents as an array of <see cref="FTPFile"/> objects.
 /// </summary>
 /// <remarks>
 /// This method works for Windows and most Unix FTP servers.  Please inform EDT
 /// about unusual formats (<a href="*****@*****.**">[email protected]</a>).
 /// </remarks>
 /// <param name="directory">Name of directory AND/OR filemask.</param>
 /// <param name="dirListCallback">Callback to notify for each listing item</param>
 /// <returns>An array of <see cref="FTPFile"/> objects.</returns>
 public virtual FTPFile[] GetFileInfos(string directory, FTPFileCallback dirListCallback)
 {
     log.Debug("GetFileInfos('" + directory + ")");
     lock (clientLock)
     {
         FTPFile[] files = null;
         Exception ex = null;
         try
         {
             OnDirectoryListing(directory);
             isTransferringData = true;
             files = ActiveClient.DirDetails(directory, dirListCallback);
             if (files == null)
                 files = new FTPFile[0];
         }
         catch (Exception e)
         {
             ex = e;
             throw;
         }
         finally
         {
             isTransferringData = false;
             OnDirectoryListed(directory, files, ex);
         }
         return files;
     }
 }
Exemple #20
0
        /// <summary>
        /// Parse server supplied string, e.g.:
        ///
        /// lrwxrwxrwx   1 wuftpd   wuftpd         14 Jul 22  2002 MIRRORS -> README-MIRRORS
        /// -rw-r--r--   1 b173771  users         431 Mar 31 20:04 .htaccess
        ///
        /// </summary>
        /// <param name="raw">  raw string to parse
        /// </param>
        public override FTPFile Parse(string raw)
        {
            // test it is a valid line, e.g. "total 342522" is invalid
            char ch = raw[0];

            if (ch != ORDINARY_FILE_CHAR && ch != DIRECTORY_CHAR && ch != SYMLINK_CHAR)
            {
                return(null);
            }

            string[] fields = Split(raw);

            if (fields.Length < MIN_FIELD_COUNT)
            {
                StringBuilder listing = new StringBuilder("Unexpected number of fields in listing '");
                listing.Append(raw).Append("' - expected minimum ").Append(MIN_FIELD_COUNT).
                Append(" fields but found ").Append(fields.Length).Append(" fields");
                throw new FormatException(listing.ToString());
            }

            // field pos
            int index = 0;

            // first field is perms
            string permissions = fields[index++];

            ch = permissions[0];
            bool isDir  = false;
            bool isLink = false;

            if (ch == DIRECTORY_CHAR)
            {
                isDir = true;
            }
            else if (ch == SYMLINK_CHAR)
            {
                isLink = true;
            }

            // some servers don't supply the link count
            int linkCount = 0;

            if (fields.Length > MIN_FIELD_COUNT)
            {
                try
                {
                    linkCount = System.Int32.Parse(fields[index++]);
                }
                catch (FormatException)
                {
                }
            }

            // owner and group
            string owner = fields[index++];
            string group = fields[index++];

            // size
            long   size    = 0L;
            string sizeStr = fields[index++];

            try
            {
                size = Int64.Parse(sizeStr);
            }
            catch (FormatException)
            {
                throw new FormatException("Failed to parse size: " + sizeStr);
            }

            // next 3 are the date time
            int dateTimePos = index;

            System.DateTime           lastModified;
            System.Text.StringBuilder stamp = new System.Text.StringBuilder(fields[index++]);
            stamp.Append('-').Append(fields[index++]).Append('-');

            string field = fields[index++];

            if (field.IndexOf((System.Char) ':') < 0)
            {
                stamp.Append(field);                 // year
                lastModified = DateTime.ParseExact(stamp.ToString(), format1,
                                                   CultureInfo.CurrentCulture.DateTimeFormat, DateTimeStyles.None);
            }
            else
            {
                // add the year ourselves as not present
                int year = CultureInfo.CurrentCulture.Calendar.GetYear(DateTime.Now);
                stamp.Append(year).Append('-').Append(field);
                lastModified = DateTime.ParseExact(stamp.ToString(), format2,
                                                   CultureInfo.CurrentCulture.DateTimeFormat, DateTimeStyles.None);

                // can't be in the future - must be the previous year
                if (lastModified > DateTime.Now)
                {
                    lastModified.AddYears(-1);
                }
            }

            // name of file or dir. Extract symlink if possible
            string name       = null;
            string linkedname = null;

            // we've got to find the starting point of the name. We
            // do this by finding the pos of all the date/time fields, then
            // the name - to ensure we don't get tricked up by a userid the
            // same as the filename,for example
            int  pos = 0;
            bool ok  = true;

            for (int i = dateTimePos; i < dateTimePos + 3; i++)
            {
                pos = raw.IndexOf(fields[i], pos);
                if (pos < 0)
                {
                    ok = false;
                    break;
                }
                else
                {
                    pos += fields[i].Length;
                }
            }
            if (ok)
            {
                string remainder = raw.Substring(pos).Trim();
                if (!isLink)
                {
                    name = remainder;
                }
                else
                {
                    // symlink, try to extract it
                    pos = remainder.IndexOf(SYMLINK_ARROW);
                    if (pos <= 0)
                    {
                        // couldn't find symlink, give up & just assign as name
                        name = remainder;
                    }
                    else
                    {
                        int len = SYMLINK_ARROW.Length;
                        name = remainder.Substring(0, (pos) - (0)).Trim();
                        if (pos + len < remainder.Length)
                        {
                            linkedname = remainder.Substring(pos + len);
                        }
                    }
                }
            }
            else
            {
                throw new FormatException("Failed to retrieve name: " + raw);
            }

            FTPFile file = new FTPFile(FTPFile.UNIX, raw, name, size, isDir, ref lastModified);

            file.Group       = group;
            file.Owner       = owner;
            file.Link        = isLink;
            file.LinkCount   = linkCount;
            file.LinkedName  = linkedname;
            file.Permissions = permissions;
            return(file);
        }
Exemple #21
0
 public virtual FTPFile[] GetFileInfos(string directory)
 {
     lock (this.clientLock)
     {
         FTPFile[] files = null;
         try
         {
             this.OnDirectoryListing(directory);
             this.isTransferringData = true;
             files = this.ActiveClient.DirDetails(directory);
             if (files == null)
             {
                 files = new FTPFile[0];
             }
         }
         finally
         {
             this.isTransferringData = false;
             this.OnDirectoryListed(directory, files);
         }
         return files;
     }
 }
Exemple #22
0
 protected virtual void OnDirectoryListed(string dir, FTPFile[] files)
 {
     if (this.areEventsEnabled && (this.DirectoryListed != null))
     {
         if (!PathUtil.IsAbsolute(dir))
         {
             dir = PathUtil.Combine(this.ServerDirectory, dir);
         }
         this.RaiseDirectoryListed(new FTPDirectoryListEventArgs(dir, files));
     }
 }
        /// <summary> 
        /// Parse server supplied string, e.g.:
        /// 
        /// lrwxrwxrwx   1 wuftpd   wuftpd         14 Jul 22  2002 MIRRORS -> README-MIRRORS
        /// -rw-r--r--   1 b173771  users         431 Mar 31 20:04 .htaccess
        /// 
        /// </summary>
        /// <param name="raw">  raw string to parse
        /// </param>
        public override FTPFile Parse(string raw)
        {
            // test it is a valid line, e.g. "total 342522" is invalid
            char ch = raw[0];
            if (ch != ORDINARY_FILE_CHAR && ch != DIRECTORY_CHAR && ch != SYMLINK_CHAR)
                return null;

            string[] fields = Split(raw);

            if (fields.Length < MIN_FIELD_COUNT)
            {
                StringBuilder listing = new StringBuilder("Unexpected number of fields in listing '");
                listing.Append(raw).Append("' - expected minimum ").Append(MIN_FIELD_COUNT).
                        Append(" fields but found ").Append(fields.Length).Append(" fields");
                throw new FormatException(listing.ToString());
            }

            // field pos
            int index = 0;

            // first field is perms
            string permissions = fields[index++];
            ch = permissions[0];
            bool isDir = false;
            bool isLink = false;
            if (ch == DIRECTORY_CHAR)
                isDir = true;
            else if (ch == SYMLINK_CHAR)
                isLink = true;

            // some servers don't supply the link count
            int linkCount = 0;
            if (fields.Length > MIN_FIELD_COUNT)
            {
                try
                {
                    linkCount = System.Int32.Parse(fields[index++]);
                }
                catch (FormatException)
                {
                }
            }

            // owner and group
            string owner = fields[index++];
            string group = fields[index++];

            // size
            long size = 0L;
            string sizeStr = fields[index++];
            try
            {
                size = Int64.Parse(sizeStr);
            }
            catch (FormatException)
            {
                throw new FormatException("Failed to parse size: " + sizeStr);
            }

            // next 3 are the date time
            int dateTimePos = index;
            System.DateTime lastModified;
            System.Text.StringBuilder stamp = new System.Text.StringBuilder(fields[index++]);
            stamp.Append('-').Append(fields[index++]).Append('-');

            string field = fields[index++];
            if (field.IndexOf((System.Char) ':') < 0)
            {
                stamp.Append(field); // year
                lastModified = DateTime.ParseExact(stamp.ToString(), format1,
                    CultureInfo.CurrentCulture.DateTimeFormat, DateTimeStyles.None);
            }
            else
            {
                // add the year ourselves as not present
                int year = CultureInfo.CurrentCulture.Calendar.GetYear(DateTime.Now);
                stamp.Append(year).Append('-').Append(field);
                lastModified = DateTime.ParseExact(stamp.ToString(), format2,
                    CultureInfo.CurrentCulture.DateTimeFormat, DateTimeStyles.None);

                // can't be in the future - must be the previous year
                if (lastModified > DateTime.Now)
                {
                    lastModified.AddYears(-1);
                }
            }

            // name of file or dir. Extract symlink if possible
            string name = null;
            string linkedname = null;

            // we've got to find the starting point of the name. We
            // do this by finding the pos of all the date/time fields, then
            // the name - to ensure we don't get tricked up by a userid the
            // same as the filename,for example
            int pos = 0;
            bool ok = true;
            for (int i = dateTimePos; i < dateTimePos + 3; i++)
            {
                pos = raw.IndexOf(fields[i], pos);
                if (pos < 0)
                {
                    ok = false;
                    break;
                }
                else {
                    pos += fields[i].Length;
                }
            }
            if (ok)
            {
                string remainder = raw.Substring(pos).Trim();
                if (!isLink)
                    name = remainder;
                else
                {
                    // symlink, try to extract it
                    pos = remainder.IndexOf(SYMLINK_ARROW);
                    if (pos <= 0)
                    {
                        // couldn't find symlink, give up & just assign as name
                        name = remainder;
                    }
                    else
                    {
                        int len = SYMLINK_ARROW.Length;
                        name = remainder.Substring(0, (pos) - (0)).Trim();
                        if (pos + len < remainder.Length)
                            linkedname = remainder.Substring(pos + len);
                    }
                }
            }
            else
            {
                throw new FormatException("Failed to retrieve name: " + raw);
            }

            FTPFile file = new FTPFile(FTPFile.UNIX, raw, name, size, isDir, ref lastModified);
            file.Group = group;
            file.Owner = owner;
            file.Link = isLink;
            file.LinkCount = linkCount;
            file.LinkedName = linkedname;
            file.Permissions = permissions;
            return file;
        }
Exemple #24
0
        /// <summary> Parse server supplied string</summary>
        /// <param name="raw">raw string to parse</param>
        /// <returns>FTPFile object representing the raw string</returns>
        /// <remarks>Listing look like the below:
        ///  OUTPUT: 
        ///    
        ///    Directory dirname
        ///     
        ///    filename
        ///            used/allocated    dd-MMM-yyyy HH:mm:ss [group,owner]        (PERMS)
        ///    filename
        ///            used/allocated    dd-MMM-yyyy HH:mm:ss [group,owner]        (PERMS)
        ///    ...
        ///    
        ///    Total of n files, n/m blocks
        /// </remarks>
        public override FTPFile Parse(string raw) 
        {
            string[] fields = StringSplitter.Split(raw);      
            
            // skip blank lines
            if(fields.Length <= 0)
                return null;
            // skip line which lists Directory
            if (fields.Length >= 2 && fields[0].Equals(HDR))
                return null;
            // skip line which lists Total
            if (fields.Length > 0 && fields[0].Equals(TOTAL))
                return null;
            if (fields.Length < MIN_EXPECTED_FIELD_COUNT)
                return null;
            
            // first field is name
            string name = fields[0];
            
            // make sure it is the name (ends with ';<INT>')
            int semiPos = name.LastIndexOf(';');
            // check for ;
            if(semiPos <= 0) 
            {
                log.Warn("File version number not found in name '" + name + "'");
                return null;
            }

            string nameNoVersion = name.Substring(0, semiPos);
            
            // check for version after ;
            string afterSemi = fields[0].Substring(semiPos+1);
            try
            {
                Int64.Parse(afterSemi);
                // didn't throw exception yet, must be number
                // we don't use it currently but we might in future
            }
            catch(FormatException) 
            {
                // don't worry about version number
            }

            // test is dir
            bool isDir = false;
            if (nameNoVersion.EndsWith(DIR)) 
            {
                isDir = true;
                name = nameNoVersion.Substring(0, nameNoVersion.Length-DIR.Length);
            }
            
            if (!versionInName && !isDir)
            {
                name = nameNoVersion;
            }
            
            // 2nd field is size USED/ALLOCATED format, or perhaps just USED
            int slashPos = fields[1].IndexOf('/');
            string sizeUsed = fields[1];
            if (slashPos > 0)
                sizeUsed = fields[1].Substring(0, slashPos);
            long size = Int64.Parse(sizeUsed) * blocksize;
            
            // 3 & 4 fields are date time
            string lastModifiedStr = TweakDateString(fields);
            DateTime lastModified = DateTime.MinValue;
            try
            {
                lastModified = DateTime.Parse(lastModifiedStr.ToString(), ParsingCulture.DateTimeFormat);
            }
            catch (FormatException)
            {
                log.Warn("Failed to parse date string '" + lastModifiedStr + "'");
            }
            
            // 5th field is [group,owner]
            string group = null;
            string owner = null;
            if (fields.Length >= 5)
            {
                if (fields[4][0] == '[' && fields[4][fields[4].Length-1] == ']') 
                {
                    int commaPos = fields[4].IndexOf(',');
                    if (commaPos < 0)
                    {
                        owner = fields[4].Substring(1, fields[4].Length-2);
                        group = "";
                    }
                    else 
                    {
                        group = fields[4].Substring(1, commaPos-1);
                        owner = fields[4].Substring(commaPos+1, fields[4].Length-commaPos-2);
                    }
                }
            }
            
            // 6th field is permissions e.g. (RWED,RWED,RE,)
            string permissions = null;
            if (fields.Length >= 6)
            {
                if (fields[5][0] == '(' && fields[5][fields[5].Length-1] == ')') 
                {
                    permissions = fields[5].Substring(1, fields[5].Length-2);
                }
            }
            
            FTPFile file = new FTPFile(FTPFile.VMS, raw, name, size, isDir, ref lastModified); 
            file.Group = group;
            file.Owner = owner;
            file.Permissions = permissions;
            return file;
        }
        /// <summary>
        /// Parse an array of raw file information returned from the
        /// FTP server
        /// </summary>
        /// <param name="fileStrings">    array of strings
        /// </param>
        /// <returns> array of FTPFile objects
        /// </returns>
        public virtual FTPFile[] Parse(string[] fileStrings)
        {
            log.Debug("Parse() called using culture: " + parserCulture.EnglishName);
            FTPFile[] files = new FTPFile[fileStrings.Length];

            // quick check if no files returned
            if (fileStrings.Length == 0)
            {
                return(files);
            }

            if (!userSetParser && !parserDetected)
            {
                DetectParser(fileStrings);
            }

            int count = 0;

            for (int i = 0; i < fileStrings.Length; i++)
            {
                if (fileStrings[i] == null || fileStrings[i].Trim().Length == 0)
                {
                    continue;
                }

                try
                {
                    FTPFile file = null;
                    if (parser.IsMultiLine())
                    {
                        // vms uses more than 1 line for some file listings. We must keep going
                        // thru till we've got everything
                        StringBuilder filename = new StringBuilder(fileStrings[i]);
                        while (i + 1 < fileStrings.Length && fileStrings[i + 1].IndexOf(';') < 0)
                        {
                            filename.Append(" ").Append(fileStrings[i + 1]);
                            i++;
                        }
                        file = parser.Parse(filename.ToString());
                    }
                    else
                    {
                        file = parser.Parse(fileStrings[i]);
                    }

                    // we skip null returns - these are duff lines we know about and don't
                    // really want to throw an exception
                    if (file != null)
                    {
                        if (timeDiff.Ticks != 0)
                        {
                            file.ApplyTimeDifference(timeDiff);
                        }
                        files[count++] = file;
                    }
                }
                catch (RestartParsingException)
                {
                    log.Debug("Restarting parsing from first entry in list");
                    i     = -1;
                    count = 0;
                    continue;
                }
            }
            FTPFile[] result = new FTPFile[count];
            Array.Copy(files, 0, result, 0, count);
            return(result);
        }
Exemple #26
0
		/// <summary> 
		/// Parse server supplied string, e.g.:
		/// 
		/// lrwxrwxrwx   1 wuftpd   wuftpd         14 Jul 22  2002 MIRRORS -> README-MIRRORS
		/// -rw-r--r--   1 b173771  users         431 Mar 31 20:04 .htaccess
		/// 
		/// </summary>
		/// <param name="raw">  raw string to parse
		/// </param>
		public override FTPFile Parse(string raw)
		{		
			// test it is a valid line, e.g. "total 342522" is invalid
			char ch = raw[0];
			if (ch != ORDINARY_FILE_CHAR && ch != DIRECTORY_CHAR && ch != SYMLINK_CHAR)
				return null;
			
			string[] fields = StringSplitter.Split(raw);
			
			if (fields.Length < MIN_FIELD_COUNT)
			{
				StringBuilder msg = new StringBuilder("Unexpected number of fields in listing '");
                msg.Append(raw).Append("' - expected minimum ").Append(MIN_FIELD_COUNT).
                        Append(" fields but found ").Append(fields.Length).Append(" fields");
                log.Warn(msg.ToString());
                return null;
			}
			
			// field pos
			int index = 0;
			
			// first field is perms
			string permissions = fields[index++];
			ch = permissions[0];
			bool isDir = false;
			bool isLink = false;
			if (ch == DIRECTORY_CHAR)
				isDir = true;
			else if (ch == SYMLINK_CHAR)
				isLink = true;
			
			// some servers don't supply the link count
			int linkCount = 0;
            if (Char.IsDigit(fields[index][0])) // assume it is if a digit
            {
                string linkCountStr = fields[index++];
                try
				{
                    linkCount = System.Int32.Parse(linkCountStr);
				}
				catch (FormatException)
				{
                    log.Warn("Failed to parse link count: " + linkCountStr);
				}
            }
            else if (fields[index][0] == '-') // IPXOS Treck FTP server
            {
                index++;
            }
			
			// owner and group
            string owner = "";
            string group = "";
            // if 2 fields ahead is numeric and there's enough fields beyond (4) for
            // the date, then the next two fields should be the owner & group
            if (IsNumeric(fields[index+2]) &&  fields.Length-(index+2) > 4) 
            {
			    owner = fields[index++];
			    group = fields[index++];
            }
            // no owner
            else if (IsNumeric(fields[index + 1]) && fields.Length - (index + 1) > 4)
            {
                group = fields[index++];
            }
            	
			// size
			long size = 0L;
			string sizeStr = fields[index++].Replace(".", ""); // get rid of .'s in size           
			try
			{
				size = Int64.Parse(sizeStr);
			}
			catch (FormatException)
			{
                log.Warn("Failed to parse size: " + sizeStr);
			}                     
            
			// next 3 fields are the date time
            
            // we expect the month first on Unix. 
            // Connect:Enterprise UNIX has a weird extra numeric field here - we test if the 
            // next field is numeric and if so, we skip it (except we check for a BSD variant
            // that means it is the day of the month)
            int dayOfMonth = -1;
            if (IsNumeric(fields[index]))
            {
                // this just might be the day of month - BSD variant
                // we check it is <= 31 AND that the next field starts
                // with a letter AND the next has a ':' within it
                try
                {
                    char[] chars = { '0' };
                    string str = fields[index].TrimStart(chars);
                    dayOfMonth = Int32.Parse(fields[index]);
                    if (dayOfMonth > 31) // can't be day of month
                        dayOfMonth = -1;
                    if (!(Char.IsLetter(fields[index + 1][0])))
                        dayOfMonth = -1;
                    if (fields[index + 2].IndexOf(':') <= 0)
                        dayOfMonth = -1;
                }
                catch (FormatException) { }
                index++;
            }

			int dateTimePos = index;
            DateTime lastModified = DateTime.MinValue;
			StringBuilder stamp = new StringBuilder(fields[index++]);
			stamp.Append('-');
            if (dayOfMonth > 0)
                stamp.Append(dayOfMonth);
            else
                stamp.Append(fields[index++]);
            stamp.Append('-');
			
			string field = fields[index++];
			if (field.IndexOf((System.Char) ':') < 0 && field.IndexOf((System.Char) '.') < 0)
			{
				stamp.Append(field); // year
                try
                {
                    lastModified = DateTime.ParseExact(stamp.ToString(), format1,
                                                ParsingCulture.DateTimeFormat, DateTimeStyles.None);
                }
                catch (FormatException)
                {
                    log.Warn("Failed to parse date string '" + stamp.ToString() + "'");
                }
			}
			else
			{
				// add the year ourselves as not present
                int year = ParsingCulture.Calendar.GetYear(DateTime.Now);
				stamp.Append(year).Append('-').Append(field);
                try
                {

                    lastModified = DateTime.ParseExact(stamp.ToString(), format2,
                                                ParsingCulture.DateTimeFormat, DateTimeStyles.None);
                }
                catch (FormatException)
                {
                    log.Warn("Failed to parse date string '" + stamp.ToString() + "'");
                }
				
				// can't be in the future - must be the previous year
                // add 2 days for time zones (thanks hgfischer)
				if (lastModified > DateTime.Now.AddDays(2))
				{
                    lastModified = lastModified.AddYears(-1);
				}
			}
			
			// name of file or dir. Extract symlink if possible
			string name = null;
			string linkedname = null;
			
			// we've got to find the starting point of the name. We
			// do this by finding the pos of all the date/time fields, then
			// the name - to ensure we don't get tricked up by a userid the
			// same as the filename,for example
			int pos = 0;
			bool ok = true;
            int dateFieldCount = dayOfMonth > 0 ? 2 : 3; // only 2 fields left if we had a leading day of month
            for (int i = dateTimePos; i < dateTimePos + dateFieldCount; i++)
			{
				pos = raw.IndexOf(fields[i], pos);
				if (pos < 0)
				{
					ok = false;
					break;
				}
                else {
                    pos += fields[i].Length;
                }
			}
			if (ok)
			{
                string remainder = raw.Substring(pos).Trim();
				if (!isLink)
					name = remainder;
				else
				{
					// symlink, try to extract it
					pos = remainder.IndexOf(SYMLINK_ARROW);
					if (pos <= 0)
					{
						// couldn't find symlink, give up & just assign as name
						name = remainder;
					}
					else
					{
						int len = SYMLINK_ARROW.Length;
						name = remainder.Substring(0, (pos) - (0)).Trim();
						if (pos + len < remainder.Length)
							linkedname = remainder.Substring(pos + len);
					}
				}
			}
			else
			{
				log.Warn("Failed to retrieve name: " + raw);
			}
			
			FTPFile file = new FTPFile(FTPFile.UNIX, raw, name, size, isDir, ref lastModified);
			file.Group = group;
			file.Owner = owner;
			file.Link = isLink;
			file.LinkCount = linkCount;
			file.LinkedName = linkedname;
			file.Permissions = permissions;
			return file;
		}
Exemple #27
0
        /// <summary> Parse server supplied string</summary>
        /// <param name="raw">raw string to parse</param>
        /// <returns>FTPFile object representing the raw string</returns>
        /// <remarks>Listing look like the below:
        ///        CFT             45056 04/12/06 14:19:31 *FILE AFTFRE1.FILE
        ///        CFT                                     *MEM AFTFRE1.FILE/AFTFRE1.MBR
        ///        CFT             36864 28/11/06 15:19:30 *FILE AFTFRE2.FILE
        ///        CFT                                     *MEM AFTFRE2.FILE/AFTFRE2.MBR
        ///        CFT             45056 04/12/06 14:19:37 *FILE AFTFRE6.FILE
        ///        CFT                                     *MEM  AFTFRE6.FILE/AFTFRE6.MBR
        ///        QSYSOPR         28672 01/12/06 20:08:04 *FILE FPKI45POK5.FILE
        ///        QSYSOPR                                 *MEM FPKI45POK5.FILE/FPKI45POK5.MBR        
        /// </remarks>
        public override FTPFile Parse(string raw) 
        {
            string[] fields = StringSplitter.Split(raw);      
            
            // skip blank lines
            if(fields.Length <= 0)
                return null;
            // return what we can for MEM
            if (fields.Length >= 2 && fields[1].Equals(MEM))
            {
                DateTime lastModifiedm = DateTime.MinValue;
                string ownerm = fields[0];
                string namem = fields[2];
                FTPFile filem = new FTPFile(FTPFile.OS400, raw, namem, 0, false, ref lastModifiedm);
                filem.Owner = ownerm;
                return filem;
            } 
            if (fields.Length < MIN_EXPECTED_FIELD_COUNT)
                return null;
            
            // first field is owner
            string owner = fields[0];

            // next is size
            long size = Int64.Parse(fields[1]);

            string lastModifiedStr = fields[2] + " " + fields[3];
            DateTime lastModified = GetLastModified(lastModifiedStr);
 
            // test is dir
            bool isDir = false;
            if (fields[4] == DIR || fields[4] == DDIR)
                isDir = true; 

            string name = fields[5];
            if (name.EndsWith("/"))
            {
                isDir = true;
                name = name.Substring(0, name.Length - 1);
            }
            
            FTPFile file = new FTPFile(FTPFile.OS400, raw, name, size, isDir, ref lastModified); 
            file.Owner = owner;
            return file;
        }
Exemple #28
0
        /// <summary> Parse server supplied string</summary>
        /// <param name="raw">raw string to parse</param>
        /// <returns>FTPFile object representing the raw string</returns>
        /// <remarks>Listing look like the below:
        ///  OUTPUT:
        ///
        ///    Directory dirname
        ///
        ///    filename
        ///            used/allocated    dd-MMM-yyyy HH:mm:ss [group,owner]        (PERMS)
        ///    filename
        ///            used/allocated    dd-MMM-yyyy HH:mm:ss [group,owner]        (PERMS)
        ///    ...
        ///
        ///    Total of n files, n/m blocks
        /// </remarks>
        public override FTPFile Parse(string raw)
        {
            string[] fields = StringSplitter.Split(raw);

            // skip blank lines
            if (fields.Length <= 0)
            {
                return(null);
            }
            // skip line which lists Directory
            if (fields.Length >= 2 && fields[0].Equals(HDR))
            {
                return(null);
            }
            // skip line which lists Total
            if (fields.Length > 0 && fields[0].Equals(TOTAL))
            {
                return(null);
            }
            if (fields.Length < MIN_EXPECTED_FIELD_COUNT)
            {
                return(null);
            }

            // first field is name
            string name = fields[0];

            // make sure it is the name (ends with ';<INT>')
            int semiPos = name.LastIndexOf(';');

            // check for ;
            if (semiPos <= 0)
            {
                log.Warn("File version number not found in name '" + name + "'");
                return(null);
            }

            string nameNoVersion = name.Substring(0, semiPos);

            // check for version after ;
            string afterSemi = fields[0].Substring(semiPos + 1);

            try
            {
                Int64.Parse(afterSemi);
                // didn't throw exception yet, must be number
                // we don't use it currently but we might in future
            }
            catch (FormatException)
            {
                // don't worry about version number
            }

            // test is dir
            bool isDir = false;

            if (nameNoVersion.EndsWith(DIR))
            {
                isDir = true;
                name  = nameNoVersion.Substring(0, nameNoVersion.Length - DIR.Length);
            }

            if (!versionInName && !isDir)
            {
                name = nameNoVersion;
            }

            // 2nd field is size USED/ALLOCATED format, or perhaps just USED
            int    slashPos = fields[1].IndexOf('/');
            string sizeUsed = fields[1];

            if (slashPos > 0)
            {
                sizeUsed = fields[1].Substring(0, slashPos);
            }
            long size = Int64.Parse(sizeUsed) * blocksize;

            // 3 & 4 fields are date time
            string   lastModifiedStr = TweakDateString(fields);
            DateTime lastModified    = DateTime.MinValue;

            try
            {
                lastModified = DateTime.Parse(lastModifiedStr.ToString(), ParsingCulture.DateTimeFormat);
            }
            catch (FormatException)
            {
                log.Warn("Failed to parse date string '" + lastModifiedStr + "'");
            }

            // 5th field is [group,owner]
            string group = null;
            string owner = null;

            if (fields.Length >= 5)
            {
                if (fields[4][0] == '[' && fields[4][fields[4].Length - 1] == ']')
                {
                    int commaPos = fields[4].IndexOf(',');
                    if (commaPos < 0)
                    {
                        owner = fields[4].Substring(1, fields[4].Length - 2);
                        group = "";
                    }
                    else
                    {
                        group = fields[4].Substring(1, commaPos - 1);
                        owner = fields[4].Substring(commaPos + 1, fields[4].Length - commaPos - 2);
                    }
                }
            }

            // 6th field is permissions e.g. (RWED,RWED,RE,)
            string permissions = null;

            if (fields.Length >= 6)
            {
                if (fields[5][0] == '(' && fields[5][fields[5].Length - 1] == ')')
                {
                    permissions = fields[5].Substring(1, fields[5].Length - 2);
                }
            }

            FTPFile file = new FTPFile(FTPFile.VMS, raw, name, size, isDir, ref lastModified);

            file.Group       = group;
            file.Owner       = owner;
            file.Permissions = permissions;
            return(file);
        }
Exemple #29
0
		/// <summary> 
		/// Parse server supplied string, e.g.:
		/// 
        /// -r-------- GMETECHNOLOGY 1 TSI         8 Nov 06 11:00:25 ,GMETECHNOLOGY,file02.csv,U,20071106A00001105190.txt
		/// 
		/// </summary>
		/// <param name="raw">  raw string to parse
		/// </param>
		public override FTPFile Parse(string raw)
		{		
			// test it is a valid line, e.g. "total 342522" is invalid
			char ch = raw[0];
			if (ch != ORDINARY_FILE_CHAR && ch != DIRECTORY_CHAR && ch != SYMLINK_CHAR)
				return null;
			
			string[] fields = StringSplitter.Split(raw);
			
			if (fields.Length < MIN_FIELD_COUNT)
			{
				StringBuilder listing = new StringBuilder("Unexpected number of fields in listing '");
				listing.Append(raw).Append("' - expected minimum ").Append(MIN_FIELD_COUNT).
                        Append(" fields but found ").Append(fields.Length).Append(" fields");
				throw new FormatException(listing.ToString());
			}
			
			// field pos
			int index = 0;
			
			// first field is perms
			string permissions = fields[index++];
			ch = permissions[0];
			bool isDir = false;
			bool isLink = false;
			if (ch == DIRECTORY_CHAR)
				isDir = true;
			else if (ch == SYMLINK_CHAR)
				isLink = true;

            string group = fields[index++];

			// some servers don't supply the link count
			int linkCount = 0;
            if (Char.IsDigit(fields[index][0])) // assume it is if a digit
            {
                string linkCountStr = fields[index++];
                try
                {
                    linkCount = System.Int32.Parse(linkCountStr);
                }
                catch (FormatException)
                {
                    log.Warn("Failed to parse link count: " + linkCountStr);
                }
            }

            string owner = fields[index++];
			
            	
			// size
			long size = 0L;
			string sizeStr = fields[index++];            
			try
			{
				size = Int64.Parse(sizeStr);
			}
			catch (FormatException)
			{
				log.Warn("Failed to parse size: " + sizeStr);
			}                     
            
			// next 3 fields are the date time
            
            // we expect the month first on Unix. 
			int dateTimePos = index;
            DateTime lastModified = DateTime.MinValue;
			StringBuilder stamp = new StringBuilder(fields[index++]);
			stamp.Append('-').Append(fields[index++]).Append('-');
			
			string field = fields[index++];
			if (field.IndexOf((System.Char) ':') < 0)
			{
				stamp.Append(field); // year
                try
                {
                    lastModified = DateTime.ParseExact(stamp.ToString(), format1,
                                                ParsingCulture.DateTimeFormat, DateTimeStyles.None);
                }
                catch (FormatException)
                {
                    log.Warn("Failed to parse date string '" + stamp.ToString() + "'");
                }
			}
			else
			{
				// add the year ourselves as not present
                int year = ParsingCulture.Calendar.GetYear(DateTime.Now);
				stamp.Append(year).Append('-').Append(field);
                try
                {

                    lastModified = DateTime.ParseExact(stamp.ToString(), format2,
                                                ParsingCulture.DateTimeFormat, DateTimeStyles.None);
                }
                catch (FormatException)
                {
                    log.Warn("Failed to parse date string '" + stamp.ToString() + "'");
                }
				
				// can't be in the future - must be the previous year
                // add 2 days for time zones (thanks hgfischer)
				if (lastModified > DateTime.Now.AddDays(2))
				{
                    lastModified = lastModified.AddYears(-1);
				}
			}
			
			// name of file or dir. Extract symlink if possible
			string name = null;
			
			// we've got to find the starting point of the name. We
			// do this by finding the pos of all the date/time fields, then
			// the name - to ensure we don't get tricked up by a userid the
			// same as the filename,for example
			int pos = 0;
			bool ok = true;
			for (int i = dateTimePos; i < dateTimePos + 3; i++)
			{
				pos = raw.IndexOf(fields[i], pos);
				if (pos < 0)
				{
					ok = false;
					break;
				}
                else {
                    pos += fields[i].Length;
                }
			}
			if (ok)
			{
                name = raw.Substring(pos).Trim();
			}
			else
			{
				log.Warn("Failed to retrieve name: " + raw);
			}
			
			FTPFile file = new FTPFile(FTPFile.UNIX, raw, name, size, isDir, ref lastModified);
			file.Group = group;
			file.Owner = owner;
			file.Link = isLink;
			file.LinkCount = linkCount;
			file.Permissions = permissions;
			return file;
		}
 public virtual FTPFile[] Parse(string[] fileStrings)
 {
     this.log.Debug("Parse() called using culture: " + this.parserCulture.EnglishName);
     FTPFile[] sourceArray = new FTPFile[fileStrings.Length];
     if (fileStrings.Length == 0)
     {
         return sourceArray;
     }
     if (!this.userSetParser && !this.parserDetected)
     {
         this.DetectParser(fileStrings);
     }
     int length = 0;
     for (int i = 0; i < fileStrings.Length; i++)
     {
         if ((fileStrings[i] != null) && (fileStrings[i].Trim().Length != 0))
         {
             try
             {
                 FTPFile file = null;
                 if (this.parser.IsMultiLine())
                 {
                     StringBuilder builder = new StringBuilder(fileStrings[i]);
                     while (((i + 1) < fileStrings.Length) && (fileStrings[i + 1].IndexOf(';') < 0))
                     {
                         builder.Append(" ").Append(fileStrings[i + 1]);
                         i++;
                     }
                     file = this.parser.Parse(builder.ToString());
                 }
                 else
                 {
                     file = this.parser.Parse(fileStrings[i]);
                 }
                 if (file != null)
                 {
                     if (this.timeDiff.Ticks != 0L)
                     {
                         file.ApplyTimeDifference(this.timeDiff);
                     }
                     sourceArray[length++] = file;
                 }
             }
             catch (RestartParsingException)
             {
                 this.log.Debug("Restarting parsing from first entry in list");
                 i = -1;
                 length = 0;
             }
         }
     }
     FTPFile[] destinationArray = new FTPFile[length];
     Array.Copy(sourceArray, 0, destinationArray, 0, length);
     return destinationArray;
 }
Exemple #31
0
        /// <summary>
        /// 同步方法
        /// </summary>
        private void List_Create_Get(FTPFile dir_or_file)
        {
            string remote_path = dir_or_file.Path;
            string remote_file_name = dir_or_file.Name;
            string tmp_local_path = string.Empty;
            if (this.remote_sync_dir != "/")
            {
                tmp_local_path = (this.local_base_dir + remote_path.Replace(this.remote_sync_dir, "")).Replace("//", "/");
            }
            else
            {
                tmp_local_path = (this.local_base_dir + remote_path).Replace("//", "/");
            }


            //文件
            if (dir_or_file.Dir)
            {
                connection.LocalDirectory = tmp_local_path;
                if (!Directory.Exists(tmp_local_path))
                {
                    Directory.CreateDirectory(tmp_local_path);
                    PrintEventHandler("#创建文件夹#" + tmp_local_path);
                }

                //deep in
                FTPFile[] files = connection.GetFileInfos(remote_path);
                foreach (FTPFile file in files)
                {
                    if (file.fileName != "." && file.fileName != "..")
                    {
                        List_Create_Get(file);
                    }
                }
            }
            //目录
            else
            {
                bool need_download = false;
                //本地不存在
                if (!File.Exists(tmp_local_path))
                {
                    need_download = true;
                    PrintEventHandler("#下载文件#" + tmp_local_path);
                }
                else
                {
                    //本地存在
                    long local_file_size = new FileInfo(tmp_local_path).Length;
                    //大小不一致
                    if (local_file_size != dir_or_file.Size)
                    {
                        need_download = true;
                        PrintEventHandler("#更新文件#" + tmp_local_path);
                    }
                }

                if (need_download)
                {
                    PrintEventHandler("#下载文件#" + tmp_local_path);
                    try
                    {
                        connection.DownloadFile(tmp_local_path, dir_or_file.Path);
                        if (this.deleteRemote)
                        {
                            connection.DeleteFile(dir_or_file.Path);
                            PrintEventHandler("#删除远程文件#" + dir_or_file.Path);
                        }
                    }
                    catch (Exception e)
                    {
                        if (!this.CloseByHand)
                        {
                            PrintEventHandler("【异常】下载文件:" + e.Message);
                        }
                    }
                }
                else
                {
                    PrintEventHandler("本地已存在,不需下载.");
                    if (this.deleteRemote)
                    {
                        connection.DeleteFile(dir_or_file.Path);
                        PrintEventHandler("#删除远程文件#" + dir_or_file.Path);
                    }
                }
            }

        }
        /// <summary>
        /// Parse server supplied string, e.g.:
        ///
        /// lrwxrwxrwx   1 wuftpd   wuftpd         14 Jul 22  2002 MIRRORS -> README-MIRRORS
        /// -rw-r--r--   1 b173771  users         431 Mar 31 20:04 .htaccess
        ///
        /// </summary>
        /// <param name="raw">  raw string to parse
        /// </param>
        public override FTPFile Parse(string raw)
        {
            // test it is a valid line, e.g. "total 342522" is invalid
            char ch = raw[0];

            if (ch != ORDINARY_FILE_CHAR && ch != DIRECTORY_CHAR && ch != SYMLINK_CHAR)
            {
                return(null);
            }

            string[] fields = StringSplitter.Split(raw);

            if (fields.Length < MIN_FIELD_COUNT)
            {
                StringBuilder msg = new StringBuilder("Unexpected number of fields in listing '");
                msg.Append(raw).Append("' - expected minimum ").Append(MIN_FIELD_COUNT).
                Append(" fields but found ").Append(fields.Length).Append(" fields");
                log.Warn(msg.ToString());
                return(null);
            }

            // field pos
            int index = 0;

            // first field is perms
            string permissions = fields[index++];

            ch = permissions[0];
            bool isDir  = false;
            bool isLink = false;

            if (ch == DIRECTORY_CHAR)
            {
                isDir = true;
            }
            else if (ch == SYMLINK_CHAR)
            {
                isLink = true;
            }

            // some servers don't supply the link count
            int linkCount = 0;

            if (Char.IsDigit(fields[index][0])) // assume it is if a digit
            {
                string linkCountStr = fields[index++];
                try
                {
                    linkCount = System.Int32.Parse(linkCountStr);
                }
                catch (FormatException)
                {
                    log.Warn("Failed to parse link count: " + linkCountStr);
                }
            }
            else if (fields[index][0] == '-') // IPXOS Treck FTP server
            {
                index++;
            }

            // owner and group
            string owner = "";
            string group = "";

            // if 2 fields ahead is numeric and there's enough fields beyond (4) for
            // the date, then the next two fields should be the owner & group
            if (IsNumeric(fields[index + 2]) && fields.Length - (index + 2) > 4)
            {
                owner = fields[index++];
                group = fields[index++];
            }
            // no owner
            else if (IsNumeric(fields[index + 1]) && fields.Length - (index + 1) > 4)
            {
                group = fields[index++];
            }

            // size
            long   size    = 0L;
            string sizeStr = fields[index++].Replace(".", "");             // get rid of .'s in size

            try
            {
                size = Int64.Parse(sizeStr);
            }
            catch (FormatException)
            {
                log.Warn("Failed to parse size: " + sizeStr);
            }

            // next 3 fields are the date time

            // we expect the month first on Unix.
            // Connect:Enterprise UNIX has a weird extra numeric field here - we test if the
            // next field is numeric and if so, we skip it (except we check for a BSD variant
            // that means it is the day of the month)
            int dayOfMonth = -1;

            if (IsNumeric(fields[index]))
            {
                // this just might be the day of month - BSD variant
                // we check it is <= 31 AND that the next field starts
                // with a letter AND the next has a ':' within it
                try
                {
                    char[] chars = { '0' };
                    string str   = fields[index].TrimStart(chars);
                    dayOfMonth = Int32.Parse(fields[index]);
                    if (dayOfMonth > 31) // can't be day of month
                    {
                        dayOfMonth = -1;
                    }
                    if (!(Char.IsLetter(fields[index + 1][0])))
                    {
                        dayOfMonth = -1;
                    }
                    if (fields[index + 2].IndexOf(':') <= 0)
                    {
                        dayOfMonth = -1;
                    }
                }
                catch (FormatException) { }
                index++;
            }

            int           dateTimePos  = index;
            DateTime      lastModified = DateTime.MinValue;
            StringBuilder stamp        = new StringBuilder(fields[index++]);

            stamp.Append('-');
            if (dayOfMonth > 0)
            {
                stamp.Append(dayOfMonth);
            }
            else
            {
                stamp.Append(fields[index++]);
            }
            stamp.Append('-');

            string field = fields[index++];

            if (field.IndexOf((System.Char) ':') < 0 && field.IndexOf((System.Char) '.') < 0)
            {
                stamp.Append(field);                 // year
                try
                {
                    lastModified = DateTime.ParseExact(stamp.ToString(), format1,
                                                       ParsingCulture.DateTimeFormat, DateTimeStyles.None);
                }
                catch (FormatException)
                {
                    log.Warn("Failed to parse date string '" + stamp.ToString() + "'");
                }
            }
            else
            {
                // add the year ourselves as not present
                int year = ParsingCulture.Calendar.GetYear(DateTime.Now);
                stamp.Append(year).Append('-').Append(field);
                try
                {
                    lastModified = DateTime.ParseExact(stamp.ToString(), format2,
                                                       ParsingCulture.DateTimeFormat, DateTimeStyles.None);
                }
                catch (FormatException)
                {
                    log.Warn("Failed to parse date string '" + stamp.ToString() + "'");
                }

                // can't be in the future - must be the previous year
                // add 2 days for time zones (thanks hgfischer)
                if (lastModified > DateTime.Now.AddDays(2))
                {
                    lastModified = lastModified.AddYears(-1);
                }
            }

            // name of file or dir. Extract symlink if possible
            string name       = null;
            string linkedname = null;

            // we've got to find the starting point of the name. We
            // do this by finding the pos of all the date/time fields, then
            // the name - to ensure we don't get tricked up by a userid the
            // same as the filename,for example
            int  pos            = 0;
            bool ok             = true;
            int  dateFieldCount = dayOfMonth > 0 ? 2 : 3; // only 2 fields left if we had a leading day of month

            for (int i = dateTimePos; i < dateTimePos + dateFieldCount; i++)
            {
                pos = raw.IndexOf(fields[i], pos);
                if (pos < 0)
                {
                    ok = false;
                    break;
                }
                else
                {
                    pos += fields[i].Length;
                }
            }
            if (ok)
            {
                string remainder = raw.Substring(pos).Trim();
                if (!isLink)
                {
                    name = remainder;
                }
                else
                {
                    // symlink, try to extract it
                    pos = remainder.IndexOf(SYMLINK_ARROW);
                    if (pos <= 0)
                    {
                        // couldn't find symlink, give up & just assign as name
                        name = remainder;
                    }
                    else
                    {
                        int len = SYMLINK_ARROW.Length;
                        name = remainder.Substring(0, (pos) - (0)).Trim();
                        if (pos + len < remainder.Length)
                        {
                            linkedname = remainder.Substring(pos + len);
                        }
                    }
                }
            }
            else
            {
                log.Warn("Failed to retrieve name: " + raw);
            }

            FTPFile file = new FTPFile(FTPFile.UNIX, raw, name, size, isDir, ref lastModified);

            file.Group       = group;
            file.Owner       = owner;
            file.Link        = isLink;
            file.LinkCount   = linkCount;
            file.LinkedName  = linkedname;
            file.Permissions = permissions;
            return(file);
        }