diff options
-rw-r--r-- | modules/dev.inc | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/modules/dev.inc b/modules/dev.inc index f213fa0..1c804a3 100644 --- a/modules/dev.inc +++ b/modules/dev.inc @@ -41,6 +41,7 @@ dev_find_partitions() { local label number mbrid uuid for dev in $(find $target* -type b); do dev_get_type "$dev" || continue + echo "$dev is $number - MBR=$mbrid, UUID=$uuid, label=$label" >&2 if regex_imatch "$mbrid" "^($want_type)$" || regex_imatch "$uuid" "^($want_uuid)$" \ || regex_match "$label" "^($want_label)$"; then printf "%s\n" "$(blockdev --getsize64 "$dev") $dev" @@ -74,11 +75,12 @@ dev_get_type() { label="$( grep -Po '(?<=^PARTNAME=).*$' "/sys/block/${devn}/${partn}/uevent" )" number="$( grep -Po '(?<=^PARTN=).*$' "/sys/block/${devn}/${partn}/uevent" )" local gpt= - if [ "$( dd if="$dev" bs=1 count=8 skip=512 2> /dev/null )" = "EFI PART" ]; then + if [ "$( dd if="$dev" bs=1 count=8 skip=512 2> /dev/null )" = "EFI PART" ] 2> /dev/null; then gpt=512 - elif [ "$( dd if="$dev" bs=1 count=8 skip=4096 2> /dev/null )" = "EFI PART" ]; then + elif [ "$( dd if="$dev" bs=1 count=8 skip=4096 2> /dev/null )" = "EFI PART" ] 2> /dev/null; then gpt=4096 fi + echo "Checking $partn (on $dev) GPT='$gpt', label='$label'" >&2 # Check if mbr signatur is there, no GPT label was in uevent, and no protective MBR local t1="$( __read_mbrid "$dev" 0 1 )" if [ -z "$label" ] && [ "$number" -lt 1000 ] && [ "$number" -gt 0 ] \ @@ -157,17 +159,24 @@ dev_get_type() { fi # Convert raw hex stream to proper string representation. First 3 groups are little endian. uuid="$( dd if="$dev" bs=1 count=16 skip="$(( current + entry_size * (number - 1) ))" 2> /dev/null \ - | xxd -p | sed -r 's/^(..)(..)(..)(..)(..)(..)(..)(..)(....)/\4\3\2\1-\6\5-\8\7-\9-/' )" + | __bin2hex | sed -r 's/^(..)(..)(..)(..)(..)(..)(..)(..)(....)/\4\3\2\1-\6\5-\8\7-\9-/' )" return 0 fi # Unknown return 1 } +# stdin = binary data, stdout = raw, unformatted hex +# __hex2bin() + +# stdin = binary data, stdout = raw, unformatted hex +# $1 = number of bytes to read and reverse (1, 2, 4, 8) +# __hex2bin_le() + # Get MBR type of partition (1 byte) as hex # Pass "$device" "$lba_offset" "$partition_number" __read_mbrid() { - dd if="$1" bs=1 skip=$(( 512 * $2 + 446 + ($3 - 1) * 16 + 4 )) count=1 2> /dev/null | xxd -p + dd if="$1" bs=1 skip=$(( 512 * $2 + 446 + ($3 - 1) * 16 + 4 )) count=1 2> /dev/null | __bin2hex } # Get LBA start address of MBR partition @@ -179,12 +188,56 @@ __read_mbrstart() { # Read the MBR signature in the given sector # Pass "$device" "$lba_offset" __read_mbrsig() { - dd if="$1" bs=1 skip=$(( 512 * $2 + 510 )) count=2 2> /dev/null | xxd -p + dd if="$1" bs=1 skip=$(( 512 * $2 + 510 )) count=2 2> /dev/null | __bin2hex } # Read a little endian value at given byte offset # Pass "$source_path" "$byte_offset" "$size" __read_le() { - local v="$( dd if="$1" bs=1 count="$3" skip="$2" 2> /dev/null | xxd -e -g "$3" | cut -d' ' -f2 )" + local v="$( dd if="$1" bs=1 count="$3" skip="$2" 2> /dev/null | __bin2hex_le "$3" )" echo $(( 0x$v )) } + +__init() { + local t + # init __hex2bin + t="7a32337465737431323374657374" + if [ "$( printf z23test123test | xxd -p )" = "$t" ]; then + #echo "Using xxd" >&2 + __bin2hex() { xxd -p; } + elif [ "$( printf z23test123test | od -t x1 -An | tr -d '\n ' )" = "$t" ]; then + #echo "Using od" >&2 + __bin2hex() { od -t x1 -An | tr -d '\n '; } + elif [ "$( printf z23test123test | hexdump -ve '/1 "%02x"' )" = "$t" ]; then + #echo "Using hexdump" >&2 + __bin2hex() { hexdump -ve '/1 "%02x"'; } + else + echo "No suitable tool for converting binary to hex" >&2 + exit 1 + fi + # init __hex2bin_le + t="383736353433327a" + if [ "$( printf z2345678 | xxd -e -g 8 | cut -d' ' -f2 )" = "$t" ]; then + #echo "Using xxd" >&2 + __bin2hex_le() { xxd -e -g "$1" | cut -d' ' -f2; } + elif [ "$( printf z2345678 | od -t x8 -An | tr -d '\n ' )" = "$t" ]; then + #echo "Using od" >&2 + __bin2hex_le() { od -t "x$1" -An | tr -d '\n '; } + elif [ "$( printf z2345678 | hexdump -ve '/4 "%02x"' \ + | sed 's/\(........\)\(........\)/\2\1/' )" = "$t" ]; then + #echo "Using hexdump" >&2 + __bin2hex_le() { + if [ "$1" -lt 8 ]; then + hexdump -ve "/$1"' "%02x"' + else + hexdump -ve '/4 "%02x"' | sed 's/\(........\)\(........\)/\2\1/' + fi + } + else + echo "No suitable tool for converting binary data to little endian hex" >&2 + exit 1 + fi + unset -f __init +} + +__init |