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

syslinux/isoboot.s: accept user args
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Jun 19 15:46:21 2020 +0000 (2020-06-19)
parents d33c3c211ef8
children a2e843f5d9e4
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 0750 0028
104 EOT
105 i=$((0x600))
106 store 417 $(($i/512)) $1 8 ### isolinux boot sector
107 printf "Moving syslinux hybrid boot record at %04X (336 bytes) ...\n" $i
108 OFS=$SIZE
109 ddn if=$2 bs=1 count=336 of=$1 seek=$i
110 rm -f /tmp/exe$$ /tmp/coff$$
111 if [ -z "$RECURSIVE_PARTITION" -a $(get 454 $1 4) -eq 0 ]; then
112 store 448 $((1+$i/512)) $1 8 ### 446+2 SECTOR
113 store 454 $(($i/512)) $1 32 ### 446+8 OFFSET
114 store 458 $(($(stat -c %s $1)/512)) $1 32 ### 446+12 SIZE
115 fi
116 }
118 add_fdbootstrap()
119 {
120 SIZE=$($0 --get bootfd.bin 2> /dev/null | wc -c)
121 if [ $SIZE -ne 0 ]; then
122 SIZE=$(( $SIZE - 512 )) # sector 2 is data
123 OFS=$(( $OFS - $SIZE ))
124 printf "Adding floppy bootstrap file at %04X (%d bytes) ...\n" $OFS $SIZE
125 $0 --get bootfd.bin | \
126 ddn of=$1 bs=1 count=512 seek=$OFS
127 $0 --get bootfd.bin | \
128 ddn of=$1 bs=1 skip=1024 seek=$((512 + $OFS))
129 store 26 $(($SIZE/512)) $1 8
130 fi
131 }
133 gzsize()
134 {
135 echo $(($(hexdump -C | awk ' {
136 for (i = 17; i > 1; i--) if ($i != "00") break;
137 if (i == 1) {
138 print "0x" $1 " + 1 + 1 - " n
139 exit
140 }
141 n = 17 - i
142 }')))
143 }
145 fileofs()
146 {
147 [ $(get 1024 "$ISO") -eq 35615 ] && x=1024 ||
148 x=$((512*(1+$(get 417 "$ISO" 1))))
149 [ $x -gt 32768 ] && x=6656
150 stub=$(($(get 20 "$ISO") - 0xC0))
151 dosstub=$stub
152 [ $stub -lt 30000 ] && stub=$((0x7FF0)) && dosstub=
153 c=$(custom_config_sector "$ISO")
154 SIZE=0; OFFSET=0
155 case "$1" in
156 win32.exe) [ $x -eq 2048 ] && x=10752
157 [ $x -eq 1024 ] || SIZE=$x;;
158 syslinux.mbr) [ $x -eq 1024 ] || OFFSET=$(($x - 512)); SIZE=336;;
159 flavor.info) [ $(get 22528 "$ISO") -eq 35615 ] && OFFSET=22528
160 [ $x -eq 2048 ] && x=$(get 0x25C "$ISO") &&
161 SIZE=$(get 0x25E "$ISO")
162 [ $(get $x "$ISO") -eq 35615 ] && OFFSET=$x
163 [ $OFFSET -ne 0 ] && [ $SIZE -eq 0 ] &&
164 SIZE=$(ddq bs=512 skip=$(($OFFSET/512)) if="$ISO" | gzsize);;
165 floppy.boot) SIZE=$(($(get 26 "$ISO" 1)*512))
166 OFFSET=$(($(get 64 "$ISO") - 0xC0 - $SIZE));;
167 rootfs.gz) SIZE=$(get 24 "$ISO"); OFFSET=$(($stub - $SIZE));;
168 isoboot.com) OFFSET=$(($(get 64 "$ISO") - 0xC0))
169 SIZE=$(($stub - $(get 24 "$ISO") - $OFFSET));;
170 dosstub) [ "$dosstub" ] && OFFSET=$stub && SIZE=$((0x7FF0 - $OFFSET));;
171 boot.md5) [ $(get 0 "$ISO") -eq 23117 ] &&
172 [ $(get 18 "$ISO") -ne 0 ] &&
173 OFFSET=$((0x7FF0)) && SIZE=16;;
174 fs.iso) OFFSET=$((0x8000))
175 SIZE=$((2048*$c - $OFFSET));;
176 custom.magic) ddq bs=2k skip=$c if="$ISO" | ddq bs=1 count=6 | \
177 grep -q '#!boot' && OFFSET=$((2048*$c)) &&
178 SIZE=39 ;;
179 custom.append) OFFSET=$((2048*$c+47)) &&
180 SIZE=$(ddq bs=2k skip=$c if="$ISO" count=1 | \
181 sed '/^append=/!d;s/^[^=]*=.//' | wc -c);;
182 custom.initrd) x=$(ddq bs=2k skip=$c if="$ISO" count=1 | \
183 sed '/^append=\|^initrd:/!d' | wc -c)
184 OFFSET=$((2048*$c+$x+40))
185 SIZE=$(($(ddq bs=2k skip=$c if="$ISO" count=1 | \
186 sed '/^initrd:/!d;s/.*://') + 0));;
187 esac
188 }
190 trailer()
191 {
192 OFFSET=$(stat -c %s "$1")
193 [ $OFFSET -gt $HEAP ] &&
194 printf "%d free bytes in %04X..%04X\n" $(($OFFSET - $HEAP)) $HEAP $OFFSET
195 if [ $(get 510 "$1") -eq 43605 ]; then
196 echo "MBR partitions :"
197 for i in 0 1 2 3; do
198 SIZE=$(get $((446+12+16*i)) "$1" 4)
199 [ $SIZE -eq 0 ] && continue
200 OFFSET=$(get $((446+8+16*i)) "$1" 4)
201 printf " $i:%08X %08X %02X\n" $OFFSET $SIZE \
202 $(get $((446+4+16*i)) "$1" 1)
203 done
204 if [ $(get 450 "$1") -eq 65262 ]; then
205 echo "EFI partitions :"
206 n=$(get 592 "$1")
207 s=$(get 596 "$1")
208 o=$(($(get 584 "$1")*512))
209 i=0
210 while [ $i -lt $n ]; do
211 f=$(get $(($o+0x20)) "$1" 4)
212 l=$(($(get $(($o+0x28)) "$1" 4)-$f))
213 [ $l -eq 0 ] && break
214 printf " $i:%08X %08X %s\n" $f $(($l+1)) \
215 "$(od -An -N 72 -w72 -j $(($o+0x38)) -t a "$1" \
216 | sed 's/ nul//g;s/ //g;s/ sp//g')"
217 o=$(($o+$s))
218 i=$(($i+1))
219 done
220 fi
221 fi
222 o=2048
223 if [ $(get $o "$1") -eq 19792 ]; then
224 echo "Apple partitions :"
225 i=0
226 while [ $(get $o "$1") -eq 19792 ]; do
227 f=$((0x$(od -An -N 4 -j $(($o+8)) -t x1 "$1" | sed 's/ //g')))
228 l=$((0x$(od -An -N 4 -j $(($o+0x54)) -t x1 "$1" | sed 's/ //g')))
229 printf " $i:%08X %08X %s\n" $f $l \
230 "$(ddq bs=1 skip=$(($o+16)) count=32 if="$1")"
231 o=$(($o+2048))
232 i=$(($i+1))
233 done
234 fi
235 }
237 list()
238 {
239 HEAP=0
240 for f in win32.exe syslinux.mbr flavor.info floppy.boot isoboot.com \
241 rootfs.gz dosstub boot.md5 fs.iso custom.magic custom.append \
242 custom.initrd; do
243 fileofs $f
244 [ $SIZE -le 0 ] && continue
245 [ "${OFFSET:8}" ] && continue
246 [ $OFFSET -lt 0 ] && continue
247 [ $(get $OFFSET "$ISO") -eq 0 ] && continue
248 [ $OFFSET -gt $HEAP ] && [ $(($OFFSET - $HEAP)) -gt 16 ] &&
249 printf "%d free bytes in %04X..%04X\n" $(($OFFSET - $HEAP)) $HEAP $OFFSET
250 [ $OFFSET -ge $HEAP ] && HEAP=$(($OFFSET+$SIZE))
251 printf "$f at %04X ($SIZE bytes).\n" $OFFSET
252 done
253 trailer $ISO
254 }
256 restore_hybrid_mbr()
257 {
258 if [ $(get 0 "$1") -eq 60905 ]; then
259 ddn bs=1 if="$1" of="$1" skip=$((0x1BE)) seek=0 count=3
260 ddn bs=1 skip=$((0x1BE)) count=66 if="$2" | \
261 ddq bs=1 seek=$((0x1BE)) count=66 of="$1"
262 if [ -n "$RECURSIVE_PARTITION" ]; then
263 for i in 0 1 2 3 ; do
264 n=$(get $((0x1C6+16*i)) $1 4)
265 [ $n -eq 0 -o $n -gt 64 ] && continue
266 store $((0x1C0+16*i)) 1 $1 8
267 store $((0x1C6+16*i)) 0 $1 32
268 store $((0x1CA+16*i)) $(($(get $((0x1CA+16*i)) $1 4)+$n)) $1 32
269 done
270 fi
271 fi
272 }
274 extract()
275 {
276 for f in $@; do
277 fileofs $f
278 [ $SIZE -eq 0 ] ||
279 ddq bs=1 count=$SIZE skip=$OFFSET if="$ISO" >$f
280 [ "$f" = "syslinux.mbr" ] && restore_hybrid_mbr "$f" "$ISO"
281 done
282 }
284 custom_config_sector()
285 {
286 get 32848 "$1" 4
287 }
289 clear_custom_config()
290 {
291 start=$(custom_config_sector $1)
292 cnt=$((512 - ($start % 512)))
293 [ $cnt -ne 512 ] &&
294 ddq if=/dev/zero of=$1 bs=2k seek=$start count=$cnt
295 }
296 case "$1" in
297 --build)
298 shift
299 TMP=/tmp/iso2exe$$
300 mkdir -p $TMP/dev
301 cp -a /dev/tty /dev/tty0 $TMP/dev
302 cat init > $TMP/init.exe
303 find $TMP -type f -print0 | xargs -0 chmod +x
304 find $TMP -print0 | xargs -0 touch -t 197001010100.00
305 ( cd $TMP; find dev init.exe | cpio -o -H newc ) | compress > rootfs.gz
306 p=$((4-($(stat -c %s rootfs.gz)%4)))
307 [ $p = 4 ] || dd if=/dev/zero bs=1 count=$p >> rootfs.gz
308 rm -rf $TMP
309 chmod 644 ${@/init/rootfs.gz}
310 chown root.root ${@/init/rootfs.gz}
311 touch -t 197001010100.00 ${@/init/rootfs.gz}
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 ISOBOOT_COM isoboot.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