wok-current view syslinux/stuff/iso2exe/iso2exe.sh @ rev 18063

syslinux: fix iso2exe -u
author Pascal Bellard <pascal.bellard@slitaz.org>
date Mon May 18 10:09:16 2015 +0200 (2015-05-18)
parents 8da7eef6c6d7
children 0606c4356e47
line source
1 #!/bin/sh
3 ddq()
4 {
5 dd $@ 2> /dev/null
6 }
8 store()
9 {
10 n=$2; for i in $(seq 8 8 ${4:-16}); do
11 printf '\\\\x%02X' $(($n & 255))
12 n=$(($n >> 8))
13 done | xargs echo -en | ddq bs=1 conv=notrunc of=$3 seek=$(($1))
14 }
16 get()
17 {
18 echo $(od -j $(($1)) -N ${3:-2} -t u${3:-2} -An $2)
19 }
21 compress()
22 {
23 if [ "$1" ]; then
24 gzip -9 > $1
25 [ "$(which advdef 2> /dev/null)" ] &&
26 advdef -z4 $1 > /dev/null
27 elif [ "$(which xz 2> /dev/null)" ]; then
28 xz -z -e --format=lzma --lzma1=mode=normal --stdout
29 else
30 lzma e -si -so
31 fi 2> /dev/null
32 }
34 add_rootfs()
35 {
36 TMP=/tmp/iso2exe$$
37 mkdir -p $TMP/bin $TMP/dev
38 cp -a /dev/?d?* /dev/tty /dev/tty0 $TMP/dev
39 $0 --get init > $TMP/init.exe
40 # mount -o loop,ro $1 $TMP
41 # oldslitaz="$(ls $TMP/boot/isolinux/splash.lss 2> /dev/null)"
42 # umount -d $TMP
43 # [ "$oldslitaz" ] && # for SliTaz <= 3.0 only...
44 # grep -q mount.posixovl.iso2exe $TMP/init.exe &&
45 # cp /usr/sbin/mount.posixovl $TMP/bin/mount.posixovl.iso2exe \
46 # 2> /dev/null && echo "Store mount.posixovl ($(wc -c \
47 # < /usr/sbin/mount.posixovl) bytes) ..."
48 find $TMP -type f -print0 | xargs -0 chmod +x
49 ( cd $TMP ; find * | cpio -o -H newc ) | compress $TMP/rootfs.gz
50 SIZE=$(wc -c < $TMP/rootfs.gz)
51 store 24 $SIZE $1
52 OFS=$(( $OFS - $SIZE ))
53 printf "Adding rootfs.gz file at %04X (%d bytes) ...\n" $OFS $SIZE
54 cat $TMP/rootfs.gz | ddq of=$1 bs=1 seek=$OFS conv=notrunc
55 rm -rf $TMP
56 }
58 add_dosexe()
59 {
60 TMP=/tmp/bootiso$$
61 $0 --get bootiso.bin > $TMP 2> /dev/null
62 OFS=$(($(get 20 $TMP) - 0xC0))
63 printf "Adding DOS/EXE stub at %04X (%d bytes) ...\n" $OFS $((0x8000 - $OFS))
64 ddq if=$TMP bs=1 skip=$OFS of=$1 seek=$OFS conv=notrunc
65 rm -f $TMP
66 }
68 add_doscom()
69 {
70 SIZE=$($0 --get boot.com | wc -c)
71 OFS=$(( $OFS - $SIZE ))
72 printf "Adding DOS boot file at %04X (%d bytes) ...\n" $OFS $SIZE
73 $0 --get boot.com | ddq of=$1 bs=1 seek=$OFS conv=notrunc
74 store 64 $(($OFS+0xC0)) $1
75 }
77 add_tazlito_info()
78 {
79 HOLE=$OFS
80 [ $(get 0 $2) -eq 35615 ] || return
81 zcat $2 | gzip -9 > /tmp/rezipped$$.gz
82 [ "$(which advdef 2> /dev/null)" ] &&
83 advdef -z4 /tmp/rezipped$$.gz > /dev/null
84 n=$(stat -c %s /tmp/rezipped$$.gz)
85 printf "Moving tazlito data record at %04X ($n bytes) ...\n" $OFS
86 ddq if=/tmp/rezipped$$.gz bs=1 of=$1 seek=$OFS conv=notrunc
87 HOLE=$(($HOLE+$n))
88 rm -f /tmp/rezipped$$.gz
89 }
91 add_win32exe()
92 {
93 SIZE=$($0 --get win32.exe 2> /dev/null | tee /tmp/exe$$ | wc -c)
94 printf "Adding WIN32 file at %04X (%d bytes) ...\n" 0 $SIZE
95 ddq if=/tmp/exe$$ of=$1 conv=notrunc
96 printf "Adding bootiso head at %04X...\n" 0
97 $0 --get bootiso.bin 2> /dev/null > /tmp/exe$$
98 ddq if=/tmp/exe$$ of=$1 bs=128 count=1 conv=notrunc
99 store $((0x94)) $((0xE0 - 12*8)) $1
100 store $((0xF4)) $((16 - 12)) $1
101 ddq if=$1 of=/tmp/coff$$ bs=1 skip=$((0x178)) count=$((0x88))
102 ddq if=/tmp/coff$$ of=$1 conv=notrunc bs=1 seek=$((0x178 - 12*8))
103 ddq if=/tmp/exe$$ of=$1 bs=1 count=24 seek=$((0x1A0)) skip=$((0x1A0)) conv=notrunc
104 ddq if=$2 bs=1 skip=$((0x1B8)) seek=$((0x1B8)) count=72 of=$1 conv=notrunc
105 store 417 $(($SIZE/512)) $1 8
106 store 510 $((0xAA55)) $1
107 rm -f /tmp/exe$$ /tmp/coff$$
108 printf "Moving syslinux hybrid boot record at %04X (512 bytes) ...\n" $SIZE
109 ddq if=$2 bs=1 count=512 of=$1 seek=$SIZE conv=notrunc
110 OFS=$(($SIZE+512))
111 }
113 add_fdbootstrap()
114 {
115 SIZE=$($0 --get bootfd.bin 2> /dev/null | wc -c)
116 if [ $SIZE -ne 0 ]; then
117 SIZE=$(( $SIZE - 512 )) # sector 2 is data
118 OFS=$(( $OFS - $SIZE ))
119 printf "Adding floppy bootstrap file at %04X (%d bytes) ...\n" $OFS $SIZE
120 $0 --get bootfd.bin | \
121 ddq of=$1 bs=1 count=512 seek=$OFS conv=notrunc
122 $0 --get bootfd.bin | \
123 ddq of=$1 bs=1 skip=1024 seek=$((512 + $OFS)) conv=notrunc
124 store 26 $(($SIZE/512)) $1 8
125 fi
126 }
127 case "$1" in
128 --build)
129 shift
130 ls -l $@
131 cat >> $0 <<EOM
132 $(tar cf - $@ | compress | uuencode -m -)
133 EOT
134 EOM
135 sed -i '/^case/,/^esac/d' $0
136 exit ;;
137 --get)
138 cat $2
139 exit ;;
140 --array)
141 DATA=/tmp/dataiso$$
142 ddq if=/dev/zero bs=32k count=1 of=$DATA
143 add_win32exe $DATA $2 > /dev/null
144 HSZ=$OFS
145 add_dosexe $DATA > /dev/null
146 add_rootfs $DATA > /dev/null
147 add_doscom $DATA > /dev/null
148 add_fdbootstrap $DATA > /dev/null
149 name=${3:-bootiso}
150 BOOTISOSZ=$((0x8000 - $OFS + $HSZ))
151 cat <<EOT
153 #define $(echo $name | tr '[a-z]' '[A-Z]')SZ $BOOTISOSZ
155 #ifdef WIN32
156 static char $name[] = {
157 /* head */
158 $(hexdump -v -n $HSZ -e '" " 16/1 "0x%02X, "' -e '" // %04.4_ax |" 16/1 "%_p" "| \n"' $DATA | sed 's/ 0x ,/ /g')
159 /* tail */
160 $(hexdump -v -s $OFS -e '" " 16/1 "0x%02X, "' -e '" // %04.4_ax |" 16/1 "%_p" "| \n"' $DATA | sed 's/ 0x ,/ /g')
162 /* These strange constants are defined in RFC 1321 as
163 T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64
164 */
165 /* static const uint32_t C_array[64] */
166 EOT
167 while read a b c d; do
168 for i in $a $b $c $d; do
169 echo $i | sed 's/0x\(..\)\(..\)\(..\)\(..\),/0x\4, 0x\3, 0x\2, 0x\1, /'
170 done
171 done <<EOT
172 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
173 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
174 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
175 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
176 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
177 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
178 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
179 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
180 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
181 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
182 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
183 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
184 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
185 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
186 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
187 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
188 EOT
189 cat <<EOT
190 /* static const char P_array[64] */
191 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
192 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
193 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
194 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, /* 4 */
195 /* static const char S_array[16] */
196 7, 12, 17, 22,
197 5, 9, 14, 20,
198 4, 11, 16, 23,
199 6, 10, 15, 21,
200 EOT
202 for mode in data offset ; do
203 ofs=0
204 while read tag str; do
205 if [ "$mode" == "data" ]; then
206 echo -en "$str\0" | hexdump -v -e '" " 16/1 "0x%02X, "' \
207 -e '" // %04.4_ax |" 16/1 "%_p" "| \n"' | \
208 sed 's/ 0x ,/ /g'
209 else
210 if [ $ofs -eq 0 ]; then
211 cat <<EOT
212 };
213 #else
214 static char *$name;
215 #endif
217 #define C_array (uint32_t *) ($name + $(($BOOTISOSZ)))
218 #define P_array (char *) ($name + $(($BOOTISOSZ+(64*4))))
219 #define S_array (char *) ($name + $(($BOOTISOSZ+(64*4)+64)))
220 #define ELTORITOOFS 3
221 EOT
222 fi
223 echo "#define $tag $(($BOOTISOSZ+(64*4)+64+16+$ofs))"
224 ofs=$(($(echo -en "$str\0" | wc -c)+$ofs))
225 fi
226 done <<EOT
227 READSECTORERR Read sector failure.
228 USAGE Usage: isohybrid.exe file.iso [--forced|--undo|--quick]
229 OPENERR Can't open r/w the iso file.
230 ELTORITOERR No EL TORITO SPECIFICATION signature.
231 CATALOGERR Invalid boot catalog.
232 HYBRIDERR No isolinux.bin hybrid signature.
233 SUCCESSMSG Now you can create a USB key with your .iso file.\\\\nSimply rename it to an .exe file and run it.
234 FORCEMSG You can add --forced to proceed anyway.
235 MD5MSG Computing md5sum...
236 UNINSTALLMSG Uninstall done.
237 EOT
238 done
239 rm -rf $DATA
240 exit ;;
241 --exe)
242 # --exe mvcom.bin x.com y.exe > xy.exe
243 cat $4 $3 > /tmp/exe$$
244 S=$(stat -c %s /tmp/exe$$)
245 store 2 $(($S%512)) /tmp/exe$$
246 store 4 $((($S+511)/512)) /tmp/exe$$
247 store 14 -16 /tmp/exe$$
248 store 16 -2 /tmp/exe$$
249 store 20 256 /tmp/exe$$
250 store 22 -16 /tmp/exe$$
251 ddq if=$2 bs=1 seek=64 of=/tmp/exe$$ conv=notrunc
252 store 65 $(stat -c %s $3) /tmp/exe$$
253 store 68 $((0x100-0x40+$(stat -c %s $4))) /tmp/exe$$
254 cat /tmp/exe$$
255 rm -f /tmp/exe$$
256 exit ;;
257 esac
259 main()
260 {
261 [ $(id -u) -ne 0 ] && exec su -c "$0 $@" < /dev/tty
262 case "${1/--/-}" in
263 -get) shift
264 uudecode | unlzma | tar xOf - $@
265 exit ;;
266 *) cat > /dev/null
267 esac
269 [ ! -s "$1" ] &&
270 echo "usage: $0 image.iso [--undo|\"DOS help message\"]" 1>&2 && exit 1
271 case "${2/--/-}" in
272 -u*|-r*|-w*)
273 case "$(get 0 $1)" in
274 23117)
275 b=$(get 417 $1 1)
276 n=$(($(get 64 $1) + 0xC0 - ($(get 26 $1 1)*512) - ($b+1)*512))
277 ddq if=$1 bs=512 count=1 skip=$b of=$1 conv=notrunc
278 ddq if=/dev/zero bs=512 seek=1 count=1 of=$1 conv=notrunc
279 ddq if=$1 bs=512 seek=2 count=30 skip=$(($b+1)) of=$1 conv=notrunc
280 ddq if=/dev/zero bs=1 seek=$n count=$((0x8000 - $n)) of=$1 conv=notrunc ;;
281 *) ddq if=/dev/zero bs=1k count=32 of=$1 conv=notrunc ;;
282 esac
283 exit 0
284 esac
285 case "$(get 0 $1)" in
286 23117) echo "The file $1 is already an EXE file." 1>&2 && exit 1;;
287 0) [ -x /usr/bin/isohybrid ] && isohybrid $1;;
288 esac
290 echo "Read hybrid & tazlito data..."
291 ddq if=$1 bs=512 count=1 of=/tmp/hybrid$$
292 ddq if=$1 bs=512 skip=2 count=20 of=/tmp/tazlito$$
293 add_win32exe $1 /tmp/hybrid$$
294 add_tazlito_info $1 /tmp/tazlito$$
295 rm -f /tmp/tazlito$$ /tmp/hybrid$$
297 # keep the largest room for the tazlito info file
298 add_dosexe $1
299 add_rootfs $1
300 add_doscom $1
301 add_fdbootstrap $1
302 printf "%d free bytes in %04X..%04X\n" $(($OFS-$HOLE)) $HOLE $OFS
303 store 440 $(date +%s) $1 32
304 [ "$2" ] && echo "$2 " | \
305 ddq bs=1 seek=$((0x7FDE)) count=15 conv=notrunc of=$1
306 if [ $(stat -c %s $1) -gt 34816 ]; then
307 echo "Adding ISO image md5 at 7FF0 (16 bytes) ..."
308 echo -en "$(ddq if=$1 bs=2k skip=16 count=$(get 32848 $1 4) | \
309 md5sum | cut -c-32 | sed 's/\(..\)/\\x\1/g')" | \
310 ddq bs=16 seek=2047 conv=notrunc of=$1
311 fi
312 echo -n "Adding boot checksum..."
313 if [ $(stat -c %s $1) -gt 32768 ]; then
314 n=$(($(get 2 $1) - 1 + ($(get 4 $1) - 1)*512))
315 n=$(($(od -v -N $n -t u2 -w2 -An $1 | \
316 awk '{ i+= $0 } END { print (i % 65536) }') \
317 + $(get $(($n+1)) $1 1)))
318 store 18 $(( (-$n -1) % 65536 )) $1
319 fi
320 echo " done."
321 }
323 main $@ <<EOT