tazlito view tazlito @ rev 508

Fix cleanup_efi_boot
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Jun 03 13:08:22 2018 +0200 (2018-06-03)
parents 035c08dd4580
children d585f8404493
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-2018 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'
21 alias stat='busybox stat'
22 alias awk='busybox awk'
24 # Tazlito configuration variables to be shorter
25 # and to use words rather than numbers.
26 COMMAND="$1"
27 LIST_NAME="$2"
28 TMP_DIR="/tmp/tazlito-$$-$RANDOM"
29 TMP_MNT="/media/tazlito-$$-$RANDOM"
30 TOP_DIR="$(pwd)"
31 INITRAMFS='rootfs.gz'
32 LOCALSTATE='/var/lib/tazpkg'
33 INSTALLED="$LOCALSTATE/installed"
34 CACHE_DIR='/var/cache/tazpkg'
35 MIRROR="$LOCALSTATE/mirror"
36 DEFAULT_MIRROR="http://mirror1.slitaz.org/packages/$(cat /etc/slitaz-release)/"
38 log='/var/log/tazlito.log'
39 if [ $(id -u) -eq 0 ]; then
40 newline > $log
41 fi
44 cleanup() {
45 if [ -d "$TMP_MNT" ]; then
46 umount $TMP_MNT
47 rmdir $TMP_MNT
48 rm -f /boot
49 fi
50 [ -d "$tmp_dir" ] && rm -r "$tmp_dir"
51 [ -d "$flv_dir" ] && rm -r "$flv_dir"
52 }
55 # Report error and finish work
57 die() {
58 emsg "<n>$(longline "$@")<n> " >&2
59 cleanup
60 exit 1
61 }
64 # Run Tazlito module
65 module() {
66 local mod="$1"; shift
67 /usr/libexec/tazlito/$mod $@
68 }
72 # Try to include config file, continue if command is gen-config or exit.
73 # The main config used by default is in /etc/tazlito.
74 # Specific distro config file can be put in a distro tree.
75 for i in /etc/tazlito "$TOP_DIR"; do
76 [ -f "$i/tazlito.conf" ] && CONFIG_FILE="$i/tazlito.conf"
77 done
79 [ -z "$CONFIG_FILE" -a "$COMMAND" != 'gen-config' ] && \
80 die 'Unable to find any configuration file.' \
81 'Please read the docs or run `tazlito gen-config` to get an empty config file.'
83 . $CONFIG_FILE
85 # While Tazpkg is not used the default mirror URL file does not exist
86 # and user can't recharge the list of flavors.
87 [ $(id -u) -eq 0 -a ! -f "$MIRROR" ] && echo "$DEFAULT_MIRROR" > $MIRROR
89 # Set the rootfs and rootcd path with $DISTRO
90 # configuration variable.
91 ROOTFS="$DISTRO/rootfs"
92 ROOTCD="$DISTRO/rootcd"
97 #####################
98 # Tazlito functions #
99 #####################
102 # Print the usage.
104 usage () {
105 [ $(basename $0) == 'tazlito' ] && cat <<EOT
107 SliTaz Live Tool - Version: $(colorize 34 "$VERSION")
109 $(boldify "Usage:") tazlito [command] [list|iso|flavor|compression] [dir|iso]
111 $(boldify "Commands:")
112 EOT
113 optlist "\
114 usage Print this short usage.
115 stats View Tazlito and distro configuration statistics.
116 list-addfiles Simple list of additional files in the rootfs.
117 gen-config Generate a new configuration file for a distro.
118 configure Configure the main config file or a specific tazlito.conf.
119 gen-iso Generate a new ISO from a distro tree.
120 gen-initiso Generate a new initramfs and ISO from the distro tree.
121 list-flavors List all flavors available on the mirror.
122 gen-flavor Generate a new Live CD description.
123 gen-liveflavor Generate a Live CD description from current system.
124 show-flavor Show Live CD description.
125 get-flavor Get a flavor's list of packages (--noup to skip update).
126 upgrade-flavor Update package list to the latest available versions.
127 extract-flavor Extract a *.flavor file into $FLAVORS_REPOSITORY.
128 pack-flavor Pack (and update) a flavor from $FLAVORS_REPOSITORY.
129 iso2flavor Create a flavor file from a SliTaz ISO image.
130 extract-distro Extract an ISO to a directory and rebuild Live CD tree.
131 gen-distro Generate a Live distro and ISO from a list of packages.
132 clean-distro Remove all files generated by gen-distro.
133 check-distro Help to check if distro is ready to release.
134 writeiso Use running system to generate a bootable ISO (with /home).
135 merge Merge multiple rootfs into one ISO.
136 deduplicate Deduplicate files in a tree.
137 repack Recompress rootfs into ISO with maximum ratio.
138 build-loram Generate a Live CD for low-RAM systems.
139 emu-iso Emulate an ISO image with QEMU.
140 burn-iso Burn ISO image to a CD-ROM using Wodim.
141 "
142 }
145 yesorno() {
146 local answer
147 echo -n "$1 (y=yes, n=no) [$2] " >&2
148 case "$DEFAULT_ANSWER" in
149 Y|y) answer="y";;
150 N|n) answer="n";;
151 *)
152 read -t 30 answer
153 [ -z "$answer" ] && answer="$2"
154 [ "$answer" != 'y' -a "$answer" != 'n' ] && answer="$2"
155 ;;
156 esac
157 echo "$answer"
158 }
161 field() {
162 grep "^$1" "$2" | \
163 case "$1" in
164 Desc*) sed 's|^.*: *||';;
165 *) sed 's/.*: \([0-9KMG\.]*\).*/\1/';;
166 esac
167 }
170 todomsg() {
171 echo -e "\\033[70G[ \\033[1;31mTODO\\033[0;39m ]"
172 }
175 # Download a file from this mirror
177 download_from() {
178 local i mirrors="$1"
179 shift
180 for i in $mirrors; do
181 case "$i" in
182 http://*|ftp://*|https://*)
183 wget -c $i$@ && break;;
184 *)
185 cp $i/$1 . && break;;
186 esac
187 done
188 }
191 # Download a file trying all mirrors
193 download() {
194 local i
195 for i in $(cat $MIRROR $LOCALSTATE/undigest/*/mirror 2>/dev/null); do
196 download_from "$i" "$@" && break
197 done
198 }
201 # Execute hooks provided by some packages
203 genisohooks() {
204 local here="$(pwd)"
205 for i in $(ls $ROOTFS/etc/tazlito/*.$1 2>/dev/null); do
206 cd $ROOTFS
207 . $i $ROOTCD
208 done
209 cd "$here"
210 }
213 # Echo the package name if the tazpkg is already installed
215 installed_package_name() {
216 local tazpkg="$1" package VERSION EXTRAVERSION
218 # Try to find package name and version to be able
219 # to repack it from installation
220 # A dash (-) can exist in name *and* in version
221 package=${tazpkg%-*}
222 i=$package
223 while true; do
224 unset VERSION EXTRAVERSION
225 eval $(grep -s ^VERSION= $INSTALLED/$i/receipt)
226 eval $(grep -s ^EXTRAVERSION= $INSTALLED/$i/receipt)
227 if [ "$i-$VERSION$EXTRAVERSION" == "$tazpkg" ]; then
228 echo $i
229 break
230 fi
231 case "$i" in
232 *-*);;
233 *) break;;
234 esac
235 i=${i%-*}
236 done
237 }
240 # Check for the rootfs tree.
242 check_rootfs() {
243 [ -d "$ROOTFS/etc" ] || die 'Unable to find a distro rootfs...'
244 }
247 # Check for the boot dir into the root CD tree.
249 verify_rootcd() {
250 [ -d "$ROOTCD/boot" ] || die 'Unable to find the rootcd boot directory...'
251 }
253 set32() {
254 for i in $(seq 0 8 $((${4:-32}-8))); do
255 printf '\\\\x%02X' $((($2 >> $i) & 255))
256 done | xargs echo -en | dd bs=1 conv=notrunc of=$3 seek=$1 2>/dev/null
257 }
259 set64() {
260 for i in $(seq 0 8 24 ; seq 24 -8 0); do
261 printf '\\\\x%02X' $((($2 >> $i) & 255))
262 done | xargs echo -en | dd bs=1 conv=notrunc of=$3 seek=$1 2>/dev/null
263 }
266 first_block() {
267 busybox stat -m "$1" | sed q
268 }
272 # Force size and location in the 2nd eltorito boot file (/boot/isolinux/efi.img)
274 fix_efi_boot_img_size() {
275 local n=$3
276 [ $n -gt 65535 ] && n=65535
277 set32 $((0x66+2048*$(first_block $2/boot/isolinux/boot.cat))) $n $1 16
278 set32 $((0x1C+2048*$4)) $(($4*4)) $1
279 }
282 # Force the size for the /boot/isolinux/efi.img file
284 fix_efi_img_size() {
285 local e=$((0x809C))
286 for i in BOOT ISOLINUX EFI.IMG ; do
287 local sz=$(get $(($e+10)) "$2" 4)
288 e=$(($(get $(($e+2)) "$2" 4) * 2048))
289 while [ $sz -gt 0 ]; do
290 local len=$(get $e "$2")
291 [ "$(dd if="$2" bs=1 skip=$(($e+33)) count=${#i} \
292 2>/dev/null)" == "$i" ] && continue 2
293 [ $len -eq 0 ] && break
294 sz=$(($sz-$len))
295 e=$(($e+$len))
296 done
297 return # not found
298 done
299 set64 $(($e+10)) $1 "$2"
300 }
303 # create /boot/isolinux/efi.img to share EFI files with the iso image
305 fixup_uefi_part() {
306 [ -s $2/boot/isolinux/efi.img ] || return
307 local n=$(get 19 "$2/boot/isolinux/efi.img")
308 [ $n -eq 0 ] && n=$(get 32 "$2/boot/isolinux/efi.img" 4)
309 efiblock=$(first_block "$2/boot/isolinux/efi.img")
310 fix_efi_img_size $(($n*512)) $1
311 fix_efi_boot_img_size $1 $2 $n $efiblock
313 # Build file list tree
314 resv=$(get 14 "$2/boot/isolinux/efi.img")
315 if [ $(get 57 "$2/boot/isolinux/efi.img" 1) -ne 49 ]; then
316 skiphead=5
317 fatsz=$(get 36 "$2/boot/isolinux/efi.img" 4)
318 basecluster=$((($resv+2*$fatsz)/4+$efiblock-2))
319 dd if=$1 bs=512 skip=$(($efiblock*4)) count=3 \
320 of=$1 seek=$(($efiblock*4+3)) conv=notrunc
321 else
322 skiphead=4
323 fatsz=$(get 22 "$2/boot/isolinux/efi.img")
324 basecluster=$((($resv+2*$fatsz)/4+$efiblock-1))
325 fi 2> /dev/null
326 hd "$2/boot/isolinux/efi.img" | awk 'BEGIN { skiphead='$skiphead' }
327 {
328 if (skiphead!=0) {
329 if ($1=="*") skiphead--
330 next
331 }
332 if (skipdot!=0) {
333 if (skipdot==2) up[cur]=$13 $12
334 else cur=$13 $12
335 skipdot=0
336 next
337 }
338 if (($2=="2e" && $3=="20") || ($2=="2e" && $3=="2e" && $4=="20")) {
339 if ($3=="2e") skipdot=2
340 else skipdot=1
341 next
342 }
343 if (gotname!=0) {
344 path=""
345 for (i=cur;i!="" && i!="0000";i=up[i]) path=dir[i] path
346 if (gotname==2) dir[$13 $12]=name
347 else print $1 " " $13 $12 " " path name
348 gotname=0
349 name=""
350 next
351 }
352 if (s!="") {
353 if (eos==0)
354 for (i=2;i<18;i+=2) {
355 if (i==12) i+=2
356 if ($i=="00") break
357 s=s substr($0,i+60,1)
358 }
359 name=s name
360 s=""
361 eos=0
362 next
363 }
364 if ($13=="0f") {
365 s=""
366 for (i=3;i<16;i+=2) {
367 if (i==13) i+=3
368 if ($i=="00") { eos=1; break }
369 s=s substr($0,i+60,1)
370 }
371 next
372 }
373 if ($13=="10") {
374 name=name "/"
375 gotname=2
376 next
377 }
378 if ($13=="20") {
379 gotname=1
380 next
381 }
382 }
383 ' | ( while read offset cluster file; do
384 cluster=$(($(first_block "$2/$file")-$basecluster))
385 set32 $(($efiblock*2048+0x$offset+10)) $cluster "$1" 16
386 set32 $(($efiblock*2048+0x$offset+4)) $(($cluster>>16)) "$1" 16
387 echo "$cluster $((($(stat -c %s "$2/$file")+2047)/2048)) $file"
388 done
390 # Update fat12 or fat16
391 get 57 "$2/boot/isolinux/efi.img"
392 dd if="$2/boot/isolinux/efi.img" bs=512 count=$fatsz skip=$resv 2> /dev/null | \
393 od -An -t u1 -w1 -v
394 ) | awk '
395 {
396 if (state==0) {
397 if ($2=="") {
398 if ($1==12849) fat=12
399 else if ($1==13873) fat=16
400 else fat=32
401 state++
402 }
403 else {
404 for (i=1;i<$2;i++) c[$1+i]=$1+i
405 c[$1+$2]=268435455
406 }
407 next
408 }
409 if (state==1) {
410 prev=$1
411 state++
412 next
413 }
414 if (state==2) {
415 if (fat==12) {
416 n=($1%16)*256+prev
417 if (n!=0) c[pos+1]=n
418 pos++
419 prev=int($1/16)
420 state++
421 next
422 }
423 n=$1*256+prev
424 if (fat==32) {
425 prev=n
426 state=13
427 next
428 }
429 }
430 else if (state==3) {
431 n=$1*16+prev
432 }
433 else if (state==13) {
434 prev=$1*65536+prev
435 state++
436 next
437 }
438 else n=$1*16777216+prev
439 if (n!=0) c[pos+1]=n
440 pos++
441 state=1
442 }
443 END {
444 for (i=1;i<=pos;i+=2) {
445 if (c[i]=="") c[i]=0
446 if (c[i+1]=="") c[i+1]=0
447 if (fat==12) printf "0 %02X %1X%1X %02X |\n",c[i]%256,c[i+1]%16,(c[i]/256)%16,(c[i+1]/16)%256
448 else if (fat==16) printf "0 %02X %02X %02X %02X |\n",c[i]%256,(c[i]/256)%256,c[i+1]%256,(c[i+1]/256)%256
449 else {
450 printf "0 %02X %02X %02X %02X |\n",c[i]%256,(c[i]/256)%256,(c[i]/65536)%256,(c[i]/16777216)%256
451 printf "0 %02X %02X %02X %02X |\n",c[i+1]%256,(c[i+1]/256)%256,(c[i+1]/65536)%256,(c[i+1]/16777216)%256
452 }
453 }
454 }' | hexdump -R | dd of="$1" seek=$((4*$efiblock+$fatsz+$resv)) \
455 conv=notrunc bs=512 > /dev/null 2>&1
456 dd if="$1" of="$1" conv=notrunc bs=512 skip=$((4*$efiblock+$fatsz+$resv)) \
457 count=$fatsz seek=$((4*$efiblock+$resv)) > /dev/null 2>&1
459 # Cleanup cache
460 umount $2
461 mount -o loop,ro $1 $2
462 }
465 # allocate efi.img stub to share EFI files in the EFI boot partition
467 alloc_uefi_part() {
468 local basedir=$(dirname "$1")/..
469 local fclust=$({
470 [ -d $basedir/efi ] &&
471 find $basedir/efi -type f -exec stat -c "%s %n" {} \;
472 while [ -s "$1" ]; do
473 local efifile
474 case "$1" in
475 *taz) efifile=bootia32.efi ;;
476 *taz64) efifile=bootx64.efi ;;
477 esac
478 if [ ! -s $basedir/efi/boot/$efifile ] &&
479 [ $(get $((0x82)) "$1") == $((0x4550)) ]; then
480 mkdir -p $basedir/efi/boot 2> /dev/null
481 ln "$1" "$basedir/efi/boot/$efifile"
482 stat -c "%s %n" "$1"
483 for i in $basedir/boot/rootfs* ; do
484 ln "$i" $basedir/efi/boot/ &&
485 stat -c "%s %n" "$i"
486 done 2> /dev/null
487 sed 's|/|\\|g' > $basedir/efi/boot/linux.cmdline <<EOT
488 rw root=0x100 autologin\
489 $( ( cd $basedir/efi/boot ; ls -r rootfs*gz ) | while read f ; do \
490 echo -n " initrd=/EFI/BOOT/$f";done)
491 EOT
492 fi
493 shift
494 done; } | sort | uniq | awk '{ n+=int(($1+2047)/2048) } END { print n+1 }')
495 [ ${fclust:-0} -eq 0 ] && return
496 local dclust=$( (cd $basedir; find efi -type d 2>/dev/null) | awk '
497 BEGIN {
498 FS="/"
499 }
500 NF > 1 {
501 d[NF $NF]+=2
502 d[NF-1 $(NF-1)]+=($NF+25)/13
503 }
504 END {
505 for (i in d)
506 n+=int((d[i]+63)/64)
507 print n
508 }')
509 local clusters=$(($fclust+$dclust))
510 if [ $clusters -lt 4068 ]; then
511 fsect=$(((($clusters+2)*3+1023)/1024))
512 ftype="31 32"
513 fhead="F8 FF FF"
514 rsect=$(( 1+ ((2*$fsect)-1)%4 ))
515 fsz="$(printf "%04X" $fsect | sed 's/\(..\)\(..\)/\2 \1/')"
516 rootsz=2
517 elif [ $clusters -lt 65525 ]; then
518 fsect=$((($clusters+2+255)/256))
519 ftype="31 36"
520 fhead="F8 FF FF FF"
521 rsect=$(( 1+ ((2*$fsect)-1)%4 ))
522 fsz="$(printf "%04X" $fsect | sed 's/\(..\)\(..\)/\2 \1/')"
523 rootsz=2
524 else
525 fsect=$((($clusters+2+127)/128))
526 ftype="33 32"
527 fhead="F8 FF FF 0F FF FF FF FF F8 FF FF 0F"
528 rsect=$(( 6+ ((2*$fsect)-6)%4 ))
529 fsz="$(printf "%08X" $fsect | sed 's/\(..\)\(..\)\(..\)\(..\)/\4 \3 \2 \1/')"
530 rootsz=1
531 fi
532 # reserved + fat*2 + root dir + dirs
533 count=$((($rsect + $fsect*2)/4 + $rootsz + $dclust ))
534 s=$((($count+$fclust)*4))
535 if [ $s -gt 65535 ]; then
536 size="00 00"
537 size32="$(printf "%02X %02X %02X %02X" $(($s%256)) \
538 $((($s>>8)%256)) $((($s>>16)%256)) $((($s>>24)%256)) )"
539 else
540 size="$(printf "%02X %02X" $(($s%256)) $((($s>>8)%256)) )"
541 size32="00 00 00 00"
542 fi
543 dd if=/dev/zero bs=512 of=$basedir/boot/isolinux/efi.img \
544 count=$s 2> /dev/null
546 # Create boot sector
547 if [ "$ftype" == "33 32" ]; then
548 hexdump -R <<EOT | dd of=$basedir/boot/isolinux/efi.img \
549 conv=notrunc
550 0 eb 58 90 53 6c 69 54 61 7a 00 00 00 02 04 $rsect 00 |
551 0 02 00 00 $size f8 00 00 20 00 40 00 00 00 00 00 |
552 0 $size32 $fsz 00 00 00 00 02 00 00 00 |
553 0 01 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 |
554 0 80 00 29 00 00 00 00 53 59 53 54 45 4d 00 00 00 |
555 0 00 00 46 41 54 $ftype 20 20 20 cd 18 cd 19 eb fa |
556 EOT
557 while read ofs data; do
558 echo "0 ${data//:/ } |" | hexdump -R | dd conv=notrunc \
559 bs=1 seek=$ofs of=$basedir/boot/isolinux/efi.img
560 done <<EOT
561 510 55:aa:52:52:61:41
562 996 72:72:41:61:ff:ff:ff:ff:02
563 1022 55:aa
564 EOT
565 else
566 echo -en '\x55\xAA' | dd of=$basedir/boot/isolinux/efi.img \
567 seek=510 bs=1 conv=notrunc
568 hexdump -R <<EOT | dd of=$basedir/boot/isolinux/efi.img \
569 conv=notrunc
570 0 eb 3c 90 53 6c 69 54 61 7a 00 00 00 02 04 $rsect 00 |
571 0 02 40 00 $size f8 $fsz 20 00 40 00 00 00 00 00 |
572 0 $size32 80 00 29 00 00 00 00 53 59 53 54 45 |
573 0 4d 20 20 20 20 20 46 41 54 $ftype 20 20 20 cd 18 |
574 0 cd 19 eb fa |
575 EOT
576 fi 2> /dev/null
578 # Create fats
579 echo "0 $fhead |" | hexdump -R | dd of=$basedir/boot/isolinux/efi.img \
580 seek=$(($rsect)) bs=512 conv=notrunc 2> /dev/null
581 echo "0 $fhead |" | hexdump -R | dd of=$basedir/boot/isolinux/efi.img \
582 seek=$(($rsect+$fsect)) bs=512 conv=notrunc 2> /dev/null
584 # Add label
585 echo "0 53 59 53 54 45 4d 20 20 20 20 20 08 |" | hexdump -R | \
586 dd of=$basedir/boot/isolinux/efi.img bs=512 conv=notrunc \
587 seek=$(($rsect+$fsect+$fsect)) 2> /dev/null
589 mkdir -p /tmp/mnt$$
590 mount -o loop $basedir/boot/isolinux/efi.img /tmp/mnt$$
591 ( cd $basedir; find efi -type d | cpio -o -H newc ) | \
592 ( cd /tmp/mnt$$ ; cpio -idmu 2> /dev/null )
593 sync
594 dd if=$basedir/boot/isolinux/efi.img of=/tmp/fat$$ \
595 skip=$rsect bs=512 count=$fsect 2> /dev/null
596 ( cd $basedir; find efi -type f | cpio -o -H newc ) | \
597 ( cd /tmp/mnt$$ ; cpio -idmu 2> /dev/null )
598 umount /tmp/mnt$$
599 cat /tmp/fat$$ /tmp/fat$$ | dd of=$basedir/boot/isolinux/efi.img \
600 seek=$rsect bs=512 conv=notrunc 2> /dev/null
601 rm /tmp/fat$$
602 rmdir /tmp/mnt$$
604 dd count=0 bs=2k of=$basedir/boot/isolinux/efi.img \
605 seek=$count 2> /dev/null
606 }
609 # isolinux.conf doesn't know the kernel version.
610 # We name the kernel image 'bzImage'.
611 # isolinux/syslinux first tries the '64' suffix with a 64bits cpu.
613 make_bzImage_hardlink() {
614 if [ -e ${1:-.}/vmlinuz*slitaz ]; then
615 rm -f ${1:-.}/bzImage 2>/dev/null
616 ln ${1:-.}/vmlinuz*slitaz ${1:-.}/bzImage
617 fi
618 if [ -e ${1:-.}/vmlinuz*slitaz64 ]; then
619 rm -f ${1:-.}/bzImage64 2> /dev/null
620 ln ${1:-.}/vmlinuz*slitaz64 ${1:-.}/bzImage64
621 fi
622 }
625 create_iso() {
626 cd $2
627 deduplicate
629 [ $(ls $2/boot/grub* 2> /dev/null | wc -l) -lt 2 ] && rm -rf $2/boot/grub*
630 make_bzImage_hardlink $2/boot
631 alloc_uefi_part $(ls -r $2/boot/vmlinuz*slitaz*)
633 cat > /tmp/cdsort$$ <<EOT
634 $PWD/boot/isolinux 100
635 $(ls -r $PWD/boot/rootfs* | awk 'BEGIN{n=149} { print $1 " " n-- }')
636 $(ls $PWD/boot/bzImage* | awk 'BEGIN{n=200} { print $1 " " n-- }')
637 $(find $PWD/efi -type f 2>/dev/null | sort -r | awk 'BEGIN{n=299} { print $1 " " n-- }')
638 $PWD/boot/isolinux/efi.img 300
639 $PWD/boot/isolinux/isolinux.bin 399
640 $PWD/boot/isolinux/boot.cat 400
641 EOT
643 action 'Computing md5...'
644 touch boot/isolinux/boot.cat
645 find * -type f ! -name md5sum ! -name 'vmlinuz-*' -exec md5sum {} \; | \
646 sort -k 2 > md5sum
647 status
649 cd - >/dev/null
650 title 'Generating ISO image'
652 _ 'Generating %s' "$1"
653 uefi="$(cd $2 ; ls boot/isolinux/efi.img 2> /dev/null)"
654 genisoimage -R -o $1 -hide-rr-moved -sort /tmp/cdsort$$ \
655 -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat \
656 -no-emul-boot -boot-load-size 4 -boot-info-table \
657 ${uefi:+-eltorito-alt-boot -efi-boot $uefi -no-emul-boot} \
658 -V "${VOLUM_NAME:-SliTaz}" -p "${PREPARED:-$(id -un)}" \
659 -volset "SliTaz $SLITAZ_VERSION" -input-charset utf-8 \
660 -A "tazlito $VERSION/$(genisoimage --version)" \
661 -copyright README -P "www.slitaz.org" -no-pad $2
662 rm -f /tmp/cdsort$$
663 dd if=/dev/zero bs=2k count=16 >> $1 2> /dev/null
665 mkdir /tmp/mnt$$
666 mount -o loop,ro $1 /tmp/mnt$$
667 fixup_uefi_part $1 /tmp/mnt$$
668 for i in boot/isolinux/isolinux.bin boot/isolinux/boot.cat \
669 ${uefi:+boot/isolinux/efi.img} ; do
670 sed -i "s|.* $i|$( cd /tmp/mnt$$ ; md5sum $i)|" $2/md5sum
671 done
672 dd if=$2/md5sum of=$1 conv=notrunc bs=2k \
673 seek=$(first_block /tmp/mnt$$/md5sum) 2> /dev/null
674 umount -d /tmp/mnt$$
675 rmdir /tmp/mnt$$
677 if [ -s '/etc/tazlito/info' ]; then
678 if [ $(stat -c %s /etc/tazlito/info) -lt $(( 31*1024 )) ]; then
679 action 'Storing ISO info...'
680 dd if=/etc/tazlito/info bs=1k seek=1 of=$1 conv=notrunc 2>/dev/null
681 status
682 fi
683 fi
685 if [ -x '/usr/bin/isohybrid' ]; then
686 action 'Creating hybrid ISO...'
687 isohybrid $1 $([ -n "$uefi" ] || echo -entry 2) 2>/dev/null
688 status
689 fi
691 if [ -x '/usr/bin/iso2exe' ]; then
692 echo 'Creating EXE header...'
693 /usr/bin/iso2exe $1 2>/dev/null
694 fi
695 }
698 # Generate a new ISO image using isolinux.
700 gen_livecd_isolinux() {
701 # Some packages may want to alter iso
702 genisohooks iso
703 [ ! -f "$ROOTCD/boot/isolinux/isolinux.bin" ] && die 'Unable to find isolinux binary.'
705 # Set date for boot msg.
706 if grep -q 'XXXXXXXX' "$ROOTCD/boot/isolinux/isolinux.cfg"; then
707 DATE=$(date +%Y%m%d)
708 action 'Setting build date to: %s...' "$DATE"
709 sed -i "s/XXXXXXXX/$DATE/" "$ROOTCD/boot/isolinux/isolinux.cfg"
710 status
711 fi
713 cd $DISTRO
714 create_iso $ISO_NAME.iso $ROOTCD
716 action 'Creating the ISO md5sum...'
717 md5sum $ISO_NAME.iso > $ISO_NAME.md5
718 status
720 separator
721 # Some packages may want to alter final iso
722 genisohooks final
723 }
726 lzma_history_bits() {
727 #
728 # This generates an ISO which boots with Qemu but gives
729 # rootfs errors in frugal or liveUSB mode.
730 #
731 # local n
732 # local sz
733 # n=20 # 1Mb
734 # sz=$(du -sk $1 | cut -f1)
735 # while [ $sz -gt 1024 -a $n -lt 28 ]; do
736 # n=$(( $n + 1 ))
737 # sz=$(( $sz / 2 ))
738 # done
739 # echo $n
740 echo ${LZMA_HISTORY_BITS:-24}
741 }
744 lzma_switches() {
745 local proc_num=$(grep -sc '^processor' /proc/cpuinfo)
746 echo "-d$(lzma_history_bits $1) -mt${proc_num:-1} -mc1000"
747 }
750 lzma_set_size() {
751 # Update size field for lzma'd file packed using -si switch
752 return # Need to fix kernel code?
754 local n i
755 n=$(unlzma < $1 | wc -c)
756 for i in $(seq 1 8); do
757 printf '\\\\x%02X' $(($n & 255))
758 n=$(($n >> 8))
759 done | xargs echo -en | dd of=$1 conv=notrunc bs=1 seek=5 2>/dev/null
760 }
763 align_to_32bits() {
764 local size=$(stat -c %s ${1:-/dev/null})
765 [ $((${size:-0} & 3)) -ne 0 ] &&
766 dd if=/dev/zero bs=1 count=$((4 - ($size & 3))) >> $1 2>/dev/null
767 }
770 dogzip() {
771 gzip -9 > $1
772 [ -x /usr/bin/advdef ] && advdef -qz4 $1
773 }
776 # Pack rootfs
778 pack_rootfs() {
779 ( cd $1; find . -print | cpio -o -H newc ) | \
780 case "$COMPRESSION" in
781 none)
782 _ 'Creating %s without compression...' 'initramfs'
783 cat > $2
784 ;;
785 gzip)
786 _ 'Creating %s with gzip compression...' 'initramfs'
787 dogzip $2
788 ;;
789 *)
790 _ 'Creating %s with lzma compression...' 'initramfs'
791 lzma e -si -so $(lzma_switches $1) > $2
792 lzma_set_size $2
793 ;;
794 esac
795 align_to_32bits $2
796 echo 1 > /tmp/rootfs
797 }
800 # Compression functions for writeiso.
802 write_initramfs() {
803 case "$COMPRESSION" in
804 lzma)
805 _n 'Creating %s with lzma compression...' "$INITRAMFS"
806 cpio -o -H newc | lzma e -si -so $(lzma_switches) > "/$INITRAMFS"
807 align='y'
808 lzma_set_size "/$INITRAMFS"
809 ;;
810 gzip)
811 _ 'Creating %s with gzip compression...' "$INITRAMFS"
812 cpio -o -H newc | dogzip "/$INITRAMFS"
813 ;;
814 *)
815 # align='y'
816 _ 'Creating %s without compression...' "$INITRAMFS"
817 cpio -o -H newc > "/$INITRAMFS"
818 ;;
819 esac < /tmp/list
820 [ "$align" == 'y' -a -z "$noalign" ] && align_to_32bits "/$INITRAMFS"
821 echo 1 > /tmp/rootfs
822 }
825 # Deduplicate files (MUST be on the same filesystem).
827 deduplicate() {
828 find "${@:-.}" -type f -size +0c -xdev -exec stat -c '%s-%a-%u-%g %i %h %n' {} \; | sort | \
829 (
830 save=0; hardlinks=0; old_attr=""; old_inode=""; old_link=""; old_file=""
831 while read attr inode link file; do
832 [ -L "$file" ] && continue
833 if [ "$attr" == "$old_attr" -a "$inode" != "$old_inode" ]; then
834 if cmp "$file" "$old_file" >/dev/null 2>&1 ; then
835 rm -f "$file"
836 if ln "$old_file" "$file" 2>/dev/null; then
837 inode="$old_inode"
838 [ "$link" -eq 1 ] && hardlinks=$(($hardlinks+1)) &&
839 save="$(($save+(${attr%%-*}+512)/1024))"
840 else
841 cp -a "$old_file" "$file"
842 fi
843 fi
844 fi
845 old_attr="$attr" ; old_inode="$inode" ; old_file="$file"
846 done
847 _ '%s Kbytes saved in %s duplicate files.' "$save" "$hardlinks"
848 )
850 find "$@" -type l -xdev -exec stat -c '%s-%u-%g-TARGET- %i %h %n' {} \; | sort | \
851 (
852 old_attr=""; hardlinks=0;
853 while read attr inode link file; do
854 attr="${attr/-TARGET-/-$(readlink $file)}"
855 if [ "$attr" == "$old_attr" ]; then
856 if [ "$inode" != "$old_inode" ]; then
857 rm -f "$file"
858 if ln "$old_file" "$file" 2>/dev/null; then
859 [ "$link" -eq 1 ] && hardlinks=$(($hardlinks+1))
860 else
861 cp -a "$old_file" "$file"
862 fi
863 fi
864 else
865 old_file="$file"
866 old_attr="$attr"
867 old_inode="$inode"
868 fi
869 done
870 _ '%s duplicate symlinks.' "$hardlinks"
871 )
872 }
875 # Generate a new initramfs from the root filesystem.
877 gen_initramfs() {
878 # Just in case CTRL+c
879 rm -f $DISTRO/gen
881 # Some packages may want to alter rootfs
882 genisohooks rootfs
883 cd $1
885 # Normalize file time
886 find $1 -newer $1 -exec touch -hr $1 {} \;
888 # Link duplicate files
889 deduplicate
891 # Use lzma if installed. Display rootfs size in realtime.
892 rm -f /tmp/rootfs 2>/dev/null
893 pack_rootfs . $DISTRO/$(basename $1).gz &
894 sleep 2
895 echo -en "\nFilesystem size:"
896 while [ ! -f /tmp/rootfs ]; do
897 sleep 1
898 echo -en "\\033[18G$(du -sh $DISTRO/$(basename $1).gz | awk '{print $1}') "
899 done
900 echo -e "\n"
901 rm -f /tmp/rootfs
902 cd $DISTRO
903 mv $(basename $1).gz $ROOTCD/boot
904 }
907 distro_sizes() {
908 if [ -n "$start_time" ]; then
909 time=$(($(date +%s) - $start_time))
910 sec=$time
911 div=$(( ($time + 30) / 60))
912 [ "$div" -ne 0 ] && min="~ ${div}m"
913 _ 'Build time : %ss %s' "$sec" "$min"
914 fi
915 cat <<EOT
916 Build date : $(date +%Y%m%d)
917 Packages : $(ls -1 $ROOTFS*$INSTALLED/*/receipt | wc -l)
918 Rootfs size : $(du -csh $ROOTFS*/ | awk 'END { print $1 }')
919 Initramfs size : $(du -csh $ROOTCD/boot/rootfs*.gz | awk 'END { print $1 }')
920 ISO image size : $(du -sh $ISO_NAME.iso | awk '{ print $1 }')
921 EOT
922 footer "Image is ready: $ISO_NAME.iso"
923 }
926 # Print ISO and rootfs size.
928 distro_stats() {
929 title 'Distro statistics: %s' "$DISTRO"
930 distro_sizes
931 }
934 # Create an empty configuration file.
936 empty_config_file() {
937 cat >> tazlito.conf <<"EOF"
938 # tazlito.conf: Tazlito (SliTaz Live Tool) configuration file.
939 #
941 # Name of the ISO image to generate.
942 ISO_NAME=""
944 # ISO image volume name.
945 VOLUM_NAME="SliTaz"
947 # Name of the preparer.
948 PREPARED="$USER"
950 # Path to the packages repository and the packages.list.
951 PACKAGES_REPOSITORY=""
953 # Path to the distro tree to gen-distro from a list of packages.
954 DISTRO=""
956 # Path to the directory containing additional files
957 # to copy into the rootfs and rootcd of the LiveCD.
958 ADDFILES="$DISTRO/addfiles"
960 # Default answer for binary question (Y or N)
961 DEFAULT_ANSWER="ASK"
963 # Compression utility (lzma, gzip or none)
964 COMPRESSION="lzma"
965 EOF
966 }
969 # Extract rootfs.gz somewhere
971 extract_rootfs() {
972 # Detect compression format: *.lzma.cpio, *.gzip.cpio, or *.cpio
973 # First part (lzcat or zcat) may not fail, but cpio will fail on incorrect format
974 (cd "$2"; lzcat "$1" | cpio -idm --quiet 2>/dev/null) && return
975 (cd "$2"; zcat "$1" | cpio -idm --quiet 2>/dev/null) && return
976 (cd "$2"; cat "$1" | cpio -idm --quiet 2>/dev/null)
977 }
980 # Extract flavor file to temp directory
982 extract_flavor() {
983 # Input: $1 - flavor name to extract;
984 # $2 = absent/empty: just extract 'outer layer'
985 # $2 = 'full': also extract 'inner' rootcd and rootfs archives, make files rename
986 # $2 = 'info': as 'full' and also make 'info' file to put into ISO
987 # Output: temp dir path where flavor was extracted
988 local f="$1.flavor" from to infos="$1.desc"
989 [ -f "$f" ] || die "File '$f' not found"
990 local dir="$(mktemp -d)"
991 zcat "$f" | (cd $dir; cpio -i --quiet >/dev/null)
993 if [ -n "$2" ]; then
994 cd $dir
996 [ -s "$1.receipt" ] && infos="$infos\n$1.receipt"
998 for i in rootcd rootfs; do
999 [ -f "$1.$i" ] || continue
1000 mkdir "$i"
1001 zcat "$1.$i" | (cd "$i"; cpio -idm --quiet 2>/dev/null)
1002 zcat "$1.$i" | cpio -tv 2>/dev/null > "$1.list$i"; infos="$infos\n$1.list$i"
1003 rm "$1.$i"
1004 done
1005 touch -t 197001010100.00 $1.*
1006 # Info to be stored inside ISO
1007 [ "$2" == info ] && echo -e $infos | cpio -o -H newc | dogzip info
1008 rm $1.list*
1010 # Renames
1011 while read from to; do
1012 [ -f "$from" ] || continue
1013 mv "$from" "$to"
1014 done <<EOT
1015 $1.nonfree non-free.list
1016 $1.pkglist packages.list
1017 $1-distro.sh distro.sh
1018 $1.receipt receipt
1019 $1.mirrors mirrors
1020 $1.desc description
1021 EOT
1022 fi
1024 echo $dir
1028 # Pack flavor file from temp directory
1030 pack_flavor() {
1031 (cd "$1"; ls | grep -v err | cpio -o -H newc) | dogzip "$2.flavor"
1035 # Remove duplicate files
1037 files_match() {
1038 if [ -d "$1" ]; then
1039 return 1
1041 elif [ -L "$1" ] && [ -L "$2" ]; then
1042 [ "$(readlink "$1")" == "$(readlink "$2")" ] && return 0
1044 elif [ -f "$1" ] && [ -f "$2" ]; then
1045 cmp -s "$1" "$2" && return 0
1047 [ "$(basename "$3")" == 'volatile.cpio.gz' ] &&
1048 [ "$(dirname $(dirname "$3"))" == ".$INSTALLED" ] &&
1049 return 0
1051 elif [ "$(ls -l "$1"|cut -c1-10)$(stat -c '%a:%u:%g:%t:%T' "$1")" == \
1052 "$(ls -l "$2"|cut -c1-10)$(stat -c '%a:%u:%g:%t:%T' "$2")" ]; then
1053 return 0
1055 fi 2> /dev/null
1056 return 1
1059 remove_with_path() {
1060 dir="$(dirname $1)"
1061 rm -f "$1"
1062 while rmdir "$dir" 2> /dev/null; do
1063 dir="$(dirname $dir)"
1064 done
1067 mergefs() {
1068 # Note, many packages have files with spaces in the name
1069 IFS=$'\n'
1071 local size1=$(du -hs "$1" | awk '{ print $1 }')
1072 local size2=$(du -hs "$2" | awk '{ print $1 }')
1073 action 'Merge %s (%s) into %s (%s)' "$(basename "$1")" "$size1" "$(basename "$2")" "$size2"
1075 # merge symlinks files and devices
1076 ( cd "$1"; find ) | \
1077 while read file; do
1078 files_match "$1/$file" "$2/$file" "$file" &&
1079 remove_with_path "$2/$file"
1080 [ -d "$1/$file" ] && [ -d "$2/$file" ] && rmdir "$2/$file" 2>/dev/null
1081 done
1083 unset IFS
1084 status
1088 cleanup_merge() {
1089 rm -rf $TMP_DIR
1090 exit 1
1094 # Update isolinux config files for multiple rootfs
1096 update_bootconfig() {
1097 local files
1098 action 'Updating boot config files...'
1099 files="$(grep -l 'include common' $1/*.cfg)"
1100 for file in $files; do
1101 awk -v n=$(echo $2 | awk '{ print NF/2 }') '{
1102 if (/label/) label=$0;
1103 else if (/kernel/) kernel=$0;
1104 else if (/append/) {
1105 i=index($0,"rootfs.gz");
1106 append=substr($0,i+9);
1108 else if (/include/) {
1109 for (i = 1; i <= n; i++) {
1110 print label i
1111 print kernel;
1112 initrd="initrd=/boot/rootfs" n ".gz"
1113 for (j = n - 1; j >= i; j--) {
1114 initrd=initrd ",/boot/rootfs" j ".gz";
1116 printf "\tappend %s%s\n",initrd,append;
1117 print "";
1119 print;
1121 else print;
1122 }' < $file > $file.$$
1123 mv -f $file.$$ $file
1124 done
1125 sel="$(echo $2 | awk '{
1126 for (i=1; i<=NF; i++)
1127 if (i % 2 == 0) printf " slitaz%d", i/2
1128 else printf " %s", $i
1129 }')"
1131 [ -s $1/common.cfg ] && cat >> $1/common.cfg <<EOT
1133 label slitaz
1134 kernel /boot/isolinux/ifmem.c32
1135 append$sel noram
1137 label noram
1138 config noram.cfg
1140 EOT
1142 # Update vesamenu
1143 if [ -s "$1/isolinux.cfg" ]; then
1144 files="$files $1/isolinux.cfg"
1145 awk -v n=$(echo $2 | awk '{ print NF/2 }') -v "sel=$sel" '
1146 BEGIN {
1147 kernel = " COM32 c32box.c32"
1150 if (/ROWS/) print "MENU ROWS " n+$3;
1151 else if (/TIMEOUTROW/) print "MENU TIMEOUTROW " n+$3;
1152 else if (/TABMSGROW/) print "MENU TABMSGROW " n+$3;
1153 else if (/CMDLINEROW/) print "MENU CMDLINEROW " n+$3;
1154 else if (/VSHIFT/) {
1155 x = $3-n;
1156 if (x < 0) x = 0;
1157 print "MENU VSHIFT " x;
1159 else if (/rootfs.gz/) {
1160 linux = "";
1161 if (/bzImage/) linux = "linux /boot/bzImage ";
1162 i = index($0, "rootfs.gz");
1163 append = substr($0, i+9);
1164 printf "\tkernel /boot/isolinux/ifmem.c32\n";
1165 printf "\tappend%s noram\n", sel;
1166 printf "\nlabel noram\n\tMENU HIDE\n\tconfig noram.cfg\n\n";
1167 for (i = 1; i <= n; i++) {
1168 print "LABEL slitaz" i
1169 printf "\tMENU LABEL SliTaz slitaz%d Live\n", i;
1170 printf "%s\n", kernel;
1171 initrd = "initrd=/boot/rootfs" n ".gz"
1172 for (j = n - 1; j >= i; j--) {
1173 initrd = initrd ",/boot/rootfs" j ".gz";
1175 printf "\tappend %s%s%s\n\n", linux, initrd, append;
1178 else if (/bzImage/) kernel = $0;
1179 else print;
1180 }' < $1/isolinux.cfg > $1/isolinux.cfg.$$
1181 mv $1/isolinux.cfg.$$ $1/isolinux.cfg
1182 fi
1184 [ -s $1/c32box.c32 ] && sed -i -e '/kernel.*ifmem/d' \
1185 -e 's/append \([0-9]\)/append ifmem \1/' $1/isolinux.cfg
1186 cat > $1/noram.cfg <<EOT
1187 implicit 0
1188 prompt 1
1189 timeout 80
1190 $(grep '^F[0-9]' $1/isolinux.cfg)
1192 $([ -s $1/isolinux.msg ] && echo display isolinux.msg)
1193 say Not enough RAM to boot slitaz. Trying hacker mode...
1194 default hacker
1195 label hacker
1196 KERNEL /boot/bzImage
1197 append rw root=/dev/null vga=normal
1199 label reboot
1200 EOT
1202 if [ -s $1/c32box.c32 ]; then
1203 cat >> $1/noram.cfg <<EOT
1204 COM32 c32box.c32
1205 append reboot
1207 label poweroff
1208 COM32 c32box.c32
1209 append poweroff
1211 EOT
1212 else
1213 echo " com32 reboot.c32" >> $1/noram.cfg
1214 fi
1216 # Restore real label names
1217 [ -s $1/common.cfg ] && files="$1/common.cfg $files"
1218 echo $2 | awk '{ for (i=NF; i>1; i-=2) printf "%d/%s\n",i/2,$i }' | \
1219 while read pat; do
1220 sed -i "s/slitaz$pat/" $files
1221 done
1222 status
1226 # Uncompress rootfs or module to stdout
1228 uncompress() {
1229 zcat $1 2> /dev/null || xzcat $1 2> /dev/null ||
1230 { [ $(od -N 1 -An $1) -eq 135 ] && unlzma < $1; } || cat $1
1234 # Install a missing package
1236 install_package() {
1237 if [ -z "$2" ]; then
1238 answer=$(yesorno "$(_ 'Install package %s?' "$1")" 'n')
1239 else
1240 answer=$(yesorno "$(_n 'Install package %s for Kernel %s? ' "$1" "$2")" 'n')
1241 fi
1242 case "$answer" in
1243 y)
1244 # We don't want package on host cache.
1245 action 'Getting and installing package: %s' "$1"
1246 yes y | tazpkg get-install $1 --quiet 2>&1 >> $log || exit 1
1247 status ;;
1248 *)
1249 return 1 ;;
1250 esac
1254 # Check iso for loram transformation
1256 check_iso_for_loram() {
1257 [ -s "$TMP_DIR/iso/boot/rootfs.gz" ] ||
1258 [ -s "$TMP_DIR/iso/boot/rootfs1.gz" ]
1262 # Remove duplicated files in $1/efi/boot from $1/boot
1264 cleanup_efi_boot() {
1265 for i in $1/efi/boot/* ; do
1266 [ -f $i ] || continue
1267 case "$i" in
1268 */rootfs*) cmp $i ${i/\/efi\//\/} || continue ;;
1269 */bootia32.efi) cmp $i $1/boot/bzImage || continue
1270 rm $1/efi/boot/linux.cmdline ;;
1271 */bootx64.efi) cmp $i $1/boot/bzImage64 || continue
1272 rm $1/efi/boot/linux.cmdline* ;;
1273 esac
1274 rm -f $i
1275 rmdir $1/efi/boot && rmdir $1/efi
1276 done 2> /dev/null
1280 # Build initial rootfs for loram ISO ram/cdrom/http
1282 build_initfs() {
1283 urliso="mirror.switch.ch/ftp/mirror/slitaz \
1284 download.tuxfamily.org/slitaz mirror1.slitaz.org mirror2.slitaz.org \
1285 mirror3.slitaz.org mirror.slitaz.org"
1286 version=$(ls $TMP_DIR/iso/boot/vmlinuz-* | sed 's/.*vmlinuz-//')
1287 [ -z "$version" ] && die "Can't find the kernel version." \
1288 'No file /boot/vmlinuz-<version> in ISO image. Abort.'
1290 [ -s /usr/share/boot/busybox-static ] || install_package busybox-static
1291 need_lib=false
1292 for i in bin dev run mnt proc tmp sys lib/modules; do
1293 mkdir -p $TMP_DIR/initfs/$i
1294 done
1295 ln -s bin $TMP_DIR/initfs/sbin
1296 ln -s . $TMP_DIR/initfs/usr
1297 for aufs in aufs overlayfs; do
1298 [ -f /lib/modules/$version/kernel/fs/$aufs/$aufs.ko.?z ] && break
1299 install_package linux-$aufs $version && break
1300 install_package $aufs $version && break
1301 done || return 1
1302 [ -s /init ] || install_package slitaz-boot-scripts
1303 cp /init $TMP_DIR/initfs/
1304 cp /lib/modules/$version/kernel/fs/$aufs/$aufs.ko.?z \
1305 $TMP_DIR/initfs/lib/modules
1306 if [ "$1" == 'cdrom' ]; then
1307 sed -i '/mod squashfs/d' $TMP_DIR/initfs/init
1308 else
1309 [ ! -f /usr/sbin/mksquashfs ] && ! install_package squashfs && return 1
1310 while [ ! -f /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z ]; do
1311 install_package linux-squashfs $version || return 1
1312 done
1313 cp /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z \
1314 $TMP_DIR/initfs/lib/modules
1315 #ls /sbin/unsquashfs /usr/lib/liblzma.so* $INSTALLED/squashfs/* | \
1316 #cpio -o -H newc > $TMP_DIR/initfs/extractfs.cpio
1317 fi
1318 if [ "$1" == 'http' ]; then
1319 mkdir $TMP_DIR/initfs/etc $TMP_DIR/fs
1320 ln -s /proc/mounts $TMP_DIR/initfs/etc/mtab
1321 cp /usr/share/udhcpc/default.script $TMP_DIR/initfs/lib/udhcpc
1322 sed -i 's|/sbin/||;s/^logger/#&/' $TMP_DIR/initfs/lib/udhcpc
1323 cp -a /dev/fuse $TMP_DIR/initfs/dev
1324 if ! $need_lib && [ -x /usr/share/boot/fusermount-static ]; then
1325 cp /usr/share/boot/fusermount-static $TMP_DIR/initfs/bin/fusermount
1326 else
1327 need_lib=true
1328 fi
1329 if ! $need_lib && [ -x /usr/share/boot/httpfs-static ]; then
1330 cp /usr/share/boot/httpfs-static $TMP_DIR/initfs/bin/httpfs
1331 else
1332 [ ! -f /usr/bin/httpfs ] && ! install_package httpfs-fuse && return 1
1333 cp /usr/bin/httpfs $TMP_DIR/initfs/bin
1334 cp /usr/bin/fusermount $TMP_DIR/initfs/bin
1335 cp -a /lib/librt* $TMP_DIR/initfs/lib
1336 cp -a /lib/libdl* $TMP_DIR/initfs/lib
1337 cp -a /lib/libpthread* $TMP_DIR/initfs/lib
1338 cp -a /usr/lib/libfuse* $TMP_DIR/initfs/lib
1339 cp -a /lib/libresolv* $TMP_DIR/initfs/lib
1340 cp -a /lib/libnss_dns* $TMP_DIR/initfs/lib
1341 need_lib=true
1342 fi
1343 cd $TMP_DIR/fs
1344 echo 'Getting slitaz-release & ethernet modules...'
1345 for i in $(ls -r $TMP_DIR/iso/boot/rootfs*z); do
1346 uncompress $i | cpio -idmu etc/slitaz-release lib/modules rootfs*
1347 [ -s rootfs* ] || continue
1348 unsquashfs -f -d . rootfs* rootfs* etc/slitaz-release lib/modules &&
1349 rm -f rootfs*
1350 done 2>&1 > /dev/null
1351 cd - > /dev/null
1352 cp $TMP_DIR/fs/etc/slitaz-release $TMP_DIR/initfs/etc/
1353 find $TMP_DIR/fs/lib/modules/*/kernel/drivers/net/ethernet \
1354 -type f -name '*.ko*' | while read mod; do
1355 f=$TMP_DIR/initfs/lib/modules/$(basename $mod | sed s/..z$//)
1356 uncompress $mod > $f
1357 grep -q alias=pci: $f || rm -f $f
1358 done
1359 for i in $TMP_DIR/initfs/lib/modules/*.ko ; do
1360 f=$(basename $i)..z
1361 grep -q $f:$ $TMP_DIR/fs/lib/modules/*/modules.dep && continue
1362 deps="$(grep $f: $TMP_DIR/fs/lib/modules/*/modules.dep | sed 's/.*: //')"
1363 echo "$deps" | sed 's|kernel/[^ ]*/||g;s/.ko..z//g' > $TMP_DIR/initfs/lib/modules/$(basename $i .ko).dep
1364 for j in $deps; do
1365 mod=$(ls $TMP_DIR/fs/lib/modules/*/$j)
1366 uncompress $mod > $TMP_DIR/initfs/lib/modules/$(basename $j | sed s/..z$//)
1367 done
1368 done
1369 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"
1370 _n 'List of URLs to insert: '
1371 read -t 30 urliso2
1372 urliso="$urliso2 $urliso"
1373 fi
1374 if ! $need_lib && [ -x /usr/share/boot/busybox-static ]; then
1375 cp /usr/share/boot/busybox-static $TMP_DIR/initfs/bin/busybox
1376 sed -i 's/LD_T.*ot/echo/;s/".*ld-.*) /"/' $TMP_DIR/initfs/init
1377 else
1378 cp /bin/busybox $TMP_DIR/initfs/bin
1379 if ! cmp /bin/busybox /sbin/insmod > /dev/null ; then
1380 cp /sbin/insmod $TMP_DIR/initfs/bin
1381 cp -a /lib/libkmod.so.* $TMP_DIR/initfs/lib
1382 cp -a /usr/lib/liblzma.so.* $TMP_DIR/initfs/lib
1383 cp -a /usr/lib/libz.so.* $TMP_DIR/initfs/lib
1384 fi
1385 need_lib=true
1386 fi
1387 for i in $($TMP_DIR/initfs/bin/busybox | awk \
1388 '{ if (s) printf "%s",$0 } /Currently/ { s=1 }' | sed 's/,//g'); do
1389 ln $TMP_DIR/initfs/bin/busybox $TMP_DIR/initfs/bin/$i
1390 done
1391 # bootfloppybox will need floppy.ko.?z, /dev/fd0, /dev/tty0
1392 cp /lib/modules/$version/kernel/drivers/block/floppy.ko.?z \
1393 $TMP_DIR/initfs/lib/modules 2>/dev/null
1394 for i in /dev/console /dev/null /dev/tty /dev/tty0 /dev/zero \
1395 /dev/kmem /dev/mem /dev/random /dev/urandom; do
1396 cp -a $i $TMP_DIR/initfs/dev
1397 done
1398 grep -q '/sys/block/./dev' $TMP_DIR/initfs/init ||
1399 for i in /dev/fd0 /dev/[hs]d[a-f]* /dev/loop* ; do
1400 cp -a $i $TMP_DIR/initfs/dev
1401 done 2>/dev/null
1402 $need_lib && for i in /lib/ld-* /lib/lib[cm][-\.]* ; do
1403 cp -a $i $TMP_DIR/initfs/lib
1404 done
1405 [ "$1" == 'http' ] && cat > $TMP_DIR/initfs/init <<EOTEOT
1406 #!/bin/sh
1408 getarg() {
1409 grep -q " \$1=" /proc/cmdline || return 1
1410 eval \$2=\$(sed "s/.* \$1=\\\\([^ ]*\\\\).*/\\\\1/" < /proc/cmdline)
1411 return 0
1414 copy_rootfs() {
1415 total=\$(grep MemTotal /proc/meminfo | sed 's/[^0-9]//g')
1416 need=\$(du -c \${path}rootfs* | tail -n 1 | cut -f1)
1417 [ \$(( \$total / \$need )) -gt 1 ] || return 1
1418 if ! grep -q " keep-loram" /proc/cmdline && cp \${path}rootfs* /mnt; then
1419 path=/mnt/
1420 return 0
1421 else
1422 rm -f /mnt/rootfs*
1423 return 1
1424 fi
1427 echo "Switching / to tmpfs..."
1428 mount -t proc proc /proc
1429 size="\$(grep rootfssize= < /proc/cmdline | \\
1430 sed 's/.*rootfssize=\\([0-9]*[kmg%]\\).*/-o size=\\1/')"
1431 [ -n "\$size" ] || size="-o size=90%"
1433 mount -t sysfs sysfs /sys
1434 for i in /lib/modules/*.ko ; do
1435 echo -en "Probe \$i \\r"
1436 for j in \$(grep alias=pci: \$i | sed 's/alias//;s/\*/.*/g'); do
1437 grep -q "\$j" /sys/bus/pci/devices/*/uevent || continue
1438 for k in \$(cat \${i/ko/dep} 2> /dev/null); do
1439 insmod /lib/modules/\$k.ko 2> /dev/null
1440 done
1441 echo "Loading \$i"
1442 insmod \$i 2> /dev/null
1443 break
1444 done
1445 done
1446 umount /sys
1447 while read var default; do
1448 eval \$var=\$default
1449 getarg \$var \$var
1450 done <<EOT
1451 eth eth0
1452 dns 208.67.222.222,208.67.220.220
1453 netmask 255.255.255.0
1454 gw
1455 ip
1456 EOT
1457 grep -q \$eth /proc/net/dev || sh
1458 if [ -n "\$ip" ]; then
1459 ifconfig \$eth \$ip netmask \$netmask up
1460 route add default gateway \$gw
1461 for i in \$(echo \$dns | sed 's/,/ /g'); do
1462 echo "nameserver \$i" >> /etc/resolv.conf
1463 done
1464 else
1465 udhcpc -f -q -s /lib/udhcpc -i \$eth
1466 fi
1467 for i in $urliso ; do
1468 [ -n "\$URLISO" ] && URLISO="\$URLISO,"
1469 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"
1470 URLISO="\$URLISO,http://\$i/iso/rolling/slitaz-rolling-loram-cdrom.iso,http://\$i/iso/rolling/slitaz-rolling-loram.iso"
1471 done
1472 getarg urliso URLISO
1473 DIR=fs
1474 if getarg loram DIR; then
1475 DEVICE=\${DIR%,*}
1476 DIR=/\${DIR#*,}
1477 fi
1478 mount -t tmpfs \$size tmpfs /mnt
1479 path2=/mnt/.httpfs/
1480 path=/mnt/.cdrom/
1481 mkdir -p /mnt/.rw /mnt/.wd \$path \$path2
1482 while [ ! -d \$path/boot ]; do
1483 for i in \$(echo \$URLISO | sed 's/,/ /g'); do
1484 httpfs \$i \$path2 && echo \$i && break
1485 done
1486 mount -o loop,ro -t iso9660 \$path2/*.iso \$path || sh
1487 done
1489 memfree=\$(grep MemFree /proc/meminfo | sed 's/[^0-9]//g')
1490 umount /proc
1491 branch=:/mnt/.cdrom/\$DIR
1492 if [ ! -d /mnt/.cdrom/\$DIR/etc ]; then
1493 branch=
1494 lp=1
1495 insmod /lib/modules/squashfs.ko 2> /dev/null
1496 for i in \${path}boot/rootfs?.* ; do
1497 fs=\${i#*root}
1498 branch=\$branch:/mnt/.\$fs
1499 mkdir -p /mnt/.rw/mnt/.\$fs /mnt/.\$fs /mnt/.rw/mnt/.cdrom
1500 losetup -o 124 /dev/loop\$lp \$i
1501 mount -o loop,ro -t squashfs /dev/loop\$lp /mnt/.\$fs
1502 lp=\$((\$lp+1))
1503 done
1504 fi
1505 mkdir -p /mnt/.rw/mnt/.httpfs
1506 while read type opt; do
1507 insmod /lib/modules/\$type.ko && mount -t \$type -o \$opt none /mnt && break
1508 done <<EOT
1509 aufs br=/mnt/.rw\$branch
1510 overlayfs workdir=/mnt/.wd\${branch/:/,lowerdir=},upperdir=/mnt/.rw
1511 EOT
1512 rm -rf /lib/modules
1513 [ -x /bin/httpfs ] && sed -i 's/DHCP="yes"/DHCP="no"/' /mnt/etc/network.conf
1514 [ \$memfree -lt 30000 ] && sed -i 's/ slim//' /mnt/etc/rcS.conf
1515 [ -x /mnt/sbin/init ] && exec /bin/switch_root mnt /sbin/init || sh
1516 EOTEOT
1517 chmod +x $TMP_DIR/initfs/init
1518 for i in $TMP_DIR/initfs/lib/modules/*z ; do
1519 unxz $i || gunzip $i || lzma d $i ${i%.gz}
1520 rm -f $i
1521 done 2>/dev/null
1522 (cd $TMP_DIR/initfs; find | busybox cpio -o -H newc 2>/dev/null) | \
1523 lzma e $TMP_DIR/initfs.gz -si
1524 lzma_set_size $TMP_DIR/initfs.gz
1525 rm -rf $TMP_DIR/initfs
1526 align_to_32bits $TMP_DIR/initfs.gz
1527 return 0
1531 # Move each initramfs to squashfs
1533 build_loram_rootfs() {
1534 rootfs_sizes=""
1535 for i in $TMP_DIR/iso/boot/rootfs*; do
1536 mkdir -p $TMP_DIR/fs
1537 cd $TMP_DIR/fs
1538 uncompress $i | cpio -idm
1539 deduplicate
1540 cd - > /dev/null
1541 rootfs=$TMP_DIR/$(basename $i)
1542 /usr/sbin/mksquashfs $TMP_DIR/fs $rootfs -comp ${1:-xz -Xbcj x86}
1543 cd $TMP_DIR
1544 rootfs_sizes="$rootfs_sizes $(( $(du -s $TMP_DIR/fs | cut -f1) - $(du -s $rootfs | cut -f1) ))"
1545 ( cd $(dirname $rootfs); echo $(basename $rootfs) | cpio -o -H newc ) > $rootfs.cpio
1546 rm -f $rootfs
1547 mv $rootfs.cpio $rootfs
1548 cd - > /dev/null
1549 rm -rf $TMP_DIR/fs
1550 done
1554 # Move meta boot configuration files to basic configuration files
1555 # because meta loram flavor is useless when rootfs is not loaded in RAM
1557 unmeta_boot() {
1558 local root=${1:-$TMP_DIR/loramiso}
1559 if [ -f $root/boot/isolinux/noram.cfg ]; then
1560 # We keep enough information to do unloram...
1561 [ -s $root/boot/isolinux/common.cfg ] &&
1562 sed -i 's/label slitaz/label orgslitaz/' \
1563 $root/boot/isolinux/common.cfg
1564 set -- $(grep 'append ifmem [0-9]' $root/boot/isolinux/isolinux.cfg)
1565 shift
1566 sed -i '/ifmem/{NNNNNNNNd};/^LABEL/{N;/LABEL SliTaz [^L]/{NNNd}}' \
1567 $root/boot/isolinux/isolinux.cfg
1568 [ -n "$3" ] || set -- $(grep 'append [0-9]' $root/boot/isolinux/common.cfg)
1569 sed -i "s/label $3\$/label slitaz/;s|=\(.*rootfs\)\(.*\)\.gz |=\1.gz |" \
1570 $root/boot/isolinux/*.cfg
1571 fi
1575 # Move rootfs to squashfs filesystem(s) to the cdrom writeable with aufs/overlayfs.
1576 # These squashfs may be loaded in RAM at boot time.
1577 # Rootfs are also copied to CD-ROM for tiny ramsize systems.
1578 # Meta flavors are converted to normal flavors.
1580 build_loram_cdrom() {
1581 build_initfs cdrom || return 1
1582 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1583 cleanup_efi_boot $TMP_DIR/loramiso
1584 mkdir $TMP_DIR/loramiso/fs
1585 cd $TMP_DIR/loramiso/fs
1586 for i in $( ls ../boot/root* | sort -r ) ; do
1587 uncompress $i | cpio -idmu
1588 rm -f $i
1589 done
1590 mkdir -p $TMP_DIR/loramiso/fs/mnt/.cdrom
1591 cd - >/dev/null
1592 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1593 unmeta_boot
1594 VOLUM_NAME="SliTaz_LoRAM_CDROM"
1595 sed -i "s|root=|isofs= rodev=/dev/cdrom/fs &|;s/.ive/cdrom/" \
1596 $TMP_DIR/loramiso/boot/isolinux/*.cfg
1597 sed -i '/LABEL slitaz/{NNNNp;s|z cdrom|& text|;s|L slitaz|&text|;s|root=|screen=text &|;s|,[^ ]*||}' \
1598 $TMP_DIR/loramiso/boot/isolinux/*.cfg
1599 create_iso $OUTPUT $TMP_DIR/loramiso
1603 # Create http bootstrap to load and remove loram_cdrom
1604 # Meta flavors are converted to normal flavors.
1606 build_loram_http() {
1607 build_initfs http || return 1
1608 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1609 cleanup_efi_boot $TMP_DIR/loramiso
1610 rm -f $TMP_DIR/loramiso/boot/rootfs*
1611 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1612 unmeta_boot
1613 create_iso $OUTPUT $TMP_DIR/loramiso
1617 # Update meta flavor selection sizes.
1618 # Reduce sizes with rootfs gains.
1620 update_metaiso_sizes() {
1621 for cfg in $(grep -El '(append|ifmem) [0-9]' $TMP_DIR/loramiso/boot/isolinux/*.cfg)
1622 do
1623 local append="$(grep -E '(append|ifmem) [0-9]' $cfg)"
1624 local sizes="$rootfs_sizes"
1625 local new
1626 set -- $append
1627 shift
1628 [ "$1" == "ifmem" ] && shift
1629 new=""
1630 while [ -n "$2" ]; do
1631 local s
1632 case "$1" in
1633 *G) s=$(( ${1%G} * 1024 * 1024 ));;
1634 *M) s=$(( ${1%M} * 1024 ));;
1635 *) s=${1%K};;
1636 esac
1637 sizes=${sizes#* }
1638 for i in $sizes ; do
1639 s=$(( $s - $i ))
1640 done
1641 new="$new $s $2"
1642 shift 2
1643 done
1644 sed -i -e "/append [0-9]/s/append .*/append$new $1/" -e \
1645 "/append ifmem [0-9]/s/append .*/append ifmem$new $1/" $cfg
1646 sed -i 's|\(initrd=\)\([^r]*\)\(rootfs\)|\1\2rootfs.gz,\2\3|' $cfg
1647 sed -i '/LABEL base/{NNNNp;s|base .ive|cdrom|;s|base|cdrom|;s|,[^ ]*||}' $cfg
1648 sed -i '/LABEL cdrom/{NNNNp;s|z cdrom|& text|;s|L cdrom|&text|;s|root=|screen=text &|;s|,[^ ]*||}' $cfg
1649 done
1653 # Move rootfs to a squashfs filesystem into the initramfs writeable with aufs/overlayfs.
1654 # Meta flavor selection sizes are updated.
1656 build_loram_ram() {
1657 build_initfs ram || return 1
1658 build_loram_rootfs "$1"
1659 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1660 cleanup_efi_boot $TMP_DIR/loramiso
1661 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1662 cp $TMP_DIR/rootfs* $TMP_DIR/loramiso/boot
1663 update_metaiso_sizes
1664 create_iso $OUTPUT $TMP_DIR/loramiso
1668 # Remove files installed by packages
1670 find_flavor_rootfs() {
1671 for i in $1/etc/tazlito/*.extract; do
1672 [ -e $i ] || continue
1673 chroot $1 /bin/sh ${i#$1}
1674 done
1676 # Clean hardlinks and files patched by genisofs in /boot
1677 for i in isolinux/isolinux.bin isolinux/boot.cat bzImage ; do
1678 rm -f $1/boot/$i*
1679 done
1681 # Clean files generated in post_install
1682 rm -f $1/lib/modules/*/modules.* $1/etc/mtab \
1683 $1/dev/core $1/dev/fd $1/dev/std*
1685 # Verify md5
1686 cat $1$INSTALLED/*/md5sum | \
1687 while read md5 file; do
1688 [ -e "$1$file" ] || continue
1689 [ "$(md5sum < "$1$file")" == "$md5 -" ] &&
1690 rm -f "$1$file"
1691 done
1693 # Check configuration files
1694 for i in $1$INSTALLED/*/volatile.cpio.gz; do
1695 [ -e $i ] || continue
1696 mkdir /tmp/volatile$$
1697 zcat $i | ( cd /tmp/volatile$$ ; cpio -idmu > /dev/null 2>&1 )
1698 ( cd /tmp/volatile$$ ; find * -type f 2> /dev/null) | \
1699 while read file ; do
1700 [ -e "$1/$file" ] || continue
1701 cmp -s "/tmp/volatile$$/$file" "$1/$file" && rm -f "$1/$file"
1702 done
1703 rm -rf /tmp/volatile$$
1704 done
1706 # Remove other files blindly
1707 for i in $1$INSTALLED/*/files.list; do
1708 for file in $(cat "$i"); do
1709 [ "$1$file" -nt "$i" ] && continue
1710 [ -f "$1$file" -a ! -L "$1$file" ] && continue
1711 [ -d "$1$file" ] || rm -f "$1$file"
1712 done
1713 done
1715 # Remove tazpkg files and tmp files
1716 rm -rf $1$INSTALLED* $1/tmp $1/var/tmp
1717 rm -f $1$LOCALSTATE/*packages* $1$LOCALSTATE/files.list.lzma \
1718 $1$LOCALSTATE/mirror* $1/var/cache/*/* \
1719 $1/var/lock/* $1/var/log/* $1/var/run/* $1/var/run/*/* \
1720 $1/var/lib/* $1/var/lib/dbus/* 2>/dev/null
1722 # Cleanup directory tree
1723 cd $1
1724 find * -type d | sort -r | while read dir; do
1725 rmdir "$dir" 2>/dev/null
1726 done
1727 cd - > /dev/null
1731 # Get byte(s) from a binary file
1733 get() {
1734 od -v -j $1 -N ${3:-2} -t u${3:-2} -w${3:-2} -An $2 2>/dev/null | sed 's/ *//'
1738 # Get cpio flavor info from the ISO image
1740 flavordata() {
1741 [ $(get 1024 $1) -eq 35615 ] && n=2 || n=$((1+$(get 417 $1 1)))
1742 dd if=$1 bs=512 skip=$n count=20 2>/dev/null | zcat 2>/dev/null
1746 # Restore undigest mirrors
1748 restore_mirrors() {
1749 local undigest="$root$LOCALSTATE/undigest" priority="$root$LOCALSTATE/priority"
1750 [ -d "$undigest.bak" ] || [ -e "$priority.bak" ] || return
1752 action 'Restoring mirrors...'
1753 if [ -d "$undigest.bak" ]; then
1754 [ -d "$undigest" ] && rm -r "$undigest"
1755 mv "$undigest.bak" "$undigest"
1756 fi
1757 [ -e "$priority.bak" ] && mv -f "$priority.bak" "$priority"
1758 :; status
1762 # Setup undigest mirrors
1764 setup_mirrors() {
1765 # Setup mirrors in plain system or in chroot (with variable root=)
1766 local mirrorlist="$1" fresh repacked
1767 local undigest="$root$LOCALSTATE/undigest" priority="$root$LOCALSTATE/priority"
1769 # Restore mirrors first: in case of non-clear exits, hangs, etc.
1770 restore_mirrors
1772 _ 'Setting up mirrors for %s...' "$root/"
1773 # Backing up current undigest mirrors and priority
1774 [ -d "$undigest" ] && mv "$undigest" "$undigest.bak"
1775 [ -e "$priority" ] && mv "$priority" "$priority.bak"
1776 rm -rf '/var/www/tazlito/'
1777 mkdir -p '/var/www/tazlito/'
1779 # Packages produced by CookUtils: on Tank or local, or repacked packages: highest priority
1780 fresh='/home/slitaz/packages'
1781 if [ -d "$fresh" ]; then
1782 # Setup first undigest mirror
1783 mkdir -p "$undigest/fresh"
1784 echo "$fresh" > "$undigest/fresh/mirror"
1785 echo 'fresh' >> "$priority"
1786 # Rebuild mirror DB if needed
1787 [ ! -e "$fresh/IDs" ] && tazpkg mkdb "$fresh" --forced --root=''
1788 [ -n "$(find -L "$fresh" -name '*.tazpkg' -newer "$fresh/IDs")" ] && \
1789 tazpkg mkdb "$fresh" --forced --root=''
1790 cp -a "$fresh/files.list.lzma" "$fresh/files-list.lzma"
1791 fi
1793 # Repacked packages: high priority
1794 repacked="$PACKAGES_REPOSITORY"
1795 if [ -d "$repacked" -a "$repacked" != "$fresh" ] && ls "$repacked" | grep -q ".tazpkg"; then
1796 # According to Tazlito setup file (tazlito.conf):
1797 # WORK_DIR="/home/slitaz/$SLITAZ_VERSION"
1798 # or
1799 # WORK_DIR="/home/slitaz"
1800 # and
1801 # PACKAGES_REPOSITORY="$WORK_DIR/packages"
1802 # It MAY or MAY NOT match /home/slitaz/packages, so here we setup second repository
1804 # Setup second undigest mirror
1805 mkdir -p "$undigest/repacked"
1806 echo "$repacked" > "$undigest/repacked/mirror"
1807 echo 'repacked' >> "$priority"
1808 # Rebuild mirror DB if needed
1809 [ ! -e "$repacked/IDs" ] && tazpkg mkdb "$repacked" --forced --root=''
1810 [ -n "$(find -L "$repacked" -name '*.tazpkg' -newer "$repacked/IDs")" ] && \
1811 tazpkg mkdb "$repacked" --forced --root=''
1812 cp -a "$repacked/files.list.lzma" "$repacked/files-list.lzma"
1813 fi
1815 # All repositories listed in mirrors list: normal priority
1816 [ -e "$mirrorlist" ] && \
1817 while read mirror; do
1818 # Provide consistent mirror ID for caching purpose: /var/cache/tazpkg/<mirror ID>/packages
1819 mirrorid=$(echo "$mirror" | md5sum | cut -d' ' -f1)
1820 mkdir -p "$undigest/$mirrorid"
1821 echo "$mirror" > "$undigest/$mirrorid/mirror"
1822 echo "$mirrorid" >> "$priority"
1823 done < "$mirrorlist"
1825 # And, finally, main mirror with the lowest (failsafe) priority (nothing to do)
1827 # Show list of mirrors
1828 [ -f "$priority" ] && awk -vdb="$root$LOCALSTATE" '
1829 function show(num, name, url) {
1830 printf " %-1.1d. %32.32s %-44.44s\n", num, name " ...............................", url;
1833 num++;
1834 "cat " db "/undigest/" $0 "/mirror" | getline url;
1835 show(num, $0, url);
1837 END {
1838 num++;
1839 "cat " db "/mirror" | getline url;
1840 show(num, "main", url);
1841 }' "$priority"
1843 tazpkg recharge --quiet >/dev/null
1847 # Get list of 'packages.info' lists using priority
1849 pi_lists() {
1850 local pi
1851 [ -s "$root$LOCALSTATE/packages.info" ] || tazpkg recharge --root="$root" >/dev/null 2>&1
1852 local priority="$root$LOCALSTATE/priority"
1853 local undigest="$root$LOCALSTATE/undigest"
1856 [ -s "$priority" ] && cat "$priority"
1857 echo 'main'
1858 [ -d "$undigest" ] && ls "$undigest"
1859 } | awk -vun="$undigest/" '
1861 if (arr[$0] != 1) {
1862 arr[$0] = 1;
1863 print un $0 "/packages.info";
1865 }' | sed 's|/undigest/main||' | \
1866 while read pi; do
1867 [ -e "$pi" ] && echo "$pi"
1868 done
1872 # Strip versions from packages list
1874 strip_versions() {
1875 if [ -n "$stripped" ]; then
1876 action 'Consider list %s already stripped' "$(basename "$1")"
1877 status
1878 return 0
1879 fi
1880 action 'Strip versions from list %s...' "$(basename "$1")"
1881 local in_list="$1" tmp_list="$(mktemp)" namever pkg
1882 [ -f "$in_list" ] || die "List '$in_list' not found."
1884 # $pkg=<name>-<version> or $pkg=<name>; both <name> and <version> may contain dashes
1885 awk '
1887 if (FILENAME ~ "packages.info") {
1888 # Collect package names
1889 FS = "\t"; pkg[$1] = 1;
1890 } else {
1891 FS = OFS = "-"; $0 = $0; # Fix bug with FS for first record
1892 while (NF > 1 && ! pkg[$0])
1893 NF --;
1894 printf "%s\n", $0;
1896 }' $(pi_lists) "$in_list" > "$tmp_list"
1898 cat "$tmp_list" > "$in_list"
1899 rm "$tmp_list"
1900 status
1904 # Display list of unknown packages (informative)
1906 display_unknown() {
1907 [ -s "$1" ] || return
1908 echo "Unknown packages:" >&2
1909 cat "$1" >&2
1910 rm "$1"
1914 # Display warnings about critical packages absent (informative)
1916 display_warn() {
1917 [ -s "$1" ] || return
1918 echo "Absent critical packages:" >&2
1919 cat "$1" >&2
1920 rm "$1"
1921 echo "Probably ISO image will be unusable."
1925 # Install packages to rootfs
1927 install_list_to_rootfs() {
1928 local list="$1" rootfs="$2" pkg i ii
1929 local undigest="$rootfs/var/lib/tazpkg/undigest"
1931 # initial tazpkg setup in empty rootfs
1932 tazpkg --root=$rootfs >/dev/null 2>&1
1933 # pass current 'mirror' to the rootfs
1934 mkdir -p $rootfs/var/lib/tazpkg $rootfs/etc
1935 cp -f /var/lib/tazpkg/mirror $rootfs/var/lib/tazpkg/mirror
1936 cp -f /etc/slitaz-release $rootfs/etc/slitaz-release
1937 # link rootfs packages cache to the regular packages cache
1938 rm -r "$rootfs/var/cache/tazpkg"
1939 ln -s /var/cache/tazpkg "$rootfs/var/cache/tazpkg"
1941 setup_mirrors mirrors
1943 # Just in case if flavor doesn't contain "tazlito" package
1944 mkdir -p "$rootfs/etc/tazlito"
1946 newline
1948 # Choose detailed log with --detailed
1949 if [ -n "$detailed" ]; then
1950 while read pkg; do
1951 separator '-'
1952 echo $pkg
1953 tazpkg -gi $pkg --root=$rootfs --local --quiet --cookmode | tee -a $log
1954 done < $list
1955 separator '='
1956 else
1957 while read pkg; do
1958 action 'Installing package: %s' "$pkg"
1959 yes y | tazpkg -gi $pkg --root=$rootfs --quiet >> $log || exit 1
1960 status
1961 done < $list
1962 fi
1963 newline
1965 restore_mirrors
1966 # Remove 'fresh' and 'repacked' undigest repos leaving all other
1967 for i in fresh repacked; do
1968 ii="$undigest/$i"
1969 [ -d "$ii" ] && rm -rf "$ii"
1970 ii="$rootfs/var/lib/tazpkg/priority"
1971 if [ -f "$ii" ]; then
1972 sed -i "/$i/d" "$ii"
1973 [ -s "$ii" ] || rm "$ii"
1974 fi
1975 done
1976 [ -d "$undigest" ] && \
1977 for i in $(find "$undigest" -type f); do
1978 # Remove all undigest PKGDB files but 'mirror'
1979 [ "$(basename "$i")" != 'mirror' ] && rm "$i"
1980 done
1981 [ -d "$undigest" ] && \
1982 rmdir --ignore-fail-on-non-empty "$undigest"
1984 # Un-link packages cache
1985 rm "$rootfs/var/cache/tazpkg"
1987 # Clean /var/lib/tazpkg
1988 (cd $rootfs/var/lib/tazpkg; rm ID* descriptions.txt extra.list files* packages.* 2>/dev/null)
1994 ####################
1995 # Tazlito commands #
1996 ####################
1998 # /usr/bin/tazlito is linked with /usr/bin/reduplicate and /usr/bin/deduplicate
1999 case "$0" in
2000 *reduplicate)
2001 find ${@:-.} ! -type d -links +1 \
2002 -exec cp -a {} {}$$ \; -exec mv {}$$ {} \;
2003 exit 0 ;;
2004 *deduplicate)
2005 deduplicate "$@"
2006 exit 0 ;;
2007 esac
2010 case "$COMMAND" in
2011 stats)
2012 # Tazlito general statistics from the config file.
2014 title 'Tazlito statistics'
2015 optlist "\
2016 Config file : $CONFIG_FILE
2017 ISO name : $ISO_NAME.iso
2018 Volume name : $VOLUM_NAME
2019 Prepared : $PREPARED
2020 Packages repository : $PACKAGES_REPOSITORY
2021 Distro directory : $DISTRO
2022 Additional files : $ADDFILES
2023 " | sed '/: $/d'
2024 footer
2025 ;;
2028 list-addfiles)
2029 # Simple list of additional files in the rootfs
2030 newline
2031 if [ -d "$ADDFILES/rootfs" ]; then
2032 cd $ADDFILES
2033 find rootfs -type f
2034 else
2035 _ 'Additional files not found: %s' "$ADDFILES/rootfs/"
2036 fi
2037 newline
2038 ;;
2041 gen-config)
2042 # Generate a new config file in the current dir or the specified
2043 # directory by $2.
2045 if [ -n "$2" ]; then
2046 mkdir -p "$2" && cd "$2"
2047 fi
2049 newline
2050 action 'Generating empty tazlito.conf...'
2051 empty_config_file
2052 status
2054 separator
2055 if [ -f 'tazlito.conf' ] ; then
2056 _ 'Configuration file is ready to edit.'
2057 _ 'File location: %s' "$(pwd)/tazlito.conf"
2058 newline
2059 fi
2060 ;;
2063 configure)
2064 # Configure a tazlito.conf config file. Start by getting
2065 # a empty config file and sed it.
2067 if [ -f 'tazlito.conf' ]; then
2068 rm tazlito.conf
2069 else
2070 [ $(id -u) -ne 0 ] && die 'You must be root to configure the main config file' \
2071 'or in the same directory of the file you want to configure.'
2072 cd /etc
2073 fi
2075 empty_config_file
2077 title 'Configuring: %s' "$(pwd)/tazlito.conf"
2079 # ISO name.
2080 echo -n "ISO name : " ; read answer
2081 sed -i s#'ISO_NAME=\"\"'#"ISO_NAME=\"$answer\""# tazlito.conf
2082 # Volume name.
2083 echo -n "Volume name : " ; read answer
2084 sed -i s/'VOLUM_NAME=\"SliTaz\"'/"VOLUM_NAME=\"$answer\""/ tazlito.conf
2085 # Packages repository.
2086 echo -n "Packages repository : " ; read answer
2087 sed -i s#'PACKAGES_REPOSITORY=\"\"'#"PACKAGES_REPOSITORY=\"$answer\""# tazlito.conf
2088 # Distro path.
2089 echo -n "Distro path : " ; read answer
2090 sed -i s#'DISTRO=\"\"'#"DISTRO=\"$answer\""# tazlito.conf
2091 footer "Config file is ready to use."
2092 echo 'You can now extract an ISO or generate a distro.'
2093 newline
2094 ;;
2097 gen-iso)
2098 # Simply generate a new iso.
2100 check_root
2101 verify_rootcd
2102 gen_livecd_isolinux
2103 distro_stats
2104 ;;
2107 gen-initiso)
2108 # Simply generate a new initramfs with a new iso.
2110 check_root
2111 verify_rootcd
2112 gen_initramfs "$ROOTFS"
2113 gen_livecd_isolinux
2114 distro_stats
2115 ;;
2118 extract-distro|extract-iso)
2119 # Extract an ISO image to a directory and rebuild the LiveCD tree.
2121 check_root
2122 ISO_IMAGE="$2"
2123 [ -z "$ISO_IMAGE" ] && die 'Please specify the path to the ISO image.' \
2124 'Example:\n tazlito image.iso /path/target'
2126 # Set the distro path by checking for $3 on cmdline.
2127 TARGET="${3:-$DISTRO}"
2129 # Exit if existing distro is found.
2130 [ -d "$TARGET/rootfs" ] && die "A rootfs exists in '$TARGET'." \
2131 'Please clean the distro tree or change directory path.'
2133 title 'Tazlito extracting: %s' "$(basename $ISO_IMAGE)"
2135 # Start to mount the ISO.
2136 action 'Mounting ISO image...'
2137 mkdir -p "$TMP_DIR"
2138 # Get ISO file size.
2139 isosize=$(du -sh "$ISO_IMAGE" | cut -f1)
2140 mount -o loop -r "$ISO_IMAGE" "$TMP_DIR"
2141 sleep 2
2142 # Prepare target dir, copy the kernel and the rootfs.
2143 mkdir -p "$TARGET/rootfs" "$TARGET/rootcd/boot"
2144 status
2146 action 'Copying the Linux kernel...'
2147 if cp $TMP_DIR/boot/vmlinuz* "$TARGET/rootcd/boot" 2>/dev/null; then
2148 make_bzImage_hardlink "$TARGET/rootcd/boot"
2149 else
2150 cp "$TMP_DIR/boot/bzImage" "$TARGET/rootcd/boot"
2151 fi
2152 status
2154 for i in $(ls $TMP_DIR); do
2155 [ "$i" == 'boot' ] && continue
2156 cp -a "$TMP_DIR/$i" "$TARGET/rootcd"
2157 done
2159 for loader in isolinux syslinux extlinux grub; do
2160 [ -d "$TMP_DIR/boot/$loader" ] || continue
2161 action 'Copying %s files...' "$loader"
2162 cp -a "$TMP_DIR/boot/$loader" "$TARGET/rootcd/boot"
2163 status
2164 done
2166 action 'Copying the rootfs...'
2167 cp $TMP_DIR/boot/rootfs*.?z* "$TARGET/rootcd/boot"
2168 status
2170 cleanup_efi_boot "$TARGET/rootcd"
2172 # Extract initramfs.
2173 cd "$TARGET/rootfs"
2174 action 'Extracting the rootfs...'
2175 for i in $(ls -r $TARGET/rootcd/boot/rootfs*z); do
2176 extract_rootfs "$i" "$TARGET/rootfs"
2177 done
2178 # unpack /usr
2179 for i in etc/tazlito/*.extract; do
2180 [ -f "$i" ] && . $i ../rootcd
2181 done
2182 # Umount and remove temp directory and cd to $TARGET to get stats.
2183 umount "$TMP_DIR" && rm -rf "$TMP_DIR"
2184 cd ..
2185 status
2187 newline
2188 separator
2189 echo "Extracted : $(basename $ISO_IMAGE) ($isosize)"
2190 echo "Distro tree : $(pwd)"
2191 echo "Rootfs size : $(du -sh rootfs)"
2192 echo "Rootcd size : $(du -sh rootcd)"
2193 footer
2194 ;;
2197 list-flavors)
2198 # Show available flavors.
2199 list='/etc/tazlito/flavors.list'
2200 [ ! -s $list -o -n "$recharge" ] && download flavors.list -O - > $list
2201 title 'List of flavors'
2202 cat $list
2203 footer
2204 ;;
2207 show-flavor)
2208 # Show flavor descriptions.
2209 set -e
2210 flavor=${2%.flavor}
2211 flv_dir="$(extract_flavor "$flavor")"
2212 desc="$flv_dir/$flavor.desc"
2213 if [ -n "$brief" ]; then
2214 if [ -z "$noheader" ]; then
2215 printf "%-16.16s %6.6s %6.6s %s\n" 'Name' 'ISO' 'Rootfs' 'Description'
2216 separator
2217 fi
2218 printf "%-16.16s %6.6s %6.6s %s\n" "$flavor" \
2219 "$(field ISO "$desc")" \
2220 "$(field Rootfs "$desc")" \
2221 "$(field Description "$desc")"
2222 else
2223 separator
2224 cat "$desc"
2225 fi
2226 cleanup
2227 ;;
2230 gen-liveflavor)
2231 # Generate a new flavor from the live system.
2232 FLAVOR=${2%.flavor}
2233 [ -z "$FLAVOR" ] && die 'Please specify flavor name on the commandline.'
2235 case "$FLAVOR" in
2236 -?|-h*|--help)
2237 cat <<EOT
2238 SliTaz Live Tool - Version: $VERSION
2240 $(boldify 'Usage:') tazlito gen-liveflavor <flavor-name> [<flavor-patch-file>]
2242 $(boldify '<flavor-patch-file> format:')
2243 $(optlist "\
2244 code data
2245 + package to add
2246 - package to remove
2247 ! non-free package to add
2248 ? display message
2249 @ flavor description
2250 ")
2252 $(boldify 'Example:')
2253 $(optlist "\
2254 @ Developer tools for SliTaz maintainers
2255 + slitaz-toolchain
2256 + mercurial
2257 ")
2258 EOT
2259 exit 1
2260 ;;
2261 esac
2262 mv /etc/tazlito/distro-packages.list \
2263 /etc/tazlito/distro-packages.list.$$ 2>/dev/null
2264 rm -f distro-packages.list non-free.list 2>/dev/null
2265 tazpkg recharge
2267 DESC=""
2268 [ -n "$3" ] && \
2269 while read action pkg; do
2270 case "$action" in
2271 +) yes | tazpkg get-install $pkg 2>&1 >> $log || exit 1 ;;
2272 -) yes | tazpkg remove $pkg ;;
2273 !) echo $pkg >> non-free.list ;;
2274 @) DESC="$pkg" ;;
2275 \?) echo -en "$pkg"; read action ;;
2276 esac
2277 done < $3
2279 yes '' | tazlito gen-distro
2280 echo "$DESC" | tazlito gen-flavor "$FLAVOR"
2281 mv /etc/tazlito/distro-packages.list.$$ \
2282 /etc/tazlito/distro-packages.list 2>/dev/null
2283 ;;
2286 gen-flavor)
2287 # Generate a new flavor from the last ISO image generated
2288 FLAVOR=${2%.flavor}
2289 [ -z "$FLAVOR" ] && die 'Please specify flavor name on the commandline.'
2291 title 'Flavor generation'
2292 check_rootfs
2293 FILES="$FLAVOR.pkglist"
2295 action 'Creating file %s...' "$FLAVOR.flavor"
2296 for i in rootcd rootfs; do
2297 if [ -d "$ADDFILES/$i" ] ; then
2298 FILES="$FILES\n$FLAVOR.$i"
2299 ( cd "$ADDFILES/$i"; find . ) | cpio -o -H newc 2>/dev/null | dogzip $FLAVOR.$i
2300 fi
2301 done
2302 status
2304 answer=$(grep -s ^Description $FLAVOR.desc)
2305 answer=${answer#Description : }
2306 if [ -z "$answer" ]; then
2307 echo -n "Description: "
2308 read answer
2309 fi
2311 action 'Compressing flavor %s...' "$FLAVOR"
2312 echo "Flavor : $FLAVOR" > $FLAVOR.desc
2313 echo "Description : $answer" >> $FLAVOR.desc
2314 (cd $DISTRO; distro_sizes) >> $FLAVOR.desc
2315 \rm -f $FLAVOR.pkglist $FLAVOR.nonfree 2>/dev/null
2316 for i in $(ls $ROOTFS$INSTALLED); do
2317 eval $(grep ^VERSION= $ROOTFS$INSTALLED/$i/receipt)
2318 EXTRAVERSION=""
2319 eval $(grep ^EXTRAVERSION= $ROOTFS$INSTALLED/$i/receipt)
2320 eval $(grep ^CATEGORY= $ROOTFS$INSTALLED/$i/receipt)
2321 if [ "$CATEGORY" == 'non-free' -a "${i%%-*}" != 'get' ]; then
2322 echo "$i" >> $FLAVOR.nonfree
2323 else
2324 echo "$i-$VERSION$EXTRAVERSION" >> $FLAVOR.pkglist
2325 fi
2326 done
2327 [ -s $FLAVOR.nonfree ] && $FILES="$FILES\n$FLAVOR.nonfree"
2328 for i in $LOCALSTATE/undigest/*/mirror ; do
2329 [ -s $i ] && cat $i >> $FLAVOR.mirrors
2330 done
2331 [ -s $FLAVOR.mirrors ] && $FILES="$FILES\n$FLAVOR.mirrors"
2332 touch -t 197001010100.00 $FLAVOR.*
2333 echo -e "$FLAVOR.desc\n$FILES" | cpio -o -H newc 2>/dev/null | dogzip $FLAVOR.flavor
2334 rm $(echo -e $FILES)
2335 status
2337 footer "Flavor size: $(du -sh $FLAVOR.flavor)"
2338 ;;
2341 upgrade-flavor)
2342 # Strip versions from pkglist and update estimated numbers in flavor.desc
2343 flavor="${2%.flavor}"
2344 set -e
2345 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2346 set +e
2348 flv_dir="$(extract_flavor "$flavor")"
2350 strip_versions "$flv_dir/$flavor.pkglist"
2352 action 'Updating %s...' "$flavor.desc"
2354 [ -f "$flv_dir/$flavor.mirrors" ] && setup_mirrors "$flv_dir/$flavor.mirrors" >/dev/null
2355 set -- $(module calc_sizes "$flv_dir" "$flavor")
2356 restore_mirrors >/dev/null
2358 sed -i -e '/Image is ready/d' \
2359 -e "s|\(Rootfs size *:\).*$|\1 $1 (estimated)|" \
2360 -e "s|\(Initramfs size *:\).*$|\1 $2 (estimated)|" \
2361 -e "s|\(ISO image size *:\).*$|\1 $3 (estimated)|" \
2362 -e "s|\(Packages *:\).*$|\1 $4|" \
2363 -e "s|\(Build date *:\).*$|\1 $(date '+%Y%m%d at %T')|" \
2364 "$flv_dir/$flavor.desc"
2366 pack_flavor "$flv_dir" "$flavor"
2367 status
2368 display_unknown "$flv_dir/err"
2369 display_warn "$flv_dir/warn"
2370 cleanup
2371 ;;
2374 extract-flavor)
2375 # Extract a flavor into $FLAVORS_REPOSITORY
2376 flavor="${2%.flavor}"
2377 set -e
2378 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2379 set +e
2381 action 'Extracting %s...' "$flavor.flavor"
2382 flv_dir="$(extract_flavor "$flavor" full)"
2383 storage="$FLAVORS_REPOSITORY/$flavor"
2385 rm -rf "$storage" 2>/dev/null
2386 mkdir -p "$storage"
2387 cp -a "$flv_dir"/* "$storage"
2388 rm "$storage/description"
2389 status
2391 strip_versions "$storage/packages.list"
2393 cleanup
2394 ;;
2397 pack-flavor)
2398 # Create a flavor from $FLAVORS_REPOSITORY.
2399 flavor=${2%.flavor}
2400 storage="$FLAVORS_REPOSITORY/$flavor"
2402 [ -s "$storage/receipt" ] || die "No $flavor receipt in $FLAVORS_REPOSITORY."
2404 action 'Creating flavor %s...' "$flavor"
2405 tmp_dir="$(mktemp -d)"
2407 while read from to; do
2408 [ -s "$storage/$from" ] || continue
2409 cp -a "$storage/$from" "$tmp_dir/$to"
2410 done <<EOT
2411 mirrors $flavor.mirrors
2412 distro.sh $flavor-distro.sh
2413 receipt $flavor.receipt
2414 non-free.list $flavor.nonfree
2415 EOT
2417 # Build the package list.
2418 # It can include a list from another flavor with the keyword @include
2419 if [ -s "$storage/packages.list" ]; then
2420 include=$(grep '^@include' "$storage/packages.list")
2421 if [ -n "$include" ]; then
2422 include=${include#@include }
2423 if [ -s "$FLAVORS_REPOSITORY/$include/packages.list" ]; then
2424 cp -f "$FLAVORS_REPOSITORY/$include/packages.list" "$tmp_dir/$flavor.pkglist"
2425 else
2426 echo -e "\nERROR: Can't find include package list from $include\n"
2427 fi
2428 fi
2429 # Generate the final/initial package list
2430 [ -s "$storage/packages.list" ] && \
2431 cat "$storage/packages.list" >> "$tmp_dir/$flavor.pkglist"
2432 sed -i '/@include/d' "$tmp_dir/$flavor.pkglist"
2433 fi
2435 if grep -q ^ROOTFS_SELECTION "$storage/receipt"; then
2436 # Process multi-rootfs flavor
2437 . "$storage/receipt"
2438 set -- $ROOTFS_SELECTION
2439 [ -n "$FRUGAL_RAM" ] || FRUGAL_RAM=$1
2440 [ -f "$FLAVORS_REPOSITORY/$2/packages.list" ] || tazlito extract-flavor $2
2441 cp "$FLAVORS_REPOSITORY/$2/packages.list" "$tmp_dir/$flavor.pkglist"
2443 for i in rootcd rootfs; do
2444 mkdir "$tmp_dir/$i"
2445 # Copy extra files from the first flavor
2446 [ -d "$FLAVORS_REPOSITORY/$2/$i" ] &&
2447 cp -a "$FLAVORS_REPOSITORY/$2/$i" "$tmp_dir"
2448 # Overload extra files by meta flavor
2449 [ -d "$storage/$i" ] && cp -a "$storage/$i" "$tmp_dir"
2450 [ -n "$(ls $tmp_dir/$i)" ] &&
2451 (cd "$tmp_dir/$i"; find . | cpio -o -H newc 2>/dev/null ) | \
2452 dogzip "$tmp_dir/$flavor.$i"
2453 rm -rf "$tmp_dir/$i"
2454 done
2455 else
2456 # Process plain flavor
2457 for i in rootcd rootfs; do
2458 [ -d "$storage/$i" ] || continue
2459 (cd "$storage/$i";
2460 find . | cpio -o -H newc 2>/dev/null) | dogzip "$tmp_dir/$flavor.$i"
2461 done
2462 fi
2464 unset VERSION MAINTAINER ROOTFS_SELECTION
2465 set -- $(module calc_sizes "$tmp_dir" "$flavor")
2466 ROOTFS_SIZE="$1 (estimated)"
2467 INITRAMFS_SIZE="$2 (estimated)"
2468 ISO_SIZE="$3 (estimated)"
2469 PKGNUM="$4"
2470 . "$storage/receipt"
2472 sed '/: $/d' > "$tmp_dir/$flavor.desc" <<EOT
2473 Flavor : $FLAVOR
2474 Description : $SHORT_DESC
2475 Version : $VERSION
2476 Maintainer : $MAINTAINER
2477 LiveCD RAM size : $FRUGAL_RAM
2478 Rootfs list : $ROOTFS_SELECTION
2479 Build date : $(date '+%Y%m%d at %T')
2480 Packages : $PKGNUM
2481 Rootfs size : $ROOTFS_SIZE
2482 Initramfs size : $INITRAMFS_SIZE
2483 ISO image size : $ISO_SIZE
2484 ================================================================================
2486 EOT
2488 rm -f $tmp_dir/packages.list
2489 pack_flavor "$tmp_dir" "$flavor"
2490 status
2491 display_unknown "$tmp_dir/err"
2492 display_warn "$flv_dir/warn"
2493 cleanup
2494 ;;
2497 get-flavor)
2498 # Get a flavor's files and prepare for gen-distro.
2499 flavor=${2%.flavor}
2500 title 'Preparing %s distro flavor' "$flavor"
2501 set -e
2502 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2503 set +e
2505 action 'Cleaning %s...' "$DISTRO"
2506 [ -d "$DISTRO" ] && rm -r "$DISTRO"
2507 # Clean old files
2508 for i in non-free.list distro-packages.list distro.sh receipt mirrors err; do
2509 [ -f "$i" ] && rm "$i"
2510 done
2511 mkdir -p "$DISTRO"
2512 status
2514 [ -z "$noup" ] && tazlito upgrade-flavor "$flavor.flavor"
2516 action 'Extracting flavor %s...' "$flavor.flavor"
2517 flv_dir="$(extract_flavor "$flavor" info)"
2518 cp -a "$flv_dir"/* .
2519 mv packages.list distro-packages.list
2520 mv -f info /etc/tazlito
2521 status
2523 for i in rootcd rootfs; do
2524 if [ -d "$i" ]; then
2525 mkdir -p "$ADDFILES"; mv "$i" "$ADDFILES/$i"
2526 fi
2527 done
2529 sed '/^Rootfs list/!d;s/.*: //' description > /etc/tazlito/rootfs.list
2530 [ -s /etc/tazlito/rootfs.list ] || rm -f /etc/tazlito/rootfs.list
2532 action 'Updating %s...' 'tazlito.conf'
2533 [ -f tazlito.conf ] || cp /etc/tazlito/tazlito.conf .
2534 grep -v "^#VOLUM_NAME" < tazlito.conf | \
2535 sed "s/^VOLUM_NA/VOLUM_NAME=\"SliTaz $flavor\"\\n#VOLUM_NA/" \
2536 > tazlito.conf.$$ && mv tazlito.conf.$$ tazlito.conf
2537 sed -i "s/ISO_NAME=.*/ISO_NAME=\"slitaz-$flavor\"/" tazlito.conf
2538 status
2540 footer 'Flavor is ready to be generated by `tazlito gen-distro`'
2541 cleanup
2542 ;;
2545 iso2flavor)
2546 [ -z "$3" -o ! -s "$2" ] && die 'Usage: tazlito iso2flavor <image.iso> <flavor_name>' \
2547 '\n\nCreate a file <flavor_name>.flavor from the CD-ROM image file <image.iso>'
2549 FLAVOR=${3%.flavor}
2550 mkdir -p $TMP_DIR/iso $TMP_DIR/rootfs $TMP_DIR/flavor
2551 mount -o loop,ro $2 $TMP_DIR/iso
2552 flavordata $2 | (cd $TMP_DIR/flavor; cpio -i 2>/dev/null)
2553 if [ -s $TMP_DIR/iso/boot/rootfs1.gz -a \
2554 ! -s $TMP_DIR/flavor/*.desc ]; then
2555 _ 'META flavors are not supported.'
2556 umount -d $TMP_DIR/iso
2557 elif [ ! -s $TMP_DIR/iso/boot/rootfs.gz -a \
2558 ! -s $TMP_DIR/iso/boot/rootfs1.gz ]; then
2559 _ 'No %s in ISO image. Needs a SliTaz ISO.' '/boot/rootfs.gz'
2560 umount -d $TMP_DIR/iso
2561 else
2562 for i in $(ls -r $TMP_DIR/iso/boot/rootfs*z); do
2563 uncompress $i | \
2564 ( cd $TMP_DIR/rootfs ; cpio -idmu > /dev/null 2>&1 )
2565 done
2566 if [ ! -s $TMP_DIR/rootfs/etc/slitaz-release ]; then
2567 _ 'No file %s in %s of ISO image. Needs a non-loram SliTaz ISO.' \
2568 '/etc/slitaz-release' '/boot/rootfs.gz'
2569 umount -d $TMP_DIR/iso
2570 else
2571 ROOTFS_SIZE=$(du -hs $TMP_DIR/rootfs | awk '{ print $1 }')
2572 RAM_SIZE=$(du -s $TMP_DIR/rootfs | awk '{ print 32*int(($1+36000)/32768) "M" }')
2573 cp -a $TMP_DIR/iso $TMP_DIR/rootcd
2574 ISO_SIZE=$(df -h $TMP_DIR/iso | awk 'END { print $2 }')
2575 BUILD_DATE=$(date '+%Y%m%d at %T' -r "$TMP_DIR/iso/md5sum")
2576 umount -d $TMP_DIR/iso
2577 INITRAMFS_SIZE=$(du -chs $TMP_DIR/rootcd/boot/rootfs*.gz | awk 'END { print $1 }')
2578 rm -f $TMP_DIR/rootcd/boot/rootfs.gz $TMP_DIR/rootcd/md5sum
2579 mv $TMP_DIR/rootcd/boot $TMP_DIR/rootfs
2580 [ -d $TMP_DIR/rootcd/efi ] && mv $TMP_DIR/rootcd/efi $TMP_DIR/rootfs
2581 sed 's/.* \(.*\).tazpkg*/\1/' > $TMP_DIR/$FLAVOR.pkglist \
2582 < $TMP_DIR/rootfs$INSTALLED.md5
2583 PKGCNT=$(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l | awk '{ print $1 }')
2584 if [ -s $TMP_DIR/flavor/*desc ]; then
2585 cp $TMP_DIR/flavor/*.desc $TMP_DIR/$FLAVOR.desc
2586 [ -s $TMP_DIR/$FLAVOR.receipt ] &&
2587 cp $TMP_DIR/flavor/*.receipt $TMP_DIR/$FLAVOR.receipt
2588 for i in rootfs rootcd ; do
2589 [ -s $TMP_DIR/flavor/*.list$i ] &&
2590 sed 's/.\{1,45\}//;/^\.$/d' $TMP_DIR/flavor/*.list$i | \
2591 ( cd $TMP_DIR/$i ; cpio -o -H newc ) | dogzip $TMP_DIR/$FLAVOR.$i
2592 done
2593 else
2594 find_flavor_rootfs $TMP_DIR/rootfs
2595 [ -d $TMP_DIR/rootfs/boot ] && mv $TMP_DIR/rootfs/boot $TMP_DIR/rootcd
2596 [ -d $TMP_DIR/rootfs/efi ] && mv $TMP_DIR/rootfs/efi $TMP_DIR/rootcd
2597 for i in rootfs rootcd ; do
2598 [ "$(ls $TMP_DIR/$i)" ] &&
2599 ( cd "$TMP_DIR/$i"; find * | cpio -o -H newc ) | dogzip "$TMP_DIR/$FLAVOR.$i"
2600 done
2601 unset VERSION MAINTAINER
2602 echo -en "Flavor short description \007: "; read -t 30 DESCRIPTION
2603 if [ -n "$DESCRIPTION" ]; then
2604 _n 'Flavor version : '; read -t 30 VERSION
2605 _n 'Flavor maintainer (your email) : '; read -t 30 MAINTAINER
2606 fi
2608 cat > $TMP_DIR/$FLAVOR.desc <<EOT
2609 Flavor : $FLAVOR
2610 Description : ${DESCRIPTION:-SliTaz $FLAVOR flavor}
2611 Version : ${VERSION:-1.0}
2612 Maintainer : ${MAINTAINER:-nobody@slitaz.org}
2613 LiveCD RAM size : $RAM_SIZE
2614 Build date : $BUILD_DATE
2615 Packages : $PKGCNT
2616 Rootfs size : $ROOTFS_SIZE
2617 Initramfs size : $INITRAMFS_SIZE
2618 ISO image size : $ISO_SIZE
2619 ================================================================================
2621 EOT
2622 longline "Tazlito can't detect each file installed during \
2623 a package post_install. You should extract this flavor (tazlito extract-flavor \
2624 $FLAVOR), check the files in /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/rootfs \
2625 tree and remove files generated by post_installs.
2626 Check /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/receipt too and \
2627 repack the flavor (tazlito pack-flavor $FLAVOR)"
2628 fi
2629 ( cd $TMP_DIR; ls $FLAVOR.* | cpio -o -H newc ) | dogzip $FLAVOR.flavor
2630 fi
2631 fi
2632 rm -rf $TMP_DIR
2633 ;;
2636 gen-distro)
2637 # Generate a live distro tree with a set of packages.
2639 check_root
2640 start_time=$(date +%s)
2642 # Tazlito options: --iso or --cdrom
2643 CDROM=''
2644 [ -n "$iso" ] && CDROM="-o loop $iso"
2645 [ -n "$cdrom" ] && CDROM="/dev/cdrom"
2647 # Check if a package list was specified on cmdline.
2648 if [ -f "$2" ]; then
2649 LIST_NAME="$2"
2650 else
2651 LIST_NAME='distro-packages.list'
2652 fi
2654 [ -d "$ROOTFS" -a -z "$forced" ] && die "A rootfs exists in '$DISTRO'." \
2655 'Please clean the distro tree or change directory path.'
2656 [ -d "$ROOTFS" ] && rm -rf "$ROOTFS"
2657 [ -d "$ROOTCD" ] && rm -rf "$ROOTCD"
2659 # If list not given: build list with all installed packages
2660 if [ ! -f "$LIST_NAME" -a -f "$LOCALSTATE/installed.info" ]; then
2661 awk -F$'\t' '{print $1}' "$LOCALSTATE/installed.info" >> "$LIST_NAME"
2662 fi
2664 # Exit if no list name.
2665 [ ! -f "$LIST_NAME" ] && die 'No packages list found or specified. Please read the docs.'
2667 # Start generation.
2668 title 'Tazlito generating a distro'
2670 # Misc checks
2671 mkdir -p "$PACKAGES_REPOSITORY"
2672 REPACK=$(yesorno 'Repack packages from rootfs?' 'n')
2673 newline
2675 # Mount CD-ROM to be able to repack boot-loader packages
2676 if [ ! -e /boot -a -n "$CDROM" ]; then
2677 mkdir $TMP_MNT
2678 if mount -r "$CDROM $TMP_MNT" 2>/dev/null; then
2679 ln -s "$TMP_MNT/boot" /
2680 if [ ! -d "$ADDFILES/rootcd" ] ; then
2681 mkdir -p "$ADDFILES/rootcd"
2682 for i in $(ls $TMP_MNT); do
2683 [ "$i" == 'boot' ] && continue
2684 cp -a "$TMP_MNT/$i" "$ADDFILES/rootcd"
2685 done
2686 fi
2687 else
2688 rmdir "$TMP_MNT"
2689 fi
2690 fi
2692 # Rootfs stuff.
2693 echo 'Preparing the rootfs directory...'
2694 mkdir -p "$ROOTFS"
2695 export root="$ROOTFS"
2696 # pass current 'mirror' to the root
2697 mkdir -p $root/var/lib/tazpkg $root/etc
2698 cp -f /var/lib/tazpkg/mirror $root/var/lib/tazpkg/mirror
2699 cp -f /etc/slitaz-release $root/etc/slitaz-release
2700 strip_versions "$LIST_NAME"
2702 if [ "$REPACK" == 'y' ]; then
2703 # Determine full packages list with all dependencies
2704 tmp_dir="$(mktemp -d)"
2705 cp "$LIST_NAME" "$tmp_dir/flavor.pkglist"
2706 touch "$tmp_dir/full.pkglist"
2707 module calc_sizes "$tmp_dir" 'flavor' "$tmp_dir/full.pkglist" >/dev/null
2709 awk -F$'\t' '{printf "%s %s\n", $1, $2}' "$LOCALSTATE/installed.info" | \
2710 while read pkgname pkgver; do
2711 # Is package in full list?
2712 grep -q "^$pkgname$" "$tmp_dir/full.pkglist" || continue
2713 # Is package already repacked?
2714 [ -e "$PACKAGES_REPOSITORY/$pkgname-$pkgver.tazpkg" ] && continue
2715 _ 'Repacking %s...' "$pkgname-$pkgver"
2716 tazpkg repack "$pkgname" --quiet
2717 [ -f "$pkgname-$pkgver.tazpkg" ] && mv "$pkgname-$pkgver.tazpkg" "$PACKAGES_REPOSITORY"
2718 status
2719 done
2721 rm -r "$tmp_dir"
2722 fi
2724 if [ -f non-free.list ]; then
2725 # FIXME: working in the ROOTFS chroot?
2726 newline
2727 echo 'Preparing non-free packages...'
2728 cp 'non-free.list' "$ROOTFS/etc/tazlito/non-free.list"
2729 for pkg in $(cat 'non-free.list'); do
2730 if [ ! -d "$INSTALLED/$pkg" ]; then
2731 if [ ! -d "$INSTALLED/get-$pkg" ]; then
2732 tazpkg get-install get-$pkg
2733 fi
2734 get-$pkg "$ROOTFS"
2735 fi
2736 tazpkg repack $pkg
2737 pkg=$(ls $pkg*.tazpkg)
2738 grep -q "^$pkg$" $LIST_NAME || echo $pkg >> $LIST_NAME
2739 mv $pkg $PACKAGES_REPOSITORY
2740 done
2741 fi
2742 cp $LIST_NAME $DISTRO/distro-packages.list
2743 newline
2745 install_list_to_rootfs "$DISTRO/distro-packages.list" "$ROOTFS"
2747 cd $DISTRO
2748 cp distro-packages.list $ROOTFS/etc/tazlito
2749 # Copy all files from $ADDFILES/rootfs to the rootfs.
2750 if [ -d "$ADDFILES/rootfs" ] ; then
2751 action 'Copying addfiles content to the rootfs...'
2752 cp -a $ADDFILES/rootfs/* $ROOTFS
2753 status
2754 fi
2756 action 'Root filesystem is generated...'; status
2758 # Root CD part.
2759 action 'Preparing the rootcd directory...'
2760 mkdir -p $ROOTCD
2761 status
2763 # Move the boot dir with the Linux kernel from rootfs.
2764 # The efi & boot dirs go directly on the CD.
2765 if [ -d "$ROOTFS/efi" ] ; then
2766 action 'Moving the efi directory...'
2767 mv $ROOTFS/efi $ROOTCD
2768 status
2769 fi
2770 if [ -d "$ROOTFS/boot" ] ; then
2771 action 'Moving the boot directory...'
2772 mv $ROOTFS/boot $ROOTCD
2773 status
2774 fi
2775 cd $DISTRO
2776 # Copy all files from $ADDFILES/rootcd to the rootcd.
2777 if [ -d "$ADDFILES/rootcd" ] ; then
2778 action 'Copying addfiles content to the rootcd...'
2779 cp -a $ADDFILES/rootcd/* $ROOTCD
2780 status
2781 fi
2782 # Execute the distro script used to perform tasks in the rootfs
2783 # before compression. Give rootfs path in arg
2784 [ -z "$DISTRO_SCRIPT" ] && DISTRO_SCRIPT="$TOP_DIR/distro.sh"
2785 if [ -x "$DISTRO_SCRIPT" ]; then
2786 echo 'Executing distro script...'
2787 sh $DISTRO_SCRIPT $DISTRO
2788 fi
2790 # Execute the custom_rules() found in receipt.
2791 if [ -s "$TOP_DIR/receipt" ]; then
2792 if grep -q ^custom_rules "$TOP_DIR/receipt"; then
2793 echo -e "Executing: custom_rules()\n"
2794 . "$TOP_DIR/receipt"
2795 custom_rules || echo -e "\nERROR: custom_rules() failed\n"
2796 fi
2797 fi
2799 # Multi-rootfs
2800 if [ -s /etc/tazlito/rootfs.list ]; then
2802 FLAVOR_LIST="$(awk '{
2803 for (i = 2; i <= NF; i+=2)
2804 printf "%s ", $i;
2805 }' /etc/tazlito/rootfs.list)"
2807 [ -s "$ROOTCD/boot/isolinux/isolinux.msg" ] &&
2808 sed -i "s/ *//;s/)/), flavors $FLAVOR_LIST/" \
2809 "$ROOTCD/boot/isolinux/isolinux.msg" 2>/dev/null
2811 [ -f "$ROOTCD/boot/isolinux/ifmem.c32" -o \
2812 -f "$ROOTCD/boot/isolinux/c32box.c32" ] ||
2813 cp '/boot/isolinux/c32box.c32' "$ROOTCD/boot/isolinux" 2>/dev/null ||
2814 cp '/boot/isolinux/ifmem.c32' "$ROOTCD/boot/isolinux"
2816 n=0
2817 last=$ROOTFS
2818 while read flavor; do
2819 n=$(($n+1))
2820 mkdir ${ROOTFS}0$n
2821 export root="${ROOTFS}0$n"
2822 # initial tazpkg setup in empty rootfs
2823 tazpkg --root=$root >/dev/null 2>&1
2825 newline
2826 boldify "Building $flavor rootfs..."
2828 [ -s "$TOP_DIR/$flavor.flavor" ] &&
2829 cp "$TOP_DIR/$flavor.flavor" .
2831 if [ ! -s "$flavor.flavor" ]; then
2832 # We may have it in $FLAVORS_REPOSITORY
2833 if [ -d "$FLAVORS_REPOSITORY/$flavor" ]; then
2834 tazlito pack-flavor $flavor
2835 else
2836 download $flavor.flavor
2837 fi
2838 fi
2840 action 'Extracting %s and %s...' "$flavor.pkglist" "$flavor.rootfs"
2841 zcat $flavor.flavor | cpio -i --quiet $flavor.pkglist $flavor.rootfs
2842 cp $flavor.pkglist $DISTRO/list-packages0$n
2843 status
2845 strip_versions "$DISTRO/list-packages0$n"
2847 install_list_to_rootfs "$DISTRO/list-packages0$n" "${ROOTFS}0$n"
2849 action 'Updating the boot directory...'
2850 yes n | cp -ai ${ROOTFS}0$n/boot $ROOTCD 2> /dev/null
2851 rm -rf ${ROOTFS}0$n/boot
2853 cd $DISTRO
2854 if [ -s $flavor.rootfs ]; then
2855 _n 'Adding %s rootfs extra files...' "$flavor"
2856 zcat < $flavor.rootfs | ( cd ${ROOTFS}0$n ; cpio -idmu )
2857 fi
2859 action 'Moving %s to %s' "list-packages0$n" "rootfs0$n"
2860 mv "$DISTRO/list-packages0$n" "${ROOTFS}0$n/etc/tazlito/distro-packages.list"
2861 status
2863 rm -f $flavor.flavor install-list
2864 mergefs ${ROOTFS}0$n $last
2865 last=${ROOTFS}0$n
2866 done <<EOT
2867 $(awk '{ for (i = 4; i <= NF; i+=2) print $i; }' < /etc/tazlito/rootfs.list)
2868 EOT
2869 #'
2870 i=$(($n+1))
2871 while [ $n -gt 0 ]; do
2872 mv ${ROOTFS}0$n ${ROOTFS}$i
2873 _ 'Compressing %s (%s)...' "${ROOTFS}0$n" "$(du -hs ${ROOTFS}$i | awk '{ print $1 }')"
2874 gen_initramfs ${ROOTFS}$i
2875 n=$(($n-1))
2876 i=$(($i-1))
2877 export LZMA_HISTORY_BITS=26
2878 done
2879 mv $ROOTFS ${ROOTFS}$i
2880 gen_initramfs ${ROOTFS}$i
2881 update_bootconfig "$ROOTCD/boot/isolinux" "$(cat /etc/tazlito/rootfs.list)"
2882 ROOTFS=${ROOTFS}1
2883 else
2884 # Initramfs and ISO image stuff.
2885 gen_initramfs $ROOTFS
2886 fi
2887 gen_livecd_isolinux
2888 distro_stats
2889 cleanup
2890 ;;
2893 clean-distro)
2894 # Remove old distro tree.
2896 check_root
2897 title 'Cleaning: %s' "$DISTRO"
2898 if [ -d "$DISTRO" ] ; then
2899 if [ -d "$ROOTFS" ] ; then
2900 action 'Removing the rootfs...'
2901 rm -f $DISTRO/$INITRAMFS
2902 rm -rf $ROOTFS
2903 status
2904 fi
2905 if [ -d "$ROOTCD" ] ; then
2906 action 'Removing the rootcd...'
2907 rm -rf $ROOTCD
2908 status
2909 fi
2910 action 'Removing eventual ISO image...'
2911 rm -f $DISTRO/$ISO_NAME.iso
2912 rm -f $DISTRO/$ISO_NAME.md5
2913 status
2914 fi
2915 footer
2916 ;;
2919 check-distro)
2920 # Check for a few LiveCD needed files not installed by packages.
2922 # TODO: Remove this function.
2923 # First two files are maintained by tazpkg while it runs on rootfs,
2924 # while last one file should be maintained by tazlito itself.
2925 check_rootfs
2926 title 'Checking distro: %s' "$ROOTFS"
2927 # SliTaz release info.
2928 rel='/etc/slitaz-release'
2929 if [ ! -f "$ROOTFS$rel" ]; then
2930 _ 'Missing release info: %s' "$rel"
2931 else
2932 action 'Release : %s' "$(cat $ROOTFS$rel)"
2933 status
2934 fi
2935 # Tazpkg mirror.
2936 if [ ! -f "$ROOTFS$LOCALSTATE/mirror" ]; then
2937 action 'Mirror URL : Missing %s' "$LOCALSTATE/mirror"
2938 todomsg
2939 else
2940 action 'Mirror configuration exists...'
2941 status
2942 fi
2943 # Isolinux msg
2944 if grep -q "cooking-XXXXXXXX" /$ROOTCD/boot/isolinux/isolinux.*g; then
2945 action 'Isolinux msg : Missing cooking date XXXXXXXX (ex %s)' "$(date +%Y%m%d)"
2946 todomsg
2947 else
2948 action 'Isolinux message seems good...'
2949 status
2950 fi
2951 footer
2952 ;;
2955 writeiso)
2956 # Writefs to ISO image including /home unlike gen-distro we don't use
2957 # packages to generate a rootfs, we build a compressed rootfs with all
2958 # the current filesystem similar to 'tazusb writefs'.
2960 DISTRO='/home/slitaz/distro'
2961 ROOTCD="$DISTRO/rootcd"
2962 COMPRESSION="${2:-none}"
2963 ISO_NAME="${3:-slitaz}"
2964 check_root
2965 # Start info
2966 title 'Write filesystem to ISO'
2967 longline "The command writeiso will write the current filesystem into a \
2968 suitable cpio archive (rootfs.gz) and generate a bootable ISO image (slitaz.iso)."
2969 newline
2970 emsg "<b>Archive compression:</b> <c 36>$COMPRESSION</c>"
2972 [ "$COMPRESSION" == 'gzip' ] && colorize 31 "gzip-compressed rootfs unsupported and may fail to boot"
2973 # Save some space
2974 rm -rf /var/cache/tazpkg/*
2975 rm -f /var/lib/tazpkg/*.bak
2976 rm -rf $DISTRO
2978 # Optionally remove sound card selection and screen resolution.
2979 if [ -z $LaunchedByTazpanel ]; then
2980 anser=$(yesorno 'Do you wish to remove the sound card and screen configs?' 'n')
2981 case $anser in
2982 y)
2983 action 'Removing current sound card and screen configurations...'
2984 rm -f /var/lib/sound-card-driver
2985 rm -f /var/lib/alsa/asound.state
2986 rm -f /etc/X11/xorg.conf ;;
2987 *)
2988 action 'Keeping current sound card and screen configurations...' ;;
2989 esac
2990 status
2991 newline
2993 # Optionally remove i18n settings
2994 anser=$(yesorno 'Do you wish to remove locale/keymap settings?' 'n')
2995 case $anser in
2996 y)
2997 action 'Removing current locale/keymap settings...'
2998 newline > /etc/locale.conf
2999 newline > /etc/keymap.conf ;;
3000 *)
3001 action 'Keeping current locale/keymap settings...' ;;
3002 esac
3003 status
3004 fi
3006 # Clean-up files by default
3007 newline > /etc/udev/rules.d/70-persistent-net.rules
3008 newline > /etc/udev/rules.d/70-persistant-cd.rules
3010 # Create list of files including default user files since it is defined in /etc/passwd
3011 # and some new users might have been added.
3012 cd /
3013 echo 'init' > /tmp/list
3014 for dir in bin etc sbin var dev lib root usr home opt; do
3015 [ -d $dir ] && find $dir
3016 done >> /tmp/list
3018 for dir in proc sys tmp mnt media media/cdrom media/flash media/usbdisk run run/udev; do
3019 [ -d $dir ] && echo $dir
3020 done >> /tmp/list
3022 sed '/var\/run\/.*pid$/d ; /var\/run\/utmp/d ; /.*\/.gvfs/d ; /home\/.*\/.cache\/.*/d' -i /tmp/list
3024 #if [ ! $(find /var/log/slitaz/tazpkg.log -size +4k) = "" ]; then
3025 # sed -i "/var\/log\/slitaz\/tazpkg.log/d" /tmp/list
3026 #fi
3027 mv -f /var/log/wtmp /tmp/tazlito-wtmp
3028 touch /var/log/wtmp
3030 for removelog in auth boot messages dmesg daemon slim .*old Xorg tazpanel cups; do
3031 sed -i "/var\/log\/$removelog/d" /tmp/list
3032 done
3034 # Generate initramfs with specified compression and display rootfs
3035 # size in realtime.
3036 rm -f /tmp/.write-iso* /tmp/rootfs 2>/dev/null
3038 write_initramfs &
3039 sleep 2
3040 cd - > /dev/null
3041 echo -en "\nFilesystem size:"
3042 while [ ! -f /tmp/rootfs ]; do
3043 sleep 1
3044 echo -en "\\033[18G$(du -sh /$INITRAMFS | awk '{print $1}') "
3045 done
3046 mv -f /tmp/tazlito-wtmp /var/log/wtmp
3047 echo -e "\n"
3048 rm -f /tmp/rootfs
3050 # Move freshly generated rootfs to the cdrom.
3051 mkdir -p $ROOTCD/boot
3052 mv -f /$INITRAMFS $ROOTCD/boot
3053 _ 'Located in: %s' "$ROOTCD/boot/$INITRAMFS"
3055 # Now we need the kernel and isolinux files.
3056 copy_from_cd() {
3057 cp /media/cdrom/boot/bzImage* $ROOTCD/boot
3058 cp -a /media/cdrom/boot/isolinux $ROOTCD/boot
3059 unmeta_boot $ROOTCD
3060 umount /media/cdrom
3063 if mount /dev/cdrom /media/cdrom 2>/dev/null; then
3064 copy_from_cd;
3065 elif mount | grep /media/cdrom; then
3066 copy_from_cd;
3067 #elif [ -f "$bootloader" -a -f /boot/vmlinuz*slitaz* ]; then
3068 # [ -f /boot/*slitaz ] && cp /boot/vmlinuz*slitaz $ROOTCD/boot/bzImage
3069 # [ -f /boot/*slitaz64 ] && cp /boot/vmlinuz*slitaz64 $ROOTCD/boot/bzImage64
3070 else
3071 touch /tmp/.write-iso-error
3072 longline "When SliTaz is running in RAM the kernel and bootloader \
3073 files are kept on the CD-ROM. `boldify ' Please insert a Live CD or run:
3074 # mount -o loop slitaz.iso /media/cdrom ' ` to let Tazlito copy the files."
3075 echo -en "----\nENTER to continue..."; read i
3076 [ ! -d /media/cdrom/boot/isolinux ] && exit 1
3077 copy_from_cd
3078 fi
3080 # Generate the iso image.
3081 touch /tmp/.write-iso
3082 newline
3083 cd $DISTRO
3084 create_iso $ISO_NAME.iso $ROOTCD
3085 action 'Creating the ISO md5sum...'
3086 md5sum $ISO_NAME.iso > $ISO_NAME.md5
3087 status
3089 footer "ISO image: $(du -sh $DISTRO/$ISO_NAME.iso)"
3090 rm -f /tmp/.write-iso
3092 if [ -z $LaunchedByTazpanel ]; then
3093 anser=$(yesorno 'Burn ISO to CD-ROM?' 'n')
3094 case $anser in
3095 y)
3096 umount /dev/cdrom 2>/dev/null
3097 eject
3098 echo -n "Please insert a blank CD-ROM and press ENTER..."
3099 read i && sleep 2
3100 tazlito burn-iso $DISTRO/$ISO_NAME.iso
3101 echo -en "----\nENTER to continue..."; read i ;;
3102 *)
3103 exit 0 ;;
3104 esac
3105 fi
3106 ;;
3109 burn-iso)
3110 # Guess CD-ROM device, ask user and burn the ISO.
3112 check_root
3113 DRIVE_NAME=$(grep "drive name" /proc/sys/dev/cdrom/info | cut -f3)
3114 DRIVE_SPEED=$(grep "drive speed" /proc/sys/dev/cdrom/info | cut -f3)
3115 # We can specify an alternative ISO from the cmdline.
3116 iso="${2:-$DISTRO/$ISO_NAME.iso}"
3117 [ ! -f "$iso" ] && die "Unable to find ISO: $iso"
3119 title 'Tazlito burn ISO'
3120 echo "CD-ROM device : /dev/$DRIVE_NAME"
3121 echo "Drive speed : $DRIVE_SPEED"
3122 echo "ISO image : $iso"
3123 footer
3125 case $(yesorno 'Burn ISO image?' 'n') in
3126 y)
3127 title 'Starting Wodim to burn the ISO...'
3128 sleep 2
3129 wodim speed=$DRIVE_SPEED dev=/dev/$DRIVE_NAME $iso
3130 footer 'ISO image is burned to CD-ROM.'
3131 ;;
3132 *)
3133 die 'Exiting. No ISO burned.'
3134 ;;
3135 esac
3136 ;;
3139 merge)
3140 # Merge multiple rootfs into one iso.
3142 if [ -z "$2" ]; then
3143 cat <<EOT
3144 Usage: tazlito merge size1 iso size2 rootfs2 [sizeN rootfsN]...
3146 Merge multiple rootfs into one ISO. Rootfs are like russian dolls
3147 i.e: rootfsN is a subset of rootfsN-1
3148 rootfs1 is found in ISO, sizeN is the RAM size needed to launch rootfsN.
3149 The boot loader will select the rootfs according to the RAM size detected.
3151 Example:
3152 $ tazlito merge 160M slitaz-core.iso 96M rootfs-justx.gz 32M rootfs-base.gz
3154 Will start slitaz-core with 160M+ RAM, slitaz-justX with 96M-160M RAM,
3155 slitaz-base with 32M-96M RAM and display an error message if RAM < 32M.
3157 EOT
3158 exit 2
3159 fi
3161 shift # skip merge
3162 append="$1 slitaz1"
3163 shift # skip size1
3164 mkdir -p $TMP_DIR/mnt $TMP_DIR/rootfs1
3166 ISO=$1.merged
3168 # Extract filesystems
3169 action 'Mounting %s' "$1"
3170 mount -o loop,ro $1 $TMP_DIR/mnt 2> /dev/null
3171 status || cleanup_merge
3173 cp -a $TMP_DIR/mnt $TMP_DIR/iso
3174 make_bzImage_hardlink $TMP_DIR/iso/boot
3175 umount -d $TMP_DIR/mnt
3176 if [ -f $TMP_DIR/iso/boot/rootfs1.gz ]; then
3177 _ '%s is already a merged iso. Aborting.' "$1"
3178 cleanup_merge
3179 fi
3180 if [ ! -f $TMP_DIR/iso/boot/isolinux/ifmem.c32 -a
3181 ! -f $TMP_DIR/iso/boot/isolinux/c32box.c32 ]; then
3182 if [ ! -f /boot/isolinux/ifmem.c32 -a
3183 ! -f /boot/isolinux/c32box.c32 ]; then
3184 cat <<EOT
3185 No file /boot/isolinux/ifmem.c32
3186 Please install syslinux package !
3187 EOT
3188 rm -rf $TMP_DIR
3189 exit 1
3190 fi
3191 cp /boot/isolinux/c32box.c32 $TMP_DIR/iso/boot/isolinux 2> /dev/null ||
3192 cp /boot/isolinux/ifmem.c32 $TMP_DIR/iso/boot/isolinux
3193 fi
3195 action 'Extracting %s' 'iso/rootfs.gz'
3196 extract_rootfs $TMP_DIR/iso/boot/rootfs.gz $TMP_DIR/rootfs1 &&
3197 [ -d $TMP_DIR/rootfs1/etc ]
3198 status || cleanup_merge
3200 n=1
3201 while [ -n "$2" ]; do
3202 shift # skip rootfs N-1
3203 p=$n
3204 n=$(($n + 1))
3205 append="$append $1 slitaz$n"
3206 shift # skip size N
3207 mkdir -p $TMP_DIR/rootfs$n
3209 action 'Extracting %s' "$1"
3210 extract_rootfs $1 $TMP_DIR/rootfs$n &&
3211 [ -d "$TMP_DIR/rootfs$n/etc" ]
3212 status || cleanup_merge
3214 mergefs $TMP_DIR/rootfs$n $TMP_DIR/rootfs$p
3215 action 'Creating %s' "rootfs$p.gz"
3216 pack_rootfs "$TMP_DIR/rootfs$p" "$TMP_DIR/iso/boot/rootfs$p.gz"
3217 status
3218 done
3219 action 'Creating %s' "rootfs$n.gz"
3220 pack_rootfs "$TMP_DIR/rootfs$n" "$TMP_DIR/iso/boot/rootfs$n.gz"
3221 status
3222 rm -f $TMP_DIR/iso/boot/rootfs.gz
3223 update_bootconfig $TMP_DIR/iso/boot/isolinux "$append"
3224 create_iso $ISO $TMP_DIR/iso
3225 rm -rf $TMP_DIR
3226 ;;
3229 repack)
3230 # Repack an iso with maximum lzma compression ratio.
3232 ISO=$2
3233 mkdir -p $TMP_DIR/mnt
3235 # Extract filesystems
3236 action 'Mounting %s' "$ISO"
3237 mount -o loop,ro $ISO $TMP_DIR/mnt 2>/dev/null
3238 status || cleanup_merge
3240 cp -a $TMP_DIR/mnt $TMP_DIR/iso
3241 umount -d $TMP_DIR/mnt
3243 for i in $TMP_DIR/iso/boot/rootfs* ; do
3244 action 'Repacking %s' "$(basename $i)"
3245 uncompress $i 2>/dev/null > $TMP_DIR/rootfs
3246 lzma e $TMP_DIR/rootfs $i $(lzma_switches $TMP_DIR/rootfs)
3247 align_to_32bits $i
3248 status
3249 done
3251 create_iso $ISO $TMP_DIR/iso
3252 rm -rf $TMP_DIR
3253 ;;
3256 build-loram)
3257 # Build a Live CD for low RAM systems.
3259 ISO="$2"
3260 OUTPUT="$3"
3261 [ -z "$3" ] && \
3262 die "Usage: tazlito build-loram <input>.iso <output>.iso [cdrom|smallcdrom|http|ram]"
3263 mkdir -p "$TMP_DIR/iso"
3264 mount -o loop,ro -t iso9660 "$ISO" "$TMP_DIR/iso"
3265 loopdev=$( (losetup -a 2>/dev/null || losetup) | sed "/$(echo $ISO | sed 's|/|\\/|g')$/!d;s/:.*//;q")
3266 if ! check_iso_for_loram ; then
3267 umount -d "$TMP_DIR/iso"
3268 die "$ISO is not a valid SliTaz live CD. Abort."
3269 fi
3270 case "$4" in
3271 cdrom) build_loram_cdrom ;;
3272 http) build_loram_http ;;
3273 *) build_loram_ram "$5" ;;
3274 esac
3275 umount $TMP_DIR/iso # no -d: needs /proc
3276 losetup -d $loopdev
3277 rm -rf $TMP_DIR
3278 ;;
3281 emu-iso)
3282 # Emulate an ISO image with Qemu.
3283 iso="${2:-$DISTRO/$ISO_NAME.iso}"
3284 [ -f "$iso" ] || die "Unable to find ISO file '$iso'."
3285 [ -x '/usr/bin/qemu' ] || die "Unable to find Qemu binary. Please install package 'qemu'."
3286 echo -e "\nStarting Qemu emulator:\n"
3287 echo -e "qemu $QEMU_OPTS $iso\n"
3288 qemu $QEMU_OPTS $iso
3289 ;;
3292 deduplicate)
3293 # Deduplicate files in a tree
3294 shift
3295 deduplicate "$@"
3296 ;;
3299 usage|*)
3300 # Print usage also for all unknown commands.
3301 usage
3302 ;;
3303 esac
3305 exit 0