예제 #1
0
        public void Backup()
        {
            _logger.Info("Backing up appdata (database/config)");
            var backupFolderAppData = _appFolderInfo.GetUpdateBackUpAppDataFolder();

            _diskProvider.CreateFolder(backupFolderAppData);
            _diskProvider.CopyFile(_appFolderInfo.GetConfigPath(), _appFolderInfo.GetUpdateBackupConfigFile(), true);
            _diskProvider.CopyFile(_appFolderInfo.GetNzbDroneDatabase(), _appFolderInfo.GetUpdateBackupDatabase(), true);
        }
예제 #2
0
        private void DownloadImage(Series series, ImageFileResult image)
        {
            var fullPath = Path.Combine(series.Path, image.RelativePath);

            try
            {
                if (image.Url.StartsWith("http"))
                {
                    _httpClient.DownloadFile(image.Url, fullPath);
                }
                else
                {
                    _diskProvider.CopyFile(image.Url, fullPath);
                }
                _mediaFileAttributeService.SetFilePermissions(fullPath);
            }
            catch (WebException ex)
            {
                _logger.Warn(ex, "Couldn't download image {0} for {1}. {2}", image.Url, series, ex.Message);
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "Couldn't download image {0} for {1}. {2}", image.Url, series, ex.Message);
            }
        }
예제 #3
0
        private void BackupDatabase()
        {
            _logger.ProgressDebug("Backing up database");

            using (var unitOfWork = new UnitOfWork(() => _maindDb.GetDataMapper()))
            {
                unitOfWork.BeginTransaction(IsolationLevel.Serializable);

                var databaseFile     = _appFolderInfo.GetNzbDroneDatabase();
                var tempDatabaseFile = Path.Combine(_backupTempFolder, Path.GetFileName(databaseFile));

                _diskProvider.CopyFile(databaseFile, tempDatabaseFile, true);

                unitOfWork.Commit();
            }
        }
예제 #4
0
        private List <MetadataFile> ProcessSeriesImages(IMetadata consumer, Series series, List <MetadataFile> existingMetadataFiles)
        {
            var result = new List <MetadataFile>();

            foreach (var image in consumer.SeriesImages(series))
            {
                if (_diskProvider.FileExists(image.RelativePath))
                {
                    _logger.Debug("Series image already exists: {0}", image.RelativePath);
                    continue;
                }

                var metadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.SeriesImage &&
                                                                     c.RelativePath == image.RelativePath) ??
                               new MetadataFile
                {
                    SeriesId     = series.Id,
                    Consumer     = consumer.GetType().Name,
                    Type         = MetadataType.SeriesImage,
                    RelativePath = image.RelativePath
                };

                _diskProvider.CopyFile(image.Url, image.RelativePath);

                result.Add(metadata);
            }

            return(result);
        }
예제 #5
0
        private void MoveSqliteDatabase(string source, string destination)
        {
            _logger.Info("Moving {0}* to {1}*", source, destination);

            var dbSuffixes = new[] { "", "-shm", "-wal", "-journal" };

            foreach (var suffix in dbSuffixes)
            {
                var sourceFile = source + suffix;
                var destFile   = destination + suffix;

                if (_diskProvider.FileExists(destFile))
                {
                    _diskProvider.DeleteFile(destFile);
                }

                if (_diskProvider.FileExists(sourceFile))
                {
                    _diskProvider.CopyFile(sourceFile, destFile);
                }
            }

            foreach (var suffix in dbSuffixes)
            {
                var sourceFile = source + suffix;

                if (_diskProvider.FileExists(sourceFile))
                {
                    _diskProvider.DeleteFile(sourceFile);
                }
            }
        }
예제 #6
0
        private IEnumerable <MetadataFile> WriteSeriesImages(Series series, List <MetadataFile> existingMetadataFiles)
        {
            foreach (var image in series.Images)
            {
                var source      = _mediaCoverService.GetCoverPath(series.Id, image.CoverType);
                var destination = Path.Combine(series.Path, image.CoverType.ToString().ToLowerInvariant() + Path.GetExtension(source));

                //TODO: Do we want to overwrite the file if it exists?
                if (_diskProvider.FileExists(destination))
                {
                    _logger.Debug("Series image: {0} already exists.", image.CoverType);
                    continue;
                }

                _diskProvider.CopyFile(source, destination, false);
                var relativePath = DiskProviderBase.GetRelativePath(series.Path, destination);

                var metadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.SeriesImage &&
                                                                     c.RelativePath == relativePath) ??
                               new MetadataFile
                {
                    SeriesId     = series.Id,
                    Consumer     = GetType().Name,
                    Type         = MetadataType.SeriesImage,
                    RelativePath = relativePath
                };

                yield return(metadata);
            }
        }
