Logo Search packages:      
Sourcecode: bareftp version File versions  Download package

FTPConnection.cs

// FTPConnection.cs
//
//  Copyright (C) 2008-2009 Christian Eide
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//

using System;
using System.Net;
using System.IO;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Collections.Generic;
using System.Collections;
using bareFTP.Protocol;
using bareFTP.Preferences;

namespace bareFTP.Protocol.Ftp
{
      public class FTPConnection : IProtocol
      {
            
            protected FTPClient ftpClient;
            private FTPMode ftpMode;
            //private IDialogHost host;
            private ConnectionProperties conn_props;
            private string cwd;
            Config conf;
            private bool xferinprogress = false;
            string system = string.Empty;
            
            public FTPConnection(ConnectionProperties conn_props)
            {
                  this.conn_props = conn_props;
            }
            
            public virtual void Init(IDialogHost host, Config config)
            {
                  //this.host = host;
                  this.conf = config;
                  if(conn_props.Bookmark != null)
                        ftpMode = conf.FTP_PassiveMode ? FTPMode.Passive : FTPMode.Active;
                  else
                        ftpMode = conf.FTP_PassiveMode ? FTPMode.Passive : FTPMode.Active;
                  
            }
            
            public virtual void Open()
            {
                  if(conn_props.Port == 0)
                        conn_props.Port = conf.FTPDefaultPort;
                  Open(conn_props.Hostname, conn_props.Port, conn_props.User, conn_props.Password);
            }
            
            public virtual void Open (string remoteHost, string user, string password)
            {
                  Open(remoteHost, conf.FTPDefaultPort, user, password);
            }

            public virtual void Open (string remoteHost, int remotePort, string user, string password)
            {
                  // Creating a new FTPClient
                  
                  if(string.IsNullOrEmpty(user) && conf.FTP_EmptyUserAnonymous)
                        user = "anonymous";
                  if(string.IsNullOrEmpty(password) && user == "anonymous" && conf.FTP_EmailAsAnonymousPass)
                        password = conf.FTP_EmailAddress;
                  
                  int port = remotePort;
                  if(port < 0)
                        port = conf.FTPDefaultPort;
                  
                  ftpClient = new FTPClient(ftpMode, conn_props.FTPS, conf);
                  
                  ftpClient.LogTextEmitted += new EventHandler(OnClientFeedback);
                  ftpClient.RemoteCharset = conn_props.RemoteCharset;
                  
                  if(conn_props.Bookmark != null)
                        ftpClient.ProtLevel = conn_props.Bookmark.EncryptData;
                  
                  ftpClient.Connect(remoteHost, port, user, password);

                  
                  List<FTPReply> replies = ftpClient.CheckReply(ftpClient.SendCommand("SYST"), true, 215);
                  foreach(FTPReply r in replies)
                        if(r.ReplyCode == 215)
                              system = r.Message;

                  ftpClient.RemoteSystem = system;
                  
            }
            
            // TODO: Fix these names...
            protected void OnClientFeedback(object sender, EventArgs e)
            {
                  OnLogTextEmitted(e as LogTextEmittedArgs);
            }

            public virtual void Close ()
            {
                  if(ftpClient != null)
                        ftpClient.Close();
            }
            
            public virtual bool Connected
            {
                  get {
                        return ftpClient.Connected;
                  }
            }
            
            public virtual bool TransferInProgress
            {
                  get {
                        return this.xferinprogress;
                  }
            }
            
            public virtual ConnectionProperties ConnProperties
            {
                  get { return conn_props; }
                  set { conn_props = value; }
            }
            
            /*
            public virtual void SetProperty (string property, object propertyValue)
            {
                  switch(property)
                  {
                  case("FTPMODE"):
                        this.ftpMode = (FTPMode)propertyValue;
                        break;
                  case("SSL"):
                        SSL = (bool)propertyValue;
                        break;
                  default:
                        break;
                  }
            }
            */
            public string SendCommand(string command)
            {
                  List<FTPReply> replies = ftpClient.SendCommand(command);
                  string result = "";
                  foreach(FTPReply reply in replies)
                  {
                        result += reply.ReplyCode.ToString() + reply.Message;
                  }
                  return result;
            }
            
