示例#1
0
        /// <summary>
        /// Signs a number of <see cref="Feed"/>s with a single <see cref="OpenPgpSecretKey"/>.
        /// </summary>
        /// <param name="secretKey">The private key to use for signing the files.</param>
        /// <param name="passphrase">The passphrase to use to unlock the key.</param>
        /// <exception cref="IOException">The feed file could not be read or written.</exception>
        /// <exception cref="UnauthorizedAccessException">Read or write access to the feed file is not permitted.</exception>
        private void SignFiles(OpenPgpSecretKey?secretKey, string passphrase)
        {
            var task = ForEachTask.Create(Resources.SigningFeeds, _files, file =>
            {
                SignedFeed signedFeed;
                try
                {
                    signedFeed = SignedFeed.Load(file.FullName);
                }
                #region Error handling
                catch (Exception ex) when(ex is UnauthorizedAccessException or InvalidDataException)
                {
                    // Wrap exception since only certain exception types are allowed
                    throw new IOException(ex.Message, ex);
                }
                #endregion

                signedFeed.SecretKey = secretKey;
                try
                {
                    signedFeed.Save(file.FullName, passphrase);
                }
                #region Error handling
                catch (Exception ex) when(ex is UnauthorizedAccessException or KeyNotFoundException or WrongPassphraseException)
                {
                    // Wrap exception since only certain exception types are allowed
                    throw new IOException(ex.Message, ex);
                }
                #endregion
            });
示例#2
0
    /// <inheritdoc />
    public void Purge(ITaskHandler handler)
    {
        #region Sanity checks
        if (handler == null)
        {
            throw new ArgumentNullException(nameof(handler));
        }
        #endregion

        var paths = Directory.GetDirectories(Path).Where(path =>
        {
            var digest = new ManifestDigest();
            digest.TryParse(System.IO.Path.GetFileName(path));
            return(digest.AvailableDigests.Any());
        }).ToList();
        if (paths.Count == 0)
        {
            return;
        }

        if (MissingAdminRights)
        {
            throw new NotAdminException(Resources.MustBeAdminToRemove);
        }

        handler.RunTask(ForEachTask.Create(
                            name: string.Format(Resources.DeletingDirectory, Path),
                            target: paths,
                            work: path => RemoveInner(path, handler, allowAutoShutdown: true)));

        RemoveDeleteInfoFile();
    }
示例#3
0
    /// <inheritdoc/>
    public long Optimise(ITaskHandler handler)
    {
        #region Sanity checks
        if (handler == null)
        {
            throw new ArgumentNullException(nameof(handler));
        }
        #endregion

        if (!Directory.Exists(Path))
        {
            return(0);
        }
        if (MissingAdminRights)
        {
            throw new NotAdminException();
        }

        using var run = new OptimiseRun(Path);
        handler.RunTask(ForEachTask.Create(
                            name: string.Format(Resources.FindingDuplicateFiles, Path),
                            target: ListAll(),
                            work: run.Work));
        return(run.SavedBytes);
    }
示例#4
0
        /// <inheritdoc/>
        public virtual long Optimise(ITaskHandler handler)
        {
            #region Sanity checks
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }
            #endregion

            if (!Directory.Exists(DirectoryPath))
            {
                return(0);
            }
            if (Kind == ImplementationStoreKind.ReadOnly && !WindowsUtils.IsAdministrator)
            {
                throw new NotAdminException(Resources.MustBeAdminToOptimise);
            }

            using var run = new OptimiseRun(DirectoryPath);
            handler.RunTask(ForEachTask.Create(
                                name: string.Format(Resources.FindingDuplicateFiles, DirectoryPath),
                                target: ListAll(),
                                work: run.Work));
            return(run.SavedBytes);
        }
示例#5
0
 internal ForEachTask(ForEachTask <S, T> parent, Spliterator <S> spliterator) : base(parent)
 {
     this.Spliterator = spliterator;
     this.Sink        = parent.Sink;
     this.TargetSize  = parent.TargetSize;
     this.Helper      = parent.Helper;
 }
示例#6
0
        public override ExitCode Execute()
        {
            var store = GetEffectiveStore();

            Handler.RunTask(ForEachTask.Create(
                                name: Resources.StoreAudit,
                                target: store.ListAll().ToList(),
                                work: digest => store.Verify(digest, Handler)));
            return(ExitCode.OK);
        }
示例#7
0
    private void CleanImplementations(IEnumerable <ImplementationSelection> implementations)
    {
        var digestsToKeep   = implementations.Select(x => x.ManifestDigest);
        var digestsToRemove = ImplementationStore.ListAll().Except(digestsToKeep, ManifestDigestPartialEqualityComparer.Instance);

        Handler.RunTask(ForEachTask.Create(
                            name: Resources.RemovingOutdated,
                            target: digestsToRemove.ToList(),
                            work: digest => ImplementationStore.Remove(digest, Handler)));
    }