예제 #7
0
        private void DownloadImage(Movie movie, ImageFileResult image)
        {
            _logger.Debug("Download Movie Image for: {0}", Path.Combine(movie.Path, movie.MovieFile?.RelativePath ?? string.Empty));

            var fullPath = Path.Combine(movie.Path, image.RelativePath);

            try
            {
                if (image.Url.StartsWith("http"))
                {
                    _httpClient.DownloadFile(image.Url, fullPath);
                }
                else
                {
                    _diskProvider.CopyFile(image.Url, fullPath);
                }

                _mediaFileAttributeService.SetFilePermissions(fullPath);
            }
            catch (HttpException ex)
            {
                _logger.Warn(ex, "Couldn't download image {0} for {1}. {2}", image.Url, movie, ex.Message);
            }
            catch (WebException ex)
            {
                _logger.Warn(ex, "Couldn't download image {0} for {1}. {2}", image.Url, movie, ex.Message);
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "Couldn't download image {0} for {1}. {2}", image.Url, movie, ex.Message);
            }
        }
예제 #8
0
        public void Backup()
        {
            _logger.Info("Backing up appdata (database/config)");
            var backupFolderAppData = _appFolderInfo.GetUpdateBackUpAppDataFolder();

            _diskProvider.CreateFolder(backupFolderAppData);

            try
            {
                _diskProvider.CopyFile(_appFolderInfo.GetConfigPath(), _appFolderInfo.GetUpdateBackupConfigFile(), true);
                _diskProvider.CopyFile(_appFolderInfo.GetNzbDroneDatabase(), _appFolderInfo.GetUpdateBackupDatabase(),
                                       true);
            }
            catch (Exception e)
            {
                _logger.ErrorException("Couldn't create a data backup", e);
            }
        }
예제 #9
0
        private void TryCopyFileVerified(string sourcePath, string targetPath, long originalSize)
        {
            try
            {
                _diskProvider.CopyFile(sourcePath, targetPath);

                var targetSize = _diskProvider.GetFileSize(targetPath);
                if (targetSize != originalSize)
                {
                    throw new IOException(string.Format("File copy incomplete. [{0}] was {1} bytes long instead of {2} bytes.", targetPath, targetSize, originalSize));
                }
            }
            catch
            {
                RollbackCopy(sourcePath, targetPath);
                throw;
            }
        }
예제 #10
0
        private MetadataFile WriteSeriesImages(Series series, List <MetadataFile> existingMetadataFiles)
        {
            //Because we only support one image, attempt to get the Poster type, then if that fails grab the first
            var image = series.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? series.Images.FirstOrDefault();

            if (image == null)
            {
                _logger.Trace("Failed to find suitable Series image for series {0}.", series.Title);
                return(null);
            }

            var source      = _mediaCoverService.GetCoverPath(series.Id, image.CoverType);
            var destination = Path.Combine(series.Path, "folder" + Path.GetExtension(source));

            //TODO: Do we want to overwrite the file if it exists?
            if (_diskProvider.FileExists(destination))
            {
                _logger.Debug("Series image: {0} already exists.", image.CoverType);
                return(null);
            }
            else
            {
                _diskProvider.CopyFile(source, destination, false);

                var metadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.SeriesImage) ??
                               new MetadataFile
                {
                    SeriesId     = series.Id,
                    Consumer     = GetType().Name,
                    Type         = MetadataType.SeriesImage,
                    RelativePath = DiskProviderBase.GetRelativePath(series.Path, destination)
                };

                return(metadata);
            }
        }
