Esempio n. 1
0
        public string Cleanup()
        {
            CommunicationStatistics stats = new CommunicationStatistics(XervBackupOperationMode.CleanUp);
            SetupCommonOptions(stats);

            bool anyRemoved = false;
            StringBuilder sb = new StringBuilder();
            using (BackendWrapper backend = new BackendWrapper(stats, m_backend, m_options))
            {
                List<ManifestEntry> sorted = backend.GetBackupSets();

                List<ManifestEntry> entries = new List<ManifestEntry>();
                entries.AddRange(sorted);
                foreach (ManifestEntry be in sorted)
                    entries.AddRange(be.Incrementals);

                string cleanup = backend.DeleteOrphans(false);
                if (!string.IsNullOrEmpty(cleanup))
                    sb.AppendLine(cleanup);

                if (m_options.SkipFileHashChecks)
                    throw new Exception(Strings.Interface.CannotCleanWithoutHashesError);
                if (m_options.DontReadManifests)
                    throw new Exception(Strings.Interface.CannotCleanWithoutHashesError);

                //We need the manifests anyway, so we verify the chain
                if (entries.Count > 0)
                    VerifyManifestChain(backend, entries[0]);

                //Now compare the actual filelist with the manifest
                foreach (ManifestEntry be in entries)
                {
                    Manifestfile manifest = GetManifest(backend, be);

                    int count = manifest.ContentHashes.Count;

                    for (int i = count - 1; i < be.Volumes.Count; i++)
                    {
                        anyRemoved = true;

                        string sigmsg = string.Format(Strings.Interface.RemovingPartialFilesMessage, be.Volumes[i].Key.Filename);
                        string cntmsg = string.Format(Strings.Interface.RemovingPartialFilesMessage, be.Volumes[i].Value.Filename);

                        Logging.Log.WriteMessage(sigmsg, XervBackup.Library.Logging.LogMessageType.Information);
                        Logging.Log.WriteMessage(cntmsg, XervBackup.Library.Logging.LogMessageType.Information);

                        sb.AppendLine(sigmsg);
                        sb.AppendLine(cntmsg);

                        if (m_options.Force)
                        {
                            backend.Delete(be.Volumes[i].Key);
                            backend.Delete(be.Volumes[i].Value);
                        }
                    }
                }
            }

            if (!m_options.Force && anyRemoved)
            {
                Logging.Log.WriteMessage(Strings.Interface.FilesAreNotForceDeletedMessage, XervBackup.Library.Logging.LogMessageType.Information);
                sb.AppendLine(Strings.Interface.FilesAreNotForceDeletedMessage);
            }

            return sb.ToString(); //TODO: Write a message here?
        }
Esempio n. 2
0
        /// <summary>
        /// Downloads all required signature files from the backend.
        /// </summary>
        /// <param name="backend">The backend to read from</param>
        /// <param name="entries">The flattened list of manifests</param>
        /// <param name="tempfolder">The tempfolder set for this operation</param>
        /// <param name="allowHashFail">True to ignore files with failed hash signature</param>
        /// <returns>A list of file archives</returns>
        private List<KeyValuePair<ManifestEntry, Library.Interface.ICompression>> FindPatches(BackendWrapper backend, List<ManifestEntry> entries, string tempfolder, bool allowHashFail, CommunicationStatistics stat)
        {
            List<KeyValuePair<ManifestEntry, Library.Interface.ICompression>> patches = new List<KeyValuePair<ManifestEntry, Library.Interface.ICompression>>();

            using (new Logging.Timer("Reading incremental data"))
            {
                OperationProgress(this, GetOperationType(), stat.OperationMode, (int)(m_progress * 100), -1, Strings.Interface.StatusReadingIncrementalData, "");

                //Calculate the total number of files to download
                //, and verify their order
                int incCount = 0;
                foreach (ManifestEntry be in entries)
                {
                    int volNo = 0;
                    //Prevent order based bugs
                    if (entries.IndexOf(be) > 0)
                        if (entries[entries.IndexOf(be) - 1].Time >= be.Time)
                            throw new Exception(Strings.Interface.BadSortingDetectedError);

                    incCount++;
                    foreach (KeyValuePair<SignatureEntry, ContentEntry> bes in be.Volumes)
                    {
                        incCount++;
                        if (volNo + 1 != bes.Key.Volumenumber || bes.Key.Volumenumber != bes.Value.Volumenumber)
                            throw new Exception(Strings.Interface.BadVolumeSortOrder);

                        volNo++;
                    }
                }

                //The incremental part has a fixed cost, and each file has a fixed fraction of that
                double unitCost = m_incrementalFraction / incCount;

                //Ensure that the manifest chain has not been tampered with
                // since we will read all manifest files anyway, there is no harm in doing it here
                if (!m_options.DontReadManifests && entries.Count > 0)
                    VerifyManifestChain(backend, entries[entries.Count - 1]);

                foreach (ManifestEntry be in entries)
                {
                    m_progress += unitCost;

                    Manifestfile manifest = GetManifest(backend, be);

                    foreach (KeyValuePair<SignatureEntry, ContentEntry> bes in be.Volumes)
                    {
                        m_progress += unitCost;

                        //Skip non-listed incrementals
                        if (manifest.SignatureHashes != null && bes.Key.Volumenumber > manifest.SignatureHashes.Count)
                        {
                            backend.AddOrphan(bes.Key);
                            backend.AddOrphan(bes.Value);
                            continue;
                        }

                        OperationProgress(this, GetOperationType(), stat.OperationMode, (int)(m_progress * 100), -1, string.Format(Strings.Interface.StatusReadingSignatureFile, be.Time.ToShortDateString() + " " + be.Time.ToShortTimeString(), bes.Key.Volumenumber), "");

                        string filename = System.IO.Path.Combine(tempfolder, "patch-" + patches.Count.ToString() + ".zip");

                        //Check just before we download stuff
                        CheckLiveControl();
                        try
                        {
                            using (new Logging.Timer("Get " + bes.Key.Filename))
                                backend.Get(bes.Key, manifest, filename, manifest.SignatureHashes == null ? null : manifest.SignatureHashes[bes.Key.Volumenumber - 1]);
                        }
                        catch (BackendWrapper.HashMismathcException hme)
                        {
                            if (allowHashFail)
                            {
                                if (stat != null)
                                    stat.LogError(string.Format(Strings.Interface.FileHashFailure, hme.Message), hme);
                                continue;
                            }
                            else
                                throw;
                        }

                        patches.Add(new KeyValuePair<ManifestEntry,XervBackup.Library.Interface.ICompression>(be, DynamicLoader.CompressionLoader.GetModule(bes.Key.Compression, filename, m_options.RawOptions)));
                    }
                }
            }

            backend.DeleteOrphans(true);

            return patches;
        }