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

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