コード例 #1
0
		protected override void OnExecute(FtpCommandContext context)
		{
			string result;
			var user = context.Server.Configuration.Users[context.Statement.Argument];

			if(user != null)
			{
				context.Channel.UserName = context.Statement.Argument;

				if(string.IsNullOrEmpty(user.Password))
				{
					context.Channel.User = user;
					result = "230 User successfully logged in.";
					context.Statement.Result = true;
				}
				else
				{
					result = "331 Password required for " + context.Statement.Argument;
					context.Statement.Result = false;
				}
			}
			else
			{
				result = "331 Password required for " + context.Statement.Argument;
				context.Statement.Result = false;
			}

			context.Channel.Send(result);
		}
コード例 #2
0
		protected override object OnExecute(FtpCommandContext context)
		{
			context.Channel.CheckLogin();

			if(string.IsNullOrEmpty(context.Statement.Argument))
				throw new SyntaxException();

			string message = null;

			var arg = context.Statement.Argument.ToUpper();
			if(arg == "A")
			{
				context.Channel.TransferMode = FtpTransferMode.Ascii;
				message = "200 ASCII transfer mode active.";
				context.Channel.Send(message);
			}
			else if(arg == "I")
			{
				context.Channel.TransferMode = FtpTransferMode.Binary;
				message = "200 Binary transfer mode active.";
				context.Channel.Send(message);
			}
			else
			{
				throw new UnknownTransferModeException();
			}

			return message;
		}
コード例 #3
0
		protected override object OnExecute(FtpCommandContext context)
		{
			string message;

			if(string.IsNullOrEmpty(context.Statement.Argument))
			{
				var cmd = context.Statement.Argument;

				if(context.Executor.Root.Children.Contains(cmd))
					message = string.Format("214 Command {0} is supported by Ftp Server", cmd.ToUpper());
				else
					message = string.Format("502 Command {0} is not recognized or supported by Ftp Server", cmd.ToUpper());
			}
			else
			{
				var cmds = context.Executor.Root.Children.Keys.ToArray();

				var text = new StringBuilder();
				text.Append("214-The following commands are recognized:");

				for(int i = 0; i < cmds.Length; i++)
				{
					if(i % 8 == 0)
						text.Append("\r\n");

					text.AppendFormat("    {0}", cmds[i]);
				}

				message = text.ToString();
			}

			context.Channel.Send(message);

			return message;
		}
コード例 #4
0
		protected override void OnExecute(FtpCommandContext context)
        {
            context.Channel.CheckLogin();

            if (string.IsNullOrEmpty(context.Statement.Argument))
                throw new SyntaxException();

            var path = context.Statement.Argument;
            var localPath = context.Channel.MapVirtualPathToLocalPath(path);
            context.Statement.Result = localPath;

            if (Directory.Exists(localPath))
                throw new FileNotFoundException(path);

            try
            {
                File.Delete(localPath);
            }
            catch (Exception)
            {
                throw new InternalException("delete file");
            }

            context.Channel.Send("250 Deleted file successfully");
        }
コード例 #5
0
		protected override void OnExecute(FtpCommandContext context)
        {
            context.Channel.Status = FtpSessionStatus.NotLogin;
            context.Channel.User = null;
            context.Channel.Send("221 Bye-bye.");
            context.Channel.Close();
        }
コード例 #6
0
		protected override void OnExecute(FtpCommandContext context)
        {
            context.Channel.CheckLogin();

            if (string.IsNullOrEmpty(context.Statement.Argument))
                throw new SyntaxException();

            var file = context.Statement.Argument;
            if (string.IsNullOrEmpty(file))
                throw new SyntaxException();

            string localPath = context.Channel.MapVirtualPathToLocalPath(file);
            try
            {
                long length = 0;
                var info = new FileInfo(localPath);
                if (info.Exists)
                    length = info.Length;

                context.Channel.Send(string.Concat("213 ", length.ToString()));
            }
            catch (FtpException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new InternalException(e.Message);
            }
        }
