Czsplit
Скрипт czsplit для разбора составных initrd:
#!/bin/bash -ef
# Copyright (C) 2007 Andrew V. Stepanov <stanv@altlinux.org>
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
chunks=(0) # Holds start of cpio archives
filename=
E_GENERAL=1
show_usage()
{
echo "Join multi cpio archive to files file[N].cpio"
echo "Usage: $0 file.cpio"
exit 0
}
scan_file()
{
offset=
word=
byte=
off=()
magic_word="TRAILER!!!"
magic_word_hex="$(echo -n "$magic_word" | xxd -p)"
magic_len=${#magic_word} # 10 bytes
part=1
off=($(grep -ba "$magic_word" "$filename" | cut -f 1 -d ':'))
if [ "${#off[@]}" = "0" ]; then
echo "No cpio archives found in $filename, does it cpio archive?"
return $E_GENERAL
fi
offset=${off[0]}
while true; do
word="$(dd if="$filename" bs=1 count=10 skip="$offset" 2>/dev/null | xxd -p)"
[ -z "$word" ] && break
if [ "$word" = "$magic_word_hex" ]; then # take out of zeros.....
offset=$((offset+magic_len))
while true; do
byte="$(dd if="$filename" bs=1 count=1 skip="$offset" 2>/dev/null | xxd -p)"
[ "$byte" != "00" ] && break
offset=$((offset+1))
done
chunks=(${chunks[@]} $offset) # offset where start next cpio archive
[ "$part" -ge "${#off[@]}" ] && break
offset=${off[$part]} # go to next magic_word
part=$((part+1))
continue
fi
offset=$((offset+1))
done
}
write_chunks()
{
part_name=
offset=
size=
i=
for i in $(seq 0 $((${#chunks[@]}-2))); do
offset=${chunks[$i]}
size=$((${chunks[$((i+1))]}-${chunks[$i]}))
part_name="$(basename "$filename")"
part_name="${part_name%.*}"
part_name="${part_name}${i}.cpio"
echo "Write: $part_name (start: $offset, size: $size)"
size=$((size/512))
offset=$((offset/512))
dd if="$filename" of="$part_name" skip="$offset" bs=512 count="$size" 2>/dev/null
done
return 0
}
# Program start from here
[ "$#" -ne 1 ] && show_usage
filename="$1"
if ! [ -f "$filename" ]; then
echo "Can't open $filename file"
show_usage
fi
scan_file || exit 0
echo "Found $((${#chunks[@]}-1)) archives in $filename, write them:"
write_chunks