Beispiel #1
0
        private IEnumerable <SelectionCandidate> GetCandidates(FeedUri feedUri, Feed feed, Requirements requirements)
        {
            var feedPreferences = FeedPreferences.LoadForSafe(feedUri);

            foreach (var element in feed.Elements)
            {
                var packageImplementation = element as PackageImplementation;
                if (packageImplementation != null)
                { // Each <package-implementation> provides 0..n selection candidates
                    var externalImplementations = _packageManager.Query(packageImplementation, requirements.Distributions.ToArray());
                    foreach (var externalImplementation in externalImplementations)
                    {
                        _externalImplementations[externalImplementation.ID] = externalImplementation;
                        yield return(new SelectionCandidate(new FeedUri(FeedUri.FromDistributionPrefix + feedUri), feedPreferences, externalImplementation, requirements));
                    }
                }
                else if (requirements.Distributions.ContainsOrEmpty(Restriction.DistributionZeroInstall))
                {
                    var implementation = element as Implementation;
                    if (implementation != null)
                    { // Each <implementation> provides 1 selection candidate
                        yield return(new SelectionCandidate(feedUri, feedPreferences, implementation, requirements,
                                                            offlineUncached: (_config.NetworkUse == NetworkLevel.Offline) && !_isCached(implementation)));
                    }
                }
            }
        }
Beispiel #2
0
        /// <inheritdoc/>
        protected override ExitCode ExecuteHelper(ICategoryIntegrationManager integrationManager, FeedUri interfaceUri)
        {
            #region Sanity checks
            if (integrationManager == null) throw new ArgumentNullException("integrationManager");
            if (interfaceUri == null) throw new ArgumentNullException("interfaceUri");
            #endregion

            try
            {
                var entry = CreateAppEntry(integrationManager, ref interfaceUri);

                if (!CatalogManager.GetCachedSafe().ContainsFeed(entry.InterfaceUri))
                    WindowsUtils.BroadcastMessage(AddedNonCatalogAppWindowMessageID); // Notify Zero Install GUIs of changes

                return ExitCode.OK;
            }
                #region Error handling
            catch (WebException)
            {
                // WebException is a subclass of InvalidOperationException but we don't want to catch it here
                throw;
            }
            catch (InvalidOperationException ex)
            { // Application already in AppList
                Handler.OutputLow(Resources.DesktopIntegration, ex.Message);
                return ExitCode.NoChanges;
            }
            #endregion
        }
Beispiel #3
0
    /// <summary>
    /// Returns a command-line for executing the "0install run" command.
    /// Generates and returns a stub EXE if possible, falls back to directly pointing to the "0install" EXE otherwise.
    /// </summary>
    /// <param name="target">The application to be launched.</param>
    /// <param name="command">The command argument to be passed to the the "0install run" command; can be <c>null</c>.</param>
    /// <param name="machineWide"><c>true</c> place the generated stub in a machine-wide location; <c>false</c> to place it in the current user profile.</param>
    /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
    /// <exception cref="InvalidOperationException">There was a compilation error while generating the stub EXE.</exception>
    /// <exception cref="IOException">A problem occurred while writing to the filesystem.</exception>
    /// <exception cref="WebException">A problem occurred while downloading additional data (such as icons).</exception>
    /// <exception cref="UnauthorizedAccessException">Write access to the filesystem is not permitted.</exception>
    public IReadOnlyList <string> GetRunCommandLine(FeedTarget target, string?command = null, bool machineWide = false)
    {
        string targetKey = target.Uri + "#" + command;

        var  entryPoint = target.Feed.GetEntryPoint(command);
        bool gui        = entryPoint is not {
            NeedsTerminal : true
        };

        string targetHash = targetKey.Hash(SHA256.Create());
        string exeName    = (entryPoint == null)
            ? FeedUri.Escape(target.Feed.Name)
            : entryPoint.BinaryName ?? entryPoint.Command;
        string path = Path.Combine(
            IntegrationManager.GetDir(machineWide, "stubs", targetHash),
            exeName + ".exe");

#if !DEBUG
        try
#endif
        {
            CreateOrUpdateRunStub(path, target, gui, command);
            return(new[] { path });
        }
#if !DEBUG
        catch (Exception ex)
        {
            var exe = GetExe(gui);
            Log.Error($"Failed to generate stub EXE for {targetKey}. Falling back to using '{exe}' directly.", ex);
            return(GetArguments(target.Uri, command, gui)
                   .Prepend(Path.Combine(Locations.InstallBase, exe))
                   .ToList());
        }
#endif
    }
Beispiel #4
0
        public void TestNormalizeLocalPath()
        {
            var localUri = new FeedUri(WindowsUtils.IsWindows ? @"C:\local\feed.xml" : "/local/feed.xml");

            var implementation1 = new Implementation {
                ID = "./subdir"
            };

            implementation1.Normalize(localUri);
            Assert.AreEqual(
                expected: WindowsUtils.IsWindows ? @"C:\local\.\subdir" : "/local/./subdir",
                actual: implementation1.ID);
            Assert.AreEqual(
                expected: WindowsUtils.IsWindows ? @"C:\local\.\subdir" : "/local/./subdir",
                actual: implementation1.LocalPath);

            var implementation2 = new Implementation {
                ID = "./wrong", LocalPath = "subdir"
            };

            implementation2.Normalize(localUri);
            Assert.AreEqual(
                expected: "./wrong",
                actual: implementation2.ID);
            Assert.AreEqual(
                expected: WindowsUtils.IsWindows ? @"C:\local\subdir" : "/local/subdir",
                actual: implementation2.LocalPath);
        }
        public void TestResolveAppAlias()
        {
            FeedUri uri     = new FeedUri("http://example.com/test1.xml");
            var     appList = new AppList
            {
                Entries =
                {
                    new AppEntry
                    {
                        AccessPoints = new AccessPointList{
                            Entries =
                            {
                                new AppAlias {
                                    Name = "foobar", Command = Command.NameTest
                                }
                            }
                        },
                        InterfaceUri = uri
                    }
                }
            };

            appList.ResolveAlias("foobar").Should().Be(uri);
            appList.ResolveAlias("other").Should().BeNull();
        }
        /// <summary>
        /// Creates a new interface dialog.
        /// </summary>
        /// <param name="interfaceUri">The interface to modify the preferences for.</param>
        /// <param name="solveCallback">Called after <see cref="InterfacePreferences"/> have been changed and the <see cref="ISolver"/> needs to be rerun.</param>
        /// <param name="feedCache">The feed cache used to retrieve feeds for additional information about implementations.</param>
        private InterfaceDialog([NotNull] FeedUri interfaceUri, [NotNull] Func <Selections> solveCallback, [NotNull] IFeedCache feedCache)
        {
            #region Sanity checks
            if (interfaceUri == null)
            {
                throw new ArgumentNullException("interfaceUri");
            }
            if (solveCallback == null)
            {
                throw new ArgumentNullException("solveCallback");
            }
            if (feedCache == null)
            {
                throw new ArgumentNullException("feedCache");
            }
            #endregion

            InitializeComponent();
            comboBoxStability.Items.AddRange(new object[] { Resources.UseDefaultSetting, Stability.Stable, Stability.Testing, Stability.Developer });
            dataColumnUserStability.Items.AddRange(Stability.Unset, Stability.Preferred, Stability.Packaged, Stability.Stable, Stability.Testing, Stability.Developer);

            _interfaceUri  = interfaceUri;
            _mainFeed      = feedCache.GetFeed(_interfaceUri);
            _solveCallback = solveCallback;
            _feedCache     = feedCache;
        }
