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);
}
}
}
}