            public virtual bool IsDir(string cwd, string dir)
            {
                  return ftpClient.IsDir(cwd, dir);
            }
            
            public virtual List<string> Dir ()
            {
                  return ftpClient.Dir();
            }
            
            public virtual List<RemoteFile> XDir ()
            {
                  List<string> listing = ftpClient.XDir();
                  
                  if(listing.Count == 0)
                        return new List<RemoteFile>();
                  
                  if(system.IndexOf("VMS") >= 0)
                        return ListParserVMS.ParseList(listing);
                  else
                  {
                        List<RemoteFile> files = ListParser.ParseList(listing);
                        
                        // Find linked file size if we need and have possibility
                        if(ftpClient.Features.Contains("MLSD") || ftpClient.Features.Contains("SIZE"))
                        {
                              foreach(RemoteFile f in files)
                              {
                                    if(!f.IsDir && f.IsLink)
                                    {
                                          long size = f.Size;
                                          bool found = false;
                                          // MLST is the prefered way...
                                          if(ftpClient.Features.Contains("MLSD"))
                                          {
                                                List<FTPReply> replies = ftpClient.CheckReply(ftpClient.SendCommand("MLST " + f.Filename), true, 216);
                                                foreach(FTPReply r in replies)
                                                {
                                                      if(r.ReplyCode == 250)
                                                      {
                                                            System.Text.RegularExpressions.Match match = System.Text.RegularExpressions.Regex.Match(r.Message, "siz\\S?=(\\d+)");
                                                            if(match.Success)
                                                            {
                                                                  try
                                                                  {
                                                                        size = Convert.ToInt64(match.Groups[1].Captures[0].ToString());
                                                                        found = true;
                                                                  } catch {}
                                                                  break;
                                                            }
                                                      }
                                                }     
                                          }
                                          if(!found)
                                          {
                                                List<FTPReply> replies = ftpClient.CheckReply(ftpClient.SendCommand("SIZE " + f.Linkdest), true, 216);
                                                foreach(FTPReply r in replies)
                                                {
                                                      if(r.ReplyCode == 213)
                                                      {
                                                            try
                                                            {
                                                                  size = Int64.Parse(r.Message.Trim());
                                                            } catch{}
                                                            break;
                                                      }
                                                }
                                          }
                                          
                                          f.Size = size;
                                    }
                              }
                        }
                        
                        return files;
                  }
            }

            public virtual void SendFile (XferFile file)
            {
                  if(file.Status == DownloadStatus.Skipped || file.Status == DownloadStatus.Aborted)
                        return;
                  
                  if(file.IsDir)
                  {
                        try
                        {
                              MakeDir(file.Path.RelativePathRemote);
                        }
                        catch(Exception ex)
                        {
                              OnLogTextEmitted(new LogTextEmittedArgs(MessageType.Error, ex.Message));
                              file.Status = DownloadStatus.Failed;
                        }
                  }
                  else
                  {
                        FileStream fs = null;
                        try
                        {
                              fs = new FileStream(file.Path.FileNameLocalAbs, FileMode.Open, FileAccess.Read, FileShare.Read);
                              xferinprogress = true;
                              ftpClient.StoreFile(file, file.Action, fs);
                              
                        }
                        catch(ReconnectException)
                        {
                              Open();
                              SetCurrentDirectory(cwd);
                        }
                        catch(Exception ex)
                        {
                              Open();
                              SetCurrentDirectory(cwd);
                              OnLogTextEmitted(new LogTextEmittedArgs(MessageType.Error, ex.Message));
                              file.Status = DownloadStatus.Failed;
                        }
                        finally
                        {
                              xferinprogress = false;
                              if(fs != null)
                                    fs.Close();
                        }
                        
                  }
                  
                  if(!string.IsNullOrEmpty(file.Permissions) && conf.General_PreserveFilePermissions && file.Status == DownloadStatus.Finished)
                  {
                        if(file.Status == DownloadStatus.Finished)
                        {
                              int mode;
                              if(Int32.TryParse(file.Permissions, out mode))
                                    ftpClient.Chmod(mode.ToString(), file.Path.FileNameRemoteAbs, true);
                        }
                  }
            }
            
