/// <summary> /// Appends a file to the content and signature archives, watching the content archive file size. /// Returns the partial file entry if the volume size was exceeded. /// Returns null if the file was written entirely. /// </summary> /// <param name="entry">The entry that describes the partial file</param> /// <param name="contentfile">The content archive file</param> /// <param name="signaturefile">The signature archive file</param> /// <param name="volumesize">The max allowed volumesize</param> /// <returns>The partial file entry if the volume size was exceeded. Returns null if the file was written entirely.</returns> private PartialFileEntry WritePossiblePartial(PartialFileEntry entry, Library.Interface.ICompression contentfile, Library.Interface.ICompression signaturefile, long volumesize) { long startPos = entry.Stream.Position; //Protect against writing this file if there is not enough space to hold the INCOMPLETE_FILE if (startPos == 0 && contentfile.Size + contentfile.FlushBufferSize + (entry.ExtraSize * 2) > volumesize) return entry; PartialFileEntry pe = WritePossiblePartialInternal(entry, contentfile, volumesize); if (pe != null) { //The record is (still) partial string[] tmplines = new PartialEntryRecord(entry.relativeName, startPos, entry.Stream.Position - startPos, entry.Stream.Length).Serialize(); contentfile.WriteAllLines(INCOMPLETE_FILE, tmplines); signaturefile.WriteAllLines(INCOMPLETE_FILE, tmplines); //If we are debugging, this can be nice to have Logging.Log.WriteMessage(string.Format(Strings.RSyncDir.PartialFileAddedLogMessage, entry.relativeName, startPos), XervBackup.Library.Logging.LogMessageType.Information); } else { //If the file was partial before, mark the file as completed if (startPos != 0) { string[] tmplines = new PartialEntryRecord(entry.relativeName, startPos, entry.Stream.Position - startPos, entry.Stream.Length).Serialize(); contentfile.WriteAllLines(COMPLETED_FILE, tmplines); signaturefile.WriteAllLines(COMPLETED_FILE, tmplines); } //Add signature AFTER content is completed. //If content is present, it is restoreable, if signature is missing, file will be backed up on next run //If signature is present, but not content, the entire differential sequence will be unable to recover the file if (!entry.DumpSignature(signaturefile)) { if (m_stat != null) m_stat.LogWarning(string.Format(Strings.RSyncDir.FileChangedWhileReadWarning, entry.fullname), null); } entry.Dispose(); } return pe; }