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

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