예제 #11
0
        private EpisodeFile TransferFile(EpisodeFile episodeFile, Series series, List <Episode> episodes, String destinationFilename, Boolean copyOnly)
        {
            Ensure.That(episodeFile, () => episodeFile).IsNotNull();
            Ensure.That(series, () => series).IsNotNull();
            Ensure.That(destinationFilename, () => destinationFilename).IsValidPath();

            var episodeFilePath = episodeFile.Path ?? Path.Combine(series.Path, episodeFile.RelativePath);

            if (!_diskProvider.FileExists(episodeFilePath))
            {
                throw new FileNotFoundException("Episode file path does not exist", episodeFilePath);
            }

            if (episodeFilePath.PathEquals(destinationFilename))
            {
                throw new SameFilenameException("File not moved, source and destination are the same", episodeFilePath);
            }

            var directoryName = new FileInfo(destinationFilename).DirectoryName;

            if (!_diskProvider.FolderExists(directoryName))
            {
                try
                {
                    _diskProvider.CreateFolder(directoryName);
                }
                catch (IOException ex)
                {
                    _logger.ErrorException("Unable to create directory: " + directoryName, ex);
                }

                SetFolderPermissions(directoryName);

                if (!directoryName.PathEquals(series.Path))
                {
                    SetFolderPermissions(series.Path);
                }
            }

            if (copyOnly)
            {
                _logger.Debug("Copying [{0}] > [{1}]", episodeFilePath, destinationFilename);
                _diskProvider.CopyFile(episodeFilePath, destinationFilename);
            }
            else
            {
                _logger.Debug("Moving [{0}] > [{1}]", episodeFilePath, destinationFilename);
                _diskProvider.MoveFile(episodeFilePath, destinationFilename);
            }

            episodeFile.RelativePath = series.Path.GetRelativePath(destinationFilename);

            _updateEpisodeFileService.ChangeFileDateForFile(episodeFile, series, episodes);

            try
            {
                SetFolderLastWriteTime(series.Path, episodeFile.DateAdded);

                if (series.SeasonFolder)
                {
                    var seasonFolder = Path.GetDirectoryName(destinationFilename);

                    SetFolderLastWriteTime(seasonFolder, episodeFile.DateAdded);
                }
            }

            catch (Exception ex)
            {
                _logger.WarnException("Unable to set last write time", ex);
            }

            //We should only run this on Windows
            if (OsInfo.IsWindows)
            {
                //Wrapped in Try/Catch to prevent this from causing issues with remote NAS boxes, the move worked, which is more important.
                try
                {
                    _diskProvider.InheritFolderPermissions(destinationFilename);
                }
                catch (Exception ex)
                {
                    if (ex is UnauthorizedAccessException || ex is InvalidOperationException)
                    {
                        _logger.Debug("Unable to apply folder permissions to: ", destinationFilename);
                        _logger.DebugException(ex.Message, ex);
                    }

                    else
                    {
                        throw;
                    }
                }
            }

            else
            {
                SetPermissions(destinationFilename, _configService.FileChmod);
            }

            return(episodeFile);
        }
