Skip to content

Commit

Permalink
Merge e38f5b8 into 9c63d20
Browse files Browse the repository at this point in the history
  • Loading branch information
wcampbell0x2a authored Feb 10, 2024
2 parents 9c63d20 + e38f5b8 commit eaf8873
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 2 deletions.
49 changes: 49 additions & 0 deletions backhand-cli/src/bin/unsquashfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use indicatif::{HumanDuration, ProgressBar, ProgressStyle};
use nix::libc::geteuid;
use nix::sys::stat::{dev_t, mknod, mode_t, umask, utimensat, utimes, Mode, SFlag, UtimensatFlags};
use nix::sys::time::{TimeSpec, TimeVal};
use nix::unistd::mkfifo;
use rayon::prelude::*;
use std::time::{Duration, Instant};

Expand Down Expand Up @@ -623,6 +624,54 @@ fn extract_all<'a, S: ParallelIterator<Item = &'a Node<SquashfsFileReader>>>(
}
}
}
InnerNode::NamedPipe => {
match mkfifo(
&filepath,
Mode::from_bits(mode_t::from(node.header.permissions)).unwrap(),
) {
Ok(_) => {
if args.info && !args.quiet {
created(&pb, filepath.to_str().unwrap());
}

set_attributes(&pb, args, &filepath, &node.header, root_process, true);
}
Err(_) => {
if args.info && !args.quiet {
created(&pb, filepath.to_str().unwrap());
}
let mut p = processing.lock().unwrap();
p.remove(fullpath);
drop(p);
return;
}
}
}
InnerNode::Socket => {
match mknod(
&filepath,
SFlag::S_IFSOCK,
Mode::from_bits(mode_t::from(node.header.permissions)).unwrap(),
dev_t::from(0_u64),
) {
Ok(_) => {
if args.info && !args.quiet {
created(&pb, filepath.to_str().unwrap());
}

set_attributes(&pb, args, &filepath, &node.header, root_process, true);
}
Err(_) => {
if args.info && !args.quiet {
created(&pb, filepath.to_str().unwrap());
let mut p = processing.lock().unwrap();
p.remove(fullpath);
drop(p);
}
return;
}
}
}
}
let mut p = processing.lock().unwrap();
p.remove(fullpath);
Expand Down
19 changes: 19 additions & 0 deletions backhand-test/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,3 +453,22 @@ fn test_few_dirs_many_files() {
only_read(&asset_defs, FILE_NAME, TEST_PATH, 0);
}
}

#[test]
#[cfg(any(feature = "gzip", feature = "gzip-zune-inflate"))]
fn test_socket_fifo() {
const FILE_NAME: &str = "squashfs_v4.specfile.bin";
let asset_defs = [TestAssetDef {
filename: FILE_NAME.to_string(),
hash: "d27f2e4baf57df961b9aa7298ac390a54fd0d2c904bf1d4baaee49cbdd0a93f1".to_string(),
url: format!("https://wcampbell.dev/squashfs/testing/test_socket_fifo/{FILE_NAME}"),
}];

const TEST_PATH: &str = "test-assets/socket_fifo";

if has_gzip_feature() {
full_test(&asset_defs, FILE_NAME, TEST_PATH, 0, Verify::Extract, true);
} else {
only_read(&asset_defs, FILE_NAME, TEST_PATH, 0);
}
}
62 changes: 60 additions & 2 deletions backhand/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use std::os::unix::prelude::OsStrExt;
use crate::data::Added;
use crate::dir::{Dir, DirEntry};
use crate::inode::{
BasicDeviceSpecialFile, BasicDirectory, BasicFile, BasicSymlink, ExtendedDirectory, Inode,
InodeHeader, InodeId, InodeInner,
BasicDeviceSpecialFile, BasicDirectory, BasicFile, BasicSymlink, ExtendedDirectory, IPCNode,
Inode, InodeHeader, InodeId, InodeInner,
};
use crate::kinds::Kind;
use crate::metadata::MetadataWriter;
Expand Down Expand Up @@ -235,6 +235,64 @@ impl<'a> Entry<'a> {

block_inode.to_bytes(node_path.as_bytes(), inode_writer, superblock, kind)
}

/// Write data and metadata for named pipe node
#[allow(clippy::too_many_arguments)]
pub fn named_pipe(
node_path: &'a OsStr,
header: NodeHeader,
inode: u32,
inode_writer: &mut MetadataWriter,
superblock: &SuperBlock,
kind: &Kind,
id_table: &[Id],
) -> Self {
let uid = id_table.iter().position(|a| a.num == header.uid).unwrap() as u16;
let gid = id_table.iter().position(|a| a.num == header.gid).unwrap() as u16;
let header = InodeHeader {
inode_number: inode,
uid,
gid,
permissions: header.permissions,
mtime: header.mtime,
};
let char_inode = Inode::new(
InodeId::BasicNamedPipe,
header,
InodeInner::BasicNamedPipe(IPCNode { link_count: 0x1 }),
);

char_inode.to_bytes(node_path.as_bytes(), inode_writer, superblock, kind)
}

