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

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