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

syslinux/iso2exe: fix gpt/efi case
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sat Feb 16 12:52:08 2019 +0100 (23 months ago)
parents 02994416f017
children fcd3d43eadad
line source
1 #!/bin/sh
3 ddq()
4 {
5 dd $@ 2> /dev/null
6 }
8 store()
9 {
10 local i
11 n=$2; for i in $(seq 8 8 ${4:-16}); do
12 printf '\\\\x%02X' $(($n & 255))
13 n=$(($n >> 8))
14 done | xargs echo -en | ddq bs=1 conv=notrunc of=$3 seek=$(($1))
15 }
17 get()
18 {
19 echo $(od -j $(($1)) -N ${3:-2} -t u${3:-2} -An "$2")
20 }
22 compress()
23 {
24 if [ "$1" ]; then
25 gzip -9 > $1
26 [ "$(which advdef 2> /dev/null)" ] &&
27 advdef -z4 -i100 $1 > /dev/null
28 elif [ "$(which xz 2> /dev/null)" ]; then
29 xz -z -e --format=lzma --lzma1=mode=normal --stdout
30 else
31 lzma e -si -so
32 fi 2> /dev/null
33 }
35 add_rootfs()
36 {
37 TMP=/tmp/iso2exe$$
38 mkdir -p $TMP
39 $0 --get rootfs.gz > $TMP/rootfs.gz
40 SIZE=$(wc -c < $TMP/rootfs.gz)
41 store 24 $SIZE $1
42 OFS=$(( $OFS - $SIZE ))
43 printf "Adding rootfs.gz file at %04X (%d bytes) ...\n" $OFS $SIZE
44 cat $TMP/rootfs.gz | ddq of=$1 bs=1 seek=$OFS conv=notrunc
45 rm -rf $TMP
46 }
48 add_dosexe()
49 {
50 TMP=/tmp/bootiso$$
51 $0 --get bootiso.bin > $TMP 2> /dev/null
52 OFS=$(($(get 20 $TMP) - 0xC0))
53 printf "Adding DOS/EXE stub at %04X (%d bytes) ...\n" $OFS $((0x7FF0 - $OFS))
54 ddq if=$TMP bs=1 skip=$OFS of=$1 seek=$OFS conv=notrunc
55 rm -f $TMP
56 }
58 add_doscom()
59 {
60 SIZE=$($0 --get boot.com | wc -c)
61 OFS=$(( $OFS - $SIZE ))
62 printf "Adding DOS boot file at %04X (%d bytes) ...\n" $OFS $SIZE
63 $0 --get boot.com | ddq of=$1 bs=1 seek=$OFS conv=notrunc
64 store 64 $(($OFS+0xC0)) $1
65 }
67 add_tazlito_info()
68 {
69 HOLE=$OFS
70 [ $(get 0 $2) -eq 35615 ] || return
71 zcat $2 | compress /tmp/rezipped$$.gz
72 n=$(stat -c %s /tmp/rezipped$$.gz)
73 printf "Moving tazlito data record at %04X ($n bytes) ...\n" $OFS
74 ddq if=/tmp/rezipped$$.gz bs=1 of=$1 seek=$OFS conv=notrunc
75 HOLE=$(($HOLE+$n))
76 rm -f /tmp/rezipped$$.gz
77 if [ -n "$gpt" ]; then
78 store $((0x25E)) $n $1
79 store $((0x25C)) $OFS $1
80 fi
81 }
83 add_win32exe()
84 {
85 SIZE=$($0 --get win32.exe 2> /dev/null | tee /tmp/exe$$ | wc -c)
86 [ -n "$gpt" ] && SIZE=$(($SIZE+1024))
87 [ -n "$mac" ] && SIZE=$(($SIZE+3072))
88 printf "Adding WIN32 file at %04X (%d bytes) ...\n" 0 $SIZE
89 ddq if=/tmp/exe$$ of=$1 conv=notrunc
90 if [ -n "$gpt" ]; then
91 printf "Adding GPT at %04X (1024 bytes) ...\n" 512
92 ddq if=$2 bs=512 skip=1 of=$1 seek=1 conv=notrunc
93 i=3; [ -n "$mac" ] && i=9
94 ddq if=/tmp/exe$$ bs=512 skip=1 of=$1 seek=$i conv=notrunc
95 OFS=$((512*($i-1)))
96 for i in 18C 1B4 1DC ; do # always 3 UPX sections
97 store $((0x$i)) $(($OFS + $(get 0x$i $1))) $1
98 done
99 fi
100 printf "Adding bootiso head at %04X...\n" 0
101 $0 --get bootiso.bin 2> /dev/null > /tmp/exe$$
102 ddq if=/tmp/exe$$ of=$1 bs=128 count=1 conv=notrunc
103 store $((0x94)) $((0xE0 - 12*8)) $1
104 store $((0xF4)) $((16 - 12)) $1
105 ddq if=$1 of=/tmp/coff$$ bs=1 skip=$((0x178)) count=$((0x88))
106 ddq if=/tmp/coff$$ of=$1 conv=notrunc bs=1 seek=$((0x178 - 12*8))
107 ddq if=/tmp/exe$$ of=$1 bs=1 count=24 seek=$((0x1A0)) skip=$((0x1A0)) conv=notrunc
108 ddq if=$2 bs=1 skip=$((0x1B8)) seek=$((0x1B8)) count=72 of=$1 conv=notrunc
109 store 510 $((0xAA55)) $1
110 i=$SIZE; OFS=$(($SIZE+512))
111 [ -n "$mac" ] && OFS=$SIZE && i=1536
112 store 417 $(($i/512)) $1 8
113 printf "Moving syslinux hybrid boot record at %04X (512 bytes) ...\n" $i
114 ddq if=$2 bs=1 count=512 of=$1 seek=$i conv=notrunc
115 if [ $(get $((0x7C00)) /tmp/exe$$) -eq 60905 ]; then
116 ddq if=/tmp/exe$$ bs=1 count=66 skip=$((0x7DBE)) of=$1 seek=$(($i + 0x1BE)) conv=notrunc
117 ddq if=$1 bs=1 count=3 skip=$i of=$1 seek=$(($i + 0x1BE)) conv=notrunc
118 ddq if=/tmp/exe$$ bs=1 count=3 skip=$((0x7C00)) of=$1 seek=$i conv=notrunc
119 fi
120 rm -f /tmp/exe$$ /tmp/coff$$
121 if [ -z "$RECURSIVE_PARTITION" -a $(get 454 $1 4) -eq 0 ]; then
122 store 448 $((1+$i/512)) $1 8
123 store 454 $(($i/512)) $1 8
124 store 458 $(($(get 458 $1 4) - $i/512)) $1 32
125 fi
126 }
128 add_fdbootstrap()
129 {
130 SIZE=$($0 --get bootfd.bin 2> /dev/null | wc -c)
131 if [ $SIZE -ne 0 ]; then
132 SIZE=$(( $SIZE - 512 )) # sector 2 is data
133 OFS=$(( $OFS - $SIZE ))
134 printf "Adding floppy bootstrap file at %04X (%d bytes) ...\n" $OFS $SIZE
135 $0 --get bootfd.bin | \
136 ddq of=$1 bs=1 count=512 seek=$OFS conv=notrunc
137 $0 --get bootfd.bin | \
138 ddq of=$1 bs=1 skip=1024 seek=$((512 + $OFS)) conv=notrunc
139 store 26 $(($SIZE/512)) $1 8
140 fi
141 }
143 gzsize()
144 {
145 echo $(($(hexdump -C | awk ' {
146 for (i = 17; i > 1; i--) if ($i != "00") break;
147 if (i == 1) {
148 print "0x" $1 " + 1 + 1 - " n
149 exit
150 }
151 n = 17 - i
152 }')))
153 }
155 fileofs()
156 {
157 [ $(get 1024 "$ISO") -eq 35615 ] && x=1024 ||
158 x=$((512*(1+$(get 417 "$ISO" 1))))
159 [ $x -gt 32768 ] && x=6656
160 stub=$(($(get 20 "$ISO") - 0xC0))
161 c=$(custom_config_sector "$ISO")
162 SIZE=0; OFFSET=0
163 case "$1" in
164 win32.exe) [ $x -eq 2048 ] && x=10752
165 [ $x -eq 1024 ] || SIZE=$(($x - 512));;
166 syslinux.mbr) [ $x -eq 1024 ] || OFFSET=$(($x - 512)); SIZE=512;;
167 flavor.info) [ $(get 22528 "$ISO") -eq 35615 ] && OFFSET=22528
168 [ $x -eq 2048 ] && x=$(get 0x25C "$ISO") &&
169 SIZE=$(get 0x25E "$ISO")
170 [ $(get $x "$ISO") -eq 35615 ] && OFFSET=$x
171 [ $OFFSET -ne 0 ] && [ $SIZE -eq 0 ] &&
172 SIZE=$(ddq bs=512 skip=$(($OFFSET/512)) if="$ISO" | gzsize);;
173 floppy.boot) SIZE=$(($(get 26 "$ISO" 1)*512))
174 OFFSET=$(($(get 64 "$ISO") - 0xC0 - $SIZE));;
175 rootfs.gz) SIZE=$(get 24 "$ISO"); OFFSET=$(($stub - $SIZE));;
176 tazboot.com) OFFSET=$(($(get 64 "$ISO") - 0xC0))
177 SIZE=$(($stub - $(get 24 "$ISO") - $OFFSET));;
178 dosstub) OFFSET=$stub; SIZE=$((0x7FF0 - $OFFSET));;
179 boot.md5) [ $(get 0 "$ISO") -eq 23117 ] &&
180 [ $(get 18 "$ISO") -ne 0 ] &&
181 OFFSET=$((0x7FF0)) && SIZE=16;;
182 fs.iso) OFFSET=$((0x8000))
183 SIZE=$((2048*$c - $OFFSET));;
184 custom.magic) ddq bs=2k skip=$c if="$ISO" | ddq bs=1 count=6 | \
185 grep -q '#!boot' && OFFSET=$((2048*$c)) &&
186 SIZE=39 ;;
187 custom.append) OFFSET=$((2048*$c+47)) &&
188 SIZE=$(ddq bs=2k skip=$c if="$ISO" count=1 | \
189 sed '/^append=/!d;s/^[^=]*=.//' | wc -c);;
190 custom.initrd) x=$(ddq bs=2k skip=$c if="$ISO" count=1 | \
191 sed '/^append=\|^initrd:/!d' | wc -c)
192 OFFSET=$((2048*$c+$x+40))
193 SIZE=$(($(ddq bs=2k skip=$c if="$ISO" count=1 | \
194 sed '/^initrd:/!d;s/.*://') + 0));;
195 esac
196 }
198 trailer()
199 {
200 OFFSET=$(stat -c %s "$1")
201 [ $OFFSET -gt $HEAP ] &&
202 printf "%d free bytes in %04X..%04X\n" $(($OFFSET - $HEAP)) $HEAP $OFFSET
203 if [ $(get 510 "$1") -eq 43605 ]; then
204 echo "MBR partitions :"
205 for i in 0 1 2 3; do
206 SIZE=$(get $((446+12+16*i)) "$1" 4)
207 [ $SIZE -eq 0 ] && continue
208 OFFSET=$(get $((446+8+16*i)) "$1" 4)
209 printf " $i:%08X %08X %02X\n" $OFFSET $SIZE \
210 $(get $((446+4+16*i)) "$1" 1)
211 done
212 if [ $(get 450 "$1") -eq 65262 ]; then
213 echo "EFI partitions :"
214 n=$(get 592 "$1")
215 s=$(get 596 "$1")
216 o=$(($(get 584 "$1")*512))
217 i=0
218 while [ $i -lt $n ]; do
219 f=$(get $(($o+0x20)) "$1" 4)
220 l=$(($(get $(($o+0x28)) "$1" 4)-$f))
221 [ $l -eq 0 ] && break
222 printf " $i:%08X %08X %s\n" $f $(($l+1)) \
223 "$(od -An -N 72 -w72 -j $(($o+0x38)) -t a "$1" \
224 | sed 's/ nul//g;s/ //g;s/ sp//g')"
225 o=$(($o+$s))
226 i=$(($i+1))
227 done
228 fi
229 fi
230 o=2048
231 if [ $(get $o "$1") -eq 19792 ]; then
232 echo "Apple partitions :"
233 i=0
234 while [ $(get $o "$1") -eq 19792 ]; do
235 f=$((0x$(od -An -N 4 -j $(($o+8)) -t x1 "$1" | sed 's/ //g')))
236 l=$((0x$(od -An -N 4 -j $(($o+0x54)) -t x1 "$1" | sed 's/ //g')))
237 printf " $i:%08X %08X %s\n" $f $l \
238 "$(ddq bs=1 skip=$(($o+16)) count=32 if="$1")"
239 o=$(($o+2048))
240 i=$(($i+1))
241 done
242 fi
243 }
245 list()
246 {
247 HEAP=0
248 for f in win32.exe syslinux.mbr flavor.info floppy.boot tazboot.com \
249 rootfs.gz dosstub boot.md5 fs.iso custom.magic custom.append \
250 custom.initrd; do
251 fileofs $f
252 [ $SIZE -le 0 ] && continue
253 [ "${OFFSET:8}" ] && continue
254 [ $OFFSET -lt 0 ] && continue
255 [ $(get $OFFSET "$ISO") -eq 0 ] && continue
256 [ $OFFSET -gt $HEAP ] && [ $(($OFFSET - $HEAP)) -gt 16 ] &&
257 printf "%d free bytes in %04X..%04X\n" $(($OFFSET - $HEAP)) $HEAP $OFFSET
258 [ $OFFSET -ge $HEAP ] && HEAP=$(($OFFSET+$SIZE))
259 printf "$f at %04X ($SIZE bytes).\n" $OFFSET
260 done
261 trailer $ISO
262 }
264 restore_hybrid_mbr()
265 {
266 if [ $(get 0 "$1") -eq 60905 ]; then
267 ddq bs=1 conv=notrunc if="$1" of="$1" skip=$((0x1BE)) seek=0 count=3
268 ddq bs=1 skip=$((0x1BE)) count=66 if="$2" | \
269 ddq bs=1 seek=$((0x1BE)) count=66 of="$1" conv=notrunc
270 if [ -n "$RECURSIVE_PARTITION" ]; then
271 for i in 0 1 2 3 ; do
272 n=$(get $((0x1C6+16*i)) $1 4)
273 [ $n -eq 0 -o $n -gt 64 ] && continue
274 store $((0x1C0+16*i)) 1 $1 8
275 store $((0x1C6+16*i)) 0 $1 32
276 store $((0x1CA+16*i)) $(($(get $((0x1CA+16*i)) $1 4)+$n)) $1 32
277 done
278 fi
279 fi
280 }
282 extract()
283 {
284 for f in $@; do
285 fileofs $f
286 [ $SIZE -eq 0 ] ||
287 ddq bs=1 count=$SIZE skip=$OFFSET if="$ISO" >$f
288 [ "$f" == "syslinux.mbr" ] && restore_hybrid_mbr "$f" "$ISO"
289 done
290 }
292 custom_config_sector()
293 {
294 get 32848 "$1" 4
295 }
297 clear_custom_config()
298 {
299 start=$(custom_config_sector $1)
300 cnt=$((512 - ($start % 512)))
301 [ $cnt -ne 512 ] &&
302 ddq if=/dev/zero of=$1 bs=2k seek=$start count=$cnt
303 }
304 case "$1" in
305 --build)
306 shift
307 TMP=/tmp/iso2exe$$
308 mkdir -p $TMP/dev
309 cp -a /dev/tty /dev/tty0 $TMP/dev
310 cat init > $TMP/init.exe
311 find $TMP -type f -print0 | xargs -0 chmod +x
312 find $TMP -print0 | xargs -0 touch -t 197001010100.00
313 ( cd $TMP; find dev init.exe | cpio -o -H newc ) | compress rootfs.gz
314 rm -rf $TMP
315 ls -l $@ rootfs.gz
316 cat >> $0 <<EOM
317 $(tar cf - ${@/init/rootfs.gz} | compress | uuencode -m -)
318 EOT
319 EOM
320 sed -i '/^case/,/^esac/d' $0
321 exit ;;
322 --get)
323 cat $2
324 exit ;;
325 --array)
326 DATA=/tmp/dataiso$$
327 ddq if=/dev/zero bs=32k count=1 of=$DATA
328 add_win32exe $DATA $2 > /dev/null
329 HSZ=$OFS
330 add_dosexe $DATA > /dev/null
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 ddq if=$2 bs=1 seek=64 of=/tmp/exe$$ conv=notrunc
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 ddq if=/tmp/hymbr$$ of=$1 conv=notrunc
533 rm -f /tmp/hymbr$$
534 if [ $(get 512 $1) -eq 17989 ]; then
535 n=$(($(get 0x25C $1)/512))
536 ddq if=$1 bs=512 seek=44 count=20 skip=$n of=$1 conv=notrunc
537 ddq if=/dev/zero bs=512 seek=9 count=35 of=$1 conv=notrunc
538 ddq if=/dev/zero bs=512 seek=3 count=1 of=$1 conv=notrunc
539 else
540 ddq if=/dev/zero bs=512 seek=1 count=1 of=$1 conv=notrunc
541 ddq if=$1 bs=512 seek=2 count=30 skip=$(($b+1)) of=$1 conv=notrunc
542 ddq if=/dev/zero bs=1 seek=$n count=$((0x8000 - $n)) of=$1 conv=notrunc
543 fi ;;
544 *) ddq if=/dev/zero bs=1k count=32 of=$1 conv=notrunc ;;
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_dosexe $1
578 add_rootfs $1
579 add_doscom $1
580 add_fdbootstrap $1
581 printf "%d free bytes in %04X..%04X\n" $(($OFS-$HOLE)) $HOLE $OFS
582 store 440 $(date +%s) $1 32
583 [ "$2" ] && echo "$2 " | \
584 ddq bs=1 seek=$((0x7FDE)) count=15 conv=notrunc of=$1
585 if [ $(stat -c %s $1) -gt 34816 ]; then
586 echo "Adding ISO image md5 at 7FF0 (16 bytes) ..."
587 echo -en "$(ddq if=$1 bs=2k skip=16 count=$(($(get 32848 "$1" 4)-16)) | \
588 md5sum | cut -c-32 | sed 's/\(..\)/\\x\1/g')" | \
589 ddq bs=16 seek=2047 conv=notrunc of=$1
590 fi
591 HEAP=$(($(custom_config_sector $1)*2048))
592 if [ "$append$initrd" ]; then
593 echo -n "Adding custom config... "
594 DATA=/tmp/$(basename $0)$$
595 rm -f $DATA > /dev/null
596 isosz=$(stat -c %s $1)
597 [ "$append" ] && echo "append=$append" >> $DATA
598 [ -s "$initrd" ] && echo "initrd:$(stat -c %s $initrd)" >> $DATA &&
599 cat $initrd >> $DATA
600 echo "#!boot $(md5sum $DATA | sed 's/ .*//')" | cat - $DATA | \
601 ddq bs=2k seek=$(custom_config_sector $1) of=$1
602 newsz=$(stat -c %s $1)
603 mb=$(((($newsz -1)/1048576)+1))
604 HEAP=$(($mb*1048576))
605 ddq bs=1048576 seek=$mb count=0 of=$1
606 h=$(get 417 "$1" 1)
607 [ -z "$RECURSIVE_PARTITION" ] || h=0
608 for i in 0 1 2 3 ; do
609 [ $(get $((0x1BE+16*i)) $1 2) == $((0x0080)) ] || continue
610 store $((0x1CA+16*i)) $(($mb*2048-$h)) $1 32
611 store $((0x1C5+16*i)) $(($mb-1)) $1 8
612 done
613 if [ $newsz -gt $isosz ]; then
614 echo "$(($newsz - $isosz)) extra bytes."
615 else
616 echo "$(($isosz - 2048*$(get 32848 $1 4)
617 - $(stat -c %s $DATA) - 24)) bytes free."
618 fi
619 rm -f $DATA > /dev/null
620 fi
621 echo -n "Adding boot checksum..."
622 if [ $(stat -c %s $1) -gt 32768 ]; then
623 n=$(($(get 2 $1) - 1 + ($(get 4 $1) - 1)*512))
624 n=$(($(od -v -N $n -t u2 -w2 -An $1 | \
625 awk '{ i+= $0 } END { print (i % 65536) }') \
626 + $(get $(($n+1)) $1 1)))
627 store 18 $(( (-$n -1) % 65536 )) $1
628 fi
629 echo " done."
630 trailer $1
631 }
633 main "$@" <<EOT