Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package backhand for openSUSE:Factory checked in at 2026-09-24 22:59:35 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/backhand (Old) and /work/SRC/openSUSE:Factory/.backhand.new.383539 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "backhand" Thu Sep 24 22:59:35 2026 rev:9 rq:1380130 version:0.25.4 Changes: -------- --- /work/SRC/openSUSE:Factory/backhand/backhand.changes 2026-09-07 11:35:07.911191050 +0200 +++ /work/SRC/openSUSE:Factory/.backhand.new.383539/backhand.changes 2026-09-24 23:01:44.141957034 +0200 @@ -1,0 +2,6 @@ +Wed Sep 23 15:24:28 UTC 2026 - Martin Hauke <[email protected]> + +- Update to version 0.25.4: + * Add basic support for extended inodes. + +------------------------------------------------------------------- Old: ---- backhand-0.25.3.obscpio New: ---- backhand-0.25.4.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ backhand.spec ++++++ --- /var/tmp/diff_new_pack.YqY6Nl/_old 2026-09-24 23:01:50.442220472 +0200 +++ /var/tmp/diff_new_pack.YqY6Nl/_new 2026-09-24 23:01:50.443220513 +0200 @@ -18,7 +18,7 @@ Name: backhand -Version: 0.25.3 +Version: 0.25.4 Release: 0 Summary: Tools for the reading, creating, and modification of SquashFS file systems License: Apache-2.0 OR MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.YqY6Nl/_old 2026-09-24 23:01:50.475221852 +0200 +++ /var/tmp/diff_new_pack.YqY6Nl/_new 2026-09-24 23:01:50.478221977 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/wcampbell0x2a/backhand</param> <param name="versionformat">@PARENT_TAG@</param> <param name="scm">git</param> - <param name="revision">v0.25.3</param> + <param name="revision">v0.25.4</param> <param name="versionrewrite-pattern">v(\d+\.\d+\.\d+)</param> <param name="changesgenerate">enable</param> </service> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.YqY6Nl/_old 2026-09-24 23:01:50.496222730 +0200 +++ /var/tmp/diff_new_pack.YqY6Nl/_new 2026-09-24 23:01:50.499222855 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/wcampbell0x2a/backhand</param> - <param name="changesrevision">eccf81b6f599cb90245d7c9694e95ee6023cad06</param></service></servicedata> + <param name="changesrevision">c9be3e619b57c1c9fda83d081f3dbbf4bf436059</param></service></servicedata> (No newline at EOF) ++++++ backhand-0.25.3.obscpio -> backhand-0.25.4.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/backhand-0.25.3/CHANGELOG.md new/backhand-0.25.4/CHANGELOG.md --- old/backhand-0.25.3/CHANGELOG.md 2026-09-07 00:13:00.000000000 +0200 +++ new/backhand-0.25.4/CHANGELOG.md 2026-09-23 05:03:16.000000000 +0200 @@ -7,6 +7,13 @@ ## [Unreleased] +## [0.25.4](https://github.com/wcampbell0x2a/backhand/compare/v0.25.3...v0.25.4) - 2026-09-23 + +### Other + +- Add basic support for extended inodes +- Avoid allocating in BasicSymlink's Debug impl + ## [0.25.3](https://github.com/wcampbell0x2a/backhand/compare/v0.25.2...v0.25.3) - 2026-09-06 ### `backhand` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/backhand-0.25.3/Cargo.lock new/backhand-0.25.4/Cargo.lock --- old/backhand-0.25.3/Cargo.lock 2026-09-07 00:13:00.000000000 +0200 +++ new/backhand-0.25.4/Cargo.lock 2026-09-23 05:03:16.000000000 +0200 @@ -106,7 +106,7 @@ [[package]] name = "backhand" -version = "0.25.3" +version = "0.25.4" dependencies = [ "assert_cmd", "criterion", @@ -138,7 +138,7 @@ [[package]] name = "backhand-cli" -version = "0.25.3" +version = "0.25.4" dependencies = [ "backhand", "clap", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/backhand-0.25.3/Cargo.toml new/backhand-0.25.4/Cargo.toml --- old/backhand-0.25.3/Cargo.toml 2026-09-07 00:13:00.000000000 +0200 +++ new/backhand-0.25.4/Cargo.toml 2026-09-23 05:03:16.000000000 +0200 @@ -9,7 +9,7 @@ resolver = "2" [workspace.package] -version = "0.25.3" +version = "0.25.4" authors = ["wcampbell <[email protected]>"] license = "MIT OR Apache-2.0" edition = "2024" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/backhand-0.25.3/backhand/src/v4/inode.rs new/backhand-0.25.4/backhand/src/v4/inode.rs --- old/backhand-0.25.3/backhand/src/v4/inode.rs 2026-09-07 00:13:00.000000000 +0200 +++ new/backhand-0.25.4/backhand/src/v4/inode.rs 2026-09-23 05:03:16.000000000 +0200 @@ -69,21 +69,20 @@ #[repr(u16)] #[rustfmt::skip] pub enum InodeId { - BasicDirectory = 1, - BasicFile = 2, - BasicSymlink = 3, - BasicBlockDevice = 4, - BasicCharacterDevice = 5, - BasicNamedPipe = 6, // aka FIFO - BasicSocket = 7, - ExtendedDirectory = 8, - ExtendedFile = 9, - // TODO: - // Extended Symlink = 10 - // Extended Block Device = 11 - // Extended Character Device = 12 - // Extended Named Pipe (FIFO) = 13 - // Extended Socked = 14 + BasicDirectory = 1, + BasicFile = 2, + BasicSymlink = 3, + BasicBlockDevice = 4, + BasicCharacterDevice = 5, + BasicNamedPipe = 6, // aka FIFO + BasicSocket = 7, + ExtendedDirectory = 8, + ExtendedFile = 9, + ExtendedSymlink = 10, + ExtendedBlockDevice = 11, + ExtendedCharacterDevice = 12, + ExtendedNamedPipe = 13, + ExtendedSocket = 14, } impl InodeId { @@ -91,6 +90,11 @@ match self { Self::ExtendedDirectory => InodeId::BasicDirectory, Self::ExtendedFile => InodeId::BasicFile, + Self::ExtendedSymlink => InodeId::BasicSymlink, + Self::ExtendedBlockDevice => InodeId::BasicBlockDevice, + Self::ExtendedCharacterDevice => InodeId::BasicCharacterDevice, + Self::ExtendedNamedPipe => InodeId::BasicNamedPipe, + Self::ExtendedSocket => InodeId::BasicSocket, _ => self, } } @@ -129,6 +133,21 @@ #[deku(id = "InodeId::ExtendedFile")] ExtendedFile(#[deku(ctx = "bytes_used, block_size, block_log")] ExtendedFile), + + #[deku(id = "InodeId::ExtendedSymlink")] + ExtendedSymlink(ExtendedSymlink), + + #[deku(id = "InodeId::ExtendedBlockDevice")] + ExtendedBlockDevice(ExtendedDeviceSpecialFile), + + #[deku(id = "InodeId::ExtendedCharacterDevice")] + ExtendedCharacterDevice(ExtendedDeviceSpecialFile), + + #[deku(id = "InodeId::ExtendedNamedPipe")] + ExtendedNamedPipe(ExtendedIPCNode), + + #[deku(id = "InodeId::ExtendedSocket")] + ExtendedSocket(ExtendedIPCNode), } #[derive(Debug, DekuRead, DekuWrite, DekuSize, Clone, Copy, PartialEq, Eq, Default)] @@ -225,13 +244,17 @@ f.debug_struct("BasicSymlink") .field("link_count", &self.link_count) .field("target_size", &self.target_size) - .field("target_path", &self.target()) + .field("target_path", &self.target_ref()) .finish() } } impl BasicSymlink { + fn target_ref(&self) -> &str { + core::str::from_utf8(&self.target_path).unwrap() + } + pub fn target(&self) -> String { - core::str::from_utf8(&self.target_path).unwrap().to_string() + self.target_ref().to_owned() } } @@ -247,3 +270,58 @@ pub struct IPCNode { pub link_count: u32, } + +/// `SQUASHFS_LSYMLINK_TYPE` (10). +/// +/// Same layout as [`BasicSymlink`], with a trailing xattr index. +#[derive(DekuRead, DekuWrite, Clone, PartialEq, Eq)] +#[deku(endian = "endian", ctx = "endian: deku::ctx::Endian")] +pub struct ExtendedSymlink { + pub link_count: u32, + #[deku(assert = "*target_size < 256")] + pub target_size: u32, + #[deku(count = "target_size")] + pub target_path: Vec<u8>, + pub xattr_index: u32, +} + +impl fmt::Debug for ExtendedSymlink { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ExtendedSymlink") + .field("link_count", &self.link_count) + .field("target_size", &self.target_size) + .field("target_path", &self.target_ref()) + .field("xattr_index", &self.xattr_index) + .finish() + } +} +impl ExtendedSymlink { + fn target_ref(&self) -> &str { + core::str::from_utf8(&self.target_path).unwrap() + } + + pub fn target(&self) -> String { + self.target_ref().to_owned() + } +} + +/// `SQUASHFS_LBLKDEV_TYPE` (11) / `SQUASHFS_LCHRDEV_TYPE` (12). +/// +/// Same layout as [`BasicDeviceSpecialFile`], with a trailing xattr index. +#[derive(Debug, DekuRead, DekuWrite, Clone, PartialEq, Eq)] +#[deku(endian = "endian", ctx = "endian: deku::ctx::Endian")] +pub struct ExtendedDeviceSpecialFile { + pub link_count: u32, + pub device_number: u32, + pub xattr_index: u32, +} + +/// `SQUASHFS_LFIFO_TYPE` (13) / `SQUASHFS_LSOCKET_TYPE` (14). +/// +/// Same layout as [`IPCNode`], with a trailing xattr index. +#[derive(Debug, DekuRead, DekuWrite, Clone, PartialEq, Eq)] +#[deku(endian = "endian", ctx = "endian: deku::ctx::Endian")] +pub struct ExtendedIPCNode { + pub link_count: u32, + pub xattr_index: u32, +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/backhand-0.25.3/backhand/src/v4/squashfs.rs new/backhand-0.25.4/backhand/src/v4/squashfs.rs --- old/backhand-0.25.3/backhand/src/v4/squashfs.rs 2026-09-07 00:13:00.000000000 +0200 +++ new/backhand-0.25.4/backhand/src/v4/squashfs.rs 2026-09-23 05:03:16.000000000 +0200 @@ -549,8 +549,8 @@ )?; InnerNode::Dir(SquashfsDir::default()) } - // BasicFile - InodeId::BasicFile => { + // Basic or Extended File + InodeId::BasicFile | InodeId::ExtendedFile => { let inner = match &found_inode.inner { InodeInner::BasicFile(file) => { SquashfsFileReader::Basic(file.clone()) @@ -562,24 +562,25 @@ }; InnerNode::File(inner) } - // Basic Symlink - InodeId::BasicSymlink => { + // Basic or Extended Symlink + InodeId::BasicSymlink | InodeId::ExtendedSymlink => { let link = self.symlink_target_path(found_inode)?; InnerNode::Symlink(SquashfsSymlink { link }) } - // Basic CharacterDevice - InodeId::BasicCharacterDevice => { + // Basic or Extended CharacterDevice + InodeId::BasicCharacterDevice | InodeId::ExtendedCharacterDevice => { let device_number = Self::char_device_number(found_inode)?; InnerNode::CharacterDevice(SquashfsCharacterDevice { device_number }) } - // Basic CharacterDevice - InodeId::BasicBlockDevice => { + // Basic or Extended BlockDevice + InodeId::BasicBlockDevice | InodeId::ExtendedBlockDevice => { let device_number = Self::block_device_number(found_inode)?; InnerNode::BlockDevice(SquashfsBlockDevice { device_number }) } - InodeId::BasicNamedPipe => InnerNode::NamedPipe, - InodeId::BasicSocket => InnerNode::Socket, - InodeId::ExtendedFile => return Err(BackhandError::UnsupportedInode), + InodeId::BasicNamedPipe | InodeId::ExtendedNamedPipe => { + InnerNode::NamedPipe + } + InodeId::BasicSocket | InodeId::ExtendedSocket => InnerNode::Socket, }; let node = Node::new( fullpath.clone(), @@ -600,8 +601,13 @@ /// # Returns /// `Ok(target_path)` fn symlink_target_path(&self, inode: &Inode) -> Result<PathBuf, BackhandError> { - if let InodeInner::BasicSymlink(basic_sym) = &inode.inner { - let path = OsString::from_vec(basic_sym.target_path.clone()); + let target_path = match &inode.inner { + InodeInner::BasicSymlink(basic_sym) => Some(&basic_sym.target_path), + InodeInner::ExtendedSymlink(ext_sym) => Some(&ext_sym.target_path), + _ => None, + }; + if let Some(target_path) = target_path { + let path = OsString::from_vec(target_path.to_vec()); return Ok(PathBuf::from(path)); } @@ -614,8 +620,10 @@ /// # Returns /// `Ok(dev_num)` fn char_device_number(inode: &Inode) -> Result<u32, BackhandError> { - if let InodeInner::BasicCharacterDevice(spc_file) = &inode.inner { - return Ok(spc_file.device_number); + match &inode.inner { + InodeInner::BasicCharacterDevice(spc_file) => return Ok(spc_file.device_number), + InodeInner::ExtendedCharacterDevice(spc_file) => return Ok(spc_file.device_number), + _ => {} } error!("char dev not found"); @@ -627,8 +635,10 @@ /// # Returns /// `Ok(dev_num)` fn block_device_number(inode: &Inode) -> Result<u32, BackhandError> { - if let InodeInner::BasicBlockDevice(spc_file) = &inode.inner { - return Ok(spc_file.device_number); + match &inode.inner { + InodeInner::BasicBlockDevice(spc_file) => return Ok(spc_file.device_number), + InodeInner::ExtendedBlockDevice(spc_file) => return Ok(spc_file.device_number), + _ => {} } error!("block dev not found"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/backhand-0.25.3/backhand-cli/Cargo.toml new/backhand-0.25.4/backhand-cli/Cargo.toml --- old/backhand-0.25.3/backhand-cli/Cargo.toml 2026-09-07 00:13:00.000000000 +0200 +++ new/backhand-0.25.4/backhand-cli/Cargo.toml 2026-09-23 05:03:16.000000000 +0200 @@ -19,7 +19,7 @@ indicatif = "0.18.6" console = "0.16.4" rayon = "1.12.0" -backhand = { path = "../backhand", default-features = false, version = "0.25.3" } +backhand = { path = "../backhand", default-features = false, version = "0.25.4" } tracing = "0.1.40" color-print = "0.3.6" clap-cargo = "0.19.0" ++++++ backhand.obsinfo ++++++ --- /var/tmp/diff_new_pack.YqY6Nl/_old 2026-09-24 23:01:50.661229629 +0200 +++ /var/tmp/diff_new_pack.YqY6Nl/_new 2026-09-24 23:01:50.664229755 +0200 @@ -1,5 +1,5 @@ name: backhand -version: 0.25.3 -mtime: 1788732780 -commit: eccf81b6f599cb90245d7c9694e95ee6023cad06 +version: 0.25.4 +mtime: 1790132596 +commit: c9be3e619b57c1c9fda83d081f3dbbf4bf436059 ++++++ vendor.tar.zst ++++++ /work/SRC/openSUSE:Factory/backhand/vendor.tar.zst /work/SRC/openSUSE:Factory/.backhand.new.383539/vendor.tar.zst differ: char 7, line 1
