Exemple #1
0
 /// <summary>
 /// Creates a new symbolic link to a file or directory.
 /// </summary>
 /// <param name="sourcePath">The path of the link to create.</param>
 /// <param name="targetPath">The path of the existing file or directory to point to (relative to <paramref name="sourcePath" />).</param>
 public static void CreateSymlink(string sourcePath, string targetPath)
 {
     try
     {
         FileUtils.CreateSymlink(sourcePath, targetPath);
     }
     catch (IOException) when(WindowsUtils.IsWindows)
     {
         Log.Debug("Creating Cygwin symlink instead of NTFS symlink due to insufficient permissions: " + sourcePath);
         CygwinUtils.CreateSymlink(sourcePath, targetPath);
     }
 }
        public override void Verify(string parentPath)
        {
            string path = Path.Combine(parentPath, Name);

            (File.Exists(path) || Directory.Exists(path)).Should().BeTrue(because: $"Symlink '{path}' should exist.");

            bool isSymlink = UnixUtils.IsUnix
                ? FileUtils.IsSymlink(path, out string?target)
                : CygwinUtils.IsSymlink(path, out target);

            isSymlink.Should().BeTrue(because: $"'{path}' should be a symlink.");
            target.Should().Be(Target, because: $"Symlink '{path}' should point to correct target.");
        }
        public override void Build(string parentPath)
        {
            string path = Path.Combine(parentPath, Name);

            if (UnixUtils.IsUnix)
            {
                FileUtils.CreateSymlink(path, Target);
            }
            else
            {
                CygwinUtils.CreateSymlink(path, Target);
            }
        }
Exemple #4
0
    /// <summary>
    /// Checks whether a file is a symbolic link.
    /// </summary>
    /// <param name="path">The path of the file to check.</param>
    /// <param name="manifestElement">The file's equivalent manifest entry, if available.</param>
    /// <param name="target">Returns the target the symbolic link points to if it exists.</param>
    /// <returns><c>true</c> if <paramref name="manifestElement"/> points to a symbolic link; <c>false</c> otherwise.</returns>
    public static bool IsSymlink(string path, [NotNullWhen(true)] out string?target, ManifestElement?manifestElement = null)
    {
        if (FileUtils.IsSymlink(path, out target) || WindowsUtils.IsWindowsNT && CygwinUtils.IsSymlink(path, out target))
        {
            return(true);
        }

        if (manifestElement is ManifestSymlink)
        {
            target = File.ReadAllText(path, Encoding.UTF8);
            return(true);
        }

        return(false);
    }
Exemple #5
0
 protected void CreateSymlink(string name)
 {
     if (WindowsUtils.IsWindows)
     {
         CygwinUtils.CreateSymlink(
             sourcePath: Path.Combine(_sourceDirectory, name),
             targetPath: Contents);
     }
     else
     {
         FileUtils.CreateSymlink(
             sourcePath: Path.Combine(_sourceDirectory, name),
             targetPath: Contents);
     }
 }
Exemple #6
0
        public void TestExtractUnixArchiveWithSymlink()
        {
            using (var extractor = new TarExtractor(typeof(TarExtractorTest).GetEmbeddedStream("testArchive.tar"), _sandbox))
                extractor.Run();

            string target;
            string source = Path.Combine(_sandbox, "symlink");

            if (UnixUtils.IsUnix)
            {
                FileUtils.IsSymlink(source, out target).Should().BeTrue();
            }
            else
            {
                CygwinUtils.IsSymlink(source, out target).Should().BeTrue();
            }

            target.Should().Be("subdir1/regular", because: "Symlink should point to 'regular'");
        }
