示例#1
0
        /// <summary>
        /// Constructs a new BackendWrapper
        /// </summary>
        /// <param name="statistics">The statistics logging module, may be null</param>
        /// <param name="backend">The url to the backend to wrap</param>
        /// <param name="options">A set of backend options</param>
        public BackendWrapper(CommunicationStatistics statistics, string backend, Options options)
        {
            m_statistics = statistics;
            m_options = options;

            m_filenamestrategy = new FilenameStrategy(m_options);
            m_backendUrl = backend;

            m_backend = Duplicati.Library.DynamicLoader.BackendLoader.GetBackend(backend, m_options.RawOptions);
            if (m_backend == null)
                throw new Exception(string.Format(Strings.BackendWrapper.BackendNotFoundError, backend));

            m_reuse_backend = !m_options.NoConnectionReuse;
            m_first_backend_use = true;
            m_backendSupportsCreateFolder = m_backend is Library.Interface.IBackend_v2;

            if (m_options.AutoCleanup)
                m_orphans = new List<BackupEntryBase>();

            if (!string.IsNullOrEmpty(m_options.SignatureCachePath) && !System.IO.Directory.Exists(m_options.SignatureCachePath))
                System.IO.Directory.CreateDirectory(m_options.SignatureCachePath);

            if (!string.IsNullOrEmpty(m_options.Backendlogdatabase))
            {
                m_backendInterfaceLogger = new StateVerification.StateDatabase(m_options.Backendlogdatabase, statistics);
                m_backendInterfaceLogger.BeginOperation(m_options.MainAction.ToString());
            }

            m_async = m_options.AsynchronousUpload;
            if (m_async)
            {
                //If we are using async operations, the entire class is actually threadsafe,
                //utilizing a common exclusive lock on all operations. But the implementation does
                //not prevent starvation, so it should not be called by multiple threads.
                m_pendingOperations = new Queue<KeyValuePair<BackupEntryBase, string>>();
                m_asyncItemProcessed = new System.Threading.AutoResetEvent(false);
                m_asyncItemReady = new System.Threading.AutoResetEvent(false);
                m_workerThread = new System.Threading.Thread(ProcessQueue);
                m_workerThread.Name = "AsyncUploaderThread";
                m_queuelock = new object();
                m_workerThread.Start();
            }
        }
示例#2
0
        internal VerificationFile(IEnumerable<ManifestEntry> parentChain, FilenameStrategy str)
        {
            m_doc = new System.Xml.XmlDocument();
            System.Xml.XmlNode root = m_doc.AppendChild(m_doc.CreateElement("Verify"));
            root.Attributes.Append(m_doc.CreateAttribute("hash-algorithm")).Value = Utility.Utility.HashAlgorithm;
            root.Attributes.Append(m_doc.CreateAttribute("version")).Value = "1";

            m_node = root.AppendChild(m_doc.CreateElement("Files"));

            foreach (ManifestEntry mfe in parentChain)
            {
                System.Xml.XmlNode f = m_node.AppendChild(m_doc.CreateElement("File"));
                f.Attributes.Append(m_doc.CreateAttribute("type")).Value = "manifest";
                f.Attributes.Append(m_doc.CreateAttribute("name")).Value = mfe.Filename;
                f.Attributes.Append(m_doc.CreateAttribute("size")).Value = mfe.Filesize.ToString();
                f.InnerText = Utility.Utility.ByteArrayAsHexString(Convert.FromBase64String(mfe.RemoteHash));

                for (int i = 0; i < mfe.ParsedManifest.SignatureHashes.Count; i++)
                {
                    string sigfilename = mfe.ParsedManifest.SignatureHashes[i].Name;
                    string contentfilename = mfe.ParsedManifest.ContentHashes[i].Name;
                    bool missing = i >= mfe.Volumes.Count;

                    if (string.IsNullOrEmpty(sigfilename) || string.IsNullOrEmpty(contentfilename))
                    {
                        if (missing)
                        {
                            sigfilename = str.GenerateFilename(new SignatureEntry(mfe.Time, mfe.IsFull, i + 1));
                            contentfilename = str.GenerateFilename(new ContentEntry(mfe.Time, mfe.IsFull, i + 1));

                            //Since these files are missing, we have to guess what their real names were
                            string compressionGuess;
                            if (mfe.Volumes.Count <= 0)
                                compressionGuess = ".zip"; //Default if we have no knowledge
                            else
                                compressionGuess = "." + mfe.Volumes[0].Key.Compression; //Most likely the same as all the others

                            //Encryption will likely be the same as the one the manifest uses
                            string encryptionGuess = string.IsNullOrEmpty(mfe.EncryptionMode) ? "" : "." + mfe.EncryptionMode;

                            sigfilename += compressionGuess + encryptionGuess;
                            contentfilename += compressionGuess + encryptionGuess;
                        }
                        else
                        {
                            sigfilename = mfe.Volumes[i].Key.Filename;
                            contentfilename = mfe.Volumes[i].Value.Filename;
                        }
                    }

                    f = m_node.AppendChild(m_doc.CreateElement("File"));
                    f.Attributes.Append(m_doc.CreateAttribute("type")).Value = "signature";
                    f.Attributes.Append(m_doc.CreateAttribute("name")).Value = sigfilename;
                    f.Attributes.Append(m_doc.CreateAttribute("size")).Value = mfe.ParsedManifest.SignatureHashes[i].Size.ToString();
                    if (missing) f.Attributes.Append(m_doc.CreateAttribute("missing")).Value = "true";
                    f.InnerText = Utility.Utility.ByteArrayAsHexString(Convert.FromBase64String(mfe.ParsedManifest.SignatureHashes[i].Hash));

                    f = m_node.AppendChild(m_doc.CreateElement("File"));
                    f.Attributes.Append(m_doc.CreateAttribute("type")).Value = "content";
                    f.Attributes.Append(m_doc.CreateAttribute("name")).Value = contentfilename;
                    f.Attributes.Append(m_doc.CreateAttribute("size")).Value = mfe.ParsedManifest.ContentHashes[i].Size.ToString();
                    if (missing) f.Attributes.Append(m_doc.CreateAttribute("missing")).Value = "true";
                    f.InnerText = Utility.Utility.ByteArrayAsHexString(Convert.FromBase64String(mfe.ParsedManifest.ContentHashes[i].Hash));
                }
            }
        }