summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--modules/dev.inc65
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