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

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