using Packaging.Targets.Rpm; using System; using System.Collections.Generic; using System.IO; using System.Text; namespace Packaging.Targets.IO { /// /// Supports generating CPIO files. /// public class CpioFileCreator { /// /// The used to fetch file metadata. /// private IFileAnalyzer fileAnayzer; /// /// Initializes a new instance of the class. /// public CpioFileCreator() { this.fileAnayzer = new FileAnalyzer(); } /// /// Generates a based on a list of /// values. /// /// /// The values based on which to generate the . /// /// /// The which will hold the . /// public void FromArchiveEntries(List archiveEntries, Stream targetStream) { using (CpioFile cpioFile = new CpioFile(targetStream, leaveOpen: true)) { foreach (var entry in archiveEntries) { if (entry.Mode.HasFlag(LinuxFileMode.S_IFDIR)) { this.AddDirectory(entry, cpioFile); } else if (entry.Mode.HasFlag(LinuxFileMode.S_IFLNK)) { this.AddSymlink(entry, cpioFile); } else { this.AddFile(entry, cpioFile); } } cpioFile.WriteTrailer(); } } /// /// Adds a directory entry to the . /// /// /// The which represents the directory. /// /// /// The to which to add the directory entry. /// public void AddDirectory(ArchiveEntry entry, CpioFile cpioFile) { // Write out an entry for the current directory CpioHeader directoryHeader = new CpioHeader() { Check = 0, DevMajor = 1, DevMinor = 0, FileSize = 0, Gid = 0, Ino = entry.Inode, FileMode = entry.Mode, LastModified = entry.Modified, Nlink = 1, RDevMajor = 0, RDevMinor = 0, Signature = "070701", Uid = 0, NameSize = 0 }; var targetPath = entry.TargetPath; if (!targetPath.StartsWith(".")) { targetPath = "." + targetPath; } cpioFile.Write(directoryHeader, targetPath, new MemoryStream(Array.Empty())); } /// /// Adds a symlink entry to a . /// /// /// The symlink entry to add. /// /// /// The to which to add the entry. /// public void AddSymlink(ArchiveEntry entry, CpioFile cpioFile) { var targetPath = entry.TargetPath; if (!targetPath.StartsWith(".")) { targetPath = "." + targetPath; } CpioHeader cpioHeader = new CpioHeader() { Check = 0, DevMajor = 1, DevMinor = 0, FileSize = entry.FileSize, Gid = 0, // root Uid = 0, // root Ino = entry.Inode, FileMode = entry.Mode, LastModified = entry.Modified, NameSize = (uint)entry.TargetPath.Length + 1, Nlink = 1, RDevMajor = 0, RDevMinor = 0, Signature = "070701", }; cpioFile.Write(cpioHeader, targetPath, new MemoryStream(Encoding.UTF8.GetBytes(entry.LinkTo))); } /// /// Adds a file entry to a . /// /// /// The file entry to add. /// /// /// The to which to add the entry. /// public void AddFile(ArchiveEntry entry, CpioFile cpioFile) { var targetPath = entry.TargetPath; if (!targetPath.StartsWith(".")) { targetPath = "." + targetPath; } using (Stream fileStream = File.OpenRead(entry.SourceFilename)) { CpioHeader cpioHeader = new CpioHeader() { Check = 0, DevMajor = 1, DevMinor = 0, FileSize = entry.FileSize, Gid = 0, // root Uid = 0, // root Ino = entry.Inode, FileMode = entry.Mode, LastModified = entry.Modified, NameSize = (uint)entry.TargetPath.Length + 1, Nlink = 1, RDevMajor = 0, RDevMinor = 0, Signature = "070701", }; cpioFile.Write(cpioHeader, targetPath, fileStream); } } } }