void OnDoBuild(UserClient client, int requestId) { if (System.IO.File.Exists("myos.iso")) { System.IO.File.Delete("myos.iso"); } var result = ReadProcessData("grub-mkrescue", "-o myos.iso isodir"); Logger.Log(LogType.Debug, "\n" + result); if (System.IO.File.Exists("myos.iso")) { client.FileTransmit = FileTransmission.CreateFromFile("myos.iso", "myos.iso"); client.CurrentTransmitDirection = FileTransmitDirection.Send; client.CreatePacket(requestId, PacketHeader.BuildResultFile) .Write(client.FileTransmit.FileSize) .Write(client.FileTransmit.RemoteChecksum) .Send(); client.FileTransmit.BeginTransmit(); // TODO: make this.. } else { Logger.Log(LogType.Warning, "Failed to create iso"); client.CreatePacket(requestId, PacketHeader.BuildResultFile) .Write((long)0) .Send(); } }
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 SetProgress(FileTransmission task) { this.Text = "接收端 下载中"; SetProgressBar(task); this.label3.Text = string.Format("进度:{0:N2}% 总长度:{1} 已完成:{2}", task.Progress, task.TotalSize, task.FinishedSize); this.label1.Text = string.Format("平均速度:{0:N2}KB/s 已用时:{1} 估计剩余时间:{2}", task.KByteAverSpeed, task.TimePast, task.TimeRemaining); this.label2.Text = string.Format("瞬时速度:{0:N2}KB/s 丢弃的区块:{1}", task.KByteSpeed, task.Blocks.Cast.Count); }
void task_BlockFinished(object sender, BlockFinishedEventArgs e) { FileTransmission task = (FileTransmission)sender; if (InvokeRequired) { this.Invoke(new Delegate_Progress(SetProgress), task); } else { SetProgress(task); } }
void task_BlockHashed(object sender, BlockFinishedEventArgs e) { FileTransmission task = (FileTransmission)sender; if (InvokeRequired) { this.Invoke(new Delegate_Void_Bool(b => this.Text = "接收端 校验中"), false); this.Invoke(new Delegate_Progress(SetProgressBar), task); } else { this.Text = "接收端 校验中"; SetProgressBar(task); } }
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(); }
void SetProgress(FileTransmission task) { this.toolStripStatusLabel1.Text = string.Format("已发送:{0:N2}%", task.Progress); this.toolStripStatusLabel2.Text = string.Format("{0:N2}KB/s", task.KByteAverSpeed); }
protected override void OnData(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { //Logger.Log(LogType.Debug, "Received {0} bytes", length); if (length != 0) { DataLogger.Log(buffer, offset, length); } if (_currentFileTransmission != null && _currentTransmitDirection == FileTransmitDirection.Receive) { if (_buffer.Length > 0) { var len = _buffer.Length; _buffer.Position = 0; _buffer.SetLength(0); OnData(_buffer.GetBuffer(), 0, (int)len, cancellationToken); if (cancellationToken.IsCancellationRequested) { return; } } if (length == 0) { return; } //Logger.Log(LogType.Debug, "Remaining: {0}", _currentFileTransmission.Remaining); // we're currently receiving a file int toWrite = (int)Math.Min(length, _currentFileTransmission.Remaining); _currentFileTransmission.Write(buffer, offset, toWrite); //Logger.Log(LogType.Debug, "Wrote {0} bytes - Remaining {1}", toWrite, userClient.FileTransmit.Remaining); if (_currentFileTransmission.Remaining == 0) { _currentFileTransmission.EndReceive(); Logger.Log(LogType.Normal, "File complete: {0}", _currentFileTransmission.RemotePath); if (_currentFileTransmission.IsFileCorrupted) { Logger.Log(LogType.Error, "ERR FILE CORRUPTED => {0}", _currentFileTransmission.RemotePath); } _currentFileTransmission.Dispose(); _currentFileTransmission = null; _currentTransmitDirection = FileTransmitDirection.None; //CreatePacket(PacketHeader.TransmitComplete).Send(); // notify transmit completed if ((length - toWrite) > 0) { var newBuffer = new byte[length - toWrite]; Buffer.BlockCopy(buffer, offset + toWrite, newBuffer, 0, length - toWrite); OnData(newBuffer, 0, newBuffer.Length, cancellationToken); // read the remaining data } } return; } _buffer.Position = _buffer.Length; _buffer.Write(buffer, offset, length); ReadPacketResult result; do { _buffer.Position = 0; int requestId; short header; int dataSize; switch (result = Utilities.ReadHeader(_buffer, out requestId, out header, out dataSize)) { case ReadPacketResult.InvalidData: case ReadPacketResult.DataSizeInvalid: case ReadPacketResult.InvalidHeader: case ReadPacketResult.UnexpectedHeaderAtThisPoint: Logger.Log( LogType.Warning, "ReadHeader: {0}", Enum.GetName(typeof(ReadPacketResult), result)); Utilities.DumpData(_buffer.GetBuffer(), (int)_buffer.Length); //Close(); return; case ReadPacketResult.NeedMoreData: return; // exit out of OnClientData and wait for more data... } // call packet methods MethodInfo methodInfo; if (!_packetMethods.TryGetValue((PacketHeader)header, out methodInfo)) { Logger.Log( LogType.Warning, "Unknown packet header: 0x{0}", header.ToString("x4")); Close(); return; } try { methodInfo.Invoke(this, new object[] { requestId }); } catch (TargetInvocationException ex) { if (ex.InnerException is DataValidationException) { Close(ex.Message); } else if (ex.InnerException is FileTransmitBeginException) { _buffer.Delete(NetworkStandards.HeaderSize + dataSize); OnData(new byte[] { }, 0, 0, cancellationToken); return; } } if (!IsConnected) { return; } _buffer.Delete(NetworkStandards.HeaderSize + dataSize); if (cancellationToken.IsCancellationRequested) { return; } if (_currentTransmitDirection == FileTransmitDirection.Receive) { OnData(new byte[] { }, 0, 0, cancellationToken); return; } if (_buffer.Length == 0) { break; } }while (result == ReadPacketResult.Succeeded); }
public void AddFileTransmission(FileTransmission fileTransmission) { _fileTransmissionQueue.Enqueue(fileTransmission); }
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); } }
public override void Process(CancellationToken cancellationToken) { base.Process(cancellationToken); if (!IsConnected) { return; } int tick = Environment.TickCount; if (_isAuthorized) { if (tick >= _nextSendPing && (_currentFileTransmission == null || !_currentFileTransmission.IsTransmitting)) { _nextSendPing = tick + 10000; CreatePacket(0, PacketHeader.Ping).Send(); } // check queue if (_currentFileTransmission != null && _currentTransmitDirection == FileTransmitDirection.Send) { if (_currentFileTransmission.IsTransmitting) { // send chunk... int toSend = (int)Math.Min(_currentFileTransmission.Remaining, _fileTransmitBuffer.Length); int numberOfBytesRead = 0; while (numberOfBytesRead < toSend) { numberOfBytesRead += _currentFileTransmission.Read(_fileTransmitBuffer, 0, toSend - numberOfBytesRead); } int numberOfBytesSent = 0; while (numberOfBytesSent < toSend) { numberOfBytesSent += Send(_fileTransmitBuffer, 0, toSend - numberOfBytesSent); } if (_currentFileTransmission.Remaining == 0) { // file upload completed Logger.Log(LogType.Normal, "Transmit completed."); _currentFileTransmission.EndTransmit(); _currentFileTransmission.Dispose(); _currentFileTransmission = null; _currentTransmitDirection = FileTransmitDirection.None; } } } else if (_fileTransmissionQueue.Count > 0) { _currentFileTransmission = _fileTransmissionQueue.Dequeue(); _currentTransmitDirection = FileTransmitDirection.Send; /*Logger.Log( * LogType.Debug, * "Request transmit {0}", * _currentFileTransmission.LocalPath);*/ CreatePacket(0, PacketHeader.Store) .Write(_currentFileTransmission.RemotePath) .Write(_currentFileTransmission.FileSize) .Write(_currentFileTransmission.FileDateUtc.Ticks) .Write((int)_currentFileTransmission.RemoteChecksum) .Send(); } } }
void SetProgressBar(FileTransmission task) { this.progressBar1.Maximum = task.Blocks.Count; this.progressBar1.Value = task.Blocks.CountValid; }
static void SubMain(string[] args) { Console.WriteLine($"Larry Build {BuildVersion.Version} ({BuildVersion.Date} UTC)"); using (var directoryChanger = new DirectoryChanger()) // DirectoryChanger automatically resets the working directory upon Dispose { int port = 11929; bool isServer = false; string address = string.Empty; string username = string.Empty; string password = string.Empty; int paramIndex = 0; var filesToSend = new List <FileSendObject>(); ShowTimesInMessages = true; #if DEBUG EnableDebugMessages = true; #else // DEBUG EnableDebugMessages = false; #endif // DEBUG for (int i = 0; i < args.Length; ++i) { if (args[i] == "--server") { isServer = true; } else if (args[i] == "--script") { if (i + 1 >= args.Length) { throw new ArgumentNotProvidedException("Script filename"); } using (var scriptRunner = new ScriptRunner()) { scriptRunner.Run(args[i + 1]); } return; } else if (args[i] == "-p") { if (i + 1 >= args.Length) { throw new ArgumentNotProvidedException("Port"); } port = int.Parse(args[++i]); } else if (args[i] == "-d" || args[i] == "--directory") { if (i + 1 >= args.Length) { throw new ArgumentNotProvidedException("Directory"); } directoryChanger.Change(args[++i]); } else if (args[i] == "--debug") { EnableDebugMessages = true; } else if (args[i] == "--no-time") { ShowTimesInMessages = false; } else { switch (paramIndex++) { case 0: address = args[i]; break; default: { var match = Regex.Match(args[i], "^([^=]+)=([^=]+)$"); if (!match.Success) { throw new MessageException("One or more files to send in parameters were invalid."); } if (!System.IO.File.Exists(match.Groups[1].Value)) { throw new MessageException("Local file not found: {0}", match.Groups[1].Value); } filesToSend.Add(new FileSendObject(match.Groups[1].Value, match.Groups[2].Value)); } break; } } } Logger.Log(LogType.Normal, "Platform: " + Environment.OSVersion.Platform); if (isServer) { if (Environment.OSVersion.Platform == PlatformID.Win32NT) { Console.Title = "Build Server"; } using (var server = new BuildServer()) { if (server.Start(port)) { Logger.Log(LogType.Normal, "Build Server running on port {0}", port); while (true) { // ... if (Console.KeyAvailable) { var key = Console.ReadKey(true); if (key.Key == ConsoleKey.Escape) { break; } } server.Process(); Thread.Sleep(SleepTime); } } else { Logger.Log(LogType.Error, "Failed to start server. Make sure that port {0} is not in use.", port); } } return; } if (string.IsNullOrEmpty(address)) { throw new MessageException("<address> was not provided."); } if (filesToSend.Count == 0) { throw new MessageException("There are no files to send."); } // run client using (var client = new BuildClient(false)) { if (client.Connect(address, port)) { //client.AddFileTransmission(FileTransmission.CreateFromFile("output\\myos.bin", "isodir\\boot\\myos.bin")); // path is normalized in linux //client.AddFileTransmission(FileTransmission.CreateFromFile("src\\grub.cfg", "isodir\\boot\\grub\\grub.cfg")); foreach (var file in filesToSend) { client.AddFileTransmission(FileTransmission.CreateFromFile( file.LocalPath, file.RemotePath)); } using (var source = new CancellationTokenSource()) { while (!client.IsFinished) { client.Process(source.Token); Thread.Sleep(SleepTime); } } } else { Logger.Log(LogType.Error, "Failed to connect to {0}:{1}", address, port); } } } }