wok-current view syslinux/stuff/iso2exe/iso2exe.sh @ rev 24019

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