Beispiel #7
0
        /// <summary>
        /// Creates a new application tile.
        /// </summary>
        /// <param name="interfaceUri">The interface URI of the application this tile represents.</param>
        /// <param name="appName">The name of the application this tile represents.</param>
        /// <param name="status">Describes whether the application is listed in the <see cref="AppList"/> and if so whether it is integrated.</param>
        /// <param name="iconCache">The icon cache used to retrieve icons specified in <see cref="Feed"/>; can be <see langword="null"/>.</param>
        /// <param name="machineWide">Apply operations machine-wide instead of just for the current user.</param>
        public AppTile([NotNull] FeedUri interfaceUri, [NotNull] string appName, AppStatus status, [CanBeNull] IIconCache iconCache = null, bool machineWide = false)
        {
            #region Sanity checks
            if (interfaceUri == null)
            {
                throw new ArgumentNullException("interfaceUri");
            }
            if (appName == null)
            {
                throw new ArgumentNullException("appName");
            }
            #endregion

            _machineWide = machineWide;

            InitializeComponent();
            buttonRun.Text        = _runButtonText;
            buttonAdd.Image       = _addButton;
            buttonRemove.Image    = _removeButton;
            buttonIntegrate.Image = _setupButton;
            toolTip.SetToolTip(buttonAdd, _addButtonTooltip);
            toolTip.SetToolTip(buttonRemove, _removeButtonTooltip);
            buttonSelectCommand.Text = _selectCommandButton;
            buttonSelectVersion.Text = _selectVersionButton;
            buttonUpdate.Text        = _updateButtonText;

            InterfaceUri      = interfaceUri;
            labelName.Text    = appName;
            labelSummary.Text = "";
            Status            = status;

            _iconCache = iconCache;

            CreateHandle();
        }
Beispiel #8
0
        public ValidSignature CheckTrust(byte[] data, FeedUri uri, string localPath = null)
        {
            #region Sanity checks
            if (uri == null) throw new ArgumentNullException(nameof(uri));
            if (data == null) throw new ArgumentNullException(nameof(data));
            #endregion

            if (uri.IsFile) throw new UriFormatException(Resources.FeedUriLocal);

            var domain = new Domain(uri.Host);
            KeyImported:
            var signatures = FeedUtils.GetSignatures(_openPgp, data).ToList();

            foreach (var signature in signatures.OfType<ValidSignature>())
                if (_trustDB.IsTrusted(signature.FormatFingerprint(), domain)) return signature;

            foreach (var signature in signatures.OfType<ValidSignature>())
                if (HandleNewKey(uri, signature.FormatFingerprint(), domain)) return signature;

            foreach (var signature in signatures.OfType<MissingKeySignature>())
            {
                Log.Info("Missing key for " + signature.FormatKeyID());
                AcquireMissingKey(signature, uri, localPath);
                goto KeyImported;
            }

            throw new SignatureException(string.Format(Resources.FeedNoTrustedSignatures, uri));
        }
Beispiel #9
0
    /// <inheritdoc/>
    public void Add(FeedUri feedUri, byte[] data)
    {
        #region Sanity checks
        if (feedUri == null)
        {
            throw new ArgumentNullException(nameof(feedUri));
        }
        if (data == null)
        {
            throw new ArgumentNullException(nameof(data));
        }
        #endregion

        if (!Directory.Exists(Path))
        {
            Directory.CreateDirectory(Path);
        }

        try
        {
            string path = System.IO.Path.Combine(Path, feedUri.Escape());
            Log.Debug($"Adding feed {feedUri.ToStringRfc()} to disk cache: {path}");
            WriteToFile(data, path);
        }
        catch (PathTooLongException)
        {
            Log.Info("File path in feed cache too long. Using hash of feed URI to shorten path.");
            WriteToFile(data, System.IO.Path.Combine(Path, feedUri.AbsoluteUri.Hash(SHA256.Create())));
        }
    }
Beispiel #10
0
        /// <summary>
        /// Loads a feed and adds it to a dictionary if it is not already in it. Recursivley adds <see cref="Feed.Feeds"/> references.
        /// </summary>
        /// <param name="dictionary">The dictionary to add the feed to.</param>
        /// <param name="feedUri">The URI to load the feed from</param>
        /// <param name="requirements">Requirements to apply as a filter to <see cref="Feed.Feeds"/> references before following them.</param>
        private void AddFeedToDict([NotNull] IDictionary <FeedUri, Feed> dictionary, [CanBeNull] FeedUri feedUri, [NotNull] Requirements requirements)
        {
            if (feedUri == null || dictionary.ContainsKey(feedUri))
            {
                return;
            }

            var feed = _feedManager[feedUri];

            if (feed.MinInjectorVersion != null && FeedElement.ZeroInstallVersion < feed.MinInjectorVersion)
            {
                Log.Warn($"The solver version is too old. The feed '{feedUri}' requires at least version {feed.MinInjectorVersion} but the installed version is {FeedElement.ZeroInstallVersion}. Try updating Zero Install.");
                return;
            }

            dictionary.Add(feedUri, feed);
            foreach (var reference in feed.Feeds)
            {
                if (reference.Architecture.IsCompatible(requirements.Architecture) &&
                    (reference.Languages.Count == 0 || reference.Languages.ContainsAny(requirements.Languages, ignoreCountry: true)))
                {
                    AddFeedToDict(dictionary, reference.Source, requirements);
                }
            }
        }
        /// <inheritdoc/>
        public void AddSource(FeedUri uri)
        {
            var sources = GetSources().ToList();

            sources.AddIfNew(uri);
            SetSources(sources);
        }
Beispiel #12
0
    /// <inheritdoc/>
    public override ExitCode Execute()
    {
        var apps = AppList.LoadSafe(MachineWide);

        if (AdditionalArgs.Count > 0)
        {
            if (Uri.TryCreate(AdditionalArgs[0], UriKind.Absolute, out var uri))
            {
                var feedUri = new FeedUri(uri);
                apps.Entries.RemoveAll(x => x.InterfaceUri != feedUri);
            }
            else
            {
                apps.Entries.RemoveAll(x => !x.Name.ContainsIgnoreCase(AdditionalArgs[0]));
            }
        }

        if (_xmlOutput)
        {
            Handler.Output(Resources.MyApps, apps.ToXmlString());
        }
        else
        {
            Handler.Output(Resources.MyApps, apps.Entries);
        }
        return(ExitCode.OK);
    }
Beispiel #13
0
        /// <summary>
        /// Detects attacks such as feed substitution or replay attacks.
        /// </summary>
        /// <param name="data">The content of the feed file as a byte array.</param>
        /// <param name="uri">The URI the feed originally came from.</param>
        /// <param name="signature">The first trusted signature for the feed.</param>
        /// <exception cref="ReplayAttackException">A replay attack was detected.</exception>
        /// <exception cref="UriFormatException"><see cref="Feed.Uri"/> is missing or does not match <paramref name="uri"/>.</exception>
        private void DetectAttacks(byte[] data, FeedUri uri, ValidSignature signature)
        {
            // Detect feed substitution
            var feed = XmlStorage.LoadXml <Feed>(new MemoryStream(data));

            if (feed.Uri == null)
            {
                throw new UriFormatException(string.Format(Resources.FeedUriMissing, uri));
            }
            if (feed.Uri != uri)
            {
                throw new UriFormatException(string.Format(Resources.FeedUriMismatch, feed.Uri, uri));
            }

            // Detect replay attacks
            try
            {
                var oldSignature = _feedCache.GetSignatures(uri).OfType <ValidSignature>().FirstOrDefault();
                if (oldSignature != null && signature.Timestamp < oldSignature.Timestamp)
                {
                    throw new ReplayAttackException(uri, oldSignature.Timestamp, signature.Timestamp);
                }
            }
            catch (KeyNotFoundException)
            {
                // No existing feed to be replaced
            }
        }
