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

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