Esempio n. 1
0
        private async Task <StepResult> DoCopySingleFileAsync(CopyFileStep step)
        {
            byte[] sourceContents;
            /* Read source file */
            if (step.Direction == FileCopyDirection.RemoteToLocal)
            {
                var command = new FetchResultRange {
                    FilePath = new[] { step.SourcePath }
                };
                var response = await _channel.SendWithReplyAsync <ResultRangeFetched>(command, _controller.CancellationToken);

                if (response.Status == FetchStatus.FileNotFound)
                {
                    return(new StepResult(false, $"File is not found on the remote machine at {step.SourcePath}", ""));
                }
                sourceContents = response.Data;
            }
            else if (!ReadLocalFile(step.SourcePath, out sourceContents, out var error))
            {
                return(new StepResult(false, error, ""));
            }
            /* Write target file */
            if (step.Direction == FileCopyDirection.LocalToRemote)
            {
                ICommand command = new PutFileCommand {
                    Data = sourceContents, Path = step.TargetPath
                };
                if (step.UseCompression)
                {
                    command = new CompressedCommand(command);
                }
                var response = await _channel.SendWithReplyAsync <PutFileResponse>(command, _controller.CancellationToken);

                if (response.Status == PutFileStatus.PermissionDenied)
                {
                    return(new StepResult(false, $"Access to path {step.TargetPath} on the remote machine is denied", ""));
                }
                if (response.Status == PutFileStatus.OtherIOError)
                {
                    return(new StepResult(false, $"File {step.TargetPath} could not be created on the remote machine", ""));
                }
            }
            else
            {
                try
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(step.TargetPath));
                    File.WriteAllBytes(step.TargetPath, sourceContents);
                }
                catch (UnauthorizedAccessException)
                {
                    return(new StepResult(false, $"Access to path {step.TargetPath} on the local machine is denied", ""));
                }
            }

            return(new StepResult(true, "", ""));
        }
Esempio n. 2
0
        private async Task <StepResult> DoCopyDirectoryAsync(CopyFileStep step, IList <FileMetadata> sourceFiles, IList <FileMetadata> targetFiles)
        {
            // Retrieve source files
            var files = new List <PackedFile>();

            bool SourceIdenticalToTarget(FileMetadata src)
            {
                foreach (var dst in targetFiles)
                {
                    if (dst.RelativePath == src.RelativePath)
                    {
                        return(dst.Size == src.Size && dst.LastWriteTimeUtc == src.LastWriteTimeUtc);
                    }
                }
                return(false);
            }

            var filesToGet = new List <string>();

            foreach (var src in sourceFiles)
            {
                if (!src.IsDirectory && !(step.SkipIfNotModified && SourceIdenticalToTarget(src)))
                {
                    filesToGet.Add(src.RelativePath);
                }
            }
            if (filesToGet.Count > 0)
            {
                if (step.Direction == FileCopyDirection.RemoteToLocal)
                {
                    var command = new GetFilesCommand {
                        RootPath = step.SourcePath, Paths = filesToGet.ToArray(), UseCompression = step.UseCompression
                    };
                    var response = await _channel.SendWithReplyAsync <GetFilesResponse>(command, _controller.CancellationToken);

                    if (response.Status != GetFilesStatus.Successful)
                    {
                        return(new StepResult(false, $"Unable to copy files from the remote machine", "The following files were requested:\r\n" + string.Join("; ", filesToGet) + "\r\n"));
                    }

                    files.AddRange(response.Files);
                }
                else
                {
                    files.AddRange(PackedFile.PackFiles(step.SourcePath, filesToGet));
                }
            }
            // Include empty directories
            foreach (var src in sourceFiles)
            {
                // ./ indicates the root directory
                if (src.IsDirectory && src.RelativePath != "./" && !(step.SkipIfNotModified && SourceIdenticalToTarget(src)))
                {
                    files.Add(new PackedFile(Array.Empty <byte>(), src.RelativePath, src.LastWriteTimeUtc));
                }
            }
            // Write source files and directories to the target directory
            if (files.Count == 0)
            {
                return(new StepResult(true, "", "No files were copied. Sizes and modification times are identical on the source and target sides.\r\n"));
            }
            if (step.Direction == FileCopyDirection.LocalToRemote)
            {
                ICommand command = new PutDirectoryCommand {
                    Files = files.ToArray(), Path = step.TargetPath, PreserveTimestamps = step.PreserveTimestamps
                };
                if (step.UseCompression)
                {
                    command = new CompressedCommand(command);
                }
                var response = await _channel.SendWithReplyAsync <PutDirectoryResponse>(command, _controller.CancellationToken);

                if (response.Status == PutDirectoryStatus.TargetPathIsFile)
                {
                    return(new StepResult(false, $"Directory \"{step.SourcePath}\" could not be copied to the remote machine: the target path is a file.", ""));
                }
                if (response.Status == PutDirectoryStatus.PermissionDenied)
                {
                    return(new StepResult(false, $"Access to path \"{step.TargetPath}\" on the remote machine is denied", ""));
                }
                if (response.Status == PutDirectoryStatus.OtherIOError)
                {
                    return(new StepResult(false, $"Directory \"{step.SourcePath}\" could not be copied to the remote machine", ""));
                }
            }
            else
            {
                if (File.Exists(step.TargetPath))
                {
                    return(new StepResult(false, $"Directory \"{step.TargetPath}\" could not be copied to the local machine: the target path is a file.", ""));
                }

                try
                {
                    PackedFile.UnpackFiles(step.TargetPath, files, step.PreserveTimestamps);
                }
                catch (UnauthorizedAccessException)
                {
                    return(new StepResult(false, $"Access to path \"{step.TargetPath}\" on the local machine is denied", ""));
                }
                catch (IOException)
                {
                    return(new StepResult(false, $"Directory \"{step.TargetPath}\" could not be copied to the local machine", ""));
                }
            }

            return(new StepResult(true, "", ""));
        }