public override BackupMode GetBackupModeForObject(FileSystemObject o, out bool followLinkTargets) { followLinkTargets = false; var nit = NameIgnoreType.None; if (IgnoredNames.TryGetValue(o.Name, out nit) && ((nit & NameIgnoreType.File) != 0 && !o.IsDirectoryish || (nit & NameIgnoreType.Directory) != 0 && o.IsDirectoryish)) return BackupMode.NoBackup; if (IgnoredExtensions.Contains(Path.GetExtension(o.Name)) && !o.IsDirectoryish || IgnoredPaths.Contains(o.UnmappedPath)) return BackupMode.NoBackup; return o.IsDirectoryish ? BackupMode.Directory : BackupMode.Full; }
public override BackupEngine.ChangeCriterium GetChangeCriterium(FileSystemObject newFile) { switch (GlobalChangeCriterium) { case ChangeCriterium.ArchiveFlag: return BackupEngine.ChangeCriterium.ArchiveFlag; case ChangeCriterium.Size: return BackupEngine.ChangeCriterium.Size; case ChangeCriterium.Date: return BackupEngine.ChangeCriterium.Date; case ChangeCriterium.Hash: return BackupEngine.ChangeCriterium.Hash; case ChangeCriterium.HashAuto: return newFile.Size < 1024*1024 ? BackupEngine.ChangeCriterium.Hash : BackupEngine.ChangeCriterium.Date; } throw new ArgumentOutOfRangeException(); }
private void Restore(FileSystemObject fso, VersionForRestore version, List<FileSystemObject> restoreLater) { version.Restore(fso, restoreLater); }
public void AddFso(FileSystemObject fso) { EnsureMaximumState(ArchiveState.PushingFsos); if (_state == ArchiveState.Initial) { _initialFsoOffset = _hashedStream.BytesWritten; _outputFilter = DoOutputFiltering(_hashedStream); _state = ArchiveState.PushingFsos; } else if (_state == ArchiveState.PushingFiles) { _outputFilter.Flush(); _outputFilter.Dispose(); _initialFsoOffset = _hashedStream.BytesWritten; _outputFilter = DoOutputFiltering(_hashedStream); _state = ArchiveState.PushingFsos; } var x0 = _outputFilter.BytesWritten; Serializer.SerializeToStream(_outputFilter, fso); var x1 = _outputFilter.BytesWritten; _baseObjectEntrySizes.Add(x1 - x0); }
FullStream GenerateInitialStream(FileSystemObject fso, Dictionary<Guid, BackupStream> knownGuids) { if (!ShouldBeAdded(fso, knownGuids)) { FixUpStreamReference(fso, knownGuids); return null; } var ret = new FullStream { UniqueId = fso.StreamUniqueId, PhysicalSize = fso.Size, VirtualSize = fso.Size, }; if (fso.FileSystemGuid != null) knownGuids[fso.FileSystemGuid.Value] = ret; ret.FileSystemObjects.Add(fso); return ret; }
private void GetDependencies(FileSystemObject fileSystemObject, HashSet<int> versionDependencies) { if (fileSystemObject.LatestVersion < 0) return; if (fileSystemObject.BackupStream == null) { if (!versionDependencies.Contains(fileSystemObject.LatestVersion)) versionDependencies.Add(fileSystemObject.LatestVersion); } else { fileSystemObject.BackupStream.GetDependencies(versionDependencies); } }
private bool CompareHashes(FileSystemObject newFile, FileSystemObject oldFile) { if (oldFile.Hashes.Count == 0) return true; var kv = oldFile.Hashes.First(); var newHash = newFile.ComputeHash(kv.Key); return !newHash.SequenceEqual(kv.Value); }
//If followLinkTargets is set, the target locations of links that lead //to locations not covered by any source locations are added as source //locations. public abstract BackupMode GetBackupModeForObject(FileSystemObject o, out bool followLinkTargets);
private static void FixUpStreamReference(FileSystemObject fso, Dictionary<Guid, BackupStream> knownGuids) { BackupStream stream; if (fso is FileHardlinkFso && fso.FileSystemGuid != null && knownGuids.TryGetValue(fso.FileSystemGuid.Value, out stream)) { fso.StreamUniqueId = stream.UniqueId; fso.BackupStream = stream; if (stream.FileSystemObjects.Count > 0) fso.LatestVersion = stream.FileSystemObjects[0].LatestVersion; stream.FileSystemObjects.Add(fso); } }
private BackupStream CheckAndMaybeAdd(FileSystemObject fso, Dictionary<Guid, BackupStream> knownGuids) { if (!ShouldBeAdded(fso, knownGuids)) { FixUpStreamReference(fso, knownGuids); return null; } int existingVersion = -1; if (fso.BackupMode != BackupMode.ForceFull && !FileHasChanged(fso, out existingVersion)) fso.BackupMode = BackupMode.Unmodified; BackupStream newStream; switch (fso.BackupMode) { case BackupMode.Unmodified: newStream = new UnmodifiedStream { UniqueId = fso.StreamUniqueId, ContainingVersion = existingVersion, VirtualSize = fso.Size, }; newStream.FileSystemObjects.Add(fso); break; case BackupMode.ForceFull: case BackupMode.Full: newStream = new FullStream { UniqueId = fso.StreamUniqueId, PhysicalSize = fso.Size, VirtualSize = fso.Size, }; newStream.FileSystemObjects.Add(fso); break; case BackupMode.Rsync: throw new NotImplementedException("Differential backup not implemented."); default: throw new ArgumentOutOfRangeException(); } if (fso.FileSystemGuid != null) knownGuids[fso.FileSystemGuid.Value] = newStream; return newStream; }
protected bool ShouldBeAdded(FileSystemObject fso, Dictionary<Guid, BackupStream> knownGuids) { fso.LatestVersion = -1; if (fso.IsDirectoryish) return false; if (fso.BackupMode == BackupMode.NoBackup) return false; if (fso.IsLinkish && fso.Type != FileSystemObjectType.FileHardlink) return false; fso.LatestVersion = NewVersionNumber; if (fso.FileSystemGuid != null && knownGuids.ContainsKey(fso.FileSystemGuid.Value)) return false; return true; }
protected virtual bool FileHasChanged(FileSystemObject newFile, FileSystemObject oldFile) { return true; }
public virtual ChangeCriterium GetChangeCriterium(FileSystemObject newFile) { return newFile.Size < 1024*1024 ? ChangeCriterium.Hash : ChangeCriterium.Date; }
private Stream GetStream(FileSystemObject fso) { if (fso.LatestVersion != VersionNumber) { VersionForRestore version; if (!_dependencies.TryGetValue(fso.LatestVersion, out version)) throw new InvalidBackup(Path, "Couldn't locate stream for object \"" + fso.PathWithoutBase + "\", even though the metadata states it should be there."); return version.GetStream(fso); } var dict = StreamDict; BackupStream backupStream; if (!dict.TryGetValue(fso.StreamUniqueId, out backupStream)) throw new InvalidBackup(Path, "Couldn't locate stream for object \"" + fso.PathWithoutBase + "\", even though the metadata states it should be there."); return backupStream.GetStream(this); }
private bool FileHasChanged(FileSystemObject newFile, out int existingVersion) { existingVersion = -1; var oldFile = FindPath(_oldObjects, newFile.MappedPath); if (oldFile == null) { newFile.ComputeHash(HashAlgorithm); return true; } var crit = GetChangeCriterium(newFile); bool ret; switch (crit) { case ChangeCriterium.ArchiveFlag: ret = newFile.ArchiveFlag; break; case ChangeCriterium.Size: ret = newFile.Size != oldFile.Size; break; case ChangeCriterium.Date: ret = newFile.ModificationTime != oldFile.ModificationTime; break; case ChangeCriterium.Hash: ret = CompareHashes(newFile, oldFile); break; case ChangeCriterium.Custom: ret = FileHasChanged(newFile, oldFile); break; default: throw new ArgumentOutOfRangeException(); } if (!ret) { oldFile.Hashes.ForEach(x => newFile.Hashes[x.Key] = x.Value); newFile.LatestVersion = oldFile.LatestVersion; existingVersion = oldFile.LatestVersion; } return ret; }
public void Restore(FileSystemObject fso, List<FileSystemObject> restoreLater) { fso.DeleteExisting(); if (!fso.Restore() && fso.LatestVersion >= 0) restoreLater.Add(fso); }
protected FileSystemObject(FileSystemObject parent, string name, string path = null) { Parent = parent; Name = name; path = path ?? MappedPath; SetFileAttributes(path); }