コード例 #7
0
		protected override void OnExecute(FtpCommandContext context)
		{
			context.Channel.CheckLogin();

			try
			{
				if(string.IsNullOrWhiteSpace(context.Statement.Argument))
					throw new SyntaxException();

				var arguments = context.Statement.Argument.Split(new[] { ' ' }, 2);
				if(arguments.Length != 2)
					throw new SyntaxException();

				var dateTime = FtpDateUtils.ParseFtpDate(arguments[0]);
				var filePath = context.Channel.MapVirtualPathToLocalPath(arguments[1]);

				var fileInfo = new FileInfo(filePath);
				if(!fileInfo.Exists)
					throw new FileNotFoundException(arguments[1]);

				fileInfo.LastWriteTimeUtc = dateTime;

				context.Channel.Send("213 Date/time changed OK");
			}
			catch(FtpException)
			{
				throw;
			}
			catch(Exception)
			{
				throw new InternalException("");
			}
		}
コード例 #8
0
		protected override void OnExecute(FtpCommandContext context)
        {
            context.Channel.CheckLogin();

            try
            {
                var path = string.Empty;
                if (!string.IsNullOrWhiteSpace(context.Statement.Argument))
                    path = context.Statement.Argument;

                if (string.IsNullOrWhiteSpace(path))
                    path = context.Channel.CurrentDir;

                var localPath = context.Channel.MapVirtualPathToLocalPath(path);
                context.Statement.Result = localPath;

                FileSystemInfo fileInfo;

                if (File.Exists(localPath))
                    fileInfo = new FileInfo(localPath);
                else if (Directory.Exists(localPath))
                    fileInfo = new DirectoryInfo(localPath);
                else
                    throw new FileNotFoundException(path);
                
                var str = string.Format("250-Listing {0}\r\n{1}250 END", path, FtpMlstFileFormater.Format(context, fileInfo));
                context.Channel.Send(str);
            }
            catch (IOException e)
            {
                throw new InternalException(e.Message);
            }
        }
コード例 #9
0
        public static void Format(FtpCommandContext context, FileSystemInfo fileInfo, StringBuilder output)
        {
            var isFile = fileInfo is FileInfo;

            //Size
            output.AppendFormat("size={0};", isFile ? ((FileInfo)fileInfo).Length : 0);

            //Permission
            output.AppendFormat("perm={0}{1};",
                                /* Can read */ isFile ? "r" : "el",
                                /* Can write */ isFile ? "adfw" : "fpcm");
            
            //Type
            output.AppendFormat("type={0};", isFile ? "file" : "dir");

            //Create
            output.AppendFormat("create={0};", FtpDateUtils.FormatFtpDate(fileInfo.CreationTimeUtc));

            //Modify
            output.AppendFormat("modify={0};", FtpDateUtils.FormatFtpDate(fileInfo.LastWriteTimeUtc));

            //File name
            output.Append(DELIM);
            output.Append(fileInfo.Name);

            output.Append(NEWLINE);
        }
コード例 #10
0
		protected override object OnExecute(FtpCommandContext context)
		{
			const string MESSAGE = "200 NOOP Command Successful.";

			context.Channel.CheckLogin();
			context.Channel.Send(MESSAGE);
			return MESSAGE;
		}
コード例 #11
0
		protected override void OnExecute(FtpCommandContext context)
        {
            context.Channel.CheckLogin();

            context.Channel.Send(string.Format("257 \"{0}\" is current directory.", context.Channel.CurrentDir));

            context.Statement.Result = context.Channel.MapVirtualPathToLocalPath(context.Channel.CurrentDir);
        }
コード例 #12
0
		protected override object OnExecute(FtpCommandContext context)
        {
            context.Channel.CheckLogin();

            context.Channel.CreatePasvDataChannel();

			return true;
        }
コード例 #13
0
 private static char[] GetPermission(FtpCommandContext context, FileSystemInfo fileInfo)
 {
     var perm = ("----------").ToCharArray();
     perm[0] = fileInfo is DirectoryInfo ? 'd' : '-';
     perm[1] = 'r';
     perm[2] = !context.Channel.User.ReadOnly ? 'w' : '-';
     perm[0] = fileInfo is DirectoryInfo ? 'x' : '-';
     return perm;
 }
コード例 #14
0
		protected override void OnExecute(FtpCommandContext context)
        {
            context.Channel.CheckLogin();

            if (string.IsNullOrEmpty(context.Statement.Argument))
                throw new SyntaxException();

            context.Channel.RenamePath = context.Channel.MapVirtualPathToLocalPath(context.Statement.Argument);
            context.Statement.Result = context.Channel.RenamePath;
            context.Channel.Send("350 File or directory exists, ready for destination name.");
        }
