84 lines
2.5 KiB
C#
84 lines
2.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
|
|
namespace DearFTP.Connection.Commands
|
|
{
|
|
class StoreCommand : ICommand
|
|
{
|
|
public const int BufferSize = 4096;
|
|
|
|
public string[] Aliases { get; } = new string[]
|
|
{
|
|
"APPE",
|
|
"STOR",
|
|
"STOU"
|
|
};
|
|
|
|
public void Execute(Session session, FtpStream stream, string alias, string argument)
|
|
{
|
|
var dataConnection = session.DataConnection;
|
|
|
|
if (!dataConnection.IsAvailable)
|
|
{
|
|
stream.Send(ResponseCode.DataConnectionOpenError, "Passive mode not activated.");
|
|
return;
|
|
}
|
|
|
|
string path = alias.ToUpper() == "STOU" ? Path.GetRandomFileName() : argument;
|
|
|
|
var (navigablePath, realPath) = session.NavigablePath.GetNewSystemFilePath(path);
|
|
|
|
if (realPath == null)
|
|
{
|
|
stream.Send(ResponseCode.FileUnavailable, "Invalid destination path.");
|
|
return;
|
|
}
|
|
|
|
if (Directory.Exists(realPath))
|
|
{
|
|
stream.Send(ResponseCode.FileUnavailable, "A directory with this name already exists.");
|
|
return;
|
|
}
|
|
|
|
if (!session.WritablesShares.Contains(navigablePath.CurrentShare))
|
|
{
|
|
stream.Send(ResponseCode.FileUnavailable, "You don't have write access to this file.");
|
|
return;
|
|
}
|
|
|
|
stream.Send(ResponseCode.FileStatusOK, "Waiting file.");
|
|
|
|
ReceiveFile(dataConnection.Stream, realPath, alias.ToUpper() == "APPE");
|
|
|
|
dataConnection.Close();
|
|
|
|
stream.Send(ResponseCode.CloseDataConnection, "File received.");
|
|
}
|
|
|
|
private void ReceiveFile(NetworkStream stream, string path, bool append)
|
|
{
|
|
using (var file = File.Open(path, append ? FileMode.Append : FileMode.Create))
|
|
{
|
|
Span<byte> buffer = stackalloc byte[BufferSize];
|
|
int readBytes;
|
|
|
|
while ((readBytes = stream.Read(buffer)) > 0)
|
|
{
|
|
if (readBytes < BufferSize)
|
|
{
|
|
file.Write(buffer.Slice(0, readBytes));
|
|
}
|
|
else
|
|
{
|
|
file.Write(buffer);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|