Ejemplo n.º 1
0
 /// <summary>
 /// Restores a single backup entry to the file system
 /// </summary>
 /// <param name="path">
 /// The file system path to restore to
 /// </param>
 /// <param name="backupEntry">
 /// The backup entry to restore
 /// </param>
 /// <param name="restoreEntry">
 /// The restore entry to restore
 /// </param>
 private void RestoreFile(
     IO.Path path,
     Backup.Entry backupEntry,
     Restore.Entry restoreEntry)
 {
     using (var input = new IO.StreamStack())
      using (var output = IO.FileSystem.Truncate(path))
      {
     // create the input stream stack, consisting of the following
     // . restore stream from the archive
     // . read rate limiter
     // . decryptor
     // . optional decompressor
     input.Push(
        this.restore.Restore(restoreEntry)
     );
     input.Push(
        this.limiter.CreateStreamFilter(input.Top)
     );
     input.Push(
        new CryptoStream(
           input.Top,
           this.Crypto.CreateDecryptor(),
           CryptoStreamMode.Read
        )
     );
     if (backupEntry.Session.Compress)
        input.Push(
           new IO.CompressionStream(
              input.Top,
              IO.CompressionMode.Decompress
           )
        );
     copier.CopyAndFlush(input, output);
      }
      // verify the backup entry's CRC if requested
      if (this.Session.VerifyResults)
     if (IO.CrcFilter.Calculate(path) != backupEntry.Crc32)
        throw new InvalidOperationException(
           String.Format(Strings.ExecuteRestoreCrcFailed, path)
        );
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Backs up a single file entry to the attached archive
 /// </summary>
 /// <param name="entry">
 /// The entry to store
 /// </param>
 private void BackupEntry(SkyFloe.Backup.Entry entry)
 {
     ReportProgress(
     new ProgressEventArgs()
     {
        Operation = "BeginBackupEntry",
        BackupSession = this.Session,
        BackupEntry = entry
     }
      );
      try
      {
     using (var input = new IO.StreamStack())
     {
        // create the input stream stack, consisting of the following
        // . source file
        // . CRC calculation filter
        // . optional compressor
        // . encryptor
        // . read rate limiter
        input.Push(
           IO.FileSystem.Open(entry.Node.GetAbsolutePath())
        );
        input.Push(
           new IO.CrcFilter(input.Top)
        );
        if (this.Session.Compress)
           input.Push(
              new IO.CompressionStream(
                 input.Top,
                 IO.CompressionMode.Compress
              )
           );
        input.Push(
           new CryptoStream(
              input.Top,
              this.Crypto.CreateEncryptor(),
              CryptoStreamMode.Read
           )
        );
        input.Push(
           this.limiter.CreateStreamFilter(input.Top)
        );
        // send the stream stack to the backup plugin
        // and record the calculated CRC value in the entry
        this.backup.Backup(entry, input);
        entry.Crc32 = input.GetStream<IO.CrcFilter>().Value;
     }
     // commit the archive entry to the index
     // at this point, the entry is locally durable
     // until the next checkpoint, when it becomes permanent
     entry.State = SkyFloe.Backup.EntryState.Completed;
     entry.Blob.Length += entry.Length;
     this.Session.ActualLength += entry.Length;
     using (var txn = new TransactionScope())
     {
        this.Archive.BackupIndex.UpdateEntry(entry);
        this.Archive.BackupIndex.UpdateBlob(entry.Blob);
        this.Archive.BackupIndex.UpdateSession(this.Session);
        txn.Complete();
     }
      }
      catch (Exception e)
      {
     switch (ReportError("BackupEntry", e))
     {
        case ErrorResult.Retry:
           // the client chose to retry, so leave the entry pending
           break;
        case ErrorResult.Fail:
           // the client chose to ignore the failed entry,
           // so mark it as failed and continue
           entry = this.Archive.BackupIndex.FetchEntry(entry.ID);
           entry.State = SkyFloe.Backup.EntryState.Failed;
           this.Archive.BackupIndex.UpdateEntry(entry);
           break;
        default:
           // the client chose to abort, so propagate the exception
           throw;
     }
      }
      if (entry.State == SkyFloe.Backup.EntryState.Completed)
     ReportProgress(
        new ProgressEventArgs()
        {
           Operation = "EndBackupEntry",
           BackupSession = this.Session,
           BackupEntry = entry
        }
     );
 }