Disk images as archive file formats
Latest update:
As a prank, how do you create an archive in Linux that ⓐ cannot be
opened in Windows (without WSL2 or Cygwin), ⓑ can be opened in MacOS
of FreeBSD?
Creating an .cpio or .tar.xz won't cut it: file archivers such as
7-Zip are free & easy to install. Furthermore, sending an ext4
image, generated as follows:
$ truncate -s 10M file.img
$ mkfs.ext4 file.img
$ sudo mount -o loop file.img /somewhere
$ sudo cp something /somewhere
$ sudo umount /somewhere
doesn't help nowadays, for 7-Zip opens them too. Although disk cloning utils like
FSArchiver can produce an image file from a directory, they are
exclusive to Linux.
It boils down to this: which filesystems can be read across
Linux/MacOS/FreeBSD that Windows file archivers don't recognise? This
rules out fat/ntfs/udf, for they are too common, or f2fs/nilfs2, for
they are Linux-only.
The only viable candidate I found is XFS. Btrfs was a contender, but
I'm unsure how to mount it on Mac.
Below is a script to automate the creation of prank archives. It takes
any zip/tar.gz (or anything else that bsdtar is able to parse) &
outputs an image file in the format specified by the output file
extension:
sudo ./mkimg file.zip file.xfs
It requires sudo, for mount -o loop
can't be done under a regular
user.
#!/bin/sh
set -e
input=$1
output=$2
type=${2##*.}
[ -r "$input" ] && [ "$output" ] && [ "`id -u`" = 0 ] || {
echo Usage: sudo mkimg file.zip file.ext2 1>&2
exit 1
}
mkfs=mkfs.$type
cmd() { for c; do command -v $c >/dev/null || { echo no $c; return 1; }; done; }
cmd bsdtar "$mkfs"
cleanup() {
set +e
umount "$mnt" 2>/dev/null
rm -rf "$mnt" "$log"
[ "$ok" ] || rm -f "$output"
}
trap cleanup 0 1 2 15
usize=`bsdtar tvf "$input" | awk '{s += $5} END {print s}'`
mnt=`mktemp -d`
log=`mktemp`
case "$type" in
msdos|*fat) size=$((1024*1024 + usize*2)); opt_tar=--no-same-owner ;;
ext*|udf ) size=$((1024*1024 + usize*2)) ;;
f2fs ) size=$((1024*1024*50 + usize*2)) ;;
btrfs ) size=$((114294784 + usize*2)) ;;
nilfs2 ) size=$((134221824 + usize*2)) ;;
xfs ) size=$((1024*1024*300 + usize*2)) ;;
jfs ) size=$((1024*1024*16 + usize*2)); opt=-q ;;
hfsplus )
size=$((1024*1024 + usize*2))
[ $((size % 4096)) != 0 ] && size=$((size + (4096-(size % 4096)))) ;;
*) echo "$type is untested" 1>&2; exit 1
esac
rm -f "$output"
truncate -s $size "$output"
$mkfs $opt "$output" > "$log" 2>&1 || { cat "$log"; exit 1; }
mount -o loop "$output" "$mnt"
bsdtar -C "$mnt" $opt_tar --chroot -xf "$input"
[ "$SUDO_UID" ] && chown "$SUDO_UID:$SUDO_GID" "$output"
ok=1
.xfs files start at a size of 300MB, even if you place a
0-length file in it, but bzip2 compresses such an image into 6270
bytes.
To mount an .xfs under a regular user, use
libfsxfs.
7z -i
prints all supported formats.
Tags: ойті
Authors: ag