Skip to content

Commit

Permalink
Merge cbea84c into 27a6e13
Browse files Browse the repository at this point in the history
  • Loading branch information
wcampbell0x2a authored Jan 21, 2024
2 parents 27a6e13 + cbea84c commit 79378f8
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 134 deletions.
34 changes: 21 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions backhand-cli/src/bin/replace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ fn main() -> ExitCode {
}

// write new file
let output = File::create(&args.out).unwrap();
filesystem.write(output).unwrap();
let mut output = File::create(&args.out).unwrap();
filesystem.write(&mut output).unwrap();
println!("replaced file and wrote to {}", args.out.display());

ExitCode::SUCCESS
Expand Down
2 changes: 1 addition & 1 deletion backhand/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ description = "Library for the reading, creating, and modification of SquashFS f
readme = "../README.md"

[dependencies]
deku = "0.16.0"
deku = { git = "https://github.com/sharksforarms/deku", branch = "impl-writer-inline-read-bytes" }
tracing = "0.1.40"
thiserror = "1.0.56"
flate2 = { version = "1.0.28", optional = true }
Expand Down
6 changes: 3 additions & 3 deletions backhand/src/compressor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::filesystem::writer::{CompressionExtra, FilesystemCompressor};

#[derive(Copy, Clone, Debug, PartialEq, Eq, DekuRead, DekuWrite, Default)]
#[deku(endian = "endian", ctx = "endian: deku::ctx::Endian")]
#[deku(type = "u16")]
#[deku(id_type = "u16")]
#[rustfmt::skip]
pub enum Compressor {
None = 0,
Expand Down Expand Up @@ -83,9 +83,9 @@ pub struct Xz {
// TODO: in openwrt, git-hash:f97ad870e11ebe5f3dcf833dda6c83b9165b37cb shows that before
// offical squashfs-tools had xz support they had the dictionary_size field as the last field
// in this struct. If we get test images, I guess we can support this in the future.
#[deku(cond = "!deku::rest.is_empty()")]
#[deku(cond = "!deku::reader.end()")]
pub bit_opts: Option<u16>,
#[deku(cond = "!deku::rest.is_empty()")]
#[deku(cond = "!deku::reader.end()")]
pub fb: Option<u16>,
}

Expand Down
4 changes: 2 additions & 2 deletions backhand/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl<'a> DataWriter<'a> {
pub(crate) fn just_copy_it<W: WriteSeek>(
&mut self,
mut reader: SquashfsRawData,
mut writer: W,
writer: &mut W,
) -> Result<(usize, Added), BackhandError> {
//just clone it, because block sizes where never modified, just copy it
let mut block_sizes = reader.file.basic.block_sizes.clone();
Expand Down Expand Up @@ -181,7 +181,7 @@ impl<'a> DataWriter<'a> {
pub(crate) fn add_bytes<W: WriteSeek>(
&mut self,
reader: impl Read,
mut writer: W,
writer: &mut W,
) -> Result<(usize, Added), BackhandError> {
let mut chunk_reader = DataWriterChunkReader {
chunk: vec![0u8; self.block_size as usize],
Expand Down
64 changes: 33 additions & 31 deletions backhand/src/filesystem/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use std::sync::Arc;
use std::sync::Mutex;
use std::time::{SystemTime, UNIX_EPOCH};

use deku::bitvec::BitVec;
use deku::DekuWrite;
use deku::writer::Writer;
use deku::DekuWriter;
use tracing::{error, info, trace};

use super::node::{InnerNode, Nodes};
Expand Down Expand Up @@ -391,8 +391,8 @@ impl<'a, 'b, 'c> FilesystemWriter<'a, 'b, 'c> {
w: W,
offset: u64,
) -> Result<(SuperBlock, u64), BackhandError> {
let writer = WriterWithOffset::new(w, offset)?;
self.write(writer)
let mut writer = WriterWithOffset::new(w, offset)?;
self.write(&mut writer)
}

fn write_data<W: WriteSeek>(
Expand Down Expand Up @@ -540,12 +540,11 @@ impl<'a, 'b, 'c> FilesystemWriter<'a, 'b, 'c> {
trace!("WRITING DIR: {block_offset:#02x?}");
let mut total_size: usize = 3;
for dir in Entry::into_dir(entries) {
let mut bv = BitVec::new();
dir.write(&mut bv, kind.inner.type_endian)?;
let bytes = bv.as_raw_slice();
dir_writer.write_all(bv.as_raw_slice())?;

let mut bytes = vec![];
let mut writer = Writer::new(&mut bytes);
dir.to_writer(&mut writer, kind.inner.type_endian)?;
total_size += bytes.len();
dir_writer.write_all(&bytes)?;
}
let entry = Entry::path(
filename,
Expand Down Expand Up @@ -581,25 +580,32 @@ impl<'a, 'b, 'c> FilesystemWriter<'a, 'b, 'c> {
// Write compression options, if any
if let Some(options) = &self.fs_compressor.options {
superblock.flags |= Flags::CompressorOptionsArePresent as u16;
let mut buf = BitVec::new();
let mut compression_opt_buf_out = vec![];
let mut writer = Writer::new(&mut compression_opt_buf_out);
match options {
CompressionOptions::Gzip(gzip) => {
gzip.write(&mut buf, self.kind.inner.type_endian)?
gzip.to_writer(&mut writer, self.kind.inner.type_endian)?
}
CompressionOptions::Lz4(lz4) => {
lz4.to_writer(&mut writer, self.kind.inner.type_endian)?
}
CompressionOptions::Lz4(lz4) => lz4.write(&mut buf, self.kind.inner.type_endian)?,
CompressionOptions::Zstd(zstd) => {
zstd.write(&mut buf, self.kind.inner.type_endian)?
zstd.to_writer(&mut writer, self.kind.inner.type_endian)?
}
CompressionOptions::Xz(xz) => {
xz.to_writer(&mut writer, self.kind.inner.type_endian)?
}
CompressionOptions::Lzo(lzo) => {
lzo.to_writer(&mut writer, self.kind.inner.type_endian)?
}
CompressionOptions::Xz(xz) => xz.write(&mut buf, self.kind.inner.type_endian)?,
CompressionOptions::Lzo(lzo) => lzo.write(&mut buf, self.kind.inner.type_endian)?,
CompressionOptions::Lzma => {}
}
let mut metadata = MetadataWriter::new(
self.fs_compressor,
self.block_size,
Kind { inner: self.kind.inner.clone() },
);
metadata.write_all(buf.as_raw_slice())?;
metadata.write_all(&compression_opt_buf_out)?;
metadata.finalize(&mut w)?;
}

Expand Down Expand Up @@ -661,7 +667,7 @@ impl<'a, 'b, 'c> FilesystemWriter<'a, 'b, 'c> {
superblock.id_count = count.try_into().unwrap();

info!("Finalize Superblock and End Bytes");
let bytes_written = self.finalize(&mut w, &mut superblock)?;
let bytes_written = self.finalize(w, &mut superblock)?;

info!("Success");
Ok((superblock, bytes_written))
Expand Down Expand Up @@ -704,17 +710,16 @@ impl<'a, 'b, 'c> FilesystemWriter<'a, 'b, 'c> {
// Seek back the beginning and write the superblock
info!("Writing Superblock");
w.rewind()?;
let mut bv = BitVec::new();
superblock.write(
&mut bv,
let mut writer = Writer::new(&mut w);
superblock.to_writer(
&mut writer,
(
self.kind.inner.magic,
self.kind.inner.version_major,
self.kind.inner.version_minor,
self.kind.inner.type_endian,
),
)?;
w.write_all(bv.as_raw_slice())?;

info!("Writing Finished");

Expand Down Expand Up @@ -750,7 +755,7 @@ impl<'a, 'b, 'c> FilesystemWriter<'a, 'b, 'c> {
/// │└────────────────────────────┘│
/// └──────────────────────────────┘
/// ```
fn write_lookup_table<D: DekuWrite<deku::ctx::Endian>, W: Write + Seek>(
fn write_lookup_table<D: DekuWriter<deku::ctx::Endian>, W: Write + Seek>(
&self,
mut w: W,
table: &Vec<D>,
Expand All @@ -760,20 +765,18 @@ impl<'a, 'b, 'c> FilesystemWriter<'a, 'b, 'c> {
let mut table_bytes = Vec::with_capacity(table.len() * element_size);
let mut iter = table.iter().peekable();
while let Some(t) = iter.next() {
let mut table_writer = Writer::new(&mut table_bytes);
// convert fragment ptr to bytes
let mut bv = BitVec::new();
t.write(&mut bv, self.kind.inner.type_endian)?;
table_bytes.write_all(bv.as_raw_slice())?;
t.to_writer(&mut table_writer, self.kind.inner.type_endian)?;

// once table_bytes + next is over the maximum size of a metadata block, write
if ((table_bytes.len() + element_size) > METADATA_MAXSIZE) || iter.peek().is_none() {
ptrs.push(w.stream_position()?);

let mut bv = BitVec::new();
// write metadata len
let len = metadata::set_if_uncompressed(table_bytes.len() as u16);
len.write(&mut bv, self.kind.inner.data_endian)?;
w.write_all(bv.as_raw_slice())?;
let mut writer = Writer::new(&mut w);
len.to_writer(&mut writer, self.kind.inner.data_endian)?;
// write metadata bytes
w.write_all(&table_bytes)?;

Expand All @@ -786,9 +789,8 @@ impl<'a, 'b, 'c> FilesystemWriter<'a, 'b, 'c> {

// write ptr
for ptr in ptrs {
let mut bv = BitVec::new();
ptr.write(&mut bv, self.kind.inner.type_endian)?;
w.write_all(bv.as_raw_slice())?;
let mut writer = Writer::new(&mut w);
ptr.to_writer(&mut writer, self.kind.inner.type_endian)?;
}

Ok((table_position, count))
Expand Down
12 changes: 6 additions & 6 deletions backhand/src/inode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use core::fmt;
use std::io::Write;

use deku::bitvec::{BitVec, Msb0};
use deku::prelude::*;

use crate::data::DataSize;
Expand Down Expand Up @@ -36,9 +35,10 @@ impl Inode {
superblock: &SuperBlock,
kind: &Kind,
) -> Entry<'a> {
let mut bytes = BitVec::<u8, Msb0>::new();
self.write(
&mut bytes,
let mut inode_bytes = vec![];
let mut writer = Writer::new(&mut inode_bytes);
self.to_writer(
&mut writer,
(
0xffff_ffff_ffff_ffff, // bytes_used is unused for ctx. set to max
superblock.block_size,
Expand All @@ -49,7 +49,7 @@ impl Inode {
.unwrap();
let start = m_writer.metadata_start;
let offset = m_writer.uncompressed_bytes.len() as u16;
m_writer.write_all(bytes.as_raw_slice()).unwrap();
m_writer.write_all(&inode_bytes).unwrap();

Entry {
start,
Expand All @@ -63,7 +63,7 @@ impl Inode {
}

#[derive(Debug, DekuRead, DekuWrite, Clone, Copy, PartialEq, Eq)]
#[deku(type = "u16")]
#[deku(id_type = "u16")]
#[deku(endian = "endian", ctx = "endian: deku::ctx::Endian")]
#[rustfmt::skip]
pub enum InodeId {
Expand Down
Loading

0 comments on commit 79378f8

Please sign in to comment.