use opticaldiscs::efs::{EFS_DIRBLK_MAGIC, EFS_MAGIC_OLD};
use opticaldiscs::sgi::{SgiPartitionType, SGI_NUM_PARTITIONS, SGI_VOLHDR_MAGIC, SGI_VOLHDR_SIZE};
pub const EFS_PART_FIRST_512: u32 = 64;
pub fn build_synth_irix_disc() -> Vec<u8> {
const N_BLOCKS_512: usize = 384; let mut img = vec![0u8; N_BLOCKS_512 * 512];
img[0..4].copy_from_slice(&SGI_VOLHDR_MAGIC.to_be_bytes());
img[4..6].copy_from_slice(&0u16.to_be_bytes()); img[6..8].copy_from_slice(&1u16.to_be_bytes()); img[8..14].copy_from_slice(b"/unix\0");
let mut parts = [(0u32, 0u32, 0u32); SGI_NUM_PARTITIONS];
parts[7] = (
(N_BLOCKS_512 as u32) - EFS_PART_FIRST_512,
EFS_PART_FIRST_512,
SgiPartitionType::SysV.as_u32(),
);
parts[8] = (EFS_PART_FIRST_512, 0, SgiPartitionType::VolHdr.as_u32());
parts[10] = (N_BLOCKS_512 as u32, 0, SgiPartitionType::Volume.as_u32());
for (i, (blocks, first, ptype)) in parts.iter().enumerate() {
let off = 0x138 + i * 12;
img[off..off + 4].copy_from_slice(&blocks.to_be_bytes());
img[off + 4..off + 8].copy_from_slice(&first.to_be_bytes());
img[off + 8..off + 12].copy_from_slice(&ptype.to_be_bytes());
}
{
let mut sum: u32 = 0;
for chunk in img[..SGI_VOLHDR_SIZE].chunks_exact(4) {
sum = sum.wrapping_add(u32::from_be_bytes(chunk.try_into().unwrap()));
}
let cksum = 0u32.wrapping_sub(sum);
img[0x1F8..0x1FC].copy_from_slice(&cksum.to_be_bytes());
}
let part_byte = EFS_PART_FIRST_512 as usize * 512;
let block = |b: usize| part_byte + b * 512;
let sb = block(1);
let part_blocks = (N_BLOCKS_512 - EFS_PART_FIRST_512 as usize) as u32;
img[sb..sb + 4].copy_from_slice(&part_blocks.to_be_bytes()); img[sb + 4..sb + 8].copy_from_slice(&18u32.to_be_bytes()); img[sb + 8..sb + 12].copy_from_slice(&(part_blocks - 18).to_be_bytes()); img[sb + 12..sb + 14].copy_from_slice(&2u16.to_be_bytes()); img[sb + 14..sb + 16].copy_from_slice(&63u16.to_be_bytes()); img[sb + 16..sb + 18].copy_from_slice(&1u16.to_be_bytes()); img[sb + 18..sb + 20].copy_from_slice(&1u16.to_be_bytes()); img[sb + 28..sb + 32].copy_from_slice(&EFS_MAGIC_OLD.to_be_bytes()); img[sb + 32..sb + 38].copy_from_slice(b"synth\0");
img[sb + 38..sb + 44].copy_from_slice(b"pack\0\0");
let ino_off = |inum: u32| -> usize {
let b = 18u32 + inum / 4;
block(b as usize) + ((inum % 4) as usize) * 128
};
let off = ino_off(2);
img[off..off + 2].copy_from_slice(&0o040755u16.to_be_bytes());
img[off + 8..off + 12].copy_from_slice(&512u32.to_be_bytes());
img[off + 28..off + 30].copy_from_slice(&1u16.to_be_bytes());
img[off + 32..off + 36].copy_from_slice(&20u32.to_be_bytes());
img[off + 36..off + 40].copy_from_slice(&(1u32 << 24).to_be_bytes());
let off = ino_off(4);
img[off..off + 2].copy_from_slice(&0o100644u16.to_be_bytes());
img[off + 8..off + 12].copy_from_slice(&512u32.to_be_bytes());
img[off + 28..off + 30].copy_from_slice(&1u16.to_be_bytes());
img[off + 32..off + 36].copy_from_slice(&21u32.to_be_bytes());
img[off + 36..off + 40].copy_from_slice(&(1u32 << 24).to_be_bytes());
let target = b"/usr/sbin/init";
let off = ino_off(5);
img[off..off + 2].copy_from_slice(&0o120777u16.to_be_bytes());
img[off + 8..off + 12].copy_from_slice(&(target.len() as u32).to_be_bytes());
img[off + 28..off + 30].copy_from_slice(&1u16.to_be_bytes());
img[off + 32..off + 36].copy_from_slice(&22u32.to_be_bytes());
img[off + 36..off + 40].copy_from_slice(&(1u32 << 24).to_be_bytes());
let off = ino_off(6);
img[off..off + 2].copy_from_slice(&0o040755u16.to_be_bytes());
img[off + 8..off + 12].copy_from_slice(&512u32.to_be_bytes());
img[off + 28..off + 30].copy_from_slice(&1u16.to_be_bytes());
img[off + 32..off + 36].copy_from_slice(&23u32.to_be_bytes());
img[off + 36..off + 40].copy_from_slice(&(1u32 << 24).to_be_bytes());
let off = ino_off(7);
img[off..off + 2].copy_from_slice(&0o100644u16.to_be_bytes());
img[off + 8..off + 12].copy_from_slice(&512u32.to_be_bytes());
img[off + 28..off + 30].copy_from_slice(&1u16.to_be_bytes());
img[off + 32..off + 36].copy_from_slice(&24u32.to_be_bytes());
img[off + 36..off + 40].copy_from_slice(&(1u32 << 24).to_be_bytes());
let d = block(20);
img[d..d + 2].copy_from_slice(&EFS_DIRBLK_MAGIC.to_be_bytes());
img[d + 3] = 3;
img[d + 4] = 0xFA;
let de = d + 500;
img[de..de + 4].copy_from_slice(&4u32.to_be_bytes());
img[de + 4] = 4;
img[de + 5..de + 9].copy_from_slice(b"data");
img[d + 5] = 0xF5;
let de = d + 490;
img[de..de + 4].copy_from_slice(&5u32.to_be_bytes());
img[de + 4] = 4;
img[de + 5..de + 9].copy_from_slice(b"link");
img[d + 6] = 0xF0;
let de = d + 480;
img[de..de + 4].copy_from_slice(&6u32.to_be_bytes());
img[de + 4] = 3;
img[de + 5..de + 8].copy_from_slice(b"sub");
let d = block(23);
img[d..d + 2].copy_from_slice(&EFS_DIRBLK_MAGIC.to_be_bytes());
img[d + 3] = 1;
img[d + 4] = 0xFA;
let de = d + 500;
img[de..de + 4].copy_from_slice(&7u32.to_be_bytes());
img[de + 4] = 6;
img[de + 5..de + 11].copy_from_slice(b"nested");
let b21 = block(21);
img[b21..b21 + 512].fill(0xAA);
let b22 = block(22);
img[b22..b22 + target.len()].copy_from_slice(target);
let b24 = block(24);
img[b24..b24 + 512].fill(0xBB);
img
}