예제 #12
0
        public TransferMode TransferFile(string sourcePath, string targetPath, TransferMode mode, bool overwrite, DiskTransferVerificationMode verificationMode)
        {
            Ensure.That(sourcePath, () => sourcePath).IsValidPath();
            Ensure.That(targetPath, () => targetPath).IsValidPath();

            _logger.Debug("{0} [{1}] > [{2}]", mode, sourcePath, targetPath);

            var originalSize = _diskProvider.GetFileSize(sourcePath);

            if (sourcePath == targetPath)
            {
                throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath));
            }

            if (sourcePath.PathEquals(targetPath, StringComparison.InvariantCultureIgnoreCase))
            {
                if (mode.HasFlag(TransferMode.HardLink) || mode.HasFlag(TransferMode.Copy))
                {
                    throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath));
                }

                if (mode.HasFlag(TransferMode.Move))
                {
                    var tempPath = sourcePath + ".backup~";

                    _diskProvider.MoveFile(sourcePath, tempPath, true);
                    try
                    {
                        ClearTargetPath(targetPath, overwrite);

                        _diskProvider.MoveFile(tempPath, targetPath);

                        return(TransferMode.Move);
                    }
                    catch
                    {
                        RollbackMove(sourcePath, tempPath);
                        throw;
                    }
                }

                return(TransferMode.None);
            }

            if (sourcePath.GetParentPath() == targetPath.GetParentPath())
            {
                if (mode.HasFlag(TransferMode.Move))
                {
                    TryMoveFileVerified(sourcePath, targetPath, originalSize);
                    return(TransferMode.Move);
                }
            }

            if (sourcePath.IsParentPath(targetPath))
            {
                throw new IOException(string.Format("Destination cannot be a child of the source [{0}] => [{1}]", sourcePath, targetPath));
            }

            ClearTargetPath(targetPath, overwrite);

            if (mode.HasFlag(TransferMode.HardLink))
            {
                var createdHardlink = _diskProvider.TryCreateHardLink(sourcePath, targetPath);
                if (createdHardlink)
                {
                    return(TransferMode.HardLink);
                }
                if (!mode.HasFlag(TransferMode.Copy))
                {
                    throw new IOException("Hardlinking from '" + sourcePath + "' to '" + targetPath + "' failed.");
                }
            }

            // We force a transactional transfer if the transfer occurs between mounts and one of the mounts is cifs, it would be a copy anyway.
            if (verificationMode == DiskTransferVerificationMode.TryTransactional && OsInfo.IsNotWindows)
            {
                var sourceMount = _diskProvider.GetMount(sourcePath);
                var targetMount = _diskProvider.GetMount(targetPath);

                if (sourceMount != null && targetMount != null && sourceMount.RootDirectory != targetMount.RootDirectory &&
                    (sourceMount.DriveFormat == "cifs" || targetMount.DriveFormat == "cifs"))
                {
                    verificationMode = DiskTransferVerificationMode.Transactional;
                }
            }

            if (mode.HasFlag(TransferMode.Copy))
            {
                if (verificationMode == DiskTransferVerificationMode.Transactional || verificationMode == DiskTransferVerificationMode.TryTransactional)
                {
                    if (TryCopyFileTransactional(sourcePath, targetPath, originalSize))
                    {
                        return(TransferMode.Copy);
                    }

                    throw new IOException(string.Format("Failed to completely transfer [{0}] to [{1}], aborting.", sourcePath, targetPath));
                }
                else if (verificationMode == DiskTransferVerificationMode.VerifyOnly)
                {
                    TryCopyFileVerified(sourcePath, targetPath, originalSize);
                    return(TransferMode.Copy);
                }
                else
                {
                    _diskProvider.CopyFile(sourcePath, targetPath);
                    return(TransferMode.Copy);
                }
            }

            if (mode.HasFlag(TransferMode.Move))
            {
                if (verificationMode == DiskTransferVerificationMode.Transactional || verificationMode == DiskTransferVerificationMode.TryTransactional)
                {
                    if (TryMoveFileTransactional(sourcePath, targetPath, originalSize, verificationMode))
                    {
                        return(TransferMode.Move);
                    }

                    throw new IOException(string.Format("Failed to completely transfer [{0}] to [{1}], aborting.", sourcePath, targetPath));
                }
                else if (verificationMode == DiskTransferVerificationMode.VerifyOnly)
                {
                    TryMoveFileVerified(sourcePath, targetPath, originalSize);
                    return(TransferMode.Move);
                }
                else
                {
                    _diskProvider.MoveFile(sourcePath, targetPath);
                    return(TransferMode.Move);
                }
            }

            return(TransferMode.None);
        }
