Example #1
0
        protected ArchiveEntryBase(string name, ArchiveEntryType type)
        {
            Exceptions.CheckArgumentNullOrEmprty(name, "name");

            Name = name;
            Type = type;
        }
        protected void AddFile(string entry, string relativePath, string prefix, List <ArchiveEntry> value, ITaskItem[] metadata)
        {
            var fileName = Path.GetFileName(entry);

            byte[] fileHeader = null;
            byte[] hash       = null;
            byte[] md5hash    = null;
            byte[] buffer     = new byte[1024];
            bool   isAscii    = true;

            var fileMetadata = metadata.SingleOrDefault(m => m.IsPublished() && string.Equals(relativePath, m.GetPublishedPath()));

            using (Stream fileStream = File.OpenRead(entry))
            {
                if (fileName.StartsWith(".") || fileStream.Length == 0)
                {
                    // Skip hidden and empty files - this would case rmplint errors.
                    return;
                }

                using (var hasher = IncrementalHash.CreateHash(HashAlgorithmName.SHA256))
                    using (var md5hasher = IncrementalHash.CreateHash(HashAlgorithmName.MD5))
                    {
                        int read;

                        while (true)
                        {
                            read = fileStream.Read(buffer, 0, buffer.Length);

                            if (fileHeader == null)
                            {
                                fileHeader = new byte[read];
                                Buffer.BlockCopy(buffer, 0, fileHeader, 0, read);
                            }

                            hasher.AppendData(buffer, 0, read);
                            md5hasher.AppendData(buffer, 0, read);
                            isAscii = isAscii && buffer.All(c => c < 128);

                            if (read < buffer.Length)
                            {
                                break;
                            }
                        }

                        hash    = hasher.GetHashAndReset();
                        md5hash = md5hasher.GetHashAndReset();
                    }

                // Only support ELF32 and ELF64 colors; otherwise default to BLACK.
                ArchiveEntryType entryType = this.GetArchiveEntryType(fileHeader);

                var mode = LinuxFileMode.S_IROTH | LinuxFileMode.S_IRGRP | LinuxFileMode.S_IRUSR | LinuxFileMode.S_IFREG;

                if (entryType == ArchiveEntryType.Executable32 || entryType == ArchiveEntryType.Executable64)
                {
                    mode |= LinuxFileMode.S_IXOTH | LinuxFileMode.S_IXGRP | LinuxFileMode.S_IWUSR | LinuxFileMode.S_IXUSR;
                }

                // If a Linux path has been specified, use that one, else, use the default one based on the prefix
                // + current file name.
                string name = fileMetadata?.GetLinuxPath();

                if (name == null)
                {
                    name = prefix + "/" + fileName;
                }

                string linkTo = string.Empty;

                if (mode.HasFlag(LinuxFileMode.S_IFLNK))
                {
                    // Find the link text
                    int stringEnd = 0;

                    while (stringEnd < fileHeader.Length - 1 && fileHeader[stringEnd] != 0)
                    {
                        stringEnd++;
                    }

                    linkTo = Encoding.UTF8.GetString(fileHeader, 0, stringEnd + 1);
                    hash   = new byte[] { };
                }

                // If the user has chosen to override the file node, respect that
                var overridenFileMode = fileMetadata?.GetLinuxFileMode();

                if (overridenFileMode != null)
                {
                    // We expect the user to specify the file mode in its octal representation.
                    try
                    {
                        mode = (LinuxFileMode)Convert.ToUInt32(overridenFileMode, 8);
                    }
                    catch (Exception)
                    {
                        throw new Exception($"Could not parse the file mode '{overridenFileMode}' for file '{name}'. Make sure to set the LinuxFileMode attriubute to an octal representation of a Unix file mode.");
                    }
                }

                ArchiveEntry archiveEntry = new ArchiveEntry()
                {
                    FileSize       = (uint)fileStream.Length,
                    Group          = fileMetadata.GetGroup(),
                    Owner          = fileMetadata.GetOwner(),
                    Modified       = File.GetLastAccessTimeUtc(entry),
                    SourceFilename = entry,
                    TargetPath     = name,
                    Sha256         = hash,
                    Md5Hash        = md5hash,
                    Type           = entryType,
                    LinkTo         = linkTo,
                    Inode          = this.inode++,
                    IsAscii        = isAscii,
                    Mode           = mode
                };

                value.Add(archiveEntry);
            }
        }
        protected void AddFile(string entry, string relativePath, string prefix, List <ArchiveEntry> value, ITaskItem[] metadata)
        {
            var fileName = Path.GetFileName(entry);

            byte[] fileHeader = null;
            byte[] hash       = null;
            byte[] md5hash    = null;
            byte[] buffer     = new byte[1024];
            bool   isAscii    = true;

            var fileMetadata = metadata.SingleOrDefault(m => m.IsPublished() && string.Equals(relativePath, m.GetPublishedPath()));

            using (Stream fileStream = File.OpenRead(entry))
            {
                // Skip hidden and empty files - this would case rpmlint errors.
                if (fileName.StartsWith("."))
                {
                    this.Log.LogWarning($"Ignoring file {relativePath} because it starts with the '.' character and is considered a hidden file.");
                    return;
                }

                if (fileStream.Length == 0)
                {
                    this.Log.LogWarning($"Ignoring file {relativePath} because it is empty.");
                    return;
                }

                using (var hasher = IncrementalHash.CreateHash(HashAlgorithmName.SHA256))
                    using (var md5hasher = IncrementalHash.CreateHash(HashAlgorithmName.MD5))
                    {
                        int read;

                        while (true)
                        {
                            read = fileStream.Read(buffer, 0, buffer.Length);

                            if (fileHeader == null)
                            {
                                fileHeader = new byte[read];
                                Buffer.BlockCopy(buffer, 0, fileHeader, 0, read);
                            }

                            hasher.AppendData(buffer, 0, read);
                            md5hasher.AppendData(buffer, 0, read);
                            isAscii = isAscii && buffer.All(c => c < 128);

                            if (read < buffer.Length)
                            {
                                break;
                            }
                        }

                        hash    = hasher.GetHashAndReset();
                        md5hash = md5hasher.GetHashAndReset();
                    }

                // Only support ELF32 and ELF64 colors; otherwise default to BLACK.
                ArchiveEntryType entryType = this.GetArchiveEntryType(fileHeader);

                var mode = LinuxFileMode.S_IROTH | LinuxFileMode.S_IRGRP | LinuxFileMode.S_IRUSR | LinuxFileMode.S_IFREG;

                if (entryType == ArchiveEntryType.Executable32 || entryType == ArchiveEntryType.Executable64)
                {
                    mode |= LinuxFileMode.S_IXOTH | LinuxFileMode.S_IXGRP | LinuxFileMode.S_IWUSR | LinuxFileMode.S_IXUSR;
                }

                // If a Linux path has been specified, use that one, else, use the default one based on the prefix
                // + current file name.
                string name = fileMetadata?.GetLinuxPath();

                if (name == null)
                {
                    if (!string.IsNullOrEmpty(prefix))
                    {
                        name = prefix + "/" + fileName;
                    }
                    else
                    {
                        name = fileName;
                    }
                }

                string linkTo = string.Empty;

                if (mode.HasFlag(LinuxFileMode.S_IFLNK))
                {
                    // Find the link text
                    int stringEnd = 0;

                    while (stringEnd < fileHeader.Length - 1 && fileHeader[stringEnd] != 0)
                    {
                        stringEnd++;
                    }

                    linkTo = Encoding.UTF8.GetString(fileHeader, 0, stringEnd + 1);
                    hash   = new byte[] { };
                }

                mode = this.GetFileMode(name, fileMetadata, mode);

                ArchiveEntry archiveEntry = new ArchiveEntry()
                {
                    FileSize       = (uint)fileStream.Length,
                    Group          = fileMetadata.GetGroup(),
                    Owner          = fileMetadata.GetOwner(),
                    Modified       = File.GetLastWriteTimeUtc(entry),
                    SourceFilename = entry,
                    TargetPath     = name,
                    Sha256         = hash,
                    Md5Hash        = md5hash,
                    Type           = entryType,
                    LinkTo         = linkTo,
                    Inode          = this.inode++,
                    IsAscii        = isAscii,
                    Mode           = mode
                };

                value.Add(archiveEntry);
            }
        }