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

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