예제 #13
0
        public TransferMode TransferFile(string sourcePath, string targetPath, TransferMode mode, bool overwrite = false, bool verified = true)
        {
            Ensure.That(sourcePath, () => sourcePath).IsValidPath();
            Ensure.That(targetPath, () => targetPath).IsValidPath();

            if (VerificationMode != DiskTransferVerificationMode.Transactional)
            {
                verified = false;
            }

            _logger.Debug("{0} [{1}] > [{2}]", mode, sourcePath, targetPath);

            if (sourcePath == targetPath)
            {
                throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath));
            }

            if (sourcePath.PathEquals(targetPath, StringComparison.InvariantCultureIgnoreCase))
            {
                if (mode.HasFlag(TransferMode.HardLink) || mode.HasFlag(TransferMode.Copy))
                {
                    throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath));
                }

                if (mode.HasFlag(TransferMode.Move))
                {
                    var tempPath = sourcePath + ".backup~";

                    _diskProvider.MoveFile(sourcePath, tempPath, true);
                    try
                    {
                        ClearTargetPath(targetPath, overwrite);

                        _diskProvider.MoveFile(tempPath, targetPath);

                        return(TransferMode.Move);
                    }
                    catch
                    {
                        RollbackMove(sourcePath, tempPath);
                        throw;
                    }
                }

                return(TransferMode.None);
            }

            if (sourcePath.IsParentPath(targetPath))
            {
                throw new IOException(string.Format("Destination cannot be a child of the source [{0}] => [{1}]", sourcePath, targetPath));
            }

            ClearTargetPath(targetPath, overwrite);

            if (mode.HasFlag(TransferMode.HardLink))
            {
                var createdHardlink = _diskProvider.TryCreateHardLink(sourcePath, targetPath);
                if (createdHardlink)
                {
                    return(TransferMode.HardLink);
                }
                if (!mode.HasFlag(TransferMode.Copy))
                {
                    throw new IOException("Hardlinking from '" + sourcePath + "' to '" + targetPath + "' failed.");
                }
            }

            if (verified)
            {
                if (mode.HasFlag(TransferMode.Copy))
                {
                    if (TryCopyFile(sourcePath, targetPath))
                    {
                        return(TransferMode.Copy);
                    }
                }

                if (mode.HasFlag(TransferMode.Move))
                {
                    if (TryMoveFile(sourcePath, targetPath))
                    {
                        return(TransferMode.Move);
                    }
                }

                throw new IOException(string.Format("Failed to completely transfer [{0}] to [{1}], aborting.", sourcePath, targetPath));
            }
            else if (VerificationMode == DiskTransferVerificationMode.VerifyOnly)
            {
                var originalSize = _diskProvider.GetFileSize(sourcePath);

                if (mode.HasFlag(TransferMode.Copy))
                {
                    try
                    {
                        _diskProvider.CopyFile(sourcePath, targetPath);

                        var targetSize = _diskProvider.GetFileSize(targetPath);
                        if (targetSize != originalSize)
                        {
                            throw new IOException(string.Format("File copy incomplete. [{0}] was {1} bytes long instead of {2} bytes.", targetPath, targetSize, originalSize));
                        }

                        return(TransferMode.Copy);
                    }
                    catch
                    {
                        RollbackCopy(sourcePath, targetPath);
                        throw;
                    }
                }

                if (mode.HasFlag(TransferMode.Move))
                {
                    try
                    {
                        _diskProvider.MoveFile(sourcePath, targetPath);

                        var targetSize = _diskProvider.GetFileSize(targetPath);
                        if (targetSize != originalSize)
                        {
                            throw new IOException(string.Format("File copy incomplete, data loss may have occured. [{0}] was {1} bytes long instead of the expected {2}.", targetPath, targetSize, originalSize));
                        }

                        return(TransferMode.Move);
                    }
                    catch
                    {
                        RollbackPartialMove(sourcePath, targetPath);
                        throw;
                    }
                }
            }
            else
            {
                if (mode.HasFlag(TransferMode.Copy))
                {
                    _diskProvider.CopyFile(sourcePath, targetPath);
                    return(TransferMode.Copy);
                }

                if (mode.HasFlag(TransferMode.Move))
                {
                    _diskProvider.MoveFile(sourcePath, targetPath);
                    return(TransferMode.Move);
                }
            }

            return(TransferMode.None);
        }
