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

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