Beispiel #14
0
        /// <summary>
        /// Adds a feed to the list of custom feeds.
        /// </summary>
        private void AddCustomFeed(string input)
        {
            FeedUri feedUri;

            try
            {
                feedUri = new FeedUri(input);
            }
            catch (UriFormatException ex)
            {
                Msg.Inform(this, ex.Message, MsgSeverity.Error);
                return;
            }

            if (_interfaceUri.IsFile)
            {
                if (!File.Exists(_interfaceUri.LocalPath))
                {
                    Msg.Inform(this, string.Format(Resources.FileOrDirNotFound, _interfaceUri.LocalPath), MsgSeverity.Warn);
                    return;
                }
            }
            else
            {
                Feed feed = null;
                try
                {
                    using var handler = new DialogTaskHandler(this);
                    handler.RunTask(new SimpleTask(Resources.CheckingFeed,
                                                   delegate
                    {
                        using var webClient = new WebClientTimeout();
                        feed = XmlStorage.FromXmlString <Feed>(webClient.DownloadString(feedUri));
                    }));
                }
Beispiel #15
0
        public void RemovePackageSource(string uri)
        {
            var feedUri = new FeedUri(uri);

            if (!CatalogManager.RemoveSource(feedUri))
                Log.Warn(string.Format(Resources.CatalogNotRegistered, feedUri.ToStringRfc()));
        }
Beispiel #16
0
        /// <inheritdoc/>
        public void ImportFeed(string path, FeedUri uri, FeedUri mirrorUrl = null)
        {
            #region Sanity checks
            if (uri == null)
            {
                throw new ArgumentNullException("uri");
            }
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }
            #endregion

            if (uri.IsFile)
            {
                throw new UriFormatException(Resources.FeedUriLocal);
            }
            Log.Debug("Importing feed " + uri.ToStringRfc() + " from: " + path);

            var data = File.ReadAllBytes(path);

            var newSignature = _trustManager.CheckTrust(data, uri, mirrorUrl);
            DetectAttacks(data, uri, newSignature);

            // Add to cache and remember time
            _feedCache.Add(uri, data);
            var preferences = FeedPreferences.LoadForSafe(uri);
            preferences.LastChecked = DateTime.UtcNow;
            preferences.Normalize();
            preferences.SaveFor(uri);
        }
Beispiel #17
0
        //--------------------//

        #region Normalize
        /// <summary>
        /// Sets missing default values and handles legacy elements.
        /// </summary>
        /// <param name="feedUri">The feed the data was originally loaded from; can be <see langword="null"/>.</param>
        /// <remarks>This method should be called to prepare a <see cref="Feed"/> for solver processing. Do not call it if you plan on serializing the feed again since it may loose some of its structure.</remarks>
        public override void Normalize(FeedUri feedUri = null)
        {
            base.Normalize(feedUri);

            // Merge the version modifier into the normal version attribute
            if (!string.IsNullOrEmpty(VersionModifier))
            {
                Version         = new ImplementationVersion(Version + VersionModifier);
                VersionModifier = null;
            }

            // Default stability rating to testing
            if (Stability == Stability.Unset)
            {
                Stability = Stability.Testing;
            }

            // Make local paths absolute
            if (!string.IsNullOrEmpty(LocalPath))
            {
                LocalPath = ModelUtils.GetAbsolutePath(LocalPath, feedUri);
            }
            else if (!string.IsNullOrEmpty(ID) && ID.StartsWith(".")) // Get local path from ID
            {
                LocalPath = ID = ModelUtils.GetAbsolutePath(ID, feedUri);
            }

            // Parse manifest digest from ID if missing
            if (!string.IsNullOrEmpty(ID))
            {
                _manifestDigest.ParseID(ID);
            }
        }
Beispiel #18
0
        /// <summary>
        /// Creates a new alias.
        /// </summary>
        /// <param name="aliasName">The name of the alias to create.</param>
        /// <param name="interfaceUri">The interface URI the alias shall point to.</param>
        /// <param name="command">A command within the interface the alias shall point to; can be <c>null</c>.</param>
        /// <returns>The exit status code to end the process with.</returns>
        private ExitCode CreateAlias(string aliasName, FeedUri interfaceUri, string command = null)
        {
            CheckInstallBase();

            using (var integrationManager = new IntegrationManager(Handler, MachineWide))
            {
                // Check this before modifying the environment
                bool needsReopenTerminal = NeedsReopenTerminal(integrationManager.MachineWide);

                var appEntry = GetAppEntry(integrationManager, ref interfaceUri);

                // Apply the new alias
                var alias = new AppAlias {
                    Name = aliasName, Command = command
                };
                integrationManager.AddAccessPoints(appEntry, FeedManager[interfaceUri], new AccessPoint[] { alias });

                string message = string.Format(Resources.AliasCreated, aliasName, appEntry.Name);
                if (needsReopenTerminal)
                {
                    message += Environment.NewLine + Resources.ReopenTerminal;
                }
                Handler.OutputLow(Resources.DesktopIntegration, message);
                return(ExitCode.OK);
            }
        }
Beispiel #19
0
        public void TestNativeFeed()
        {
            var mainFeed = FeedTest.CreateTestFeed();

            mainFeed.Elements.RemoveAt(1);
            mainFeed.Feeds.Clear();
            _feedManagerMock.Setup(x => x.GetFeed(FeedTest.Test1Uri)).Returns(mainFeed);

            using (new LocationsRedirect("0install-unit-tests"))
            {
                var localUri = new FeedUri(Locations.GetSaveDataPath("0install.net", true, "native_feeds", mainFeed.Uri.PrettyEscape()));

                var subFeed = mainFeed.Clone();
                subFeed.Uri = FeedTest.Sub1Uri;
                subFeed.Elements[0].Version = new ImplementationVersion("2.0");
                subFeed.SaveXml(localUri.LocalPath);
                _feedManagerMock.Setup(x => x.GetFeed(localUri)).Returns(subFeed);

                var requirements = new Requirements(FeedTest.Test1Uri, Command.NameRun);
                CollectionAssert.AreEqual(
                    expected: new[]
                {
                    new SelectionCandidate(localUri, new FeedPreferences(), (Implementation)subFeed.Elements[0], requirements),
                    new SelectionCandidate(FeedTest.Test1Uri, new FeedPreferences(), (Implementation)mainFeed.Elements[0], requirements)
                },
                    actual: Target.GetSortedCandidates(requirements));
            }
        }
Beispiel #20
0
        public void TestSitePackages()
        {
            var mainFeed = FeedTest.CreateTestFeed();

            mainFeed.Feeds.Clear();
            FeedManagerMock.Setup(x => x[FeedTest.Test1Uri]).Returns(mainFeed);

            using (new LocationsRedirect("0install-unit-tests"))
            {
                var pathComponents = mainFeed.Uri.EscapeComponent()
                                     .Prepend("site-packages")
                                     .Concat(new[] { "xyz", "0install", "feed.xml" });
                var localUri = new FeedUri(Locations.GetSaveDataPath("0install.net", isFile: true, resource: pathComponents.ToArray()));

                var subFeed = mainFeed.Clone();
                subFeed.Uri = FeedTest.Sub1Uri;
                subFeed.Elements[0].Version = new ImplementationVersion("2.0");
                subFeed.SaveXml(localUri.LocalPath);
                FeedManagerMock.Setup(x => x[localUri]).Returns(subFeed);
                PackageManagerMock.Setup(x => x.Query((PackageImplementation)mainFeed.Elements[1])).Returns(Enumerable.Empty <ExternalImplementation>());

                var requirements = new Requirements(FeedTest.Test1Uri, Command.NameRun);
                Target.GetSortedCandidates(requirements).Should().Equal(
                    new SelectionCandidate(localUri, new FeedPreferences(), (Implementation)subFeed.Elements[0], requirements),
                    new SelectionCandidate(FeedTest.Test1Uri, new FeedPreferences(), (Implementation)mainFeed.Elements[0], requirements));
            }
        }
Beispiel #21
0
        public static InterfacePreferences LoadForSafe([NotNull] FeedUri interfaceUri)
        {
            #region Sanity checks
            if (interfaceUri == null)
            {
                throw new ArgumentNullException("interfaceUri");
            }
            #endregion

            try
            {
                return(LoadFor(interfaceUri));
            }
            #region Error handling
            catch (IOException ex)
            {
                Log.Warn(string.Format(Resources.ErrorLoadingInterfacePrefs, interfaceUri));
                Log.Warn(ex);
                return(new InterfacePreferences());
            }
            catch (UnauthorizedAccessException ex)
            {
                Log.Warn(string.Format(Resources.ErrorLoadingInterfacePrefs, interfaceUri));
                Log.Warn(ex);
                return(new InterfacePreferences());
            }
            catch (InvalidDataException ex)
            {
                Log.Warn(string.Format(Resources.ErrorLoadingInterfacePrefs, interfaceUri));
                Log.Warn(ex);
                return(new InterfacePreferences());
            }
            #endregion
        }
        /// <inheritdoc/>
        public void RemoveSource(FeedUri uri)
        {
            var sources = GetSources().ToList();

            sources.Remove(uri);
            SetSources(sources);
        }
Beispiel #23
0
        /// <summary>
        /// Removes a <see cref="FeedReference"/> from one or more <see cref="InterfacePreferences"/>.
        /// </summary>
        /// <returns>The interfaces that were actually affected.</returns>
        protected override ICollection <FeedUri> ApplyFeedToInterfaces(FeedUri feedUri, IEnumerable <FeedUri> interfaces)
        {
            #region Sanity checks
            if (feedUri == null)
            {
                throw new ArgumentNullException("feedUri");
            }
            if (interfaces == null)
            {
                throw new ArgumentNullException("interfaces");
            }
            #endregion

            var modified  = new List <FeedUri>();
            var reference = new FeedReference {
                Source = feedUri
            };
            foreach (var interfaceUri in interfaces)
            {
                var preferences = InterfacePreferences.LoadFor(interfaceUri);
                if (preferences.Feeds.Remove(reference))
                {
                    modified.Add(interfaceUri);
                }
                preferences.SaveFor(interfaceUri);
            }
            return(modified);
        }
        private void DownloadMissingKey(FeedUri uri, FeedUri mirrorUrl, MissingKeySignature signature)
        {
            var keyUri = new Uri(mirrorUrl ?? uri, signature.KeyID + ".gpg");

            byte[] keyData;
            if (keyUri.IsFile)
            { // Load key file from local file
                keyData = File.ReadAllBytes(keyUri.LocalPath);
            }
            else
            { // Load key file from server
                try
                {
                    using (var keyFile = new TemporaryFile("0install-key"))
                    {
                        _handler.RunTask(new DownloadFile(keyUri, keyFile));
                        keyData = File.ReadAllBytes(keyFile);
                    }
                }
                #region Error handling
                catch (WebException ex)
                {
                    // Wrap exception to add context information
                    throw new SignatureException(string.Format(Resources.UnableToLoadKeyFile, uri), ex);
                }
                #endregion
            }

            Log.Info("Importing OpenPGP public key for " + signature.KeyID);
            _openPgp.ImportKey(keyData);
        }
Beispiel #25
0
        /// <summary>
        /// Creates a new interface dialog.
        /// </summary>
        /// <param name="interfaceUri">The interface to modify the preferences for.</param>
        /// <param name="solveCallback">Called after <see cref="InterfacePreferences"/> have been changed and the <see cref="ISolver"/> needs to be rerun.</param>
        /// <param name="feedManager">The feed manager used to retrieve feeds for additional information about implementations.</param>
        private InterfaceDialog(FeedUri interfaceUri, Func <Selections> solveCallback, IFeedManager feedManager)
        {
            #region Sanity checks
            if (interfaceUri == null)
            {
                throw new ArgumentNullException(nameof(interfaceUri));
            }
            if (solveCallback == null)
            {
                throw new ArgumentNullException(nameof(solveCallback));
            }
            if (feedManager == null)
            {
                throw new ArgumentNullException(nameof(feedManager));
            }
            #endregion

            InitializeComponent();
            comboBoxStability.Items.AddRange(new object[] { Resources.UseDefaultSetting, Stability.Stable, Stability.Testing, Stability.Developer });
            dataColumnUserStability.Items.AddRange(Stability.Unset, Stability.Preferred, Stability.Stable, Stability.Testing, Stability.Developer, Stability.Buggy, Stability.Insecure);

            _interfaceUri  = interfaceUri;
            _mainFeed      = feedManager[_interfaceUri];
            _solveCallback = solveCallback;
            _feedManager   = feedManager;
        }
Beispiel #26
0
        /// <summary>
        /// Sets missing default values and handles legacy elements.
        /// </summary>
        /// <param name="feedUri">The feed the data was originally loaded from.</param>
        /// <remarks>This method should be called to prepare a <see cref="Feed"/> for solver processing. Do not call it if you plan on serializing the feed again since it may loose some of its structure.</remarks>
        public override void Normalize(FeedUri feedUri)
        {
            #region Sanity checks
            if (feedUri == null)
            {
                throw new ArgumentNullException(nameof(feedUri));
            }
            #endregion

            base.Normalize(feedUri);

            // Apply if-0install-version filter
            RetrievalMethods.RemoveAll(FilterMismatch);

            var toRemove = new List <RetrievalMethod>();
            foreach (var retrievalMethod in RetrievalMethods)
            {
                try
                {
                    retrievalMethod.Normalize(feedUri);
                }
                #region Error handling
                catch (UriFormatException ex)
                {
                    Log.Error(ex);
                    toRemove.Add(retrievalMethod);
                }
                #endregion
            }
            RetrievalMethods.RemoveRange(toRemove);
        }
Beispiel #27
0
    /// <summary>
    /// Returns a command-line for executing the "0install run" command. Generates and returns a stub EXE if possible, falls back to directly pointing to the "0install" binary otherwise.
    /// </summary>
    /// <param name="target">The application to be launched.</param>
    /// <param name="command">The command argument to be passed to the the "0install run" command; can be <c>null</c>.</param>
    /// <param name="machineWide"><c>true</c> place the generated stub in a machine-wide location; <c>false</c> to place it in the current user profile.</param>
    /// <returns></returns>
    /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
    /// <exception cref="InvalidOperationException">There was a compilation error while generating the stub EXE.</exception>
    /// <exception cref="IOException">A problem occurred while writing to the filesystem.</exception>
    /// <exception cref="WebException">A problem occurred while downloading additional data (such as icons).</exception>
    /// <exception cref="UnauthorizedAccessException">Write access to the filesystem is not permitted.</exception>
    public IReadOnlyList <string> GetRunCommandLine(FeedTarget target, string?command = null, bool machineWide = false)
    {
        var  entryPoint = target.Feed.GetEntryPoint(command);
        bool gui        = entryPoint is not {
            NeedsTerminal : true
        };

        try
        {
#if NETFRAMEWORK
            string hash    = (target.Uri + "#" + command).Hash(SHA256.Create());
            string exeName = (entryPoint == null)
                ? FeedUri.Escape(target.Feed.Name)
                : entryPoint.BinaryName ?? entryPoint.Command;
            string path = Path.Combine(
                IntegrationManager.GetDir(machineWide, "stubs", hash),
                exeName + ".exe");

            CreateOrUpdateRunStub(path, target, gui, command);
            return(new[] { path });
#else
            return(GetArguments(target.Uri, command, gui)
                   .Prepend(GetBinary(gui))
                   .ToList());
#endif
        }
        #region Error handling
        catch (InvalidOperationException ex)
        {
            // Wrap exception since only certain exception types are allowed
            throw new IOException(ex.Message, ex);
        }
        #endregion
    }
Beispiel #28
0
        /// <inheritdoc/>
        public string GetPath(FeedUri feedUri)
        {
            #region Sanity checks
            if (feedUri == null)
            {
                throw new ArgumentNullException(nameof(feedUri));
            }
            #endregion

            if (feedUri.IsFile)
            {
                throw new KeyNotFoundException("Feed cache does not handle local files: " + feedUri.ToStringRfc());
            }

            string fileName = feedUri.Escape();
            string path     = Path.Combine(DirectoryPath, fileName);
            if (FileUtils.ExistsCaseSensitive(path))
            {
                return(path);
            }
            else
            {
                throw new KeyNotFoundException(string.Format(Resources.FeedNotInCache, feedUri, path));
            }
        }
Beispiel #29
0
        private void Download(FeedUri url)
        {
            SetLastCheckAttempt(url);

            using (var feedFile = new TemporaryFile("0install-feed"))
            {
                try
                {
                    _handler.RunTask(new DownloadFile(url, feedFile));
                    ImportFeed(feedFile, url);
                }
                catch (WebException ex)
                {
                    Log.Warn(string.Format(Resources.FeedDownloadError, url));

                    if (url.IsLoopback)
                    {
                        throw;
                    }
                    Log.Info(Resources.TryingFeedMirror);
                    try
                    {
                        DownloadMirror(url);
                    }
                    catch (WebException)
                    {
                        // Report the original problem instead of mirror errors
                        throw ex;
                    }
                }
            }
        }
Beispiel #30
0
    /// <inheritdoc/>
    public async Task IntegrateAsync(FeedUri uri, IEnumerable <string>?add = null, IEnumerable <string>?remove = null, bool machineWide = false)
    {
        var args = new List <string> {
            "integrate", "--batch", uri.ToStringRfc()
        };

        if (machineWide)
        {
            args.Add("--machine");
        }

        void AddToArgs(string option, IEnumerable <string>?elements)
        {
            if (elements == null)
            {
                return;
            }
            foreach (string category in elements)
            {
                args.Add(option);
                args.Add(category);
            }
        }

        AddToArgs("--add", add);
        AddToArgs("--remove", remove);

        await Task.Run(() => _launcher.RunAndCapture(args.ToArray()));
    }
Beispiel #31
0
        /// <inheritdoc/>
        public void Add(FeedUri feedUri, byte[] data)
        {
            #region Sanity checks
            if (feedUri == null)
            {
                throw new ArgumentNullException("feedUri");
            }
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            #endregion

            // Add to underlying cache
            _backingCache.Add(feedUri, data);

            // Add to memory cache (replacing existing old versions)
            var feed = XmlStorage.LoadXml <Feed>(new MemoryStream(data));
            feed.Normalize(feedUri);

            string key = feedUri.Escape();
            lock (_feedDictionary)
            {
                _feedDictionary.Remove(key);
                _feedDictionary.Add(key, feed);
            }
        }
Beispiel #32
0
        /// <summary>
        /// Creates a new selection candidate.
        /// </summary>
        /// <param name="feedUri">The file name or URL of the feed listing the implementation.</param>
        /// <param name="feedPreferences">The <see cref="FeedPreferences"/> for <see cref="FeedUri"/>.</param>
        /// <param name="implementation">The implementation this selection candidate references.</param>
        /// <param name="requirements">A set of requirements/restrictions the <paramref name="implementation"/> needs to fullfill for <see cref="IsSuitable"/> to be <c>true</c>.</param>
        /// <param name="offlineUncached">Mark this candidate as unsuitable because it is uncached and <see cref="Config.NetworkUse"/> is set to <see cref="NetworkLevel.Offline"/>.</param>
        /// <exception cref="InvalidDataException"><paramref name="implementation"/>'s <see cref="ImplementationBase.ID"/> is empty.</exception>
        public SelectionCandidate([NotNull] FeedUri feedUri, [NotNull] FeedPreferences feedPreferences, [NotNull] Implementation implementation, [NotNull] Requirements requirements, bool offlineUncached = false)
        {
            #region Sanity checks
            if (feedUri == null)
            {
                throw new ArgumentNullException(nameof(feedUri));
            }
            if (feedPreferences == null)
            {
                throw new ArgumentNullException(nameof(feedPreferences));
            }
            if (implementation == null)
            {
                throw new ArgumentNullException(nameof(implementation));
            }
            if (requirements == null)
            {
                throw new ArgumentNullException(nameof(requirements));
            }
            #endregion

            if (string.IsNullOrEmpty(implementation.ID))
            {
                throw new InvalidDataException(string.Format(Resources.ImplementationMissingID, implementation, feedUri));
            }

            FeedUri         = feedUri;
            FeedPreferences = feedPreferences;
            Implementation  = implementation;

            _implementationPreferences = feedPreferences[implementation.ID];

            CheckSuitabilty(requirements, offlineUncached);
        }
Beispiel #33
0
        //--------------------//

        #region Normalize
        /// <summary>
        /// Flattens the <see cref="Group"/> inheritance structure and sets missing default values in <see cref="Implementation"/>s.
        /// </summary>
        /// <param name="feedUri">The feed the data was originally loaded from; can be <see langword="null"/>.</param>
        /// <remarks>This method should be called to prepare a <see cref="Feed"/> for solver processing. Do not call it if you plan on serializing the feed again since it may loose some of its structure.</remarks>
        public override void Normalize(FeedUri feedUri = null)
        {
            #region Sanity checks
            if (feedUri == null)
            {
                throw new ArgumentNullException("feedUri");
            }
            #endregion

            // Apply if-0install-version filter
            _elements.RemoveAll(FilterMismatch);

            var collapsedElements = new List <Element>();

            foreach (var element in _elements)
            {
                element.InheritFrom(this);

                // Flatten structure in sub-groups, set missing default values in implementations
                element.Normalize(feedUri);

                var group = element as Group;
                if (group != null)
                {
                    // Move implementations out of sub-groups
                    collapsedElements.AddRange(group._elements);
                }
                else
                {
                    collapsedElements.Add(element);
                }
            }
            _elements.Clear();
            _elements.AddRange(collapsedElements);
        }
        /// <inheritdoc/>
        public override void Normalize(FeedUri feedUri)
        {
            #region Sanity checks
            if (feedUri == null) throw new ArgumentNullException(nameof(feedUri));
            #endregion

            base.Normalize(feedUri);

            if (Href != null) Href = ModelUtils.GetAbsoluteHref(Href, feedUri);
        }
Beispiel #35
0
        public void AddPackageSource(string uri)
        {
            var feedUri = new FeedUri(uri);

            CatalogManager.DownloadCatalog(feedUri);

            if (CatalogManager.AddSource(feedUri))
                CatalogManager.GetOnlineSafe();
            else
                Log.Warn(string.Format(Resources.CatalogAlreadyRegistered, feedUri.ToStringRfc()));
        }
Beispiel #36
0
        /// <inheritdoc/>
        public bool Contains(FeedUri feedUri)
        {
            #region Sanity checks
            if (feedUri == null) throw new ArgumentNullException(nameof(feedUri));
            #endregion

            // Local files are passed through directly
            if (feedUri.IsFile) return File.Exists(feedUri.LocalPath);

            return FileUtils.ExistsCaseSensitive(Path.Combine(DirectoryPath, feedUri.Escape()));
        }
            public override ExitCode Execute()
            {
                var uri = new FeedUri(AdditionalArgs[0]);

                if (CatalogManager.RemoveSource(uri))
                    return ExitCode.OK;
                else
                {
                    Handler.OutputLow(Resources.CatalogSources, string.Format(Resources.CatalogNotRegistered, uri.ToStringRfc()));
                    return ExitCode.NoChanges;
                }
            }
        /// <summary>
        /// Returns a list of all interface URIs a given feed can be registered for.
        /// </summary>
        /// <param name="feedUri">The URI of the feed to register.</param>
        /// <param name="suggestedStabilityPolicy">Returns the suggested value for <see cref="InterfacePreferences.StabilityPolicy"/>.</param>
        /// <returns>A set of interface URIs.</returns>
        private IEnumerable<FeedUri> GetInterfaces(FeedUri feedUri, ref Stability suggestedStabilityPolicy)
        {
            var feed = FeedManager.GetFresh(feedUri);
            var interfaces = feed.FeedFor.Select(reference => reference.Target).WhereNotNull().ToList();
            if (interfaces.Count == 0)
                throw new OptionException(string.Format(Resources.MissingFeedFor, feedUri), null);

            if (feed.Elements.Count == 1)
            {
                var singletonImplementation = feed.Elements[0] as Implementation;
                if (singletonImplementation != null) suggestedStabilityPolicy = singletonImplementation.Stability;
            }

            return interfaces;
        }
Beispiel #39
0
            public override ExitCode Execute()
            {
                var uri = new FeedUri(AdditionalArgs[0]);
                if (!_skipVerify) CatalogManager.DownloadCatalog(uri);

                if (CatalogManager.AddSource(uri))
                {
                    if (!_skipVerify) CatalogManager.GetOnlineSafe();
                    return ExitCode.OK;
                }
                else
                {
                    Handler.OutputLow(Resources.CatalogSources, string.Format(Resources.CatalogAlreadyRegistered, uri.ToStringRfc()));
                    return ExitCode.NoChanges;
                }
            }
        /// <summary>
        /// Creates a new interface dialog.
        /// </summary>
        /// <param name="interfaceUri">The interface to modify the preferences for.</param>
        /// <param name="solveCallback">Called after <see cref="InterfacePreferences"/> have been changed and the <see cref="ISolver"/> needs to be rerun.</param>
        /// <param name="feedManager">The feed manager used to retrieve feeds for additional information about implementations.</param>
        private InterfaceDialog([NotNull] FeedUri interfaceUri, [NotNull] Func<Selections> solveCallback, [NotNull] IFeedManager feedManager)
        {
            #region Sanity checks
            if (interfaceUri == null) throw new ArgumentNullException(nameof(interfaceUri));
            if (solveCallback == null) throw new ArgumentNullException(nameof(solveCallback));
            if (feedManager == null) throw new ArgumentNullException(nameof(feedManager));
            #endregion

            InitializeComponent();
            comboBoxStability.Items.AddRange(new object[] {Resources.UseDefaultSetting, Stability.Stable, Stability.Testing, Stability.Developer});
            dataColumnUserStability.Items.AddRange(Stability.Unset, Stability.Preferred, Stability.Packaged, Stability.Stable, Stability.Testing, Stability.Developer);

            _interfaceUri = interfaceUri;
            _mainFeed = feedManager[_interfaceUri];
            _solveCallback = solveCallback;
            _feedManager = feedManager;
        }
Beispiel #41
0
        /// <summary>
        /// Loads the embedded configuration.
        /// </summary>
        private EmbeddedConfig()
        {
            var lines = typeof(EmbeddedConfig).GetEmbeddedString("EmbeddedConfig.txt").SplitMultilineText();

            try
            {
                AppUri = new FeedUri(ConfigurationManager.AppSettings["app_uri"] ?? lines[0].TrimEnd());
                Log.Info("Embedded config: AppUri: " + AppUri);

                AppName = ConfigurationManager.AppSettings["app_name"] ?? lines[1].TrimEnd();
                Log.Info("Embedded config: AppName: " + AppName);

                AppMode = GetAppMode(ConfigurationManager.AppSettings["app_mode"] ?? lines[2].TrimEnd());
                Log.Info("Embedded config: AppMode: " + AppMode);
            }
            catch (UriFormatException)
            {
                // No (valid) feed URI set
            }
        }
        /// <inheritdoc/>
        public void Add(FeedUri feedUri, byte[] data)
        {
            #region Sanity checks
            if (feedUri == null) throw new ArgumentNullException("feedUri");
            if (data == null) throw new ArgumentNullException("data");
            #endregion

            // Add to underlying cache
            _backingCache.Add(feedUri, data);

            // Add to memory cache (replacing existing old versions)
            var feed = XmlStorage.LoadXml<Feed>(new MemoryStream(data));
            feed.Normalize(feedUri);

            string key = feedUri.Escape();
            lock (_feedDictionary)
            {
                _feedDictionary.Remove(key);
                _feedDictionary.Add(key, feed);
            }
        }
Beispiel #43
0
        /// <inheritdoc/>
        protected override ExitCode ExecuteHelper(ICategoryIntegrationManager integrationManager, FeedUri interfaceUri)
        {
            #region Sanity checks
            if (interfaceUri == null) throw new ArgumentNullException("interfaceUri");
            if (integrationManager == null) throw new ArgumentNullException("integrationManager");
            #endregion

            try
            {
                integrationManager.RemoveApp(integrationManager.AppList[interfaceUri]);
            }
                #region Sanity checks
            catch (KeyNotFoundException ex)
            {
                // Wrap exception since only certain exception types are allowed
                throw new IOException(ex.Message, ex);
            }
            #endregion

            return ExitCode.OK;
        }
        /// <summary>
        /// Helper method for <see cref="GetHumanReadable"/> that recursivley writes information about <see cref="ImplementationSelection"/>s to a <see cref="StringBuilder"/>.
        /// </summary>
        /// <param name="selections">The selections to be displayed.</param>
        /// <param name="builder">The string builder to write the output to.</param>
        /// <param name="handled">A list of interface URIs that have already been handled; used to prevent infinite recursion.</param>
        /// <param name="store">A store to search for implementation storage locations.</param>
        /// <param name="indent">An indention prefix for the current recursion level (to create a visual hierachy).</param>
        /// <param name="interfaceUri">The <see cref="ImplementationSelection.InterfaceUri"/> to look for.</param>
        private static void PrintNode(Selections selections, StringBuilder builder, HashSet<FeedUri> handled, IStore store, string indent, FeedUri interfaceUri)
        {
            // Prevent infinite recursion
            if (handled.Contains(interfaceUri)) return;
            handled.Add(interfaceUri);

            builder.AppendLine(indent + "- URI: " + interfaceUri);
            try
            {
                var implementation = selections[interfaceUri];
                builder.AppendLine(indent + "  Version: " + implementation.Version);
                builder.AppendLine(indent + "  Path: " + (implementation.LocalPath ?? implementation.GetPath(store) ?? Resources.NotCached));
                builder.AppendLine();

                indent += "    ";

                // Recurse into regular dependencies
                foreach (var dependency in implementation.Dependencies)
                    PrintNode(selections, builder, handled, store, indent, dependency.InterfaceUri);

                if (implementation.Commands.Count != 0)
                {
                    var command = implementation.Commands[0];

                    // Recurse into command dependencies
                    foreach (var dependency in command.Dependencies)
                        PrintNode(selections, builder, handled, store, indent, dependency.InterfaceUri);

                    // Recurse into runner dependency
                    if (command.Runner != null)
                        PrintNode(selections, builder, handled, store, indent, command.Runner.InterfaceUri);
                }
            }
            catch (KeyNotFoundException)
            {
                builder.AppendLine(indent + "  " + Resources.NoSelectedVersion);
            }
        }
        /// <summary>
        /// Sets missing default values and handles legacy elements.
        /// </summary>
        /// <param name="feedUri">The feed the data was originally loaded from.</param>
        /// <remarks>This method should be called to prepare a <see cref="Feed"/> for solver processing. Do not call it if you plan on serializing the feed again since it may loose some of its structure.</remarks>
        public override void Normalize(FeedUri feedUri)
        {
            #region Sanity checks
            if (feedUri == null) throw new ArgumentNullException(nameof(feedUri));
            #endregion

            base.Normalize(feedUri);

            // Merge the version modifier into the normal version attribute
            if (!string.IsNullOrEmpty(VersionModifier))
            {
                Version = new ImplementationVersion(Version + VersionModifier);
                VersionModifier = null;
            }

            // Default stability rating to testing
            if (Stability == Stability.Unset) Stability = Stability.Testing;

            // Make local paths absolute
            try
            {
                if (!string.IsNullOrEmpty(LocalPath))
                    LocalPath = ModelUtils.GetAbsolutePath(LocalPath, feedUri);
                else if (!string.IsNullOrEmpty(ID) && ID.StartsWith(".")) // Get local path from ID
                    LocalPath = ID = ModelUtils.GetAbsolutePath(ID, feedUri);
            }
                #region Error handling
            catch (UriFormatException ex)
            {
                Log.Error(ex);
                LocalPath = null;
            }
            #endregion

            // Parse manifest digest from ID if missing
            if (!string.IsNullOrEmpty(ID)) _manifestDigest.ParseID(ID);
        }
Beispiel #46
0
        /// <summary>
        /// Sets <see cref="Store.Model.Requirements.InterfaceUri"/> and applies <see cref="Requirements"/> options that need to be deferred to the end of the parsing process.
        /// </summary>
        protected void SetInterfaceUri(FeedUri uri)
        {
            Requirements.InterfaceUri = uri;

            if (_version != null)
                Requirements.ExtraRestrictions[Requirements.InterfaceUri] = _version;
            else if (_notBefore != null || _before != null)
                Requirements.ExtraRestrictions[Requirements.InterfaceUri] = new VersionRange(_notBefore, _before);
        }
        public void TestNormalizeLocalPath()
        {
            var localUri = new FeedUri(WindowsUtils.IsWindows ? @"C:\local\feed.xml" : "/local/feed.xml");

            var implementation1 = new Implementation {ID = "./subdir"};
            implementation1.Normalize(localUri);
            Assert.AreEqual(
                expected: WindowsUtils.IsWindows ? @"C:\local\.\subdir" : "/local/./subdir",
                actual: implementation1.ID);
            Assert.AreEqual(
                expected: WindowsUtils.IsWindows ? @"C:\local\.\subdir" : "/local/./subdir",
                actual: implementation1.LocalPath);

            var implementation2 = new Implementation {ID = "./wrong", LocalPath = "subdir"};
            implementation2.Normalize(localUri);
            Assert.AreEqual(
                expected: "./wrong",
                actual: implementation2.ID);
            Assert.AreEqual(
                expected: WindowsUtils.IsWindows ? @"C:\local\subdir" : "/local/subdir",
                actual: implementation2.LocalPath);
        }
        private IEnumerable<SelectionCandidate> GenerateDummyCandidates(FeedUri feedUri)
        {
            if (feedUri.IsFromDistribution) return Enumerable.Empty<SelectionCandidate>();

            try
            {
                var feed = _feedCache.GetFeed(feedUri);
                var feedPreferences = FeedPreferences.LoadForSafe(feedUri);
                return feed.Elements.OfType<Implementation>().Select(implementation => GenerateDummyCandidate(feedUri, feedPreferences, implementation));
            }
                #region Error handling
            catch (KeyNotFoundException)
            {
                return Enumerable.Empty<SelectionCandidate>();
            }
            #endregion
        }
 private SelectionCandidate GenerateDummyCandidate(FeedUri feedUri, FeedPreferences feedPreferences, Implementation implementation)
 {
     return new SelectionCandidate(feedUri, feedPreferences, implementation,
         new Requirements(_interfaceUri, Command.NameRun, new Architecture(Architecture.CurrentSystem.OS, Cpu.All)));
 }
        /// <summary>
        /// Adds a feed to the list of custom feeds.
        /// </summary>
        private void AddCustomFeed(string input)
        {
            FeedUri feedUri;
            try
            {
                feedUri = new FeedUri(input);
            }
            catch (UriFormatException ex)
            {
                Msg.Inform(this, ex.Message, MsgSeverity.Error);
                return;
            }

            if (_interfaceUri.IsFile)
            {
                if (!File.Exists(_interfaceUri.LocalPath))
                {
                    Msg.Inform(this, string.Format(Resources.FileOrDirNotFound, _interfaceUri.LocalPath), MsgSeverity.Warn);
                    return;
                }
            }
            else
            {
                Feed feed = null;
                try
                {
                    using (var handler = new GuiTaskHandler(this))
                    {
                        handler.RunTask(new SimpleTask(Resources.CheckingFeed,
                            delegate
                            {
                                using (var webClient = new WebClientTimeout())
                                    feed = XmlStorage.FromXmlString<Feed>(webClient.DownloadString(feedUri));
                            }));
                    }
                }
                    #region Error handling
                catch (OperationCanceledException)
                {
                    return;
                }
                catch (IOException ex)
                {
                    Msg.Inform(this, ex.Message, MsgSeverity.Error);
                    return;
                }
                catch (InvalidDataException ex)
                {
                    Msg.Inform(this, ex.Message, MsgSeverity.Error);
                    return;
                }
                catch (WebException ex)
                {
                    Msg.Inform(this, ex.Message, MsgSeverity.Error);
                    return;
                }
                catch (UnauthorizedAccessException ex)
                {
                    Msg.Inform(this, ex.Message, MsgSeverity.Error);
                    return;
                }
                #endregion

                // Ensure a matching <feed-for> is present for online feeds
                if (feed.FeedFor.All(entry => entry.Target != _interfaceUri))
                    if (!Msg.YesNo(this, Resources.IgnoreMissingFeedFor, MsgSeverity.Warn)) return;
            }

            var reference = new FeedReference {Source = feedUri};
            if (_interfacePreferences.Feeds.Contains(reference)) return;
            _interfacePreferences.Feeds.Add(reference);
            listBoxFeeds.Items.Add(reference);
        }
Beispiel #51
0
        /// <inheritdoc/>
        protected override ExitCode ExecuteHelper(ICategoryIntegrationManager integrationManager, FeedUri interfaceUri)
        {
            #region Sanity checks
            if (interfaceUri == null) throw new ArgumentNullException(nameof(interfaceUri));
            if (integrationManager == null) throw new ArgumentNullException(nameof(integrationManager));
            #endregion

            if (RemoveOnly())
            {
                RemoveOnly(integrationManager, interfaceUri);
                return ExitCode.OK;
            }

            CheckInstallBase();

            var appEntry = GetAppEntry(integrationManager, ref interfaceUri);
            var feed = FeedManager[interfaceUri];

            if (NoSpecifiedIntegrations())
            {
                var state = new IntegrationState(integrationManager, appEntry, feed);
                Retry:
                Handler.ShowIntegrateApp(state);
                try
                {
                    state.ApplyChanges();
                }
                    #region Error handling
                catch (ConflictException ex)
                {
                    if (Handler.Ask(
                        Resources.IntegrateAppInvalid + Environment.NewLine + ex.Message + Environment.NewLine + Environment.NewLine + Resources.IntegrateAppRetry,
                        defaultAnswer: false, alternateMessage: ex.Message))
                        goto Retry;
                }
                catch (InvalidDataException ex)
                {
                    if (Handler.Ask(
                        Resources.IntegrateAppInvalid + Environment.NewLine + ex.Message + Environment.NewLine + Environment.NewLine + Resources.IntegrateAppRetry,
                        defaultAnswer: false, alternateMessage: ex.Message))
                        goto Retry;
                }
                #endregion

                return ExitCode.OK;
            }

            RemoveAndAdd(integrationManager, feed, appEntry);
            return ExitCode.OK;
        }
        /// <inheritdoc/>
        public Catalog DownloadCatalog(FeedUri source)
        {
            #region Sanity checks
            if (source == null) throw new ArgumentNullException("source");
            #endregion

            if (source.IsFile) return XmlStorage.LoadXml<Catalog>(source.LocalPath);

            var download = new DownloadMemory(source);
            _handler.RunTask(download);
            var data = download.GetData();
            _trustManager.CheckTrust(data, source);
            return XmlStorage.LoadXml<Catalog>(new MemoryStream(data));
        }
Beispiel #53
0
        /// <inheritdoc/>
        public void RemoveTile(FeedUri interfaceUri)
        {
            #region Sanity checks
            if (interfaceUri == null) throw new ArgumentNullException(nameof(interfaceUri));
            #endregion

            RemoveTile(_tileDictionary[interfaceUri]);
        }
Beispiel #54
0
        /// <inheritdoc/>
        public IAppTile GetTile(FeedUri interfaceUri)
        {
            #region Sanity checks
            if (interfaceUri == null) throw new ArgumentNullException(nameof(interfaceUri));
            #endregion

            return _tileDictionary.ContainsKey(interfaceUri) ? _tileDictionary[interfaceUri] : null;
        }
Beispiel #55
0
        /// <inheritdoc/>
        public IAppTile QueueNewTile(FeedUri interfaceUri, string appName, AppStatus status, IIconCache iconCache = null, bool machineWide = false)
        {
            #region Sanity checks
            if (interfaceUri == null) throw new ArgumentNullException(nameof(interfaceUri));
            if (appName == null) throw new ArgumentNullException(nameof(appName));
            if (_tileDictionary.ContainsKey(interfaceUri)) throw new InvalidOperationException("Duplicate interface URI");
            #endregion

            var tile = new AppTile(interfaceUri, appName, status, iconCache, machineWide) {Width = _flowLayout.Width};

            if (appName.ContainsIgnoreCase(TextSearch.Text))
            {
                _appTileQueueHeight += tile.Height;

                // Alternate between light and dark tiles
                tile.BackColor = _lastTileLight ? TileColorDark : TileColorLight;
                _lastTileLight = !_lastTileLight;
            }
            else tile.Visible = false;

            _appTileQueue.Add(tile);
            _tileDictionary.Add(interfaceUri, tile);
            return tile;
        }
Beispiel #56
0
        /// <summary>
        /// Finds an existing <see cref="AppEntry"/> or creates a new one for a specific interface URI and feed.
        /// </summary>
        /// <param name="integrationManager">Manages desktop integration operations.</param>
        /// <param name="interfaceUri">The interface URI to create an <see cref="AppEntry"/> for. Will be updated if <see cref="Feed.ReplacedBy"/> is set and accepted by the user.</param>
        protected override AppEntry GetAppEntry(IIntegrationManager integrationManager, ref FeedUri interfaceUri)
        {
            #region Sanity checks
            if (integrationManager == null) throw new ArgumentNullException(nameof(integrationManager));
            if (interfaceUri == null) throw new ArgumentNullException(nameof(interfaceUri));
            #endregion

            var appEntry = base.GetAppEntry(integrationManager, ref interfaceUri);
            var feed = FeedManager.GetFresh(interfaceUri);

            // Detect feed changes that may make an AppEntry update necessary
            if (!appEntry.CapabilityLists.UnsequencedEquals(feed.CapabilityLists))
            {
                string changedMessage = string.Format(Resources.CapabilitiesChanged, appEntry.Name);
                if (Handler.Ask(
                    changedMessage + " " + Resources.AskUpdateCapabilities,
                    defaultAnswer: false, alternateMessage: changedMessage))
                    integrationManager.UpdateApp(appEntry, feed);
            }

            return appEntry;
        }
 /// <inheritdoc/>
 public bool AddSource(FeedUri uri)
 {
     var sources = GetSources().ToList();
     if (!sources.AddIfNew(uri)) return false;
     SetSources(sources);
     return true;
 }
 private LinkLabel CreateLinkLabel(FeedUri interfaceUri)
 {
     var linkLabel = new LinkLabel {Text = Resources.Change, Dock = DockStyle.Fill, TextAlign = ContentAlignment.MiddleLeft};
     linkLabel.LinkClicked += delegate { InterfaceDialog.Show(this, interfaceUri, _solveCallback, _feedCache); };
     return linkLabel;
 }
        /// <inheritdoc/>
        public bool RemoveSource(FeedUri uri)
        {
            var sources = GetSources().ToList();
            if (!sources.Remove(uri)) return false;
            SetSources(sources);

            // Remove relevant entries from cache
            var cached = GetCached();
            if (cached != null)
            {
                cached.Feeds.RemoveAll(x => x.CatalogUri == uri);
                SaveCache(cached);
            }

            return true;
        }
Beispiel #60
0
 /// <summary>
 /// Applies the <see cref="_removeCategories"/> specified by the user.
 /// </summary>
 private void RemoveOnly(ICategoryIntegrationManager integrationManager, FeedUri interfaceUri)
 {
     integrationManager.RemoveAccessPointCategories(integrationManager.AppList[interfaceUri], _removeCategories.ToArray());
 }