예제 #14
0
        public TransferMode TransferFile(string sourcePath, string targetPath, TransferMode mode, bool overwrite, DiskTransferVerificationMode verificationMode)
        {
            Ensure.That(sourcePath, () => sourcePath).IsValidPath();
            Ensure.That(targetPath, () => targetPath).IsValidPath();

            _logger.Debug("{0} [{1}] > [{2}]", mode, sourcePath, targetPath);

            var originalSize = _diskProvider.GetFileSize(sourcePath);

            if (sourcePath == targetPath)
            {
                throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath));
            }

            if (sourcePath.PathEquals(targetPath, StringComparison.InvariantCultureIgnoreCase))
            {
                if (mode.HasFlag(TransferMode.HardLink) || mode.HasFlag(TransferMode.Copy))
                {
                    throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath));
                }

                if (mode.HasFlag(TransferMode.Move))
                {
                    var tempPath = sourcePath + ".backup~";

                    _diskProvider.MoveFile(sourcePath, tempPath, true);
                    try
                    {
                        ClearTargetPath(sourcePath, targetPath, overwrite);

                        _diskProvider.MoveFile(tempPath, targetPath);

                        return(TransferMode.Move);
                    }
                    catch
                    {
                        RollbackMove(sourcePath, tempPath);
                        throw;
                    }
                }

                return(TransferMode.None);
            }

            if (sourcePath.GetParentPath() == targetPath.GetParentPath())
            {
                if (mode.HasFlag(TransferMode.Move))
                {
                    TryMoveFileVerified(sourcePath, targetPath, originalSize);
                    return(TransferMode.Move);
                }
            }

            if (sourcePath.IsParentPath(targetPath))
            {
                throw new IOException(string.Format("Destination cannot be a child of the source [{0}] => [{1}]", sourcePath, targetPath));
            }

            ClearTargetPath(sourcePath, targetPath, overwrite);

            if (mode.HasFlag(TransferMode.HardLink))
            {
                var createdHardlink = _diskProvider.TryCreateHardLink(sourcePath, targetPath);
                if (createdHardlink)
                {
                    return(TransferMode.HardLink);
                }
                if (!mode.HasFlag(TransferMode.Copy))
                {
                    throw new IOException("Hardlinking from '" + sourcePath + "' to '" + targetPath + "' failed.");
                }
            }

            // Adjust the transfer mode depending on the filesystems
            if (verificationMode == DiskTransferVerificationMode.TryTransactional)
            {
                var sourceMount = _diskProvider.GetMount(sourcePath);
                var targetMount = _diskProvider.GetMount(targetPath);

                var isSameMount = (sourceMount != null && targetMount != null && sourceMount.RootDirectory == targetMount.RootDirectory);

                var sourceDriveFormat = sourceMount?.DriveFormat ?? string.Empty;
                var targetDriveFormat = targetMount?.DriveFormat ?? string.Empty;

                if (isSameMount)
                {
                    // No transaction needed for operations on same mount, force VerifyOnly
                    verificationMode = DiskTransferVerificationMode.VerifyOnly;
                }
                else if (sourceDriveFormat.Contains("mergerfs") || sourceDriveFormat.Contains("rclone") ||
                         targetDriveFormat.Contains("mergerfs") || targetDriveFormat.Contains("rclone"))
                {
                    // Cloud storage filesystems don't need any Transactional stuff and it hurts performance, force VerifyOnly
                    verificationMode = DiskTransferVerificationMode.VerifyOnly;
                }
                else if ((sourceDriveFormat == "cifs" || targetDriveFormat == "cifs") && OsInfo.IsNotWindows)
                {
                    // Force Transactional on a cifs mount due to the likeliness of move failures on certain scenario's on mono
                    verificationMode = DiskTransferVerificationMode.Transactional;
                }
            }

            if (mode.HasFlag(TransferMode.Copy))
            {
                if (verificationMode == DiskTransferVerificationMode.Transactional || verificationMode == DiskTransferVerificationMode.TryTransactional)
                {
                    if (TryCopyFileTransactional(sourcePath, targetPath, originalSize))
                    {
                        return(TransferMode.Copy);
                    }

                    throw new IOException(string.Format("Failed to completely transfer [{0}] to [{1}], aborting.", sourcePath, targetPath));
                }
                else if (verificationMode == DiskTransferVerificationMode.VerifyOnly)
                {
                    TryCopyFileVerified(sourcePath, targetPath, originalSize);
                    return(TransferMode.Copy);
                }
                else
                {
                    _diskProvider.CopyFile(sourcePath, targetPath);
                    return(TransferMode.Copy);
                }
            }

            if (mode.HasFlag(TransferMode.Move))
            {
                if (verificationMode == DiskTransferVerificationMode.Transactional || verificationMode == DiskTransferVerificationMode.TryTransactional)
                {
                    if (TryMoveFileTransactional(sourcePath, targetPath, originalSize, verificationMode))
                    {
                        return(TransferMode.Move);
                    }

                    throw new IOException(string.Format("Failed to completely transfer [{0}] to [{1}], aborting.", sourcePath, targetPath));
                }
                else if (verificationMode == DiskTransferVerificationMode.VerifyOnly)
                {
                    TryMoveFileVerified(sourcePath, targetPath, originalSize);
                    return(TransferMode.Move);
                }
                else
                {
                    _diskProvider.MoveFile(sourcePath, targetPath);
                    return(TransferMode.Move);
                }
            }

            return(TransferMode.None);
        }