-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathextract_new_qdk.sh
124 lines (107 loc) · 4.13 KB
/
extract_new_qdk.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/bin/bash
SIGN_CERT=sign.crt
SIGN_KEY=sign.key
PREFIX=qpkg_workspace
EXTRACT_PATH=qpkg_content
len_to_binary() {
len=$1
byte4="\\`printf 'x%02x' $((len%256))`"
len=$((len/256))
byte3="\\`printf 'x%02x' $((len%256))`"
len=$((len/256))
byte2="\\`printf 'x%02x' $((len%256))`"
len=$((len/256))
byte1="\\`printf 'x%02x' $((len%256))`"
printf "$byte1$byte2$byte3$byte4"
}
get_offset() {
offsets="$(/bin/sed -n '1,/^exit 1/{
s/^script_len=\([0-9]*\).*$/\1/p
s/^offset.*script_len[^0-9]*\([0-9]*\).*$/\1/p
s/^offset.*offset[^0-9]*\([0-9]*\).*$/\1/p
/^exit 1/q
}' "${QPKG}")"
script_len=`echo $offsets|cut -f 1 -d " "`
raw_offset1=`echo $offsets|cut -f 2 -d " "`
raw_offset2=`echo $offsets|cut -f 3 -d " "`
offset1=$((script_len+raw_offset1))
offset2=$((offset1+raw_offset2))
}
extract_qdk() {
mkdir -p $PREFIX/$EXTRACT_PATH
get_offset
echo $script_len $raw_offset1 $raw_offset2 $offset1 $offset2
echo $(((raw_offset2+1024)/1024))
dd if=$QPKG bs=$script_len count=1 > $PREFIX/head
if grep data.tar.7z $PREFIX/head >/dev/null; then
is7z=1
fi
dd if=$QPKG bs=$script_len skip=1 |/bin/tar -xO | /bin/tar -xzv -C $PREFIX/$EXTRACT_PATH
dd if=$QPKG bs=$offset1 skip=1 | /bin/cat | /bin/dd bs=1024 of=$PREFIX/$EXTRACT_PATH/data.tar.gz
busybox truncate -s $raw_offset2 $PREFIX/$EXTRACT_PATH/data.tar.gz
mkdir $PREFIX/$EXTRACT_PATH/data
if [ "$is7z" == "1" ]; then
mv $PREFIX/$EXTRACT_PATH/data.tar.gz $PREFIX/$EXTRACT_PATH/data.tar.7z
7z x -so $PREFIX/$EXTRACT_PATH/data.tar.7z | tar x -C $PREFIX/$EXTRACT_PATH/data
else
tar xf $PREFIX/$EXTRACT_PATH/data.tar.gz -C $PREFIX/$EXTRACT_PATH/data
fi
tail -c 100 $QPKG> $PREFIX/tail
}
pack_qdk() {
# control.tar.gz
tar czf $PREFIX/control.tar.gz -C $PREFIX/$EXTRACT_PATH built_info package_routines qinstall.sh qpkg.cfg
tar cf $PREFIX/control.tar -C $PREFIX control.tar.gz
new_offset1=`stat -c "%s" $PREFIX/control.tar`
new_offset2=`stat -c "%s" $PREFIX/$EXTRACT_PATH/data.tar.gz`
# update control.tar offset
sed -i "s/^\(.*script_len \+ \)$raw_offset1\(.*\)\$/\1$new_offset1\2/g" $PREFIX/head
# update data.tar.gz offset
# assume the longest number will not expect confict.
sed -i "s/^\(.*\)$raw_offset2\(.*\)\$/\1$new_offset2\2/g" $PREFIX/head
# update /bin/dd bs=1024 count=
bcount=$(((new_offset2+1024)/1024))
sed -i "s/^\(.*bs=1024 count=\)[0-9]*\(.*\)\$/\1$bcount\2/g" $PREFIX/head
# update script_len
script_len=`stat -c "%s" $PREFIX/head`
sed -i "s/^script_len=.*\$/script_len=$script_len/g" $PREFIX/head
# assemble
cat $PREFIX/head $PREFIX/control.tar $PREFIX/$EXTRACT_PATH/data.tar.gz > $PREFIX/qpkg.bin
# sign
openssl sha1 -binary $PREFIX/qpkg.bin | openssl cms -sign -nodetach -binary -signer $SIGN_CERT -inkey $SIGN_KEY > $PREFIX/qpkg.bin.sign
# tail
sign_len=`stat -c "%s" $PREFIX/qpkg.bin.sign`
echo -n "QDK" >> $PREFIX/qpkg.bin
printf "\xFE" >> $PREFIX/qpkg.bin
len_to_binary $sign_len >> $PREFIX/qpkg.bin
cat $PREFIX/qpkg.bin.sign >> $PREFIX/qpkg.bin
printf "\xFF" >> $PREFIX/qpkg.bin
cat $PREFIX/tail >> $PREFIX/qpkg.bin
# update encrypt
fullsize=`stat -c "%s" $PREFIX/qpkg.bin`
encrypt=$((fullsize * 3589 + 1000000000))
echo -n "$encrypt" | dd of=$PREFIX/qpkg.bin seek=$((fullsize-60)) bs=1 conv=notrunc
mv $PREFIX/qpkg.bin $PREFIX/$QPKG
}
usage() {
echo "Usage:"
echo "$0 extract foldername pkgname extract package to foldername"
echo "$0 pack foldername pkgname pack files under folder to foldername"
exit 1
}
if [ "$#" -eq "2" ]; then
usage
fi
PREFIX="$2"
QPKG=$3
case "$1" in
extract)
extract_qdk
;;
pack)
pack_qdk
echo "please find it in $PREFIX/$QPKG"
;;
*)
usage
esac