示例#8
0
        public void TestCallback()
        {
            var target = new[] {"element1", "element2", "element2"};
            var calledFor = new List<string>();

            var task = new ForEachTask<string>("Test task", target, calledFor.Add);
            task.Run();

            calledFor.Should().Equal(target);
        }
示例#9
0
        /// <summary>
        /// Signs a number of <see cref="Feed"/>s with a single <see cref="OpenPgpSecretKey"/>.
        /// </summary>
        /// <param name="secretKey">The private key to use for signing the files.</param>
        /// <param name="passphrase">The passphrase to use to unlock the key.</param>
        /// <exception cref="IOException">The feed file could not be read or written.</exception>
        /// <exception cref="UnauthorizedAccessException">Read or write access to the feed file is not permitted.</exception>
        private void SignFiles(OpenPgpSecretKey secretKey, string passphrase)
        {
            var task = ForEachTask.Create("Signing feeds", _files, file =>
            {
                SignedFeed signedFeed;
                try
                {
                    signedFeed = SignedFeed.Load(file.FullName);
                }
                #region Error handling
                catch (UnauthorizedAccessException ex)
                {
                    // Wrap exception since only certain exception types are allowed
                    throw new IOException(ex.Message, ex);
                }
                catch (InvalidDataException ex)
                {
                    // Wrap exception since only certain exception types are allowed
                    throw new IOException(ex.Message + (ex.InnerException == null ? "" : Environment.NewLine + ex.InnerException.Message), ex);
                }
                #endregion

                signedFeed.SecretKey = secretKey;
                try
                {
                    signedFeed.Save(file.FullName, passphrase);
                }
                #region Error handling
                catch (UnauthorizedAccessException ex)
                {
                    // Wrap exception since only certain exception types are allowed
                    throw new IOException(ex.Message, ex);
                }
                catch (KeyNotFoundException ex)
                {
                    // Wrap exception since only certain exception types are allowed
                    throw new IOException(ex.Message, ex);
                }
                catch (WrongPassphraseException ex)
                {
                    // Wrap exception since only certain exception types are allowed
                    throw new IOException(ex.Message, ex);
                }
                #endregion
            });

            using (var handler = new DialogTaskHandler(this)) handler.RunTask(task);
            Msg.Inform(this, "Successfully signed files.", MsgSeverity.Info);
        }
示例#10
0
        /// <inheritdoc/>
        public override ExitCode Execute()
        {
            if (!Handler.Ask(Resources.ConfirmRemoveAll, defaultAnswer: true))
            {
                return(ExitCode.NoChanges);
            }

            using var integrationManager = new IntegrationManager(Config, Handler, MachineWide);
            Handler.RunTask(ForEachTask.Create(Resources.RemovingApplications, integrationManager.AppList.Entries.ToList(), integrationManager.RemoveApp));

            // Purge sync status, otherwise next sync would remove everything from server as well instead of restoring from there
            File.Delete(AppList.GetDefaultPath(MachineWide) + SyncIntegrationManager.AppListLastSyncSuffix);

            return(ExitCode.OK);
        }
示例#11
0
        /// <summary>
        /// Removes all applications from the <see cref="AppList"/> and undoes any desktop environment integration.
        /// </summary>
        /// <param name="handler">A callback object used when the the user is to be informed about the progress of long-running operations such as downloads.</param>
        /// <param name="machineWide">Apply the operation machine-wide instead of just for the current user.</param>
        public static void RemoveAllApps(ITaskHandler handler, bool machineWide)
        {
            #region Sanity checks
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }
            #endregion

            using (var integrationManager = new IntegrationManager(handler, machineWide))
            {
                handler.RunTask(ForEachTask.Create(Resources.RemovingApplications, integrationManager.AppList.Entries.ToList(), integrationManager.RemoveApp));

                // Purge sync status, otherwise next sync would remove everything from server as well instead of restoring from there
                File.Delete(AppList.GetDefaultPath(machineWide) + SyncIntegrationManager.AppListLastSyncSuffix);
            }
        }
示例#12
0
        /// <inheritdoc/>
        protected override void OnStage()
        {
            _pendingDirectoryDeletes.Push(Path);

            var filesToDelete = new List <string>();

            string manifestPath = System.IO.Path.Combine(Path, Manifest.ManifestFile);

            if (File.Exists(manifestPath))
            {
                filesToDelete.Add(manifestPath);
            }

            foreach (var pair in ElementPaths)
            {
                string elementPath = System.IO.Path.Combine(Path, pair.Key);

                if (pair.Value is ManifestDirectory)
                {
                    if (Directory.Exists(elementPath))
                    {
                        _pendingDirectoryDeletes.Push(elementPath);
                    }
                }
                else
                {
                    if (File.Exists(elementPath))
                    {
                        filesToDelete.Add(elementPath);
                    }
                }
            }

            if (filesToDelete.Count != 0)
            {
                UnlockFiles(filesToDelete);

                Handler.RunTask(ForEachTask.Create(Resources.DeletingObsoleteFiles, filesToDelete, path =>
                {
                    string tempPath = Randomize(path);
                    File.Move(path, tempPath);
                    _pendingFilesDeletes.Push(new KeyValuePair <string, string>(path, tempPath));
                }));
            }
        }
