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

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