//****************************************************************************************************** // FtpClient.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 05/22/2003 - J. Ritchie Carroll // Generated original version of source code. // 09/23/2008 - J. Ritchie Carroll // Generated original version of source code. // 09/14/2009 - Stephen C. Wills // Added new header and license agreement. // 12/17/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** #region [ Contributor License Agreements ] //******************************************************************************************************* // // Code based on the following project: // http://www.codeproject.com/KB/IP/net_ftp_upload.aspx // // Copyright Alex Kwok & Uwe Keim // // The Code Project Open License (CPOL): // http://www.codeproject.com/info/cpol10.aspx // //******************************************************************************************************* #endregion using System; using System.ComponentModel; using System.Drawing; // This FTP library is based on a similar C# library found on "The Code Project" web site originally written by // Alex Kwok (no license specified), then enhanced by Uwe Keim (licensed under The Code Project Open License). // GSF translated the code into VB with most of classes being renamed (removed Ftp prefix) and the namespace was // changed to GSF.Ftp. Many bug fixes, additions and modifications have been made to this code as well as extensive // testing. Note worthy changes: converted the C# delegates to standard .NET events for ease of use, made the // library work with IIS based FTP servers that were in Unix mode, added detailed file system information for FTP // files and directories (size, timestamp, etc), converted FTP session into a component that could be dragged onto // a design surface, created an FTP FileWatcher component and an FTP file system crawler based on this library. // In 2008 we migrated the entire code set to C# and restored the original "Ftp" prefix to the classes for to // satisfy uniqueness in type name constraint coming from code analysis. namespace GSF.Net.Ftp { /// /// Represents a FTP session. /// /// /// Creates a client connection to an FTP server for uploading or downloading files. /// [ToolboxBitmap(typeof(FtpClient)), DefaultProperty("Server"), DefaultEvent("FileTransferProgress"), Description("Creates a client connection to an FTP server")] public class FtpClient : Component { #region [ Members ] // Events /// /// Raised when file transfer begins. /// /// /// is local filename, /// is remote filename, /// is file transfer direction. /// public event EventHandler> BeginFileTransfer; /// /// Raised when file transfer completes. /// /// /// is local filename, /// is remote filename, /// is file transfer direction. /// public event EventHandler> EndFileTransfer; /// /// Raised as file transfer is progressing. /// /// /// is current file transfer progress, /// is file transfer direction. /// public event EventHandler, TransferDirection>> FileTransferProgress; /// /// Raised when ansynchronous file transfer process has completed (success or failure). /// /// /// is result of asynchronous FTP transfer process. /// public event EventHandler> FileTransferNotification; /// /// Raised when FTP response has been received. /// /// /// is received FTP response. /// public event EventHandler> ResponseReceived; /// /// Raised when FTP command has been sent. /// /// /// is sent FTP command. /// public event EventHandler> CommandSent; // Fields private bool m_caseInsensitive; private IFtpSessionState m_currentState; private int m_waitLockTimeOut; private bool m_disposed; #endregion #region [ Constructors ] /// /// Constructs a new FTP session using the default settings. /// public FtpClient() : this(false) { } /// /// Constructs a new FTP session using the specified settings. /// /// Set to true to not be case sensitive with FTP file and directory names. public FtpClient(bool caseInsensitive) { m_caseInsensitive = caseInsensitive; m_waitLockTimeOut = 10; m_currentState = new FtpSessionDisconnected(this, m_caseInsensitive); } /// /// Initializes a new instance of the class. /// /// object that contains the . public FtpClient(IContainer container) : this() { if ((object)container != null) container.Add(this); } #endregion #region [ Properties ] /// /// Gets or sets FTP server name (DNS name or IP). /// /// /// FTP server name should not be prefixed with FTP://. /// [Browsable(true), Category("Configuration"), Description("Specify FTP server name (do not prefix with FTP://).")] public string Server { get { return m_currentState.Server; } set { m_currentState.Server = value; } } /// /// Gets or sets FTP case sensitivity of file and directory names. /// /// /// Set to true to not be case sensitive with FTP file and directory names. /// [Browsable(true), Category("Configuration"), Description("Set to True to not be case sensitive with FTP file names."), DefaultValue(false)] public bool CaseInsensitive { get { return m_caseInsensitive; } set { m_caseInsensitive = value; } } /// /// Gets or sets FTP server port to use, defaults to 21. /// /// /// This only needs to be changed if the FTP server is established on a non-standard port number. /// [Browsable(true), Category("Configuration"), Description("Specify FTP server port, if needed."), DefaultValue(21)] public int Port { get { return m_currentState.Port; } set { m_currentState.Port = value; } } /// /// Gets or sets current FTP session directory. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public FtpDirectory CurrentDirectory { get { return m_currentState.CurrentDirectory; } set { m_currentState.CurrentDirectory = value; } } /// /// Gets FTP session root directory entry. /// [Browsable(false)] public FtpDirectory RootDirectory { get { return m_currentState.RootDirectory; } } /// /// Gets or sets maximum number of seconds to wait for read lock for files to be uploaded. Defaults to 10 seconds. /// [Browsable(true), Category("Configuration"), Description("Specify the maximum number of seconds to wait for read lock for files to be uploaded."), DefaultValue(10)] public int WaitLockTimeout { get { return m_waitLockTimeOut; } set { m_waitLockTimeOut = value; } } /// /// Changes the current FTP session directory to the specified path. /// /// New directory. public void SetCurrentDirectory(string directoryPath) { if (!IsConnected) throw new InvalidOperationException("You must be connected to the FTP server before you can set the current directory."); if (directoryPath.Length > 0) { m_currentState.CurrentDirectory = new FtpDirectory((FtpSessionConnected)m_currentState, CaseInsensitive, directoryPath); m_currentState.CurrentDirectory.Refresh(); } } /// /// Gets the current FTP control channel. /// [Browsable(false)] public FtpControlChannel ControlChannel { get { return m_currentState.ControlChannel; } } /// /// Returns true if FTP session is currently connected. /// [Browsable(false)] public bool IsConnected { get { return (m_currentState is FtpSessionConnected); } } /// /// Returns true if FTP session is currently busy. /// [Browsable(false)] public bool IsBusy { get { return m_currentState.IsBusy; } } internal IFtpSessionState State { get { return m_currentState; } set { m_currentState = value; } } #endregion #region [ Methods ] /// /// Releases the unmanaged resources used by the object and optionally releases the managed resources. /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected override void Dispose(bool disposing) { if (!m_disposed) { try { if (disposing) { if ((object)m_currentState != null) m_currentState.Dispose(); m_currentState = null; } } finally { m_disposed = true; // Prevent duplicate dispose. base.Dispose(disposing); // Call base class Dispose(). } } } /// /// Aborts current file transfer. /// public void AbortTransfer() { m_currentState.AbortTransfer(); } /// /// Connects to FTP server using specified credentials. /// /// User name used to authenticate to FTP server. /// Password used to authenticate to FTP server. public void Connect(string userName, string password) { m_currentState.Connect(userName, password); } /// /// Closes current FTP session. /// public void Close() { m_currentState.Close(); } internal void OnResponseReceived(string response) { if ((object)ResponseReceived != null) ResponseReceived(this, new EventArgs(response)); } internal void OnCommandSent(string command) { if ((object)CommandSent != null) CommandSent(this, new EventArgs(command)); } internal void OnBeginFileTransfer(string localFileName, string remoteFileName, TransferDirection transferDirection) { if ((object)BeginFileTransfer != null) BeginFileTransfer(this, new EventArgs(localFileName, remoteFileName, transferDirection)); } internal void OnEndFileTransfer(string localFileName, string remoteFileName, TransferDirection transferDirection) { if ((object)EndFileTransfer != null) EndFileTransfer(this, new EventArgs(localFileName, remoteFileName, transferDirection)); } internal void OnFileTransferProgress(ProcessProgress fileTransferProgress, TransferDirection transferDirection) { if ((object)FileTransferProgress != null) FileTransferProgress(this, new EventArgs, TransferDirection>(fileTransferProgress, transferDirection)); } internal void OnFileTransferNotification(FtpAsyncResult transferResult) { if ((object)FileTransferNotification != null) FileTransferNotification(this, new EventArgs(transferResult)); } #endregion } }