tazlito view tazlito @ rev 484

tazlito: remove /boot/grub on cdrom (again)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Feb 25 17:55:06 2018 +0100 (2018-02-25)
parents dd492543ffe4
children 66335bf0d909
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 the size in the 2nd eltorito boot file (/boot/isolinux/efi.img)
264 fix_efi_boot_img_size() {
265 i=$(stat -m $2/boot/isolinux/boot.cat | sed q)
266 set -- $1 $((102+2048*$i)) $3
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 }
273 # Force the size for the /boot/isolinux/efi.img file
275 fix_efi_img_size() {
276 local e=$((0x809C))
277 for i in BOOT ISOLINUX EFI.IMG ; do
278 local sz=$(get $(($e+10)) "$2")
279 e=$(($(get $(($e+2)) "$2") * 2048))
280 while [ $sz -gt 0 ]; do
281 local len=$(get $e "$2" 2)
282 [ "$(dd if="$2" bs=1 skip=$(($e+33)) count=${#i} \
283 2>/dev/null)" == "$i" ] && continue 2
284 [ $len -eq 0 ] && break
285 sz=$(($sz-$len))
286 e=$(($e+$len))
287 done
288 return # not found
289 done
290 set64 $(($e+10)) $1 "$2"
291 }
294 # create /boot/isolinux/efi.img to share EFI files with the iso image
296 fixup_uefi_part() {
297 local n
298 [ -s $2/boot/isolinux/efi.img ] || return
300 # Build file list tree
302 ( cd $2 ; find efi -type f -exec echo \
303 'stat -c "$(stat -m {} | sed q) %s f %n" {}' \; | sh | sort -n ) \
304 >/tmp/fatfiles$$
305 n=$(sed 's/ .*//;q' /tmp/fatfiles$$)
306 ( cd $2; find efi ) | awk -v n=$n 'BEGIN { FS="/" }
307 NF > 1 {
308 d[NF $NF]+=2
309 p[NF $NF]=$0
310 b[a++]=NF $NF
311 if (NF>2) d[NF-1 $(NF-1)]++
312 }
313 END {
314 while (a-- > 0) if (d[i=b[a]] > 2) {
315 n-= j =int((d[i]+63)/64)
316 print n " " j*2048 " d " p[i]
317 }
318 print n-1 " 2048 d efi"
319 }' >>/tmp/fatfiles$$
320 sort -n /tmp/fatfiles$$ | awk '{ if (s == 0) s=$1;
321 print ($1-s)+2 " " $2 " " $3 " " $4 }' > /tmp/fatfiles$$.tmp
322 mv -f /tmp/fatfiles$$.tmp /tmp/fatfiles$$
324 # Build fat12 or fat16
326 if [ $(awk '{n+=int(($2+2047)/2048)}END{print n}' /tmp/fatfiles$$) \
327 -lt 4000 ]; then
328 sed '1s/.*/4087 2049 x\n1 1 x/' /tmp/fatfiles$$ | while read c s x; do
329 seq $(($c+1)) $((($s-1)/2048+$c))
330 echo 4095
331 done | awk 'BEGIN { printf "0 "}
332 {
333 if (n == 0) n=$1
334 else {
335 printf "%02X %02X %02X ",n%256,
336 ($1%16)*16+(n/256),$1/16
337 n=0
338 }
339 }
340 END {
341 if (n != 0) printf "FF 0F 00 "
342 print " |"
343 }' | hexdump -R > /tmp/fatbin-12-$$
344 else
345 sed '1s/.*/65527 2049 x\n1 1 x/' /tmp/fatfiles$$ | while read c s x; do
346 seq $(($c+1)) $((($s-1)/2048+$c))
347 echo 65535
348 done | awk 'BEGIN { printf "0 "}
349 {
350 printf "%02X %02X ",$1%256,$1/256
351 }
352 END {
353 print " |"
354 }' | hexdump -R > /tmp/fatbin-16-$$
355 fi
357 # align fat to 512 bytes
358 dd of=$(ls /tmp/fatbin-*-$$) count=0 bs=512 \
359 seek=$((($(stat -c %s /tmp/fatbin-*-$$)-1)/512+1)) 2>/dev/null
361 # build directory records
363 awk '
364 BEGIN {
365 c=2
366 b16="/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0"
367 b14="/0/0/0/0/0/0/0/0/0/0/0/0/0/0"
368 print "EFI /x10" b14 "/x0" c "/0/0/x08/0/0"
369 for (n=i=0; i<63; i++) print b16 b16
370 }
371 {
372 clu[n]=$1
373 size[n]=$2
374 type[n]=$3
375 name[n]=$4
376 n++
377 }
378 END {
379 path="efi"
380 d21="/x10" b14 "/x%02X/x%02X/0/x08/0/0\n"
381 up[0]=0
382 s=1
383 do {
384 l=split(path,x,"/")
385 up[l]=c
386 printf ". " d21,c%256,c/256
387 printf ".. " d21,up[l-1]%256,up[l-1]/256
388 for (i=s,e=2; i<n; i++) {
389 if (substr(name[i],1,length(path)) != path ||
390 split(substr(name[i],length(path)+2),x,"/") > 1)
391 continue
392 split(toupper(x[1]),x,".")
393 if (length(x[1]) >= 8) printf substr(x[1],1,8)
394 else printf x[1] substr(" ",1,8-length(x[1]))
395 if (length(x[2]) >= 3) printf substr(x[2],1,3)
396 else printf x[2] substr(" ",1,3-length(x[2]))
397 if (type[i] == "d") printf "/x10"; else printf "/0"
398 printf b14 "/x%02X/x%02X",clu[i]%256,clu[i]/256
399 printf "/x%02X/x%02X/x%02X/x%02X\n",size[i]%256,
400 (size[i]/256)%256,(size[i]/256/256)%256,
401 size[i]/256/256/256
402 e++
403 }
404 while (e++ < 64) print b16 b16
405 path=name[s]
406 c=clu[s]
407 } while (type[s++] == "d")
408 }' < /tmp/fatfiles$$ | while read line; do
409 echo "$line" | sed 's| |/x20|g;s|/|\\\\|g' | xargs echo -en
410 done > /tmp/fatdir$$
412 # build boot record
414 fat=$(($(stat -c %s /tmp/fatbin-*-$$)/512))
415 r=$((4-($fat+$fat+$(stat -c %s /tmp/fatdir$$)/512)%4))
416 dd if=/dev/zero bs=512 count=$r of=/tmp/fatbr$$ 2> /dev/null
417 echo -en '\x55\xAA' | \
418 dd of=/tmp/fatbr$$ seek=510 bs=1 conv=notrunc 2> /dev/null
419 n=$(stat -m $2/boot/isolinux/efi.img | sed q)
420 fat="$(printf "%02X %02X" $(($fat%256)) $((($fat>>8)%256)))"
421 s=$((($(stat -m $(ls -r $2/boot/rootfs* | sed q) | sed q) - $n)*4))
422 if [ $s -gt 65535 ]; then
423 size="00 00"
424 size32="$(printf "%02X %02X %02X %02X" $(($s%256)) \
425 $((($s>>8)%256)) $((($s>>16)%256)) $((($s>>24)%256)) )"
426 else
427 size="$(printf "%02X %02X" $(($s%256)) $((($s>>8)%256)) )"
428 size32="00 00 00 00"
429 fi
430 t=32; [ -s /tmp/fatbin-16-$$ ] && t=36
431 hexdump -R <<EOT | dd conv=notrunc of=/tmp/fatbr$$ 2> /dev/null
432 0 eb 3c 90 53 6c 69 54 61 7a 00 00 00 02 04 $r 00 |
433 0 02 40 00 $size f8 $fat 20 00 40 00 00 00 00 00 |
434 0 $size32 80 00 29 00 00 00 00 4e 4f 20 4e 41 |
435 0 4d 45 20 20 20 20 46 41 54 31 $t 20 20 20 cd 18 |
436 0 cd 19 eb fa |
437 EOT
439 # patch efi.img stub
441 cat /tmp/fatbr$$ /tmp/fatbin-*-$$ /tmp/fatbin-*-$$ /tmp/fatdir$$ | \
442 dd of=$1 conv=notrunc bs=2k seek=$n 2>/dev/null
443 fix_efi_img_size $(($s*512)) $1
444 fix_efi_boot_img_size $1 $2 $s
445 rm -f /tmp/fat*$$
446 }
449 # allocate efi.img stub to share EFI files in the EFI boot partition
451 alloc_uefi_part() {
452 local basedir=$(dirname "$1")/..
453 local clusters=$({
454 [ -d $basedir/efi ] &&
455 find $basedir/efi -type f -exec stat -c "%s" {} \;
456 while [ -s "$1" ]; do
457 local efifile
458 case "$1" in
459 *taz) efifile=bootia32.efi ;;
460 *taz64) efifile=bootx64.efi ;;
461 esac
462 if [ ! -s $basedir/efi/boot/$efifile ] &&
463 [ $(get $((0x82)) "$1") == $((0x4550)) ]; then
464 stat -c "%s" "$1"
465 mkdir -p $basedir/efi/boot 2> /dev/null
466 ln "$1" $basedir/efi/boot/$efifile
467 fi
468 shift
469 done; } | awk '{ n+=int(($1+2047)/2048) } END { print n }')
470 [ ${clusters:-0} -eq 0 ] && return
471 local dclust=$( (cd $basedir; find efi -type d 2>/dev/null) | awk '
472 BEGIN {
473 FS="/"
474 }
475 NF > 1 {
476 d[NF $NF]+=2
477 d[NF-1 $(NF-1)]++
478 }
479 END {
480 for (i in d)
481 n+=int((d[i]+63)/64)
482 print n
483 }')
484 clusters=$(($clusters+$dclust))
485 if [ $clusters -lt 4000 ]; then
486 # reserved + fat*2 + root dir + dirs
487 count=$(((1 + (($clusters*3+1023)/1024)*2+3)/4+1 + $dclust ))
488 else
489 # reserved + fat*2 + root dir + dirs
490 count=$(((1 + (($clusters+255)/256)*2+3)/4 + 1 + $dclust ))
491 fi
492 dd if=/dev/zero bs=2k of=$basedir/boot/isolinux/efi.img \
493 count=$count 2> /dev/null
494 }
497 # isolinux.conf doesn't know the kernel version.
498 # We name the kernel image 'bzImage'.
499 # isolinux/syslinux first tries the '64' suffix with a 64bits cpu.
501 make_bzImage_hardlink() {
502 if [ -e ${1:-.}/vmlinuz*slitaz ]; then
503 rm -f ${1:-.}/bzImage 2>/dev/null
504 ln ${1:-.}/vmlinuz*slitaz ${1:-.}/bzImage
505 fi
506 if [ -e ${1:-.}/vmlinuz*slitaz64 ]; then
507 rm -f ${1:-.}/bzImage64 2> /dev/null
508 ln ${1:-.}/vmlinuz*slitaz64 ${1:-.}/bzImage64
509 fi
510 }
513 create_iso() {
514 cd $2
515 deduplicate
517 rm -rf $2/boot/grub*
518 make_bzImage_hardlink $2/boot
519 alloc_uefi_part $(ls -r $2/boot/vmlinuz*slitaz*)
521 cat > /tmp/cdsort$$ <<EOT
522 $PWD/boot/isolinux 100
523 $(ls -r $PWD/boot/rootfs* | awk 'BEGIN{n=149} { print $1 " " n-- }')
524 $(ls $PWD/boot/bzImage* | awk 'BEGIN{n=200} { print $1 " " n-- }')
525 $(find $PWD/efi -type f 2>/dev/null | awk 'BEGIN{n=299} { print $1 " " n-- }')
526 $PWD/boot/isolinux/efi.img 300
527 $PWD/boot/isolinux/isolinux.bin 399
528 $PWD/boot/isolinux/boot.cat 400
529 EOT
531 action 'Computing md5...'
532 touch boot/isolinux/boot.cat
533 find * -type f ! -name md5sum ! -name 'vmlinuz-*' -exec md5sum {} \; > md5sum
534 status
536 cd - >/dev/null
537 title 'Generating ISO image'
539 _ 'Generating %s' "$1"
540 uefi="$(cd $2 ; ls boot/isolinux/efi.img 2> /dev/null)"
541 genisoimage -R -o $1 -hide-rr-moved -sort /tmp/cdsort$$ \
542 -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat \
543 -no-emul-boot -boot-load-size 4 -boot-info-table \
544 ${uefi:+-eltorito-alt-boot -efi-boot $uefi -no-emul-boot} \
545 -V "${VOLUM_NAME:-SliTaz}" -p "${PREPARED:-$(id -un)}" \
546 -volset "SliTaz $SLITAZ_VERSION" -input-charset utf-8 \
547 -A "tazlito $VERSION/$(genisoimage --version)" \
548 -copyright README -P "www.slitaz.org" -no-pad $2
549 rm -f /tmp/cdsort$$
550 dd if=/dev/zero bs=2k count=16 >> $1 2> /dev/null
552 mkdir /tmp/mnt$$
553 mount -o loop,ro $1 /tmp/mnt$$
554 fixup_uefi_part $1 /tmp/mnt$$
555 for i in boot/isolinux/isolinux.bin boot/isolinux/boot.cat \
556 ${uefi:+boot/isolinux/efi.img} ; do
557 sed -i "s|.* $i|$( cd /tmp/mnt$$ ; md5sum $i)|" $2/md5sum
558 done
559 dd if=$2/md5sum of=$1 conv=notrunc bs=2k \
560 seek=$(stat -m /tmp/mnt$$/md5sum | sed q) 2> /dev/null
561 umount -d /tmp/mnt$$
562 rmdir /tmp/mnt$$
564 if [ -s '/etc/tazlito/info' ]; then
565 if [ $(stat -c %s /etc/tazlito/info) -lt $(( 31*1024 )) ]; then
566 action 'Storing ISO info...'
567 dd if=/etc/tazlito/info bs=1k seek=1 of=$1 conv=notrunc 2>/dev/null
568 status
569 fi
570 fi
572 if [ -x '/usr/bin/isohybrid' ]; then
573 action 'Creating hybrid ISO...'
574 isohybrid $1 $([ -n "$uefi" ] || echo -entry 2) 2>/dev/null
575 status
576 fi
578 if [ -x '/usr/bin/iso2exe' ]; then
579 echo 'Creating EXE header...'
580 /usr/bin/iso2exe $1 2>/dev/null
581 fi
582 }
585 # Generate a new ISO image using isolinux.
587 gen_livecd_isolinux() {
588 # Some packages may want to alter iso
589 genisohooks iso
590 [ ! -f "$ROOTCD/boot/isolinux/isolinux.bin" ] && die 'Unable to find isolinux binary.'
592 # Set date for boot msg.
593 if grep -q 'XXXXXXXX' "$ROOTCD/boot/isolinux/isolinux.cfg"; then
594 DATE=$(date +%Y%m%d)
595 action 'Setting build date to: %s...' "$DATE"
596 sed -i "s/XXXXXXXX/$DATE/" "$ROOTCD/boot/isolinux/isolinux.cfg"
597 status
598 fi
600 cd $DISTRO
601 create_iso $ISO_NAME.iso $ROOTCD
603 action 'Creating the ISO md5sum...'
604 md5sum $ISO_NAME.iso > $ISO_NAME.md5
605 status
607 separator
608 # Some packages may want to alter final iso
609 genisohooks final
610 }
613 lzma_history_bits() {
614 #
615 # This generates an ISO which boots with Qemu but gives
616 # rootfs errors in frugal or liveUSB mode.
617 #
618 # local n
619 # local sz
620 # n=20 # 1Mb
621 # sz=$(du -sk $1 | cut -f1)
622 # while [ $sz -gt 1024 -a $n -lt 28 ]; do
623 # n=$(( $n + 1 ))
624 # sz=$(( $sz / 2 ))
625 # done
626 # echo $n
627 echo ${LZMA_HISTORY_BITS:-24}
628 }
631 lzma_switches() {
632 local proc_num=$(grep -sc '^processor' /proc/cpuinfo)
633 echo "-d$(lzma_history_bits $1) -mt${proc_num:-1} -mc1000"
634 }
637 lzma_set_size() {
638 # Update size field for lzma'd file packed using -si switch
639 return # Need to fix kernel code?
641 local n i
642 n=$(unlzma < $1 | wc -c)
643 for i in $(seq 1 8); do
644 printf '\\\\x%02X' $(($n & 255))
645 n=$(($n >> 8))
646 done | xargs echo -en | dd of=$1 conv=notrunc bs=1 seek=5 2>/dev/null
647 }
650 align_to_32bits() {
651 local size=$(stat -c %s ${1:-/dev/null})
652 [ $((${size:-0} & 3)) -ne 0 ] &&
653 dd if=/dev/zero bs=1 count=$((4 - ($size & 3))) >> $1 2>/dev/null
654 }
657 dogzip() {
658 gzip -9 > $1
659 [ -x /usr/bin/advdef ] && advdef -qz4 $1
660 }
663 # Pack rootfs
665 pack_rootfs() {
666 ( cd $1; find . -print | cpio -o -H newc ) | \
667 case "$COMPRESSION" in
668 none)
669 _ 'Creating %s without compression...' 'initramfs'
670 cat > $2
671 ;;
672 gzip)
673 _ 'Creating %s with gzip compression...' 'initramfs'
674 dogzip $2
675 ;;
676 *)
677 _ 'Creating %s with lzma compression...' 'initramfs'
678 lzma e -si -so $(lzma_switches $1) > $2
679 lzma_set_size $2
680 ;;
681 esac
682 align_to_32bits $2
683 echo 1 > /tmp/rootfs
684 }
687 # Compression functions for writeiso.
689 write_initramfs() {
690 case "$COMPRESSION" in
691 lzma)
692 _n 'Creating %s with lzma compression...' "$INITRAMFS"
693 cpio -o -H newc | lzma e -si -so $(lzma_switches) > "/$INITRAMFS"
694 align='y'
695 lzma_set_size "/$INITRAMFS"
696 ;;
697 gzip)
698 _ 'Creating %s with gzip compression...' "$INITRAMFS"
699 cpio -o -H newc | dogzip "/$INITRAMFS"
700 ;;
701 *)
702 # align='y'
703 _ 'Creating %s without compression...' "$INITRAMFS"
704 cpio -o -H newc > "/$INITRAMFS"
705 ;;
706 esac < /tmp/list
707 [ "$align" == 'y' -a -z "$noalign" ] && align_to_32bits "/$INITRAMFS"
708 echo 1 > /tmp/rootfs
709 }
712 # Deduplicate files (MUST be on the same filesystem).
714 deduplicate() {
715 find "${@:-.}" -type f -size +0c -xdev -exec stat -c '%s-%a-%u-%g %i %h %n' {} \; | sort | \
716 (
717 save=0; hardlinks=0; old_attr=""; old_inode=""; old_link=""; old_file=""
718 while read attr inode link file; do
719 [ -L "$file" ] && continue
720 if [ "$attr" == "$old_attr" -a "$inode" != "$old_inode" ]; then
721 if cmp "$file" "$old_file" >/dev/null 2>&1 ; then
722 rm -f "$file"
723 if ln "$old_file" "$file" 2>/dev/null; then
724 inode="$old_inode"
725 [ "$link" -eq 1 ] && hardlinks=$(($hardlinks+1)) &&
726 save="$(($save+(${attr%%-*}+512)/1024))"
727 else
728 cp -a "$old_file" "$file"
729 fi
730 fi
731 fi
732 old_attr="$attr" ; old_inode="$inode" ; old_file="$file"
733 done
734 _ '%s Kbytes saved in %s duplicate files.' "$save" "$hardlinks"
735 )
737 find "$@" -type l -xdev -exec stat -c '%s-%u-%g-TARGET- %i %h %n' {} \; | sort | \
738 (
739 old_attr=""; hardlinks=0;
740 while read attr inode link file; do
741 attr="${attr/-TARGET-/-$(readlink $file)}"
742 if [ "$attr" == "$old_attr" ]; then
743 if [ "$inode" != "$old_inode" ]; then
744 rm -f "$file"
745 if ln "$old_file" "$file" 2>/dev/null; then
746 [ "$link" -eq 1 ] && hardlinks=$(($hardlinks+1))
747 else
748 cp -a "$old_file" "$file"
749 fi
750 fi
751 else
752 old_file="$file"
753 old_attr="$attr"
754 old_inode="$inode"
755 fi
756 done
757 _ '%s duplicate symlinks.' "$hardlinks"
758 )
759 }
762 # Generate a new initramfs from the root filesystem.
764 gen_initramfs() {
765 # Just in case CTRL+c
766 rm -f $DISTRO/gen
768 # Some packages may want to alter rootfs
769 genisohooks rootfs
770 cd $1
772 # Normalize file time
773 find $1 -newer $1 -exec touch -hr $1 {} \;
775 # Link duplicate files
776 deduplicate
778 # Use lzma if installed. Display rootfs size in realtime.
779 rm -f /tmp/rootfs 2>/dev/null
780 pack_rootfs . $DISTRO/$(basename $1).gz &
781 sleep 2
782 echo -en "\nFilesystem size:"
783 while [ ! -f /tmp/rootfs ]; do
784 sleep 1
785 echo -en "\\033[18G$(du -sh $DISTRO/$(basename $1).gz | awk '{print $1}') "
786 done
787 echo -e "\n"
788 rm -f /tmp/rootfs
789 cd $DISTRO
790 mv $(basename $1).gz $ROOTCD/boot
791 }
794 distro_sizes() {
795 if [ -n "$start_time" ]; then
796 time=$(($(date +%s) - $start_time))
797 sec=$time
798 div=$(( ($time + 30) / 60))
799 [ "$div" -ne 0 ] && min="~ ${div}m"
800 _ 'Build time : %ss %s' "$sec" "$min"
801 fi
802 cat <<EOT
803 Build date : $(date +%Y%m%d)
804 Packages : $(ls -1 $ROOTFS*$INSTALLED/*/receipt | wc -l)
805 Rootfs size : $(du -csh $ROOTFS*/ | awk 'END { print $1 }')
806 Initramfs size : $(du -csh $ROOTCD/boot/rootfs*.gz | awk 'END { print $1 }')
807 ISO image size : $(du -sh $ISO_NAME.iso | awk '{ print $1 }')
808 EOT
809 footer "Image is ready: $ISO_NAME.iso"
810 }
813 # Print ISO and rootfs size.
815 distro_stats() {
816 title 'Distro statistics: %s' "$DISTRO"
817 distro_sizes
818 }
821 # Create an empty configuration file.
823 empty_config_file() {
824 cat >> tazlito.conf <<"EOF"
825 # tazlito.conf: Tazlito (SliTaz Live Tool) configuration file.
826 #
828 # Name of the ISO image to generate.
829 ISO_NAME=""
831 # ISO image volume name.
832 VOLUM_NAME="SliTaz"
834 # Name of the preparer.
835 PREPARED="$USER"
837 # Path to the packages repository and the packages.list.
838 PACKAGES_REPOSITORY=""
840 # Path to the distro tree to gen-distro from a list of packages.
841 DISTRO=""
843 # Path to the directory containing additional files
844 # to copy into the rootfs and rootcd of the LiveCD.
845 ADDFILES="$DISTRO/addfiles"
847 # Default answer for binary question (Y or N)
848 DEFAULT_ANSWER="ASK"
850 # Compression utility (lzma, gzip or none)
851 COMPRESSION="lzma"
852 EOF
853 }
856 # Extract rootfs.gz somewhere
858 extract_rootfs() {
859 # Detect compression format: *.lzma.cpio, *.gzip.cpio, or *.cpio
860 # First part (lzcat or zcat) may not fail, but cpio will fail on incorrect format
861 (cd "$2"; lzcat "$1" | cpio -idm --quiet 2>/dev/null) && return
862 (cd "$2"; zcat "$1" | cpio -idm --quiet 2>/dev/null) && return
863 (cd "$2"; cat "$1" | cpio -idm --quiet 2>/dev/null)
864 }
867 # Extract flavor file to temp directory
869 extract_flavor() {
870 # Input: $1 - flavor name to extract;
871 # $2 = absent/empty: just extract 'outer layer'
872 # $2 = 'full': also extract 'inner' rootcd and rootfs archives, make files rename
873 # $2 = 'info': as 'full' and also make 'info' file to put into ISO
874 # Output: temp dir path where flavor was extracted
875 local f="$1.flavor" from to infos="$1.desc"
876 [ -f "$f" ] || die "File '$f' not found"
877 local dir="$(mktemp -d)"
878 zcat "$f" | (cd $dir; cpio -i --quiet >/dev/null)
880 if [ -n "$2" ]; then
881 cd $dir
883 [ -s "$1.receipt" ] && infos="$infos\n$1.receipt"
885 for i in rootcd rootfs; do
886 [ -f "$1.$i" ] || continue
887 mkdir "$i"
888 zcat "$1.$i" | (cd "$i"; cpio -idm --quiet 2>/dev/null)
889 zcat "$1.$i" | cpio -tv 2>/dev/null > "$1.list$i"; infos="$infos\n$1.list$i"
890 rm "$1.$i"
891 done
892 touch -t 197001010100.00 "$1.*"
893 # Info to be stored inside ISO
894 [ "$2" == info ] && echo -e $infos | cpio -o -H newc | dogzip info
895 rm $1.list*
897 # Renames
898 while read from to; do
899 [ -f "$from" ] || continue
900 mv "$from" "$to"
901 done <<EOT
902 $1.nonfree non-free.list
903 $1.pkglist packages.list
904 $1-distro.sh distro.sh
905 $1.receipt receipt
906 $1.mirrors mirrors
907 $1.desc description
908 EOT
909 fi
911 echo $dir
912 }
915 # Pack flavor file from temp directory
917 pack_flavor() {
918 (cd "$1"; ls | grep -v err | cpio -o -H newc) | dogzip "$2.flavor"
919 }
922 # Remove duplicate files
924 files_match() {
925 if [ -d "$1" ]; then
926 return 1
928 elif [ -L "$1" ] && [ -L "$2" ]; then
929 [ "$(readlink "$1")" == "$(readlink "$2")" ] && return 0
931 elif [ -f "$1" ] && [ -f "$2" ]; then
932 cmp -s "$1" "$2" && return 0
934 [ "$(basename "$3")" == 'volatile.cpio.gz' ] &&
935 [ "$(dirname $(dirname "$3"))" == ".$INSTALLED" ] &&
936 return 0
938 elif [ "$(ls -l "$1"|cut -c1-10)$(stat -c '%a:%u:%g:%t:%T' "$1")" == \
939 "$(ls -l "$2"|cut -c1-10)$(stat -c '%a:%u:%g:%t:%T' "$2")" ]; then
940 return 0
942 fi 2> /dev/null
943 return 1
944 }
946 remove_with_path() {
947 dir="$(dirname $1)"
948 rm -f "$1"
949 while rmdir "$dir" 2> /dev/null; do
950 dir="$(dirname $dir)"
951 done
952 }
954 mergefs() {
955 # Note, many packages have files with spaces in the name
956 IFS=$'\n'
958 local size1=$(du -hs "$1" | awk '{ print $1 }')
959 local size2=$(du -hs "$2" | awk '{ print $1 }')
960 action 'Merge %s (%s) into %s (%s)' "$(basename "$1")" "$size1" "$(basename "$2")" "$size2"
962 # merge symlinks files and devices
963 ( cd "$1"; find ) | \
964 while read file; do
965 files_match "$1/$file" "$2/$file" "$file" &&
966 remove_with_path "$2/$file"
967 done
969 unset IFS
970 status
971 }
974 cleanup_merge() {
975 rm -rf $TMP_DIR
976 exit 1
977 }
980 # Update isolinux config files for multiple rootfs
982 update_bootconfig() {
983 local files
984 action 'Updating boot config files...'
985 files="$(grep -l 'include common' $1/*.cfg)"
986 for file in $files; do
987 awk -v n=$(echo $2 | awk '{ print NF/2 }') '{
988 if (/label/) label=$0;
989 else if (/kernel/) kernel=$0;
990 else if (/append/) {
991 i=index($0,"rootfs.gz");
992 append=substr($0,i+9);
993 }
994 else if (/include/) {
995 for (i = 1; i <= n; i++) {
996 print label i
997 print kernel;
998 initrd="initrd=/boot/rootfs" n ".gz"
999 for (j = n - 1; j >= i; j--) {
1000 initrd=initrd ",/boot/rootfs" j ".gz";
1002 printf "\tappend %s%s\n",initrd,append;
1003 print "";
1005 print;
1007 else print;
1008 }' < $file > $file.$$
1009 mv -f $file.$$ $file
1010 done
1011 sel="$(echo $2 | awk '{
1012 for (i=1; i<=NF; i++)
1013 if (i % 2 == 0) printf " slitaz%d", i/2
1014 else printf " %s", $i
1015 }')"
1017 [ -s $1/common.cfg ] && cat >> $1/common.cfg <<EOT
1019 label slitaz
1020 kernel /boot/isolinux/ifmem.c32
1021 append$sel noram
1023 label noram
1024 config noram.cfg
1026 EOT
1028 # Update vesamenu
1029 if [ -s "$1/isolinux.cfg" ]; then
1030 files="$files $1/isolinux.cfg"
1031 awk -v n=$(echo $2 | awk '{ print NF/2 }') -v "sel=$sel" '
1032 BEGIN {
1033 kernel = " COM32 c32box.c32"
1036 if (/ROWS/) print "MENU ROWS " n+$3;
1037 else if (/TIMEOUTROW/) print "MENU TIMEOUTROW " n+$3;
1038 else if (/TABMSGROW/) print "MENU TABMSGROW " n+$3;
1039 else if (/CMDLINEROW/) print "MENU CMDLINEROW " n+$3;
1040 else if (/VSHIFT/) {
1041 x = $3-n;
1042 if (x < 0) x = 0;
1043 print "MENU VSHIFT " x;
1045 else if (/rootfs.gz/) {
1046 linux = "";
1047 if (/bzImage/) linux = "linux /boot/bzImage ";
1048 i = index($0, "rootfs.gz");
1049 append = substr($0, i+9);
1050 printf "\tkernel /boot/isolinux/ifmem.c32\n";
1051 printf "\tappend%s noram\n", sel;
1052 printf "\nlabel noram\n\tMENU HIDE\n\tconfig noram.cfg\n\n";
1053 for (i = 1; i <= n; i++) {
1054 print "LABEL slitaz" i
1055 printf "\tMENU LABEL SliTaz slitaz%d Live\n", i;
1056 printf "%s\n", kernel;
1057 initrd = "initrd=/boot/rootfs" n ".gz"
1058 for (j = n - 1; j >= i; j--) {
1059 initrd = initrd ",/boot/rootfs" j ".gz";
1061 printf "\tappend %s%s%s\n\n", linux, initrd, append;
1064 else if (/bzImage/) kernel = $0;
1065 else print;
1066 }' < $1/isolinux.cfg > $1/isolinux.cfg.$$
1067 mv $1/isolinux.cfg.$$ $1/isolinux.cfg
1068 fi
1070 [ -s $1/c32box.c32 ] && sed -i -e '/kernel.*ifmem/d' \
1071 -e 's/append \([0-9]\)/append ifmem \1/' $1/isolinux.cfg
1072 cat > $1/noram.cfg <<EOT
1073 implicit 0
1074 prompt 1
1075 timeout 80
1076 $(grep '^F[0-9]' $1/isolinux.cfg)
1078 $([ -s $1/isolinux.msg ] && echo display isolinux.msg)
1079 say Not enough RAM to boot slitaz. Trying hacker mode...
1080 default hacker
1081 label hacker
1082 KERNEL /boot/bzImage
1083 append rw root=/dev/null vga=normal
1085 label reboot
1086 EOT
1088 if [ -s $1/c32box.c32 ]; then
1089 cat >> $1/noram.cfg <<EOT
1090 COM32 c32box.c32
1091 append reboot
1093 label poweroff
1094 COM32 c32box.c32
1095 append poweroff
1097 EOT
1098 else
1099 echo " com32 reboot.c32" >> $1/noram.cfg
1100 fi
1102 # Restore real label names
1103 [ -s $1/common.cfg ] && files="$1/common.cfg $files"
1104 echo $2 | awk '{ for (i=NF; i>1; i-=2) printf "%d/%s\n",i/2,$i }' | \
1105 while read pat; do
1106 sed -i "s/slitaz$pat/" $files
1107 done
1108 status
1112 # Uncompress rootfs or module to stdout
1114 uncompress() {
1115 zcat $1 2> /dev/null || xzcat $1 2> /dev/null ||
1116 { [ $(od -N 1 -An $1) -eq 135 ] && unlzma < $1; } || cat $1
1120 # Install a missing package
1122 install_package() {
1123 if [ -z "$2" ]; then
1124 answer=$(yesorno "$(_ 'Install package %s?' "$1")" 'n')
1125 else
1126 answer=$(yesorno "$(_n 'Install package %s for Kernel %s? ' "$1" "$2")" 'n')
1127 fi
1128 case "$answer" in
1129 y)
1130 # We don't want package on host cache.
1131 action 'Getting and installing package: %s' "$1"
1132 yes y | tazpkg get-install $1 --quiet 2>&1 >> $log || exit 1
1133 status ;;
1134 *)
1135 return 1 ;;
1136 esac
1140 # Check iso for loram transformation
1142 check_iso_for_loram() {
1143 [ -s "$TMP_DIR/iso/boot/rootfs.gz" ] ||
1144 [ -s "$TMP_DIR/iso/boot/rootfs1.gz" ]
1148 # Build initial rootfs for loram ISO ram/cdrom/http
1150 build_initfs() {
1151 urliso="mirror.switch.ch/ftp/mirror/slitaz \
1152 download.tuxfamily.org/slitaz mirror1.slitaz.org mirror2.slitaz.org \
1153 mirror3.slitaz.org mirror.slitaz.org"
1154 version=$(ls $TMP_DIR/iso/boot/vmlinuz-* | sed 's/.*vmlinuz-//')
1155 [ -z "$version" ] && die "Can't find the kernel version." \
1156 'No file /boot/vmlinuz-<version> in ISO image. Abort.'
1158 [ -s /usr/share/boot/busybox-static ] || install_package busybox-static
1159 need_lib=false
1160 for i in bin dev run mnt proc tmp sys lib/modules; do
1161 mkdir -p $TMP_DIR/initfs/$i
1162 done
1163 ln -s bin $TMP_DIR/initfs/sbin
1164 ln -s . $TMP_DIR/initfs/usr
1165 for aufs in aufs overlayfs; do
1166 [ -f /lib/modules/$version/kernel/fs/$aufs/$aufs.ko.?z ] && break
1167 install_package $aufs $version && break
1168 done || return 1
1169 [ -s /init ] || install_package slitaz-boot-scripts
1170 cp /init $TMP_DIR/initfs/
1171 cp /lib/modules/$version/kernel/fs/$aufs/$aufs.ko.?z \
1172 $TMP_DIR/initfs/lib/modules
1173 if [ "$1" == 'cdrom' ]; then
1174 sed -i '/mod squashfs/d' $TMP_DIR/initfs/init
1175 else
1176 [ ! -f /usr/sbin/mksquashfs ] && ! install_package squashfs && return 1
1177 while [ ! -f /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z ]; do
1178 install_package linux-squashfs $version || return 1
1179 done
1180 cp /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z \
1181 $TMP_DIR/initfs/lib/modules
1182 #ls /sbin/unsquashfs /usr/lib/liblzma.so* $INSTALLED/squashfs/* | \
1183 #cpio -o -H newc > $TMP_DIR/initfs/extractfs.cpio
1184 fi
1185 if [ "$1" == 'http' ]; then
1186 mkdir $TMP_DIR/initfs/etc $TMP_DIR/fs
1187 ln -s /proc/mounts $TMP_DIR/initfs/etc/mtab
1188 cp /usr/share/udhcpc/default.script $TMP_DIR/initfs/lib/udhcpc
1189 sed -i 's|/sbin/||;s/^logger/#&/' $TMP_DIR/initfs/lib/udhcpc
1190 cp -a /dev/fuse $TMP_DIR/initfs/dev
1191 if ! $need_lib && [ -x /usr/share/boot/fusermount-static ]; then
1192 cp /usr/share/boot/fusermount-static $TMP_DIR/initfs/bin/fusermount
1193 else
1194 need_lib=true
1195 fi
1196 if ! $need_lib && [ -x /usr/share/boot/httpfs-static ]; then
1197 cp /usr/share/boot/httpfs-static $TMP_DIR/initfs/bin/httpfs
1198 else
1199 [ ! -f /usr/bin/httpfs ] && ! install_package httpfs-fuse && return 1
1200 cp /usr/bin/httpfs $TMP_DIR/initfs/bin
1201 cp /usr/bin/fusermount $TMP_DIR/initfs/bin
1202 cp -a /lib/librt* $TMP_DIR/initfs/lib
1203 cp -a /lib/libdl* $TMP_DIR/initfs/lib
1204 cp -a /lib/libpthread* $TMP_DIR/initfs/lib
1205 cp -a /usr/lib/libfuse* $TMP_DIR/initfs/lib
1206 cp -a /lib/libresolv* $TMP_DIR/initfs/lib
1207 cp -a /lib/libnss_dns* $TMP_DIR/initfs/lib
1208 need_lib=true
1209 fi
1210 cd $TMP_DIR/fs
1211 echo 'Getting slitaz-release & ethernet modules...'
1212 for i in $(ls -r $TMP_DIR/iso/boot/rootfs*z); do
1213 uncompress $i | cpio -idmu etc/slitaz-release lib/modules rootfs*
1214 [ -s rootfs* ] || continue
1215 unsquashfs -f -d . rootfs* rootfs* etc/slitaz-release lib/modules &&
1216 rm -f rootfs*
1217 done 2>&1 > /dev/null
1218 cd - > /dev/null
1219 cp $TMP_DIR/fs/etc/slitaz-release $TMP_DIR/initfs/etc/
1220 find $TMP_DIR/fs/lib/modules/*/kernel/drivers/net/ethernet \
1221 -type f -name '*.ko*' | while read mod; do
1222 f=$TMP_DIR/initfs/lib/modules/$(basename $mod | sed s/..z$//)
1223 uncompress $mod > $f
1224 grep -q alias=pci: $f || rm -f $f
1225 done
1226 for i in $TMP_DIR/initfs/lib/modules/*.ko ; do
1227 f=$(basename $i)..z
1228 grep -q $f:$ $TMP_DIR/fs/lib/modules/*/modules.dep && continue
1229 deps="$(grep $f: $TMP_DIR/fs/lib/modules/*/modules.dep | sed 's/.*: //')"
1230 echo "$deps" | sed 's|kernel/[^ ]*/||g;s/.ko..z//g' > $TMP_DIR/initfs/lib/modules/$(basename $i .ko).dep
1231 for j in $deps; do
1232 mod=$(ls $TMP_DIR/fs/lib/modules/*/$j)
1233 uncompress $mod > $TMP_DIR/initfs/lib/modules/$(basename $j | sed s/..z$//)
1234 done
1235 done
1236 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"
1237 _n 'List of URLs to insert: '
1238 read -t 30 urliso2
1239 urliso="$urliso2 $urliso"
1240 fi
1241 if ! $need_lib && [ -x /usr/share/boot/busybox-static ]; then
1242 cp /usr/share/boot/busybox-static $TMP_DIR/initfs/bin/busybox
1243 sed -i 's/LD_T.*ot/echo/;s/".*ld-.*) /"/' $TMP_DIR/initfs/init
1244 else
1245 cp /bin/busybox $TMP_DIR/initfs/bin
1246 if ! cmp /bin/busybox /sbin/insmod > /dev/null ; then
1247 cp /sbin/insmod $TMP_DIR/initfs/bin
1248 cp -a /lib/libkmod.so.* $TMP_DIR/initfs/lib
1249 cp -a /usr/lib/liblzma.so.* $TMP_DIR/initfs/lib
1250 cp -a /usr/lib/libz.so.* $TMP_DIR/initfs/lib
1251 fi
1252 need_lib=true
1253 fi
1254 for i in $($TMP_DIR/initfs/bin/busybox | awk \
1255 '{ if (s) printf "%s",$0 } /Currently/ { s=1 }' | sed 's/,//g'); do
1256 ln $TMP_DIR/initfs/bin/busybox $TMP_DIR/initfs/bin/$i
1257 done
1258 # bootfloppybox will need floppy.ko.?z, /dev/fd0, /dev/tty0
1259 cp /lib/modules/$version/kernel/drivers/block/floppy.ko.?z \
1260 $TMP_DIR/initfs/lib/modules 2>/dev/null
1261 for i in /dev/console /dev/null /dev/tty /dev/tty0 /dev/zero \
1262 /dev/kmem /dev/mem /dev/random /dev/urandom; do
1263 cp -a $i $TMP_DIR/initfs/dev
1264 done
1265 grep -q '/sys/block/./dev' $TMP_DIR/initfs/init ||
1266 for i in /dev/fd0 /dev/[hs]d[a-f]* /dev/loop* ; do
1267 cp -a $i $TMP_DIR/initfs/dev
1268 done 2>/dev/null
1269 $need_lib && for i in /lib/ld-* /lib/lib[cm][-\.]* ; do
1270 cp -a $i $TMP_DIR/initfs/lib
1271 done
1272 [ "$1" == 'http' ] && cat > $TMP_DIR/initfs/init <<EOTEOT
1273 #!/bin/sh
1275 getarg() {
1276 grep -q " \$1=" /proc/cmdline || return 1
1277 eval \$2=\$(sed "s/.* \$1=\\\\([^ ]*\\\\).*/\\\\1/" < /proc/cmdline)
1278 return 0
1281 copy_rootfs() {
1282 total=\$(grep MemTotal /proc/meminfo | sed 's/[^0-9]//g')
1283 need=\$(du -c \${path}rootfs* | tail -n 1 | cut -f1)
1284 [ \$(( \$total / \$need )) -gt 1 ] || return 1
1285 if ! grep -q " keep-loram" /proc/cmdline && cp \${path}rootfs* /mnt; then
1286 path=/mnt/
1287 return 0
1288 else
1289 rm -f /mnt/rootfs*
1290 return 1
1291 fi
1294 echo "Switching / to tmpfs..."
1295 mount -t proc proc /proc
1296 size="\$(grep rootfssize= < /proc/cmdline | \\
1297 sed 's/.*rootfssize=\\([0-9]*[kmg%]\\).*/-o size=\\1/')"
1298 [ -n "\$size" ] || size="-o size=90%"
1300 mount -t sysfs sysfs /sys
1301 for i in /lib/modules/*.ko ; do
1302 echo -en "Probe \$i \\r"
1303 for j in \$(grep alias=pci: \$i | sed 's/alias//;s/\*/.*/g'); do
1304 grep -q "\$j" /sys/bus/pci/devices/*/uevent || continue
1305 for k in \$(cat \${i/ko/dep} 2> /dev/null); do
1306 insmod /lib/modules/\$k.ko 2> /dev/null
1307 done
1308 echo "Loading \$i"
1309 insmod \$i 2> /dev/null
1310 break
1311 done
1312 done
1313 umount /sys
1314 while read var default; do
1315 eval \$var=\$default
1316 getarg \$var \$var
1317 done <<EOT
1318 eth eth0
1319 dns 208.67.222.222,208.67.220.220
1320 netmask 255.255.255.0
1321 gw
1322 ip
1323 EOT
1324 grep -q \$eth /proc/net/dev || sh
1325 if [ -n "\$ip" ]; then
1326 ifconfig \$eth \$ip netmask \$netmask up
1327 route add default gateway \$gw
1328 for i in \$(echo \$dns | sed 's/,/ /g'); do
1329 echo "nameserver \$i" >> /etc/resolv.conf
1330 done
1331 else
1332 udhcpc -f -q -s /lib/udhcpc -i \$eth
1333 fi
1334 for i in $urliso ; do
1335 [ -n "\$URLISO" ] && URLISO="\$URLISO,"
1336 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"
1337 URLISO="\$URLISO,http://\$i/iso/rolling/slitaz-rolling-loram-cdrom.iso,http://\$i/iso/rolling/slitaz-rolling-loram.iso"
1338 done
1339 getarg urliso URLISO
1340 DIR=fs
1341 if getarg loram DIR; then
1342 DEVICE=\${DIR%,*}
1343 DIR=/\${DIR#*,}
1344 fi
1345 mount -t tmpfs \$size tmpfs /mnt
1346 path2=/mnt/.httpfs/
1347 path=/mnt/.cdrom/
1348 mkdir -p /mnt/.rw /mnt/.wd \$path \$path2
1349 while [ ! -d \$path/boot ]; do
1350 for i in \$(echo \$URLISO | sed 's/,/ /g'); do
1351 httpfs \$i \$path2 && echo \$i && break
1352 done
1353 mount -o loop,ro -t iso9660 \$path2/*.iso \$path || sh
1354 done
1356 memfree=\$(grep MemFree /proc/meminfo | sed 's/[^0-9]//g')
1357 umount /proc
1358 branch=:/mnt/.cdrom/\$DIR
1359 if [ ! -d /mnt/.cdrom/\$DIR/etc ]; then
1360 branch=
1361 lp=1
1362 insmod /lib/modules/squashfs.ko 2> /dev/null
1363 for i in \${path}boot/rootfs?.* ; do
1364 fs=\${i#*root}
1365 branch=\$branch:/mnt/.\$fs
1366 mkdir -p /mnt/.rw/mnt/.\$fs /mnt/.\$fs /mnt/.rw/mnt/.cdrom
1367 losetup -o 124 /dev/loop\$lp \$i
1368 mount -o loop,ro -t squashfs /dev/loop\$lp /mnt/.\$fs
1369 lp=\$((\$lp+1))
1370 done
1371 fi
1372 mkdir -p /mnt/.rw/mnt/.httpfs
1373 while read type opt; do
1374 insmod /lib/modules/\$type.ko && mount -t \$type -o \$opt none /mnt && break
1375 done <<EOT
1376 aufs br=/mnt/.rw\$branch
1377 overlayfs workdir=/mnt/.wd\${branch/:/,lowerdir=},upperdir=/mnt/.rw
1378 EOT
1379 rm -rf /lib/modules
1380 [ -x /bin/httpfs ] && sed -i 's/DHCP="yes"/DHCP="no"/' /mnt/etc/network.conf
1381 [ \$memfree -lt 30000 ] && sed -i 's/ slim//' /mnt/etc/rcS.conf
1382 [ -x /mnt/sbin/init ] && exec /bin/switch_root mnt /sbin/init || sh
1383 EOTEOT
1384 chmod +x $TMP_DIR/initfs/init
1385 for i in $TMP_DIR/initfs/lib/modules/*z ; do
1386 unxz $i || gunzip $i || lzma d $i ${i%.gz}
1387 rm -f $i
1388 done 2>/dev/null
1389 (cd $TMP_DIR/initfs; find | busybox cpio -o -H newc 2>/dev/null) | \
1390 lzma e $TMP_DIR/initfs.gz -si
1391 lzma_set_size $TMP_DIR/initfs.gz
1392 rm -rf $TMP_DIR/initfs
1393 align_to_32bits $TMP_DIR/initfs.gz
1394 return 0
1398 # Move each initramfs to squashfs
1400 build_loram_rootfs() {
1401 rootfs_sizes=""
1402 for i in $TMP_DIR/iso/boot/rootfs*; do
1403 mkdir -p $TMP_DIR/fs
1404 cd $TMP_DIR/fs
1405 uncompress $i | cpio -idm
1406 deduplicate
1407 cd - > /dev/null
1408 rootfs=$TMP_DIR/$(basename $i)
1409 /usr/sbin/mksquashfs $TMP_DIR/fs $rootfs -comp ${1:-xz -Xbcj x86}
1410 cd $TMP_DIR
1411 rootfs_sizes="$rootfs_sizes $(( $(du -s $TMP_DIR/fs | cut -f1) - $(du -s $rootfs | cut -f1) ))"
1412 ( cd $(dirname $rootfs); echo $(basename $rootfs) | cpio -o -H newc ) > $rootfs.cpio
1413 rm -f $rootfs
1414 mv $rootfs.cpio $rootfs
1415 cd - > /dev/null
1416 rm -rf $TMP_DIR/fs
1417 done
1421 # Move meta boot configuration files to basic configuration files
1422 # because meta loram flavor is useless when rootfs is not loaded in RAM
1424 unmeta_boot() {
1425 local root=${1:-$TMP_DIR/loramiso}
1426 if [ -f $root/boot/isolinux/noram.cfg ]; then
1427 # We keep enough information to do unloram...
1428 [ -s $root/boot/isolinux/common.cfg ] &&
1429 sed -i 's/label slitaz/label orgslitaz/' \
1430 $root/boot/isolinux/common.cfg
1431 set -- $(grep 'append ifmem [0-9]' $root/boot/isolinux/isolinux.cfg)
1432 shift
1433 sed -i '/ifmem/{NNNNNNNNd};/^LABEL/{N;/LABEL SliTaz [^L]/{NNNd}}' \
1434 $root/boot/isolinux/isolinux.cfg
1435 [ -n "$3" ] || set -- $(grep 'append [0-9]' $root/boot/isolinux/common.cfg)
1436 sed -i "s/label $3\$/label slitaz/;s|=\(.*rootfs\)\(.*\)\.gz |=\1.gz |" \
1437 $root/boot/isolinux/*.cfg
1438 fi
1442 # Move rootfs to squashfs filesystem(s) to the cdrom writeable with aufs/overlayfs.
1443 # These squashfs may be loaded in RAM at boot time.
1444 # Rootfs are also copied to CD-ROM for tiny ramsize systems.
1445 # Meta flavors are converted to normal flavors.
1447 build_loram_cdrom() {
1448 build_initfs cdrom || return 1
1449 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1450 mkdir $TMP_DIR/loramiso/fs
1451 cd $TMP_DIR/loramiso/fs
1452 for i in $( ls ../boot/root* | sort -r ) ; do
1453 uncompress $i | cpio -idmu
1454 rm -f $i
1455 done
1456 mkdir -p $TMP_DIR/loramiso/fs/mnt/.cdrom
1457 cd - >/dev/null
1458 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1459 unmeta_boot
1460 VOLUM_NAME="SliTaz_LoRAM_CDROM"
1461 sed -i "s|root=|isofs= rodev=/dev/cdrom/fs &|;s/.ive/cdrom/" \
1462 $TMP_DIR/loramiso/boot/isolinux/*.cfg
1463 sed -i '/LABEL slitaz/{NNNNp;s|z cdrom|& text|;s|L slitaz|&text|;s|root=|screen=text &|;s|,[^ ]*||}' \
1464 $TMP_DIR/loramiso/boot/isolinux/*.cfg
1465 create_iso $OUTPUT $TMP_DIR/loramiso
1469 # Create http bootstrap to load and remove loram_cdrom
1470 # Meta flavors are converted to normal flavors.
1472 build_loram_http() {
1473 build_initfs http || return 1
1474 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1475 rm -f $TMP_DIR/loramiso/boot/rootfs*
1476 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1477 unmeta_boot
1478 create_iso $OUTPUT $TMP_DIR/loramiso
1482 # Update meta flavor selection sizes.
1483 # Reduce sizes with rootfs gains.
1485 update_metaiso_sizes() {
1486 for cfg in $(grep -El '(append|ifmem) [0-9]' $TMP_DIR/loramiso/boot/isolinux/*.cfg)
1487 do
1488 local append="$(grep -E '(append|ifmem) [0-9]' $cfg)"
1489 local sizes="$rootfs_sizes"
1490 local new
1491 set -- $append
1492 shift
1493 [ "$1" == "ifmem" ] && shift
1494 new=""
1495 while [ -n "$2" ]; do
1496 local s
1497 case "$1" in
1498 *G) s=$(( ${1%G} * 1024 * 1024 ));;
1499 *M) s=$(( ${1%M} * 1024 ));;
1500 *) s=${1%K};;
1501 esac
1502 sizes=${sizes#* }
1503 for i in $sizes ; do
1504 s=$(( $s - $i ))
1505 done
1506 new="$new $s $2"
1507 shift 2
1508 done
1509 sed -i -e "/append [0-9]/s/append .*/append$new $1/" -e \
1510 "/append ifmem [0-9]/s/append .*/append ifmem$new $1/" $cfg
1511 sed -i 's|\(initrd=\)\([^r]*\)\(rootfs\)|\1\2rootfs.gz,\2\3|' $cfg
1512 sed -i '/LABEL base/{NNNNp;s|base .ive|cdrom|;s|base|cdrom|;s|,[^ ]*||}' $cfg
1513 sed -i '/LABEL cdrom/{NNNNp;s|z cdrom|& text|;s|L cdrom|&text|;s|root=|screen=text &|;s|,[^ ]*||}' $cfg
1514 done
1518 # Move rootfs to a squashfs filesystem into the initramfs writeable with aufs/overlayfs.
1519 # Meta flavor selection sizes are updated.
1521 build_loram_ram() {
1522 build_initfs ram || return 1
1523 build_loram_rootfs "$1"
1524 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1525 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1526 cp $TMP_DIR/rootfs* $TMP_DIR/loramiso/boot
1527 update_metaiso_sizes
1528 create_iso $OUTPUT $TMP_DIR/loramiso
1532 # Remove files installed by packages
1534 find_flavor_rootfs() {
1535 for i in $1/etc/tazlito/*.extract; do
1536 [ -e $i ] || continue
1537 chroot $1 /bin/sh ${i#$1}
1538 done
1540 # Clean hardlinks and files patched by genisofs in /boot
1541 for i in isolinux/isolinux.bin isolinux/boot.cat bzImage ; do
1542 rm -f $1/boot/$i*
1543 done
1545 # Clean files generated in post_install
1546 rm -f $1/lib/modules/*/modules.* $1/etc/mtab \
1547 $1/dev/core $1/dev/fd $1/dev/std*
1549 # Verify md5
1550 cat $1$INSTALLED/*/md5sum | \
1551 while read md5 file; do
1552 [ -e "$1$file" ] || continue
1553 [ "$(md5sum < "$1$file")" == "$md5 -" ] &&
1554 rm -f "$1$file"
1555 done
1557 # Check configuration files
1558 for i in $1$INSTALLED/*/volatile.cpio.gz; do
1559 [ -e $i ] || continue
1560 mkdir /tmp/volatile$$
1561 zcat $i | ( cd /tmp/volatile$$ ; cpio -idmu > /dev/null 2>&1 )
1562 ( cd /tmp/volatile$$ ; find * -type f 2> /dev/null) | \
1563 while read file ; do
1564 [ -e "$1/$file" ] || continue
1565 cmp -s "/tmp/volatile$$/$file" "$1/$file" && rm -f "$1/$file"
1566 done
1567 rm -rf /tmp/volatile$$
1568 done
1570 # Remove other files blindly
1571 for i in $1$INSTALLED/*/files.list; do
1572 for file in $(cat "$i"); do
1573 [ "$1$file" -nt "$i" ] && continue
1574 [ -f "$1$file" -a ! -L "$1$file" ] && continue
1575 [ -d "$1$file" ] || rm -f "$1$file"
1576 done
1577 done
1579 # Remove tazpkg files and tmp files
1580 rm -rf $1$INSTALLED* $1/tmp $1/var/tmp
1581 rm -f $1$LOCALSTATE/*packages* $1$LOCALSTATE/files.list.lzma \
1582 $1$LOCALSTATE/mirror* $1/var/cache/*/* \
1583 $1/var/lock/* $1/var/log/* $1/var/run/* $1/var/run/*/* \
1584 $1/var/lib/* $1/var/lib/dbus/* 2>/dev/null
1586 # Cleanup directory tree
1587 cd $1
1588 find * -type d | sort -r | while read dir; do
1589 rmdir "$dir" 2>/dev/null
1590 done
1591 cd - > /dev/null
1595 # Get byte(s) from a binary file
1597 get() {
1598 od -v -j $1 -N ${3:-2} -t u${3:-2} -w${3:-2} -An $2 2>/dev/null
1602 # Get cpio flavor info from the ISO image
1604 flavordata() {
1605 [ $(get 1024 $1) -eq 35615 ] && n=2 || n=$((1+$(get 417 $1 1)))
1606 dd if=$1 bs=512 skip=$n count=20 2>/dev/null | zcat 2>/dev/null
1610 # Restore undigest mirrors
1612 restore_mirrors() {
1613 local undigest="$root$LOCALSTATE/undigest" priority="$root$LOCALSTATE/priority"
1614 [ -d "$undigest.bak" ] || [ -e "$priority.bak" ] || return
1616 action 'Restoring mirrors...'
1617 if [ -d "$undigest.bak" ]; then
1618 [ -d "$undigest" ] && rm -r "$undigest"
1619 mv "$undigest.bak" "$undigest"
1620 fi
1621 [ -e "$priority.bak" ] && mv -f "$priority.bak" "$priority"
1622 :; status
1626 # Setup undigest mirrors
1628 setup_mirrors() {
1629 # Setup mirrors in plain system or in chroot (with variable root=)
1630 local mirrorlist="$1" fresh repacked
1631 local undigest="$root$LOCALSTATE/undigest" priority="$root$LOCALSTATE/priority"
1633 # Restore mirrors first: in case of non-clear exits, hangs, etc.
1634 restore_mirrors
1636 _ 'Setting up mirrors for %s...' "$root/"
1637 # Backing up current undigest mirrors and priority
1638 [ -d "$undigest" ] && mv "$undigest" "$undigest.bak"
1639 [ -e "$priority" ] && mv "$priority" "$priority.bak"
1640 rm -rf '/var/www/tazlito/'
1641 mkdir -p '/var/www/tazlito/'
1643 # Packages produced by CookUtils: on Tank or local, or repacked packages: highest priority
1644 fresh='/home/slitaz/packages'
1645 if [ -d "$fresh" ]; then
1646 # Setup first undigest mirror
1647 mkdir -p "$undigest/fresh"
1648 echo "$fresh" > "$undigest/fresh/mirror"
1649 echo 'fresh' >> "$priority"
1650 # Rebuild mirror DB if needed
1651 [ ! -e "$fresh/IDs" ] && tazpkg mkdb "$fresh" --forced --root=''
1652 [ -n "$(find -L "$fresh" -name '*.tazpkg' -newer "$fresh/IDs")" ] && \
1653 tazpkg mkdb "$fresh" --forced --root=''
1654 cp -a "$fresh/files.list.lzma" "$fresh/files-list.lzma"
1655 fi
1657 # Repacked packages: high priority
1658 repacked="$PACKAGES_REPOSITORY"
1659 if [ -d "$repacked" -a "$repacked" != "$fresh" ] && ls "$repacked" | grep -q ".tazpkg"; then
1660 # According to Tazlito setup file (tazlito.conf):
1661 # WORK_DIR="/home/slitaz/$SLITAZ_VERSION"
1662 # or
1663 # WORK_DIR="/home/slitaz"
1664 # and
1665 # PACKAGES_REPOSITORY="$WORK_DIR/packages"
1666 # It MAY or MAY NOT match /home/slitaz/packages, so here we setup second repository
1668 # Setup second undigest mirror
1669 mkdir -p "$undigest/repacked"
1670 echo "$repacked" > "$undigest/repacked/mirror"
1671 echo 'repacked' >> "$priority"
1672 # Rebuild mirror DB if needed
1673 [ ! -e "$repacked/IDs" ] && tazpkg mkdb "$repacked" --forced --root=''
1674 [ -n "$(find -L "$repacked" -name '*.tazpkg' -newer "$repacked/IDs")" ] && \
1675 tazpkg mkdb "$repacked" --forced --root=''
1676 cp -a "$repacked/files.list.lzma" "$repacked/files-list.lzma"
1677 fi
1679 # All repositories listed in mirrors list: normal priority
1680 [ -e "$mirrorlist" ] && \
1681 while read mirror; do
1682 # Provide consistent mirror ID for caching purpose: /var/cache/tazpkg/<mirror ID>/packages
1683 mirrorid=$(echo "$mirror" | md5sum | cut -d' ' -f1)
1684 mkdir -p "$undigest/$mirrorid"
1685 echo "$mirror" > "$undigest/$mirrorid/mirror"
1686 echo "$mirrorid" >> "$priority"
1687 done < "$mirrorlist"
1689 # And, finally, main mirror with the lowest (failsafe) priority (nothing to do)
1691 # Show list of mirrors
1692 [ -f "$priority" ] && awk -vdb="$root$LOCALSTATE" '
1693 function show(num, name, url) {
1694 printf " %-1.1d. %32.32s %-44.44s\n", num, name " ...............................", url;
1697 num++;
1698 "cat " db "/undigest/" $0 "/mirror" | getline url;
1699 show(num, $0, url);
1701 END {
1702 num++;
1703 "cat " db "/mirror" | getline url;
1704 show(num, "main", url);
1705 }' "$priority"
1707 tazpkg recharge --quiet >/dev/null
1711 # Get list of 'packages.info' lists using priority
1713 pi_lists() {
1714 local pi
1715 [ -s "$root$LOCALSTATE/packages.info" ] || tazpkg recharge --root="$root" >/dev/null 2>&1
1716 local priority="$root$LOCALSTATE/priority"
1717 local undigest="$root$LOCALSTATE/undigest"
1720 [ -s "$priority" ] && cat "$priority"
1721 echo 'main'
1722 [ -d "$undigest" ] && ls "$undigest"
1723 } | awk -vun="$undigest/" '
1725 if (arr[$0] != 1) {
1726 arr[$0] = 1;
1727 print un $0 "/packages.info";
1729 }' | sed 's|/undigest/main||' | \
1730 while read pi; do
1731 [ -e "$pi" ] && echo "$pi"
1732 done
1736 # Strip versions from packages list
1738 strip_versions() {
1739 if [ -n "$stripped" ]; then
1740 action 'Consider list %s already stripped' "$(basename "$1")"
1741 status
1742 return 0
1743 fi
1744 action 'Strip versions from list %s...' "$(basename "$1")"
1745 local in_list="$1" tmp_list="$(mktemp)" namever pkg
1746 [ -f "$in_list" ] || die "List '$in_list' not found."
1748 # $pkg=<name>-<version> or $pkg=<name>; both <name> and <version> may contain dashes
1749 awk '
1751 if (FILENAME ~ "packages.info") {
1752 # Collect package names
1753 FS = "\t"; pkg[$1] = 1;
1754 } else {
1755 FS = OFS = "-"; $0 = $0; # Fix bug with FS for first record
1756 while (NF > 1 && ! pkg[$0])
1757 NF --;
1758 printf "%s\n", $0;
1760 }' $(pi_lists) "$in_list" > "$tmp_list"
1762 cat "$tmp_list" > "$in_list"
1763 rm "$tmp_list"
1764 status
1768 # Display list of unknown packages (informative)
1770 display_unknown() {
1771 [ -s "$1" ] || return
1772 echo "Unknown packages:" >&2
1773 cat "$1" >&2
1774 rm "$1"
1778 # Display warnings about critical packages absent (informative)
1780 display_warn() {
1781 [ -s "$1" ] || return
1782 echo "Absent critical packages:" >&2
1783 cat "$1" >&2
1784 rm "$1"
1785 echo "Probably ISO image will be unusable."
1789 # Install packages to rootfs
1791 install_list_to_rootfs() {
1792 local list="$1" rootfs="$2" pkg i ii
1793 local undigest="$rootfs/var/lib/tazpkg/undigest"
1795 # initial tazpkg setup in empty rootfs
1796 tazpkg --root=$rootfs >/dev/null 2>&1
1797 # pass current 'mirror' to the rootfs
1798 mkdir -p $rootfs/var/lib/tazpkg $rootfs/etc
1799 cp -f /var/lib/tazpkg/mirror $rootfs/var/lib/tazpkg/mirror
1800 cp -f /etc/slitaz-release $rootfs/etc/slitaz-release
1801 # link rootfs packages cache to the regular packages cache
1802 rm -r "$rootfs/var/cache/tazpkg"
1803 ln -s /var/cache/tazpkg "$rootfs/var/cache/tazpkg"
1805 setup_mirrors mirrors
1807 # Just in case if flavor doesn't contain "tazlito" package
1808 mkdir -p "$rootfs/etc/tazlito"
1810 newline
1812 # Choose detailed log with --detailed
1813 if [ -n "$detailed" ]; then
1814 while read pkg; do
1815 separator '-'
1816 echo $pkg
1817 tazpkg -gi $pkg --root=$rootfs --local --quiet --cookmode | tee -a $log
1818 done < $list
1819 separator '='
1820 else
1821 while read pkg; do
1822 action 'Installing package: %s' "$pkg"
1823 yes y | tazpkg -gi $pkg --root=$rootfs --quiet >> $log || exit 1
1824 status
1825 done < $list
1826 fi
1827 newline
1829 restore_mirrors
1830 # Remove 'fresh' and 'repacked' undigest repos leaving all other
1831 for i in fresh repacked; do
1832 ii="$undigest/$i"
1833 [ -d "$ii" ] && rm -rf "$ii"
1834 ii="$rootfs/var/lib/tazpkg/priority"
1835 if [ -f "$ii" ]; then
1836 sed -i "/$i/d" "$ii"
1837 [ -s "$ii" ] || rm "$ii"
1838 fi
1839 done
1840 [ -d "$undigest" ] && \
1841 for i in $(find "$undigest" -type f); do
1842 # Remove all undigest PKGDB files but 'mirror'
1843 [ "$(basename "$i")" != 'mirror' ] && rm "$i"
1844 done
1845 [ -d "$undigest" ] && \
1846 rmdir --ignore-fail-on-non-empty "$undigest"
1848 # Un-link packages cache
1849 rm "$rootfs/var/cache/tazpkg"
1851 # Clean /var/lib/tazpkg
1852 (cd $rootfs/var/lib/tazpkg; rm ID* descriptions.txt extra.list files* packages.* 2>/dev/null)
1858 ####################
1859 # Tazlito commands #
1860 ####################
1862 # /usr/bin/tazlito is linked with /usr/bin/reduplicate and /usr/bin/deduplicate
1863 case "$0" in
1864 *reduplicate)
1865 find ${@:-.} ! -type d -links +1 \
1866 -exec cp -a {} {}$$ \; -exec mv {}$$ {} \;
1867 exit 0 ;;
1868 *deduplicate)
1869 deduplicate "$@"
1870 exit 0 ;;
1871 esac
1874 case "$COMMAND" in
1875 stats)
1876 # Tazlito general statistics from the config file.
1878 title 'Tazlito statistics'
1879 optlist "\
1880 Config file : $CONFIG_FILE
1881 ISO name : $ISO_NAME.iso
1882 Volume name : $VOLUM_NAME
1883 Prepared : $PREPARED
1884 Packages repository : $PACKAGES_REPOSITORY
1885 Distro directory : $DISTRO
1886 Additional files : $ADDFILES
1887 " | sed '/: $/d'
1888 footer
1889 ;;
1892 list-addfiles)
1893 # Simple list of additional files in the rootfs
1894 newline
1895 if [ -d "$ADDFILES/rootfs" ]; then
1896 cd $ADDFILES
1897 find rootfs -type f
1898 else
1899 _ 'Additional files not found: %s' "$ADDFILES/rootfs/"
1900 fi
1901 newline
1902 ;;
1905 gen-config)
1906 # Generate a new config file in the current dir or the specified
1907 # directory by $2.
1909 if [ -n "$2" ]; then
1910 mkdir -p "$2" && cd "$2"
1911 fi
1913 newline
1914 action 'Generating empty tazlito.conf...'
1915 empty_config_file
1916 status
1918 separator
1919 if [ -f 'tazlito.conf' ] ; then
1920 _ 'Configuration file is ready to edit.'
1921 _ 'File location: %s' "$(pwd)/tazlito.conf"
1922 newline
1923 fi
1924 ;;
1927 configure)
1928 # Configure a tazlito.conf config file. Start by getting
1929 # a empty config file and sed it.
1931 if [ -f 'tazlito.conf' ]; then
1932 rm tazlito.conf
1933 else
1934 [ $(id -u) -ne 0 ] && die 'You must be root to configure the main config file' \
1935 'or in the same directory of the file you want to configure.'
1936 cd /etc
1937 fi
1939 empty_config_file
1941 title 'Configuring: %s' "$(pwd)/tazlito.conf"
1943 # ISO name.
1944 echo -n "ISO name : " ; read answer
1945 sed -i s#'ISO_NAME=\"\"'#"ISO_NAME=\"$answer\""# tazlito.conf
1946 # Volume name.
1947 echo -n "Volume name : " ; read answer
1948 sed -i s/'VOLUM_NAME=\"SliTaz\"'/"VOLUM_NAME=\"$answer\""/ tazlito.conf
1949 # Packages repository.
1950 echo -n "Packages repository : " ; read answer
1951 sed -i s#'PACKAGES_REPOSITORY=\"\"'#"PACKAGES_REPOSITORY=\"$answer\""# tazlito.conf
1952 # Distro path.
1953 echo -n "Distro path : " ; read answer
1954 sed -i s#'DISTRO=\"\"'#"DISTRO=\"$answer\""# tazlito.conf
1955 footer "Config file is ready to use."
1956 echo 'You can now extract an ISO or generate a distro.'
1957 newline
1958 ;;
1961 gen-iso)
1962 # Simply generate a new iso.
1964 check_root
1965 verify_rootcd
1966 gen_livecd_isolinux
1967 distro_stats
1968 ;;
1971 gen-initiso)
1972 # Simply generate a new initramfs with a new iso.
1974 check_root
1975 verify_rootcd
1976 gen_initramfs "$ROOTFS"
1977 gen_livecd_isolinux
1978 distro_stats
1979 ;;
1982 extract-distro)
1983 # Extract an ISO image to a directory and rebuild the LiveCD tree.
1985 check_root
1986 ISO_IMAGE="$2"
1987 [ -z "$ISO_IMAGE" ] && die 'Please specify the path to the ISO image.' \
1988 'Example:\n tazlito image.iso /path/target'
1990 # Set the distro path by checking for $3 on cmdline.
1991 TARGET="${3:-$DISTRO}"
1993 # Exit if existing distro is found.
1994 [ -d "$TARGET/rootfs" ] && die "A rootfs exists in '$TARGET'." \
1995 'Please clean the distro tree or change directory path.'
1997 title 'Tazlito extracting: %s' "$(basename $ISO_IMAGE)"
1999 # Start to mount the ISO.
2000 action 'Mounting ISO image...'
2001 mkdir -p "$TMP_DIR"
2002 # Get ISO file size.
2003 isosize=$(du -sh "$ISO_IMAGE" | cut -f1)
2004 mount -o loop -r "$ISO_IMAGE" "$TMP_DIR"
2005 sleep 2
2006 # Prepare target dir, copy the kernel and the rootfs.
2007 mkdir -p "$TARGET/rootfs" "$TARGET/rootcd/boot"
2008 status
2010 action 'Copying the Linux kernel...'
2011 if cp $TMP_DIR/boot/vmlinuz* "$TARGET/rootcd/boot" 2>/dev/null; then
2012 make_bzImage_hardlink "$TARGET/rootcd/boot"
2013 else
2014 cp "$TMP_DIR/boot/bzImage" "$TARGET/rootcd/boot"
2015 fi
2016 status
2018 for i in $(ls $TMP_DIR); do
2019 [ "$i" == 'boot' ] && continue
2020 cp -a "$TMP_DIR/$i" "$TARGET/rootcd"
2021 done
2023 for loader in isolinux syslinux extlinux grub; do
2024 [ -d "$TMP_DIR/boot/$loader" ] || continue
2025 action 'Copying %s files...' "$loader"
2026 cp -a "$TMP_DIR/boot/$loader" "$TARGET/rootcd/boot"
2027 status
2028 done
2030 action 'Copying the rootfs...'
2031 cp $TMP_DIR/boot/rootfs*.?z "$TARGET/rootcd/boot"
2032 status
2034 # Extract initramfs.
2035 cd "$TARGET/rootfs"
2036 action 'Extracting the rootfs...'
2037 extract_rootfs "$TARGET/rootcd/boot/$INITRAMFS" "$TARGET/rootfs"
2038 # unpack /usr
2039 for i in etc/tazlito/*.extract; do
2040 [ -f "$i" ] && . $i ../rootcd
2041 done
2042 # Umount and remove temp directory and cd to $TARGET to get stats.
2043 umount "$TMP_DIR" && rm -rf "$TMP_DIR"
2044 cd ..
2045 status
2047 newline
2048 separator
2049 echo "Extracted : $(basename $ISO_IMAGE) ($isosize)"
2050 echo "Distro tree : $(pwd)"
2051 echo "Rootfs size : $(du -sh rootfs)"
2052 echo "Rootcd size : $(du -sh rootcd)"
2053 footer
2054 ;;
2057 list-flavors)
2058 # Show available flavors.
2059 list='/etc/tazlito/flavors.list'
2060 [ ! -s $list -o -n "$recharge" ] && download flavors.list -O - > $list
2061 title 'List of flavors'
2062 cat $list
2063 footer
2064 ;;
2067 show-flavor)
2068 # Show flavor descriptions.
2069 set -e
2070 flavor=${2%.flavor}
2071 flv_dir="$(extract_flavor "$flavor")"
2072 desc="$flv_dir/$flavor.desc"
2073 if [ -n "$brief" ]; then
2074 if [ -z "$noheader" ]; then
2075 printf "%-16.16s %6.6s %6.6s %s\n" 'Name' 'ISO' 'Rootfs' 'Description'
2076 separator
2077 fi
2078 printf "%-16.16s %6.6s %6.6s %s\n" "$flavor" \
2079 "$(field ISO "$desc")" \
2080 "$(field Rootfs "$desc")" \
2081 "$(field Description "$desc")"
2082 else
2083 separator
2084 cat "$desc"
2085 fi
2086 cleanup
2087 ;;
2090 gen-liveflavor)
2091 # Generate a new flavor from the live system.
2092 FLAVOR=${2%.flavor}
2093 [ -z "$FLAVOR" ] && die 'Please specify flavor name on the commandline.'
2095 case "$FLAVOR" in
2096 -?|-h*|--help)
2097 cat <<EOT
2098 SliTaz Live Tool - Version: $VERSION
2100 $(boldify 'Usage:') tazlito gen-liveflavor <flavor-name> [<flavor-patch-file>]
2102 $(boldify '<flavor-patch-file> format:')
2103 $(optlist "\
2104 code data
2105 + package to add
2106 - package to remove
2107 ! non-free package to add
2108 ? display message
2109 @ flavor description
2110 ")
2112 $(boldify 'Example:')
2113 $(optlist "\
2114 @ Developer tools for SliTaz maintainers
2115 + slitaz-toolchain
2116 + mercurial
2117 ")
2118 EOT
2119 exit 1
2120 ;;
2121 esac
2122 mv /etc/tazlito/distro-packages.list \
2123 /etc/tazlito/distro-packages.list.$$ 2>/dev/null
2124 rm -f distro-packages.list non-free.list 2>/dev/null
2125 tazpkg recharge
2127 DESC=""
2128 [ -n "$3" ] && \
2129 while read action pkg; do
2130 case "$action" in
2131 +) yes | tazpkg get-install $pkg 2>&1 >> $log || exit 1 ;;
2132 -) yes | tazpkg remove $pkg ;;
2133 !) echo $pkg >> non-free.list ;;
2134 @) DESC="$pkg" ;;
2135 \?) echo -en "$pkg"; read action ;;
2136 esac
2137 done < $3
2139 yes '' | tazlito gen-distro
2140 echo "$DESC" | tazlito gen-flavor "$FLAVOR"
2141 mv /etc/tazlito/distro-packages.list.$$ \
2142 /etc/tazlito/distro-packages.list 2>/dev/null
2143 ;;
2146 gen-flavor)
2147 # Generate a new flavor from the last ISO image generated
2148 FLAVOR=${2%.flavor}
2149 [ -z "$FLAVOR" ] && die 'Please specify flavor name on the commandline.'
2151 title 'Flavor generation'
2152 check_rootfs
2153 FILES="$FLAVOR.pkglist"
2155 action 'Creating file %s...' "$FLAVOR.flavor"
2156 for i in rootcd rootfs; do
2157 if [ -d "$ADDFILES/$i" ] ; then
2158 FILES="$FILES\n$FLAVOR.$i"
2159 ( cd "$ADDFILES/$i"; find . ) | cpio -o -H newc 2>/dev/null | dogzip $FLAVOR.$i
2160 fi
2161 done
2162 status
2164 answer=$(grep -s ^Description $FLAVOR.desc)
2165 answer=${answer#Description : }
2166 if [ -z "$answer" ]; then
2167 echo -n "Description: "
2168 read answer
2169 fi
2171 action 'Compressing flavor %s...' "$FLAVOR"
2172 echo "Flavor : $FLAVOR" > $FLAVOR.desc
2173 echo "Description : $answer" >> $FLAVOR.desc
2174 (cd $DISTRO; distro_sizes) >> $FLAVOR.desc
2175 \rm -f $FLAVOR.pkglist $FLAVOR.nonfree 2>/dev/null
2176 for i in $(ls $ROOTFS$INSTALLED); do
2177 eval $(grep ^VERSION= $ROOTFS$INSTALLED/$i/receipt)
2178 EXTRAVERSION=""
2179 eval $(grep ^EXTRAVERSION= $ROOTFS$INSTALLED/$i/receipt)
2180 eval $(grep ^CATEGORY= $ROOTFS$INSTALLED/$i/receipt)
2181 if [ "$CATEGORY" == 'non-free' -a "${i%%-*}" != 'get' ]; then
2182 echo "$i" >> $FLAVOR.nonfree
2183 else
2184 echo "$i-$VERSION$EXTRAVERSION" >> $FLAVOR.pkglist
2185 fi
2186 done
2187 [ -s $FLAVOR.nonfree ] && $FILES="$FILES\n$FLAVOR.nonfree"
2188 for i in $LOCALSTATE/undigest/*/mirror ; do
2189 [ -s $i ] && cat $i >> $FLAVOR.mirrors
2190 done
2191 [ -s $FLAVOR.mirrors ] && $FILES="$FILES\n$FLAVOR.mirrors"
2192 touch -t 197001010100.00 $FLAVOR.*
2193 echo -e "$FLAVOR.desc\n$FILES" | cpio -o -H newc 2>/dev/null | dogzip $FLAVOR.flavor
2194 rm $(echo -e $FILES)
2195 status
2197 footer "Flavor size: $(du -sh $FLAVOR.flavor)"
2198 ;;
2201 upgrade-flavor)
2202 # Strip versions from pkglist and update estimated numbers in flavor.desc
2203 flavor="${2%.flavor}"
2204 set -e
2205 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2206 set +e
2208 flv_dir="$(extract_flavor "$flavor")"
2210 strip_versions "$flv_dir/$flavor.pkglist"
2212 action 'Updating %s...' "$flavor.desc"
2214 [ -f "$flv_dir/$flavor.mirrors" ] && setup_mirrors "$flv_dir/$flavor.mirrors" >/dev/null
2215 set -- $(module calc_sizes "$flv_dir" "$flavor")
2216 restore_mirrors >/dev/null
2218 sed -i -e '/Image is ready/d' \
2219 -e "s|\(Rootfs size *:\).*$|\1 $1 (estimated)|" \
2220 -e "s|\(Initramfs size *:\).*$|\1 $2 (estimated)|" \
2221 -e "s|\(ISO image size *:\).*$|\1 $3 (estimated)|" \
2222 -e "s|\(Packages *:\).*$|\1 $4|" \
2223 -e "s|\(Build date *:\).*$|\1 $(date '+%Y%m%d at %T')|" \
2224 "$flv_dir/$flavor.desc"
2226 pack_flavor "$flv_dir" "$flavor"
2227 status
2228 display_unknown "$flv_dir/err"
2229 display_warn "$flv_dir/warn"
2230 cleanup
2231 ;;
2234 extract-flavor)
2235 # Extract a flavor into $FLAVORS_REPOSITORY
2236 flavor="${2%.flavor}"
2237 set -e
2238 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2239 set +e
2241 action 'Extracting %s...' "$flavor.flavor"
2242 flv_dir="$(extract_flavor "$flavor" full)"
2243 storage="$FLAVORS_REPOSITORY/$flavor"
2245 rm -rf "$storage" 2>/dev/null
2246 mkdir -p "$storage"
2247 cp -a "$flv_dir"/* "$storage"
2248 rm "$storage/description"
2249 status
2251 strip_versions "$storage/packages.list"
2253 cleanup
2254 ;;
2257 pack-flavor)
2258 # Create a flavor from $FLAVORS_REPOSITORY.
2259 flavor=${2%.flavor}
2260 storage="$FLAVORS_REPOSITORY/$flavor"
2262 [ -s "$storage/receipt" ] || die "No $flavor receipt in $FLAVORS_REPOSITORY."
2264 action 'Creating flavor %s...' "$flavor"
2265 tmp_dir="$(mktemp -d)"
2267 while read from to; do
2268 [ -s "$storage/$from" ] || continue
2269 cp -a "$storage/$from" "$tmp_dir/$to"
2270 done <<EOT
2271 mirrors $flavor.mirrors
2272 distro.sh $flavor-distro.sh
2273 receipt $flavor.receipt
2274 non-free.list $flavor.nonfree
2275 EOT
2277 # Build the package list.
2278 # It can include a list from another flavor with the keyword @include
2279 if [ -s "$storage/packages.list" ]; then
2280 include=$(grep '^@include' "$storage/packages.list")
2281 if [ -n "$include" ]; then
2282 include=${include#@include }
2283 if [ -s "$FLAVORS_REPOSITORY/$include/packages.list" ]; then
2284 cp -f "$FLAVORS_REPOSITORY/$include/packages.list" "$tmp_dir/$flavor.pkglist"
2285 else
2286 echo -e "\nERROR: Can't find include package list from $include\n"
2287 fi
2288 fi
2289 # Generate the final/initial package list
2290 [ -s "$storage/packages.list" ] && \
2291 cat "$storage/packages.list" >> "$tmp_dir/$flavor.pkglist"
2292 sed -i '/@include/d' "$tmp_dir/$flavor.pkglist"
2293 fi
2295 if grep -q ^ROOTFS_SELECTION "$storage/receipt"; then
2296 # Process multi-rootfs flavor
2297 . "$storage/receipt"
2298 set -- $ROOTFS_SELECTION
2299 [ -n "$FRUGAL_RAM" ] || FRUGAL_RAM=$1
2300 [ -f "$FLAVORS_REPOSITORY/$2/packages.list" ] || tazlito extract-flavor $2
2301 cp "$FLAVORS_REPOSITORY/$2/packages.list" "$tmp_dir/$flavor.pkglist"
2303 for i in rootcd rootfs; do
2304 mkdir "$tmp_dir/$i"
2305 # Copy extra files from the first flavor
2306 [ -d "$FLAVORS_REPOSITORY/$2/$i" ] &&
2307 cp -a "$FLAVORS_REPOSITORY/$2/$i" "$tmp_dir"
2308 # Overload extra files by meta flavor
2309 [ -d "$storage/$i" ] && cp -a "$storage/$i" "$tmp_dir"
2310 [ -n "$(ls $tmp_dir/$i)" ] &&
2311 (cd "$tmp_dir/$i"; find . | cpio -o -H newc 2>/dev/null ) | \
2312 dogzip "$tmp_dir/$flavor.$i"
2313 rm -rf "$tmp_dir/$i"
2314 done
2315 else
2316 # Process plain flavor
2317 for i in rootcd rootfs; do
2318 [ -d "$storage/$i" ] || continue
2319 (cd "$storage/$i";
2320 find . | cpio -o -H newc 2>/dev/null) | dogzip "$tmp_dir/$flavor.$i"
2321 done
2322 fi
2324 unset VERSION MAINTAINER ROOTFS_SELECTION
2325 set -- $(module calc_sizes "$tmp_dir" "$flavor")
2326 ROOTFS_SIZE="$1 (estimated)"
2327 INITRAMFS_SIZE="$2 (estimated)"
2328 ISO_SIZE="$3 (estimated)"
2329 PKGNUM="$4"
2330 . "$storage/receipt"
2332 sed '/: $/d' > "$tmp_dir/$flavor.desc" <<EOT
2333 Flavor : $FLAVOR
2334 Description : $SHORT_DESC
2335 Version : $VERSION
2336 Maintainer : $MAINTAINER
2337 LiveCD RAM size : $FRUGAL_RAM
2338 Rootfs list : $ROOTFS_SELECTION
2339 Build date : $(date '+%Y%m%d at %T')
2340 Packages : $PKGNUM
2341 Rootfs size : $ROOTFS_SIZE
2342 Initramfs size : $INITRAMFS_SIZE
2343 ISO image size : $ISO_SIZE
2344 ================================================================================
2346 EOT
2348 rm -f $tmp_dir/packages.list
2349 pack_flavor "$tmp_dir" "$flavor"
2350 status
2351 display_unknown "$tmp_dir/err"
2352 display_warn "$flv_dir/warn"
2353 cleanup
2354 ;;
2357 get-flavor)
2358 # Get a flavor's files and prepare for gen-distro.
2359 flavor=${2%.flavor}
2360 title 'Preparing %s distro flavor' "$flavor"
2361 set -e
2362 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2363 set +e
2365 action 'Cleaning %s...' "$DISTRO"
2366 [ -d "$DISTRO" ] && rm -r "$DISTRO"
2367 # Clean old files
2368 for i in non-free.list distro-packages.list distro.sh receipt mirrors err; do
2369 [ -f "$i" ] && rm "$i"
2370 done
2371 mkdir -p "$DISTRO"
2372 status
2374 [ -z "$noup" ] && tazlito upgrade-flavor "$flavor.flavor"
2376 action 'Extracting flavor %s...' "$flavor.flavor"
2377 flv_dir="$(extract_flavor "$flavor" info)"
2378 cp -a "$flv_dir"/* .
2379 mv packages.list distro-packages.list
2380 mv -f info /etc/tazlito
2381 status
2383 for i in rootcd rootfs; do
2384 if [ -d "$i" ]; then
2385 mkdir -p "$ADDFILES"; mv "$i" "$ADDFILES/$i"
2386 fi
2387 done
2389 sed '/^Rootfs list/!d;s/.*: //' description > /etc/tazlito/rootfs.list
2390 [ -s /etc/tazlito/rootfs.list ] || rm -f /etc/tazlito/rootfs.list
2392 action 'Updating %s...' 'tazlito.conf'
2393 [ -f tazlito.conf ] || cp /etc/tazlito/tazlito.conf .
2394 grep -v "^#VOLUM_NAME" < tazlito.conf | \
2395 sed "s/^VOLUM_NA/VOLUM_NAME=\"SliTaz $flavor\"\\n#VOLUM_NA/" \
2396 > tazlito.conf.$$ && mv tazlito.conf.$$ tazlito.conf
2397 sed -i "s/ISO_NAME=.*/ISO_NAME=\"slitaz-$flavor\"/" tazlito.conf
2398 status
2400 footer 'Flavor is ready to be generated by `tazlito gen-distro`'
2401 cleanup
2402 ;;
2405 iso2flavor)
2406 [ -z "$3" -o ! -s "$2" ] && die 'Usage: tazlito iso2flavor <image.iso> <flavor_name>' \
2407 '\n\nCreate a file <flavor_name>.flavor from the CD-ROM image file <image.iso>'
2409 FLAVOR=${3%.flavor}
2410 mkdir -p $TMP_DIR/iso $TMP_DIR/rootfs $TMP_DIR/flavor
2411 mount -o loop,ro $2 $TMP_DIR/iso
2412 flavordata $2 | (cd $TMP_DIR/flavor; cpio -i 2>/dev/null)
2413 if [ -s $TMP_DIR/iso/boot/rootfs1.gz -a \
2414 ! -s $TMP_DIR/flavor/*.desc ]; then
2415 _ 'META flavors are not supported.'
2416 umount -d $TMP_DIR/iso
2417 elif [ ! -s $TMP_DIR/iso/boot/rootfs.gz -a \
2418 ! -s $TMP_DIR/iso/boot/rootfs1.gz ]; then
2419 _ 'No %s in ISO image. Needs a SliTaz ISO.' '/boot/rootfs.gz'
2420 umount -d $TMP_DIR/iso
2421 else
2422 for i in $(ls -r $TMP_DIR/iso/boot/rootfs*z); do
2423 uncompress $i | \
2424 ( cd $TMP_DIR/rootfs ; cpio -idmu > /dev/null 2>&1 )
2425 done
2426 if [ ! -s $TMP_DIR/rootfs/etc/slitaz-release ]; then
2427 _ 'No file %s in %s of ISO image. Needs a non-loram SliTaz ISO.' \
2428 '/etc/slitaz-release' '/boot/rootfs.gz'
2429 umount -d $TMP_DIR/iso
2430 else
2431 ROOTFS_SIZE=$(du -hs $TMP_DIR/rootfs | awk '{ print $1 }')
2432 RAM_SIZE=$(du -s $TMP_DIR/rootfs | awk '{ print 32*int(($1+36000)/32768) "M" }')
2433 cp -a $TMP_DIR/iso $TMP_DIR/rootcd
2434 ISO_SIZE=$(df -h $TMP_DIR/iso | awk 'END { print $2 }')
2435 BUILD_DATE=$(date '+%Y%m%d at %T' -r "$TMP_DIR/iso/md5sum")
2436 umount -d $TMP_DIR/iso
2437 INITRAMFS_SIZE=$(du -chs $TMP_DIR/rootcd/boot/rootfs*.gz | awk 'END { print $1 }')
2438 rm -f $TMP_DIR/rootcd/boot/rootfs.gz $TMP_DIR/rootcd/md5sum
2439 mv $TMP_DIR/rootcd/boot $TMP_DIR/rootfs
2440 [ -d $TMP_DIR/rootcd/efi ] && mv $TMP_DIR/rootcd/efi $TMP_DIR/rootfs
2441 sed 's/.* \(.*\).tazpkg*/\1/' > $TMP_DIR/$FLAVOR.pkglist \
2442 < $TMP_DIR/rootfs$INSTALLED.md5
2443 PKGCNT=$(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l | awk '{ print $1 }')
2444 if [ -s $TMP_DIR/flavor/*desc ]; then
2445 cp $TMP_DIR/flavor/*.desc $TMP_DIR/$FLAVOR.desc
2446 [ -s $TMP_DIR/$FLAVOR.receipt ] &&
2447 cp $TMP_DIR/flavor/*.receipt $TMP_DIR/$FLAVOR.receipt
2448 for i in rootfs rootcd ; do
2449 [ -s $TMP_DIR/flavor/*.list$i ] &&
2450 sed 's/.\{1,45\}//;/^\.$/d' $TMP_DIR/flavor/*.list$i | \
2451 ( cd $TMP_DIR/$i ; cpio -o -H newc ) | dogzip $TMP_DIR/$FLAVOR.$i
2452 done
2453 else
2454 find_flavor_rootfs $TMP_DIR/rootfs
2455 [ -d $TMP_DIR/rootfs/boot ] && mv $TMP_DIR/rootfs/boot $TMP_DIR/rootcd
2456 [ -d $TMP_DIR/rootfs/efi ] && mv $TMP_DIR/rootfs/efi $TMP_DIR/rootcd
2457 for i in rootfs rootcd ; do
2458 [ "$(ls $TMP_DIR/$i)" ] &&
2459 ( cd "$TMP_DIR/$i"; find * | cpio -o -H newc ) | dogzip "$TMP_DIR/$FLAVOR.$i"
2460 done
2461 unset VERSION MAINTAINER
2462 echo -en "Flavor short description \007: "; read -t 30 DESCRIPTION
2463 if [ -n "$DESCRIPTION" ]; then
2464 _n 'Flavor version : '; read -t 30 VERSION
2465 _n 'Flavor maintainer (your email) : '; read -t 30 MAINTAINER
2466 fi
2468 cat > $TMP_DIR/$FLAVOR.desc <<EOT
2469 Flavor : $FLAVOR
2470 Description : ${DESCRIPTION:-SliTaz $FLAVOR flavor}
2471 Version : ${VERSION:-1.0}
2472 Maintainer : ${MAINTAINER:-nobody@slitaz.org}
2473 LiveCD RAM size : $RAM_SIZE
2474 Build date : $BUILD_DATE
2475 Packages : $PKGCNT
2476 Rootfs size : $ROOTFS_SIZE
2477 Initramfs size : $INITRAMFS_SIZE
2478 ISO image size : $ISO_SIZE
2479 ================================================================================
2481 EOT
2482 longline "Tazlito can't detect each file installed during \
2483 a package post_install. You should extract this flavor (tazlito extract-flavor \
2484 $FLAVOR), check the files in /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/rootfs \
2485 tree and remove files generated by post_installs.
2486 Check /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/receipt too and \
2487 repack the flavor (tazlito pack-flavor $FLAVOR)"
2488 fi
2489 ( cd $TMP_DIR; ls $FLAVOR.* | cpio -o -H newc ) | dogzip $FLAVOR.flavor
2490 fi
2491 fi
2492 rm -rf $TMP_DIR
2493 ;;
2496 gen-distro)
2497 # Generate a live distro tree with a set of packages.
2499 check_root
2500 start_time=$(date +%s)
2502 # Tazlito options: --iso or --cdrom
2503 CDROM=''
2504 [ -n "$iso" ] && CDROM="-o loop $iso"
2505 [ -n "$cdrom" ] && CDROM="/dev/cdrom"
2507 # Check if a package list was specified on cmdline.
2508 if [ -f "$2" ]; then
2509 LIST_NAME="$2"
2510 else
2511 LIST_NAME='distro-packages.list'
2512 fi
2514 [ -d "$ROOTFS" -a -z "$forced" ] && die "A rootfs exists in '$DISTRO'." \
2515 'Please clean the distro tree or change directory path.'
2516 [ -d "$ROOTFS" ] && rm -rf "$ROOTFS"
2517 [ -d "$ROOTCD" ] && rm -rf "$ROOTCD"
2519 # If list not given: build list with all installed packages
2520 if [ ! -f "$LIST_NAME" -a -f "$LOCALSTATE/installed.info" ]; then
2521 awk -F$'\t' '{print $1}' "$LOCALSTATE/installed.info" >> "$LIST_NAME"
2522 fi
2524 # Exit if no list name.
2525 [ ! -f "$LIST_NAME" ] && die 'No packages list found or specified. Please read the docs.'
2527 # Start generation.
2528 title 'Tazlito generating a distro'
2530 # Misc checks
2531 mkdir -p "$PACKAGES_REPOSITORY"
2532 REPACK=$(yesorno 'Repack packages from rootfs?' 'n')
2533 newline
2535 # Mount CD-ROM to be able to repack boot-loader packages
2536 if [ ! -e /boot -a -n "$CDROM" ]; then
2537 mkdir $TMP_MNT
2538 if mount -r "$CDROM $TMP_MNT" 2>/dev/null; then
2539 ln -s "$TMP_MNT/boot" /
2540 if [ ! -d "$ADDFILES/rootcd" ] ; then
2541 mkdir -p "$ADDFILES/rootcd"
2542 for i in $(ls $TMP_MNT); do
2543 [ "$i" == 'boot' ] && continue
2544 cp -a "$TMP_MNT/$i" "$ADDFILES/rootcd"
2545 done
2546 fi
2547 else
2548 rmdir "$TMP_MNT"
2549 fi
2550 fi
2552 # Rootfs stuff.
2553 echo 'Preparing the rootfs directory...'
2554 mkdir -p "$ROOTFS"
2555 export root="$ROOTFS"
2556 # pass current 'mirror' to the root
2557 mkdir -p $root/var/lib/tazpkg $root/etc
2558 cp -f /var/lib/tazpkg/mirror $root/var/lib/tazpkg/mirror
2559 cp -f /etc/slitaz-release $root/etc/slitaz-release
2560 strip_versions "$LIST_NAME"
2562 if [ "$REPACK" == 'y' ]; then
2563 # Determine full packages list with all dependencies
2564 tmp_dir="$(mktemp -d)"
2565 cp "$LIST_NAME" "$tmp_dir/flavor.pkglist"
2566 touch "$tmp_dir/full.pkglist"
2567 module calc_sizes "$tmp_dir" 'flavor' "$tmp_dir/full.pkglist" >/dev/null
2569 awk -F$'\t' '{printf "%s %s\n", $1, $2}' "$LOCALSTATE/installed.info" | \
2570 while read pkgname pkgver; do
2571 # Is package in full list?
2572 grep -q "^$pkgname$" "$tmp_dir/full.pkglist" || continue
2573 # Is package already repacked?
2574 [ -e "$PACKAGES_REPOSITORY/$pkgname-$pkgver.tazpkg" ] && continue
2575 _ 'Repacking %s...' "$pkgname-$pkgver"
2576 tazpkg repack "$pkgname" --quiet
2577 [ -f "$pkgname-$pkgver.tazpkg" ] && mv "$pkgname-$pkgver.tazpkg" "$PACKAGES_REPOSITORY"
2578 status
2579 done
2581 rm -r "$tmp_dir"
2582 fi
2584 if [ -f non-free.list ]; then
2585 # FIXME: working in the ROOTFS chroot?
2586 newline
2587 echo 'Preparing non-free packages...'
2588 cp 'non-free.list' "$ROOTFS/etc/tazlito/non-free.list"
2589 for pkg in $(cat 'non-free.list'); do
2590 if [ ! -d "$INSTALLED/$pkg" ]; then
2591 if [ ! -d "$INSTALLED/get-$pkg" ]; then
2592 tazpkg get-install get-$pkg
2593 fi
2594 get-$pkg "$ROOTFS"
2595 fi
2596 tazpkg repack $pkg
2597 pkg=$(ls $pkg*.tazpkg)
2598 grep -q "^$pkg$" $LIST_NAME || echo $pkg >> $LIST_NAME
2599 mv $pkg $PACKAGES_REPOSITORY
2600 done
2601 fi
2602 cp $LIST_NAME $DISTRO/distro-packages.list
2603 newline
2605 install_list_to_rootfs "$DISTRO/distro-packages.list" "$ROOTFS"
2607 cd $DISTRO
2608 cp distro-packages.list $ROOTFS/etc/tazlito
2609 # Copy all files from $ADDFILES/rootfs to the rootfs.
2610 if [ -d "$ADDFILES/rootfs" ] ; then
2611 action 'Copying addfiles content to the rootfs...'
2612 cp -a $ADDFILES/rootfs/* $ROOTFS
2613 status
2614 fi
2616 action 'Root filesystem is generated...'; status
2618 # Root CD part.
2619 action 'Preparing the rootcd directory...'
2620 mkdir -p $ROOTCD
2621 status
2623 # Move the boot dir with the Linux kernel from rootfs.
2624 # The efi & boot dirs go directly on the CD.
2625 if [ -d "$ROOTFS/efi" ] ; then
2626 action 'Moving the efi directory...'
2627 mv $ROOTFS/efi $ROOTCD
2628 status
2629 fi
2630 if [ -d "$ROOTFS/boot" ] ; then
2631 action 'Moving the boot directory...'
2632 mv $ROOTFS/boot $ROOTCD
2633 status
2634 fi
2635 cd $DISTRO
2636 # Copy all files from $ADDFILES/rootcd to the rootcd.
2637 if [ -d "$ADDFILES/rootcd" ] ; then
2638 action 'Copying addfiles content to the rootcd...'
2639 cp -a $ADDFILES/rootcd/* $ROOTCD
2640 status
2641 fi
2642 # Execute the distro script used to perform tasks in the rootfs
2643 # before compression. Give rootfs path in arg
2644 [ -z "$DISTRO_SCRIPT" ] && DISTRO_SCRIPT="$TOP_DIR/distro.sh"
2645 if [ -x "$DISTRO_SCRIPT" ]; then
2646 echo 'Executing distro script...'
2647 sh $DISTRO_SCRIPT $DISTRO
2648 fi
2650 # Execute the custom_rules() found in receipt.
2651 if [ -s "$TOP_DIR/receipt" ]; then
2652 if grep -q ^custom_rules "$TOP_DIR/receipt"; then
2653 echo -e "Executing: custom_rules()\n"
2654 . "$TOP_DIR/receipt"
2655 custom_rules || echo -e "\nERROR: custom_rules() failed\n"
2656 fi
2657 fi
2659 # Multi-rootfs
2660 if [ -s /etc/tazlito/rootfs.list ]; then
2662 FLAVOR_LIST="$(awk '{
2663 for (i = 2; i <= NF; i+=2)
2664 printf "%s ", $i;
2665 }' /etc/tazlito/rootfs.list)"
2667 [ -s "$ROOTCD/boot/isolinux/isolinux.msg" ] &&
2668 sed -i "s/ *//;s/)/), flavors $FLAVOR_LIST/" \
2669 "$ROOTCD/boot/isolinux/isolinux.msg" 2>/dev/null
2671 [ -f "$ROOTCD/boot/isolinux/ifmem.c32" -o \
2672 -f "$ROOTCD/boot/isolinux/c32box.c32" ] ||
2673 cp '/boot/isolinux/c32box.c32' "$ROOTCD/boot/isolinux" 2>/dev/null ||
2674 cp '/boot/isolinux/ifmem.c32' "$ROOTCD/boot/isolinux"
2676 n=0
2677 last=$ROOTFS
2678 while read flavor; do
2679 n=$(($n+1))
2680 mkdir ${ROOTFS}0$n
2681 export root="${ROOTFS}0$n"
2682 # initial tazpkg setup in empty rootfs
2683 tazpkg --root=$root >/dev/null 2>&1
2685 newline
2686 boldify "Building $flavor rootfs..."
2688 [ -s "$TOP_DIR/$flavor.flavor" ] &&
2689 cp "$TOP_DIR/$flavor.flavor" .
2691 if [ ! -s "$flavor.flavor" ]; then
2692 # We may have it in $FLAVORS_REPOSITORY
2693 if [ -d "$FLAVORS_REPOSITORY/$flavor" ]; then
2694 tazlito pack-flavor $flavor
2695 else
2696 download $flavor.flavor
2697 fi
2698 fi
2700 action 'Extracting %s and %s...' "$flavor.pkglist" "$flavor.rootfs"
2701 zcat $flavor.flavor | cpio -i --quiet $flavor.pkglist $flavor.rootfs
2702 cp $flavor.pkglist $DISTRO/list-packages0$n
2703 status
2705 strip_versions "$DISTRO/list-packages0$n"
2707 install_list_to_rootfs "$DISTRO/list-packages0$n" "${ROOTFS}0$n"
2709 cp -a ${ROOTFS}0$n/boot $ROOTCD
2710 rm -rf ${ROOTFS}0$n/boot
2712 cd $DISTRO
2713 if [ -s $flavor.rootfs ]; then
2714 _n 'Adding %s rootfs extra files...' "$flavor"
2715 zcat < $flavor.rootfs | ( cd ${ROOTFS}0$n ; cpio -idmu )
2716 fi
2718 action 'Moving %s to %s' "list-packages0$n" "rootfs0$n"
2719 mv "$DISTRO/list-packages0$n" "${ROOTFS}0$n/etc/tazlito/distro-packages.list"
2720 status
2722 rm -f $flavor.flavor install-list
2723 mergefs ${ROOTFS}0$n $last
2724 last=${ROOTFS}0$n
2725 done <<EOT
2726 $(awk '{ for (i = 4; i <= NF; i+=2) print $i; }' < /etc/tazlito/rootfs.list)
2727 EOT
2728 #'
2729 i=$(($n+1))
2730 while [ $n -gt 0 ]; do
2731 mv ${ROOTFS}0$n ${ROOTFS}$i
2732 _ 'Compressing %s (%s)...' "${ROOTFS}0$n" "$(du -hs ${ROOTFS}$i | awk '{ print $1 }')"
2733 gen_initramfs ${ROOTFS}$i
2734 n=$(($n-1))
2735 i=$(($i-1))
2736 export LZMA_HISTORY_BITS=26
2737 done
2738 mv $ROOTFS ${ROOTFS}$i
2739 gen_initramfs ${ROOTFS}$i
2740 update_bootconfig "$ROOTCD/boot/isolinux" "$(cat /etc/tazlito/rootfs.list)"
2741 ROOTFS=${ROOTFS}1
2742 else
2743 # Initramfs and ISO image stuff.
2744 gen_initramfs $ROOTFS
2745 fi
2746 gen_livecd_isolinux
2747 distro_stats
2748 cleanup
2749 ;;
2752 clean-distro)
2753 # Remove old distro tree.
2755 check_root
2756 title 'Cleaning: %s' "$DISTRO"
2757 if [ -d "$DISTRO" ] ; then
2758 if [ -d "$ROOTFS" ] ; then
2759 action 'Removing the rootfs...'
2760 rm -f $DISTRO/$INITRAMFS
2761 rm -rf $ROOTFS
2762 status
2763 fi
2764 if [ -d "$ROOTCD" ] ; then
2765 action 'Removing the rootcd...'
2766 rm -rf $ROOTCD
2767 status
2768 fi
2769 action 'Removing eventual ISO image...'
2770 rm -f $DISTRO/$ISO_NAME.iso
2771 rm -f $DISTRO/$ISO_NAME.md5
2772 status
2773 fi
2774 footer
2775 ;;
2778 check-distro)
2779 # Check for a few LiveCD needed files not installed by packages.
2781 # TODO: Remove this function.
2782 # First two files are maintained by tazpkg while it runs on rootfs,
2783 # while last one file should be maintained by tazlito itself.
2784 check_rootfs
2785 title 'Checking distro: %s' "$ROOTFS"
2786 # SliTaz release info.
2787 rel='/etc/slitaz-release'
2788 if [ ! -f "$ROOTFS$rel" ]; then
2789 _ 'Missing release info: %s' "$rel"
2790 else
2791 action 'Release : %s' "$(cat $ROOTFS$rel)"
2792 status
2793 fi
2794 # Tazpkg mirror.
2795 if [ ! -f "$ROOTFS$LOCALSTATE/mirror" ]; then
2796 action 'Mirror URL : Missing %s' "$LOCALSTATE/mirror"
2797 todomsg
2798 else
2799 action 'Mirror configuration exists...'
2800 status
2801 fi
2802 # Isolinux msg
2803 if grep -q "cooking-XXXXXXXX" /$ROOTCD/boot/isolinux/isolinux.*g; then
2804 action 'Isolinux msg : Missing cooking date XXXXXXXX (ex %s)' "$(date +%Y%m%d)"
2805 todomsg
2806 else
2807 action 'Isolinux message seems good...'
2808 status
2809 fi
2810 footer
2811 ;;
2814 writeiso)
2815 # Writefs to ISO image including /home unlike gen-distro we don't use
2816 # packages to generate a rootfs, we build a compressed rootfs with all
2817 # the current filesystem similar to 'tazusb writefs'.
2819 DISTRO='/home/slitaz/distro'
2820 ROOTCD="$DISTRO/rootcd"
2821 COMPRESSION="${2:-none}"
2822 ISO_NAME="${3:-slitaz}"
2823 check_root
2824 # Start info
2825 title 'Write filesystem to ISO'
2826 longline "The command writeiso will write the current filesystem into a \
2827 suitable cpio archive (rootfs.gz) and generate a bootable ISO image (slitaz.iso)."
2828 newline
2829 emsg "<b>Archive compression:</b> <c 36>$COMPRESSION</c>"
2831 [ "$COMPRESSION" == 'gzip' ] && colorize 31 "gzip-compressed rootfs unsupported and may fail to boot"
2832 # Save some space
2833 rm -rf /var/cache/tazpkg/*
2834 rm -f /var/lib/tazpkg/*.bak
2835 rm -rf $DISTRO
2837 # Optionally remove sound card selection and screen resolution.
2838 if [ -z $LaunchedByTazpanel ]; then
2839 anser=$(yesorno 'Do you wish to remove the sound card and screen configs?' 'n')
2840 case $anser in
2841 y)
2842 action 'Removing current sound card and screen configurations...'
2843 rm -f /var/lib/sound-card-driver
2844 rm -f /var/lib/alsa/asound.state
2845 rm -f /etc/X11/xorg.conf ;;
2846 *)
2847 action 'Keeping current sound card and screen configurations...' ;;
2848 esac
2849 status
2850 newline
2852 # Optionally remove i18n settings
2853 anser=$(yesorno 'Do you wish to remove locale/keymap settings?' 'n')
2854 case $anser in
2855 y)
2856 action 'Removing current locale/keymap settings...'
2857 newline > /etc/locale.conf
2858 newline > /etc/keymap.conf ;;
2859 *)
2860 action 'Keeping current locale/keymap settings...' ;;
2861 esac
2862 status
2863 fi
2865 # Clean-up files by default
2866 newline > /etc/udev/rules.d/70-persistent-net.rules
2867 newline > /etc/udev/rules.d/70-persistant-cd.rules
2869 # Create list of files including default user files since it is defined in /etc/passwd
2870 # and some new users might have been added.
2871 cd /
2872 echo 'init' > /tmp/list
2873 for dir in bin etc sbin var dev lib root usr home opt; do
2874 [ -d $dir ] && find $dir
2875 done >> /tmp/list
2877 for dir in proc sys tmp mnt media media/cdrom media/flash media/usbdisk run run/udev; do
2878 [ -d $dir ] && echo $dir
2879 done >> /tmp/list
2881 sed '/var\/run\/.*pid$/d ; /var\/run\/utmp/d ; /.*\/.gvfs/d ; /home\/.*\/.cache\/.*/d' -i /tmp/list
2883 #if [ ! $(find /var/log/slitaz/tazpkg.log -size +4k) = "" ]; then
2884 # sed -i "/var\/log\/slitaz\/tazpkg.log/d" /tmp/list
2885 #fi
2886 mv -f /var/log/wtmp /tmp/tazlito-wtmp
2887 touch /var/log/wtmp
2889 for removelog in auth boot messages dmesg daemon slim .*old Xorg tazpanel cups; do
2890 sed -i "/var\/log\/$removelog/d" /tmp/list
2891 done
2893 # Generate initramfs with specified compression and display rootfs
2894 # size in realtime.
2895 rm -f /tmp/.write-iso* /tmp/rootfs 2>/dev/null
2897 write_initramfs &
2898 sleep 2
2899 cd - > /dev/null
2900 echo -en "\nFilesystem size:"
2901 while [ ! -f /tmp/rootfs ]; do
2902 sleep 1
2903 echo -en "\\033[18G$(du -sh /$INITRAMFS | awk '{print $1}') "
2904 done
2905 mv -f /tmp/tazlito-wtmp /var/log/wtmp
2906 echo -e "\n"
2907 rm -f /tmp/rootfs
2909 # Move freshly generated rootfs to the cdrom.
2910 mkdir -p $ROOTCD/boot
2911 mv -f /$INITRAMFS $ROOTCD/boot
2912 _ 'Located in: %s' "$ROOTCD/boot/$INITRAMFS"
2914 # Now we need the kernel and isolinux files.
2915 copy_from_cd() {
2916 cp /media/cdrom/boot/bzImage* $ROOTCD/boot
2917 cp -a /media/cdrom/boot/isolinux $ROOTCD/boot
2918 unmeta_boot $ROOTCD
2919 umount /media/cdrom
2922 if mount /dev/cdrom /media/cdrom 2>/dev/null; then
2923 copy_from_cd;
2924 elif mount | grep /media/cdrom; then
2925 copy_from_cd;
2926 #elif [ -f "$bootloader" -a -f /boot/vmlinuz*slitaz* ]; then
2927 # [ -f /boot/*slitaz ] && cp /boot/vmlinuz*slitaz $ROOTCD/boot/bzImage
2928 # [ -f /boot/*slitaz64 ] && cp /boot/vmlinuz*slitaz64 $ROOTCD/boot/bzImage64
2929 else
2930 touch /tmp/.write-iso-error
2931 longline "When SliTaz is running in RAM the kernel and bootloader \
2932 files are kept on the CD-ROM. `boldify ' Please insert a Live CD or run:
2933 # mount -o loop slitaz.iso /media/cdrom ' ` to let Tazlito copy the files."
2934 echo -en "----\nENTER to continue..."; read i
2935 [ ! -d /media/cdrom/boot/isolinux ] && exit 1
2936 copy_from_cd
2937 fi
2939 # Generate the iso image.
2940 touch /tmp/.write-iso
2941 newline
2942 cd $DISTRO
2943 create_iso $ISO_NAME.iso $ROOTCD
2944 action 'Creating the ISO md5sum...'
2945 md5sum $ISO_NAME.iso > $ISO_NAME.md5
2946 status
2948 footer "ISO image: $(du -sh $DISTRO/$ISO_NAME.iso)"
2949 rm -f /tmp/.write-iso
2951 if [ -z $LaunchedByTazpanel ]; then
2952 anser=$(yesorno 'Burn ISO to CD-ROM?' 'n')
2953 case $anser in
2954 y)
2955 umount /dev/cdrom 2>/dev/null
2956 eject
2957 echo -n "Please insert a blank CD-ROM and press ENTER..."
2958 read i && sleep 2
2959 tazlito burn-iso $DISTRO/$ISO_NAME.iso
2960 echo -en "----\nENTER to continue..."; read i ;;
2961 *)
2962 exit 0 ;;
2963 esac
2964 fi
2965 ;;
2968 burn-iso)
2969 # Guess CD-ROM device, ask user and burn the ISO.
2971 check_root
2972 DRIVE_NAME=$(grep "drive name" /proc/sys/dev/cdrom/info | cut -f3)
2973 DRIVE_SPEED=$(grep "drive speed" /proc/sys/dev/cdrom/info | cut -f3)
2974 # We can specify an alternative ISO from the cmdline.
2975 iso="${2:-$DISTRO/$ISO_NAME.iso}"
2976 [ ! -f "$iso" ] && die "Unable to find ISO: $iso"
2978 title 'Tazlito burn ISO'
2979 echo "CD-ROM device : /dev/$DRIVE_NAME"
2980 echo "Drive speed : $DRIVE_SPEED"
2981 echo "ISO image : $iso"
2982 footer
2984 case $(yesorno 'Burn ISO image?' 'n') in
2985 y)
2986 title 'Starting Wodim to burn the ISO...'
2987 sleep 2
2988 wodim speed=$DRIVE_SPEED dev=/dev/$DRIVE_NAME $iso
2989 footer 'ISO image is burned to CD-ROM.'
2990 ;;
2991 *)
2992 die 'Exiting. No ISO burned.'
2993 ;;
2994 esac
2995 ;;
2998 merge)
2999 # Merge multiple rootfs into one iso.
3001 if [ -z "$2" ]; then
3002 cat <<EOT
3003 Usage: tazlito merge size1 iso size2 rootfs2 [sizeN rootfsN]...
3005 Merge multiple rootfs into one ISO. Rootfs are like russian dolls
3006 i.e: rootfsN is a subset of rootfsN-1
3007 rootfs1 is found in ISO, sizeN is the RAM size needed to launch rootfsN.
3008 The boot loader will select the rootfs according to the RAM size detected.
3010 Example:
3011 $ tazlito merge 160M slitaz-core.iso 96M rootfs-justx.gz 32M rootfs-base.gz
3013 Will start slitaz-core with 160M+ RAM, slitaz-justX with 96M-160M RAM,
3014 slitaz-base with 32M-96M RAM and display an error message if RAM < 32M.
3016 EOT
3017 exit 2
3018 fi
3020 shift # skip merge
3021 append="$1 slitaz1"
3022 shift # skip size1
3023 mkdir -p $TMP_DIR/mnt $TMP_DIR/rootfs1
3025 ISO=$1.merged
3027 # Extract filesystems
3028 action 'Mounting %s' "$1"
3029 mount -o loop,ro $1 $TMP_DIR/mnt 2> /dev/null
3030 status || cleanup_merge
3032 cp -a $TMP_DIR/mnt $TMP_DIR/iso
3033 make_bzImage_hardlink $TMP_DIR/iso/boot
3034 umount -d $TMP_DIR/mnt
3035 if [ -f $TMP_DIR/iso/boot/rootfs1.gz ]; then
3036 _ '%s is already a merged iso. Aborting.' "$1"
3037 cleanup_merge
3038 fi
3039 if [ ! -f $TMP_DIR/iso/boot/isolinux/ifmem.c32 -a
3040 ! -f $TMP_DIR/iso/boot/isolinux/c32box.c32 ]; then
3041 if [ ! -f /boot/isolinux/ifmem.c32 -a
3042 ! -f /boot/isolinux/c32box.c32 ]; then
3043 cat <<EOT
3044 No file /boot/isolinux/ifmem.c32
3045 Please install syslinux package !
3046 EOT
3047 rm -rf $TMP_DIR
3048 exit 1
3049 fi
3050 cp /boot/isolinux/c32box.c32 $TMP_DIR/iso/boot/isolinux 2> /dev/null ||
3051 cp /boot/isolinux/ifmem.c32 $TMP_DIR/iso/boot/isolinux
3052 fi
3054 action 'Extracting %s' 'iso/rootfs.gz'
3055 extract_rootfs $TMP_DIR/iso/boot/rootfs.gz $TMP_DIR/rootfs1 &&
3056 [ -d $TMP_DIR/rootfs1/etc ]
3057 status || cleanup_merge
3059 n=1
3060 while [ -n "$2" ]; do
3061 shift # skip rootfs N-1
3062 p=$n
3063 n=$(($n + 1))
3064 append="$append $1 slitaz$n"
3065 shift # skip size N
3066 mkdir -p $TMP_DIR/rootfs$n
3068 action 'Extracting %s' "$1"
3069 extract_rootfs $1 $TMP_DIR/rootfs$n &&
3070 [ -d "$TMP_DIR/rootfs$n/etc" ]
3071 status || cleanup_merge
3073 mergefs $TMP_DIR/rootfs$n $TMP_DIR/rootfs$p
3074 action 'Creating %s' "rootfs$p.gz"
3075 pack_rootfs "$TMP_DIR/rootfs$p" "$TMP_DIR/iso/boot/rootfs$p.gz"
3076 status
3077 done
3078 action 'Creating %s' "rootfs$n.gz"
3079 pack_rootfs "$TMP_DIR/rootfs$n" "$TMP_DIR/iso/boot/rootfs$n.gz"
3080 status
3081 rm -f $TMP_DIR/iso/boot/rootfs.gz
3082 update_bootconfig $TMP_DIR/iso/boot/isolinux "$append"
3083 create_iso $ISO $TMP_DIR/iso
3084 rm -rf $TMP_DIR
3085 ;;
3088 repack)
3089 # Repack an iso with maximum lzma compression ratio.
3091 ISO=$2
3092 mkdir -p $TMP_DIR/mnt
3094 # Extract filesystems
3095 action 'Mounting %s' "$ISO"
3096 mount -o loop,ro $ISO $TMP_DIR/mnt 2>/dev/null
3097 status || cleanup_merge
3099 cp -a $TMP_DIR/mnt $TMP_DIR/iso
3100 umount -d $TMP_DIR/mnt
3102 for i in $TMP_DIR/iso/boot/rootfs* ; do
3103 action 'Repacking %s' "$(basename $i)"
3104 uncompress $i 2>/dev/null > $TMP_DIR/rootfs
3105 lzma e $TMP_DIR/rootfs $i $(lzma_switches $TMP_DIR/rootfs)
3106 align_to_32bits $i
3107 status
3108 done
3110 create_iso $ISO $TMP_DIR/iso
3111 rm -rf $TMP_DIR
3112 ;;
3115 build-loram)
3116 # Build a Live CD for low RAM systems.
3118 ISO="$2"
3119 OUTPUT="$3"
3120 [ -z "$3" ] && \
3121 die "Usage: tazlito build-loram <input>.iso <output>.iso [cdrom|smallcdrom|http|ram]"
3122 mkdir -p "$TMP_DIR/iso"
3123 mount -o loop,ro -t iso9660 "$ISO" "$TMP_DIR/iso"
3124 loopdev=$( (losetup -a 2>/dev/null || losetup) | sed "/$(echo $ISO | sed 's|/|\\/|g')$/!d;s/:.*//;q")
3125 if ! check_iso_for_loram ; then
3126 umount -d "$TMP_DIR/iso"
3127 die "$ISO is not a valid SliTaz live CD. Abort."
3128 fi
3129 case "$4" in
3130 cdrom) build_loram_cdrom ;;
3131 http) build_loram_http ;;
3132 *) build_loram_ram "$5" ;;
3133 esac
3134 umount $TMP_DIR/iso # no -d: needs /proc
3135 losetup -d $loopdev
3136 rm -rf $TMP_DIR
3137 ;;
3140 emu-iso)
3141 # Emulate an ISO image with Qemu.
3142 iso="${2:-$DISTRO/$ISO_NAME.iso}"
3143 [ -f "$iso" ] || die "Unable to find ISO file '$iso'."
3144 [ -x '/usr/bin/qemu' ] || die "Unable to find Qemu binary. Please install package 'qemu'."
3145 echo -e "\nStarting Qemu emulator:\n"
3146 echo -e "qemu $QEMU_OPTS $iso\n"
3147 qemu $QEMU_OPTS $iso
3148 ;;
3151 deduplicate)
3152 # Deduplicate files in a tree
3153 shift
3154 deduplicate "$@"
3155 ;;
3158 usage|*)
3159 # Print usage also for all unknown commands.
3160 usage
3161 ;;
3162 esac
3164 exit 0