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

syslinux/iso2exe: fix old case
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Feb 08 19:28:56 2019 +0100 (23 months ago)
parents 4c206553708a
children 02994416f017
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 -i100 $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
38 $0 --get rootfs.gz > $TMP/rootfs.gz
39 SIZE=$(wc -c < $TMP/rootfs.gz)
40 store 24 $SIZE $1
41 OFS=$(( $OFS - $SIZE ))
42 printf "Adding rootfs.gz file at %04X (%d bytes) ...\n" $OFS $SIZE
43 cat $TMP/rootfs.gz | ddq of=$1 bs=1 seek=$OFS conv=notrunc
44 rm -rf $TMP
45 }
47 add_dosexe()
48 {
49 TMP=/tmp/bootiso$$
50 $0 --get bootiso.bin > $TMP 2> /dev/null
51 OFS=$(($(get 20 $TMP) - 0xC0))
52 printf "Adding DOS/EXE stub at %04X (%d bytes) ...\n" $OFS $((0x7FF0 - $OFS))
53 ddq if=$TMP bs=1 skip=$OFS of=$1 seek=$OFS conv=notrunc
54 rm -f $TMP
55 }
57 add_doscom()
58 {
59 SIZE=$($0 --get boot.com | wc -c)
60 OFS=$(( $OFS - $SIZE ))
61 printf "Adding DOS boot file at %04X (%d bytes) ...\n" $OFS $SIZE
62 $0 --get boot.com | ddq of=$1 bs=1 seek=$OFS conv=notrunc
63 store 64 $(($OFS+0xC0)) $1
64 }
66 add_tazlito_info()
67 {
68 HOLE=$OFS
69 [ $(get 0 $2) -eq 35615 ] || return
70 zcat $2 | compress /tmp/rezipped$$.gz
71 n=$(stat -c %s /tmp/rezipped$$.gz)
72 printf "Moving tazlito data record at %04X ($n bytes) ...\n" $OFS
73 ddq if=/tmp/rezipped$$.gz bs=1 of=$1 seek=$OFS conv=notrunc
74 HOLE=$(($HOLE+$n))
75 rm -f /tmp/rezipped$$.gz
76 if [ -n "$gpt" ]; then
77 store $((0x25E)) $n $1
78 store $((0x25C)) $OFS $1
79 fi
80 }
82 add_win32exe()
83 {
84 SIZE=$($0 --get win32.exe 2> /dev/null | tee /tmp/exe$$ | wc -c)
85 [ -n "$gpt" ] && SIZE=$(($SIZE+1024))
86 [ -n "$mac" ] && SIZE=$(($SIZE+3072))
87 printf "Adding WIN32 file at %04X (%d bytes) ...\n" 0 $SIZE
88 ddq if=/tmp/exe$$ of=$1 conv=notrunc
89 if [ -n "$gpt" ]; then
90 printf "Adding GPT at %04X (1024 bytes) ...\n" 512
91 ddq if=$2 bs=512 skip=1 of=$1 seek=1 conv=notrunc
92 i=3; [ -n "$mac" ] && i=9
93 ddq if=/tmp/exe$$ bs=512 skip=1 of=$1 seek=$i conv=notrunc
94 for i in 12C 154 17C ; do # always 3 UPX sections
95 store $((0x$i)) $((1024 + $(get 0x$i $1))) $1
96 done
97 fi
98 printf "Adding bootiso head at %04X...\n" 0
99 $0 --get bootiso.bin 2> /dev/null > /tmp/exe$$
100 ddq if=/tmp/exe$$ of=$1 bs=128 count=1 conv=notrunc
101 store $((0x94)) $((0xE0 - 12*8)) $1
102 store $((0xF4)) $((16 - 12)) $1
103 ddq if=$1 of=/tmp/coff$$ bs=1 skip=$((0x178)) count=$((0x88))
104 ddq if=/tmp/coff$$ of=$1 conv=notrunc bs=1 seek=$((0x178 - 12*8))
105 ddq if=/tmp/exe$$ of=$1 bs=1 count=24 seek=$((0x1A0)) skip=$((0x1A0)) conv=notrunc
106 ddq if=$2 bs=1 skip=$((0x1B8)) seek=$((0x1B8)) count=72 of=$1 conv=notrunc
107 store 510 $((0xAA55)) $1
108 i=$SIZE; OFS=$(($SIZE+512))
109 [ -n "$mac" ] && OFS=$SIZE && i=1536
110 store 417 $(($i/512)) $1 8
111 printf "Moving syslinux hybrid boot record at %04X (512 bytes) ...\n" $i
112 ddq if=$2 bs=1 count=512 of=$1 seek=$i conv=notrunc
113 if [ $(get $((0x7C00)) /tmp/exe$$) -eq 60905 ]; then
114 ddq if=/tmp/exe$$ bs=1 count=66 skip=$((0x7DBE)) of=$1 seek=$(($i + 0x1BE)) conv=notrunc
115 ddq if=$1 bs=1 count=3 skip=$i of=$1 seek=$(($i + 0x1BE)) conv=notrunc
116 ddq if=/tmp/exe$$ bs=1 count=3 skip=$((0x7C00)) of=$1 seek=$i conv=notrunc
117 fi
118 rm -f /tmp/exe$$ /tmp/coff$$
119 if [ -z "$RECURSIVE_PARTITION" -a $(get 454 $1 4) -eq 0 ]; then
120 store 448 $((1+$i/512)) $1 8
121 store 454 $(($i/512)) $1 8
122 store 458 $(($(get 458 $1 4) - $i/512)) $1 32
123 fi
124 }
126 add_fdbootstrap()
127 {
128 SIZE=$($0 --get bootfd.bin 2> /dev/null | wc -c)
129 if [ $SIZE -ne 0 ]; then
130 SIZE=$(( $SIZE - 512 )) # sector 2 is data
131 OFS=$(( $OFS - $SIZE ))
132 printf "Adding floppy bootstrap file at %04X (%d bytes) ...\n" $OFS $SIZE
133 $0 --get bootfd.bin | \
134 ddq of=$1 bs=1 count=512 seek=$OFS conv=notrunc
135 $0 --get bootfd.bin | \
136 ddq of=$1 bs=1 skip=1024 seek=$((512 + $OFS)) conv=notrunc
137 store 26 $(($SIZE/512)) $1 8
138 fi
139 }
141 gzsize()
142 {
143 echo $(($(hexdump -C | awk ' {
144 for (i = 17; i > 1; i--) if ($i != "00") break;
145 if (i == 1) {
146 print "0x" $1 " + 1 + 1 - " n
147 exit
148 }
149 n = 17 - i
150 }')))
151 }
153 fileofs()
154 {
155 [ $(get 1024 "$ISO") -eq 35615 ] && x=1024 ||
156 x=$((512*(1+$(get 417 "$ISO" 1))))
157 [ $x -gt 32768 ] && x=6656
158 stub=$(($(get 20 "$ISO") - 0xC0))
159 c=$(custom_config_sector "$ISO")
160 SIZE=0; OFFSET=0
161 case "$1" in
162 win32.exe) [ $x -eq 2048 ] && x=10752
163 [ $x -eq 1024 ] || SIZE=$(($x - 512));;
164 syslinux.mbr) [ $x -eq 1024 ] || OFFSET=$(($x - 512)); SIZE=512;;
165 flavor.info) [ $(get 22528 "$ISO") -eq 35615 ] && OFFSET=22528
166 [ $x -eq 2048 ] && x=$(get 0x25C "$ISO") &&
167 SIZE=$(get 0x25E "$ISO")
168 [ $(get $x "$ISO") -eq 35615 ] && OFFSET=$x
169 [ $OFFSET -ne 0 ] && [ $SIZE -eq 0 ] &&
170 SIZE=$(ddq bs=512 skip=$(($OFFSET/512)) if="$ISO" | gzsize);;
171 floppy.boot) SIZE=$(($(get 26 "$ISO" 1)*512))
172 OFFSET=$(($(get 64 "$ISO") - 0xC0 - $SIZE));;
173 rootfs.gz) SIZE=$(get 24 "$ISO"); OFFSET=$(($stub - $SIZE));;
174 tazboot.com) OFFSET=$(($(get 64 "$ISO") - 0xC0))
175 SIZE=$(($stub - $(get 24 "$ISO") - $OFFSET));;
176 dosstub) OFFSET=$stub; SIZE=$((0x7FF0 - $OFFSET));;
177 boot.md5) [ $(get 0 "$ISO") -eq 23117 ] &&
178 [ $(get 18 "$ISO") -ne 0 ] &&
179 OFFSET=$((0x7FF0)) && SIZE=16;;
180 fs.iso) OFFSET=$((0x8000))
181 SIZE=$((2048*$c - $OFFSET));;
182 custom.magic) ddq bs=2k skip=$c if="$ISO" | ddq bs=1 count=6 | \
183 grep -q '#!boot' && OFFSET=$((2048*$c)) &&
184 SIZE=39 ;;
185 custom.append) OFFSET=$((2048*$c+47)) &&
186 SIZE=$(ddq bs=2k skip=$c if="$ISO" count=1 | \
187 sed '/^append=/!d;s/^[^=]*=.//' | wc -c);;
188 custom.initrd) x=$(ddq bs=2k skip=$c if="$ISO" count=1 | \
189 sed '/^append=\|^initrd:/!d' | wc -c)
190 OFFSET=$((2048*$c+$x+40))
191 SIZE=$(($(ddq bs=2k skip=$c if="$ISO" count=1 | \
192 sed '/^initrd:/!d;s/.*://') + 0));;
193 esac
194 }
196 trailer()
197 {
198 OFFSET=$(stat -c %s "$1")
199 [ $OFFSET -gt $HEAP ] &&
200 printf "%d free bytes in %04X..%04X\n" $(($OFFSET - $HEAP)) $HEAP $OFFSET
201 if [ $(get 510 "$1") -eq 43605 ]; then
202 echo "MBR partitions :"
203 for i in 0 1 2 3; do
204 SIZE=$(get $((446+12+16*i)) "$1" 4)
205 [ $SIZE -eq 0 ] && continue
206 OFFSET=$(get $((446+8+16*i)) "$1" 4)
207 printf " $i:%08X %08X %02X\n" $OFFSET $SIZE \
208 $(get $((446+4+16*i)) "$1" 1)
209 done
210 if [ $(get 450 "$1") -eq 65262 ]; then
211 echo "EFI partitions :"
212 n=$(get 592 "$1")
213 s=$(get 596 "$1")
214 o=$(($(get 584 "$1")*512))
215 i=0
216 while [ $i -lt $n ]; do
217 f=$(get $(($o+0x20)) "$1" 4)
218 l=$(($(get $(($o+0x28)) "$1" 4)-$f))
219 [ $l -eq 0 ] && break
220 printf " $i:%08X %08X %s\n" $f $(($l+1)) \
221 "$(od -An -N 72 -w72 -j $(($o+0x38)) -t a "$1" \
222 | sed 's/ nul//g;s/ //g;s/ sp//g')"
223 o=$(($o+$s))
224 i=$(($i+1))
225 done
226 fi
227 fi
228 o=2048
229 if [ $(get $o "$1") -eq 19792 ]; then
230 echo "Apple partitions :"
231 i=0
232 while [ $(get $o "$1") -eq 19792 ]; do
233 f=$((0x$(od -An -N 4 -j $(($o+8)) -t x1 "$1" | sed 's/ //g')))
234 l=$((0x$(od -An -N 4 -j $(($o+0x54)) -t x1 "$1" | sed 's/ //g')))
235 printf " $i:%08X %08X %s\n" $f $l \
236 "$(ddq bs=1 skip=$(($o+16)) count=32 if="$1")"
237 o=$(($o+2048))
238 i=$(($i+1))
239 done
240 fi
241 }
243 list()
244 {
245 HEAP=0
246 for f in win32.exe syslinux.mbr flavor.info floppy.boot tazboot.com \
247 rootfs.gz dosstub boot.md5 fs.iso custom.magic custom.append \
248 custom.initrd; do
249 fileofs $f
250 [ $SIZE -le 0 ] && continue
251 [ "${OFFSET:8}" ] && continue
252 [ $OFFSET -lt 0 ] && continue
253 [ $(get $OFFSET "$ISO") -eq 0 ] && continue
254 [ $OFFSET -gt $HEAP ] && [ $(($OFFSET - $HEAP)) -gt 16 ] &&
255 printf "%d free bytes in %04X..%04X\n" $(($OFFSET - $HEAP)) $HEAP $OFFSET
256 [ $OFFSET -ge $HEAP ] && HEAP=$(($OFFSET+$SIZE))
257 printf "$f at %04X ($SIZE bytes).\n" $OFFSET
258 done
259 trailer $ISO
260 }
262 restore_hybrid_mbr()
263 {
264 if [ $(get 0 "$1") -eq 60905 ]; then
265 ddq bs=1 conv=notrunc if="$1" of="$1" skip=$((0x1BE)) seek=0 count=3
266 ddq bs=1 skip=$((0x1BE)) count=66 if="$2" | \
267 ddq bs=1 seek=$((0x1BE)) count=66 of="$1" conv=notrunc
268 if [ -n "$RECURSIVE_PARTITION" ]; then
269 for i in 0 1 2 3 ; do
270 n=$(get $((0x1C6+16*i)) $1 4)
271 [ $n -eq 0 -o $n -gt 64 ] && continue
272 store $((0x1C0+16*i)) 1 $1 8
273 store $((0x1C6+16*i)) 0 $1 32
274 store $((0x1CA+16*i)) $(($(get $((0x1CA+16*i)) $1 4)+$n)) $1 32
275 done
276 fi
277 fi
278 }
280 extract()
281 {
282 for f in $@; do
283 fileofs $f
284 [ $SIZE -eq 0 ] ||
285 ddq bs=1 count=$SIZE skip=$OFFSET if="$ISO" >$f
286 [ "$f" == "syslinux.mbr" ] && restore_hybrid_mbr "$f" "$ISO"
287 done
288 }
290 custom_config_sector()
291 {
292 get 32848 "$1" 4
293 }
295 clear_custom_config()
296 {
297 start=$(custom_config_sector $1)
298 cnt=$((512 - ($start % 512)))
299 [ $cnt -ne 512 ] &&
300 ddq if=/dev/zero of=$1 bs=2k seek=$start count=$cnt
301 }
302 case "$1" in
303 --build)
304 shift
305 TMP=/tmp/iso2exe$$
306 mkdir -p $TMP/dev
307 cp -a /dev/tty /dev/tty0 $TMP/dev
308 cat init > $TMP/init.exe
309 find $TMP -type f -print0 | xargs -0 chmod +x
310 find $TMP -print0 | xargs -0 touch -t 197001010100.00
311 ( cd $TMP; find dev init.exe | cpio -o -H newc ) | compress rootfs.gz
312 rm -rf $TMP
313 ls -l $@ rootfs.gz
314 cat >> $0 <<EOM
315 $(tar cf - ${@/init/rootfs.gz} | compress | uuencode -m -)
316 EOT
317 EOM
318 sed -i '/^case/,/^esac/d' $0
319 exit ;;
320 --get)
321 cat $2
322 exit ;;
323 --array)
324 DATA=/tmp/dataiso$$
325 ddq if=/dev/zero bs=32k count=1 of=$DATA
326 add_win32exe $DATA $2 > /dev/null
327 HSZ=$OFS
328 add_dosexe $DATA > /dev/null
329 add_rootfs $DATA > /dev/null
330 add_doscom $DATA > /dev/null
331 add_fdbootstrap $DATA > /dev/null
332 name=${3:-bootiso}
333 BOOTISOSZ=$((0x8000 - $OFS + $HSZ))
334 cat <<EOT
336 #define $(echo $name | tr '[a-z]' '[A-Z]')SZ $BOOTISOSZ
338 #ifndef __MSDOS__
339 static char $name[] = {
340 /* head */
341 $(hexdump -v -n $HSZ -e '" " 16/1 "0x%02X, "' -e '" /* %04.4_ax */ \n"' $DATA | sed 's/ 0x ,/ /g')
342 /* tail */
343 $(hexdump -v -s $OFS -e '" " 16/1 "0x%02X, "' -e '" /* %04.4_ax */ \n"' $DATA | sed 's/ 0x ,/ /g')
345 /* These strange constants are defined in RFC 1321 as
346 T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64
347 */
348 /* static const uint32_t C_array[64] */
349 EOT
350 while read a b c d; do
351 for i in $a $b $c $d; do
352 echo $i | sed 's/0x\(..\)\(..\)\(..\)\(..\),/0x\4, 0x\3, 0x\2, 0x\1, /'
353 done
354 done <<EOT
355 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
356 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
357 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
358 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
359 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
360 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
361 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
362 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
363 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
364 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
365 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
366 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
367 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
368 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
369 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
370 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
371 EOT
372 cat <<EOT
373 /* static const char P_array[64] */
374 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
375 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
376 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
377 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, /* 4 */
378 /* static const char S_array[16] */
379 7, 12, 17, 22,
380 5, 9, 14, 20,
381 4, 11, 16, 23,
382 6, 10, 15, 21,
383 EOT
385 for mode in data offset ; do
386 ofs=0
387 while read tag str; do
388 if [ "$mode" == "data" ]; then
389 echo -en "$str\0" | hexdump -v -e '" " 16/1 "0x%02X, "' \
390 -e '" /* %04.4_ax */ \n"' | \
391 sed 's/ 0x ,/ /g'
392 else
393 if [ $ofs -eq 0 ]; then
394 cat <<EOT
395 };
396 #endif
398 #define C_array (uint32_t *) ($name + $(($BOOTISOSZ)))
399 #define P_array (char *) ($name + $(($BOOTISOSZ+(64*4))))
400 #define S_array (char *) ($name + $(($BOOTISOSZ+(64*4)+64)))
401 #define ELTORITOOFS 3
402 EOT
403 fi
404 echo "#define $tag $(($BOOTISOSZ+(64*4)+64+16+$ofs))"
405 ofs=$(($(echo -en "$str\0" | wc -c)+$ofs))
406 fi
407 done <<EOT
408 READSECTORERR Read sector failure.
409 USAGE Usage: isohybrid.exe [--list|--read] [--append cmdline] [--initrd file] file.iso [--forced|--undo|--quick|filename...]
410 OPENERR Can't open the iso file.
411 ELTORITOERR No EL TORITO SPECIFICATION signature.
412 CATALOGERR Invalid boot catalog.
413 HYBRIDERR No isolinux.bin hybrid signature.
414 SUCCESSMSG Now you can create a USB key with your .iso file.\\\\nSimply rename it to an .exe file and run it.
415 FORCEMSG You can add --forced to proceed anyway.
416 MD5MSG Computing md5sum...
417 UNINSTALLMSG Uninstall done.
418 OPENINITRDERR Can't open the initrd file.
419 ALREADYEXEERR Already an EXE file.
420 WIN32_EXE win32.exe
421 SYSLINUX_MBR syslinux.mbr
422 FLAVOR_INFO flavor.info
423 FLOPPY_BOOT floppy.boot
424 TAZBOOT_COM tazboot.com
425 ROOTFS_GZ rootfs.gz
426 DOSSTUB dosstub
427 BOOT_MD5 boot.md5
428 FS_ISO fs.iso
429 CUSTOM_MAGIC custom.magic
430 CUSTOM_APPEND custom.append
431 CUSTOM_INITRD custom.initrd
432 CUSTOM_HEADER #!boot 00000000000000000000000000000000\\\\n
433 FREE_FORMAT %ld free bytes in %04lX..%04lX\\\\n
434 USED_FORMAT %s at %04lX (%ld bytes).\\\\n
435 CMDLINE_TAG append=
436 INITRD_TAG initrd:
437 EOT
438 done
439 cat <<EOT
440 #ifdef __MSDOS__
441 #define BOOTISOFULLSIZE $(($BOOTISOSZ+(64*4)+64+16+$ofs))
442 static char bootiso[BOOTISOFULLSIZE];
443 static data_fixup(void)
444 {
445 #asm
446 push ds
447 push ds
448 pop es
449 mov ax,ds
450 sub ax,#0x1000
451 mov ds,ax
452 xor si,si
453 scanlp:
454 dec si
455 jz copydone
456 cmp byte ptr [si+2],#0xEB
457 jne scanlp
458 cmp word ptr [si],#0x5A4D
459 jne scanlp
460 mov cx,#BOOTISOFULLSIZE
461 mov di,#_bootiso
462 cld
463 rep
464 movsb
465 copydone:
466 pop ds
467 #endasm
468 if (!bootiso[0]) {
469 puts("No bootiso data");
470 exit(-1);
471 }
472 }
473 #else
474 #define data_fixup()
475 #endif
476 EOT
477 rm -rf $DATA
478 exit ;;
479 --exe)
480 # --exe mvcom.bin x.com y.exe > xy.exe
481 cat $4 $3 > /tmp/exe$$
482 S=$(stat -c %s /tmp/exe$$)
483 store 2 $(($S%512)) /tmp/exe$$
484 store 4 $((($S+511)/512)) /tmp/exe$$
485 store 14 -16 /tmp/exe$$
486 store 16 -2 /tmp/exe$$
487 store 20 256 /tmp/exe$$
488 store 22 -16 /tmp/exe$$
489 ddq if=$2 bs=1 seek=64 of=/tmp/exe$$ conv=notrunc
490 store 65 $(stat -c %s $3) /tmp/exe$$
491 store 68 $((0x100-0x40+$(stat -c %s $4))) /tmp/exe$$
492 cat /tmp/exe$$
493 rm -f /tmp/exe$$
494 exit ;;
495 esac
497 main()
498 {
499 [ $(id -u) -ne 0 ] && cmd="$0 $@" && exec su -c "$cmd" < /dev/tty
500 append=
501 initrd=
503 while [ "$1" ]; do
504 case "${1/--/-}" in
505 -get) shift
506 uudecode | unlzma | tar xOf - $@
507 exit ;;
508 -a*) append="$2" ; shift 2 ;;
509 -i*) initrd="$2" ; shift 2 ;;
510 -r*|-l*)
511 ISO="$2" ; shift 2
512 [ -z "$1" ] && list || extract $@
513 exit ;;
514 *) cat > /dev/null
515 break
516 esac
517 done
519 [ ! -s "$1" ] && cat 1>&2 <<EOT && exit 1
520 usage: $0 [--list|--read] [--append custom_cmdline ] [ --initrd custom_initrd ] image.iso [--force|--undo|"DOS help message"|filename...]
521 EOT
522 case "${2/--/-}" in
523 -u*|-r*|-w*|-f*)
524 case "$(get 0 $1)" in
525 23117)
526 b=$(get 417 $1 1)
527 n=$(($(get 64 $1) + 0xC0 - ($(get 26 $1 1)*512) - ($b+1)*512))
528 ddq if=$1 bs=512 count=1 skip=$b of=/tmp/hymbr$$
529 restore_hybrid_mbr /tmp/hymbr$$ $1
530 ddq if=/tmp/hymbr$$ of=$1 conv=notrunc
531 rm -f /tmp/hymbr$$
532 if [ $(get 512 $1) -eq 17989 ]; then
533 n=$(($(get 0x25C $1)/512))
534 ddq if=$1 bs=512 seek=44 count=20 skip=$n of=$1 conv=notrunc
535 ddq if=/dev/zero bs=512 seek=9 count=35 of=$1 conv=notrunc
536 ddq if=/dev/zero bs=512 seek=3 count=1 of=$1 conv=notrunc
537 else
538 ddq if=/dev/zero bs=512 seek=1 count=1 of=$1 conv=notrunc
539 ddq if=$1 bs=512 seek=2 count=30 skip=$(($b+1)) of=$1 conv=notrunc
540 ddq if=/dev/zero bs=1 seek=$n count=$((0x8000 - $n)) of=$1 conv=notrunc
541 fi ;;
542 *) ddq if=/dev/zero bs=1k count=32 of=$1 conv=notrunc ;;
543 esac
544 case "${2/--/-}" in
545 -f*)
546 [ "$append$initrd" ] && clear_custom_config $1
547 set -- "$1" "$3" ;;
548 *)
549 clear_custom_config $1
550 exit 0 ;;
551 esac
552 esac
553 case "$(get 0 $1)" in
554 23117) echo "The file $1 is already an EXE file." 1>&2 && exit 1;;
555 0) [ -x /usr/bin/isohybrid ] && isohybrid -entry 2 $1;;
556 esac
558 gpt= ; [ $(get 450 $1) -eq 65262 ] && gpt=1
559 mac= ; [ $(get 2048 $1) -eq 19792 ] && mac=1
560 echo "Read hybrid & tazlito data..."
561 if [ -n "$gpt" ]; then
562 echo "GUID Partition Table..."
563 n=3; [ -n "$mac" ] && n=9 && echo "Apple Partition Table..."
564 ddq if=$1 bs=512 count=$n of=/tmp/hybrid$$
565 ddq if=$1 bs=512 skip=44 count=20 of=/tmp/tazlito$$
566 else
567 ddq if=$1 bs=512 count=1 of=/tmp/hybrid$$
568 ddq if=$1 bs=512 skip=2 count=20 of=/tmp/tazlito$$
569 fi
570 add_win32exe $1 /tmp/hybrid$$
571 add_tazlito_info $1 /tmp/tazlito$$
572 rm -f /tmp/tazlito$$ /tmp/hybrid$$
574 # keep the largest room for the tazlito info file
575 add_dosexe $1
576 add_rootfs $1
577 add_doscom $1
578 add_fdbootstrap $1
579 printf "%d free bytes in %04X..%04X\n" $(($OFS-$HOLE)) $HOLE $OFS
580 store 440 $(date +%s) $1 32
581 [ "$2" ] && echo "$2 " | \
582 ddq bs=1 seek=$((0x7FDE)) count=15 conv=notrunc of=$1
583 if [ $(stat -c %s $1) -gt 34816 ]; then
584 echo "Adding ISO image md5 at 7FF0 (16 bytes) ..."
585 echo -en "$(ddq if=$1 bs=2k skip=16 count=$(($(get 32848 "$1" 4)-16)) | \
586 md5sum | cut -c-32 | sed 's/\(..\)/\\x\1/g')" | \
587 ddq bs=16 seek=2047 conv=notrunc of=$1
588 fi
589 HEAP=$(($(custom_config_sector $1)*2048))
590 if [ "$append$initrd" ]; then
591 echo -n "Adding custom config... "
592 DATA=/tmp/$(basename $0)$$
593 rm -f $DATA > /dev/null
594 isosz=$(stat -c %s $1)
595 [ "$append" ] && echo "append=$append" >> $DATA
596 [ -s "$initrd" ] && echo "initrd:$(stat -c %s $initrd)" >> $DATA &&
597 cat $initrd >> $DATA
598 echo "#!boot $(md5sum $DATA | sed 's/ .*//')" | cat - $DATA | \
599 ddq bs=2k seek=$(custom_config_sector $1) of=$1
600 newsz=$(stat -c %s $1)
601 mb=$(((($newsz -1)/1048576)+1))
602 HEAP=$(($mb*1048576))
603 ddq bs=1048576 seek=$mb count=0 of=$1
604 h=$(get 417 "$1" 1)
605 [ -z "$RECURSIVE_PARTITION" ] || h=0
606 for i in 0 1 2 3 ; do
607 [ $(get $((0x1BE+16*i)) $1 2) == $((0x0080)) ] || continue
608 store $((0x1CA+16*i)) $(($mb*2048-$h)) $1 32
609 store $((0x1C5+16*i)) $(($mb-1)) $1 8
610 done
611 if [ $newsz -gt $isosz ]; then
612 echo "$(($newsz - $isosz)) extra bytes."
613 else
614 echo "$(($isosz - 2048*$(get 32848 $1 4)
615 - $(stat -c %s $DATA) - 24)) bytes free."
616 fi
617 rm -f $DATA > /dev/null
618 fi
619 echo -n "Adding boot checksum..."
620 if [ $(stat -c %s $1) -gt 32768 ]; then
621 n=$(($(get 2 $1) - 1 + ($(get 4 $1) - 1)*512))
622 n=$(($(od -v -N $n -t u2 -w2 -An $1 | \
623 awk '{ i+= $0 } END { print (i % 65536) }') \
624 + $(get $(($n+1)) $1 1)))
625 store 18 $(( (-$n -1) % 65536 )) $1
626 fi
627 echo " done."
628 trailer $1
629 }
631 main "$@" <<EOT