void OnTransferFileRequest(UserClient client, int requestId) { var direction = client.Buffer.ReadByte() == 1 ? FileTransmitDirection.Send : FileTransmitDirection.Receive; // when FileTransmitDirection.Send then the client is sending if (direction != FileTransmitDirection.Send) { HandleRequestLocalFile(client, requestId); return; } var fileName = Utilities.GetPlatformPath(client.Buffer.ReadPrefixString()); var fileSize = client.Buffer.ReadInt64(); var lastWriteTimeUtc = new DateTime(client.Buffer.ReadInt64(), DateTimeKind.Utc); var crc = (uint)client.Buffer.ReadInt32(); var temporaryFileName = Path.GetTempFileName(); client.FileTransmit = FileTransmission.BeginReceive( fileName, fileName, lastWriteTimeUtc, fileSize, temporaryFileName, crc); client.CurrentTransmitDirection = FileTransmitDirection.Receive; Logger.Log(LogType.Normal, $"Receiving {fileName}"); client.CreatePacket(requestId, PacketHeader.TransferFileRequestResponse) .Write((byte)0) // ok (no error code) .Send(); }
void OnStoreFile(UserClient client, int requestId) { var remotePath = Utilities.GetPlatformPath(client.Buffer.ReadPrefixString()); var fileSize = client.Buffer.ReadInt64(); var ticks = client.Buffer.ReadInt64(); var remoteChecksum = (uint)client.Buffer.ReadInt32(); //Logger.Log(LogType.Debug, "Ticks: {0}", ticks); var fileDateUtc = DateTime.UtcNow; //DateTime.SpecifyKind(new DateTime(ticks), DateTimeKind.Utc); if (Path.IsPathRooted(remotePath) || remotePath.Contains("..")) { client.CreatePacket(requestId, PacketHeader.Store) .Write((byte)1) // 1 is FAIL - The remote path contains invalid characters .Send(); return; } var localPath = Environment.OSVersion.Platform == PlatformID.Unix ? Path.Combine(Environment.CurrentDirectory, remotePath.Replace("\\", "/")) : Path.Combine(Environment.CurrentDirectory, remotePath.Replace("/", "\\")); if (!localPath.ToLower().StartsWith(Environment.CurrentDirectory.ToLower())) { Logger.Log(LogType.Warning, "Invalid path location received: {0}", localPath); client.CreatePacket(requestId, PacketHeader.Store) .Write((byte)2) // 2 is FAIL - The remote path is not within the directory specified by server .Send(); return; } client.FileTransmit = FileTransmission.BeginReceive(localPath, remotePath, fileDateUtc, fileSize, Path.GetTempFileName(), remoteChecksum); client.CurrentTransmitDirection = FileTransmitDirection.Receive; Logger.Log(LogType.Debug, "Begin transmit {0} ({1} bytes)", remotePath, fileSize); client.CreatePacket(requestId, PacketHeader.Store) .Write((byte)0) // 0 is OK - send the data .Send(); }
void OnBuildResultFile(int requestId) { long fileSize = _buffer.ReadInt64(); var remoteChecksum = (uint)_buffer.ReadInt32(); //Logger.Log(LogType.Debug, "OnBuildResultFile - {0} bytes", fileSize); _currentTransmitDirection = FileTransmitDirection.Receive; _currentFileTransmission = FileTransmission.BeginReceive( "myos.iso", "myos.iso", DateTime.UtcNow, fileSize, Path.GetTempFileName(), remoteChecksum); _currentFileTransmission.FileReceived += (sender) => _buildCompletedAndReceived = true; Logger.Log(LogType.Normal, "Receiving myos.iso - {0} bytes, checksum: {1}", fileSize, remoteChecksum.ToString("X8")); throw new FileTransmitBeginException(); }
public void TransferFile(string localFilename, string remoteFilename, FileTransmitDirection direction, TimeSpan timeout) { if (direction == FileTransmitDirection.Send) { var fi = new FileInfo(localFilename); var succeeded = false; var crc = new Crc32().ComputeFile(fi.FullName); using (var request = CreateRequest()) { CreatePacket(request.Id, PacketHeader.TransferFileRequest) .Write((byte)1) // send .Write(remoteFilename) .Write(fi.Length) .Write(fi.LastWriteTimeUtc.Ticks) .Write(crc) .Send(); if (!WaitForRequest(request, timeout)) { throw new RequestTimeoutException(); } succeeded = (bool)request.Data; } if (!succeeded) { throw new InvalidOperationException("Failed to request to transfer file..."); } using (var stream = System.IO.File.Open(localFilename, FileMode.Open, FileAccess.Read, FileShare.Read)) { var pos = 0L; var buffer = new byte[65536]; while (pos < fi.Length) { var read = stream.Read(buffer, 0, (int)Math.Min(buffer.Length, fi.Length - pos)); pos += read; var sendPos = 0; while (sendPos < read) { var sent = Send(buffer, sendPos, read - sendPos); if (sent <= 0) { throw new Exception("TransferFile Send error. Return value: " + sent); } sendPos += sent; } } } } else // receive { FileRequestResult result; using (var request = CreateRequest()) { CreatePacket(request.Id, PacketHeader.TransferFileRequest) .Write((byte)0) // receive .Write(remoteFilename) .Send(); if (!WaitForRequest(request, timeout)) { throw new RequestTimeoutException(); } result = (FileRequestResult)request.Data; } if (!result.Succeeded) { throw new InvalidOperationException("Failed to request to receive file..."); } // receive data... _currentTransmitDirection = FileTransmitDirection.Receive; _currentFileTransmission = FileTransmission.BeginReceive( localFilename, remoteFilename, result.LastWriteTimeUtc, result.Size, Path.GetTempFileName(), result.Crc); } }