using System; using System.Collections.Generic; using FluentFTP; namespace FluentFTP.Extensions { /// /// Implementation of the non-standard MD5 command /// public static class MD5 { delegate string AsyncGetMD5(string path); static Dictionary m_asyncmethods = new Dictionary(); /// /// Gets the MD5 hash of the specified file using MD5. This is a non-standard extension /// to the protocol and may or may not work. A FtpCommandException will be /// thrown if the command fails. /// /// FtpClient Object /// Full or relative path to remote file /// Server response, presumably the MD5 hash. public static string GetMD5(this FtpClient client, string path) { // http://tools.ietf.org/html/draft-twine-ftpmd5-00#section-3.1 FtpReply reply; string response; if (!(reply = client.Execute("MD5 {0}", path)).Success) throw new FtpCommandException(reply); response = reply.Message; if (response.StartsWith(path)) { response = response.Remove(0, path.Length).Trim(); } return response; } /// /// Asynchronusly retrieve a MD5 hash. The MD5 command is non-standard /// and not guaranteed to work. /// /// FtpClient Object /// Full or relative path to remote file /// AsyncCallback /// State Object /// IAsyncResult public static IAsyncResult BeginGetMD5(this FtpClient client, string path, AsyncCallback callback, object state) { AsyncGetMD5 func = new AsyncGetMD5(client.GetMD5); IAsyncResult ar = func.BeginInvoke(path, callback, state); ; lock (m_asyncmethods) { m_asyncmethods.Add(ar, func); } return ar; } /// /// Ends an asynchronous call to BeginGetMD5() /// /// IAsyncResult returned from BeginGetMD5() /// The MD5 hash of the specified file. public static string EndGetMD5(IAsyncResult ar) { AsyncGetMD5 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); } } }