#! /bin/bash # (c) 2023-2026 by Thomas Lange, lange@debian.org # # mk-data-partition ISO | # extend an ISO file by size and create a data partition # for USB stick the data partition will take the whole size of the USB stick set -o pipefail mntdir=/media/data die() { local e=$1 # first parameter is the exit code shift echo "$*" >&2 # print error message exit $e } add_p3() { # $1: filename or device name # $2: partition name local type [ -b "$2" ] && die 4 "Partition 3 already exists on $1" if [ X$fmt = Xexfat ]; then type=7 else type=83 fi # add 3th partion to the image or device { { echo -e "n\np\n3\n\n\n"; sleep 2; echo -e "v\nt\n3\n$type\nw\n" } | fdisk -w never "$1" } >/dev/null 2>&1 || die 3 "Cannot add 3rd partition to $1. Error code $?" udevadm settle --timeout=10 } add_p4() { # $1: filename or device name # $2: partition name local type [ -b "$2" ] && die 4 "Partition 4 already exists on $1" if [ X$fmt = Xexfat ]; then type=0700 else type=8300 fi # add 4th gpt partion to the image or device { echo -e "x\ne\nm\nn\n\n\n\n8300\nw\nY\n" | gdisk $1 } >/dev/null 2>&1 || die 3 "Cannot add 4th partition to $1. Error code $?" udevadm settle --timeout=10 } make_fs() { if [ -b "$1" ]; then if [ X$fmt = Xexfat ]; then mkfs.exfat -L MY-DATA $1 else mkfs.ext4 -q -L MY-DATA -J size=5 -E lazy_itable_init $1 fi echo "Data partition MY-DATA created" fi } mount_data() { mkdir $mntdir mount $1 $mntdir } umount_data() { umount $mntdir rmdir $mntdir } copy_data() { cp -a $* $mntdir echo "Copied files into the ISO." du --exclude=lost+found -sh $mntdir/* } usage() { cat </dev/null && die 5 "Size $size needs a unit like K, M, G, T" if [ -n "$1" ] && [ X$copy = X ]; then die 3 "If you want to copy directories, add -c" fi [ $(id -u) != "0" ] && die 2 "Run this program as root." if [ ! -b "$filename" ] && [ ! -f "$filename" ]; then die 9 "$filename is neither a device nor an existing file" fi type=$(fdisk -l $filename 2>/dev/null| grep -Po '(?<=Disklabel type:\s)...' ) case $type in dos) p=3 fname=add_p3 ;; gpt) p=4 fname=add_p4 ;; esac if [ -b "$filename" ]; then # file is a USB device if [ -n "$size" ]; then echo "Warning: Ignoring the size parameter for USB sticks." fi part=${filename}$p $fname $filename $part make_fs $part fi if [ -f "$filename" ]; then # check if the image already has a 3th partition set +e fdisk -l $filename | egrep -q ^${filename}$p && die 5 "Partition $p already exists on $filename" size=${size:-300M} echo "Extend $filename by $size" truncate -s +$size $filename || die 9 "Cannot extend $filename. Aborting" if ! loop=$(losetup -P -f --show $filename); then die 5 "Cannot create loop device" fi trap "losetup -d $loop" EXIT part=${loop}p$p $fname $loop $part make_fs $part fi if [ X$copy = X1 ]; then mount_data $part copy_data $* umount_data $part fi