コード例 #15
0
        protected override void OnExecute(FtpCommandContext context)
        {
            context.Channel.CheckLogin();

            long offset;
            if (!long.TryParse(context.Statement.Argument, out offset))
                throw new SyntaxException();

            context.Channel.FileOffset = offset;

            context.Channel.Send(string.Format("350 Restarting at {0}. Send STORE or RETR to initiate transfer.", offset));
        }
コード例 #16
0
		protected override object OnExecute(FtpCommandContext context)
        {
            context.Channel.CheckLogin();

			var message = string.Format("257 \"{0}\" is current directory.", context.Channel.CurrentDir);

			context.Channel.Send(message);

            context.Statement.Result = context.Channel.MapVirtualPathToLocalPath(context.Channel.CurrentDir);

			return message;
        }
コード例 #17
0
		protected override object OnExecute(FtpCommandContext context)
        {
			const string MESSAGE = "150 Opening data connection for file transfer.";

            context.Channel.CheckLogin();
            context.Channel.CheckDataChannel();

            var dataChannel = context.Channel.DataChannel;

            try
            {
                context.Channel.Status = FtpSessionStatus.Upload;

                var path = context.Statement.Argument;
                if (string.IsNullOrWhiteSpace(path))
                    throw new SyntaxException();

                var localPath = context.Channel.MapVirtualPathToLocalPath(path);
                context.Statement.Result = localPath;

                context.Channel.UpFileStream = File.Open(localPath, FileMode.Append, FileAccess.Write, FileShare.Read);
                context.Channel.UpFileLocalPath = localPath;
                context.Channel.UpFileFailed = false;
                dataChannel.Closed += DataChannel_Closed;
                dataChannel.Error += DataChannel_Failed;
                dataChannel.Received += DataChannel_Received;

                dataChannel.Receive();

                context.Channel.Send(MESSAGE);

				return MESSAGE;
            }
            catch (Exception ex)
            {
				Logger.Error(ex);

                if (context.Channel.UpFileStream != null)
                {
                    context.Channel.UpFileStream.Close();
                    context.Channel.UpFileStream = null;
                }
                context.Channel.CloseDataChannel();

                if (ex is FtpException)
                    throw ex;

                throw new InternalException("store file");
            }
        }
コード例 #18
0
		protected override object OnExecute(FtpCommandContext context)
        {
            context.Channel.CheckLogin();

            if (string.IsNullOrEmpty(context.Statement.Argument))
                throw new SyntaxException();

            context.Channel.CheckDataChannel();

			try
			{
				//context.Channel.Status = FtpSessionStatus.Download;

				var path = context.Statement.Argument;
				string localPath = context.Channel.MapVirtualPathToLocalPath(path);
				context.Statement.Result = localPath;

				var fileInfo = new FileInfo(localPath);

				if(!fileInfo.Exists)
					throw new FileNotFoundException(path);

				var message = "150 Open data connection for file transfer.";

				if(context.Channel.DataChannel.SendFile(fileInfo, context.Channel.FileOffset))
					message = "226 Transfer complete.";
				else
					message = "426 Connection closed; transfer aborted.";

				context.Channel.Send(message);
				context.Channel.FileOffset = 0;

				return message;
			}
			catch(FtpException)
			{
				throw;
			}
			catch(Exception e)
			{
				throw new InternalException(e.Message);
			}
			finally
			{
				context.Channel.CloseDataChannel();
				//context.Channel.Status = FtpSessionStatus.Wait;
			}
        }
コード例 #19
0
		protected override void OnExecute(FtpCommandContext context)
        {
            context.Result = null;

            context.Channel.CheckLogin();
            context.Channel.CheckDataChannel();

            var dataChannel = context.Channel.DataChannel;

            try
            {
                context.Channel.Status = FtpSessionStatus.Upload;

                var path = context.Statement.Argument;
                if (string.IsNullOrWhiteSpace(path))
                    throw new SyntaxException();

                var localPath = context.Channel.MapVirtualPathToLocalPath(path);
                context.Statement.Result = localPath;

                context.Channel.UpFileStream = File.Open(localPath, FileMode.Append, FileAccess.Write, FileShare.Read);
                context.Channel.UpFileLocalPath = localPath;
                context.Channel.UpFileFailed = false;
                dataChannel.Closed += DataChannel_Closed;
                dataChannel.Error += DataChannel_Failed;
                dataChannel.Received += DataChannel_Received;

                dataChannel.Receive();

                context.Channel.Send("150 Opening data connection for file transfer.");
            }
            catch (Exception e)
            {
                Tracer.Default.Trace(typeof(FtpStorCommand).FullName, e.ToString());

                if (context.Channel.UpFileStream != null)
                {
                    context.Channel.UpFileStream.Close();
                    context.Channel.UpFileStream = null;
                }
                context.Channel.CloseDataChannel();

                if (e is FtpException)
                    throw e;

                throw new InternalException("store file");
            }
        }
