Provides a temporary path to write to and atomically inserts it at the destination location on disposal (if Commit was called).
Inheritance: IDisposable
Esempio n. 1
0
        /// <inheritdoc/>
        public string GetIcon(Uri iconUrl, ITaskHandler handler)
        {
            #region Sanity checks
            if (iconUrl == null) throw new ArgumentNullException(nameof(iconUrl));
            if (handler == null) throw new ArgumentNullException(nameof(handler));
            #endregion

            string path = Path.Combine(DirectoryPath, new FeedUri(iconUrl).Escape());

            // Prevent file-exists race conditions
            lock (_lock)
            {
                // Download missing icons
                if (!File.Exists(path))
                {
                    using (var atomic = new AtomicWrite(path))
                    {
                        handler.RunTask(new DownloadFile(iconUrl, atomic.WritePath));
                        atomic.Commit();
                    }
                }
            }

            return path;
        }
Esempio n. 2
0
        /// <summary>
        /// Sets the list of catalog sources in a configuration file.
        /// </summary>
        /// <param name="uris">The list of catalog sources to use from now on.</param>
        /// <exception cref="IOException">There was a problem writing a configuration file.</exception>
        /// <exception cref="UnauthorizedAccessException">Access to a configuration file was not permitted.</exception>
        public static void SetSources([NotNull, ItemNotNull, InstantHandle] IEnumerable<FeedUri> uris)
        {
            #region Sanity checks
            if (uris == null) throw new ArgumentNullException("uris");
            #endregion

            using (var atomic = new AtomicWrite(Locations.GetSaveConfigPath("0install.net", true, "catalog-sources")))
            {
                using (var configFile = new StreamWriter(atomic.WritePath, append: false, encoding: FeedUtils.Encoding) {NewLine = "\n"})
                {
                    foreach (var uri in uris)
                        configFile.WriteLine(uri.ToStringRfc());
                }
                atomic.Commit();
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Saves the settings to an INI file.
        /// </summary>
        /// <remarks>This method performs an atomic write operation when possible.</remarks>
        /// <exception cref="IOException">A problem occurs while writing the file.</exception>
        /// <exception cref="UnauthorizedAccessException">Write access to the file is not permitted.</exception>
        public void Save([NotNull] string path)
        {
            TransferToIni();

            Log.Debug("Saving Config to: " + path);

            using (var atomic = new AtomicWrite(path))
            using (var writer = new StreamWriter(atomic.WritePath, append: false, encoding: FeedUtils.Encoding))
            {
                new StreamIniDataParser().WriteData(writer, _iniData);
                atomic.Commit();
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Adds a directory prefix to all entries in an external flag file.
        /// </summary>
        /// <param name="path">The full path to the flag file, named <see cref="FlagUtils.XbitFile"/> or <see cref="FlagUtils.SymlinkFile"/>.</param>
        /// <param name="source">The old path of the renamed file or directory relative to <paramref name="path"/>.</param>
        /// <param name="destination">The new path of the renamed file or directory relative to <paramref name="path"/>.</param>
        /// <exception cref="ArgumentException"><paramref name="source"/> or <paramref name="destination"/> is not a relative path.</exception>
        /// <exception cref="IOException">There was an error writing the flag file.</exception>
        /// <exception cref="UnauthorizedAccessException">You have insufficient rights to write the flag file.</exception>
        public static void Rename([NotNull] string path, [NotNull] string source, [NotNull] string destination)
        {
            #region Sanity checks
            if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path");
            if (string.IsNullOrEmpty(source)) throw new ArgumentNullException("source");
            if (Path.IsPathRooted(source)) throw new ArgumentException(Resources.PathNotRelative, "source");
            if (string.IsNullOrEmpty(destination)) throw new ArgumentNullException("destination");
            if (Path.IsPathRooted(destination)) throw new ArgumentException(Resources.PathNotRelative, "destination");
            #endregion

            if (!File.Exists(path)) return;

            // Convert paths to rooted Unix-style
            source = "/" + source.Replace(Path.DirectorySeparatorChar, '/');
            destination = "/" + destination.Replace(Path.DirectorySeparatorChar, '/');

            using (var atomic = new AtomicWrite(path))
            using (var newFlagFile = new StreamWriter(atomic.WritePath, append: false, encoding: FeedUtils.Encoding) {NewLine = "\n"})
            using (var oldFlagFile = File.OpenText(path))
            {
                // Each line in the file signals a flagged file
                while (!oldFlagFile.EndOfStream)
                {
                    string line = oldFlagFile.ReadLine();
                    if (line != null && line.StartsWith("/"))
                    {
                        if (line == source || line.StartsWith(source + "/"))
                            newFlagFile.WriteLine(destination + line.Substring(source.Length));
                        else newFlagFile.WriteLine(line);
                    }
                }
                atomic.Commit();
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Removes one or more flags for a file or directory in an external flag file.
        /// </summary>
        /// <param name="path">The full path to the flag file, named <see cref="FlagUtils.XbitFile"/> or <see cref="FlagUtils.SymlinkFile"/>.</param>
        /// <param name="relativePath">The path of the file or directory to remove relative to <paramref name="path"/>.</param>
        /// <exception cref="ArgumentException"><paramref name="relativePath"/> is not a relative path.</exception>
        /// <exception cref="IOException">There was an error writing the flag file.</exception>
        /// <exception cref="UnauthorizedAccessException">You have insufficient rights to write the flag file.</exception>
        public static void Remove([NotNull] string path, [NotNull] string relativePath)
        {
            #region Sanity checks
            if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path");
            if (string.IsNullOrEmpty(relativePath)) throw new ArgumentNullException("relativePath");
            if (Path.IsPathRooted(relativePath)) throw new ArgumentException(Resources.PathNotRelative, "relativePath");
            #endregion

            if (!File.Exists(path)) return;

            // Convert path to rooted Unix-style
            string unixPath = "/" + relativePath.Replace(Path.DirectorySeparatorChar, '/');

            using (var atomic = new AtomicWrite(path))
            using (var newFlagFile = new StreamWriter(atomic.WritePath, append: false, encoding: FeedUtils.Encoding) {NewLine = "\n"})
            using (var oldFlagFile = File.OpenText(path))
            {
                // Each line in the file signals a flagged file
                while (!oldFlagFile.EndOfStream)
                {
                    string line = oldFlagFile.ReadLine();
                    if (line != null && line.StartsWith("/"))
                    {
                        if (line == unixPath || line.StartsWith(unixPath + "/")) continue; // Filter out removed files

                        newFlagFile.WriteLine(line);
                    }
                }
                atomic.Commit();
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Sets the list of implementation directory paths in the current user configuration.
        /// </summary>
        /// <param name="paths">The list of implementation directory paths to set.</param>
        /// <exception cref="IOException">There was a problem writing a configuration file.</exception>
        /// <exception cref="UnauthorizedAccessException">Access to a configuration file was not permitted.</exception>
        public static void SetUserCustomImplementationDirs([NotNull, ItemNotNull, InstantHandle] IEnumerable<string> paths)
        {
            #region Sanity checks
            if (paths == null) throw new ArgumentNullException("paths");
            #endregion

            using (var atomic = new AtomicWrite(Locations.GetSaveConfigPath("0install.net", true, "injector", "implementation-dirs")))
            {
                using (var configFile = new StreamWriter(atomic.WritePath, append: false, encoding: FeedUtils.Encoding) {NewLine = "\n"})
                {
                    foreach (var path in paths)
                        configFile.WriteLine(path);
                }
                atomic.Commit();
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Sets the list of implementation directories in a specific configuration file.
        /// </summary>
        /// <param name="configPath">The path of the configuration file to write.</param>
        /// <param name="paths">The list of implementation directories to set.</param>
        /// <exception cref="IOException">There was a problem writing <paramref name="configPath"/>.</exception>
        /// <exception cref="UnauthorizedAccessException">Access to <paramref name="configPath"/> was not permitted.</exception>
        private static void SetImplementationDirs([NotNull] string configPath, [NotNull, ItemNotNull, InstantHandle] IEnumerable<string> paths)
        {
            #region Sanity checks
            if (string.IsNullOrEmpty(configPath)) throw new ArgumentNullException(nameof(configPath));
            if (paths == null) throw new ArgumentNullException(nameof(paths));
            #endregion

            using (var atomic = new AtomicWrite(configPath))
            {
                using (var configFile = new StreamWriter(atomic.WritePath, append: false, encoding: FeedUtils.Encoding) {NewLine = "\n"})
                {
                    foreach (var path in paths)
                        configFile.WriteLine(path);
                }
                atomic.Commit();
            }
        }
Esempio n. 8
0
 /// <summary>
 /// Writes the entire content of a byte array to file atomically.
 /// </summary>
 /// <param name="data">The data to write.</param>
 /// <param name="path">The file to write to.</param>
 private void WriteToFile(byte[] data, string path)
 {
     lock (_replaceLock)
         using (var atomic = new AtomicWrite(path))
         {
             File.WriteAllBytes(atomic.WritePath, data);
             atomic.Commit();
         }
 }