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

Update some WEB_SITE
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Feb 22 10:45:05 2019 +0100 (2019-02-22)
parents 01b30edcef4e
children 2cb24e6379d5
line source
1 #!/bin/sh
3 ddq()
4 {
5 dd $@ 2> /dev/null
6 }
8 store()
9 {
10 local i
11 local n
12 n=$2; for i in $(seq 8 8 ${4:-16}); do
13 printf '\\\\x%02X' $(($n & 255))
14 n=$(($n >> 8))
15 done | xargs echo -en | ddq bs=1 conv=notrunc of=$3 seek=$(($1))
16 }
18 get()
19 {
20 echo $(od -j $(($1)) -N ${3:-2} -t u${3:-2} -An "$2")
21 }
23 compress()
24 {
25 if [ "$1" ]; then
26 gzip -9 > $1
27 [ "$(which advdef 2> /dev/null)" ] &&
28 advdef -z4 -i100 $1 > /dev/null
29 elif [ "$(which xz 2> /dev/null)" ]; then
30 xz -z -e --format=lzma --lzma1=mode=normal --stdout
31 else
32 lzma e -si -so
33 fi 2> /dev/null
34 }
36 add_rootfs()
37 {
38 TMP=/tmp/iso2exe$$
39 mkdir -p $TMP
40 $0 --get rootfs.gz > $TMP/rootfs.gz
41 SIZE=$(wc -c < $TMP/rootfs.gz)
42 store 24 $SIZE $1
43 OFS=$(( $OFS - $SIZE ))
44 printf "Adding rootfs.gz file at %04X (%d bytes) ...\n" $OFS $SIZE
45 cat $TMP/rootfs.gz | ddq of=$1 bs=1 seek=$OFS conv=notrunc
46 rm -rf $TMP
47 }
49 add_dosexe()
50 {
51 TMP=/tmp/bootiso$$
52 $0 --get bootiso.bin > $TMP 2> /dev/null
53 OFS=$(($(get 20 $TMP) - 0xC0))
54 printf "Adding DOS/EXE stub at %04X (%d bytes) ...\n" $OFS $((0x7FF0 - $OFS))
55 ddq if=$TMP bs=1 skip=$OFS of=$1 seek=$OFS conv=notrunc
56 rm -f $TMP
57 }
59 add_doscom()
60 {
61 SIZE=$($0 --get boot.com | wc -c)
62 OFS=$(( $OFS - $SIZE ))
63 printf "Adding DOS boot file at %04X (%d bytes) ...\n" $OFS $SIZE
64 $0 --get boot.com | ddq of=$1 bs=1 seek=$OFS conv=notrunc
65 store 64 $(($OFS+0xC0)) $1
66 }
68 add_tazlito_info()
69 {
70 HOLE=$OFS
71 [ $(get 0 $2) -eq 35615 ] || return
72 zcat $2 | compress /tmp/rezipped$$.gz
73 n=$(stat -c %s /tmp/rezipped$$.gz)
74 printf "Moving tazlito data record at %04X ($n bytes) ...\n" $OFS
75 ddq if=/tmp/rezipped$$.gz bs=1 of=$1 seek=$OFS conv=notrunc
76 HOLE=$(($HOLE+$n))
77 rm -f /tmp/rezipped$$.gz
78 if [ -n "$gpt" ]; then
79 store $((0x25E)) $n $1
80 store $((0x25C)) $OFS $1
81 fi
82 }
84 add_win32exe()
85 {
86 SIZE=$($0 --get win32.exe 2> /dev/null | tee /tmp/exe$$ | wc -c)
87 [ -n "$gpt" ] && n=1536 || n=512
88 SIZE=$(($SIZE+$n))
89 printf "Adding WIN32 file at %04X (%d bytes) ...\n" 0 $SIZE
90 [ -n "$gpt" ] && printf "Adding GPT at %04X (1024 bytes) ...\n" 512
91 for i in $(seq 396 40 $((356+$(get 0x86 /tmp/exe$$)*40))); do
92 x=$(($n + $(get $i /tmp/exe$$)))
93 store $(($i)) $x /tmp/exe$$ ### section offset
94 done
95 cut=$((0x98+$(get 0x94 /tmp/exe$$))) ### end of header
96 store $((0x94)) $(($n + $cut - 0x98)) /tmp/exe$$
97 ddq if=/tmp/exe$$ of=$1 conv=notrunc bs=1 count=$cut
98 ddq if=/tmp/exe$$ of=$1 conv=notrunc bs=1 skip=$cut seek=$(($n+$cut))
99 printf "Adding bootiso head at %04X...\n" 0
100 $0 --get bootiso.bin 2> /dev/null > /tmp/exe$$
101 ddq if=/tmp/exe$$ of=$1 bs=128 count=1 conv=notrunc ### DOS stub
102 ddq if=/tmp/exe$$ of=$1 bs=1 count=24 seek=$((0x1A0)) skip=$((0x1A0)) conv=notrunc
103 ddq if=$2 bs=1 skip=$((0x1B8)) seek=$((0x1B8)) count=72 of=$1 conv=notrunc
104 store 510 $((0xAA55)) $1
105 i=$SIZE; OFS=$(($SIZE+512))
106 store 417 $(($i/512)) $1 8 ### isolinux boot sector
107 printf "Moving syslinux hybrid boot record at %04X (512 bytes) ...\n" $i
108 ddq if=$2 bs=1 count=512 of=$1 seek=$i conv=notrunc
109 if [ $(get $((0x7C00)) /tmp/exe$$) -eq 60905 ]; then # partition boot code
110 ddq if=/tmp/exe$$ bs=1 count=66 skip=$((0x7DBE)) of=$1 seek=$(($i + 0x1BE)) conv=notrunc
111 ddq if=$1 bs=1 count=3 skip=$i of=$1 seek=$(($i + 0x1BE)) conv=notrunc
112 ddq if=/tmp/exe$$ bs=1 count=3 skip=$((0x7C00)) of=$1 seek=$i conv=notrunc
113 fi
114 rm -f /tmp/exe$$ /tmp/coff$$
115 if [ -z "$RECURSIVE_PARTITION" -a $(get 454 $1 4) -eq 0 ]; then
116 store 448 $((1+$i/512)) $1 8
117 store 454 $(($i/512)) $1 8
118 store 458 $(($(get 458 $1 4) - $i/512)) $1 32
119 fi
120 }
122 add_fdbootstrap()
123 {
124 SIZE=$($0 --get bootfd.bin 2> /dev/null | wc -c)
125 if [ $SIZE -ne 0 ]; then
126 SIZE=$(( $SIZE - 512 )) # sector 2 is data
127 OFS=$(( $OFS - $SIZE ))
128 printf "Adding floppy bootstrap file at %04X (%d bytes) ...\n" $OFS $SIZE
129 $0 --get bootfd.bin | \
130 ddq of=$1 bs=1 count=512 seek=$OFS conv=notrunc
131 $0 --get bootfd.bin | \
132 ddq of=$1 bs=1 skip=1024 seek=$((512 + $OFS)) conv=notrunc
133 store 26 $(($SIZE/512)) $1 8
134 fi
135 }
137 gzsize()
138 {
139 echo $(($(hexdump -C | awk ' {
140 for (i = 17; i > 1; i--) if ($i != "00") break;
141 if (i == 1) {
142 print "0x" $1 " + 1 + 1 - " n
143 exit
144 }
145 n = 17 - i
146 }')))
147 }
149 fileofs()
150 {
151 [ $(get 1024 "$ISO") -eq 35615 ] && x=1024 ||
152 x=$((512*(1+$(get 417 "$ISO" 1))))
153 [ $x -gt 32768 ] && x=6656
154 stub=$(($(get 20 "$ISO") - 0xC0))
155 c=$(custom_config_sector "$ISO")
156 SIZE=0; OFFSET=0
157 case "$1" in
158 win32.exe) [ $x -eq 2048 ] && x=10752
159 [ $x -eq 1024 ] || SIZE=$(($x - 512));;
160 syslinux.mbr) [ $x -eq 1024 ] || OFFSET=$(($x - 512)); SIZE=512;;
161 flavor.info) [ $(get 22528 "$ISO") -eq 35615 ] && OFFSET=22528
162 [ $x -eq 2048 ] && x=$(get 0x25C "$ISO") &&
163 SIZE=$(get 0x25E "$ISO")
164 [ $(get $x "$ISO") -eq 35615 ] && OFFSET=$x
165 [ $OFFSET -ne 0 ] && [ $SIZE -eq 0 ] &&
166 SIZE=$(ddq bs=512 skip=$(($OFFSET/512)) if="$ISO" | gzsize);;
167 floppy.boot) SIZE=$(($(get 26 "$ISO" 1)*512))
168 OFFSET=$(($(get 64 "$ISO") - 0xC0 - $SIZE));;
169 rootfs.gz) SIZE=$(get 24 "$ISO"); OFFSET=$(($stub - $SIZE));;
170 tazboot.com) OFFSET=$(($(get 64 "$ISO") - 0xC0))
171 SIZE=$(($stub - $(get 24 "$ISO") - $OFFSET));;
172 dosstub) OFFSET=$stub; SIZE=$((0x7FF0 - $OFFSET));;
173 boot.md5) [ $(get 0 "$ISO") -eq 23117 ] &&
174 [ $(get 18 "$ISO") -ne 0 ] &&
175 OFFSET=$((0x7FF0)) && SIZE=16;;
176 fs.iso) OFFSET=$((0x8000))
177 SIZE=$((2048*$c - $OFFSET));;
178 custom.magic) ddq bs=2k skip=$c if="$ISO" | ddq bs=1 count=6 | \
179 grep -q '#!boot' && OFFSET=$((2048*$c)) &&
180 SIZE=39 ;;
181 custom.append) OFFSET=$((2048*$c+47)) &&
182 SIZE=$(ddq bs=2k skip=$c if="$ISO" count=1 | \
183 sed '/^append=/!d;s/^[^=]*=.//' | wc -c);;
184 custom.initrd) x=$(ddq bs=2k skip=$c if="$ISO" count=1 | \
185 sed '/^append=\|^initrd:/!d' | wc -c)
186 OFFSET=$((2048*$c+$x+40))
187 SIZE=$(($(ddq bs=2k skip=$c if="$ISO" count=1 | \
188 sed '/^initrd:/!d;s/.*://') + 0));;
189 esac
190 }
192 trailer()
193 {
194 OFFSET=$(stat -c %s "$1")
195 [ $OFFSET -gt $HEAP ] &&
196 printf "%d free bytes in %04X..%04X\n" $(($OFFSET - $HEAP)) $HEAP $OFFSET
197 if [ $(get 510 "$1") -eq 43605 ]; then
198 echo "MBR partitions :"
199 for i in 0 1 2 3; do
200 SIZE=$(get $((446+12+16*i)) "$1" 4)
201 [ $SIZE -eq 0 ] && continue
202 OFFSET=$(get $((446+8+16*i)) "$1" 4)
203 printf " $i:%08X %08X %02X\n" $OFFSET $SIZE \
204 $(get $((446+4+16*i)) "$1" 1)
205 done
206 if [ $(get 450 "$1") -eq 65262 ]; then
207 echo "EFI partitions :"
208 n=$(get 592 "$1")
209 s=$(get 596 "$1")
210 o=$(($(get 584 "$1")*512))
211 i=0
212 while [ $i -lt $n ]; do
213 f=$(get $(($o+0x20)) "$1" 4)
214 l=$(($(get $(($o+0x28)) "$1" 4)-$f))
215 [ $l -eq 0 ] && break
216 printf " $i:%08X %08X %s\n" $f $(($l+1)) \
217 "$(od -An -N 72 -w72 -j $(($o+0x38)) -t a "$1" \
218 | sed 's/ nul//g;s/ //g;s/ sp//g')"
219 o=$(($o+$s))
220 i=$(($i+1))
221 done
222 fi
223 fi
224 o=2048
225 if [ $(get $o "$1") -eq 19792 ]; then
226 echo "Apple partitions :"
227 i=0
228 while [ $(get $o "$1") -eq 19792 ]; do
229 f=$((0x$(od -An -N 4 -j $(($o+8)) -t x1 "$1" | sed 's/ //g')))
230 l=$((0x$(od -An -N 4 -j $(($o+0x54)) -t x1 "$1" | sed 's/ //g')))
231 printf " $i:%08X %08X %s\n" $f $l \
232 "$(ddq bs=1 skip=$(($o+16)) count=32 if="$1")"
233 o=$(($o+2048))
234 i=$(($i+1))
235 done
236 fi
237 }
239 list()
240 {
241 HEAP=0
242 for f in win32.exe syslinux.mbr flavor.info floppy.boot tazboot.com \
243 rootfs.gz dosstub boot.md5 fs.iso custom.magic custom.append \
244 custom.initrd; do
245 fileofs $f
246 [ $SIZE -le 0 ] && continue
247 [ "${OFFSET:8}" ] && continue
248 [ $OFFSET -lt 0 ] && continue
249 [ $(get $OFFSET "$ISO") -eq 0 ] && continue
250 [ $OFFSET -gt $HEAP ] && [ $(($OFFSET - $HEAP)) -gt 16 ] &&
251 printf "%d free bytes in %04X..%04X\n" $(($OFFSET - $HEAP)) $HEAP $OFFSET
252 [ $OFFSET -ge $HEAP ] && HEAP=$(($OFFSET+$SIZE))
253 printf "$f at %04X ($SIZE bytes).\n" $OFFSET
254 done
255 trailer $ISO
256 }
258 restore_hybrid_mbr()
259 {
260 if [ $(get 0 "$1") -eq 60905 ]; then
261 ddq bs=1 conv=notrunc if="$1" of="$1" skip=$((0x1BE)) seek=0 count=3
262 ddq bs=1 skip=$((0x1BE)) count=66 if="$2" | \
263 ddq bs=1 seek=$((0x1BE)) count=66 of="$1" conv=notrunc
264 if [ -n "$RECURSIVE_PARTITION" ]; then
265 for i in 0 1 2 3 ; do
266 n=$(get $((0x1C6+16*i)) $1 4)
267 [ $n -eq 0 -o $n -gt 64 ] && continue
268 store $((0x1C0+16*i)) 1 $1 8
269 store $((0x1C6+16*i)) 0 $1 32
270 store $((0x1CA+16*i)) $(($(get $((0x1CA+16*i)) $1 4)+$n)) $1 32
271 done
272 fi
273 fi
274 }
276 extract()
277 {
278 for f in $@; do
279 fileofs $f
280 [ $SIZE -eq 0 ] ||
281 ddq bs=1 count=$SIZE skip=$OFFSET if="$ISO" >$f
282 [ "$f" == "syslinux.mbr" ] && restore_hybrid_mbr "$f" "$ISO"
283 done
284 }
286 custom_config_sector()
287 {
288 get 32848 "$1" 4
289 }
291 clear_custom_config()
292 {
293 start=$(custom_config_sector $1)
294 cnt=$((512 - ($start % 512)))
295 [ $cnt -ne 512 ] &&
296 ddq if=/dev/zero of=$1 bs=2k seek=$start count=$cnt
297 }
298 case "$1" in
299 --build)
300 shift
301 TMP=/tmp/iso2exe$$
302 mkdir -p $TMP/dev
303 cp -a /dev/tty /dev/tty0 $TMP/dev
304 cat init > $TMP/init.exe
305 find $TMP -type f -print0 | xargs -0 chmod +x
306 find $TMP -print0 | xargs -0 touch -t 197001010100.00
307 ( cd $TMP; find dev init.exe | cpio -o -H newc ) | compress rootfs.gz
308 rm -rf $TMP
309 ls -l $@ rootfs.gz
310 cat >> $0 <<EOM
311 $(tar cf - ${@/init/rootfs.gz} | compress | uuencode -m -)
312 EOT
313 EOM
314 sed -i 's|[ \t]*###.*||;/^case/,/^esac/d' $0
315 exit ;;
316 --get)
317 cat $2
318 exit ;;
319 --array)
320 DATA=/tmp/dataiso$$
321 ddq if=/dev/zero bs=32k count=1 of=$DATA
322 add_win32exe $DATA $2 > /dev/null
323 HSZ=$OFS
324 add_dosexe $DATA > /dev/null
325 add_rootfs $DATA > /dev/null
326 add_doscom $DATA > /dev/null
327 add_fdbootstrap $DATA > /dev/null
328 name=${3:-bootiso}
329 BOOTISOSZ=$((0x8000 - $OFS + $HSZ))
330 cat <<EOT
332 #define $(echo $name | tr '[a-z]' '[A-Z]')SZ $BOOTISOSZ
334 #ifndef __MSDOS__
335 static char $name[] = {
336 /* head */
337 $(hexdump -v -n $HSZ -e '" " 16/1 "0x%02X, "' -e '" /* %04.4_ax */ \n"' $DATA | sed 's/ 0x ,/ /g')
338 /* tail */
339 $(hexdump -v -s $OFS -e '" " 16/1 "0x%02X, "' -e '" /* %04.4_ax */ \n"' $DATA | sed 's/ 0x ,/ /g')
341 /* These strange constants are defined in RFC 1321 as
342 T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64
343 */
344 /* static const uint32_t C_array[64] */
345 EOT
346 while read a b c d; do
347 for i in $a $b $c $d; do
348 echo $i | sed 's/0x\(..\)\(..\)\(..\)\(..\),/0x\4, 0x\3, 0x\2, 0x\1, /'
349 done
350 done <<EOT
351 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
352 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
353 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
354 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
355 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
356 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
357 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
358 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
359 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
360 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
361 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
362 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
363 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
364 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
365 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
366 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
367 EOT
368 cat <<EOT
369 /* static const char P_array[64] */
370 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
371 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
372 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
373 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, /* 4 */
374 /* static const char S_array[16] */
375 7, 12, 17, 22,
376 5, 9, 14, 20,
377 4, 11, 16, 23,
378 6, 10, 15, 21,
379 EOT
381 for mode in data offset ; do
382 ofs=0
383 while read tag str; do
384 if [ "$mode" == "data" ]; then
385 echo -en "$str\0" | hexdump -v -e '" " 16/1 "0x%02X, "' \
386 -e '" /* %04.4_ax */ \n"' | \
387 sed 's/ 0x ,/ /g'
388 else
389 if [ $ofs -eq 0 ]; then
390 cat <<EOT
391 };
392 #endif
394 #define C_array (uint32_t *) ($name + $(($BOOTISOSZ)))
395 #define P_array (char *) ($name + $(($BOOTISOSZ+(64*4))))
396 #define S_array (char *) ($name + $(($BOOTISOSZ+(64*4)+64)))
397 #define ELTORITOOFS 3
398 EOT
399 fi
400 echo "#define $tag $(($BOOTISOSZ+(64*4)+64+16+$ofs))"
401 ofs=$(($(echo -en "$str\0" | wc -c)+$ofs))
402 fi
403 done <<EOT
404 READSECTORERR Read sector failure.
405 USAGE Usage: isohybrid.exe [--list|--read] [--append cmdline] [--initrd file] file.iso [--forced|--undo|--quick|filename...]
406 OPENERR Can't open the iso file.
407 ELTORITOERR No EL TORITO SPECIFICATION signature.
408 CATALOGERR Invalid boot catalog.
409 HYBRIDERR No isolinux.bin hybrid signature.
410 SUCCESSMSG Now you can create a USB key with your .iso file.\\\\nSimply rename it to an .exe file and run it.
411 FORCEMSG You can add --forced to proceed anyway.
412 MD5MSG Computing md5sum...
413 UNINSTALLMSG Uninstall done.
414 OPENINITRDERR Can't open the initrd file.
415 ALREADYEXEERR Already an EXE file.
416 WIN32_EXE win32.exe
417 SYSLINUX_MBR syslinux.mbr
418 FLAVOR_INFO flavor.info
419 FLOPPY_BOOT floppy.boot
420 TAZBOOT_COM tazboot.com
421 ROOTFS_GZ rootfs.gz
422 DOSSTUB dosstub
423 BOOT_MD5 boot.md5
424 FS_ISO fs.iso
425 CUSTOM_MAGIC custom.magic
426 CUSTOM_APPEND custom.append
427 CUSTOM_INITRD custom.initrd
428 CUSTOM_HEADER #!boot 00000000000000000000000000000000\\\\n
429 FREE_FORMAT %ld free bytes in %04lX..%04lX\\\\n
430 USED_FORMAT %s at %04lX (%ld bytes).\\\\n
431 CMDLINE_TAG append=
432 INITRD_TAG initrd:
433 EOT
434 done
435 cat <<EOT
436 #ifdef __MSDOS__
437 #define BOOTISOFULLSIZE $(($BOOTISOSZ+(64*4)+64+16+$ofs))
438 static char bootiso[BOOTISOFULLSIZE];
439 static data_fixup(void)
440 {
441 #asm
442 push ds
443 push ds
444 pop es
445 mov ax,ds
446 sub ax,#0x1000
447 mov ds,ax
448 xor si,si
449 scanlp:
450 dec si
451 jz copydone
452 cmp byte ptr [si+2],#0xEB
453 jne scanlp
454 cmp word ptr [si],#0x5A4D
455 jne scanlp
456 mov cx,#BOOTISOFULLSIZE
457 mov di,#_bootiso
458 cld
459 rep
460 movsb
461 copydone:
462 pop ds
463 #endasm
464 if (!bootiso[0]) {
465 puts("No bootiso data");
466 exit(-1);
467 }
468 }
469 #else
470 #define data_fixup()
471 #endif
472 EOT
473 rm -rf $DATA
474 exit ;;
475 --exe)
476 # --exe mvcom.bin x.com y.exe > xy.exe
477 cat $4 $3 > /tmp/exe$$
478 S=$(stat -c %s /tmp/exe$$)
479 store 2 $(($S%512)) /tmp/exe$$
480 store 4 $((($S+511)/512)) /tmp/exe$$
481 store 14 -16 /tmp/exe$$
482 store 16 -2 /tmp/exe$$
483 store 20 256 /tmp/exe$$
484 store 22 -16 /tmp/exe$$
485 ddq if=$2 bs=1 seek=64 of=/tmp/exe$$ conv=notrunc
486 store 65 $(stat -c %s $3) /tmp/exe$$
487 store 68 $((0x100-0x40+$(stat -c %s $4))) /tmp/exe$$
488 cat /tmp/exe$$
489 rm -f /tmp/exe$$
490 exit ;;
491 esac
493 main()
494 {
495 [ $(id -u) -ne 0 ] && cmd="$0 $@" && exec su -c "$cmd" < /dev/tty
496 append=
497 initrd=
499 while [ "$1" ]; do
500 case "${1/--/-}" in
501 -get) shift
502 uudecode | unlzma | tar xOf - $@
503 exit ;;
504 -a*) append="$2" ; shift 2 ;;
505 -i*) initrd="$2" ; shift 2 ;;
506 -r*|-l*)
507 ISO="$2" ; shift 2
508 [ -z "$1" ] && list || extract $@
509 exit ;;
510 *) cat > /dev/null
511 break
512 esac
513 done
515 [ ! -s "$1" ] && cat 1>&2 <<EOT && exit 1
516 usage: $0 [--list|--read] [--append custom_cmdline ] [ --initrd custom_initrd ] image.iso [--force|--undo|"DOS help message"|filename...]
517 EOT
518 case "${2/--/-}" in
519 -u*|-r*|-w*|-f*)
520 case "$(get 0 $1)" in
521 23117)
522 b=$(get 417 $1 1)
523 n=$(($(get 64 $1) + 0xC0 - ($(get 26 $1 1)*512) - ($b+1)*512))
524 ddq if=$1 bs=512 count=1 skip=$b of=/tmp/hymbr$$
525 restore_hybrid_mbr /tmp/hymbr$$ $1
526 ddq if=/tmp/hymbr$$ of=$1 conv=notrunc
527 rm -f /tmp/hymbr$$
528 if [ $(get 512 $1) -eq 17989 ]; then
529 n=$(($(get 0x25C $1)/512))
530 ddq if=$1 bs=512 seek=44 count=20 skip=$n of=$1 conv=notrunc
531 ddq if=/dev/zero bs=512 seek=9 count=35 of=$1 conv=notrunc
532 ddq if=/dev/zero bs=512 seek=3 count=1 of=$1 conv=notrunc
533 else
534 ddq if=/dev/zero bs=512 seek=1 count=1 of=$1 conv=notrunc
535 ddq if=$1 bs=512 seek=2 count=30 skip=$(($b+1)) of=$1 conv=notrunc
536 ddq if=/dev/zero bs=1 seek=$n count=$((0x8000 - $n)) of=$1 conv=notrunc
537 fi ;;
538 *) ddq if=/dev/zero bs=1k count=32 of=$1 conv=notrunc ;;
539 esac
540 case "${2/--/-}" in
541 -f*)
542 [ "$append$initrd" ] && clear_custom_config $1
543 set -- "$1" "$3" ;;
544 *)
545 clear_custom_config $1
546 exit 0 ;;
547 esac
548 esac
549 case "$(get 0 $1)" in
550 23117) echo "The file $1 is already an EXE file." 1>&2 && exit 1;;
551 0) [ -x /usr/bin/isohybrid ] && isohybrid -entry 2 $1;;
552 esac
554 gpt= ; [ $(get 450 $1) -eq 65262 ] && gpt=1
555 mac= ; [ $(get 2048 $1) -eq 19792 ] && mac=1
556 echo "Read hybrid & tazlito data..."
557 if [ -n "$gpt" ]; then
558 echo "GUID Partition Table..."
559 n=3; [ -n "$mac" ] && n=9 && echo "Apple Partition Table..."
560 ddq if=$1 bs=512 count=$n of=/tmp/hybrid$$
561 ddq if=$1 bs=512 skip=44 count=20 of=/tmp/tazlito$$
562 else
563 ddq if=$1 bs=512 count=1 of=/tmp/hybrid$$
564 ddq if=$1 bs=512 skip=2 count=20 of=/tmp/tazlito$$
565 fi
566 add_win32exe $1 /tmp/hybrid$$
567 add_tazlito_info $1 /tmp/tazlito$$
568 rm -f /tmp/tazlito$$ /tmp/hybrid$$
570 # keep the largest room for the tazlito info file
571 add_dosexe $1
572 add_rootfs $1
573 add_doscom $1
574 add_fdbootstrap $1
575 printf "%d free bytes in %04X..%04X\n" $(($OFS-$HOLE)) $HOLE $OFS
576 store 440 $(date +%s) $1 32
577 [ "$2" ] && echo "$2 " | \
578 ddq bs=1 seek=$((0x7FDE)) count=15 conv=notrunc of=$1
579 if [ $(stat -c %s $1) -gt 34816 ]; then
580 echo "Adding ISO image md5 at 7FF0 (16 bytes) ..."
581 echo -en "$(ddq if=$1 bs=2k skip=16 count=$(($(get 32848 "$1" 4)-16)) | \
582 md5sum | cut -c-32 | sed 's/\(..\)/\\x\1/g')" | \
583 ddq bs=16 seek=2047 conv=notrunc of=$1
584 fi
585 HEAP=$(($(custom_config_sector $1)*2048))
586 if [ "$append$initrd" ]; then
587 echo -n "Adding custom config... "
588 DATA=/tmp/$(basename $0)$$
589 rm -f $DATA > /dev/null
590 isosz=$(stat -c %s $1)
591 [ "$append" ] && echo "append=$append" >> $DATA
592 [ -s "$initrd" ] && echo "initrd:$(stat -c %s $initrd)" >> $DATA &&
593 cat $initrd >> $DATA
594 echo "#!boot $(md5sum $DATA | sed 's/ .*//')" | cat - $DATA | \
595 ddq bs=2k seek=$(custom_config_sector $1) of=$1
596 newsz=$(stat -c %s $1)
597 mb=$(((($newsz -1)/1048576)+1))
598 HEAP=$(($mb*1048576))
599 ddq bs=1048576 seek=$mb count=0 of=$1
600 h=$(get 417 "$1" 1)
601 [ -z "$RECURSIVE_PARTITION" ] || h=0
602 for i in 0 1 2 3 ; do
603 [ $(get $((0x1BE+16*i)) $1 2) == $((0x0080)) ] || continue
604 store $((0x1CA+16*i)) $(($mb*2048-$h)) $1 32
605 store $((0x1C5+16*i)) $(($mb-1)) $1 8
606 done
607 if [ $newsz -gt $isosz ]; then
608 echo "$(($newsz - $isosz)) extra bytes."
609 else
610 echo "$(($isosz - 2048*$(get 32848 $1 4)
611 - $(stat -c %s $DATA) - 24)) bytes free."
612 fi
613 rm -f $DATA > /dev/null
614 fi
615 echo -n "Adding boot checksum..."
616 if [ $(stat -c %s $1) -gt 32768 ]; then
617 n=$(($(get 2 $1) - 1 + ($(get 4 $1) - 1)*512))
618 n=$(($(od -v -N $n -t u2 -w2 -An $1 | \
619 awk '{ i+= $0 } END { print (i % 65536) }') \
620 + $(get $(($n+1)) $1 1)))
621 store 18 $(( (-$n -1) % 65536 )) $1
622 fi
623 echo " done."
624 trailer $1
625 }
627 main "$@" <<EOT