示例#13
0
            // Similar to AbstractTask but doesn't need to track child tasks
            public void Compute()
            {
                Spliterator <S> rightSplit = Spliterator, leftSplit;
                long            sizeEstimate = rightSplit.EstimateSize(), sizeThreshold;

                if ((sizeThreshold = TargetSize) == 0L)
                {
                    TargetSize = sizeThreshold = AbstractTask.SuggestTargetSize(sizeEstimate);
                }
                bool               isShortCircuit = StreamOpFlag.SHORT_CIRCUIT.isKnown(Helper.StreamAndOpFlags);
                bool               forkRight      = false;
                Sink <S>           taskSink       = Sink;
                ForEachTask <S, T> task           = this;

                while (!isShortCircuit || !taskSink.cancellationRequested())
                {
                    if (sizeEstimate <= sizeThreshold || (leftSplit = rightSplit.TrySplit()) == null)
                    {
                        task.Helper.CopyInto(taskSink, rightSplit);
                        break;
                    }
                    ForEachTask <S, T> leftTask = new ForEachTask <S, T>(task, leftSplit);
                    task.AddToPendingCount(1);
                    ForEachTask <S, T> taskToFork;
                    if (forkRight)
                    {
                        forkRight  = false;
                        rightSplit = leftSplit;
                        taskToFork = task;
                        task       = leftTask;
                    }
                    else
                    {
                        forkRight  = true;
                        taskToFork = leftTask;
                    }
                    taskToFork.Fork();
                    sizeEstimate = rightSplit.EstimateSize();
                }
                task.Spliterator = null;
                task.PropagateCompletion();
            }
        /// <summary>
        /// Runs ngen in the background to pre-compile new/updated .NET assemblies.
        /// </summary>
        private void NgenApply()
        {
            if (!WindowsUtils.IsWindows)
            {
                return;
            }
            if (!File.Exists(_ngenExe))
            {
                return;
            }

            Handler.RunTask(ForEachTask.Create(Resources.RunNgen, _ngenAssemblies, assembly =>
            {
                string arguments = new[] { "install", Path.Combine(TargetDir, assembly), "/queue" }.JoinEscapeArguments();
                new ProcessStartInfo(_ngenExe, arguments)
                {
                    WindowStyle = ProcessWindowStyle.Hidden
                }.Run();
            }));
        }
示例#15
0
    private void CleanImplementations(IEnumerable <ImplementationSelection> implementations)
    {
        var digestsToKeep   = implementations.Select(x => x.ManifestDigest);
        var digestsToRemove = ImplementationStore.ListAll().Except(digestsToKeep, ManifestDigestPartialEqualityComparer.Instance);

        Handler.RunTask(ForEachTask.Create(
                            name: Resources.RemovingOutdated,
                            target: digestsToRemove.ToList(),
                            work: digest =>
        {
            try
            {
                ImplementationStore.Remove(digest, Handler);
            }
            catch (NotAdminException ex) when(ZeroInstallInstance.IsLibraryMode)
            {
                Log.Info($"Unable to remove {digest}", ex);
            }
        }
                            ));
    }
    /// <inheritdoc />
    public void Purge(ITaskHandler handler)
    {
        #region Sanity checks
        if (handler == null)
        {
            throw new ArgumentNullException(nameof(handler));
        }
        #endregion

        ThrowIfMissingAdminRights();

        var paths = Directory.GetDirectories(Path).Where(path =>
        {
            var digest = new ManifestDigest();
            digest.ParseID(System.IO.Path.GetFileName(path));
            return(digest.Best != null);
        }).ToList();

        handler.RunTask(ForEachTask.Create(
                            name: string.Format(Resources.DeletingDirectory, Path),
                            target: paths,
                            work: digest => RemoveInner(digest, handler, purge: true)));
    }
示例#17
0
        /// <inheritdoc/>
        public void Repair(Converter <FeedUri, Feed> feedRetriever)
        {
            #region Sanity checks
            if (feedRetriever == null)
            {
                throw new ArgumentNullException(nameof(feedRetriever));
            }
            #endregion

            try
            {
                Handler.RunTask(ForEachTask.Create(Resources.RepairingIntegration, AppList.Entries,
                                                   x => RepairAppInternal(x, feedRetriever(x.InterfaceUri))));
            }
            catch (KeyNotFoundException ex)
            {
                // Wrap exception since only certain exception types are allowed
                throw new InvalidDataException(ex.Message, ex);
            }
            finally
            {
                Finish();
            }
        }
