Esempio n. 1
0
        public BackendManager(string backendurl, Options options, IBackendWriter statwriter, LocalDatabase database)
        {
            m_options = options;
            m_backendurl = backendurl;
            m_statwriter = statwriter;
            m_taskControl = statwriter as BasicResults;
            m_db = new DatabaseCollector(database, statwriter);

            m_backend = DynamicLoader.BackendLoader.GetBackend(m_backendurl, m_options.RawOptions);
            if (m_backend == null)
                throw new Exception(string.Format("Backend not supported: {0}", m_backendurl));

            if (!m_options.NoEncryption)
            {
                m_encryption = DynamicLoader.EncryptionLoader.GetModule(m_options.EncryptionModule, m_options.Passphrase, m_options.RawOptions);
                if (m_encryption == null)
                    throw new Exception(string.Format("Encryption method not supported: ", m_options.EncryptionModule));
            }

            if (m_taskControl != null)
                m_taskControl.StateChangedEvent += (state) => {
                    if (state == TaskControlState.Abort)
                        m_thread.Abort();
                };
            m_queue = new BlockingQueue<FileEntryItem>(options.SynchronousUpload ? 1 : (options.AsynchronousUploadLimit == 0 ? int.MaxValue : options.AsynchronousUploadLimit));
            m_thread = new System.Threading.Thread(this.ThreadRun);
            m_thread.Name = "Backend Async Worker";
            m_thread.IsBackground = true;
            m_thread.Start();
        }
Esempio n. 2
0
        public RawContainer(IWizardControl nextpage, Library.Interface.IBackend backend, IDictionary <string, string> settings)
            : base(nextpage, backend.SupportedCommands, settings, "backend:" + backend.ProtocolKey, backend.DisplayName, backend.Description)
        {
            InitializeComponent();

            m_backend        = backend;
            ProtocolKey.Text = m_backend.ProtocolKey + "://";
        }
Esempio n. 3
0
        public RawContainer(IWizardControl nextpage, Library.Interface.IBackend backend, IDictionary<string, string> settings)
            : base(nextpage, backend.SupportedCommands, settings, "backend:" + backend.ProtocolKey, backend.DisplayName, backend.Description)
        {
            InitializeComponent();

            m_backend = backend;
            ProtocolKey.Text = m_backend.ProtocolKey + "://";
        }
Esempio n. 4
0
        private void Item_CheckChanged(object sender, EventArgs e)
        {
            Library.Interface.IBackend selectedBackend = null;
            foreach (RadioButton button in BackendList.Controls)
            {
                if (button.Checked && button.Tag is Library.Interface.IBackend)
                {
                    selectedBackend = button.Tag as Library.Interface.IBackend;
                }
            }

            m_owner.NextButton.Enabled = selectedBackend != null;
        }
Esempio n. 5
0
        protected virtual string SetupBackend(Dictionary <string, string> environment, Dictionary <string, string> options)
        {
            Library.Interface.IBackend selectedBackend = null;
            foreach (Library.Interface.IBackend b in Library.DynamicLoader.BackendLoader.Backends)
            {
                if (b.ProtocolKey == this.Task.Service)
                {
                    selectedBackend = b;
                    break;
                }
            }

            if (selectedBackend == null)
            {
                throw new Exception("Missing backend");
            }

            string destination;

            if (selectedBackend is Library.Interface.IBackendGUI)
            {
                //Simply invoke the backends setup function
                destination = ((Library.Interface.IBackendGUI)selectedBackend).GetConfiguration(environment, this.Task.BackendSettingsLookup, options);
            }
            else
            {
                //We store destination with the key "Destination" and other options with the -- prefix
                if (!options.ContainsKey(Duplicati.GUI.Wizard_pages.GridContainer.DESTINATION_EXTENSION_KEY))
                {
                    throw new Exception("Invalid configuration");
                }

                destination = options[Duplicati.GUI.Wizard_pages.GridContainer.DESTINATION_EXTENSION_KEY];
                foreach (KeyValuePair <string, string> k in this.Task.BackendSettingsLookup)
                {
                    if (k.Key.StartsWith("--")) //All options are prefixed with this
                    {
                        options[k.Key.Substring(2)] = k.Value;
                    }
                }
            }

            return(destination);
        }