            public virtual void GetFile (XferFile file)
            {
                  if(file.Status == DownloadStatus.Skipped || file.Status == DownloadStatus.Aborted)
                        return;

                  string path = string.Empty;
                  
                  
                  if(file.IsDir)
                  {
                        try
                        {
                              path = System.IO.Path.Combine(file.Path.LocalPath, file.Path.RelativePathLocal);
                              if(!Directory.Exists(path))
                              {
                                    Directory.CreateDirectory(path);
                              }
                              
                        }
                        catch(Exception ex)
                        {
                              OnLogTextEmitted(new LogTextEmittedArgs(MessageType.Error, ex.Message));
                              file.Status = DownloadStatus.Failed;
                        }
                  }
                  else
                  {
                        try
                        {
                              xferinprogress = true;
                              FileMode mode;

                              path = System.IO.Path.Combine(file.Path.LocalPath, file.Path.RelativePathLocal);
                              path = System.IO.Path.Combine(path, file.Path.FileName);
                              
                              if(file.Action == FileAction.Resume || file.Action == FileAction.Append)
                                    mode = FileMode.Append;
                              else
                              {
                              
                                    if(System.IO.File.Exists(path))
                                          mode = FileMode.Truncate;
                                    else
                                          mode = FileMode.CreateNew;
                              }

                              using(FileStream fs = new FileStream(file.Path.FileNameLocalAbs, mode))
                              {
                                    ftpClient.RetrieveFile(file, file.Action, fs);
                                    fs.Flush();
                                    fs.Close();
                              }
                              
                        }
                        catch(ReconnectException)
                        {
                              Open();
                              SetCurrentDirectory(cwd);
                        }
                        catch(Exception ex)
                        {
                              OnLogTextEmitted(new LogTextEmittedArgs(MessageType.Error, ex.Message));
                              file.Status = DownloadStatus.Failed;
                        }
                        finally
                        {
                              xferinprogress = false;
                        }
                  }

                  if(!string.IsNullOrEmpty(file.Permissions) && conf.General_PreserveFilePermissions)
                  {
                        if(file.Status == DownloadStatus.Failed)
                              return;
                        
                        bareFTP.Common.Utils.LocalChmod.Chmod(path, file.Permissions);
                  }
            }

            public virtual void DeleteFile (string remoteFileName)
            {
                  ftpClient.Delete(remoteFileName);
            }

            public virtual void MoveFile (string remoteFileName, string toRemotePath)
            {
                  throw new NotImplementedException();
            }

            public virtual void RenameFile (string fromRemoteFileName, string toRemoteFileName)
            {
                  ftpClient.RenameFile(fromRemoteFileName, toRemoteFileName);
            }

            public virtual void SetCurrentDirectory (string remotePath)
            {
                  ftpClient.ChangeDir(remotePath);
            }

            public virtual string GetCurrentDirectory ()
            {
                  string retVal = ftpClient.GetCurrentDirectory();
                  
                  if(retVal.IndexOf("\"") >= 0)
                  {
                        retVal = retVal.Remove(0, retVal.IndexOf("\"")+1);
                        retVal = retVal.Remove(retVal.IndexOf("\""));
                  }
                  cwd = retVal;
                  return retVal;
                   
            }

            public virtual void MakeDir (string directoryName)
            {
                  ftpClient.MakeDir(directoryName);
            }

            public virtual void RemoveDir (string directoryName)
            {
                  ftpClient.RemoveDir(directoryName);
            }
            
            public virtual void Chmod(string mode, string filename)
            {
                  ftpClient.Chmod(mode, filename);
            }
            
            public virtual void Abort()
            {
                  ftpClient.Abort();
                  LostConnection(cwd, null);
            }
            
            public virtual string CurrentDirectory
            {
                  get { return cwd; }
            }
            
            public event EventHandler LostConnection;
            
            public event EventHandler LogTextEmitted;
            public virtual void OnLogTextEmitted(LogTextEmittedArgs e)
            {
                  try
                  {
                        LogTextEmitted(this, e);
                  } catch{}
            }
            
      }
      
}

Generated by  Doxygen 1.6.0   Back to index