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

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