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? }
private string RemoveBackupSets(BackendWrapper backend, List<ManifestEntry> entries) { StringBuilder sb = new StringBuilder(); sb.Append(backend.FinishDeleteTransaction(false)); if (entries.Count > 0) { System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); System.Xml.XmlNode root = doc.AppendChild(doc.CreateElement("files")); root.Attributes.Append(doc.CreateAttribute("version")).Value = "1"; foreach (ManifestEntry me in entries) { if (me.Alternate != null) root.AppendChild(doc.CreateElement("file")).InnerText = me.Alternate.Filename; root.AppendChild(doc.CreateElement("file")).InnerText = me.Filename; if (me.Verification != null) root.AppendChild(doc.CreateElement("file")).InnerText = me.Verification.Filename; foreach (KeyValuePair<SignatureEntry, ContentEntry> kx in me.Volumes) { root.AppendChild(doc.CreateElement("file")).InnerText = kx.Key.Filename; root.AppendChild(doc.CreateElement("file")).InnerText = kx.Value.Filename; } } if (m_options.Force) { using (TempFile tf = new TempFile()) { doc.Save(tf); tf.Protected = true; backend.WriteDeleteTransactionFile(tf); } } foreach (ManifestEntry me in entries) { sb.AppendLine(string.Format(Strings.Interface.DeletingBackupSetMessage, me.Time.ToString(System.Globalization.CultureInfo.InvariantCulture))); if (m_options.Force) { //Delete manifest if (me.Alternate != null) backend.Delete(me.Alternate); backend.Delete(me); if (me.Verification != null) backend.Delete(me.Verification); foreach (KeyValuePair<SignatureEntry, ContentEntry> kx in me.Volumes) { backend.Delete(kx.Key); backend.Delete(kx.Value); } } } if (m_options.Force) backend.RemoveDeleteTransactionFile(); if (!m_options.Force && entries.Count > 0) sb.AppendLine(Strings.Interface.FilesAreNotForceDeletedMessage); } return sb.ToString(); }