Exemple #7
0
 /// <summary>
 /// Handles a file system entry the OS reports as a file.
 /// </summary>
 /// <param name="entry">The file entry to handle.</param>
 /// <param name="externalXbits">A list of fully qualified paths of files that are named in the <see cref="FlagUtils.SymlinkFile"/>.</param>
 /// <param name="externalSymlinks">A list of fully qualified paths of files that are named in the <see cref="FlagUtils.SymlinkFile"/>.</param>
 /// <exception cref="NotSupportedException">The <paramref name="entry"/> has illegal properties (e.g. is a device file, has line breaks in the filename, etc.).</exception>
 /// <exception cref="IOException">There was an error reading the file.</exception>
 /// <exception cref="UnauthorizedAccessException">You have insufficient rights to read the file.</exception>
 private void HandleEntry([NotNull] FileInfo entry, [NotNull] ICollection <string> externalXbits, [NotNull] ICollection <string> externalSymlinks)
 {
     if (_isUnixFS)
     {
         string symlinkTarget;
         if (FileUtils.IsSymlink(entry.FullName, out symlinkTarget))
         {
             HandleSymlink(entry, Encoding.UTF8.GetBytes(symlinkTarget));
         }
         else if (FileUtils.IsExecutable(entry.FullName))
         {
             HandleFile(entry, executable: true);
         }
         else if (!FileUtils.IsRegularFile(entry.FullName))
         {
             throw new NotSupportedException(string.Format(Resources.IllegalFileType, entry.FullName));
         }
         else
         {
             HandleFile(entry);
         }
     }
     else
     {
         string symlinkTarget;
         if (CygwinUtils.IsSymlink(entry.FullName, out symlinkTarget))
         {
             HandleSymlink(entry, Encoding.UTF8.GetBytes(symlinkTarget));
         }
         else if (externalSymlinks.Contains(entry.FullName))
         {
             HandleSymlink(entry, File.ReadAllBytes(entry.FullName));
         }
         else if (externalXbits.Contains(entry.FullName))
         {
             HandleFile(entry, executable: true);
         }
         else
         {
             HandleFile(entry);
         }
     }
 }
Exemple #8
0
        /// <summary>
        /// Creates a symbolic link in the filesystem if possible; stores it in a <see cref="FlagUtils.SymlinkFile"/> otherwise.
        /// </summary>
        /// <param name="source">A path relative to <see cref="SubDir"/>.</param>
        /// <param name="target">The target the symbolic link shall point to relative to <paramref name="source"/>. May use non-native path separators!</param>
        protected void CreateSymlink([NotNull] string source, [NotNull] string target)
        {
            #region Sanity checks
            if (string.IsNullOrEmpty(source))
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (string.IsNullOrEmpty(target))
            {
                throw new ArgumentNullException(nameof(target));
            }
            #endregion

            string sourceAbsolute  = CombinePath(source);
            string sourceDirectory = Path.GetDirectoryName(sourceAbsolute);
            if (sourceDirectory != null && !Directory.Exists(sourceDirectory))
            {
                Directory.CreateDirectory(sourceDirectory);
            }

            if (_isUnixFS)
            {
                FileUtils.CreateSymlink(sourceAbsolute, target);
            }
            else if (WindowsUtils.IsWindowsNT)
            {
                // NOTE: NTFS symbolic links require admin privileges; use Cygwin symlinks instead
                CygwinUtils.CreateSymlink(sourceAbsolute, target);
            }
            else
            {
                // Write link data as a normal file
                File.WriteAllText(sourceAbsolute, target);

                // Some OSes can't store the symlink flag directly in the filesystem; remember in a text-file instead
                string flagRelativePath = string.IsNullOrEmpty(Destination) ? source : Path.Combine(Destination, source);
                FlagUtils.Set(Path.Combine(TargetDir, FlagUtils.SymlinkFile), flagRelativePath);
            }
        }
Exemple #9
0
        public void TestApplyRecipeArchiv()
        {
            using (var archiveFile = new TemporaryFile("0install-unit-tests"))
            {
                typeof(ArchiveExtractorTest).CopyEmbeddedToFile("testArchive.zip", archiveFile);

                var downloadedFiles = new[] { archiveFile };
                var recipe          = new Recipe {
                    Steps = { new Archive {
                                  MimeType = Archive.MimeTypeZip, Destination = "subDir"
                              } }
                };

                using (TemporaryDirectory recipeDir = recipe.Apply(downloadedFiles, new SilentTaskHandler()))
                {
                    // /dest/symlink [S]
                    string path = Path.Combine(recipeDir, "subDir", "symlink");
                    File.Exists(path).Should().BeTrue(because: "File should exist: " + path);
                    if (UnixUtils.IsUnix)
                    {
                        FileUtils.IsSymlink(path).Should().BeTrue();
                    }
                    else
                    {
                        CygwinUtils.IsSymlink(path).Should().BeTrue();
                    }

                    // /dest/subdir2/executable [deleted]
                    path = Path.Combine(recipeDir, "subDir", "subdir2", "executable");
                    File.Exists(path).Should().BeTrue(because: "File should exist: " + path);
                    if (!UnixUtils.IsUnix)
                    {
                        FlagUtils.GetFiles(FlagUtils.XbitFile, recipeDir).Should().BeEquivalentTo(path);
                    }
                }
            }
        }