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

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