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

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