Esempio n. 6
0
        static bool Run(List <string> args, Dictionary <string, string> options, bool first)
        {
            Library.Interface.IBackend backend = Library.DynamicLoader.BackendLoader.GetBackend(args[0], options);
            if (backend == null)
            {
                Console.WriteLine("Unsupported backend");
                Console.WriteLine();
                Console.WriteLine("Supported backends: " + string.Join(",", Duplicati.Library.DynamicLoader.BackendLoader.Keys));
                return(false);
            }

            string allowedChars = ValidFilenameChars;

            if (options.ContainsKey("extended-chars"))
            {
                allowedChars += String.IsNullOrEmpty(options["extended-chars"]) ? ExtendedChars : options["extended-chars"];
            }

            bool autoCreateFolders = Library.Utility.Utility.ParseBoolOption(options, "auto-create-folder");

            string disabledModulesValue;
            string enabledModulesValue;

            options.TryGetValue("enable-module", out enabledModulesValue);
            options.TryGetValue("disable-module", out disabledModulesValue);
            string[] enabledModules  = enabledModulesValue == null ? new string[0] : enabledModulesValue.Trim().ToLower(CultureInfo.InvariantCulture).Split(',');
            string[] disabledModules = disabledModulesValue == null ? new string[0] : disabledModulesValue.Trim().ToLower(CultureInfo.InvariantCulture).Split(',');

            List <Library.Interface.IGenericModule> loadedModules = new List <IGenericModule>();

            foreach (Library.Interface.IGenericModule m in Library.DynamicLoader.GenericLoader.Modules)
            {
                if (!disabledModules.Contains(m.Key, StringComparer.OrdinalIgnoreCase) && (m.LoadAsDefault || enabledModules.Contains(m.Key, StringComparer.OrdinalIgnoreCase)))
                {
                    m.Configure(options);
                    loadedModules.Add(m);
                }
            }

            try
            {
                IEnumerable <Library.Interface.IFileEntry> curlist = null;
                try
                {
                    backend.Test();
                    curlist = backend.List();
                }
                catch (FolderMissingException)
                {
                    if (autoCreateFolders)
                    {
                        try
                        {
                            backend.CreateFolder();
                            curlist = backend.List();
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("Autocreate folder failed with message: " + ex.Message);
                        }
                    }

                    if (curlist == null)
                    {
                        throw;
                    }
                }

                foreach (Library.Interface.IFileEntry fe in curlist)
                {
                    if (!fe.IsFolder)
                    {
                        if (Library.Utility.Utility.ParseBoolOption(options, "auto-clean") && first)
                        {
                            if (Library.Utility.Utility.ParseBoolOption(options, "force"))
                            {
                                Console.WriteLine("Auto clean, removing file: {0}", fe.Name);
                                backend.Delete(fe.Name);
                                continue;
                            }
                            else
                            {
                                Console.WriteLine("Specify the --force flag to actually delete files");
                            }
                        }

                        Console.WriteLine("*** Remote folder is not empty, aborting");
                        return(false);
                    }
                }


                int  number_of_files    = 10;
                int  min_file_size      = 1024;
                int  max_file_size      = 1024 * 1024 * 50;
                int  min_filename_size  = 5;
                int  max_filename_size  = 80;
                bool disableStreaming   = Library.Utility.Utility.ParseBoolOption(options, "disable-streaming-transfers");
                bool skipOverwriteTest  = Library.Utility.Utility.ParseBoolOption(options, "skip-overwrite-test");
                bool trimFilenameSpaces = Library.Utility.Utility.ParseBoolOption(options, "trim-filename-spaces");

                if (options.ContainsKey("number-of-files"))
                {
                    number_of_files = int.Parse(options["number-of-files"]);
                }
                if (options.ContainsKey("min-file-size"))
                {
                    min_file_size = (int)Duplicati.Library.Utility.Sizeparser.ParseSize(options["min-file-size"], "mb");
                }
                if (options.ContainsKey("max-file-size"))
                {
                    max_file_size = (int)Duplicati.Library.Utility.Sizeparser.ParseSize(options["max-file-size"], "mb");
                }

                if (options.ContainsKey("min-filename-length"))
                {
                    min_filename_size = int.Parse(options["min-filename-length"]);
                }
                if (options.ContainsKey("max-filename-length"))
                {
                    max_filename_size = int.Parse(options["max-filename-length"]);
                }

                Random rnd = new Random();
                System.Security.Cryptography.SHA256 sha = System.Security.Cryptography.SHA256.Create();

                //Create random files
                using (Library.Utility.TempFolder tf = new Duplicati.Library.Utility.TempFolder())
                {
                    List <TempFile> files = new List <TempFile>();
                    for (int i = 0; i < number_of_files; i++)
                    {
                        string filename = CreateRandomRemoteFileName(min_filename_size, max_filename_size, allowedChars, trimFilenameSpaces, rnd);

                        string localfilename = CreateRandomFile(tf, i, min_file_size, max_file_size, rnd);

                        //Calculate local hash and length
                        using (System.IO.FileStream fs = new System.IO.FileStream(localfilename, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                            files.Add(new TempFile(filename, localfilename, sha.ComputeHash(fs), fs.Length));
                    }

                    byte[] dummyFileHash = null;
                    if (!skipOverwriteTest)
                    {
                        Console.WriteLine("Uploading wrong files ...");
                        using (Library.Utility.TempFile dummy = Library.Utility.TempFile.WrapExistingFile(CreateRandomFile(tf, files.Count, 1024, 2048, rnd)))
                        {
                            using (System.IO.FileStream fs = new System.IO.FileStream(dummy, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                dummyFileHash = sha.ComputeHash(fs);

                            //Upload a dummy file for entry 0 and the last one, they will be replaced by the real files afterwards
                            //We upload entry 0 twice just to try to freak any internal cache list
                            Uploadfile(dummy, 0, files[0].remotefilename, backend, disableStreaming);
                            Uploadfile(dummy, 0, files[0].remotefilename, backend, disableStreaming);
                            Uploadfile(dummy, files.Count - 1, files[files.Count - 1].remotefilename, backend, disableStreaming);
                        }
                    }

                    Console.WriteLine("Uploading files ...");

                    for (int i = 0; i < files.Count; i++)
                    {
                        Uploadfile(files[i].localfilename, i, files[i].remotefilename, backend, disableStreaming);
                    }

                    TempFile originalRenamedFile = null;
                    string   renamedFileNewName  = null;
                    IRenameEnabledBackend renameEnabledBackend = backend as IRenameEnabledBackend;
                    if (renameEnabledBackend != null)
                    {
                        // Rename the second file in the list, if there are more than one. If not, just do the first one.
                        int renameIndex = files.Count > 1 ? 1 : 0;
                        originalRenamedFile = files[renameIndex];

                        renamedFileNewName = CreateRandomRemoteFileName(min_filename_size, max_filename_size, allowedChars, trimFilenameSpaces, rnd);

                        Console.WriteLine("Renaming file {0} from {1} to {2}", renameIndex, originalRenamedFile.remotefilename, renamedFileNewName);

                        renameEnabledBackend.Rename(originalRenamedFile.remotefilename, renamedFileNewName);
                        files[renameIndex] = new TempFile(renamedFileNewName, originalRenamedFile.localfilename, originalRenamedFile.hash, originalRenamedFile.length);
                    }

                    Console.WriteLine("Verifying file list ...");

                    curlist = backend.List();
                    foreach (Library.Interface.IFileEntry fe in curlist)
                    {
                        if (!fe.IsFolder)
                        {
                            bool found = false;
                            foreach (TempFile tx in files)
                            {
                                if (tx.remotefilename == fe.Name)
                                {
                                    if (tx.found)
                                    {
                                        Console.WriteLine("*** File with name {0} was found more than once", tx.remotefilename);
                                    }
                                    found    = true;
                                    tx.found = true;

                                    if (fe.Size > 0 && tx.length != fe.Size)
                                    {
                                        Console.WriteLine("*** File with name {0} has size {1} but the size was reported as {2}", tx.remotefilename, tx.length, fe.Size);
                                    }

                                    break;
                                }
                            }

                            if (!found)
                            {
                                if (originalRenamedFile != null && renamedFileNewName != null && originalRenamedFile.remotefilename == fe.Name)
                                {
                                    Console.WriteLine("*** File with name {0} was found on server but was supposed to have been renamed to {1}!", fe.Name, renamedFileNewName);
                                }
                                else
                                {
                                    Console.WriteLine("*** File with name {0} was found on server but not uploaded!", fe.Name);
                                }
                            }
                        }
                    }

                    foreach (TempFile tx in files)
                    {
                        if (!tx.found)
                        {
                            Console.WriteLine("*** File with name {0} was uploaded but not found afterwards", tx.remotefilename);
                        }
                    }

                    Console.WriteLine("Downloading files");

                    for (int i = 0; i < files.Count; i++)
                    {
                        using (Duplicati.Library.Utility.TempFile cf = new Duplicati.Library.Utility.TempFile())
                        {
                            Exception e = null;
                            Console.Write("Downloading file {0} ... ", i);

                            try
                            {
                                if (backend is IStreamingBackend streamingBackend && !disableStreaming)
                                {
                                    using (System.IO.FileStream fs = new System.IO.FileStream(cf, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
                                        using (NonSeekableStream nss = new NonSeekableStream(fs))
                                            streamingBackend.Get(files[i].remotefilename, nss);
                                }
                                else
                                {
                                    backend.Get(files[i].remotefilename, cf);
                                }

                                e = null;
                            }
                            catch (Exception ex)
                            {
                                e = ex;
                            }

                            if (e != null)
                            {
                                Console.WriteLine("failed\n*** Error: {0}", e);
                            }
                            else
                            {
                                Console.WriteLine("done");
                            }

                            Console.Write("Checking hash ... ");

                            using (System.IO.FileStream fs = new System.IO.FileStream(cf, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                if (Convert.ToBase64String(sha.ComputeHash(fs)) != Convert.ToBase64String(files[i].hash))
                                {
                                    if (dummyFileHash != null && Convert.ToBase64String(sha.ComputeHash(fs)) == Convert.ToBase64String(dummyFileHash))
                                    {
                                        Console.WriteLine("failed\n*** Downloaded file was the dummy file");
                                    }
                                    else
                                    {
                                        Console.WriteLine("failed\n*** Downloaded file was corrupt");
                                    }
                                }
                                else
                                {
                                    Console.WriteLine("done");
                                }
                        }
Esempio n. 7
0
        static bool Run(List <string> args, Dictionary <string, string> options, bool first)
        {
            string allowedChars = ValidFilenameChars;

            if (options.ContainsKey("extended-chars"))
            {
                allowedChars += options["extended-chars"];
            }
            else
            {
                allowedChars += ExtendedChars;
            }

            bool autoCreateFolders = Library.Utility.Utility.ParseBoolOption(options, "auto-create-folder");

            Library.Interface.IBackend backend = Library.DynamicLoader.BackendLoader.GetBackend(args[0], options);
            if (backend == null)
            {
                Console.WriteLine("Unsupported backend");
                Console.WriteLine();
                Console.WriteLine("Supported backends: " + string.Join(",", Duplicati.Library.DynamicLoader.BackendLoader.Keys));
                return(false);
            }

            string disabledModulesValue;
            string enabledModulesValue;

            options.TryGetValue("enable-module", out enabledModulesValue);
            options.TryGetValue("disable-module", out disabledModulesValue);
            string[] enabledModules  = enabledModulesValue == null ? new string[0] : enabledModulesValue.Trim().ToLower().Split(',');
            string[] disabledModules = disabledModulesValue == null ? new string[0] : disabledModulesValue.Trim().ToLower().Split(',');

            List <Library.Interface.IGenericModule> loadedModules = new List <IGenericModule>();

            foreach (Library.Interface.IGenericModule m in Library.DynamicLoader.GenericLoader.Modules)
            {
                if (Array.IndexOf <string>(disabledModules, m.Key.ToLower()) < 0 && (m.LoadAsDefault || Array.IndexOf <string>(enabledModules, m.Key.ToLower()) >= 0))
                {
                    m.Configure(options);
                    loadedModules.Add(m);
                }
            }

            try
            {
                List <Library.Interface.IFileEntry> curlist = null;
                try
                {
                    curlist = backend.List();
                }
                catch (FolderMissingException fex)
                {
                    if (autoCreateFolders)
                    {
                        try
                        {
                            if (backend is IBackend_v2)
                            {
                                ((IBackend_v2)backend).CreateFolder();
                            }

                            curlist = backend.List();
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("Autocreate folder failed with message: " + ex.Message);
                        }
                    }

                    if (curlist == null)
                    {
                        throw fex;
                    }
                }

                foreach (Library.Interface.IFileEntry fe in curlist)
                {
                    if (!fe.IsFolder)
                    {
                        if (Library.Utility.Utility.ParseBoolOption(options, "auto-clean") && first)
                        {
                            if (Library.Utility.Utility.ParseBoolOption(options, "force"))
                            {
                                Console.WriteLine("Auto clean, removing file: {0}", fe.Name);
                                backend.Delete(fe.Name);
                                continue;
                            }
                            else
                            {
                                Console.WriteLine("Specify the --force flag to actually delete files");
                            }
                        }

                        Console.WriteLine("*** Remote folder is not empty, aborting");
                        return(false);
                    }
                }


                int  number_of_files   = 10;
                int  min_file_size     = 1024;
                int  max_file_size     = 1024 * 1024 * 50;
                int  min_filename_size = 5;
                int  max_filename_size = 80;
                bool disableStreaming  = Library.Utility.Utility.ParseBoolOption(options, "disable-streaming-transfers");
                bool skipOverwriteTest = Library.Utility.Utility.ParseBoolOption(options, "skip-overwrite-test");

                if (options.ContainsKey("number-of-files"))
                {
                    number_of_files = int.Parse(options["number-of-files"]);
                }
                if (options.ContainsKey("min-file-size"))
                {
                    min_file_size = (int)Duplicati.Library.Utility.Sizeparser.ParseSize(options["min-file-size"], "mb");
                }
                if (options.ContainsKey("max-file-size"))
                {
                    max_file_size = (int)Duplicati.Library.Utility.Sizeparser.ParseSize(options["max-file-size"]);
                }

                if (options.ContainsKey("min-filename-length"))
                {
                    min_filename_size = int.Parse(options["min-filename-length"]);
                }
                if (options.ContainsKey("max-filename-length"))
                {
                    max_filename_size = int.Parse(options["max-filename-length"]);
                }

                Random rnd = new Random();
                System.Security.Cryptography.SHA256 sha = System.Security.Cryptography.SHA256.Create();

                //Create random files
                using (Library.Utility.TempFolder tf = new Duplicati.Library.Utility.TempFolder())
                {
                    List <TempFile> files = new List <TempFile>();
                    for (int i = 0; i < number_of_files; i++)
                    {
                        StringBuilder filename    = new StringBuilder();
                        int           filenamelen = rnd.Next(min_filename_size, max_filename_size);
                        for (int j = 0; j < filenamelen; j++)
                        {
                            filename.Append(allowedChars[rnd.Next(0, allowedChars.Length)]);
                        }

                        string localfilename = CreateRandomFile(tf, i, min_file_size, max_file_size, rnd);

                        //Calculate local hash and length
                        using (System.IO.FileStream fs = new System.IO.FileStream(localfilename, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                            files.Add(new TempFile(filename.ToString(), localfilename, sha.ComputeHash(fs), fs.Length));
                    }

                    byte[] dummyFileHash = null;
                    if (!skipOverwriteTest)
                    {
                        Console.WriteLine("Uploading wrong files ...");
                        using (Library.Utility.TempFile dummy = new Library.Utility.TempFile(CreateRandomFile(tf, files.Count, 1024, 2048, rnd)))
                        {
                            using (System.IO.FileStream fs = new System.IO.FileStream(dummy, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                dummyFileHash = sha.ComputeHash(fs);

                            //Upload a dummy file for entry 0 and the last one, they will be replaced by the real files afterwards
                            //We upload entry 0 twice just to try to freak any internal cache list
                            Uploadfile(dummy, 0, files[0].remotefilename, backend, disableStreaming);
                            Uploadfile(dummy, 0, files[0].remotefilename, backend, disableStreaming);
                            Uploadfile(dummy, files.Count - 1, files[files.Count - 1].remotefilename, backend, disableStreaming);
                        }
                    }

                    Console.WriteLine("Uploading files ...");

                    for (int i = 0; i < files.Count; i++)
                    {
                        Uploadfile(files[i].localfilename, i, files[i].remotefilename, backend, disableStreaming);
                    }

                    Console.WriteLine("Verifying file list ...");

                    curlist = backend.List();
                    foreach (Library.Interface.IFileEntry fe in curlist)
                    {
                        if (!fe.IsFolder)
                        {
                            bool found = false;
                            foreach (TempFile tx in files)
                            {
                                if (tx.remotefilename == fe.Name)
                                {
                                    if (tx.found)
                                    {
                                        Console.WriteLine("*** File with name {0} was found more than once", tx.remotefilename);
                                    }
                                    found    = true;
                                    tx.found = true;

                                    if (fe.Size > 0 && tx.length != fe.Size)
                                    {
                                        Console.WriteLine("*** File with name {0} has size {1} but the size was reported as {2}", tx.remotefilename, tx.length, fe.Size);
                                    }

                                    break;
                                }
                            }

                            if (!found)
                            {
                                Console.WriteLine("*** File with name {0} was found on server but not uploaded!", fe.Name);
                            }
                        }
                    }

                    foreach (TempFile tx in files)
                    {
                        if (!tx.found)
                        {
                            Console.WriteLine("*** File with name {0} was uploaded but not found afterwards", tx.remotefilename);
                        }
                    }

                    Console.WriteLine("Downloading files");

                    for (int i = 0; i < files.Count; i++)
                    {
                        using (Duplicati.Library.Utility.TempFile cf = new Duplicati.Library.Utility.TempFile())
                        {
                            Exception e = null;
                            Console.Write("Downloading file {0} ... ", i);

                            try
                            {
                                if (backend is Library.Interface.IStreamingBackend && !disableStreaming)
                                {
                                    using (System.IO.FileStream fs = new System.IO.FileStream(cf, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
                                        using (NonSeekableStream nss = new NonSeekableStream(fs))
                                            (backend as Library.Interface.IStreamingBackend).Get(files[i].remotefilename, nss);
                                }
                                else
                                {
                                    backend.Get(files[i].remotefilename, cf);
                                }

                                e = null;
                            }
                            catch (Exception ex)
                            {
                                e = ex;
                            }

                            if (e != null)
                            {
                                Console.WriteLine("failed\n*** Error: {0}", e.ToString());
                            }
                            else
                            {
                                Console.WriteLine("done");
                            }

                            Console.Write("Checking hash ... ");

                            using (System.IO.FileStream fs = new System.IO.FileStream(cf, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                if (Convert.ToBase64String(sha.ComputeHash(fs)) != Convert.ToBase64String(files[i].hash))
                                {
                                    if (dummyFileHash != null && Convert.ToBase64String(sha.ComputeHash(fs)) == Convert.ToBase64String(dummyFileHash))
                                    {
                                        Console.WriteLine("failed\n*** Downloaded file was the dummy file");
                                    }
                                    else
                                    {
                                        Console.WriteLine("failed\n*** Downloaded file was corrupt");
                                    }
                                }
                                else
                                {
                                    Console.WriteLine("done");
                                }
                        }
                    }

                    Console.WriteLine("Deleting files...");

                    foreach (TempFile tx in files)
                    {
                        try { backend.Delete(tx.remotefilename); }
                        catch (Exception ex)
                        {
                            Console.WriteLine("*** Failed to delete file {0}, message: {1}", tx.remotefilename, ex.ToString());
                        }
                    }

                    curlist = backend.List();
                    foreach (Library.Interface.IFileEntry fe in curlist)
                    {
                        if (!fe.IsFolder)
                        {
                            Console.WriteLine("*** Remote folder contains {0} after cleanup", fe.Name);
                        }
                    }
                }
            }
            finally
            {
                foreach (Library.Interface.IGenericModule m in loadedModules)
                {
                    if (m is IDisposable)
                    {
                        ((IDisposable)m).Dispose();
                    }
                }
            }

            return(true);
        }
Esempio n. 8
0
        void SelectBackend_PageLeave(object sender, PageChangedArgs args)
        {
            if (args.Direction == PageChangedDirection.Back)
            {
                return;
            }

            Library.Interface.IBackend selectedBackend = null;
            foreach (RadioButton button in BackendList.Controls)
            {
                if (button.Checked && button.Tag is Library.Interface.IBackend)
                {
                    selectedBackend = button.Tag as Library.Interface.IBackend;
                }
            }

            if (selectedBackend == null)
            {
                MessageBox.Show(this, Strings.SelectBackend.NoActionSelected, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                args.Cancel = true;
                return;
            }

            //If the user chooses another backend, we need to clear the settings,
            // so items like the tested flag are not set
            if (m_wrapper.Backend != selectedBackend.ProtocolKey)
            {
                m_wrapper.BackendSettings.Clear();
            }

            m_wrapper.Backend = selectedBackend.ProtocolKey;

            if (m_wrapper.PrimayAction == WizardSettingsWrapper.MainAction.Restore)
            {
                if (m_wrapper.ShowAdvancedRestoreOptions)
                {
                    args.NextPage = new Add_backup.SettingOverrides();
                }
                else
                {
                    args.NextPage = new Restore.SelectBackupVersion();
                }
            }
            else if (m_wrapper.PrimayAction == WizardSettingsWrapper.MainAction.RestoreSetup)
            {
                if (m_wrapper.ShowAdvancedRestoreOptions)
                {
                    args.NextPage = new Add_backup.SettingOverrides();
                }
                else
                {
                    args.NextPage = new RestoreSetup.FinishedRestoreSetup();
                }
            }
            else
            {
                args.NextPage = new Add_backup.AdvancedOptions();
            }

            //Create the appropriate GUI for the backend settings
            if (selectedBackend is Library.Interface.IBackendGUI)
            {
                args.NextPage = new GUIContainer(args.NextPage, selectedBackend as Library.Interface.IGUIControl);
            }
            else
            {
                args.NextPage = new Backends.RawContainer(args.NextPage, selectedBackend, m_wrapper.BackendSettings);
            }
        }
Esempio n. 9
0
        private void ThreadRun()
        {
            var uploadSuccess = false;
            while (!m_queue.Completed)
            {
                var item = m_queue.Dequeue();
                if (item != null)
                {
                    int retries = 0;
                    Exception lastException = null;

                    do
                    {
                        try
                        {
                            if (m_taskControl != null)
                                m_taskControl.TaskControlRendevouz();

                            if (m_options.NoConnectionReuse && m_backend != null)
                            {
                                m_backend.Dispose();
                                m_backend = null;
                            }

                            if (m_backend == null)
                                m_backend = DynamicLoader.BackendLoader.GetBackend(m_backendurl, m_options.RawOptions);
                            if (m_backend == null)
                                throw new Exception("Backend failed to re-load");

                            using(new Logging.Timer(string.Format("RemoteOperation{0}", item.Operation)))
                                switch (item.Operation)
                                {
                                    case OperationType.Put:
                                        DoPut(item);
                                        // We do not auto create folders,
                                        // because we know the folder exists
                                        uploadSuccess = true;
                                        break;
                                    case OperationType.Get:
                                        DoGet(item);
                                        break;
                                    case OperationType.List:
                                        DoList(item);
                                        break;
                                    case OperationType.Delete:
                                        DoDelete(item);
                                        break;
                                    case OperationType.CreateFolder:
                                        DoCreateFolder(item);
                                        break;
                                    case OperationType.Terminate:
                                        m_queue.SetCompleted();
                                        break;
                                }

                            lastException = null;
                            retries = m_options.NumberOfRetries;
                        }
                        catch (Exception ex)
                        {
                            retries++;
                            lastException = ex;
                            m_statwriter.AddRetryAttempt(string.Format("Operation {0} with file {1} attempt {2} of {3} failed with message: {4}", item.Operation, item.RemoteFilename, retries, m_options.NumberOfRetries, ex.Message), ex);

                            // If the thread is aborted, we exit here
                            if (ex is System.Threading.ThreadAbortException)
                            {
                                m_queue.SetCompleted();
                                item.Exception = ex;
                                item.SignalComplete();
                                throw;
                            }

                            m_statwriter.SendEvent(item.BackendActionType, retries < m_options.NumberOfRetries ? BackendEventType.Retrying : BackendEventType.Failed, item.RemoteFilename, item.Size);

                            bool recovered = false;
                            if (!uploadSuccess && ex is Duplicati.Library.Interface.FolderMissingException && m_options.AutocreateFolders)
                            {
                                try
                                {
                                    // If we successfully create the folder, we can re-use the connection
                                    m_backend.CreateFolder();
                                    recovered = true;
                                }
                                catch(Exception dex)
                                {
                                    m_statwriter.AddWarning(string.Format("Failed to create folder: {0}", ex.Message), dex);
                                }
                            }

                            // To work around the Apache WEBDAV issue, we rename the file here
                            if (item.Operation == OperationType.Put && retries < m_options.NumberOfRetries && !item.NotTrackedInDb)
                                RenameFileAfterError(item);

                            if (!recovered)
                            {
                                try { m_backend.Dispose(); }
                                catch(Exception dex) { m_statwriter.AddWarning(string.Format("Failed to dispose backend instance: {0}", ex.Message), dex); }

                                m_backend = null;

                                if (retries < m_options.NumberOfRetries && m_options.RetryDelay.Ticks != 0)
                                    System.Threading.Thread.Sleep(m_options.RetryDelay);
                            }
                        }

                    } while (retries < m_options.NumberOfRetries);

                    if (lastException != null)
                    {
                        item.Exception = lastException;
                        if (item.Operation == OperationType.Put)
                            item.DeleteLocalFile(m_statwriter);

                        if (item.ExceptionKillsHandler)
                        {
                            m_lastException = lastException;

                            //TODO: If there are temp files in the queue, we must delete them
                            m_queue.SetCompleted();
                       	}

                    }

                    item.SignalComplete();
                }
            }

            //Make sure everything in the queue is signalled
            FileEntryItem i;
            while ((i = m_queue.Dequeue()) != null)
                i.SignalComplete();
        }
Esempio n. 10
0
        public void Dispose()
        {
            if (m_queue != null && !m_queue.Completed)
                m_queue.SetCompleted();

            if (m_thread != null)
            {
                if (!m_thread.Join(TimeSpan.FromSeconds(10)))
                {
                    m_thread.Abort();
                    m_thread.Join(TimeSpan.FromSeconds(10));
                }

                m_thread = null;
            }

            //TODO: We cannot null this, because it will be recreated
            //Should we wait for queue completion or abort immediately?
            if (m_backend != null)
            {
                m_backend.Dispose();
                m_backend = null;
            }

            try { m_db.FlushDbMessages(true); }
            catch (Exception ex) { m_statwriter.AddError(string.Format("Backend Shutdown error: {0}", ex.Message), ex); }
        }