wok view syslinux/stuff/iso2exe/iso2exe.sh @ rev 18815

lxpanel: fix post_install
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Jan 15 16:27:43 2016 +0100 (2016-01-15)
parents 67f5b3bae0a8
children 6e468bea3c84
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/dev
38 cp -a /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 && mkdir $TMP/bin &&
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 }
128 fileofs()
129 {
130 [ $(get 1024 $ISO) -eq 35615 ] && i=1024 || i=$((512*(1+$(get 417 $ISO 1))))
131 stub=$(($(get 20 $ISO) - 0xC0))
132 SIZE=0; OFFSET=0
133 case "$1" in
134 win32.exe) [ $i -eq 1024 ] || SIZE=$(($i - 512));;
135 syslinux.mbr) [ $i -eq 1024 ] || OFFSET=$(($i - 512)); SIZE=512;;
136 flavor.info) OFFSET=$i; SIZE=-1;;
137 floppy.boot) SIZE=$(($(get 26 $ISO 1)*512))
138 OFFSET=$(($(get 64 $ISO) - 0xC0 - $SIZE));;
139 rootfs.gz) SIZE=$(get 24 $ISO); OFFSET=$(($stub - $SIZE));;
140 tazboot.com) OFFSET=$(($(get 64 $ISO) - 0xC0))
141 SIZE=$(($stub - $(get 24 $ISO) - $OFFSET));;
142 dosstub) OFFSET=$stub; SIZE=$((0x8000 - $OFFSET));;
143 md5) OFFSET=$((0x7FF0)); SIZE=16;;
144 esac
145 }
147 list()
148 {
149 for f in win32.exe syslinux.mbr flavor.info floppy.boot \
150 dosstub rootfs.gz tazboot.com md5 ; do
151 fileofs $f
152 [ $SIZE -eq 0 ] && continue
153 echo -n "$f at $(printf "%X\n" $OFFSET)"
154 [ $SIZE -eq -1 ] || echo -n " ($SIZE bytes)"
155 echo .
156 done
157 }
159 extract()
160 {
161 for f in $@; do
162 fileofs $f
163 case "$SIZE" in
164 0) ;;
165 -1) ddq bs=1 count=20480 skip=$OFFSET if="$ISO" | zcat >$f ;;
166 *) ddq bs=1 count=$SIZE skip=$OFFSET if="$ISO" >$f ;;
167 esac
168 done
169 }
171 custom_config_sector()
172 {
173 echo $(($(get 32848 "$1" 4)+16))
174 }
176 clear_custom_config()
177 {
178 start=$(custom_config_sector $1)
179 cnt=$((512 - ($start % 512)))
180 [ $cnt -ne 512 ] &&
181 ddq if=/dev/zero of=$1 bs=2k seek=$start count=$cnt
182 }
184 extract_custom_config()
185 {
186 ISO="$1"
187 header=
188 ddq bs=2k skip=$(custom_config_sector "$ISO") if="$ISO" | \
189 while read line; do
190 case "$line" in
191 \#!boot*) header=1 ;;
192 append=*) [ "$header" ] &&
193 echo "${line#append=}" > "$ISO.append" &&
194 ls -l "$ISO.append" ;;
195 initrd:*) [ "$header" ] &&
196 ddq bs=1 count=${line#initrd:} > "$ISO.initrd" &&
197 ls -l "$ISO.initrd" ;;
198 esac
199 [ "$header" ] || break
200 done
201 }
202 case "$1" in
203 --build)
204 shift
205 ls -l $@
206 cat >> $0 <<EOM
207 $(tar cf - $@ | compress | uuencode -m -)
208 EOT
209 EOM
210 sed -i '/^case/,/^esac/d' $0
211 exit ;;
212 --get)
213 cat $2
214 exit ;;
215 --array)
216 DATA=/tmp/dataiso$$
217 ddq if=/dev/zero bs=32k count=1 of=$DATA
218 add_win32exe $DATA $2 > /dev/null
219 HSZ=$OFS
220 add_dosexe $DATA > /dev/null
221 add_rootfs $DATA > /dev/null
222 add_doscom $DATA > /dev/null
223 add_fdbootstrap $DATA > /dev/null
224 name=${3:-bootiso}
225 BOOTISOSZ=$((0x8000 - $OFS + $HSZ))
226 cat <<EOT
228 #define $(echo $name | tr '[a-z]' '[A-Z]')SZ $BOOTISOSZ
230 #ifndef __MSDOS__
231 static char $name[] = {
232 /* head */
233 $(hexdump -v -n $HSZ -e '" " 16/1 "0x%02X, "' -e '" // %04.4_ax |" 16/1 "%_p" "| \n"' $DATA | sed 's/ 0x ,/ /g')
234 /* tail */
235 $(hexdump -v -s $OFS -e '" " 16/1 "0x%02X, "' -e '" // %04.4_ax |" 16/1 "%_p" "| \n"' $DATA | sed 's/ 0x ,/ /g')
237 /* These strange constants are defined in RFC 1321 as
238 T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64
239 */
240 /* static const uint32_t C_array[64] */
241 EOT
242 while read a b c d; do
243 for i in $a $b $c $d; do
244 echo $i | sed 's/0x\(..\)\(..\)\(..\)\(..\),/0x\4, 0x\3, 0x\2, 0x\1, /'
245 done
246 done <<EOT
247 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
248 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
249 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
250 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
251 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
252 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
253 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
254 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
255 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
256 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
257 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
258 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
259 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
260 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
261 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
262 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
263 EOT
264 cat <<EOT
265 /* static const char P_array[64] */
266 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
267 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
268 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
269 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, /* 4 */
270 /* static const char S_array[16] */
271 7, 12, 17, 22,
272 5, 9, 14, 20,
273 4, 11, 16, 23,
274 6, 10, 15, 21,
275 EOT
277 for mode in data offset ; do
278 ofs=0
279 while read tag str; do
280 if [ "$mode" == "data" ]; then
281 echo -en "$str\0" | hexdump -v -e '" " 16/1 "0x%02X, "' \
282 -e '" // %04.4_ax |" 16/1 "%_p" "| \n"' | \
283 sed 's/ 0x ,/ /g'
284 else
285 if [ $ofs -eq 0 ]; then
286 cat <<EOT
287 };
288 #else
289 static char *$name;
290 #endif
292 #define C_array (uint32_t *) ($name + $(($BOOTISOSZ)))
293 #define P_array (char *) ($name + $(($BOOTISOSZ+(64*4))))
294 #define S_array (char *) ($name + $(($BOOTISOSZ+(64*4)+64)))
295 #define ELTORITOOFS 3
296 EOT
297 fi
298 echo "#define $tag $(($BOOTISOSZ+(64*4)+64+16+$ofs))"
299 ofs=$(($(echo -en "$str\0" | wc -c)+$ofs))
300 fi
301 done <<EOT
302 READSECTORERR Read sector failure.
303 USAGE Usage: isohybrid.exe [--append cmdline] [--initrd file] file.iso [--forced|--undo|--quick]
304 OPENERR Can't open r/w the iso file.
305 ELTORITOERR No EL TORITO SPECIFICATION signature.
306 CATALOGERR Invalid boot catalog.
307 HYBRIDERR No isolinux.bin hybrid signature.
308 SUCCESSMSG Now you can create a USB key with your .iso file.\\\\nSimply rename it to an .exe file and run it.
309 FORCEMSG You can add --forced to proceed anyway.
310 MD5MSG Computing md5sum...
311 UNINSTALLMSG Uninstall done.
312 OPENINITRDERR Can't open the initrd file.
313 ALREADYEXEERR Already an EXE file.
314 EOT
315 done
316 rm -rf $DATA
317 exit ;;
318 --exe)
319 # --exe mvcom.bin x.com y.exe > xy.exe
320 cat $4 $3 > /tmp/exe$$
321 S=$(stat -c %s /tmp/exe$$)
322 store 2 $(($S%512)) /tmp/exe$$
323 store 4 $((($S+511)/512)) /tmp/exe$$
324 store 14 -16 /tmp/exe$$
325 store 16 -2 /tmp/exe$$
326 store 20 256 /tmp/exe$$
327 store 22 -16 /tmp/exe$$
328 ddq if=$2 bs=1 seek=64 of=/tmp/exe$$ conv=notrunc
329 store 65 $(stat -c %s $3) /tmp/exe$$
330 store 68 $((0x100-0x40+$(stat -c %s $4))) /tmp/exe$$
331 cat /tmp/exe$$
332 rm -f /tmp/exe$$
333 exit ;;
334 esac
336 main()
337 {
338 [ $(id -u) -ne 0 ] && cmd="$0 $@" && exec su -c "$cmd" < /dev/tty
339 append=
340 initrd=
341 while [ "$1" ]; do
342 case "${1/--/-}" in
343 -get) shift
344 uudecode | unlzma | tar xOf - $@
345 exit ;;
346 -a*) append="$2" ; shift 2 ;;
347 -i*) initrd="$2" ; shift 2 ;;
348 -e*) extract_custom_config "$2"
349 exit ;;
350 -r*) ISO="$2" ; shift 2
351 [ -z "$1" ] && list || extract $@
352 exit ;;
353 *) cat > /dev/null
354 break
355 esac
356 done
358 [ ! -s "$1" ] && cat 1>&2 <<EOT && exit 1
359 usage: $0 [--append custom_cmdline ] [ --initrd custom_initramfs ] image.iso [--force|--undo|"DOS help message"]
360 or: $0 --extract-custom-config image.iso
361 EOT
362 case "${2/--/-}" in
363 -u*|-r*|-w*)
364 case "$(get 0 $1)" in
365 23117)
366 b=$(get 417 $1 1)
367 n=$(($(get 64 $1) + 0xC0 - ($(get 26 $1 1)*512) - ($b+1)*512))
368 ddq if=$1 bs=512 count=1 skip=$b of=$1 conv=notrunc
369 ddq if=/dev/zero bs=512 seek=1 count=1 of=$1 conv=notrunc
370 ddq if=$1 bs=512 seek=2 count=30 skip=$(($b+1)) of=$1 conv=notrunc
371 ddq if=/dev/zero bs=1 seek=$n count=$((0x8000 - $n)) of=$1 conv=notrunc ;;
372 *) ddq if=/dev/zero bs=1k count=32 of=$1 conv=notrunc ;;
373 esac
374 clear_custom_config $1
375 exit 0 ;;
376 -f*)
377 ddq if=/dev/zero bs=1k count=32 of=$1 conv=notrunc
378 [ "$append$initrd" ] && clear_custom_config $1
379 esac
380 case "$(get 0 $1)" in
381 23117) echo "The file $1 is already an EXE file." 1>&2 && exit 1;;
382 0) [ -x /usr/bin/isohybrid ] && isohybrid $1;;
383 esac
385 echo "Read hybrid & tazlito data..."
386 ddq if=$1 bs=512 count=1 of=/tmp/hybrid$$
387 ddq if=$1 bs=512 skip=2 count=20 of=/tmp/tazlito$$
388 add_win32exe $1 /tmp/hybrid$$
389 add_tazlito_info $1 /tmp/tazlito$$
390 rm -f /tmp/tazlito$$ /tmp/hybrid$$
392 # keep the largest room for the tazlito info file
393 add_dosexe $1
394 add_rootfs $1
395 add_doscom $1
396 add_fdbootstrap $1
397 printf "%d free bytes in %04X..%04X\n" $(($OFS-$HOLE)) $HOLE $OFS
398 store 440 $(date +%s) $1 32
399 [ "$2" ] && echo "$2 " | \
400 ddq bs=1 seek=$((0x7FDE)) count=15 conv=notrunc of=$1
401 if [ $(stat -c %s $1) -gt 34816 ]; then
402 echo "Adding ISO image md5 at 7FF0 (16 bytes) ..."
403 echo -en "$(ddq if=$1 bs=2k skip=16 count=$(get 32848 $1 4) | \
404 md5sum | cut -c-32 | sed 's/\(..\)/\\x\1/g')" | \
405 ddq bs=16 seek=2047 conv=notrunc of=$1
406 fi
407 echo -n "Adding boot checksum..."
408 if [ $(stat -c %s $1) -gt 32768 ]; then
409 n=$(($(get 2 $1) - 1 + ($(get 4 $1) - 1)*512))
410 n=$(($(od -v -N $n -t u2 -w2 -An $1 | \
411 awk '{ i+= $0 } END { print (i % 65536) }') \
412 + $(get $(($n+1)) $1 1)))
413 store 18 $(( (-$n -1) % 65536 )) $1
414 fi
415 echo " done."
416 if [ "$append$initrd" ]; then
417 echo -n "Adding custom config... "
418 DATA=/tmp/$(basename $0)$$
419 rm -f $DATA > /dev/null
420 isosz=$(stat -c %s $1)
421 [ "$append" ] && echo "append=$append" >> $DATA
422 [ -s "$initrd" ] && echo "initrd:$(stat -c %s $initrd)" >> $DATA &&
423 cat $initrd >> $DATA
424 echo "#!boot $(md5sum $DATA | sed 's/ .*//')" | cat - $DATA | \
425 ddq bs=2k seek=$(custom_config_sector $1) of=$1 conv=notrunc
426 if [ $(stat -c %s $1) -gt $isosz ]; then
427 echo "$(($(stat -c %s $1) - $isosz)) extra bytes."
428 else
429 echo "$(($isosz - 32768 - 2048*$(get 32848 $1 4)
430 - $(stat -c %s $DATA) - 24)) bytes free."
431 fi
432 rm -f $DATA > /dev/null
433 fi
434 }
436 main "$@" <<EOT