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

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