30 lines
842 B
Bash
30 lines
842 B
Bash
|
#!/usr/bin/env bash
|
||
|
set -eo pipefail
|
||
|
|
||
|
[ -t 0 ] && { echo "$0 must be run as a filter." >&2; exit 1; }
|
||
|
|
||
|
mfile="$1"; [ -z "$1" ] && { echo "No image file specified!" >&2; exit 1; }
|
||
|
|
||
|
BLOCKSIZE=`sed -nE 's/^#BLOCKSIZE=([0-9]+)$/\1/p' "$mfile"`
|
||
|
[ -z "$BLOCKSIZE" ] && { echo "Mapfile does not specify blocksize!" >&2; exit 1; }
|
||
|
|
||
|
map="$(grep -v ^\# "$mfile" \
|
||
|
| awk '/[a-f0-9]{64}/{curfile=$2;next}{print curfile, $0}' \
|
||
|
| sort -unk 3)"
|
||
|
nitems=`wc -l <<<"$map"`
|
||
|
|
||
|
shopt -s expand_aliases
|
||
|
alias dd="dd bs=$BLOCKSIZE status=none"
|
||
|
|
||
|
{
|
||
|
pos=0
|
||
|
for (( i = 0; i < $nitems; i++ )) do
|
||
|
read hash lblock block lengt _ < <(sed $((i+1))'q;d' <<<"$map")
|
||
|
dd if=/dev/stdin count=$((block-pos))
|
||
|
dd if=/dev/stdin count=$((lengt-1)) >/dev/null
|
||
|
dd if=pool/$hash count=$((lengt-1)) skip=$lblock
|
||
|
pos=$((block+lengt-1))
|
||
|
done
|
||
|
dd if=/dev/stdin
|
||
|
} > "${2:-/dev/stdout}"
|