using System; using System.Collections.Generic; using System.Text; namespace FluentFTP.Extensions { /// /// Retrieve checksum of file on the server /// public static class ChecksumExtension { delegate FtpHash AsyncGetChecksum(string path); static Dictionary m_asyncmethods = new Dictionary(); /// /// Retrieves a checksum of the given file using a checksumming method /// that the server supports, if any. The algorithm used goes in this order: /// 1. HASH command; server preferred algorithm. See FtpClient.SetHashAlgorithm() /// 2. MD5 / XMD5 commands /// 3. XSHA1 command /// 4. XSHA256 command /// 5. XSHA512 command /// 6. XCRC command /// /// FtpClient Object /// Full or relative path of the file to checksum /// FtpHash object containing the value and algorithm. Use the IsValid property to /// determine if this command was successfull. FtpCommandException's can be thrown from /// the underlying calls. /// public static FtpHash GetChecksum(this FtpClient client, string path) { if (client.HasFeature(FtpCapability.HASH)) { return client.GetHash(path); } else { FtpHash res = new FtpHash(); if (client.HasFeature(FtpCapability.MD5)) { res.Value = client.GetMD5(path); res.Algorithm = FtpHashAlgorithm.MD5; } else if (client.HasFeature(FtpCapability.XMD5)) { res.Value = client.GetXMD5(path); res.Algorithm = FtpHashAlgorithm.MD5; } else if (client.HasFeature(FtpCapability.XSHA1)) { res.Value = client.GetXSHA1(path); res.Algorithm = FtpHashAlgorithm.SHA1; } else if (client.HasFeature(FtpCapability.XSHA256)) { res.Value = client.GetXSHA256(path); res.Algorithm = FtpHashAlgorithm.SHA256; } else if (client.HasFeature(FtpCapability.XSHA512)) { res.Value = client.GetXSHA512(path); res.Algorithm = FtpHashAlgorithm.SHA512; } else if (client.HasFeature(FtpCapability.XCRC)) { res.Value = client.GetXCRC(path); res.Algorithm = FtpHashAlgorithm.CRC; } return res; } } /// /// Asynchronusly retrieve a checksum of the specified file. This feature /// is non-standard. /// /// FtpClient Object /// Full or relative path to remote file /// AsyncCallback /// State Object /// IAsyncResult public static IAsyncResult BeginGetChecksum(this FtpClient client, string path, AsyncCallback callback, object state) { AsyncGetChecksum func = new AsyncGetChecksum(client.GetChecksum); IAsyncResult ar = func.BeginInvoke(path, callback, state); ; lock (m_asyncmethods) { m_asyncmethods.Add(ar, func); } return ar; } /// /// Ends an asynchronous call to BeginGetChecksum() /// /// IAsyncResult returned from BeginGetChecksum() /// FtpHash object containing the value and algorithm. Use the IsValid property to /// determine if this command was successfull. FtpCommandException's can be thrown from /// the underlying calls. public static FtpHash EndGetChecksum(IAsyncResult ar) { AsyncGetChecksum func = null; lock (m_asyncmethods) { if (!m_asyncmethods.ContainsKey(ar)) throw new InvalidOperationException("The specified IAsyncResult was not found in the collection."); func = m_asyncmethods[ar]; m_asyncmethods.Remove(ar); } return func.EndInvoke(ar); } } }