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);
 }