wok-6.x view syslinux/stuff/iso2exe/iso2exe.sh @ rev 24228

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