コード例 #20
0
		protected override void OnExecute(FtpCommandContext context)
		{
			context.Channel.Send(
				@"211-Features:
 MDTM
 SIZE
 PASV
 UTF8
 HELP
 MFMT
 MLST size*;type*;perm*;create*;modify*;
 MLSD
 REST
 OPTS
 NOOP
211 End");
		}
コード例 #21
0
		protected override void OnExecute(FtpCommandContext context)
        {
            context.Channel.CheckLogin();

            var localPath = context.Channel.MapVirtualPathToLocalPath("..");
            context.Statement.Result = localPath;
            var virtualPath = context.Channel.MapLocalPathToVirtualPath(localPath);

            if (Directory.Exists(localPath))
            {
                context.Channel.CurrentDir = virtualPath;
                context.Channel.Send("250 \"" + context.Channel.CurrentDir + "\" is current directory.");
            }
            else
            {
                throw new DirectoryNotFoundException(virtualPath);
            }
        }
コード例 #22
0
		protected override void OnExecute(FtpCommandContext context)
        {
            context.Channel.CheckLogin();

            if (string.IsNullOrWhiteSpace(context.Statement.Argument))
                throw new SyntaxException();

            var split = context.Statement.Argument.Split(',');

            if (split.Length != 6)
                throw new SyntaxException();

            var ip = string.Join(".", split, 0, 4);
            int port = int.Parse(split[4]) * 256 + int.Parse(split[5]);
            var address = new IPEndPoint(IPAddress.Parse(ip), port);

            context.Channel.CreatePortDataChannel(address);
        }
コード例 #23
0
		protected override void OnExecute(FtpCommandContext context)
        {
			var user = context.Server.Configuration.Users[context.Channel.UserName];

            if (user != null)
            {
                if (string.Equals(context.Statement.Argument, user.Password, StringComparison.OrdinalIgnoreCase))
                {
                    context.Channel.User = user;
                    context.Channel.Send("230 User successfully logged in.", null);
                    context.Statement.Result = true;
                    return;
                }
            }

            context.Channel.Send("530 Not logged in, user or password incorrect!", null);
            context.Statement.Result = false;
        }
コード例 #24
0
 public static void Format(FtpCommandContext context, FileSystemInfo fileInfo, StringBuilder output)
 {
     output.Append(GetPermission(context, fileInfo));
     output.Append(DELIM);
     output.Append(DELIM);
     output.Append(DELIM);
     output.Append(1); //LinkCount
     output.Append(DELIM);
     output.Append("ftp"); //OwnerName
     output.Append(DELIM);
     output.Append("ftp"); //GroupName
     output.Append(DELIM);
     output.Append(GetLength(fileInfo));
     output.Append(DELIM);
     output.Append(GetLastModified(fileInfo));
     output.Append(DELIM);
     output.Append(fileInfo.Name);
     output.Append(NEWLINE);
 }
コード例 #25
0
		protected override void OnExecute(FtpCommandContext context)
        {
            context.Channel.CheckLogin();

            if (string.IsNullOrEmpty(context.Statement.Argument))
                throw new SyntaxException();

            var changeDir = context.Statement.Argument;

            var path = context.Channel.MapVirtualPathToLocalPath(changeDir);

            if (File.Exists(path) || !Directory.Exists(path))
                throw new DirectoryNotFoundException(changeDir);

            context.Statement.Result = path;

            context.Channel.CurrentDir = context.Channel.MapLocalPathToVirtualPath(path);
            context.Channel.Send(string.Format("250 \"{0}\" is current directory.", context.Channel.CurrentDir));
        }
コード例 #26
0
		protected override object OnExecute(FtpCommandContext context)
		{
			const string MESSAGE = @"211-Features:
 MDTM
 SIZE
 PASV
 UTF8
 HELP
 MFMT
 MLST size*;type*;perm*;create*;modify*;
 MLSD
 REST
 OPTS
 NOOP
211 End";
			context.Channel.Send(MESSAGE);

			return MESSAGE;
		}
コード例 #27
0
		protected override void OnExecute(FtpCommandContext context)
		{
			context.Channel.CheckLogin();

			if(string.IsNullOrEmpty(context.Statement.Argument))
				throw new SyntaxException();

			var path = context.Statement.Argument;
			var localPath = context.Channel.MapVirtualPathToLocalPath(path);
			context.Statement.Result = localPath;

			var info = new FileInfo(localPath);
			if(info.Exists)
			{
				var str = string.Format("213 {0}", FtpDateUtils.FormatFtpDate(info.LastWriteTimeUtc));
				context.Channel.Send(str);
			}
			else
				throw new FileNotFoundException(path);
		}
コード例 #28
0
		protected override object OnExecute(FtpCommandContext context)
        {
			const string MESSAGE = "250 Rename successful.";

            context.Channel.CheckLogin();

            try
            {
                if (string.IsNullOrEmpty(context.Statement.Argument))
                    throw new SyntaxException();

                if (string.IsNullOrEmpty(context.Channel.RenamePath))
                    throw new BadSeqCommandsException();

                string destPath = context.Channel.MapVirtualPathToLocalPath(context.Statement.Argument);
                context.Statement.Result = destPath;

                try
                {
                    if (Directory.Exists(context.Channel.RenamePath))
                    {
                        Directory.Move(context.Channel.RenamePath, destPath);
                    }
                    else
                    {
                        File.Move(context.Channel.RenamePath, destPath);
                    }
                }
                catch (Exception)
                {
                    throw new InternalException("rename path");
                }

                context.Channel.Send(MESSAGE);
				return MESSAGE;
            }
            finally
            {
                context.Channel.RenamePath = null;
            }
        }
コード例 #29
0
		protected override void OnExecute(FtpCommandContext context)
        {
            context.Channel.CheckLogin();

            if (string.IsNullOrEmpty(context.Statement.Argument))
                throw new SyntaxException();

            var args = context.Statement.Argument;

            if (args.Equals("UTF8 ON", StringComparison.OrdinalIgnoreCase))
            {
                context.Channel.Encoding = Encoding.UTF8;
                context.Channel.Send("200 UTF enabled mode.");
            }
            else if (args.Equals("UTF8 OFF", StringComparison.OrdinalIgnoreCase))
            {
                context.Channel.Encoding = Encoding.ASCII;
                context.Channel.Send("200 ASCII enabled mode.");
            }
            else
            {
                throw new SyntaxException();
            }
        }
コード例 #30
0
		protected override void OnExecute(FtpCommandContext context)
		{
			context.Channel.CheckLogin();

			context.Channel.CheckDataChannel();
			context.Channel.DataChannel.Receive();

			try
			{
				context.Channel.Status = FtpSessionStatus.List;

				var path = string.Empty;
				if(!string.IsNullOrWhiteSpace(context.Statement.Argument))
					path = context.Statement.Argument;

				//解析参数
				if(path.StartsWith("-"))
				{
					var split = path.Split(new[] { ' ' });

					var pathIndex = Array.FindIndex(split, p => !p.StartsWith("-"));
					path = pathIndex >= 0 ? string.Join(" ", split, pathIndex, split.Length - pathIndex) : string.Empty;
				}

				if(string.IsNullOrWhiteSpace(path))
					path = context.Channel.CurrentDir;

				var localPath = context.Channel.MapVirtualPathToLocalPath(path);
				context.Statement.Result = localPath;

				if(File.Exists(localPath))
				{
					context.Channel.Send("150 Opening data connection for directory list.");

					var file = new FileInfo(localPath);
					WriteFileInfo(context, file);
				}
				else if(Directory.Exists(localPath))
				{
					context.Channel.Send("150 Opening data connection for directory list.");

					var localDir = new DirectoryInfo(localPath);

					//列举目录
					foreach(var dir in localDir.GetDirectories())
					{
						WriteFileInfo(context, dir);
					}

					//列举文件
					foreach(FileInfo file in localDir.GetFiles())
					{
						WriteFileInfo(context, file);
					}
				}
				else
				{
					throw new DirectoryNotFoundException(path);
				}

				context.Channel.Send("226 Transfer complete.");
			}
			catch(IOException e)
			{
				throw new InternalException(e.Message);
			}
			finally
			{
				context.Channel.CloseDataChannel();
				context.Channel.Status = FtpSessionStatus.Wait;
			}
		}