/// Write data and metadata for socket
#[allow(clippy::too_many_arguments)]
pub fn socket(
node_path: &'a OsStr,
header: NodeHeader,
inode: u32,
inode_writer: &mut MetadataWriter,
superblock: &SuperBlock,
kind: &Kind,
id_table: &[Id],
) -> Self {
let uid = id_table.iter().position(|a| a.num == header.uid).unwrap() as u16;
let gid = id_table.iter().position(|a| a.num == header.gid).unwrap() as u16;
let header = InodeHeader {
inode_number: inode,
uid,
gid,
permissions: header.permissions,
mtime: header.mtime,
};
let char_inode = Inode::new(
InodeId::BasicSocket,
header,
InodeInner::BasicSocket(IPCNode { link_count: 0x1 }),
);

char_inode.to_bytes(node_path.as_bytes(), inode_writer, superblock, kind)
}
}

impl<'a> fmt::Debug for Entry<'a> {
Expand Down
2 changes: 2 additions & 0 deletions backhand/src/filesystem/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ pub enum InnerNode<T> {
Dir(SquashfsDir),
CharacterDevice(SquashfsCharacterDevice),
BlockDevice(SquashfsBlockDevice),
NamedPipe,
Socket,
}

/// Unread file for filesystem
Expand Down
2 changes: 2 additions & 0 deletions backhand/src/filesystem/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ use crate::{Node, Squashfs, SquashfsFileReader};
/// InnerNode::Dir(_) => (),
/// InnerNode::CharacterDevice(_) => (),
/// InnerNode::BlockDevice(_) => (),
/// InnerNode::NamedPipe => (),
/// InnerNode::Socket => (),
/// }
/// }
/// ```
Expand Down
24 changes: 24 additions & 0 deletions backhand/src/filesystem/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ impl<'a, 'b, 'c> FilesystemWriter<'a, 'b, 'c> {
InnerNode::Dir(x) => InnerNode::Dir(*x),
InnerNode::CharacterDevice(x) => InnerNode::CharacterDevice(*x),
InnerNode::BlockDevice(x) => InnerNode::BlockDevice(*x),
InnerNode::NamedPipe => InnerNode::NamedPipe,
InnerNode::Socket => InnerNode::Socket,
};
Node { fullpath: node.fullpath.clone(), header: node.header, inner }
})
Expand Down Expand Up @@ -531,6 +533,28 @@ impl<'a, 'b, 'c> FilesystemWriter<'a, 'b, 'c> {
id_table,
))
}
InnerNode::NamedPipe => {
return Ok(Entry::named_pipe(
filename,
node.header,
node_id.get().try_into().unwrap(),
inode_writer,
superblock,
kind,
id_table,
))
}
InnerNode::Socket => {
return Ok(Entry::socket(
filename,
node.header,
node_id.get().try_into().unwrap(),
inode_writer,
superblock,
kind,
id_table,
))
}
// if dir, fall through
InnerNode::Dir(_) => (),
};
Expand Down
14 changes: 14 additions & 0 deletions backhand/src/inode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ pub enum InodeId {
BasicSymlink = 3,
BasicBlockDevice = 4,
BasicCharacterDevice = 5,
BasicNamedPipe = 6, // aka FIFO
BasicSocket = 7,
ExtendedDirectory = 8,
ExtendedFile = 9,
// TODO:
Expand Down Expand Up @@ -114,6 +116,12 @@ pub enum InodeInner {
#[deku(id = "InodeId::BasicCharacterDevice")]
BasicCharacterDevice(BasicDeviceSpecialFile),

#[deku(id = "InodeId::BasicNamedPipe")]
BasicNamedPipe(IPCNode),

#[deku(id = "InodeId::BasicSocket")]
BasicSocket(IPCNode),

#[deku(id = "InodeId::ExtendedDirectory")]
ExtendedDirectory(ExtendedDirectory),

Expand Down Expand Up @@ -244,3 +252,9 @@ pub struct BasicDeviceSpecialFile {
pub link_count: u32,
pub device_number: u32,
}

#[derive(Debug, DekuRead, DekuWrite, Clone, PartialEq, Eq)]
#[deku(endian = "endian", ctx = "endian: deku::ctx::Endian")]
pub struct IPCNode {
pub link_count: u32,
}
2 changes: 2 additions & 0 deletions backhand/src/squashfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,8 @@ impl<'b> Squashfs<'b> {
let device_number = self.block_device(found_inode)?;
InnerNode::BlockDevice(SquashfsBlockDevice { device_number })
}
InodeId::BasicNamedPipe => InnerNode::NamedPipe,
InodeId::BasicSocket => InnerNode::Socket,
InodeId::ExtendedFile => {
return Err(BackhandError::UnsupportedInode(found_inode.inner.clone()))
}
Expand Down

0 comments on commit eaf8873

Please sign in to comment.