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

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