tazlito view tazlito @ rev 490

Store location of 2nd eltorito boot file
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Mar 16 23:20:47 2018 +0100 (2018-03-16)
parents 4cfb991effc5
children 94ef1a590b5d
line source
1 #!/bin/sh
2 # TazLito - SliTaz Live Tool.
3 #
4 # Tazlito is a tool to help generate and configure SliTaz Live CD
5 # ISO images. You can create a custom distro in one command from a list of
6 # packages, extract an existing ISO image to hack it, create a new initramfs
7 # and/or a new ISO. Most commands must be run by root, except the stats
8 # and the configuration file manipulation.
9 #
10 # (C) 2007-2017 SliTaz - GNU General Public License.
11 #
12 # Authors: see the AUTHORS file
13 #
15 VERSION='6.0'
17 . /lib/libtaz.sh
18 # Force to use Busybox cpio and wget
19 alias cpio='busybox cpio'
20 alias wget='busybox wget'
22 # Tazlito configuration variables to be shorter
23 # and to use words rather than numbers.
24 COMMAND="$1"
25 LIST_NAME="$2"
26 TMP_DIR="/tmp/tazlito-$$-$RANDOM"
27 TMP_MNT="/media/tazlito-$$-$RANDOM"
28 TOP_DIR="$(pwd)"
29 INITRAMFS='rootfs.gz'
30 LOCALSTATE='/var/lib/tazpkg'
31 INSTALLED="$LOCALSTATE/installed"
32 CACHE_DIR='/var/cache/tazpkg'
33 MIRROR="$LOCALSTATE/mirror"
34 DEFAULT_MIRROR="http://mirror1.slitaz.org/packages/$(cat /etc/slitaz-release)/"
36 log='/var/log/tazlito.log'
37 if [ $(id -u) -eq 0 ]; then
38 newline > $log
39 fi
42 cleanup() {
43 if [ -d "$TMP_MNT" ]; then
44 umount $TMP_MNT
45 rmdir $TMP_MNT
46 rm -f /boot
47 fi
48 [ -d "$tmp_dir" ] && rm -r "$tmp_dir"
49 [ -d "$flv_dir" ] && rm -r "$flv_dir"
50 }
53 # Report error and finish work
55 die() {
56 emsg "<n>$(longline "$@")<n> " >&2
57 cleanup
58 exit 1
59 }
62 # Run Tazlito module
63 module() {
64 local mod="$1"; shift
65 /usr/libexec/tazlito/$mod $@
66 }
70 # Try to include config file, continue if command is gen-config or exit.
71 # The main config used by default is in /etc/tazlito.
72 # Specific distro config file can be put in a distro tree.
73 for i in /etc/tazlito "$TOP_DIR"; do
74 [ -f "$i/tazlito.conf" ] && CONFIG_FILE="$i/tazlito.conf"
75 done
77 [ -z "$CONFIG_FILE" -a "$COMMAND" != 'gen-config' ] && \
78 die 'Unable to find any configuration file.' \
79 'Please read the docs or run `tazlito gen-config` to get an empty config file.'
81 . $CONFIG_FILE
83 # While Tazpkg is not used the default mirror URL file does not exist
84 # and user can't recharge the list of flavors.
85 [ $(id -u) -eq 0 -a ! -f "$MIRROR" ] && echo "$DEFAULT_MIRROR" > $MIRROR
87 # Set the rootfs and rootcd path with $DISTRO
88 # configuration variable.
89 ROOTFS="$DISTRO/rootfs"
90 ROOTCD="$DISTRO/rootcd"
95 #####################
96 # Tazlito functions #
97 #####################
100 # Print the usage.
102 usage () {
103 [ $(basename $0) == 'tazlito' ] && cat <<EOT
105 SliTaz Live Tool - Version: $(colorize 34 "$VERSION")
107 $(boldify "Usage:") tazlito [command] [list|iso|flavor|compression] [dir|iso]
109 $(boldify "Commands:")
110 EOT
111 optlist "\
112 usage Print this short usage.
113 stats View Tazlito and distro configuration statistics.
114 list-addfiles Simple list of additional files in the rootfs.
115 gen-config Generate a new configuration file for a distro.
116 configure Configure the main config file or a specific tazlito.conf.
117 gen-iso Generate a new ISO from a distro tree.
118 gen-initiso Generate a new initramfs and ISO from the distro tree.
119 list-flavors List all flavors available on the mirror.
120 gen-flavor Generate a new Live CD description.
121 gen-liveflavor Generate a Live CD description from current system.
122 show-flavor Show Live CD description.
123 get-flavor Get a flavor's list of packages (--noup to skip update).
124 upgrade-flavor Update package list to the latest available versions.
125 extract-flavor Extract a *.flavor file into $FLAVORS_REPOSITORY.
126 pack-flavor Pack (and update) a flavor from $FLAVORS_REPOSITORY.
127 iso2flavor Create a flavor file from a SliTaz ISO image.
128 extract-distro Extract an ISO to a directory and rebuild Live CD tree.
129 gen-distro Generate a Live distro and ISO from a list of packages.
130 clean-distro Remove all files generated by gen-distro.
131 check-distro Help to check if distro is ready to release.
132 writeiso Use running system to generate a bootable ISO (with /home).
133 merge Merge multiple rootfs into one ISO.
134 deduplicate Deduplicate files in a tree.
135 repack Recompress rootfs into ISO with maximum ratio.
136 build-loram Generate a Live CD for low-RAM systems.
137 emu-iso Emulate an ISO image with QEMU.
138 burn-iso Burn ISO image to a CD-ROM using Wodim.
139 "
140 }
143 yesorno() {
144 local answer
145 echo -n "$1 (y=yes, n=no) [$2] " >&2
146 case "$DEFAULT_ANSWER" in
147 Y|y) answer="y";;
148 N|n) answer="n";;
149 *)
150 read -t 30 answer
151 [ -z "$answer" ] && answer="$2"
152 [ "$answer" != 'y' -a "$answer" != 'n' ] && answer="$2"
153 ;;
154 esac
155 echo "$answer"
156 }
159 field() {
160 grep "^$1" "$2" | \
161 case "$1" in
162 Desc*) sed 's|^.*: *||';;
163 *) sed 's/.*: \([0-9KMG\.]*\).*/\1/';;
164 esac
165 }
168 todomsg() {
169 echo -e "\\033[70G[ \\033[1;31mTODO\\033[0;39m ]"
170 }
173 # Download a file from this mirror
175 download_from() {
176 local i mirrors="$1"
177 shift
178 for i in $mirrors; do
179 case "$i" in
180 http://*|ftp://*|https://*)
181 wget -c $i$@ && break;;
182 *)
183 cp $i/$1 . && break;;
184 esac
185 done
186 }
189 # Download a file trying all mirrors
191 download() {
192 local i
193 for i in $(cat $MIRROR $LOCALSTATE/undigest/*/mirror 2>/dev/null); do
194 download_from "$i" "$@" && break
195 done
196 }
199 # Execute hooks provided by some packages
201 genisohooks() {
202 local here="$(pwd)"
203 for i in $(ls $ROOTFS/etc/tazlito/*.$1 2>/dev/null); do
204 cd $ROOTFS
205 . $i $ROOTCD
206 done
207 cd "$here"
208 }
211 # Echo the package name if the tazpkg is already installed
213 installed_package_name() {
214 local tazpkg="$1" package VERSION EXTRAVERSION
216 # Try to find package name and version to be able
217 # to repack it from installation
218 # A dash (-) can exist in name *and* in version
219 package=${tazpkg%-*}
220 i=$package
221 while true; do
222 unset VERSION EXTRAVERSION
223 eval $(grep -s ^VERSION= $INSTALLED/$i/receipt)
224 eval $(grep -s ^EXTRAVERSION= $INSTALLED/$i/receipt)
225 if [ "$i-$VERSION$EXTRAVERSION" == "$tazpkg" ]; then
226 echo $i
227 break
228 fi
229 case "$i" in
230 *-*);;
231 *) break;;
232 esac
233 i=${i%-*}
234 done
235 }
238 # Check for the rootfs tree.
240 check_rootfs() {
241 [ -d "$ROOTFS/etc" ] || die 'Unable to find a distro rootfs...'
242 }
245 # Check for the boot dir into the root CD tree.
247 verify_rootcd() {
248 [ -d "$ROOTCD/boot" ] || die 'Unable to find the rootcd boot directory...'
249 }
251 get() {
252 od -v -j $1 -N ${3:-4} -t u${3:-4} -w${3:-4} -An "$2" 2>/dev/null | sed 's/ *//'
253 }
255 set64() {
256 for i in $(seq 0 8 24 ; seq 24 -8 0); do
257 printf '\\\\x%02X' $((($2 >> $i) & 255))
258 done | xargs echo -en | dd bs=1 conv=notrunc of=$3 seek=$1 2>/dev/null
259 }
262 # Force size and location in the 2nd eltorito boot file (/boot/isolinux/efi.img)
264 fix_efi_boot_img_size() {
265 i=$((2048*$(stat -m $2/boot/isolinux/boot.cat | sed q)+102))
266 set -- $1 $i $3 $i $2
267 for i in $(seq 0 8 24); do
268 printf '\\\\x%02X' $((($3 >> $i) & 255))
269 done | xargs echo -en | dd bs=1 conv=notrunc of=$1 seek=$2 2>/dev/null
270 set -- $1 $((4+$4)) $(stat -m $5/boot/isolinux/efi.img | sed q)
271 for i in $(seq 0 8 24); do
272 printf '\\\\x%02X' $((($3 >> $i) & 255))
273 done | xargs echo -en | dd bs=1 conv=notrunc of=$1 seek=$2 2>/dev/null
274 }
277 # Force the size for the /boot/isolinux/efi.img file
279 fix_efi_img_size() {
280 local e=$((0x809C))
281 for i in BOOT ISOLINUX EFI.IMG ; do
282 local sz=$(get $(($e+10)) "$2")
283 e=$(($(get $(($e+2)) "$2") * 2048))
284 while [ $sz -gt 0 ]; do
285 local len=$(get $e "$2" 2)
286 [ "$(dd if="$2" bs=1 skip=$(($e+33)) count=${#i} \
287 2>/dev/null)" == "$i" ] && continue 2
288 [ $len -eq 0 ] && break
289 sz=$(($sz-$len))
290 e=$(($e+$len))
291 done
292 return # not found
293 done
294 set64 $(($e+10)) $1 "$2"
295 }
298 # create /boot/isolinux/efi.img to share EFI files with the iso image
300 fixup_uefi_part() {
301 local n
302 [ -s $2/boot/isolinux/efi.img ] || return
304 # Build file list tree
306 ( cd $2 ; find efi -type f -exec echo \
307 'stat -c "$(stat -m {} | sed q) %s f %n" {}' \; | sh | sort -n ) \
308 >/tmp/fatfiles$$
309 n=$(sed 's/ .*//;q' /tmp/fatfiles$$)
310 ( cd $2; find efi ) | awk -v n=$n 'BEGIN { FS="/" }
311 NF > 1 {
312 d[NF $NF]+=2
313 p[NF $NF]=$0
314 b[a++]=NF $NF
315 if (NF>2) d[NF-1 $(NF-1)]++
316 }
317 END {
318 while (a-- > 0) if (d[i=b[a]] > 2) {
319 n-= j =int((d[i]+63)/64)
320 print n " " j*2048 " d " p[i]
321 }
322 print n-1 " 2048 d efi"
323 }' >>/tmp/fatfiles$$
324 sort -n /tmp/fatfiles$$ | awk '{ if (s == 0) s=$1;
325 print ($1-s)+2 " " $2 " " $3 " " $4 }' > /tmp/fatfiles$$.tmp
326 mv -f /tmp/fatfiles$$.tmp /tmp/fatfiles$$
328 # Build fat12 or fat16
330 if [ $(awk '{n+=int(($2+2047)/2048)}END{print n}' /tmp/fatfiles$$) \
331 -lt 4000 ]; then
332 sed '1s/.*/4087 2049 x\n1 1 x/' /tmp/fatfiles$$ | while read c s x; do
333 seq $(($c+1)) $((($s-1)/2048+$c))
334 echo 4095
335 done | awk 'BEGIN { printf "0 "}
336 {
337 if (n == 0) n=$1
338 else {
339 printf "%02X %02X %02X ",n%256,
340 ($1%16)*16+(n/256),$1/16
341 n=0
342 }
343 }
344 END {
345 if (n != 0) printf "FF 0F 00 "
346 print " |"
347 }' | hexdump -R > /tmp/fatbin-12-$$
348 else
349 sed '1s/.*/65527 2049 x\n1 1 x/' /tmp/fatfiles$$ | while read c s x; do
350 seq $(($c+1)) $((($s-1)/2048+$c))
351 echo 65535
352 done | awk 'BEGIN { printf "0 "}
353 {
354 printf "%02X %02X ",$1%256,$1/256
355 }
356 END {
357 print " |"
358 }' | hexdump -R > /tmp/fatbin-16-$$
359 fi
361 # align fat to 512 bytes
362 dd of=$(ls /tmp/fatbin-*-$$) count=0 bs=512 \
363 seek=$((($(stat -c %s /tmp/fatbin-*-$$)-1)/512+1)) 2>/dev/null
365 # build directory records
367 awk '
368 BEGIN {
369 c=2
370 b16="/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0"
371 b14="/0/0/0/0/0/0/0/0/0/0/0/0/0/0"
372 print "EFI /x10" b14 "/x0" c "/0/0/x08/0/0"
373 for (n=i=0; i<63; i++) print b16 b16
374 }
375 {
376 clu[n]=$1
377 size[n]=$2
378 type[n]=$3
379 name[n]=$4
380 n++
381 }
382 END {
383 path="efi"
384 d21="/x10" b14 "/x%02X/x%02X/0/x08/0/0\n"
385 up[0]=0
386 s=1
387 do {
388 l=split(path,x,"/")
389 up[l]=c
390 printf ". " d21,c%256,c/256
391 printf ".. " d21,up[l-1]%256,up[l-1]/256
392 for (i=s,e=2; i<n; i++) {
393 if (substr(name[i],1,length(path)) != path ||
394 split(substr(name[i],length(path)+2),x,"/") > 1)
395 continue
396 split(toupper(x[1]),x,".")
397 if (length(x[1]) >= 8) printf substr(x[1],1,8)
398 else printf x[1] substr(" ",1,8-length(x[1]))
399 if (length(x[2]) >= 3) printf substr(x[2],1,3)
400 else printf x[2] substr(" ",1,3-length(x[2]))
401 if (type[i] == "d") printf "/x10"; else printf "/0"
402 printf b14 "/x%02X/x%02X",clu[i]%256,clu[i]/256
403 printf "/x%02X/x%02X/x%02X/x%02X\n",size[i]%256,
404 (size[i]/256)%256,(size[i]/256/256)%256,
405 size[i]/256/256/256
406 e++
407 }
408 while (e++ < 64) print b16 b16
409 path=name[s]
410 c=clu[s]
411 } while (type[s++] == "d")
412 }' < /tmp/fatfiles$$ | while read line; do
413 echo "$line" | sed 's| |/x20|g;s|/|\\\\|g' | xargs echo -en
414 done > /tmp/fatdir$$
416 # build boot record
418 fat=$(($(stat -c %s /tmp/fatbin-*-$$)/512))
419 r=$((4-($fat+$fat+$(stat -c %s /tmp/fatdir$$)/512)%4))
420 dd if=/dev/zero bs=512 count=$r of=/tmp/fatbr$$ 2> /dev/null
421 echo -en '\x55\xAA' | \
422 dd of=/tmp/fatbr$$ seek=510 bs=1 conv=notrunc 2> /dev/null
423 n=$(stat -m $2/boot/isolinux/efi.img | sed q)
424 fat="$(printf "%02X %02X" $(($fat%256)) $((($fat>>8)%256)))"
425 s=$((($(stat -m $(ls -r $2/boot/rootfs* | sed q) | sed q) - $n)*4))
426 if [ $s -gt 65535 ]; then
427 size="00 00"
428 size32="$(printf "%02X %02X %02X %02X" $(($s%256)) \
429 $((($s>>8)%256)) $((($s>>16)%256)) $((($s>>24)%256)) )"
430 else
431 size="$(printf "%02X %02X" $(($s%256)) $((($s>>8)%256)) )"
432 size32="00 00 00 00"
433 fi
434 t=32; [ -s /tmp/fatbin-16-$$ ] && t=36
435 hexdump -R <<EOT | dd conv=notrunc of=/tmp/fatbr$$ 2> /dev/null
436 0 eb 3c 90 53 6c 69 54 61 7a 00 00 00 02 04 $r 00 |
437 0 02 40 00 $size f8 $fat 20 00 40 00 00 00 00 00 |
438 0 $size32 80 00 29 00 00 00 00 4e 4f 20 4e 41 |
439 0 4d 45 20 20 20 20 46 41 54 31 $t 20 20 20 cd 18 |
440 0 cd 19 eb fa |
441 EOT
443 # patch efi.img stub
445 cat /tmp/fatbr$$ /tmp/fatbin-*-$$ /tmp/fatbin-*-$$ /tmp/fatdir$$ | \
446 dd of=$1 conv=notrunc bs=2k seek=$n 2>/dev/null
447 fix_efi_img_size $(($s*512)) $1
448 fix_efi_boot_img_size $1 $2 $s
449 rm -f /tmp/fat*$$
451 # Cleanup cache
452 umount $2
453 mount -o loop,ro $1 $2
454 }
457 # allocate efi.img stub to share EFI files in the EFI boot partition
459 alloc_uefi_part() {
460 local basedir=$(dirname "$1")/..
461 local clusters=$({
462 [ -d $basedir/efi ] &&
463 find $basedir/efi -type f -exec stat -c "%s" {} \;
464 while [ -s "$1" ]; do
465 local efifile
466 case "$1" in
467 *taz) efifile=bootia32.efi ;;
468 *taz64) efifile=bootx64.efi ;;
469 esac
470 if [ ! -s $basedir/efi/boot/$efifile ] &&
471 [ $(get $((0x82)) "$1") == $((0x4550)) ]; then
472 stat -c "%s" "$1"
473 mkdir -p $basedir/efi/boot 2> /dev/null
474 ln "$1" $basedir/efi/boot/$efifile
475 fi
476 shift
477 done; } | awk '{ n+=int(($1+2047)/2048) } END { print n }')
478 [ ${clusters:-0} -eq 0 ] && return
479 local dclust=$( (cd $basedir; find efi -type d 2>/dev/null) | awk '
480 BEGIN {
481 FS="/"
482 }
483 NF > 1 {
484 d[NF $NF]+=2
485 d[NF-1 $(NF-1)]++
486 }
487 END {
488 for (i in d)
489 n+=int((d[i]+63)/64)
490 print n
491 }')
492 clusters=$(($clusters+$dclust))
493 if [ $clusters -lt 4000 ]; then
494 # reserved + fat*2 + root dir + dirs
495 count=$(((1 + (($clusters*3+1023)/1024)*2+3)/4+1 + $dclust ))
496 else
497 # reserved + fat*2 + root dir + dirs
498 count=$(((1 + (($clusters+255)/256)*2+3)/4 + 1 + $dclust ))
499 fi
500 dd if=/dev/zero bs=2k of=$basedir/boot/isolinux/efi.img \
501 count=$count 2> /dev/null
502 }
505 # isolinux.conf doesn't know the kernel version.
506 # We name the kernel image 'bzImage'.
507 # isolinux/syslinux first tries the '64' suffix with a 64bits cpu.
509 make_bzImage_hardlink() {
510 if [ -e ${1:-.}/vmlinuz*slitaz ]; then
511 rm -f ${1:-.}/bzImage 2>/dev/null
512 ln ${1:-.}/vmlinuz*slitaz ${1:-.}/bzImage
513 fi
514 if [ -e ${1:-.}/vmlinuz*slitaz64 ]; then
515 rm -f ${1:-.}/bzImage64 2> /dev/null
516 ln ${1:-.}/vmlinuz*slitaz64 ${1:-.}/bzImage64
517 fi
518 }
521 create_iso() {
522 cd $2
523 deduplicate
525 rm -rf $2/boot/grub*
526 make_bzImage_hardlink $2/boot
527 alloc_uefi_part $(ls -r $2/boot/vmlinuz*slitaz*)
529 cat > /tmp/cdsort$$ <<EOT
530 $PWD/boot/isolinux 100
531 $(ls -r $PWD/boot/rootfs* | awk 'BEGIN{n=149} { print $1 " " n-- }')
532 $(ls $PWD/boot/bzImage* | awk 'BEGIN{n=200} { print $1 " " n-- }')
533 $(find $PWD/efi -type f 2>/dev/null | awk 'BEGIN{n=299} { print $1 " " n-- }')
534 $PWD/boot/isolinux/efi.img 300
535 $PWD/boot/isolinux/isolinux.bin 399
536 $PWD/boot/isolinux/boot.cat 400
537 EOT
539 action 'Computing md5...'
540 touch boot/isolinux/boot.cat
541 find * -type f ! -name md5sum ! -name 'vmlinuz-*' -exec md5sum {} \; | \
542 sort -k 2 > md5sum
543 status
545 cd - >/dev/null
546 title 'Generating ISO image'
548 _ 'Generating %s' "$1"
549 uefi="$(cd $2 ; ls boot/isolinux/efi.img 2> /dev/null)"
550 genisoimage -R -o $1 -hide-rr-moved -sort /tmp/cdsort$$ \
551 -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat \
552 -no-emul-boot -boot-load-size 4 -boot-info-table \
553 ${uefi:+-eltorito-alt-boot -efi-boot $uefi -no-emul-boot} \
554 -V "${VOLUM_NAME:-SliTaz}" -p "${PREPARED:-$(id -un)}" \
555 -volset "SliTaz $SLITAZ_VERSION" -input-charset utf-8 \
556 -A "tazlito $VERSION/$(genisoimage --version)" \
557 -copyright README -P "www.slitaz.org" -no-pad $2
558 rm -f /tmp/cdsort$$
559 dd if=/dev/zero bs=2k count=16 >> $1 2> /dev/null
561 mkdir /tmp/mnt$$
562 mount -o loop,ro $1 /tmp/mnt$$
563 fixup_uefi_part $1 /tmp/mnt$$
564 for i in boot/isolinux/isolinux.bin boot/isolinux/boot.cat \
565 ${uefi:+boot/isolinux/efi.img} ; do
566 sed -i "s|.* $i|$( cd /tmp/mnt$$ ; md5sum $i)|" $2/md5sum
567 done
568 dd if=$2/md5sum of=$1 conv=notrunc bs=2k \
569 seek=$(stat -m /tmp/mnt$$/md5sum | sed q) 2> /dev/null
570 umount -d /tmp/mnt$$
571 rmdir /tmp/mnt$$
573 if [ -s '/etc/tazlito/info' ]; then
574 if [ $(stat -c %s /etc/tazlito/info) -lt $(( 31*1024 )) ]; then
575 action 'Storing ISO info...'
576 dd if=/etc/tazlito/info bs=1k seek=1 of=$1 conv=notrunc 2>/dev/null
577 status
578 fi
579 fi
581 if [ -x '/usr/bin/isohybrid' ]; then
582 action 'Creating hybrid ISO...'
583 isohybrid $1 $([ -n "$uefi" ] || echo -entry 2) 2>/dev/null
584 status
585 fi
587 if [ -x '/usr/bin/iso2exe' ]; then
588 echo 'Creating EXE header...'
589 /usr/bin/iso2exe $1 2>/dev/null
590 fi
591 }
594 # Generate a new ISO image using isolinux.
596 gen_livecd_isolinux() {
597 # Some packages may want to alter iso
598 genisohooks iso
599 [ ! -f "$ROOTCD/boot/isolinux/isolinux.bin" ] && die 'Unable to find isolinux binary.'
601 # Set date for boot msg.
602 if grep -q 'XXXXXXXX' "$ROOTCD/boot/isolinux/isolinux.cfg"; then
603 DATE=$(date +%Y%m%d)
604 action 'Setting build date to: %s...' "$DATE"
605 sed -i "s/XXXXXXXX/$DATE/" "$ROOTCD/boot/isolinux/isolinux.cfg"
606 status
607 fi
609 cd $DISTRO
610 create_iso $ISO_NAME.iso $ROOTCD
612 action 'Creating the ISO md5sum...'
613 md5sum $ISO_NAME.iso > $ISO_NAME.md5
614 status
616 separator
617 # Some packages may want to alter final iso
618 genisohooks final
619 }
622 lzma_history_bits() {
623 #
624 # This generates an ISO which boots with Qemu but gives
625 # rootfs errors in frugal or liveUSB mode.
626 #
627 # local n
628 # local sz
629 # n=20 # 1Mb
630 # sz=$(du -sk $1 | cut -f1)
631 # while [ $sz -gt 1024 -a $n -lt 28 ]; do
632 # n=$(( $n + 1 ))
633 # sz=$(( $sz / 2 ))
634 # done
635 # echo $n
636 echo ${LZMA_HISTORY_BITS:-24}
637 }
640 lzma_switches() {
641 local proc_num=$(grep -sc '^processor' /proc/cpuinfo)
642 echo "-d$(lzma_history_bits $1) -mt${proc_num:-1} -mc1000"
643 }
646 lzma_set_size() {
647 # Update size field for lzma'd file packed using -si switch
648 return # Need to fix kernel code?
650 local n i
651 n=$(unlzma < $1 | wc -c)
652 for i in $(seq 1 8); do
653 printf '\\\\x%02X' $(($n & 255))
654 n=$(($n >> 8))
655 done | xargs echo -en | dd of=$1 conv=notrunc bs=1 seek=5 2>/dev/null
656 }
659 align_to_32bits() {
660 local size=$(stat -c %s ${1:-/dev/null})
661 [ $((${size:-0} & 3)) -ne 0 ] &&
662 dd if=/dev/zero bs=1 count=$((4 - ($size & 3))) >> $1 2>/dev/null
663 }
666 dogzip() {
667 gzip -9 > $1
668 [ -x /usr/bin/advdef ] && advdef -qz4 $1
669 }
672 # Pack rootfs
674 pack_rootfs() {
675 ( cd $1; find . -print | cpio -o -H newc ) | \
676 case "$COMPRESSION" in
677 none)
678 _ 'Creating %s without compression...' 'initramfs'
679 cat > $2
680 ;;
681 gzip)
682 _ 'Creating %s with gzip compression...' 'initramfs'
683 dogzip $2
684 ;;
685 *)
686 _ 'Creating %s with lzma compression...' 'initramfs'
687 lzma e -si -so $(lzma_switches $1) > $2
688 lzma_set_size $2
689 ;;
690 esac
691 align_to_32bits $2
692 echo 1 > /tmp/rootfs
693 }
696 # Compression functions for writeiso.
698 write_initramfs() {
699 case "$COMPRESSION" in
700 lzma)
701 _n 'Creating %s with lzma compression...' "$INITRAMFS"
702 cpio -o -H newc | lzma e -si -so $(lzma_switches) > "/$INITRAMFS"
703 align='y'
704 lzma_set_size "/$INITRAMFS"
705 ;;
706 gzip)
707 _ 'Creating %s with gzip compression...' "$INITRAMFS"
708 cpio -o -H newc | dogzip "/$INITRAMFS"
709 ;;
710 *)
711 # align='y'
712 _ 'Creating %s without compression...' "$INITRAMFS"
713 cpio -o -H newc > "/$INITRAMFS"
714 ;;
715 esac < /tmp/list
716 [ "$align" == 'y' -a -z "$noalign" ] && align_to_32bits "/$INITRAMFS"
717 echo 1 > /tmp/rootfs
718 }
721 # Deduplicate files (MUST be on the same filesystem).
723 deduplicate() {
724 find "${@:-.}" -type f -size +0c -xdev -exec stat -c '%s-%a-%u-%g %i %h %n' {} \; | sort | \
725 (
726 save=0; hardlinks=0; old_attr=""; old_inode=""; old_link=""; old_file=""
727 while read attr inode link file; do
728 [ -L "$file" ] && continue
729 if [ "$attr" == "$old_attr" -a "$inode" != "$old_inode" ]; then
730 if cmp "$file" "$old_file" >/dev/null 2>&1 ; then
731 rm -f "$file"
732 if ln "$old_file" "$file" 2>/dev/null; then
733 inode="$old_inode"
734 [ "$link" -eq 1 ] && hardlinks=$(($hardlinks+1)) &&
735 save="$(($save+(${attr%%-*}+512)/1024))"
736 else
737 cp -a "$old_file" "$file"
738 fi
739 fi
740 fi
741 old_attr="$attr" ; old_inode="$inode" ; old_file="$file"
742 done
743 _ '%s Kbytes saved in %s duplicate files.' "$save" "$hardlinks"
744 )
746 find "$@" -type l -xdev -exec stat -c '%s-%u-%g-TARGET- %i %h %n' {} \; | sort | \
747 (
748 old_attr=""; hardlinks=0;
749 while read attr inode link file; do
750 attr="${attr/-TARGET-/-$(readlink $file)}"
751 if [ "$attr" == "$old_attr" ]; then
752 if [ "$inode" != "$old_inode" ]; then
753 rm -f "$file"
754 if ln "$old_file" "$file" 2>/dev/null; then
755 [ "$link" -eq 1 ] && hardlinks=$(($hardlinks+1))
756 else
757 cp -a "$old_file" "$file"
758 fi
759 fi
760 else
761 old_file="$file"
762 old_attr="$attr"
763 old_inode="$inode"
764 fi
765 done
766 _ '%s duplicate symlinks.' "$hardlinks"
767 )
768 }
771 # Generate a new initramfs from the root filesystem.
773 gen_initramfs() {
774 # Just in case CTRL+c
775 rm -f $DISTRO/gen
777 # Some packages may want to alter rootfs
778 genisohooks rootfs
779 cd $1
781 # Normalize file time
782 find $1 -newer $1 -exec touch -hr $1 {} \;
784 # Link duplicate files
785 deduplicate
787 # Use lzma if installed. Display rootfs size in realtime.
788 rm -f /tmp/rootfs 2>/dev/null
789 pack_rootfs . $DISTRO/$(basename $1).gz &
790 sleep 2
791 echo -en "\nFilesystem size:"
792 while [ ! -f /tmp/rootfs ]; do
793 sleep 1
794 echo -en "\\033[18G$(du -sh $DISTRO/$(basename $1).gz | awk '{print $1}') "
795 done
796 echo -e "\n"
797 rm -f /tmp/rootfs
798 cd $DISTRO
799 mv $(basename $1).gz $ROOTCD/boot
800 }
803 distro_sizes() {
804 if [ -n "$start_time" ]; then
805 time=$(($(date +%s) - $start_time))
806 sec=$time
807 div=$(( ($time + 30) / 60))
808 [ "$div" -ne 0 ] && min="~ ${div}m"
809 _ 'Build time : %ss %s' "$sec" "$min"
810 fi
811 cat <<EOT
812 Build date : $(date +%Y%m%d)
813 Packages : $(ls -1 $ROOTFS*$INSTALLED/*/receipt | wc -l)
814 Rootfs size : $(du -csh $ROOTFS*/ | awk 'END { print $1 }')
815 Initramfs size : $(du -csh $ROOTCD/boot/rootfs*.gz | awk 'END { print $1 }')
816 ISO image size : $(du -sh $ISO_NAME.iso | awk '{ print $1 }')
817 EOT
818 footer "Image is ready: $ISO_NAME.iso"
819 }
822 # Print ISO and rootfs size.
824 distro_stats() {
825 title 'Distro statistics: %s' "$DISTRO"
826 distro_sizes
827 }
830 # Create an empty configuration file.
832 empty_config_file() {
833 cat >> tazlito.conf <<"EOF"
834 # tazlito.conf: Tazlito (SliTaz Live Tool) configuration file.
835 #
837 # Name of the ISO image to generate.
838 ISO_NAME=""
840 # ISO image volume name.
841 VOLUM_NAME="SliTaz"
843 # Name of the preparer.
844 PREPARED="$USER"
846 # Path to the packages repository and the packages.list.
847 PACKAGES_REPOSITORY=""
849 # Path to the distro tree to gen-distro from a list of packages.
850 DISTRO=""
852 # Path to the directory containing additional files
853 # to copy into the rootfs and rootcd of the LiveCD.
854 ADDFILES="$DISTRO/addfiles"
856 # Default answer for binary question (Y or N)
857 DEFAULT_ANSWER="ASK"
859 # Compression utility (lzma, gzip or none)
860 COMPRESSION="lzma"
861 EOF
862 }
865 # Extract rootfs.gz somewhere
867 extract_rootfs() {
868 # Detect compression format: *.lzma.cpio, *.gzip.cpio, or *.cpio
869 # First part (lzcat or zcat) may not fail, but cpio will fail on incorrect format
870 (cd "$2"; lzcat "$1" | cpio -idm --quiet 2>/dev/null) && return
871 (cd "$2"; zcat "$1" | cpio -idm --quiet 2>/dev/null) && return
872 (cd "$2"; cat "$1" | cpio -idm --quiet 2>/dev/null)
873 }
876 # Extract flavor file to temp directory
878 extract_flavor() {
879 # Input: $1 - flavor name to extract;
880 # $2 = absent/empty: just extract 'outer layer'
881 # $2 = 'full': also extract 'inner' rootcd and rootfs archives, make files rename
882 # $2 = 'info': as 'full' and also make 'info' file to put into ISO
883 # Output: temp dir path where flavor was extracted
884 local f="$1.flavor" from to infos="$1.desc"
885 [ -f "$f" ] || die "File '$f' not found"
886 local dir="$(mktemp -d)"
887 zcat "$f" | (cd $dir; cpio -i --quiet >/dev/null)
889 if [ -n "$2" ]; then
890 cd $dir
892 [ -s "$1.receipt" ] && infos="$infos\n$1.receipt"
894 for i in rootcd rootfs; do
895 [ -f "$1.$i" ] || continue
896 mkdir "$i"
897 zcat "$1.$i" | (cd "$i"; cpio -idm --quiet 2>/dev/null)
898 zcat "$1.$i" | cpio -tv 2>/dev/null > "$1.list$i"; infos="$infos\n$1.list$i"
899 rm "$1.$i"
900 done
901 touch -t 197001010100.00 "$1.*"
902 # Info to be stored inside ISO
903 [ "$2" == info ] && echo -e $infos | cpio -o -H newc | dogzip info
904 rm $1.list*
906 # Renames
907 while read from to; do
908 [ -f "$from" ] || continue
909 mv "$from" "$to"
910 done <<EOT
911 $1.nonfree non-free.list
912 $1.pkglist packages.list
913 $1-distro.sh distro.sh
914 $1.receipt receipt
915 $1.mirrors mirrors
916 $1.desc description
917 EOT
918 fi
920 echo $dir
921 }
924 # Pack flavor file from temp directory
926 pack_flavor() {
927 (cd "$1"; ls | grep -v err | cpio -o -H newc) | dogzip "$2.flavor"
928 }
931 # Remove duplicate files
933 files_match() {
934 if [ -d "$1" ]; then
935 return 1
937 elif [ -L "$1" ] && [ -L "$2" ]; then
938 [ "$(readlink "$1")" == "$(readlink "$2")" ] && return 0
940 elif [ -f "$1" ] && [ -f "$2" ]; then
941 cmp -s "$1" "$2" && return 0
943 [ "$(basename "$3")" == 'volatile.cpio.gz' ] &&
944 [ "$(dirname $(dirname "$3"))" == ".$INSTALLED" ] &&
945 return 0
947 elif [ "$(ls -l "$1"|cut -c1-10)$(stat -c '%a:%u:%g:%t:%T' "$1")" == \
948 "$(ls -l "$2"|cut -c1-10)$(stat -c '%a:%u:%g:%t:%T' "$2")" ]; then
949 return 0
951 fi 2> /dev/null
952 return 1
953 }
955 remove_with_path() {
956 dir="$(dirname $1)"
957 rm -f "$1"
958 while rmdir "$dir" 2> /dev/null; do
959 dir="$(dirname $dir)"
960 done
961 }
963 mergefs() {
964 # Note, many packages have files with spaces in the name
965 IFS=$'\n'
967 local size1=$(du -hs "$1" | awk '{ print $1 }')
968 local size2=$(du -hs "$2" | awk '{ print $1 }')
969 action 'Merge %s (%s) into %s (%s)' "$(basename "$1")" "$size1" "$(basename "$2")" "$size2"
971 # merge symlinks files and devices
972 ( cd "$1"; find ) | \
973 while read file; do
974 files_match "$1/$file" "$2/$file" "$file" &&
975 remove_with_path "$2/$file"
976 [ -d "$1/$file" ] && [ -d "$2/$file" ] && rmdir "$2/$file" 2>/dev/null
977 done
979 unset IFS
980 status
981 }
984 cleanup_merge() {
985 rm -rf $TMP_DIR
986 exit 1
987 }
990 # Update isolinux config files for multiple rootfs
992 update_bootconfig() {
993 local files
994 action 'Updating boot config files...'
995 files="$(grep -l 'include common' $1/*.cfg)"
996 for file in $files; do
997 awk -v n=$(echo $2 | awk '{ print NF/2 }') '{
998 if (/label/) label=$0;
999 else if (/kernel/) kernel=$0;
1000 else if (/append/) {
1001 i=index($0,"rootfs.gz");
1002 append=substr($0,i+9);
1004 else if (/include/) {
1005 for (i = 1; i <= n; i++) {
1006 print label i
1007 print kernel;
1008 initrd="initrd=/boot/rootfs" n ".gz"
1009 for (j = n - 1; j >= i; j--) {
1010 initrd=initrd ",/boot/rootfs" j ".gz";
1012 printf "\tappend %s%s\n",initrd,append;
1013 print "";
1015 print;
1017 else print;
1018 }' < $file > $file.$$
1019 mv -f $file.$$ $file
1020 done
1021 sel="$(echo $2 | awk '{
1022 for (i=1; i<=NF; i++)
1023 if (i % 2 == 0) printf " slitaz%d", i/2
1024 else printf " %s", $i
1025 }')"
1027 [ -s $1/common.cfg ] && cat >> $1/common.cfg <<EOT
1029 label slitaz
1030 kernel /boot/isolinux/ifmem.c32
1031 append$sel noram
1033 label noram
1034 config noram.cfg
1036 EOT
1038 # Update vesamenu
1039 if [ -s "$1/isolinux.cfg" ]; then
1040 files="$files $1/isolinux.cfg"
1041 awk -v n=$(echo $2 | awk '{ print NF/2 }') -v "sel=$sel" '
1042 BEGIN {
1043 kernel = " COM32 c32box.c32"
1046 if (/ROWS/) print "MENU ROWS " n+$3;
1047 else if (/TIMEOUTROW/) print "MENU TIMEOUTROW " n+$3;
1048 else if (/TABMSGROW/) print "MENU TABMSGROW " n+$3;
1049 else if (/CMDLINEROW/) print "MENU CMDLINEROW " n+$3;
1050 else if (/VSHIFT/) {
1051 x = $3-n;
1052 if (x < 0) x = 0;
1053 print "MENU VSHIFT " x;
1055 else if (/rootfs.gz/) {
1056 linux = "";
1057 if (/bzImage/) linux = "linux /boot/bzImage ";
1058 i = index($0, "rootfs.gz");
1059 append = substr($0, i+9);
1060 printf "\tkernel /boot/isolinux/ifmem.c32\n";
1061 printf "\tappend%s noram\n", sel;
1062 printf "\nlabel noram\n\tMENU HIDE\n\tconfig noram.cfg\n\n";
1063 for (i = 1; i <= n; i++) {
1064 print "LABEL slitaz" i
1065 printf "\tMENU LABEL SliTaz slitaz%d Live\n", i;
1066 printf "%s\n", kernel;
1067 initrd = "initrd=/boot/rootfs" n ".gz"
1068 for (j = n - 1; j >= i; j--) {
1069 initrd = initrd ",/boot/rootfs" j ".gz";
1071 printf "\tappend %s%s%s\n\n", linux, initrd, append;
1074 else if (/bzImage/) kernel = $0;
1075 else print;
1076 }' < $1/isolinux.cfg > $1/isolinux.cfg.$$
1077 mv $1/isolinux.cfg.$$ $1/isolinux.cfg
1078 fi
1080 [ -s $1/c32box.c32 ] && sed -i -e '/kernel.*ifmem/d' \
1081 -e 's/append \([0-9]\)/append ifmem \1/' $1/isolinux.cfg
1082 cat > $1/noram.cfg <<EOT
1083 implicit 0
1084 prompt 1
1085 timeout 80
1086 $(grep '^F[0-9]' $1/isolinux.cfg)
1088 $([ -s $1/isolinux.msg ] && echo display isolinux.msg)
1089 say Not enough RAM to boot slitaz. Trying hacker mode...
1090 default hacker
1091 label hacker
1092 KERNEL /boot/bzImage
1093 append rw root=/dev/null vga=normal
1095 label reboot
1096 EOT
1098 if [ -s $1/c32box.c32 ]; then
1099 cat >> $1/noram.cfg <<EOT
1100 COM32 c32box.c32
1101 append reboot
1103 label poweroff
1104 COM32 c32box.c32
1105 append poweroff
1107 EOT
1108 else
1109 echo " com32 reboot.c32" >> $1/noram.cfg
1110 fi
1112 # Restore real label names
1113 [ -s $1/common.cfg ] && files="$1/common.cfg $files"
1114 echo $2 | awk '{ for (i=NF; i>1; i-=2) printf "%d/%s\n",i/2,$i }' | \
1115 while read pat; do
1116 sed -i "s/slitaz$pat/" $files
1117 done
1118 status
1122 # Uncompress rootfs or module to stdout
1124 uncompress() {
1125 zcat $1 2> /dev/null || xzcat $1 2> /dev/null ||
1126 { [ $(od -N 1 -An $1) -eq 135 ] && unlzma < $1; } || cat $1
1130 # Install a missing package
1132 install_package() {
1133 if [ -z "$2" ]; then
1134 answer=$(yesorno "$(_ 'Install package %s?' "$1")" 'n')
1135 else
1136 answer=$(yesorno "$(_n 'Install package %s for Kernel %s? ' "$1" "$2")" 'n')
1137 fi
1138 case "$answer" in
1139 y)
1140 # We don't want package on host cache.
1141 action 'Getting and installing package: %s' "$1"
1142 yes y | tazpkg get-install $1 --quiet 2>&1 >> $log || exit 1
1143 status ;;
1144 *)
1145 return 1 ;;
1146 esac
1150 # Check iso for loram transformation
1152 check_iso_for_loram() {
1153 [ -s "$TMP_DIR/iso/boot/rootfs.gz" ] ||
1154 [ -s "$TMP_DIR/iso/boot/rootfs1.gz" ]
1158 # Build initial rootfs for loram ISO ram/cdrom/http
1160 build_initfs() {
1161 urliso="mirror.switch.ch/ftp/mirror/slitaz \
1162 download.tuxfamily.org/slitaz mirror1.slitaz.org mirror2.slitaz.org \
1163 mirror3.slitaz.org mirror.slitaz.org"
1164 version=$(ls $TMP_DIR/iso/boot/vmlinuz-* | sed 's/.*vmlinuz-//')
1165 [ -z "$version" ] && die "Can't find the kernel version." \
1166 'No file /boot/vmlinuz-<version> in ISO image. Abort.'
1168 [ -s /usr/share/boot/busybox-static ] || install_package busybox-static
1169 need_lib=false
1170 for i in bin dev run mnt proc tmp sys lib/modules; do
1171 mkdir -p $TMP_DIR/initfs/$i
1172 done
1173 ln -s bin $TMP_DIR/initfs/sbin
1174 ln -s . $TMP_DIR/initfs/usr
1175 for aufs in aufs overlayfs; do
1176 [ -f /lib/modules/$version/kernel/fs/$aufs/$aufs.ko.?z ] && break
1177 install_package linux-$aufs $version && break
1178 install_package $aufs $version && break
1179 done || return 1
1180 [ -s /init ] || install_package slitaz-boot-scripts
1181 cp /init $TMP_DIR/initfs/
1182 cp /lib/modules/$version/kernel/fs/$aufs/$aufs.ko.?z \
1183 $TMP_DIR/initfs/lib/modules
1184 if [ "$1" == 'cdrom' ]; then
1185 sed -i '/mod squashfs/d' $TMP_DIR/initfs/init
1186 else
1187 [ ! -f /usr/sbin/mksquashfs ] && ! install_package squashfs && return 1
1188 while [ ! -f /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z ]; do
1189 install_package linux-squashfs $version || return 1
1190 done
1191 cp /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z \
1192 $TMP_DIR/initfs/lib/modules
1193 #ls /sbin/unsquashfs /usr/lib/liblzma.so* $INSTALLED/squashfs/* | \
1194 #cpio -o -H newc > $TMP_DIR/initfs/extractfs.cpio
1195 fi
1196 if [ "$1" == 'http' ]; then
1197 mkdir $TMP_DIR/initfs/etc $TMP_DIR/fs
1198 ln -s /proc/mounts $TMP_DIR/initfs/etc/mtab
1199 cp /usr/share/udhcpc/default.script $TMP_DIR/initfs/lib/udhcpc
1200 sed -i 's|/sbin/||;s/^logger/#&/' $TMP_DIR/initfs/lib/udhcpc
1201 cp -a /dev/fuse $TMP_DIR/initfs/dev
1202 if ! $need_lib && [ -x /usr/share/boot/fusermount-static ]; then
1203 cp /usr/share/boot/fusermount-static $TMP_DIR/initfs/bin/fusermount
1204 else
1205 need_lib=true
1206 fi
1207 if ! $need_lib && [ -x /usr/share/boot/httpfs-static ]; then
1208 cp /usr/share/boot/httpfs-static $TMP_DIR/initfs/bin/httpfs
1209 else
1210 [ ! -f /usr/bin/httpfs ] && ! install_package httpfs-fuse && return 1
1211 cp /usr/bin/httpfs $TMP_DIR/initfs/bin
1212 cp /usr/bin/fusermount $TMP_DIR/initfs/bin
1213 cp -a /lib/librt* $TMP_DIR/initfs/lib
1214 cp -a /lib/libdl* $TMP_DIR/initfs/lib
1215 cp -a /lib/libpthread* $TMP_DIR/initfs/lib
1216 cp -a /usr/lib/libfuse* $TMP_DIR/initfs/lib
1217 cp -a /lib/libresolv* $TMP_DIR/initfs/lib
1218 cp -a /lib/libnss_dns* $TMP_DIR/initfs/lib
1219 need_lib=true
1220 fi
1221 cd $TMP_DIR/fs
1222 echo 'Getting slitaz-release & ethernet modules...'
1223 for i in $(ls -r $TMP_DIR/iso/boot/rootfs*z); do
1224 uncompress $i | cpio -idmu etc/slitaz-release lib/modules rootfs*
1225 [ -s rootfs* ] || continue
1226 unsquashfs -f -d . rootfs* rootfs* etc/slitaz-release lib/modules &&
1227 rm -f rootfs*
1228 done 2>&1 > /dev/null
1229 cd - > /dev/null
1230 cp $TMP_DIR/fs/etc/slitaz-release $TMP_DIR/initfs/etc/
1231 find $TMP_DIR/fs/lib/modules/*/kernel/drivers/net/ethernet \
1232 -type f -name '*.ko*' | while read mod; do
1233 f=$TMP_DIR/initfs/lib/modules/$(basename $mod | sed s/..z$//)
1234 uncompress $mod > $f
1235 grep -q alias=pci: $f || rm -f $f
1236 done
1237 for i in $TMP_DIR/initfs/lib/modules/*.ko ; do
1238 f=$(basename $i)..z
1239 grep -q $f:$ $TMP_DIR/fs/lib/modules/*/modules.dep && continue
1240 deps="$(grep $f: $TMP_DIR/fs/lib/modules/*/modules.dep | sed 's/.*: //')"
1241 echo "$deps" | sed 's|kernel/[^ ]*/||g;s/.ko..z//g' > $TMP_DIR/initfs/lib/modules/$(basename $i .ko).dep
1242 for j in $deps; do
1243 mod=$(ls $TMP_DIR/fs/lib/modules/*/$j)
1244 uncompress $mod > $TMP_DIR/initfs/lib/modules/$(basename $j | sed s/..z$//)
1245 done
1246 done
1247 longline "Default URLs for /iso/$(cat $TMP_DIR/initfs/etc/slitaz-release)/flavors/slitaz-loram-cdrom.iso /iso/$(cat $TMP_DIR/initfs/etc/slitaz-release)/flavors/slitaz-$(cat $TMP_DIR/initfs/etc/slitaz-release)-loram-cdrom.iso: $urliso"
1248 _n 'List of URLs to insert: '
1249 read -t 30 urliso2
1250 urliso="$urliso2 $urliso"
1251 fi
1252 if ! $need_lib && [ -x /usr/share/boot/busybox-static ]; then
1253 cp /usr/share/boot/busybox-static $TMP_DIR/initfs/bin/busybox
1254 sed -i 's/LD_T.*ot/echo/;s/".*ld-.*) /"/' $TMP_DIR/initfs/init
1255 else
1256 cp /bin/busybox $TMP_DIR/initfs/bin
1257 if ! cmp /bin/busybox /sbin/insmod > /dev/null ; then
1258 cp /sbin/insmod $TMP_DIR/initfs/bin
1259 cp -a /lib/libkmod.so.* $TMP_DIR/initfs/lib
1260 cp -a /usr/lib/liblzma.so.* $TMP_DIR/initfs/lib
1261 cp -a /usr/lib/libz.so.* $TMP_DIR/initfs/lib
1262 fi
1263 need_lib=true
1264 fi
1265 for i in $($TMP_DIR/initfs/bin/busybox | awk \
1266 '{ if (s) printf "%s",$0 } /Currently/ { s=1 }' | sed 's/,//g'); do
1267 ln $TMP_DIR/initfs/bin/busybox $TMP_DIR/initfs/bin/$i
1268 done
1269 # bootfloppybox will need floppy.ko.?z, /dev/fd0, /dev/tty0
1270 cp /lib/modules/$version/kernel/drivers/block/floppy.ko.?z \
1271 $TMP_DIR/initfs/lib/modules 2>/dev/null
1272 for i in /dev/console /dev/null /dev/tty /dev/tty0 /dev/zero \
1273 /dev/kmem /dev/mem /dev/random /dev/urandom; do
1274 cp -a $i $TMP_DIR/initfs/dev
1275 done
1276 grep -q '/sys/block/./dev' $TMP_DIR/initfs/init ||
1277 for i in /dev/fd0 /dev/[hs]d[a-f]* /dev/loop* ; do
1278 cp -a $i $TMP_DIR/initfs/dev
1279 done 2>/dev/null
1280 $need_lib && for i in /lib/ld-* /lib/lib[cm][-\.]* ; do
1281 cp -a $i $TMP_DIR/initfs/lib
1282 done
1283 [ "$1" == 'http' ] && cat > $TMP_DIR/initfs/init <<EOTEOT
1284 #!/bin/sh
1286 getarg() {
1287 grep -q " \$1=" /proc/cmdline || return 1
1288 eval \$2=\$(sed "s/.* \$1=\\\\([^ ]*\\\\).*/\\\\1/" < /proc/cmdline)
1289 return 0
1292 copy_rootfs() {
1293 total=\$(grep MemTotal /proc/meminfo | sed 's/[^0-9]//g')
1294 need=\$(du -c \${path}rootfs* | tail -n 1 | cut -f1)
1295 [ \$(( \$total / \$need )) -gt 1 ] || return 1
1296 if ! grep -q " keep-loram" /proc/cmdline && cp \${path}rootfs* /mnt; then
1297 path=/mnt/
1298 return 0
1299 else
1300 rm -f /mnt/rootfs*
1301 return 1
1302 fi
1305 echo "Switching / to tmpfs..."
1306 mount -t proc proc /proc
1307 size="\$(grep rootfssize= < /proc/cmdline | \\
1308 sed 's/.*rootfssize=\\([0-9]*[kmg%]\\).*/-o size=\\1/')"
1309 [ -n "\$size" ] || size="-o size=90%"
1311 mount -t sysfs sysfs /sys
1312 for i in /lib/modules/*.ko ; do
1313 echo -en "Probe \$i \\r"
1314 for j in \$(grep alias=pci: \$i | sed 's/alias//;s/\*/.*/g'); do
1315 grep -q "\$j" /sys/bus/pci/devices/*/uevent || continue
1316 for k in \$(cat \${i/ko/dep} 2> /dev/null); do
1317 insmod /lib/modules/\$k.ko 2> /dev/null
1318 done
1319 echo "Loading \$i"
1320 insmod \$i 2> /dev/null
1321 break
1322 done
1323 done
1324 umount /sys
1325 while read var default; do
1326 eval \$var=\$default
1327 getarg \$var \$var
1328 done <<EOT
1329 eth eth0
1330 dns 208.67.222.222,208.67.220.220
1331 netmask 255.255.255.0
1332 gw
1333 ip
1334 EOT
1335 grep -q \$eth /proc/net/dev || sh
1336 if [ -n "\$ip" ]; then
1337 ifconfig \$eth \$ip netmask \$netmask up
1338 route add default gateway \$gw
1339 for i in \$(echo \$dns | sed 's/,/ /g'); do
1340 echo "nameserver \$i" >> /etc/resolv.conf
1341 done
1342 else
1343 udhcpc -f -q -s /lib/udhcpc -i \$eth
1344 fi
1345 for i in $urliso ; do
1346 [ -n "\$URLISO" ] && URLISO="\$URLISO,"
1347 URLISO="\${URLISO}http://\$i/iso/\$(cat /etc/slitaz-release)/flavors/slitaz-loram-cdrom.iso,http://\$i/iso/\$(cat /etc/slitaz-release)/flavors/slitaz-\$(cat /etc/slitaz-release)-loram-cdrom.iso"
1348 URLISO="\$URLISO,http://\$i/iso/rolling/slitaz-rolling-loram-cdrom.iso,http://\$i/iso/rolling/slitaz-rolling-loram.iso"
1349 done
1350 getarg urliso URLISO
1351 DIR=fs
1352 if getarg loram DIR; then
1353 DEVICE=\${DIR%,*}
1354 DIR=/\${DIR#*,}
1355 fi
1356 mount -t tmpfs \$size tmpfs /mnt
1357 path2=/mnt/.httpfs/
1358 path=/mnt/.cdrom/
1359 mkdir -p /mnt/.rw /mnt/.wd \$path \$path2
1360 while [ ! -d \$path/boot ]; do
1361 for i in \$(echo \$URLISO | sed 's/,/ /g'); do
1362 httpfs \$i \$path2 && echo \$i && break
1363 done
1364 mount -o loop,ro -t iso9660 \$path2/*.iso \$path || sh
1365 done
1367 memfree=\$(grep MemFree /proc/meminfo | sed 's/[^0-9]//g')
1368 umount /proc
1369 branch=:/mnt/.cdrom/\$DIR
1370 if [ ! -d /mnt/.cdrom/\$DIR/etc ]; then
1371 branch=
1372 lp=1
1373 insmod /lib/modules/squashfs.ko 2> /dev/null
1374 for i in \${path}boot/rootfs?.* ; do
1375 fs=\${i#*root}
1376 branch=\$branch:/mnt/.\$fs
1377 mkdir -p /mnt/.rw/mnt/.\$fs /mnt/.\$fs /mnt/.rw/mnt/.cdrom
1378 losetup -o 124 /dev/loop\$lp \$i
1379 mount -o loop,ro -t squashfs /dev/loop\$lp /mnt/.\$fs
1380 lp=\$((\$lp+1))
1381 done
1382 fi
1383 mkdir -p /mnt/.rw/mnt/.httpfs
1384 while read type opt; do
1385 insmod /lib/modules/\$type.ko && mount -t \$type -o \$opt none /mnt && break
1386 done <<EOT
1387 aufs br=/mnt/.rw\$branch
1388 overlayfs workdir=/mnt/.wd\${branch/:/,lowerdir=},upperdir=/mnt/.rw
1389 EOT
1390 rm -rf /lib/modules
1391 [ -x /bin/httpfs ] && sed -i 's/DHCP="yes"/DHCP="no"/' /mnt/etc/network.conf
1392 [ \$memfree -lt 30000 ] && sed -i 's/ slim//' /mnt/etc/rcS.conf
1393 [ -x /mnt/sbin/init ] && exec /bin/switch_root mnt /sbin/init || sh
1394 EOTEOT
1395 chmod +x $TMP_DIR/initfs/init
1396 for i in $TMP_DIR/initfs/lib/modules/*z ; do
1397 unxz $i || gunzip $i || lzma d $i ${i%.gz}
1398 rm -f $i
1399 done 2>/dev/null
1400 (cd $TMP_DIR/initfs; find | busybox cpio -o -H newc 2>/dev/null) | \
1401 lzma e $TMP_DIR/initfs.gz -si
1402 lzma_set_size $TMP_DIR/initfs.gz
1403 rm -rf $TMP_DIR/initfs
1404 align_to_32bits $TMP_DIR/initfs.gz
1405 return 0
1409 # Move each initramfs to squashfs
1411 build_loram_rootfs() {
1412 rootfs_sizes=""
1413 for i in $TMP_DIR/iso/boot/rootfs*; do
1414 mkdir -p $TMP_DIR/fs
1415 cd $TMP_DIR/fs
1416 uncompress $i | cpio -idm
1417 deduplicate
1418 cd - > /dev/null
1419 rootfs=$TMP_DIR/$(basename $i)
1420 /usr/sbin/mksquashfs $TMP_DIR/fs $rootfs -comp ${1:-xz -Xbcj x86}
1421 cd $TMP_DIR
1422 rootfs_sizes="$rootfs_sizes $(( $(du -s $TMP_DIR/fs | cut -f1) - $(du -s $rootfs | cut -f1) ))"
1423 ( cd $(dirname $rootfs); echo $(basename $rootfs) | cpio -o -H newc ) > $rootfs.cpio
1424 rm -f $rootfs
1425 mv $rootfs.cpio $rootfs
1426 cd - > /dev/null
1427 rm -rf $TMP_DIR/fs
1428 done
1432 # Move meta boot configuration files to basic configuration files
1433 # because meta loram flavor is useless when rootfs is not loaded in RAM
1435 unmeta_boot() {
1436 local root=${1:-$TMP_DIR/loramiso}
1437 if [ -f $root/boot/isolinux/noram.cfg ]; then
1438 # We keep enough information to do unloram...
1439 [ -s $root/boot/isolinux/common.cfg ] &&
1440 sed -i 's/label slitaz/label orgslitaz/' \
1441 $root/boot/isolinux/common.cfg
1442 set -- $(grep 'append ifmem [0-9]' $root/boot/isolinux/isolinux.cfg)
1443 shift
1444 sed -i '/ifmem/{NNNNNNNNd};/^LABEL/{N;/LABEL SliTaz [^L]/{NNNd}}' \
1445 $root/boot/isolinux/isolinux.cfg
1446 [ -n "$3" ] || set -- $(grep 'append [0-9]' $root/boot/isolinux/common.cfg)
1447 sed -i "s/label $3\$/label slitaz/;s|=\(.*rootfs\)\(.*\)\.gz |=\1.gz |" \
1448 $root/boot/isolinux/*.cfg
1449 fi
1453 # Move rootfs to squashfs filesystem(s) to the cdrom writeable with aufs/overlayfs.
1454 # These squashfs may be loaded in RAM at boot time.
1455 # Rootfs are also copied to CD-ROM for tiny ramsize systems.
1456 # Meta flavors are converted to normal flavors.
1458 build_loram_cdrom() {
1459 build_initfs cdrom || return 1
1460 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1461 mkdir $TMP_DIR/loramiso/fs
1462 cd $TMP_DIR/loramiso/fs
1463 for i in $( ls ../boot/root* | sort -r ) ; do
1464 uncompress $i | cpio -idmu
1465 rm -f $i
1466 done
1467 mkdir -p $TMP_DIR/loramiso/fs/mnt/.cdrom
1468 cd - >/dev/null
1469 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1470 unmeta_boot
1471 VOLUM_NAME="SliTaz_LoRAM_CDROM"
1472 sed -i "s|root=|isofs= rodev=/dev/cdrom/fs &|;s/.ive/cdrom/" \
1473 $TMP_DIR/loramiso/boot/isolinux/*.cfg
1474 sed -i '/LABEL slitaz/{NNNNp;s|z cdrom|& text|;s|L slitaz|&text|;s|root=|screen=text &|;s|,[^ ]*||}' \
1475 $TMP_DIR/loramiso/boot/isolinux/*.cfg
1476 create_iso $OUTPUT $TMP_DIR/loramiso
1480 # Create http bootstrap to load and remove loram_cdrom
1481 # Meta flavors are converted to normal flavors.
1483 build_loram_http() {
1484 build_initfs http || return 1
1485 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1486 rm -f $TMP_DIR/loramiso/boot/rootfs*
1487 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1488 unmeta_boot
1489 create_iso $OUTPUT $TMP_DIR/loramiso
1493 # Update meta flavor selection sizes.
1494 # Reduce sizes with rootfs gains.
1496 update_metaiso_sizes() {
1497 for cfg in $(grep -El '(append|ifmem) [0-9]' $TMP_DIR/loramiso/boot/isolinux/*.cfg)
1498 do
1499 local append="$(grep -E '(append|ifmem) [0-9]' $cfg)"
1500 local sizes="$rootfs_sizes"
1501 local new
1502 set -- $append
1503 shift
1504 [ "$1" == "ifmem" ] && shift
1505 new=""
1506 while [ -n "$2" ]; do
1507 local s
1508 case "$1" in
1509 *G) s=$(( ${1%G} * 1024 * 1024 ));;
1510 *M) s=$(( ${1%M} * 1024 ));;
1511 *) s=${1%K};;
1512 esac
1513 sizes=${sizes#* }
1514 for i in $sizes ; do
1515 s=$(( $s - $i ))
1516 done
1517 new="$new $s $2"
1518 shift 2
1519 done
1520 sed -i -e "/append [0-9]/s/append .*/append$new $1/" -e \
1521 "/append ifmem [0-9]/s/append .*/append ifmem$new $1/" $cfg
1522 sed -i 's|\(initrd=\)\([^r]*\)\(rootfs\)|\1\2rootfs.gz,\2\3|' $cfg
1523 sed -i '/LABEL base/{NNNNp;s|base .ive|cdrom|;s|base|cdrom|;s|,[^ ]*||}' $cfg
1524 sed -i '/LABEL cdrom/{NNNNp;s|z cdrom|& text|;s|L cdrom|&text|;s|root=|screen=text &|;s|,[^ ]*||}' $cfg
1525 done
1529 # Move rootfs to a squashfs filesystem into the initramfs writeable with aufs/overlayfs.
1530 # Meta flavor selection sizes are updated.
1532 build_loram_ram() {
1533 build_initfs ram || return 1
1534 build_loram_rootfs "$1"
1535 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1536 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1537 cp $TMP_DIR/rootfs* $TMP_DIR/loramiso/boot
1538 update_metaiso_sizes
1539 create_iso $OUTPUT $TMP_DIR/loramiso
1543 # Remove files installed by packages
1545 find_flavor_rootfs() {
1546 for i in $1/etc/tazlito/*.extract; do
1547 [ -e $i ] || continue
1548 chroot $1 /bin/sh ${i#$1}
1549 done
1551 # Clean hardlinks and files patched by genisofs in /boot
1552 for i in isolinux/isolinux.bin isolinux/boot.cat bzImage ; do
1553 rm -f $1/boot/$i*
1554 done
1556 # Clean files generated in post_install
1557 rm -f $1/lib/modules/*/modules.* $1/etc/mtab \
1558 $1/dev/core $1/dev/fd $1/dev/std*
1560 # Verify md5
1561 cat $1$INSTALLED/*/md5sum | \
1562 while read md5 file; do
1563 [ -e "$1$file" ] || continue
1564 [ "$(md5sum < "$1$file")" == "$md5 -" ] &&
1565 rm -f "$1$file"
1566 done
1568 # Check configuration files
1569 for i in $1$INSTALLED/*/volatile.cpio.gz; do
1570 [ -e $i ] || continue
1571 mkdir /tmp/volatile$$
1572 zcat $i | ( cd /tmp/volatile$$ ; cpio -idmu > /dev/null 2>&1 )
1573 ( cd /tmp/volatile$$ ; find * -type f 2> /dev/null) | \
1574 while read file ; do
1575 [ -e "$1/$file" ] || continue
1576 cmp -s "/tmp/volatile$$/$file" "$1/$file" && rm -f "$1/$file"
1577 done
1578 rm -rf /tmp/volatile$$
1579 done
1581 # Remove other files blindly
1582 for i in $1$INSTALLED/*/files.list; do
1583 for file in $(cat "$i"); do
1584 [ "$1$file" -nt "$i" ] && continue
1585 [ -f "$1$file" -a ! -L "$1$file" ] && continue
1586 [ -d "$1$file" ] || rm -f "$1$file"
1587 done
1588 done
1590 # Remove tazpkg files and tmp files
1591 rm -rf $1$INSTALLED* $1/tmp $1/var/tmp
1592 rm -f $1$LOCALSTATE/*packages* $1$LOCALSTATE/files.list.lzma \
1593 $1$LOCALSTATE/mirror* $1/var/cache/*/* \
1594 $1/var/lock/* $1/var/log/* $1/var/run/* $1/var/run/*/* \
1595 $1/var/lib/* $1/var/lib/dbus/* 2>/dev/null
1597 # Cleanup directory tree
1598 cd $1
1599 find * -type d | sort -r | while read dir; do
1600 rmdir "$dir" 2>/dev/null
1601 done
1602 cd - > /dev/null
1606 # Get byte(s) from a binary file
1608 get() {
1609 od -v -j $1 -N ${3:-2} -t u${3:-2} -w${3:-2} -An $2 2>/dev/null
1613 # Get cpio flavor info from the ISO image
1615 flavordata() {
1616 [ $(get 1024 $1) -eq 35615 ] && n=2 || n=$((1+$(get 417 $1 1)))
1617 dd if=$1 bs=512 skip=$n count=20 2>/dev/null | zcat 2>/dev/null
1621 # Restore undigest mirrors
1623 restore_mirrors() {
1624 local undigest="$root$LOCALSTATE/undigest" priority="$root$LOCALSTATE/priority"
1625 [ -d "$undigest.bak" ] || [ -e "$priority.bak" ] || return
1627 action 'Restoring mirrors...'
1628 if [ -d "$undigest.bak" ]; then
1629 [ -d "$undigest" ] && rm -r "$undigest"
1630 mv "$undigest.bak" "$undigest"
1631 fi
1632 [ -e "$priority.bak" ] && mv -f "$priority.bak" "$priority"
1633 :; status
1637 # Setup undigest mirrors
1639 setup_mirrors() {
1640 # Setup mirrors in plain system or in chroot (with variable root=)
1641 local mirrorlist="$1" fresh repacked
1642 local undigest="$root$LOCALSTATE/undigest" priority="$root$LOCALSTATE/priority"
1644 # Restore mirrors first: in case of non-clear exits, hangs, etc.
1645 restore_mirrors
1647 _ 'Setting up mirrors for %s...' "$root/"
1648 # Backing up current undigest mirrors and priority
1649 [ -d "$undigest" ] && mv "$undigest" "$undigest.bak"
1650 [ -e "$priority" ] && mv "$priority" "$priority.bak"
1651 rm -rf '/var/www/tazlito/'
1652 mkdir -p '/var/www/tazlito/'
1654 # Packages produced by CookUtils: on Tank or local, or repacked packages: highest priority
1655 fresh='/home/slitaz/packages'
1656 if [ -d "$fresh" ]; then
1657 # Setup first undigest mirror
1658 mkdir -p "$undigest/fresh"
1659 echo "$fresh" > "$undigest/fresh/mirror"
1660 echo 'fresh' >> "$priority"
1661 # Rebuild mirror DB if needed
1662 [ ! -e "$fresh/IDs" ] && tazpkg mkdb "$fresh" --forced --root=''
1663 [ -n "$(find -L "$fresh" -name '*.tazpkg' -newer "$fresh/IDs")" ] && \
1664 tazpkg mkdb "$fresh" --forced --root=''
1665 cp -a "$fresh/files.list.lzma" "$fresh/files-list.lzma"
1666 fi
1668 # Repacked packages: high priority
1669 repacked="$PACKAGES_REPOSITORY"
1670 if [ -d "$repacked" -a "$repacked" != "$fresh" ] && ls "$repacked" | grep -q ".tazpkg"; then
1671 # According to Tazlito setup file (tazlito.conf):
1672 # WORK_DIR="/home/slitaz/$SLITAZ_VERSION"
1673 # or
1674 # WORK_DIR="/home/slitaz"
1675 # and
1676 # PACKAGES_REPOSITORY="$WORK_DIR/packages"
1677 # It MAY or MAY NOT match /home/slitaz/packages, so here we setup second repository
1679 # Setup second undigest mirror
1680 mkdir -p "$undigest/repacked"
1681 echo "$repacked" > "$undigest/repacked/mirror"
1682 echo 'repacked' >> "$priority"
1683 # Rebuild mirror DB if needed
1684 [ ! -e "$repacked/IDs" ] && tazpkg mkdb "$repacked" --forced --root=''
1685 [ -n "$(find -L "$repacked" -name '*.tazpkg' -newer "$repacked/IDs")" ] && \
1686 tazpkg mkdb "$repacked" --forced --root=''
1687 cp -a "$repacked/files.list.lzma" "$repacked/files-list.lzma"
1688 fi
1690 # All repositories listed in mirrors list: normal priority
1691 [ -e "$mirrorlist" ] && \
1692 while read mirror; do
1693 # Provide consistent mirror ID for caching purpose: /var/cache/tazpkg/<mirror ID>/packages
1694 mirrorid=$(echo "$mirror" | md5sum | cut -d' ' -f1)
1695 mkdir -p "$undigest/$mirrorid"
1696 echo "$mirror" > "$undigest/$mirrorid/mirror"
1697 echo "$mirrorid" >> "$priority"
1698 done < "$mirrorlist"
1700 # And, finally, main mirror with the lowest (failsafe) priority (nothing to do)
1702 # Show list of mirrors
1703 [ -f "$priority" ] && awk -vdb="$root$LOCALSTATE" '
1704 function show(num, name, url) {
1705 printf " %-1.1d. %32.32s %-44.44s\n", num, name " ...............................", url;
1708 num++;
1709 "cat " db "/undigest/" $0 "/mirror" | getline url;
1710 show(num, $0, url);
1712 END {
1713 num++;
1714 "cat " db "/mirror" | getline url;
1715 show(num, "main", url);
1716 }' "$priority"
1718 tazpkg recharge --quiet >/dev/null
1722 # Get list of 'packages.info' lists using priority
1724 pi_lists() {
1725 local pi
1726 [ -s "$root$LOCALSTATE/packages.info" ] || tazpkg recharge --root="$root" >/dev/null 2>&1
1727 local priority="$root$LOCALSTATE/priority"
1728 local undigest="$root$LOCALSTATE/undigest"
1731 [ -s "$priority" ] && cat "$priority"
1732 echo 'main'
1733 [ -d "$undigest" ] && ls "$undigest"
1734 } | awk -vun="$undigest/" '
1736 if (arr[$0] != 1) {
1737 arr[$0] = 1;
1738 print un $0 "/packages.info";
1740 }' | sed 's|/undigest/main||' | \
1741 while read pi; do
1742 [ -e "$pi" ] && echo "$pi"
1743 done
1747 # Strip versions from packages list
1749 strip_versions() {
1750 if [ -n "$stripped" ]; then
1751 action 'Consider list %s already stripped' "$(basename "$1")"
1752 status
1753 return 0
1754 fi
1755 action 'Strip versions from list %s...' "$(basename "$1")"
1756 local in_list="$1" tmp_list="$(mktemp)" namever pkg
1757 [ -f "$in_list" ] || die "List '$in_list' not found."
1759 # $pkg=<name>-<version> or $pkg=<name>; both <name> and <version> may contain dashes
1760 awk '
1762 if (FILENAME ~ "packages.info") {
1763 # Collect package names
1764 FS = "\t"; pkg[$1] = 1;
1765 } else {
1766 FS = OFS = "-"; $0 = $0; # Fix bug with FS for first record
1767 while (NF > 1 && ! pkg[$0])
1768 NF --;
1769 printf "%s\n", $0;
1771 }' $(pi_lists) "$in_list" > "$tmp_list"
1773 cat "$tmp_list" > "$in_list"
1774 rm "$tmp_list"
1775 status
1779 # Display list of unknown packages (informative)
1781 display_unknown() {
1782 [ -s "$1" ] || return
1783 echo "Unknown packages:" >&2
1784 cat "$1" >&2
1785 rm "$1"
1789 # Display warnings about critical packages absent (informative)
1791 display_warn() {
1792 [ -s "$1" ] || return
1793 echo "Absent critical packages:" >&2
1794 cat "$1" >&2
1795 rm "$1"
1796 echo "Probably ISO image will be unusable."
1800 # Install packages to rootfs
1802 install_list_to_rootfs() {
1803 local list="$1" rootfs="$2" pkg i ii
1804 local undigest="$rootfs/var/lib/tazpkg/undigest"
1806 # initial tazpkg setup in empty rootfs
1807 tazpkg --root=$rootfs >/dev/null 2>&1
1808 # pass current 'mirror' to the rootfs
1809 mkdir -p $rootfs/var/lib/tazpkg $rootfs/etc
1810 cp -f /var/lib/tazpkg/mirror $rootfs/var/lib/tazpkg/mirror
1811 cp -f /etc/slitaz-release $rootfs/etc/slitaz-release
1812 # link rootfs packages cache to the regular packages cache
1813 rm -r "$rootfs/var/cache/tazpkg"
1814 ln -s /var/cache/tazpkg "$rootfs/var/cache/tazpkg"
1816 setup_mirrors mirrors
1818 # Just in case if flavor doesn't contain "tazlito" package
1819 mkdir -p "$rootfs/etc/tazlito"
1821 newline
1823 # Choose detailed log with --detailed
1824 if [ -n "$detailed" ]; then
1825 while read pkg; do
1826 separator '-'
1827 echo $pkg
1828 tazpkg -gi $pkg --root=$rootfs --local --quiet --cookmode | tee -a $log
1829 done < $list
1830 separator '='
1831 else
1832 while read pkg; do
1833 action 'Installing package: %s' "$pkg"
1834 yes y | tazpkg -gi $pkg --root=$rootfs --quiet >> $log || exit 1
1835 status
1836 done < $list
1837 fi
1838 newline
1840 restore_mirrors
1841 # Remove 'fresh' and 'repacked' undigest repos leaving all other
1842 for i in fresh repacked; do
1843 ii="$undigest/$i"
1844 [ -d "$ii" ] && rm -rf "$ii"
1845 ii="$rootfs/var/lib/tazpkg/priority"
1846 if [ -f "$ii" ]; then
1847 sed -i "/$i/d" "$ii"
1848 [ -s "$ii" ] || rm "$ii"
1849 fi
1850 done
1851 [ -d "$undigest" ] && \
1852 for i in $(find "$undigest" -type f); do
1853 # Remove all undigest PKGDB files but 'mirror'
1854 [ "$(basename "$i")" != 'mirror' ] && rm "$i"
1855 done
1856 [ -d "$undigest" ] && \
1857 rmdir --ignore-fail-on-non-empty "$undigest"
1859 # Un-link packages cache
1860 rm "$rootfs/var/cache/tazpkg"
1862 # Clean /var/lib/tazpkg
1863 (cd $rootfs/var/lib/tazpkg; rm ID* descriptions.txt extra.list files* packages.* 2>/dev/null)
1869 ####################
1870 # Tazlito commands #
1871 ####################
1873 # /usr/bin/tazlito is linked with /usr/bin/reduplicate and /usr/bin/deduplicate
1874 case "$0" in
1875 *reduplicate)
1876 find ${@:-.} ! -type d -links +1 \
1877 -exec cp -a {} {}$$ \; -exec mv {}$$ {} \;
1878 exit 0 ;;
1879 *deduplicate)
1880 deduplicate "$@"
1881 exit 0 ;;
1882 esac
1885 case "$COMMAND" in
1886 stats)
1887 # Tazlito general statistics from the config file.
1889 title 'Tazlito statistics'
1890 optlist "\
1891 Config file : $CONFIG_FILE
1892 ISO name : $ISO_NAME.iso
1893 Volume name : $VOLUM_NAME
1894 Prepared : $PREPARED
1895 Packages repository : $PACKAGES_REPOSITORY
1896 Distro directory : $DISTRO
1897 Additional files : $ADDFILES
1898 " | sed '/: $/d'
1899 footer
1900 ;;
1903 list-addfiles)
1904 # Simple list of additional files in the rootfs
1905 newline
1906 if [ -d "$ADDFILES/rootfs" ]; then
1907 cd $ADDFILES
1908 find rootfs -type f
1909 else
1910 _ 'Additional files not found: %s' "$ADDFILES/rootfs/"
1911 fi
1912 newline
1913 ;;
1916 gen-config)
1917 # Generate a new config file in the current dir or the specified
1918 # directory by $2.
1920 if [ -n "$2" ]; then
1921 mkdir -p "$2" && cd "$2"
1922 fi
1924 newline
1925 action 'Generating empty tazlito.conf...'
1926 empty_config_file
1927 status
1929 separator
1930 if [ -f 'tazlito.conf' ] ; then
1931 _ 'Configuration file is ready to edit.'
1932 _ 'File location: %s' "$(pwd)/tazlito.conf"
1933 newline
1934 fi
1935 ;;
1938 configure)
1939 # Configure a tazlito.conf config file. Start by getting
1940 # a empty config file and sed it.
1942 if [ -f 'tazlito.conf' ]; then
1943 rm tazlito.conf
1944 else
1945 [ $(id -u) -ne 0 ] && die 'You must be root to configure the main config file' \
1946 'or in the same directory of the file you want to configure.'
1947 cd /etc
1948 fi
1950 empty_config_file
1952 title 'Configuring: %s' "$(pwd)/tazlito.conf"
1954 # ISO name.
1955 echo -n "ISO name : " ; read answer
1956 sed -i s#'ISO_NAME=\"\"'#"ISO_NAME=\"$answer\""# tazlito.conf
1957 # Volume name.
1958 echo -n "Volume name : " ; read answer
1959 sed -i s/'VOLUM_NAME=\"SliTaz\"'/"VOLUM_NAME=\"$answer\""/ tazlito.conf
1960 # Packages repository.
1961 echo -n "Packages repository : " ; read answer
1962 sed -i s#'PACKAGES_REPOSITORY=\"\"'#"PACKAGES_REPOSITORY=\"$answer\""# tazlito.conf
1963 # Distro path.
1964 echo -n "Distro path : " ; read answer
1965 sed -i s#'DISTRO=\"\"'#"DISTRO=\"$answer\""# tazlito.conf
1966 footer "Config file is ready to use."
1967 echo 'You can now extract an ISO or generate a distro.'
1968 newline
1969 ;;
1972 gen-iso)
1973 # Simply generate a new iso.
1975 check_root
1976 verify_rootcd
1977 gen_livecd_isolinux
1978 distro_stats
1979 ;;
1982 gen-initiso)
1983 # Simply generate a new initramfs with a new iso.
1985 check_root
1986 verify_rootcd
1987 gen_initramfs "$ROOTFS"
1988 gen_livecd_isolinux
1989 distro_stats
1990 ;;
1993 extract-distro)
1994 # Extract an ISO image to a directory and rebuild the LiveCD tree.
1996 check_root
1997 ISO_IMAGE="$2"
1998 [ -z "$ISO_IMAGE" ] && die 'Please specify the path to the ISO image.' \
1999 'Example:\n tazlito image.iso /path/target'
2001 # Set the distro path by checking for $3 on cmdline.
2002 TARGET="${3:-$DISTRO}"
2004 # Exit if existing distro is found.
2005 [ -d "$TARGET/rootfs" ] && die "A rootfs exists in '$TARGET'." \
2006 'Please clean the distro tree or change directory path.'
2008 title 'Tazlito extracting: %s' "$(basename $ISO_IMAGE)"
2010 # Start to mount the ISO.
2011 action 'Mounting ISO image...'
2012 mkdir -p "$TMP_DIR"
2013 # Get ISO file size.
2014 isosize=$(du -sh "$ISO_IMAGE" | cut -f1)
2015 mount -o loop -r "$ISO_IMAGE" "$TMP_DIR"
2016 sleep 2
2017 # Prepare target dir, copy the kernel and the rootfs.
2018 mkdir -p "$TARGET/rootfs" "$TARGET/rootcd/boot"
2019 status
2021 action 'Copying the Linux kernel...'
2022 if cp $TMP_DIR/boot/vmlinuz* "$TARGET/rootcd/boot" 2>/dev/null; then
2023 make_bzImage_hardlink "$TARGET/rootcd/boot"
2024 else
2025 cp "$TMP_DIR/boot/bzImage" "$TARGET/rootcd/boot"
2026 fi
2027 status
2029 for i in $(ls $TMP_DIR); do
2030 [ "$i" == 'boot' ] && continue
2031 cp -a "$TMP_DIR/$i" "$TARGET/rootcd"
2032 done
2034 for loader in isolinux syslinux extlinux grub; do
2035 [ -d "$TMP_DIR/boot/$loader" ] || continue
2036 action 'Copying %s files...' "$loader"
2037 cp -a "$TMP_DIR/boot/$loader" "$TARGET/rootcd/boot"
2038 status
2039 done
2041 action 'Copying the rootfs...'
2042 cp $TMP_DIR/boot/rootfs*.?z "$TARGET/rootcd/boot"
2043 status
2045 # Extract initramfs.
2046 cd "$TARGET/rootfs"
2047 action 'Extracting the rootfs...'
2048 extract_rootfs "$TARGET/rootcd/boot/$INITRAMFS" "$TARGET/rootfs"
2049 # unpack /usr
2050 for i in etc/tazlito/*.extract; do
2051 [ -f "$i" ] && . $i ../rootcd
2052 done
2053 # Umount and remove temp directory and cd to $TARGET to get stats.
2054 umount "$TMP_DIR" && rm -rf "$TMP_DIR"
2055 cd ..
2056 status
2058 newline
2059 separator
2060 echo "Extracted : $(basename $ISO_IMAGE) ($isosize)"
2061 echo "Distro tree : $(pwd)"
2062 echo "Rootfs size : $(du -sh rootfs)"
2063 echo "Rootcd size : $(du -sh rootcd)"
2064 footer
2065 ;;
2068 list-flavors)
2069 # Show available flavors.
2070 list='/etc/tazlito/flavors.list'
2071 [ ! -s $list -o -n "$recharge" ] && download flavors.list -O - > $list
2072 title 'List of flavors'
2073 cat $list
2074 footer
2075 ;;
2078 show-flavor)
2079 # Show flavor descriptions.
2080 set -e
2081 flavor=${2%.flavor}
2082 flv_dir="$(extract_flavor "$flavor")"
2083 desc="$flv_dir/$flavor.desc"
2084 if [ -n "$brief" ]; then
2085 if [ -z "$noheader" ]; then
2086 printf "%-16.16s %6.6s %6.6s %s\n" 'Name' 'ISO' 'Rootfs' 'Description'
2087 separator
2088 fi
2089 printf "%-16.16s %6.6s %6.6s %s\n" "$flavor" \
2090 "$(field ISO "$desc")" \
2091 "$(field Rootfs "$desc")" \
2092 "$(field Description "$desc")"
2093 else
2094 separator
2095 cat "$desc"
2096 fi
2097 cleanup
2098 ;;
2101 gen-liveflavor)
2102 # Generate a new flavor from the live system.
2103 FLAVOR=${2%.flavor}
2104 [ -z "$FLAVOR" ] && die 'Please specify flavor name on the commandline.'
2106 case "$FLAVOR" in
2107 -?|-h*|--help)
2108 cat <<EOT
2109 SliTaz Live Tool - Version: $VERSION
2111 $(boldify 'Usage:') tazlito gen-liveflavor <flavor-name> [<flavor-patch-file>]
2113 $(boldify '<flavor-patch-file> format:')
2114 $(optlist "\
2115 code data
2116 + package to add
2117 - package to remove
2118 ! non-free package to add
2119 ? display message
2120 @ flavor description
2121 ")
2123 $(boldify 'Example:')
2124 $(optlist "\
2125 @ Developer tools for SliTaz maintainers
2126 + slitaz-toolchain
2127 + mercurial
2128 ")
2129 EOT
2130 exit 1
2131 ;;
2132 esac
2133 mv /etc/tazlito/distro-packages.list \
2134 /etc/tazlito/distro-packages.list.$$ 2>/dev/null
2135 rm -f distro-packages.list non-free.list 2>/dev/null
2136 tazpkg recharge
2138 DESC=""
2139 [ -n "$3" ] && \
2140 while read action pkg; do
2141 case "$action" in
2142 +) yes | tazpkg get-install $pkg 2>&1 >> $log || exit 1 ;;
2143 -) yes | tazpkg remove $pkg ;;
2144 !) echo $pkg >> non-free.list ;;
2145 @) DESC="$pkg" ;;
2146 \?) echo -en "$pkg"; read action ;;
2147 esac
2148 done < $3
2150 yes '' | tazlito gen-distro
2151 echo "$DESC" | tazlito gen-flavor "$FLAVOR"
2152 mv /etc/tazlito/distro-packages.list.$$ \
2153 /etc/tazlito/distro-packages.list 2>/dev/null
2154 ;;
2157 gen-flavor)
2158 # Generate a new flavor from the last ISO image generated
2159 FLAVOR=${2%.flavor}
2160 [ -z "$FLAVOR" ] && die 'Please specify flavor name on the commandline.'
2162 title 'Flavor generation'
2163 check_rootfs
2164 FILES="$FLAVOR.pkglist"
2166 action 'Creating file %s...' "$FLAVOR.flavor"
2167 for i in rootcd rootfs; do
2168 if [ -d "$ADDFILES/$i" ] ; then
2169 FILES="$FILES\n$FLAVOR.$i"
2170 ( cd "$ADDFILES/$i"; find . ) | cpio -o -H newc 2>/dev/null | dogzip $FLAVOR.$i
2171 fi
2172 done
2173 status
2175 answer=$(grep -s ^Description $FLAVOR.desc)
2176 answer=${answer#Description : }
2177 if [ -z "$answer" ]; then
2178 echo -n "Description: "
2179 read answer
2180 fi
2182 action 'Compressing flavor %s...' "$FLAVOR"
2183 echo "Flavor : $FLAVOR" > $FLAVOR.desc
2184 echo "Description : $answer" >> $FLAVOR.desc
2185 (cd $DISTRO; distro_sizes) >> $FLAVOR.desc
2186 \rm -f $FLAVOR.pkglist $FLAVOR.nonfree 2>/dev/null
2187 for i in $(ls $ROOTFS$INSTALLED); do
2188 eval $(grep ^VERSION= $ROOTFS$INSTALLED/$i/receipt)
2189 EXTRAVERSION=""
2190 eval $(grep ^EXTRAVERSION= $ROOTFS$INSTALLED/$i/receipt)
2191 eval $(grep ^CATEGORY= $ROOTFS$INSTALLED/$i/receipt)
2192 if [ "$CATEGORY" == 'non-free' -a "${i%%-*}" != 'get' ]; then
2193 echo "$i" >> $FLAVOR.nonfree
2194 else
2195 echo "$i-$VERSION$EXTRAVERSION" >> $FLAVOR.pkglist
2196 fi
2197 done
2198 [ -s $FLAVOR.nonfree ] && $FILES="$FILES\n$FLAVOR.nonfree"
2199 for i in $LOCALSTATE/undigest/*/mirror ; do
2200 [ -s $i ] && cat $i >> $FLAVOR.mirrors
2201 done
2202 [ -s $FLAVOR.mirrors ] && $FILES="$FILES\n$FLAVOR.mirrors"
2203 touch -t 197001010100.00 $FLAVOR.*
2204 echo -e "$FLAVOR.desc\n$FILES" | cpio -o -H newc 2>/dev/null | dogzip $FLAVOR.flavor
2205 rm $(echo -e $FILES)
2206 status
2208 footer "Flavor size: $(du -sh $FLAVOR.flavor)"
2209 ;;
2212 upgrade-flavor)
2213 # Strip versions from pkglist and update estimated numbers in flavor.desc
2214 flavor="${2%.flavor}"
2215 set -e
2216 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2217 set +e
2219 flv_dir="$(extract_flavor "$flavor")"
2221 strip_versions "$flv_dir/$flavor.pkglist"
2223 action 'Updating %s...' "$flavor.desc"
2225 [ -f "$flv_dir/$flavor.mirrors" ] && setup_mirrors "$flv_dir/$flavor.mirrors" >/dev/null
2226 set -- $(module calc_sizes "$flv_dir" "$flavor")
2227 restore_mirrors >/dev/null
2229 sed -i -e '/Image is ready/d' \
2230 -e "s|\(Rootfs size *:\).*$|\1 $1 (estimated)|" \
2231 -e "s|\(Initramfs size *:\).*$|\1 $2 (estimated)|" \
2232 -e "s|\(ISO image size *:\).*$|\1 $3 (estimated)|" \
2233 -e "s|\(Packages *:\).*$|\1 $4|" \
2234 -e "s|\(Build date *:\).*$|\1 $(date '+%Y%m%d at %T')|" \
2235 "$flv_dir/$flavor.desc"
2237 pack_flavor "$flv_dir" "$flavor"
2238 status
2239 display_unknown "$flv_dir/err"
2240 display_warn "$flv_dir/warn"
2241 cleanup
2242 ;;
2245 extract-flavor)
2246 # Extract a flavor into $FLAVORS_REPOSITORY
2247 flavor="${2%.flavor}"
2248 set -e
2249 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2250 set +e
2252 action 'Extracting %s...' "$flavor.flavor"
2253 flv_dir="$(extract_flavor "$flavor" full)"
2254 storage="$FLAVORS_REPOSITORY/$flavor"
2256 rm -rf "$storage" 2>/dev/null
2257 mkdir -p "$storage"
2258 cp -a "$flv_dir"/* "$storage"
2259 rm "$storage/description"
2260 status
2262 strip_versions "$storage/packages.list"
2264 cleanup
2265 ;;
2268 pack-flavor)
2269 # Create a flavor from $FLAVORS_REPOSITORY.
2270 flavor=${2%.flavor}
2271 storage="$FLAVORS_REPOSITORY/$flavor"
2273 [ -s "$storage/receipt" ] || die "No $flavor receipt in $FLAVORS_REPOSITORY."
2275 action 'Creating flavor %s...' "$flavor"
2276 tmp_dir="$(mktemp -d)"
2278 while read from to; do
2279 [ -s "$storage/$from" ] || continue
2280 cp -a "$storage/$from" "$tmp_dir/$to"
2281 done <<EOT
2282 mirrors $flavor.mirrors
2283 distro.sh $flavor-distro.sh
2284 receipt $flavor.receipt
2285 non-free.list $flavor.nonfree
2286 EOT
2288 # Build the package list.
2289 # It can include a list from another flavor with the keyword @include
2290 if [ -s "$storage/packages.list" ]; then
2291 include=$(grep '^@include' "$storage/packages.list")
2292 if [ -n "$include" ]; then
2293 include=${include#@include }
2294 if [ -s "$FLAVORS_REPOSITORY/$include/packages.list" ]; then
2295 cp -f "$FLAVORS_REPOSITORY/$include/packages.list" "$tmp_dir/$flavor.pkglist"
2296 else
2297 echo -e "\nERROR: Can't find include package list from $include\n"
2298 fi
2299 fi
2300 # Generate the final/initial package list
2301 [ -s "$storage/packages.list" ] && \
2302 cat "$storage/packages.list" >> "$tmp_dir/$flavor.pkglist"
2303 sed -i '/@include/d' "$tmp_dir/$flavor.pkglist"
2304 fi
2306 if grep -q ^ROOTFS_SELECTION "$storage/receipt"; then
2307 # Process multi-rootfs flavor
2308 . "$storage/receipt"
2309 set -- $ROOTFS_SELECTION
2310 [ -n "$FRUGAL_RAM" ] || FRUGAL_RAM=$1
2311 [ -f "$FLAVORS_REPOSITORY/$2/packages.list" ] || tazlito extract-flavor $2
2312 cp "$FLAVORS_REPOSITORY/$2/packages.list" "$tmp_dir/$flavor.pkglist"
2314 for i in rootcd rootfs; do
2315 mkdir "$tmp_dir/$i"
2316 # Copy extra files from the first flavor
2317 [ -d "$FLAVORS_REPOSITORY/$2/$i" ] &&
2318 cp -a "$FLAVORS_REPOSITORY/$2/$i" "$tmp_dir"
2319 # Overload extra files by meta flavor
2320 [ -d "$storage/$i" ] && cp -a "$storage/$i" "$tmp_dir"
2321 [ -n "$(ls $tmp_dir/$i)" ] &&
2322 (cd "$tmp_dir/$i"; find . | cpio -o -H newc 2>/dev/null ) | \
2323 dogzip "$tmp_dir/$flavor.$i"
2324 rm -rf "$tmp_dir/$i"
2325 done
2326 else
2327 # Process plain flavor
2328 for i in rootcd rootfs; do
2329 [ -d "$storage/$i" ] || continue
2330 (cd "$storage/$i";
2331 find . | cpio -o -H newc 2>/dev/null) | dogzip "$tmp_dir/$flavor.$i"
2332 done
2333 fi
2335 unset VERSION MAINTAINER ROOTFS_SELECTION
2336 set -- $(module calc_sizes "$tmp_dir" "$flavor")
2337 ROOTFS_SIZE="$1 (estimated)"
2338 INITRAMFS_SIZE="$2 (estimated)"
2339 ISO_SIZE="$3 (estimated)"
2340 PKGNUM="$4"
2341 . "$storage/receipt"
2343 sed '/: $/d' > "$tmp_dir/$flavor.desc" <<EOT
2344 Flavor : $FLAVOR
2345 Description : $SHORT_DESC
2346 Version : $VERSION
2347 Maintainer : $MAINTAINER
2348 LiveCD RAM size : $FRUGAL_RAM
2349 Rootfs list : $ROOTFS_SELECTION
2350 Build date : $(date '+%Y%m%d at %T')
2351 Packages : $PKGNUM
2352 Rootfs size : $ROOTFS_SIZE
2353 Initramfs size : $INITRAMFS_SIZE
2354 ISO image size : $ISO_SIZE
2355 ================================================================================
2357 EOT
2359 rm -f $tmp_dir/packages.list
2360 pack_flavor "$tmp_dir" "$flavor"
2361 status
2362 display_unknown "$tmp_dir/err"
2363 display_warn "$flv_dir/warn"
2364 cleanup
2365 ;;
2368 get-flavor)
2369 # Get a flavor's files and prepare for gen-distro.
2370 flavor=${2%.flavor}
2371 title 'Preparing %s distro flavor' "$flavor"
2372 set -e
2373 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2374 set +e
2376 action 'Cleaning %s...' "$DISTRO"
2377 [ -d "$DISTRO" ] && rm -r "$DISTRO"
2378 # Clean old files
2379 for i in non-free.list distro-packages.list distro.sh receipt mirrors err; do
2380 [ -f "$i" ] && rm "$i"
2381 done
2382 mkdir -p "$DISTRO"
2383 status
2385 [ -z "$noup" ] && tazlito upgrade-flavor "$flavor.flavor"
2387 action 'Extracting flavor %s...' "$flavor.flavor"
2388 flv_dir="$(extract_flavor "$flavor" info)"
2389 cp -a "$flv_dir"/* .
2390 mv packages.list distro-packages.list
2391 mv -f info /etc/tazlito
2392 status
2394 for i in rootcd rootfs; do
2395 if [ -d "$i" ]; then
2396 mkdir -p "$ADDFILES"; mv "$i" "$ADDFILES/$i"
2397 fi
2398 done
2400 sed '/^Rootfs list/!d;s/.*: //' description > /etc/tazlito/rootfs.list
2401 [ -s /etc/tazlito/rootfs.list ] || rm -f /etc/tazlito/rootfs.list
2403 action 'Updating %s...' 'tazlito.conf'
2404 [ -f tazlito.conf ] || cp /etc/tazlito/tazlito.conf .
2405 grep -v "^#VOLUM_NAME" < tazlito.conf | \
2406 sed "s/^VOLUM_NA/VOLUM_NAME=\"SliTaz $flavor\"\\n#VOLUM_NA/" \
2407 > tazlito.conf.$$ && mv tazlito.conf.$$ tazlito.conf
2408 sed -i "s/ISO_NAME=.*/ISO_NAME=\"slitaz-$flavor\"/" tazlito.conf
2409 status
2411 footer 'Flavor is ready to be generated by `tazlito gen-distro`'
2412 cleanup
2413 ;;
2416 iso2flavor)
2417 [ -z "$3" -o ! -s "$2" ] && die 'Usage: tazlito iso2flavor <image.iso> <flavor_name>' \
2418 '\n\nCreate a file <flavor_name>.flavor from the CD-ROM image file <image.iso>'
2420 FLAVOR=${3%.flavor}
2421 mkdir -p $TMP_DIR/iso $TMP_DIR/rootfs $TMP_DIR/flavor
2422 mount -o loop,ro $2 $TMP_DIR/iso
2423 flavordata $2 | (cd $TMP_DIR/flavor; cpio -i 2>/dev/null)
2424 if [ -s $TMP_DIR/iso/boot/rootfs1.gz -a \
2425 ! -s $TMP_DIR/flavor/*.desc ]; then
2426 _ 'META flavors are not supported.'
2427 umount -d $TMP_DIR/iso
2428 elif [ ! -s $TMP_DIR/iso/boot/rootfs.gz -a \
2429 ! -s $TMP_DIR/iso/boot/rootfs1.gz ]; then
2430 _ 'No %s in ISO image. Needs a SliTaz ISO.' '/boot/rootfs.gz'
2431 umount -d $TMP_DIR/iso
2432 else
2433 for i in $(ls -r $TMP_DIR/iso/boot/rootfs*z); do
2434 uncompress $i | \
2435 ( cd $TMP_DIR/rootfs ; cpio -idmu > /dev/null 2>&1 )
2436 done
2437 if [ ! -s $TMP_DIR/rootfs/etc/slitaz-release ]; then
2438 _ 'No file %s in %s of ISO image. Needs a non-loram SliTaz ISO.' \
2439 '/etc/slitaz-release' '/boot/rootfs.gz'
2440 umount -d $TMP_DIR/iso
2441 else
2442 ROOTFS_SIZE=$(du -hs $TMP_DIR/rootfs | awk '{ print $1 }')
2443 RAM_SIZE=$(du -s $TMP_DIR/rootfs | awk '{ print 32*int(($1+36000)/32768) "M" }')
2444 cp -a $TMP_DIR/iso $TMP_DIR/rootcd
2445 ISO_SIZE=$(df -h $TMP_DIR/iso | awk 'END { print $2 }')
2446 BUILD_DATE=$(date '+%Y%m%d at %T' -r "$TMP_DIR/iso/md5sum")
2447 umount -d $TMP_DIR/iso
2448 INITRAMFS_SIZE=$(du -chs $TMP_DIR/rootcd/boot/rootfs*.gz | awk 'END { print $1 }')
2449 rm -f $TMP_DIR/rootcd/boot/rootfs.gz $TMP_DIR/rootcd/md5sum
2450 mv $TMP_DIR/rootcd/boot $TMP_DIR/rootfs
2451 [ -d $TMP_DIR/rootcd/efi ] && mv $TMP_DIR/rootcd/efi $TMP_DIR/rootfs
2452 sed 's/.* \(.*\).tazpkg*/\1/' > $TMP_DIR/$FLAVOR.pkglist \
2453 < $TMP_DIR/rootfs$INSTALLED.md5
2454 PKGCNT=$(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l | awk '{ print $1 }')
2455 if [ -s $TMP_DIR/flavor/*desc ]; then
2456 cp $TMP_DIR/flavor/*.desc $TMP_DIR/$FLAVOR.desc
2457 [ -s $TMP_DIR/$FLAVOR.receipt ] &&
2458 cp $TMP_DIR/flavor/*.receipt $TMP_DIR/$FLAVOR.receipt
2459 for i in rootfs rootcd ; do
2460 [ -s $TMP_DIR/flavor/*.list$i ] &&
2461 sed 's/.\{1,45\}//;/^\.$/d' $TMP_DIR/flavor/*.list$i | \
2462 ( cd $TMP_DIR/$i ; cpio -o -H newc ) | dogzip $TMP_DIR/$FLAVOR.$i
2463 done
2464 else
2465 find_flavor_rootfs $TMP_DIR/rootfs
2466 [ -d $TMP_DIR/rootfs/boot ] && mv $TMP_DIR/rootfs/boot $TMP_DIR/rootcd
2467 [ -d $TMP_DIR/rootfs/efi ] && mv $TMP_DIR/rootfs/efi $TMP_DIR/rootcd
2468 for i in rootfs rootcd ; do
2469 [ "$(ls $TMP_DIR/$i)" ] &&
2470 ( cd "$TMP_DIR/$i"; find * | cpio -o -H newc ) | dogzip "$TMP_DIR/$FLAVOR.$i"
2471 done
2472 unset VERSION MAINTAINER
2473 echo -en "Flavor short description \007: "; read -t 30 DESCRIPTION
2474 if [ -n "$DESCRIPTION" ]; then
2475 _n 'Flavor version : '; read -t 30 VERSION
2476 _n 'Flavor maintainer (your email) : '; read -t 30 MAINTAINER
2477 fi
2479 cat > $TMP_DIR/$FLAVOR.desc <<EOT
2480 Flavor : $FLAVOR
2481 Description : ${DESCRIPTION:-SliTaz $FLAVOR flavor}
2482 Version : ${VERSION:-1.0}
2483 Maintainer : ${MAINTAINER:-nobody@slitaz.org}
2484 LiveCD RAM size : $RAM_SIZE
2485 Build date : $BUILD_DATE
2486 Packages : $PKGCNT
2487 Rootfs size : $ROOTFS_SIZE
2488 Initramfs size : $INITRAMFS_SIZE
2489 ISO image size : $ISO_SIZE
2490 ================================================================================
2492 EOT
2493 longline "Tazlito can't detect each file installed during \
2494 a package post_install. You should extract this flavor (tazlito extract-flavor \
2495 $FLAVOR), check the files in /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/rootfs \
2496 tree and remove files generated by post_installs.
2497 Check /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/receipt too and \
2498 repack the flavor (tazlito pack-flavor $FLAVOR)"
2499 fi
2500 ( cd $TMP_DIR; ls $FLAVOR.* | cpio -o -H newc ) | dogzip $FLAVOR.flavor
2501 fi
2502 fi
2503 rm -rf $TMP_DIR
2504 ;;
2507 gen-distro)
2508 # Generate a live distro tree with a set of packages.
2510 check_root
2511 start_time=$(date +%s)
2513 # Tazlito options: --iso or --cdrom
2514 CDROM=''
2515 [ -n "$iso" ] && CDROM="-o loop $iso"
2516 [ -n "$cdrom" ] && CDROM="/dev/cdrom"
2518 # Check if a package list was specified on cmdline.
2519 if [ -f "$2" ]; then
2520 LIST_NAME="$2"
2521 else
2522 LIST_NAME='distro-packages.list'
2523 fi
2525 [ -d "$ROOTFS" -a -z "$forced" ] && die "A rootfs exists in '$DISTRO'." \
2526 'Please clean the distro tree or change directory path.'
2527 [ -d "$ROOTFS" ] && rm -rf "$ROOTFS"
2528 [ -d "$ROOTCD" ] && rm -rf "$ROOTCD"
2530 # If list not given: build list with all installed packages
2531 if [ ! -f "$LIST_NAME" -a -f "$LOCALSTATE/installed.info" ]; then
2532 awk -F$'\t' '{print $1}' "$LOCALSTATE/installed.info" >> "$LIST_NAME"
2533 fi
2535 # Exit if no list name.
2536 [ ! -f "$LIST_NAME" ] && die 'No packages list found or specified. Please read the docs.'
2538 # Start generation.
2539 title 'Tazlito generating a distro'
2541 # Misc checks
2542 mkdir -p "$PACKAGES_REPOSITORY"
2543 REPACK=$(yesorno 'Repack packages from rootfs?' 'n')
2544 newline
2546 # Mount CD-ROM to be able to repack boot-loader packages
2547 if [ ! -e /boot -a -n "$CDROM" ]; then
2548 mkdir $TMP_MNT
2549 if mount -r "$CDROM $TMP_MNT" 2>/dev/null; then
2550 ln -s "$TMP_MNT/boot" /
2551 if [ ! -d "$ADDFILES/rootcd" ] ; then
2552 mkdir -p "$ADDFILES/rootcd"
2553 for i in $(ls $TMP_MNT); do
2554 [ "$i" == 'boot' ] && continue
2555 cp -a "$TMP_MNT/$i" "$ADDFILES/rootcd"
2556 done
2557 fi
2558 else
2559 rmdir "$TMP_MNT"
2560 fi
2561 fi
2563 # Rootfs stuff.
2564 echo 'Preparing the rootfs directory...'
2565 mkdir -p "$ROOTFS"
2566 export root="$ROOTFS"
2567 # pass current 'mirror' to the root
2568 mkdir -p $root/var/lib/tazpkg $root/etc
2569 cp -f /var/lib/tazpkg/mirror $root/var/lib/tazpkg/mirror
2570 cp -f /etc/slitaz-release $root/etc/slitaz-release
2571 strip_versions "$LIST_NAME"
2573 if [ "$REPACK" == 'y' ]; then
2574 # Determine full packages list with all dependencies
2575 tmp_dir="$(mktemp -d)"
2576 cp "$LIST_NAME" "$tmp_dir/flavor.pkglist"
2577 touch "$tmp_dir/full.pkglist"
2578 module calc_sizes "$tmp_dir" 'flavor' "$tmp_dir/full.pkglist" >/dev/null
2580 awk -F$'\t' '{printf "%s %s\n", $1, $2}' "$LOCALSTATE/installed.info" | \
2581 while read pkgname pkgver; do
2582 # Is package in full list?
2583 grep -q "^$pkgname$" "$tmp_dir/full.pkglist" || continue
2584 # Is package already repacked?
2585 [ -e "$PACKAGES_REPOSITORY/$pkgname-$pkgver.tazpkg" ] && continue
2586 _ 'Repacking %s...' "$pkgname-$pkgver"
2587 tazpkg repack "$pkgname" --quiet
2588 [ -f "$pkgname-$pkgver.tazpkg" ] && mv "$pkgname-$pkgver.tazpkg" "$PACKAGES_REPOSITORY"
2589 status
2590 done
2592 rm -r "$tmp_dir"
2593 fi
2595 if [ -f non-free.list ]; then
2596 # FIXME: working in the ROOTFS chroot?
2597 newline
2598 echo 'Preparing non-free packages...'
2599 cp 'non-free.list' "$ROOTFS/etc/tazlito/non-free.list"
2600 for pkg in $(cat 'non-free.list'); do
2601 if [ ! -d "$INSTALLED/$pkg" ]; then
2602 if [ ! -d "$INSTALLED/get-$pkg" ]; then
2603 tazpkg get-install get-$pkg
2604 fi
2605 get-$pkg "$ROOTFS"
2606 fi
2607 tazpkg repack $pkg
2608 pkg=$(ls $pkg*.tazpkg)
2609 grep -q "^$pkg$" $LIST_NAME || echo $pkg >> $LIST_NAME
2610 mv $pkg $PACKAGES_REPOSITORY
2611 done
2612 fi
2613 cp $LIST_NAME $DISTRO/distro-packages.list
2614 newline
2616 install_list_to_rootfs "$DISTRO/distro-packages.list" "$ROOTFS"
2618 cd $DISTRO
2619 cp distro-packages.list $ROOTFS/etc/tazlito
2620 # Copy all files from $ADDFILES/rootfs to the rootfs.
2621 if [ -d "$ADDFILES/rootfs" ] ; then
2622 action 'Copying addfiles content to the rootfs...'
2623 cp -a $ADDFILES/rootfs/* $ROOTFS
2624 status
2625 fi
2627 action 'Root filesystem is generated...'; status
2629 # Root CD part.
2630 action 'Preparing the rootcd directory...'
2631 mkdir -p $ROOTCD
2632 status
2634 # Move the boot dir with the Linux kernel from rootfs.
2635 # The efi & boot dirs go directly on the CD.
2636 if [ -d "$ROOTFS/efi" ] ; then
2637 action 'Moving the efi directory...'
2638 mv $ROOTFS/efi $ROOTCD
2639 status
2640 fi
2641 if [ -d "$ROOTFS/boot" ] ; then
2642 action 'Moving the boot directory...'
2643 mv $ROOTFS/boot $ROOTCD
2644 status
2645 fi
2646 cd $DISTRO
2647 # Copy all files from $ADDFILES/rootcd to the rootcd.
2648 if [ -d "$ADDFILES/rootcd" ] ; then
2649 action 'Copying addfiles content to the rootcd...'
2650 cp -a $ADDFILES/rootcd/* $ROOTCD
2651 status
2652 fi
2653 # Execute the distro script used to perform tasks in the rootfs
2654 # before compression. Give rootfs path in arg
2655 [ -z "$DISTRO_SCRIPT" ] && DISTRO_SCRIPT="$TOP_DIR/distro.sh"
2656 if [ -x "$DISTRO_SCRIPT" ]; then
2657 echo 'Executing distro script...'
2658 sh $DISTRO_SCRIPT $DISTRO
2659 fi
2661 # Execute the custom_rules() found in receipt.
2662 if [ -s "$TOP_DIR/receipt" ]; then
2663 if grep -q ^custom_rules "$TOP_DIR/receipt"; then
2664 echo -e "Executing: custom_rules()\n"
2665 . "$TOP_DIR/receipt"
2666 custom_rules || echo -e "\nERROR: custom_rules() failed\n"
2667 fi
2668 fi
2670 # Multi-rootfs
2671 if [ -s /etc/tazlito/rootfs.list ]; then
2673 FLAVOR_LIST="$(awk '{
2674 for (i = 2; i <= NF; i+=2)
2675 printf "%s ", $i;
2676 }' /etc/tazlito/rootfs.list)"
2678 [ -s "$ROOTCD/boot/isolinux/isolinux.msg" ] &&
2679 sed -i "s/ *//;s/)/), flavors $FLAVOR_LIST/" \
2680 "$ROOTCD/boot/isolinux/isolinux.msg" 2>/dev/null
2682 [ -f "$ROOTCD/boot/isolinux/ifmem.c32" -o \
2683 -f "$ROOTCD/boot/isolinux/c32box.c32" ] ||
2684 cp '/boot/isolinux/c32box.c32' "$ROOTCD/boot/isolinux" 2>/dev/null ||
2685 cp '/boot/isolinux/ifmem.c32' "$ROOTCD/boot/isolinux"
2687 n=0
2688 last=$ROOTFS
2689 while read flavor; do
2690 n=$(($n+1))
2691 mkdir ${ROOTFS}0$n
2692 export root="${ROOTFS}0$n"
2693 # initial tazpkg setup in empty rootfs
2694 tazpkg --root=$root >/dev/null 2>&1
2696 newline
2697 boldify "Building $flavor rootfs..."
2699 [ -s "$TOP_DIR/$flavor.flavor" ] &&
2700 cp "$TOP_DIR/$flavor.flavor" .
2702 if [ ! -s "$flavor.flavor" ]; then
2703 # We may have it in $FLAVORS_REPOSITORY
2704 if [ -d "$FLAVORS_REPOSITORY/$flavor" ]; then
2705 tazlito pack-flavor $flavor
2706 else
2707 download $flavor.flavor
2708 fi
2709 fi
2711 action 'Extracting %s and %s...' "$flavor.pkglist" "$flavor.rootfs"
2712 zcat $flavor.flavor | cpio -i --quiet $flavor.pkglist $flavor.rootfs
2713 cp $flavor.pkglist $DISTRO/list-packages0$n
2714 status
2716 strip_versions "$DISTRO/list-packages0$n"
2718 install_list_to_rootfs "$DISTRO/list-packages0$n" "${ROOTFS}0$n"
2720 action 'Updating the boot directory...'
2721 yes n | cp -ai ${ROOTFS}0$n/boot $ROOTCD 2> /dev/null
2722 rm -rf ${ROOTFS}0$n/boot
2724 cd $DISTRO
2725 if [ -s $flavor.rootfs ]; then
2726 _n 'Adding %s rootfs extra files...' "$flavor"
2727 zcat < $flavor.rootfs | ( cd ${ROOTFS}0$n ; cpio -idmu )
2728 fi
2730 action 'Moving %s to %s' "list-packages0$n" "rootfs0$n"
2731 mv "$DISTRO/list-packages0$n" "${ROOTFS}0$n/etc/tazlito/distro-packages.list"
2732 status
2734 rm -f $flavor.flavor install-list
2735 mergefs ${ROOTFS}0$n $last
2736 last=${ROOTFS}0$n
2737 done <<EOT
2738 $(awk '{ for (i = 4; i <= NF; i+=2) print $i; }' < /etc/tazlito/rootfs.list)
2739 EOT
2740 #'
2741 i=$(($n+1))
2742 while [ $n -gt 0 ]; do
2743 mv ${ROOTFS}0$n ${ROOTFS}$i
2744 _ 'Compressing %s (%s)...' "${ROOTFS}0$n" "$(du -hs ${ROOTFS}$i | awk '{ print $1 }')"
2745 gen_initramfs ${ROOTFS}$i
2746 n=$(($n-1))
2747 i=$(($i-1))
2748 export LZMA_HISTORY_BITS=26
2749 done
2750 mv $ROOTFS ${ROOTFS}$i
2751 gen_initramfs ${ROOTFS}$i
2752 update_bootconfig "$ROOTCD/boot/isolinux" "$(cat /etc/tazlito/rootfs.list)"
2753 ROOTFS=${ROOTFS}1
2754 else
2755 # Initramfs and ISO image stuff.
2756 gen_initramfs $ROOTFS
2757 fi
2758 gen_livecd_isolinux
2759 distro_stats
2760 cleanup
2761 ;;
2764 clean-distro)
2765 # Remove old distro tree.
2767 check_root
2768 title 'Cleaning: %s' "$DISTRO"
2769 if [ -d "$DISTRO" ] ; then
2770 if [ -d "$ROOTFS" ] ; then
2771 action 'Removing the rootfs...'
2772 rm -f $DISTRO/$INITRAMFS
2773 rm -rf $ROOTFS
2774 status
2775 fi
2776 if [ -d "$ROOTCD" ] ; then
2777 action 'Removing the rootcd...'
2778 rm -rf $ROOTCD
2779 status
2780 fi
2781 action 'Removing eventual ISO image...'
2782 rm -f $DISTRO/$ISO_NAME.iso
2783 rm -f $DISTRO/$ISO_NAME.md5
2784 status
2785 fi
2786 footer
2787 ;;
2790 check-distro)
2791 # Check for a few LiveCD needed files not installed by packages.
2793 # TODO: Remove this function.
2794 # First two files are maintained by tazpkg while it runs on rootfs,
2795 # while last one file should be maintained by tazlito itself.
2796 check_rootfs
2797 title 'Checking distro: %s' "$ROOTFS"
2798 # SliTaz release info.
2799 rel='/etc/slitaz-release'
2800 if [ ! -f "$ROOTFS$rel" ]; then
2801 _ 'Missing release info: %s' "$rel"
2802 else
2803 action 'Release : %s' "$(cat $ROOTFS$rel)"
2804 status
2805 fi
2806 # Tazpkg mirror.
2807 if [ ! -f "$ROOTFS$LOCALSTATE/mirror" ]; then
2808 action 'Mirror URL : Missing %s' "$LOCALSTATE/mirror"
2809 todomsg
2810 else
2811 action 'Mirror configuration exists...'
2812 status
2813 fi
2814 # Isolinux msg
2815 if grep -q "cooking-XXXXXXXX" /$ROOTCD/boot/isolinux/isolinux.*g; then
2816 action 'Isolinux msg : Missing cooking date XXXXXXXX (ex %s)' "$(date +%Y%m%d)"
2817 todomsg
2818 else
2819 action 'Isolinux message seems good...'
2820 status
2821 fi
2822 footer
2823 ;;
2826 writeiso)
2827 # Writefs to ISO image including /home unlike gen-distro we don't use
2828 # packages to generate a rootfs, we build a compressed rootfs with all
2829 # the current filesystem similar to 'tazusb writefs'.
2831 DISTRO='/home/slitaz/distro'
2832 ROOTCD="$DISTRO/rootcd"
2833 COMPRESSION="${2:-none}"
2834 ISO_NAME="${3:-slitaz}"
2835 check_root
2836 # Start info
2837 title 'Write filesystem to ISO'
2838 longline "The command writeiso will write the current filesystem into a \
2839 suitable cpio archive (rootfs.gz) and generate a bootable ISO image (slitaz.iso)."
2840 newline
2841 emsg "<b>Archive compression:</b> <c 36>$COMPRESSION</c>"
2843 [ "$COMPRESSION" == 'gzip' ] && colorize 31 "gzip-compressed rootfs unsupported and may fail to boot"
2844 # Save some space
2845 rm -rf /var/cache/tazpkg/*
2846 rm -f /var/lib/tazpkg/*.bak
2847 rm -rf $DISTRO
2849 # Optionally remove sound card selection and screen resolution.
2850 if [ -z $LaunchedByTazpanel ]; then
2851 anser=$(yesorno 'Do you wish to remove the sound card and screen configs?' 'n')
2852 case $anser in
2853 y)
2854 action 'Removing current sound card and screen configurations...'
2855 rm -f /var/lib/sound-card-driver
2856 rm -f /var/lib/alsa/asound.state
2857 rm -f /etc/X11/xorg.conf ;;
2858 *)
2859 action 'Keeping current sound card and screen configurations...' ;;
2860 esac
2861 status
2862 newline
2864 # Optionally remove i18n settings
2865 anser=$(yesorno 'Do you wish to remove locale/keymap settings?' 'n')
2866 case $anser in
2867 y)
2868 action 'Removing current locale/keymap settings...'
2869 newline > /etc/locale.conf
2870 newline > /etc/keymap.conf ;;
2871 *)
2872 action 'Keeping current locale/keymap settings...' ;;
2873 esac
2874 status
2875 fi
2877 # Clean-up files by default
2878 newline > /etc/udev/rules.d/70-persistent-net.rules
2879 newline > /etc/udev/rules.d/70-persistant-cd.rules
2881 # Create list of files including default user files since it is defined in /etc/passwd
2882 # and some new users might have been added.
2883 cd /
2884 echo 'init' > /tmp/list
2885 for dir in bin etc sbin var dev lib root usr home opt; do
2886 [ -d $dir ] && find $dir
2887 done >> /tmp/list
2889 for dir in proc sys tmp mnt media media/cdrom media/flash media/usbdisk run run/udev; do
2890 [ -d $dir ] && echo $dir
2891 done >> /tmp/list
2893 sed '/var\/run\/.*pid$/d ; /var\/run\/utmp/d ; /.*\/.gvfs/d ; /home\/.*\/.cache\/.*/d' -i /tmp/list
2895 #if [ ! $(find /var/log/slitaz/tazpkg.log -size +4k) = "" ]; then
2896 # sed -i "/var\/log\/slitaz\/tazpkg.log/d" /tmp/list
2897 #fi
2898 mv -f /var/log/wtmp /tmp/tazlito-wtmp
2899 touch /var/log/wtmp
2901 for removelog in auth boot messages dmesg daemon slim .*old Xorg tazpanel cups; do
2902 sed -i "/var\/log\/$removelog/d" /tmp/list
2903 done
2905 # Generate initramfs with specified compression and display rootfs
2906 # size in realtime.
2907 rm -f /tmp/.write-iso* /tmp/rootfs 2>/dev/null
2909 write_initramfs &
2910 sleep 2
2911 cd - > /dev/null
2912 echo -en "\nFilesystem size:"
2913 while [ ! -f /tmp/rootfs ]; do
2914 sleep 1
2915 echo -en "\\033[18G$(du -sh /$INITRAMFS | awk '{print $1}') "
2916 done
2917 mv -f /tmp/tazlito-wtmp /var/log/wtmp
2918 echo -e "\n"
2919 rm -f /tmp/rootfs
2921 # Move freshly generated rootfs to the cdrom.
2922 mkdir -p $ROOTCD/boot
2923 mv -f /$INITRAMFS $ROOTCD/boot
2924 _ 'Located in: %s' "$ROOTCD/boot/$INITRAMFS"
2926 # Now we need the kernel and isolinux files.
2927 copy_from_cd() {
2928 cp /media/cdrom/boot/bzImage* $ROOTCD/boot
2929 cp -a /media/cdrom/boot/isolinux $ROOTCD/boot
2930 unmeta_boot $ROOTCD
2931 umount /media/cdrom
2934 if mount /dev/cdrom /media/cdrom 2>/dev/null; then
2935 copy_from_cd;
2936 elif mount | grep /media/cdrom; then
2937 copy_from_cd;
2938 #elif [ -f "$bootloader" -a -f /boot/vmlinuz*slitaz* ]; then
2939 # [ -f /boot/*slitaz ] && cp /boot/vmlinuz*slitaz $ROOTCD/boot/bzImage
2940 # [ -f /boot/*slitaz64 ] && cp /boot/vmlinuz*slitaz64 $ROOTCD/boot/bzImage64
2941 else
2942 touch /tmp/.write-iso-error
2943 longline "When SliTaz is running in RAM the kernel and bootloader \
2944 files are kept on the CD-ROM. `boldify ' Please insert a Live CD or run:
2945 # mount -o loop slitaz.iso /media/cdrom ' ` to let Tazlito copy the files."
2946 echo -en "----\nENTER to continue..."; read i
2947 [ ! -d /media/cdrom/boot/isolinux ] && exit 1
2948 copy_from_cd
2949 fi
2951 # Generate the iso image.
2952 touch /tmp/.write-iso
2953 newline
2954 cd $DISTRO
2955 create_iso $ISO_NAME.iso $ROOTCD
2956 action 'Creating the ISO md5sum...'
2957 md5sum $ISO_NAME.iso > $ISO_NAME.md5
2958 status
2960 footer "ISO image: $(du -sh $DISTRO/$ISO_NAME.iso)"
2961 rm -f /tmp/.write-iso
2963 if [ -z $LaunchedByTazpanel ]; then
2964 anser=$(yesorno 'Burn ISO to CD-ROM?' 'n')
2965 case $anser in
2966 y)
2967 umount /dev/cdrom 2>/dev/null
2968 eject
2969 echo -n "Please insert a blank CD-ROM and press ENTER..."
2970 read i && sleep 2
2971 tazlito burn-iso $DISTRO/$ISO_NAME.iso
2972 echo -en "----\nENTER to continue..."; read i ;;
2973 *)
2974 exit 0 ;;
2975 esac
2976 fi
2977 ;;
2980 burn-iso)
2981 # Guess CD-ROM device, ask user and burn the ISO.
2983 check_root
2984 DRIVE_NAME=$(grep "drive name" /proc/sys/dev/cdrom/info | cut -f3)
2985 DRIVE_SPEED=$(grep "drive speed" /proc/sys/dev/cdrom/info | cut -f3)
2986 # We can specify an alternative ISO from the cmdline.
2987 iso="${2:-$DISTRO/$ISO_NAME.iso}"
2988 [ ! -f "$iso" ] && die "Unable to find ISO: $iso"
2990 title 'Tazlito burn ISO'
2991 echo "CD-ROM device : /dev/$DRIVE_NAME"
2992 echo "Drive speed : $DRIVE_SPEED"
2993 echo "ISO image : $iso"
2994 footer
2996 case $(yesorno 'Burn ISO image?' 'n') in
2997 y)
2998 title 'Starting Wodim to burn the ISO...'
2999 sleep 2
3000 wodim speed=$DRIVE_SPEED dev=/dev/$DRIVE_NAME $iso
3001 footer 'ISO image is burned to CD-ROM.'
3002 ;;
3003 *)
3004 die 'Exiting. No ISO burned.'
3005 ;;
3006 esac
3007 ;;
3010 merge)
3011 # Merge multiple rootfs into one iso.
3013 if [ -z "$2" ]; then
3014 cat <<EOT
3015 Usage: tazlito merge size1 iso size2 rootfs2 [sizeN rootfsN]...
3017 Merge multiple rootfs into one ISO. Rootfs are like russian dolls
3018 i.e: rootfsN is a subset of rootfsN-1
3019 rootfs1 is found in ISO, sizeN is the RAM size needed to launch rootfsN.
3020 The boot loader will select the rootfs according to the RAM size detected.
3022 Example:
3023 $ tazlito merge 160M slitaz-core.iso 96M rootfs-justx.gz 32M rootfs-base.gz
3025 Will start slitaz-core with 160M+ RAM, slitaz-justX with 96M-160M RAM,
3026 slitaz-base with 32M-96M RAM and display an error message if RAM < 32M.
3028 EOT
3029 exit 2
3030 fi
3032 shift # skip merge
3033 append="$1 slitaz1"
3034 shift # skip size1
3035 mkdir -p $TMP_DIR/mnt $TMP_DIR/rootfs1
3037 ISO=$1.merged
3039 # Extract filesystems
3040 action 'Mounting %s' "$1"
3041 mount -o loop,ro $1 $TMP_DIR/mnt 2> /dev/null
3042 status || cleanup_merge
3044 cp -a $TMP_DIR/mnt $TMP_DIR/iso
3045 make_bzImage_hardlink $TMP_DIR/iso/boot
3046 umount -d $TMP_DIR/mnt
3047 if [ -f $TMP_DIR/iso/boot/rootfs1.gz ]; then
3048 _ '%s is already a merged iso. Aborting.' "$1"
3049 cleanup_merge
3050 fi
3051 if [ ! -f $TMP_DIR/iso/boot/isolinux/ifmem.c32 -a
3052 ! -f $TMP_DIR/iso/boot/isolinux/c32box.c32 ]; then
3053 if [ ! -f /boot/isolinux/ifmem.c32 -a
3054 ! -f /boot/isolinux/c32box.c32 ]; then
3055 cat <<EOT
3056 No file /boot/isolinux/ifmem.c32
3057 Please install syslinux package !
3058 EOT
3059 rm -rf $TMP_DIR
3060 exit 1
3061 fi
3062 cp /boot/isolinux/c32box.c32 $TMP_DIR/iso/boot/isolinux 2> /dev/null ||
3063 cp /boot/isolinux/ifmem.c32 $TMP_DIR/iso/boot/isolinux
3064 fi
3066 action 'Extracting %s' 'iso/rootfs.gz'
3067 extract_rootfs $TMP_DIR/iso/boot/rootfs.gz $TMP_DIR/rootfs1 &&
3068 [ -d $TMP_DIR/rootfs1/etc ]
3069 status || cleanup_merge
3071 n=1
3072 while [ -n "$2" ]; do
3073 shift # skip rootfs N-1
3074 p=$n
3075 n=$(($n + 1))
3076 append="$append $1 slitaz$n"
3077 shift # skip size N
3078 mkdir -p $TMP_DIR/rootfs$n
3080 action 'Extracting %s' "$1"
3081 extract_rootfs $1 $TMP_DIR/rootfs$n &&
3082 [ -d "$TMP_DIR/rootfs$n/etc" ]
3083 status || cleanup_merge
3085 mergefs $TMP_DIR/rootfs$n $TMP_DIR/rootfs$p
3086 action 'Creating %s' "rootfs$p.gz"
3087 pack_rootfs "$TMP_DIR/rootfs$p" "$TMP_DIR/iso/boot/rootfs$p.gz"
3088 status
3089 done
3090 action 'Creating %s' "rootfs$n.gz"
3091 pack_rootfs "$TMP_DIR/rootfs$n" "$TMP_DIR/iso/boot/rootfs$n.gz"
3092 status
3093 rm -f $TMP_DIR/iso/boot/rootfs.gz
3094 update_bootconfig $TMP_DIR/iso/boot/isolinux "$append"
3095 create_iso $ISO $TMP_DIR/iso
3096 rm -rf $TMP_DIR
3097 ;;
3100 repack)
3101 # Repack an iso with maximum lzma compression ratio.
3103 ISO=$2
3104 mkdir -p $TMP_DIR/mnt
3106 # Extract filesystems
3107 action 'Mounting %s' "$ISO"
3108 mount -o loop,ro $ISO $TMP_DIR/mnt 2>/dev/null
3109 status || cleanup_merge
3111 cp -a $TMP_DIR/mnt $TMP_DIR/iso
3112 umount -d $TMP_DIR/mnt
3114 for i in $TMP_DIR/iso/boot/rootfs* ; do
3115 action 'Repacking %s' "$(basename $i)"
3116 uncompress $i 2>/dev/null > $TMP_DIR/rootfs
3117 lzma e $TMP_DIR/rootfs $i $(lzma_switches $TMP_DIR/rootfs)
3118 align_to_32bits $i
3119 status
3120 done
3122 create_iso $ISO $TMP_DIR/iso
3123 rm -rf $TMP_DIR
3124 ;;
3127 build-loram)
3128 # Build a Live CD for low RAM systems.
3130 ISO="$2"
3131 OUTPUT="$3"
3132 [ -z "$3" ] && \
3133 die "Usage: tazlito build-loram <input>.iso <output>.iso [cdrom|smallcdrom|http|ram]"
3134 mkdir -p "$TMP_DIR/iso"
3135 mount -o loop,ro -t iso9660 "$ISO" "$TMP_DIR/iso"
3136 loopdev=$( (losetup -a 2>/dev/null || losetup) | sed "/$(echo $ISO | sed 's|/|\\/|g')$/!d;s/:.*//;q")
3137 if ! check_iso_for_loram ; then
3138 umount -d "$TMP_DIR/iso"
3139 die "$ISO is not a valid SliTaz live CD. Abort."
3140 fi
3141 case "$4" in
3142 cdrom) build_loram_cdrom ;;
3143 http) build_loram_http ;;
3144 *) build_loram_ram "$5" ;;
3145 esac
3146 umount $TMP_DIR/iso # no -d: needs /proc
3147 losetup -d $loopdev
3148 rm -rf $TMP_DIR
3149 ;;
3152 emu-iso)
3153 # Emulate an ISO image with Qemu.
3154 iso="${2:-$DISTRO/$ISO_NAME.iso}"
3155 [ -f "$iso" ] || die "Unable to find ISO file '$iso'."
3156 [ -x '/usr/bin/qemu' ] || die "Unable to find Qemu binary. Please install package 'qemu'."
3157 echo -e "\nStarting Qemu emulator:\n"
3158 echo -e "qemu $QEMU_OPTS $iso\n"
3159 qemu $QEMU_OPTS $iso
3160 ;;
3163 deduplicate)
3164 # Deduplicate files in a tree
3165 shift
3166 deduplicate "$@"
3167 ;;
3170 usage|*)
3171 # Print usage also for all unknown commands.
3172 usage
3173 ;;
3174 esac
3176 exit 0