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

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