hadris-cpio 2.0.0

A rust implementation of the CPIO archive format (newc/SVR4).
Documentation

Hadris CPIO

A Rust implementation of the CPIO archive format (newc/SVR4) with support for no-std environments, streaming reads, and archive creation.

Features

  • Read & Write Support - Stream entries from existing archives, create new ones
  • No-std Compatible - Use in bootloaders, kernels, and embedded systems
  • newc Format - Both 070701 (standard) and 070702 (CRC) variants
  • Full Entry Types - Regular files, directories, symlinks, hard links, device nodes, FIFOs
  • Filesystem Scanning - Build archives directly from a host directory tree

Quick Start

Reading an Archive

use std::fs::File;
use std::io::BufReader;
use hadris_cpio::CpioArchiveReader;

let file = File::open("archive.cpio")?;
let mut reader = CpioArchiveReader::new(BufReader::new(file));

while let Some(entry) = reader.next_entry_alloc()? {
    let name = entry.name_str().unwrap_or("<invalid>");
    println!("{} ({} bytes)", name, entry.file_size());
    reader.skip_entry_data_owned(&entry)?;
}

Creating an Archive from a Directory

use std::fs::File;
use std::io::BufWriter;
use hadris_cpio::{CpioArchiveWriter, CpioWriteOptions, FileTree};

let tree = FileTree::from_fs(std::path::Path::new("./my-directory"))?;
let out = BufWriter::new(File::create("archive.cpio")?);
let _out = CpioArchiveWriter::new(out, CpioWriteOptions::default()).finish(&tree)?;

Building an Archive Programmatically

use hadris_cpio::{CpioArchiveWriter, CpioWriteOptions, FileNode, FileTree};

let mut tree = FileTree::new();
tree.add(FileNode::file("hello.txt", b"Hello, world!\n".to_vec(), 0o644));
tree.add(FileNode::dir("subdir", vec![
    FileNode::file("nested.txt", b"Nested content\n".to_vec(), 0o644),
], 0o755));
tree.add(FileNode::symlink("link.txt", "hello.txt"));

let buf = CpioArchiveWriter::new(Vec::new(), CpioWriteOptions::default()).finish(&tree)?;

Feature Flags

Feature Description Dependencies
read Streaming archive reader None
alloc Heap allocation without full std alloc crate
std Full standard library support std, alloc
sync Synchronous archive API hadris-io/sync
async Asynchronous archive API hadris-io/async
write Archive creation alloc, read

Default features: std, sync, read, write

std selects platform integration but does not select an I/O mode. Custom configurations should enable sync, async, or both explicitly.

For Bootloaders (minimal footprint)

[dependencies]
hadris-cpio = { version = "2.0.0", default-features = false, features = ["read", "sync"] }

For Kernels with Heap (no-std + alloc)

[dependencies]
hadris-cpio = { version = "2.0.0", default-features = false, features = ["read", "alloc", "sync"] }

For Desktop Applications (full features)

[dependencies]
hadris-cpio = "2.0.0"  # Uses default features

Archive Format

This crate implements the "new" (newc) ASCII CPIO format, which is the format used by:

  • Linux initramfs images (gen_init_cpio)
  • RPM package payloads
  • The cpio -H newc command

Each entry consists of a 110-byte ASCII header, a NUL-terminated filename, and file data. All sections are padded to 4-byte boundaries. The archive ends with a TRAILER!!! sentinel.

Two magic numbers are supported:

  • 070701 - Standard newc format
  • 070702 - newc with per-file CRC checksums

No-std Compatibility

The crate is designed for no-std environments:

  • Core reading requires only the read feature (zero allocations with next_entry_with_buf)
  • Allocating reader requires alloc (uses Vec for filenames and data)
  • Writing and filesystem scanning require alloc and std respectively
  • All I/O uses hadris-io traits instead of std::io

Interoperability

Archives created with this crate are compatible with:

  • GNU cpio (cpio -t, cpio -i)
  • Linux kernel initramfs loader
  • RPM tools

Specification References

  • cpio(5) man page
  • Linux kernel usr/gen_init_cpio.c
  • RPM file format specification

License

This project is licensed under the MIT license.