#region Disclaimer / License // Copyright (C) 2011, Kenneth Skovhede // http://www.hexad.dk, opensource@hexad.dk // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // #endregion using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; namespace Duplicati.Library.Main { /// /// This class is responsible for naming remote files, /// and parsing remote filenames /// internal class FilenameStrategy { //In Duplicati 1.0 there is only one manifest file, and it is called manifest or M in short mode //Issue# 58 introduced a backup manifest. Since 1.0 does not verify the manifest version number, // the name manifest/M is not used, which prevents 1.0 clients from reading the manifests and volumes. //The new names are manifestA and manifestB (A/B in short mode). //Future versions of Duplicati always verify the version number to avoid reading/writing data to a format // that is not supported. // //These are the strings that are used: private const string MANIFEST_OLD = "manifest"; private const string MANIFEST_A = "manifestA"; private const string MANIFEST_B = "manifestB"; private const string MANIFEST_OLD_SHORT = "M"; private const string MANIFEST_A_SHORT = "A"; private const string MANIFEST_B_SHORT = "B"; private const string CONTENT = "content"; private const string SIGNATURE = "signature"; private const string FULL = "full"; private const string INCREMENTAL = "inc"; private const string CONTENT_SHORT = "C"; private const string SIGNATURE_SHORT = "S"; private const string FULL_SHORT = "F"; private const string INCREMENTAL_SHORT = "I"; private const string VOLUME = "vol"; private const string DELETE_TRANSACTION_FILENAME = "delete.transaction"; //Note: Actually the K should be Z which is more correct as it is forced to be Z, but Z as a format specifier is fairly undocumented private const string TIMESTAMP_FORMAT = "yyyyMMdd'T'HHmmssK"; private bool m_useOldFilenames; private bool m_useShortFilenames; private string m_timeSeparator; private string m_prefix; private readonly Regex m_oldFilenameRegExp; private readonly Regex m_filenameRegExp; private readonly Regex m_shortRegExp; private readonly Regex m_verificationRegExp; private readonly Regex m_deleteTransactionRegExp; /// /// A cache used to ensure that filenames are consistent, /// even if the timezone changes in between filename generation /// private Dictionary m_timeStringCache; public FilenameStrategy(string prefix) : this(prefix, null, false, false) { } public FilenameStrategy(string prefix, string timeSeparator, bool useShortNames, bool oldFilenames) { m_prefix = prefix; m_timeSeparator = timeSeparator; m_useShortFilenames = useShortNames; m_useOldFilenames = oldFilenames; m_shortRegExp = new Regex( string.Format(@"(?{0})\-(?({1}|{2}|{3}|{4}|{5}))(?({6}|{7}))(?