示例#18
0
        private void Clean(IEnumerable <ManifestDigest> digestsToKeep)
        {
            var toDelete = ImplementationStore.ListAll().Except(digestsToKeep, ManifestDigestPartialEqualityComparer.Instance).ToList();

            Handler.RunTask(ForEachTask.Create(Resources.RemovingOutdated, toDelete, x => ImplementationStore.Remove(x, Handler)));
        }
示例#19
0
        /// <summary>
        /// Signs a number of <see cref="Feed"/>s with a single <see cref="OpenPgpSecretKey"/>.
        /// </summary>
        /// <param name="secretKey">The private key to use for signing the files.</param>
        /// <param name="passphrase">The passphrase to use to unlock the key.</param>
        /// <exception cref="IOException">The feed file could not be read or written.</exception>
        /// <exception cref="UnauthorizedAccessException">Read or write access to the feed file is not permitted.</exception>
        private void SignFiles(OpenPgpSecretKey secretKey, string passphrase)
        {
            var task = new ForEachTask<FileInfo>("Signing feeds", _files, file =>
            {
                SignedFeed signedFeed;
                try
                {
                    signedFeed = SignedFeed.Load(file.FullName);
                }
                    #region Error handling
                catch (UnauthorizedAccessException ex)
                {
                    // Wrap exception since only certain exception types are allowed
                    throw new IOException(ex.Message, ex);
                }
                catch (InvalidDataException ex)
                {
                    // Wrap exception since only certain exception types are allowed
                    throw new IOException(ex.Message + (ex.InnerException == null ? "" : "\n" + ex.InnerException.Message), ex);
                }
                #endregion

                signedFeed.SecretKey = secretKey;
                try
                {
                    signedFeed.Save(file.FullName, passphrase);
                }
                    #region Error handling
                catch (UnauthorizedAccessException ex)
                {
                    // Wrap exception since only certain exception types are allowed
                    throw new IOException(ex.Message, ex);
                }
                catch (KeyNotFoundException ex)
                {
                    // Wrap exception since only certain exception types are allowed
                    throw new IOException(ex.Message, ex);
                }
                catch (WrongPassphraseException ex)
                {
                    // Wrap exception since only certain exception types are allowed
                    throw new IOException(ex.Message, ex);
                }
                #endregion
            });
            using (var handler = new GuiTaskHandler(this)) handler.RunTask(task);
            Msg.Inform(this, "Successfully signed files.", MsgSeverity.Info);
        }
示例#20
0
        /// <inheritdoc/>
        protected override void OnStage()
        {
            if (!Directory.Exists(DestinationPath))
            {
                Directory.CreateDirectory(DestinationPath);
                _createdDirectories.Push(DestinationPath);
            }

            if (FileUtils.DetermineTimeAccuracy(DestinationPath) > 0)
            {
                throw new IOException(Resources.InsufficientFSTimeAccuracy);
            }

            string manifestPath     = System.IO.Path.Combine(DestinationPath, Manifest.ManifestFile);
            string tempManifestPath = Randomize(manifestPath);

            _pendingFileRenames.Push(new KeyValuePair <string, string>(tempManifestPath, manifestPath));
            Manifest.Save(tempManifestPath);

            Handler.RunTask(ForEachTask.Create(Resources.CopyFiles, ElementPaths, pair =>
            {
                string sourcePath      = System.IO.Path.Combine(Path, pair.Key);
                string destinationPath = System.IO.Path.Combine(DestinationPath, pair.Key);

                if (pair.Value is ManifestDirectory)
                {
                    if (!Directory.Exists(destinationPath))
                    {
                        Directory.CreateDirectory(destinationPath);
                        _createdDirectories.Push(destinationPath);
                    }
                }
                else
                {
                    string tempPath = Randomize(destinationPath);
                    _pendingFileRenames.Push(new KeyValuePair <string, string>(tempPath, destinationPath));

                    switch (pair.Value)
                    {
                    case ManifestFileBase file:
                        File.Copy(sourcePath, tempPath);
                        File.SetLastWriteTimeUtc(tempPath, file.ModifiedTime);

                        if (UnixUtils.IsUnix)
                        {
                            FileUtils.SetExecutable(tempPath, file is ManifestExecutableFile);
                        }
                        break;

                    case ManifestSymlink _:
                        if (UnixUtils.IsUnix)
                        {
                            if (UnixUtils.IsSymlink(sourcePath, out string?symlinkTarget))
                            {
                                UnixUtils.CreateSymlink(tempPath, symlinkTarget);
                            }
                        }
                        break;
                    }
                }
            }));
        }