tazlito view tazlito @ rev 507

Do not use efi shell
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sat Jun 02 15:45:33 2018 +0200 (2018-06-02)
parents 15343f90d12e
children 8b6be2b2d776
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 b=${i/\/efi\//\/}
1268 cmp $i ${b%.efi} || continue
1269 rm -f $i
1270 case "$i" in
1271 *vmlinuz*) rm -f $(dirname $i)/linux.cmdline ;;
1272 esac
1273 rmdir $1/efi/boot && rmdir $1/efi
1274 done 2> /dev/null
1278 # Build initial rootfs for loram ISO ram/cdrom/http
1280 build_initfs() {
1281 urliso="mirror.switch.ch/ftp/mirror/slitaz \
1282 download.tuxfamily.org/slitaz mirror1.slitaz.org mirror2.slitaz.org \
1283 mirror3.slitaz.org mirror.slitaz.org"
1284 version=$(ls $TMP_DIR/iso/boot/vmlinuz-* | sed 's/.*vmlinuz-//')
1285 [ -z "$version" ] && die "Can't find the kernel version." \
1286 'No file /boot/vmlinuz-<version> in ISO image. Abort.'
1288 [ -s /usr/share/boot/busybox-static ] || install_package busybox-static
1289 need_lib=false
1290 for i in bin dev run mnt proc tmp sys lib/modules; do
1291 mkdir -p $TMP_DIR/initfs/$i
1292 done
1293 ln -s bin $TMP_DIR/initfs/sbin
1294 ln -s . $TMP_DIR/initfs/usr
1295 for aufs in aufs overlayfs; do
1296 [ -f /lib/modules/$version/kernel/fs/$aufs/$aufs.ko.?z ] && break
1297 install_package linux-$aufs $version && break
1298 install_package $aufs $version && break
1299 done || return 1
1300 [ -s /init ] || install_package slitaz-boot-scripts
1301 cp /init $TMP_DIR/initfs/
1302 cp /lib/modules/$version/kernel/fs/$aufs/$aufs.ko.?z \
1303 $TMP_DIR/initfs/lib/modules
1304 if [ "$1" == 'cdrom' ]; then
1305 sed -i '/mod squashfs/d' $TMP_DIR/initfs/init
1306 else
1307 [ ! -f /usr/sbin/mksquashfs ] && ! install_package squashfs && return 1
1308 while [ ! -f /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z ]; do
1309 install_package linux-squashfs $version || return 1
1310 done
1311 cp /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z \
1312 $TMP_DIR/initfs/lib/modules
1313 #ls /sbin/unsquashfs /usr/lib/liblzma.so* $INSTALLED/squashfs/* | \
1314 #cpio -o -H newc > $TMP_DIR/initfs/extractfs.cpio
1315 fi
1316 if [ "$1" == 'http' ]; then
1317 mkdir $TMP_DIR/initfs/etc $TMP_DIR/fs
1318 ln -s /proc/mounts $TMP_DIR/initfs/etc/mtab
1319 cp /usr/share/udhcpc/default.script $TMP_DIR/initfs/lib/udhcpc
1320 sed -i 's|/sbin/||;s/^logger/#&/' $TMP_DIR/initfs/lib/udhcpc
1321 cp -a /dev/fuse $TMP_DIR/initfs/dev
1322 if ! $need_lib && [ -x /usr/share/boot/fusermount-static ]; then
1323 cp /usr/share/boot/fusermount-static $TMP_DIR/initfs/bin/fusermount
1324 else
1325 need_lib=true
1326 fi
1327 if ! $need_lib && [ -x /usr/share/boot/httpfs-static ]; then
1328 cp /usr/share/boot/httpfs-static $TMP_DIR/initfs/bin/httpfs
1329 else
1330 [ ! -f /usr/bin/httpfs ] && ! install_package httpfs-fuse && return 1
1331 cp /usr/bin/httpfs $TMP_DIR/initfs/bin
1332 cp /usr/bin/fusermount $TMP_DIR/initfs/bin
1333 cp -a /lib/librt* $TMP_DIR/initfs/lib
1334 cp -a /lib/libdl* $TMP_DIR/initfs/lib
1335 cp -a /lib/libpthread* $TMP_DIR/initfs/lib
1336 cp -a /usr/lib/libfuse* $TMP_DIR/initfs/lib
1337 cp -a /lib/libresolv* $TMP_DIR/initfs/lib
1338 cp -a /lib/libnss_dns* $TMP_DIR/initfs/lib
1339 need_lib=true
1340 fi
1341 cd $TMP_DIR/fs
1342 echo 'Getting slitaz-release & ethernet modules...'
1343 for i in $(ls -r $TMP_DIR/iso/boot/rootfs*z); do
1344 uncompress $i | cpio -idmu etc/slitaz-release lib/modules rootfs*
1345 [ -s rootfs* ] || continue
1346 unsquashfs -f -d . rootfs* rootfs* etc/slitaz-release lib/modules &&
1347 rm -f rootfs*
1348 done 2>&1 > /dev/null
1349 cd - > /dev/null
1350 cp $TMP_DIR/fs/etc/slitaz-release $TMP_DIR/initfs/etc/
1351 find $TMP_DIR/fs/lib/modules/*/kernel/drivers/net/ethernet \
1352 -type f -name '*.ko*' | while read mod; do
1353 f=$TMP_DIR/initfs/lib/modules/$(basename $mod | sed s/..z$//)
1354 uncompress $mod > $f
1355 grep -q alias=pci: $f || rm -f $f
1356 done
1357 for i in $TMP_DIR/initfs/lib/modules/*.ko ; do
1358 f=$(basename $i)..z
1359 grep -q $f:$ $TMP_DIR/fs/lib/modules/*/modules.dep && continue
1360 deps="$(grep $f: $TMP_DIR/fs/lib/modules/*/modules.dep | sed 's/.*: //')"
1361 echo "$deps" | sed 's|kernel/[^ ]*/||g;s/.ko..z//g' > $TMP_DIR/initfs/lib/modules/$(basename $i .ko).dep
1362 for j in $deps; do
1363 mod=$(ls $TMP_DIR/fs/lib/modules/*/$j)
1364 uncompress $mod > $TMP_DIR/initfs/lib/modules/$(basename $j | sed s/..z$//)
1365 done
1366 done
1367 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"
1368 _n 'List of URLs to insert: '
1369 read -t 30 urliso2
1370 urliso="$urliso2 $urliso"
1371 fi
1372 if ! $need_lib && [ -x /usr/share/boot/busybox-static ]; then
1373 cp /usr/share/boot/busybox-static $TMP_DIR/initfs/bin/busybox
1374 sed -i 's/LD_T.*ot/echo/;s/".*ld-.*) /"/' $TMP_DIR/initfs/init
1375 else
1376 cp /bin/busybox $TMP_DIR/initfs/bin
1377 if ! cmp /bin/busybox /sbin/insmod > /dev/null ; then
1378 cp /sbin/insmod $TMP_DIR/initfs/bin
1379 cp -a /lib/libkmod.so.* $TMP_DIR/initfs/lib
1380 cp -a /usr/lib/liblzma.so.* $TMP_DIR/initfs/lib
1381 cp -a /usr/lib/libz.so.* $TMP_DIR/initfs/lib
1382 fi
1383 need_lib=true
1384 fi
1385 for i in $($TMP_DIR/initfs/bin/busybox | awk \
1386 '{ if (s) printf "%s",$0 } /Currently/ { s=1 }' | sed 's/,//g'); do
1387 ln $TMP_DIR/initfs/bin/busybox $TMP_DIR/initfs/bin/$i
1388 done
1389 # bootfloppybox will need floppy.ko.?z, /dev/fd0, /dev/tty0
1390 cp /lib/modules/$version/kernel/drivers/block/floppy.ko.?z \
1391 $TMP_DIR/initfs/lib/modules 2>/dev/null
1392 for i in /dev/console /dev/null /dev/tty /dev/tty0 /dev/zero \
1393 /dev/kmem /dev/mem /dev/random /dev/urandom; do
1394 cp -a $i $TMP_DIR/initfs/dev
1395 done
1396 grep -q '/sys/block/./dev' $TMP_DIR/initfs/init ||
1397 for i in /dev/fd0 /dev/[hs]d[a-f]* /dev/loop* ; do
1398 cp -a $i $TMP_DIR/initfs/dev
1399 done 2>/dev/null
1400 $need_lib && for i in /lib/ld-* /lib/lib[cm][-\.]* ; do
1401 cp -a $i $TMP_DIR/initfs/lib
1402 done
1403 [ "$1" == 'http' ] && cat > $TMP_DIR/initfs/init <<EOTEOT
1404 #!/bin/sh
1406 getarg() {
1407 grep -q " \$1=" /proc/cmdline || return 1
1408 eval \$2=\$(sed "s/.* \$1=\\\\([^ ]*\\\\).*/\\\\1/" < /proc/cmdline)
1409 return 0
1412 copy_rootfs() {
1413 total=\$(grep MemTotal /proc/meminfo | sed 's/[^0-9]//g')
1414 need=\$(du -c \${path}rootfs* | tail -n 1 | cut -f1)
1415 [ \$(( \$total / \$need )) -gt 1 ] || return 1
1416 if ! grep -q " keep-loram" /proc/cmdline && cp \${path}rootfs* /mnt; then
1417 path=/mnt/
1418 return 0
1419 else
1420 rm -f /mnt/rootfs*
1421 return 1
1422 fi
1425 echo "Switching / to tmpfs..."
1426 mount -t proc proc /proc
1427 size="\$(grep rootfssize= < /proc/cmdline | \\
1428 sed 's/.*rootfssize=\\([0-9]*[kmg%]\\).*/-o size=\\1/')"
1429 [ -n "\$size" ] || size="-o size=90%"
1431 mount -t sysfs sysfs /sys
1432 for i in /lib/modules/*.ko ; do
1433 echo -en "Probe \$i \\r"
1434 for j in \$(grep alias=pci: \$i | sed 's/alias//;s/\*/.*/g'); do
1435 grep -q "\$j" /sys/bus/pci/devices/*/uevent || continue
1436 for k in \$(cat \${i/ko/dep} 2> /dev/null); do
1437 insmod /lib/modules/\$k.ko 2> /dev/null
1438 done
1439 echo "Loading \$i"
1440 insmod \$i 2> /dev/null
1441 break
1442 done
1443 done
1444 umount /sys
1445 while read var default; do
1446 eval \$var=\$default
1447 getarg \$var \$var
1448 done <<EOT
1449 eth eth0
1450 dns 208.67.222.222,208.67.220.220
1451 netmask 255.255.255.0
1452 gw
1453 ip
1454 EOT
1455 grep -q \$eth /proc/net/dev || sh
1456 if [ -n "\$ip" ]; then
1457 ifconfig \$eth \$ip netmask \$netmask up
1458 route add default gateway \$gw
1459 for i in \$(echo \$dns | sed 's/,/ /g'); do
1460 echo "nameserver \$i" >> /etc/resolv.conf
1461 done
1462 else
1463 udhcpc -f -q -s /lib/udhcpc -i \$eth
1464 fi
1465 for i in $urliso ; do
1466 [ -n "\$URLISO" ] && URLISO="\$URLISO,"
1467 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"
1468 URLISO="\$URLISO,http://\$i/iso/rolling/slitaz-rolling-loram-cdrom.iso,http://\$i/iso/rolling/slitaz-rolling-loram.iso"
1469 done
1470 getarg urliso URLISO
1471 DIR=fs
1472 if getarg loram DIR; then
1473 DEVICE=\${DIR%,*}
1474 DIR=/\${DIR#*,}
1475 fi
1476 mount -t tmpfs \$size tmpfs /mnt
1477 path2=/mnt/.httpfs/
1478 path=/mnt/.cdrom/
1479 mkdir -p /mnt/.rw /mnt/.wd \$path \$path2
1480 while [ ! -d \$path/boot ]; do
1481 for i in \$(echo \$URLISO | sed 's/,/ /g'); do
1482 httpfs \$i \$path2 && echo \$i && break
1483 done
1484 mount -o loop,ro -t iso9660 \$path2/*.iso \$path || sh
1485 done
1487 memfree=\$(grep MemFree /proc/meminfo | sed 's/[^0-9]//g')
1488 umount /proc
1489 branch=:/mnt/.cdrom/\$DIR
1490 if [ ! -d /mnt/.cdrom/\$DIR/etc ]; then
1491 branch=
1492 lp=1
1493 insmod /lib/modules/squashfs.ko 2> /dev/null
1494 for i in \${path}boot/rootfs?.* ; do
1495 fs=\${i#*root}
1496 branch=\$branch:/mnt/.\$fs
1497 mkdir -p /mnt/.rw/mnt/.\$fs /mnt/.\$fs /mnt/.rw/mnt/.cdrom
1498 losetup -o 124 /dev/loop\$lp \$i
1499 mount -o loop,ro -t squashfs /dev/loop\$lp /mnt/.\$fs
1500 lp=\$((\$lp+1))
1501 done
1502 fi
1503 mkdir -p /mnt/.rw/mnt/.httpfs
1504 while read type opt; do
1505 insmod /lib/modules/\$type.ko && mount -t \$type -o \$opt none /mnt && break
1506 done <<EOT
1507 aufs br=/mnt/.rw\$branch
1508 overlayfs workdir=/mnt/.wd\${branch/:/,lowerdir=},upperdir=/mnt/.rw
1509 EOT
1510 rm -rf /lib/modules
1511 [ -x /bin/httpfs ] && sed -i 's/DHCP="yes"/DHCP="no"/' /mnt/etc/network.conf
1512 [ \$memfree -lt 30000 ] && sed -i 's/ slim//' /mnt/etc/rcS.conf
1513 [ -x /mnt/sbin/init ] && exec /bin/switch_root mnt /sbin/init || sh
1514 EOTEOT
1515 chmod +x $TMP_DIR/initfs/init
1516 for i in $TMP_DIR/initfs/lib/modules/*z ; do
1517 unxz $i || gunzip $i || lzma d $i ${i%.gz}
1518 rm -f $i
1519 done 2>/dev/null
1520 (cd $TMP_DIR/initfs; find | busybox cpio -o -H newc 2>/dev/null) | \
1521 lzma e $TMP_DIR/initfs.gz -si
1522 lzma_set_size $TMP_DIR/initfs.gz
1523 rm -rf $TMP_DIR/initfs
1524 align_to_32bits $TMP_DIR/initfs.gz
1525 return 0
1529 # Move each initramfs to squashfs
1531 build_loram_rootfs() {
1532 rootfs_sizes=""
1533 for i in $TMP_DIR/iso/boot/rootfs*; do
1534 mkdir -p $TMP_DIR/fs
1535 cd $TMP_DIR/fs
1536 uncompress $i | cpio -idm
1537 deduplicate
1538 cd - > /dev/null
1539 rootfs=$TMP_DIR/$(basename $i)
1540 /usr/sbin/mksquashfs $TMP_DIR/fs $rootfs -comp ${1:-xz -Xbcj x86}
1541 cd $TMP_DIR
1542 rootfs_sizes="$rootfs_sizes $(( $(du -s $TMP_DIR/fs | cut -f1) - $(du -s $rootfs | cut -f1) ))"
1543 ( cd $(dirname $rootfs); echo $(basename $rootfs) | cpio -o -H newc ) > $rootfs.cpio
1544 rm -f $rootfs
1545 mv $rootfs.cpio $rootfs
1546 cd - > /dev/null
1547 rm -rf $TMP_DIR/fs
1548 done
1552 # Move meta boot configuration files to basic configuration files
1553 # because meta loram flavor is useless when rootfs is not loaded in RAM
1555 unmeta_boot() {
1556 local root=${1:-$TMP_DIR/loramiso}
1557 if [ -f $root/boot/isolinux/noram.cfg ]; then
1558 # We keep enough information to do unloram...
1559 [ -s $root/boot/isolinux/common.cfg ] &&
1560 sed -i 's/label slitaz/label orgslitaz/' \
1561 $root/boot/isolinux/common.cfg
1562 set -- $(grep 'append ifmem [0-9]' $root/boot/isolinux/isolinux.cfg)
1563 shift
1564 sed -i '/ifmem/{NNNNNNNNd};/^LABEL/{N;/LABEL SliTaz [^L]/{NNNd}}' \
1565 $root/boot/isolinux/isolinux.cfg
1566 [ -n "$3" ] || set -- $(grep 'append [0-9]' $root/boot/isolinux/common.cfg)
1567 sed -i "s/label $3\$/label slitaz/;s|=\(.*rootfs\)\(.*\)\.gz |=\1.gz |" \
1568 $root/boot/isolinux/*.cfg
1569 fi
1573 # Move rootfs to squashfs filesystem(s) to the cdrom writeable with aufs/overlayfs.
1574 # These squashfs may be loaded in RAM at boot time.
1575 # Rootfs are also copied to CD-ROM for tiny ramsize systems.
1576 # Meta flavors are converted to normal flavors.
1578 build_loram_cdrom() {
1579 build_initfs cdrom || return 1
1580 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1581 cleanup_efi_boot $TMP_DIR/loramiso
1582 mkdir $TMP_DIR/loramiso/fs
1583 cd $TMP_DIR/loramiso/fs
1584 for i in $( ls ../boot/root* | sort -r ) ; do
1585 uncompress $i | cpio -idmu
1586 rm -f $i
1587 done
1588 mkdir -p $TMP_DIR/loramiso/fs/mnt/.cdrom
1589 cd - >/dev/null
1590 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1591 unmeta_boot
1592 VOLUM_NAME="SliTaz_LoRAM_CDROM"
1593 sed -i "s|root=|isofs= rodev=/dev/cdrom/fs &|;s/.ive/cdrom/" \
1594 $TMP_DIR/loramiso/boot/isolinux/*.cfg
1595 sed -i '/LABEL slitaz/{NNNNp;s|z cdrom|& text|;s|L slitaz|&text|;s|root=|screen=text &|;s|,[^ ]*||}' \
1596 $TMP_DIR/loramiso/boot/isolinux/*.cfg
1597 create_iso $OUTPUT $TMP_DIR/loramiso
1601 # Create http bootstrap to load and remove loram_cdrom
1602 # Meta flavors are converted to normal flavors.
1604 build_loram_http() {
1605 build_initfs http || return 1
1606 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1607 cleanup_efi_boot $TMP_DIR/loramiso
1608 rm -f $TMP_DIR/loramiso/boot/rootfs*
1609 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1610 unmeta_boot
1611 create_iso $OUTPUT $TMP_DIR/loramiso
1615 # Update meta flavor selection sizes.
1616 # Reduce sizes with rootfs gains.
1618 update_metaiso_sizes() {
1619 for cfg in $(grep -El '(append|ifmem) [0-9]' $TMP_DIR/loramiso/boot/isolinux/*.cfg)
1620 do
1621 local append="$(grep -E '(append|ifmem) [0-9]' $cfg)"
1622 local sizes="$rootfs_sizes"
1623 local new
1624 set -- $append
1625 shift
1626 [ "$1" == "ifmem" ] && shift
1627 new=""
1628 while [ -n "$2" ]; do
1629 local s
1630 case "$1" in
1631 *G) s=$(( ${1%G} * 1024 * 1024 ));;
1632 *M) s=$(( ${1%M} * 1024 ));;
1633 *) s=${1%K};;
1634 esac
1635 sizes=${sizes#* }
1636 for i in $sizes ; do
1637 s=$(( $s - $i ))
1638 done
1639 new="$new $s $2"
1640 shift 2
1641 done
1642 sed -i -e "/append [0-9]/s/append .*/append$new $1/" -e \
1643 "/append ifmem [0-9]/s/append .*/append ifmem$new $1/" $cfg
1644 sed -i 's|\(initrd=\)\([^r]*\)\(rootfs\)|\1\2rootfs.gz,\2\3|' $cfg
1645 sed -i '/LABEL base/{NNNNp;s|base .ive|cdrom|;s|base|cdrom|;s|,[^ ]*||}' $cfg
1646 sed -i '/LABEL cdrom/{NNNNp;s|z cdrom|& text|;s|L cdrom|&text|;s|root=|screen=text &|;s|,[^ ]*||}' $cfg
1647 done
1651 # Move rootfs to a squashfs filesystem into the initramfs writeable with aufs/overlayfs.
1652 # Meta flavor selection sizes are updated.
1654 build_loram_ram() {
1655 build_initfs ram || return 1
1656 build_loram_rootfs "$1"
1657 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1658 cleanup_efi_boot $TMP_DIR/loramiso
1659 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1660 cp $TMP_DIR/rootfs* $TMP_DIR/loramiso/boot
1661 update_metaiso_sizes
1662 create_iso $OUTPUT $TMP_DIR/loramiso
1666 # Remove files installed by packages
1668 find_flavor_rootfs() {
1669 for i in $1/etc/tazlito/*.extract; do
1670 [ -e $i ] || continue
1671 chroot $1 /bin/sh ${i#$1}
1672 done
1674 # Clean hardlinks and files patched by genisofs in /boot
1675 for i in isolinux/isolinux.bin isolinux/boot.cat bzImage ; do
1676 rm -f $1/boot/$i*
1677 done
1679 # Clean files generated in post_install
1680 rm -f $1/lib/modules/*/modules.* $1/etc/mtab \
1681 $1/dev/core $1/dev/fd $1/dev/std*
1683 # Verify md5
1684 cat $1$INSTALLED/*/md5sum | \
1685 while read md5 file; do
1686 [ -e "$1$file" ] || continue
1687 [ "$(md5sum < "$1$file")" == "$md5 -" ] &&
1688 rm -f "$1$file"
1689 done
1691 # Check configuration files
1692 for i in $1$INSTALLED/*/volatile.cpio.gz; do
1693 [ -e $i ] || continue
1694 mkdir /tmp/volatile$$
1695 zcat $i | ( cd /tmp/volatile$$ ; cpio -idmu > /dev/null 2>&1 )
1696 ( cd /tmp/volatile$$ ; find * -type f 2> /dev/null) | \
1697 while read file ; do
1698 [ -e "$1/$file" ] || continue
1699 cmp -s "/tmp/volatile$$/$file" "$1/$file" && rm -f "$1/$file"
1700 done
1701 rm -rf /tmp/volatile$$
1702 done
1704 # Remove other files blindly
1705 for i in $1$INSTALLED/*/files.list; do
1706 for file in $(cat "$i"); do
1707 [ "$1$file" -nt "$i" ] && continue
1708 [ -f "$1$file" -a ! -L "$1$file" ] && continue
1709 [ -d "$1$file" ] || rm -f "$1$file"
1710 done
1711 done
1713 # Remove tazpkg files and tmp files
1714 rm -rf $1$INSTALLED* $1/tmp $1/var/tmp
1715 rm -f $1$LOCALSTATE/*packages* $1$LOCALSTATE/files.list.lzma \
1716 $1$LOCALSTATE/mirror* $1/var/cache/*/* \
1717 $1/var/lock/* $1/var/log/* $1/var/run/* $1/var/run/*/* \
1718 $1/var/lib/* $1/var/lib/dbus/* 2>/dev/null
1720 # Cleanup directory tree
1721 cd $1
1722 find * -type d | sort -r | while read dir; do
1723 rmdir "$dir" 2>/dev/null
1724 done
1725 cd - > /dev/null
1729 # Get byte(s) from a binary file
1731 get() {
1732 od -v -j $1 -N ${3:-2} -t u${3:-2} -w${3:-2} -An $2 2>/dev/null | sed 's/ *//'
1736 # Get cpio flavor info from the ISO image
1738 flavordata() {
1739 [ $(get 1024 $1) -eq 35615 ] && n=2 || n=$((1+$(get 417 $1 1)))
1740 dd if=$1 bs=512 skip=$n count=20 2>/dev/null | zcat 2>/dev/null
1744 # Restore undigest mirrors
1746 restore_mirrors() {
1747 local undigest="$root$LOCALSTATE/undigest" priority="$root$LOCALSTATE/priority"
1748 [ -d "$undigest.bak" ] || [ -e "$priority.bak" ] || return
1750 action 'Restoring mirrors...'
1751 if [ -d "$undigest.bak" ]; then
1752 [ -d "$undigest" ] && rm -r "$undigest"
1753 mv "$undigest.bak" "$undigest"
1754 fi
1755 [ -e "$priority.bak" ] && mv -f "$priority.bak" "$priority"
1756 :; status
1760 # Setup undigest mirrors
1762 setup_mirrors() {
1763 # Setup mirrors in plain system or in chroot (with variable root=)
1764 local mirrorlist="$1" fresh repacked
1765 local undigest="$root$LOCALSTATE/undigest" priority="$root$LOCALSTATE/priority"
1767 # Restore mirrors first: in case of non-clear exits, hangs, etc.
1768 restore_mirrors
1770 _ 'Setting up mirrors for %s...' "$root/"
1771 # Backing up current undigest mirrors and priority
1772 [ -d "$undigest" ] && mv "$undigest" "$undigest.bak"
1773 [ -e "$priority" ] && mv "$priority" "$priority.bak"
1774 rm -rf '/var/www/tazlito/'
1775 mkdir -p '/var/www/tazlito/'
1777 # Packages produced by CookUtils: on Tank or local, or repacked packages: highest priority
1778 fresh='/home/slitaz/packages'
1779 if [ -d "$fresh" ]; then
1780 # Setup first undigest mirror
1781 mkdir -p "$undigest/fresh"
1782 echo "$fresh" > "$undigest/fresh/mirror"
1783 echo 'fresh' >> "$priority"
1784 # Rebuild mirror DB if needed
1785 [ ! -e "$fresh/IDs" ] && tazpkg mkdb "$fresh" --forced --root=''
1786 [ -n "$(find -L "$fresh" -name '*.tazpkg' -newer "$fresh/IDs")" ] && \
1787 tazpkg mkdb "$fresh" --forced --root=''
1788 cp -a "$fresh/files.list.lzma" "$fresh/files-list.lzma"
1789 fi
1791 # Repacked packages: high priority
1792 repacked="$PACKAGES_REPOSITORY"
1793 if [ -d "$repacked" -a "$repacked" != "$fresh" ] && ls "$repacked" | grep -q ".tazpkg"; then
1794 # According to Tazlito setup file (tazlito.conf):
1795 # WORK_DIR="/home/slitaz/$SLITAZ_VERSION"
1796 # or
1797 # WORK_DIR="/home/slitaz"
1798 # and
1799 # PACKAGES_REPOSITORY="$WORK_DIR/packages"
1800 # It MAY or MAY NOT match /home/slitaz/packages, so here we setup second repository
1802 # Setup second undigest mirror
1803 mkdir -p "$undigest/repacked"
1804 echo "$repacked" > "$undigest/repacked/mirror"
1805 echo 'repacked' >> "$priority"
1806 # Rebuild mirror DB if needed
1807 [ ! -e "$repacked/IDs" ] && tazpkg mkdb "$repacked" --forced --root=''
1808 [ -n "$(find -L "$repacked" -name '*.tazpkg' -newer "$repacked/IDs")" ] && \
1809 tazpkg mkdb "$repacked" --forced --root=''
1810 cp -a "$repacked/files.list.lzma" "$repacked/files-list.lzma"
1811 fi
1813 # All repositories listed in mirrors list: normal priority
1814 [ -e "$mirrorlist" ] && \
1815 while read mirror; do
1816 # Provide consistent mirror ID for caching purpose: /var/cache/tazpkg/<mirror ID>/packages
1817 mirrorid=$(echo "$mirror" | md5sum | cut -d' ' -f1)
1818 mkdir -p "$undigest/$mirrorid"
1819 echo "$mirror" > "$undigest/$mirrorid/mirror"
1820 echo "$mirrorid" >> "$priority"
1821 done < "$mirrorlist"
1823 # And, finally, main mirror with the lowest (failsafe) priority (nothing to do)
1825 # Show list of mirrors
1826 [ -f "$priority" ] && awk -vdb="$root$LOCALSTATE" '
1827 function show(num, name, url) {
1828 printf " %-1.1d. %32.32s %-44.44s\n", num, name " ...............................", url;
1831 num++;
1832 "cat " db "/undigest/" $0 "/mirror" | getline url;
1833 show(num, $0, url);
1835 END {
1836 num++;
1837 "cat " db "/mirror" | getline url;
1838 show(num, "main", url);
1839 }' "$priority"
1841 tazpkg recharge --quiet >/dev/null
1845 # Get list of 'packages.info' lists using priority
1847 pi_lists() {
1848 local pi
1849 [ -s "$root$LOCALSTATE/packages.info" ] || tazpkg recharge --root="$root" >/dev/null 2>&1
1850 local priority="$root$LOCALSTATE/priority"
1851 local undigest="$root$LOCALSTATE/undigest"
1854 [ -s "$priority" ] && cat "$priority"
1855 echo 'main'
1856 [ -d "$undigest" ] && ls "$undigest"
1857 } | awk -vun="$undigest/" '
1859 if (arr[$0] != 1) {
1860 arr[$0] = 1;
1861 print un $0 "/packages.info";
1863 }' | sed 's|/undigest/main||' | \
1864 while read pi; do
1865 [ -e "$pi" ] && echo "$pi"
1866 done
1870 # Strip versions from packages list
1872 strip_versions() {
1873 if [ -n "$stripped" ]; then
1874 action 'Consider list %s already stripped' "$(basename "$1")"
1875 status
1876 return 0
1877 fi
1878 action 'Strip versions from list %s...' "$(basename "$1")"
1879 local in_list="$1" tmp_list="$(mktemp)" namever pkg
1880 [ -f "$in_list" ] || die "List '$in_list' not found."
1882 # $pkg=<name>-<version> or $pkg=<name>; both <name> and <version> may contain dashes
1883 awk '
1885 if (FILENAME ~ "packages.info") {
1886 # Collect package names
1887 FS = "\t"; pkg[$1] = 1;
1888 } else {
1889 FS = OFS = "-"; $0 = $0; # Fix bug with FS for first record
1890 while (NF > 1 && ! pkg[$0])
1891 NF --;
1892 printf "%s\n", $0;
1894 }' $(pi_lists) "$in_list" > "$tmp_list"
1896 cat "$tmp_list" > "$in_list"
1897 rm "$tmp_list"
1898 status
1902 # Display list of unknown packages (informative)
1904 display_unknown() {
1905 [ -s "$1" ] || return
1906 echo "Unknown packages:" >&2
1907 cat "$1" >&2
1908 rm "$1"
1912 # Display warnings about critical packages absent (informative)
1914 display_warn() {
1915 [ -s "$1" ] || return
1916 echo "Absent critical packages:" >&2
1917 cat "$1" >&2
1918 rm "$1"
1919 echo "Probably ISO image will be unusable."
1923 # Install packages to rootfs
1925 install_list_to_rootfs() {
1926 local list="$1" rootfs="$2" pkg i ii
1927 local undigest="$rootfs/var/lib/tazpkg/undigest"
1929 # initial tazpkg setup in empty rootfs
1930 tazpkg --root=$rootfs >/dev/null 2>&1
1931 # pass current 'mirror' to the rootfs
1932 mkdir -p $rootfs/var/lib/tazpkg $rootfs/etc
1933 cp -f /var/lib/tazpkg/mirror $rootfs/var/lib/tazpkg/mirror
1934 cp -f /etc/slitaz-release $rootfs/etc/slitaz-release
1935 # link rootfs packages cache to the regular packages cache
1936 rm -r "$rootfs/var/cache/tazpkg"
1937 ln -s /var/cache/tazpkg "$rootfs/var/cache/tazpkg"
1939 setup_mirrors mirrors
1941 # Just in case if flavor doesn't contain "tazlito" package
1942 mkdir -p "$rootfs/etc/tazlito"
1944 newline
1946 # Choose detailed log with --detailed
1947 if [ -n "$detailed" ]; then
1948 while read pkg; do
1949 separator '-'
1950 echo $pkg
1951 tazpkg -gi $pkg --root=$rootfs --local --quiet --cookmode | tee -a $log
1952 done < $list
1953 separator '='
1954 else
1955 while read pkg; do
1956 action 'Installing package: %s' "$pkg"
1957 yes y | tazpkg -gi $pkg --root=$rootfs --quiet >> $log || exit 1
1958 status
1959 done < $list
1960 fi
1961 newline
1963 restore_mirrors
1964 # Remove 'fresh' and 'repacked' undigest repos leaving all other
1965 for i in fresh repacked; do
1966 ii="$undigest/$i"
1967 [ -d "$ii" ] && rm -rf "$ii"
1968 ii="$rootfs/var/lib/tazpkg/priority"
1969 if [ -f "$ii" ]; then
1970 sed -i "/$i/d" "$ii"
1971 [ -s "$ii" ] || rm "$ii"
1972 fi
1973 done
1974 [ -d "$undigest" ] && \
1975 for i in $(find "$undigest" -type f); do
1976 # Remove all undigest PKGDB files but 'mirror'
1977 [ "$(basename "$i")" != 'mirror' ] && rm "$i"
1978 done
1979 [ -d "$undigest" ] && \
1980 rmdir --ignore-fail-on-non-empty "$undigest"
1982 # Un-link packages cache
1983 rm "$rootfs/var/cache/tazpkg"
1985 # Clean /var/lib/tazpkg
1986 (cd $rootfs/var/lib/tazpkg; rm ID* descriptions.txt extra.list files* packages.* 2>/dev/null)
1992 ####################
1993 # Tazlito commands #
1994 ####################
1996 # /usr/bin/tazlito is linked with /usr/bin/reduplicate and /usr/bin/deduplicate
1997 case "$0" in
1998 *reduplicate)
1999 find ${@:-.} ! -type d -links +1 \
2000 -exec cp -a {} {}$$ \; -exec mv {}$$ {} \;
2001 exit 0 ;;
2002 *deduplicate)
2003 deduplicate "$@"
2004 exit 0 ;;
2005 esac
2008 case "$COMMAND" in
2009 stats)
2010 # Tazlito general statistics from the config file.
2012 title 'Tazlito statistics'
2013 optlist "\
2014 Config file : $CONFIG_FILE
2015 ISO name : $ISO_NAME.iso
2016 Volume name : $VOLUM_NAME
2017 Prepared : $PREPARED
2018 Packages repository : $PACKAGES_REPOSITORY
2019 Distro directory : $DISTRO
2020 Additional files : $ADDFILES
2021 " | sed '/: $/d'
2022 footer
2023 ;;
2026 list-addfiles)
2027 # Simple list of additional files in the rootfs
2028 newline
2029 if [ -d "$ADDFILES/rootfs" ]; then
2030 cd $ADDFILES
2031 find rootfs -type f
2032 else
2033 _ 'Additional files not found: %s' "$ADDFILES/rootfs/"
2034 fi
2035 newline
2036 ;;
2039 gen-config)
2040 # Generate a new config file in the current dir or the specified
2041 # directory by $2.
2043 if [ -n "$2" ]; then
2044 mkdir -p "$2" && cd "$2"
2045 fi
2047 newline
2048 action 'Generating empty tazlito.conf...'
2049 empty_config_file
2050 status
2052 separator
2053 if [ -f 'tazlito.conf' ] ; then
2054 _ 'Configuration file is ready to edit.'
2055 _ 'File location: %s' "$(pwd)/tazlito.conf"
2056 newline
2057 fi
2058 ;;
2061 configure)
2062 # Configure a tazlito.conf config file. Start by getting
2063 # a empty config file and sed it.
2065 if [ -f 'tazlito.conf' ]; then
2066 rm tazlito.conf
2067 else
2068 [ $(id -u) -ne 0 ] && die 'You must be root to configure the main config file' \
2069 'or in the same directory of the file you want to configure.'
2070 cd /etc
2071 fi
2073 empty_config_file
2075 title 'Configuring: %s' "$(pwd)/tazlito.conf"
2077 # ISO name.
2078 echo -n "ISO name : " ; read answer
2079 sed -i s#'ISO_NAME=\"\"'#"ISO_NAME=\"$answer\""# tazlito.conf
2080 # Volume name.
2081 echo -n "Volume name : " ; read answer
2082 sed -i s/'VOLUM_NAME=\"SliTaz\"'/"VOLUM_NAME=\"$answer\""/ tazlito.conf
2083 # Packages repository.
2084 echo -n "Packages repository : " ; read answer
2085 sed -i s#'PACKAGES_REPOSITORY=\"\"'#"PACKAGES_REPOSITORY=\"$answer\""# tazlito.conf
2086 # Distro path.
2087 echo -n "Distro path : " ; read answer
2088 sed -i s#'DISTRO=\"\"'#"DISTRO=\"$answer\""# tazlito.conf
2089 footer "Config file is ready to use."
2090 echo 'You can now extract an ISO or generate a distro.'
2091 newline
2092 ;;
2095 gen-iso)
2096 # Simply generate a new iso.
2098 check_root
2099 verify_rootcd
2100 gen_livecd_isolinux
2101 distro_stats
2102 ;;
2105 gen-initiso)
2106 # Simply generate a new initramfs with a new iso.
2108 check_root
2109 verify_rootcd
2110 gen_initramfs "$ROOTFS"
2111 gen_livecd_isolinux
2112 distro_stats
2113 ;;
2116 extract-distro|extract-iso)
2117 # Extract an ISO image to a directory and rebuild the LiveCD tree.
2119 check_root
2120 ISO_IMAGE="$2"
2121 [ -z "$ISO_IMAGE" ] && die 'Please specify the path to the ISO image.' \
2122 'Example:\n tazlito image.iso /path/target'
2124 # Set the distro path by checking for $3 on cmdline.
2125 TARGET="${3:-$DISTRO}"
2127 # Exit if existing distro is found.
2128 [ -d "$TARGET/rootfs" ] && die "A rootfs exists in '$TARGET'." \
2129 'Please clean the distro tree or change directory path.'
2131 title 'Tazlito extracting: %s' "$(basename $ISO_IMAGE)"
2133 # Start to mount the ISO.
2134 action 'Mounting ISO image...'
2135 mkdir -p "$TMP_DIR"
2136 # Get ISO file size.
2137 isosize=$(du -sh "$ISO_IMAGE" | cut -f1)
2138 mount -o loop -r "$ISO_IMAGE" "$TMP_DIR"
2139 sleep 2
2140 # Prepare target dir, copy the kernel and the rootfs.
2141 mkdir -p "$TARGET/rootfs" "$TARGET/rootcd/boot"
2142 status
2144 action 'Copying the Linux kernel...'
2145 if cp $TMP_DIR/boot/vmlinuz* "$TARGET/rootcd/boot" 2>/dev/null; then
2146 make_bzImage_hardlink "$TARGET/rootcd/boot"
2147 else
2148 cp "$TMP_DIR/boot/bzImage" "$TARGET/rootcd/boot"
2149 fi
2150 status
2152 for i in $(ls $TMP_DIR); do
2153 [ "$i" == 'boot' ] && continue
2154 cp -a "$TMP_DIR/$i" "$TARGET/rootcd"
2155 done
2157 for loader in isolinux syslinux extlinux grub; do
2158 [ -d "$TMP_DIR/boot/$loader" ] || continue
2159 action 'Copying %s files...' "$loader"
2160 cp -a "$TMP_DIR/boot/$loader" "$TARGET/rootcd/boot"
2161 status
2162 done
2164 action 'Copying the rootfs...'
2165 cp $TMP_DIR/boot/rootfs*.?z* "$TARGET/rootcd/boot"
2166 status
2168 cleanup_efi_boot "$TARGET/rootcd"
2170 # Extract initramfs.
2171 cd "$TARGET/rootfs"
2172 action 'Extracting the rootfs...'
2173 for i in $(ls -r $TARGET/rootcd/boot/rootfs*z); do
2174 extract_rootfs "$i" "$TARGET/rootfs"
2175 done
2176 # unpack /usr
2177 for i in etc/tazlito/*.extract; do
2178 [ -f "$i" ] && . $i ../rootcd
2179 done
2180 # Umount and remove temp directory and cd to $TARGET to get stats.
2181 umount "$TMP_DIR" && rm -rf "$TMP_DIR"
2182 cd ..
2183 status
2185 newline
2186 separator
2187 echo "Extracted : $(basename $ISO_IMAGE) ($isosize)"
2188 echo "Distro tree : $(pwd)"
2189 echo "Rootfs size : $(du -sh rootfs)"
2190 echo "Rootcd size : $(du -sh rootcd)"
2191 footer
2192 ;;
2195 list-flavors)
2196 # Show available flavors.
2197 list='/etc/tazlito/flavors.list'
2198 [ ! -s $list -o -n "$recharge" ] && download flavors.list -O - > $list
2199 title 'List of flavors'
2200 cat $list
2201 footer
2202 ;;
2205 show-flavor)
2206 # Show flavor descriptions.
2207 set -e
2208 flavor=${2%.flavor}
2209 flv_dir="$(extract_flavor "$flavor")"
2210 desc="$flv_dir/$flavor.desc"
2211 if [ -n "$brief" ]; then
2212 if [ -z "$noheader" ]; then
2213 printf "%-16.16s %6.6s %6.6s %s\n" 'Name' 'ISO' 'Rootfs' 'Description'
2214 separator
2215 fi
2216 printf "%-16.16s %6.6s %6.6s %s\n" "$flavor" \
2217 "$(field ISO "$desc")" \
2218 "$(field Rootfs "$desc")" \
2219 "$(field Description "$desc")"
2220 else
2221 separator
2222 cat "$desc"
2223 fi
2224 cleanup
2225 ;;
2228 gen-liveflavor)
2229 # Generate a new flavor from the live system.
2230 FLAVOR=${2%.flavor}
2231 [ -z "$FLAVOR" ] && die 'Please specify flavor name on the commandline.'
2233 case "$FLAVOR" in
2234 -?|-h*|--help)
2235 cat <<EOT
2236 SliTaz Live Tool - Version: $VERSION
2238 $(boldify 'Usage:') tazlito gen-liveflavor <flavor-name> [<flavor-patch-file>]
2240 $(boldify '<flavor-patch-file> format:')
2241 $(optlist "\
2242 code data
2243 + package to add
2244 - package to remove
2245 ! non-free package to add
2246 ? display message
2247 @ flavor description
2248 ")
2250 $(boldify 'Example:')
2251 $(optlist "\
2252 @ Developer tools for SliTaz maintainers
2253 + slitaz-toolchain
2254 + mercurial
2255 ")
2256 EOT
2257 exit 1
2258 ;;
2259 esac
2260 mv /etc/tazlito/distro-packages.list \
2261 /etc/tazlito/distro-packages.list.$$ 2>/dev/null
2262 rm -f distro-packages.list non-free.list 2>/dev/null
2263 tazpkg recharge
2265 DESC=""
2266 [ -n "$3" ] && \
2267 while read action pkg; do
2268 case "$action" in
2269 +) yes | tazpkg get-install $pkg 2>&1 >> $log || exit 1 ;;
2270 -) yes | tazpkg remove $pkg ;;
2271 !) echo $pkg >> non-free.list ;;
2272 @) DESC="$pkg" ;;
2273 \?) echo -en "$pkg"; read action ;;
2274 esac
2275 done < $3
2277 yes '' | tazlito gen-distro
2278 echo "$DESC" | tazlito gen-flavor "$FLAVOR"
2279 mv /etc/tazlito/distro-packages.list.$$ \
2280 /etc/tazlito/distro-packages.list 2>/dev/null
2281 ;;
2284 gen-flavor)
2285 # Generate a new flavor from the last ISO image generated
2286 FLAVOR=${2%.flavor}
2287 [ -z "$FLAVOR" ] && die 'Please specify flavor name on the commandline.'
2289 title 'Flavor generation'
2290 check_rootfs
2291 FILES="$FLAVOR.pkglist"
2293 action 'Creating file %s...' "$FLAVOR.flavor"
2294 for i in rootcd rootfs; do
2295 if [ -d "$ADDFILES/$i" ] ; then
2296 FILES="$FILES\n$FLAVOR.$i"
2297 ( cd "$ADDFILES/$i"; find . ) | cpio -o -H newc 2>/dev/null | dogzip $FLAVOR.$i
2298 fi
2299 done
2300 status
2302 answer=$(grep -s ^Description $FLAVOR.desc)
2303 answer=${answer#Description : }
2304 if [ -z "$answer" ]; then
2305 echo -n "Description: "
2306 read answer
2307 fi
2309 action 'Compressing flavor %s...' "$FLAVOR"
2310 echo "Flavor : $FLAVOR" > $FLAVOR.desc
2311 echo "Description : $answer" >> $FLAVOR.desc
2312 (cd $DISTRO; distro_sizes) >> $FLAVOR.desc
2313 \rm -f $FLAVOR.pkglist $FLAVOR.nonfree 2>/dev/null
2314 for i in $(ls $ROOTFS$INSTALLED); do
2315 eval $(grep ^VERSION= $ROOTFS$INSTALLED/$i/receipt)
2316 EXTRAVERSION=""
2317 eval $(grep ^EXTRAVERSION= $ROOTFS$INSTALLED/$i/receipt)
2318 eval $(grep ^CATEGORY= $ROOTFS$INSTALLED/$i/receipt)
2319 if [ "$CATEGORY" == 'non-free' -a "${i%%-*}" != 'get' ]; then
2320 echo "$i" >> $FLAVOR.nonfree
2321 else
2322 echo "$i-$VERSION$EXTRAVERSION" >> $FLAVOR.pkglist
2323 fi
2324 done
2325 [ -s $FLAVOR.nonfree ] && $FILES="$FILES\n$FLAVOR.nonfree"
2326 for i in $LOCALSTATE/undigest/*/mirror ; do
2327 [ -s $i ] && cat $i >> $FLAVOR.mirrors
2328 done
2329 [ -s $FLAVOR.mirrors ] && $FILES="$FILES\n$FLAVOR.mirrors"
2330 touch -t 197001010100.00 $FLAVOR.*
2331 echo -e "$FLAVOR.desc\n$FILES" | cpio -o -H newc 2>/dev/null | dogzip $FLAVOR.flavor
2332 rm $(echo -e $FILES)
2333 status
2335 footer "Flavor size: $(du -sh $FLAVOR.flavor)"
2336 ;;
2339 upgrade-flavor)
2340 # Strip versions from pkglist and update estimated numbers in flavor.desc
2341 flavor="${2%.flavor}"
2342 set -e
2343 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2344 set +e
2346 flv_dir="$(extract_flavor "$flavor")"
2348 strip_versions "$flv_dir/$flavor.pkglist"
2350 action 'Updating %s...' "$flavor.desc"
2352 [ -f "$flv_dir/$flavor.mirrors" ] && setup_mirrors "$flv_dir/$flavor.mirrors" >/dev/null
2353 set -- $(module calc_sizes "$flv_dir" "$flavor")
2354 restore_mirrors >/dev/null
2356 sed -i -e '/Image is ready/d' \
2357 -e "s|\(Rootfs size *:\).*$|\1 $1 (estimated)|" \
2358 -e "s|\(Initramfs size *:\).*$|\1 $2 (estimated)|" \
2359 -e "s|\(ISO image size *:\).*$|\1 $3 (estimated)|" \
2360 -e "s|\(Packages *:\).*$|\1 $4|" \
2361 -e "s|\(Build date *:\).*$|\1 $(date '+%Y%m%d at %T')|" \
2362 "$flv_dir/$flavor.desc"
2364 pack_flavor "$flv_dir" "$flavor"
2365 status
2366 display_unknown "$flv_dir/err"
2367 display_warn "$flv_dir/warn"
2368 cleanup
2369 ;;
2372 extract-flavor)
2373 # Extract a flavor into $FLAVORS_REPOSITORY
2374 flavor="${2%.flavor}"
2375 set -e
2376 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2377 set +e
2379 action 'Extracting %s...' "$flavor.flavor"
2380 flv_dir="$(extract_flavor "$flavor" full)"
2381 storage="$FLAVORS_REPOSITORY/$flavor"
2383 rm -rf "$storage" 2>/dev/null
2384 mkdir -p "$storage"
2385 cp -a "$flv_dir"/* "$storage"
2386 rm "$storage/description"
2387 status
2389 strip_versions "$storage/packages.list"
2391 cleanup
2392 ;;
2395 pack-flavor)
2396 # Create a flavor from $FLAVORS_REPOSITORY.
2397 flavor=${2%.flavor}
2398 storage="$FLAVORS_REPOSITORY/$flavor"
2400 [ -s "$storage/receipt" ] || die "No $flavor receipt in $FLAVORS_REPOSITORY."
2402 action 'Creating flavor %s...' "$flavor"
2403 tmp_dir="$(mktemp -d)"
2405 while read from to; do
2406 [ -s "$storage/$from" ] || continue
2407 cp -a "$storage/$from" "$tmp_dir/$to"
2408 done <<EOT
2409 mirrors $flavor.mirrors
2410 distro.sh $flavor-distro.sh
2411 receipt $flavor.receipt
2412 non-free.list $flavor.nonfree
2413 EOT
2415 # Build the package list.
2416 # It can include a list from another flavor with the keyword @include
2417 if [ -s "$storage/packages.list" ]; then
2418 include=$(grep '^@include' "$storage/packages.list")
2419 if [ -n "$include" ]; then
2420 include=${include#@include }
2421 if [ -s "$FLAVORS_REPOSITORY/$include/packages.list" ]; then
2422 cp -f "$FLAVORS_REPOSITORY/$include/packages.list" "$tmp_dir/$flavor.pkglist"
2423 else
2424 echo -e "\nERROR: Can't find include package list from $include\n"
2425 fi
2426 fi
2427 # Generate the final/initial package list
2428 [ -s "$storage/packages.list" ] && \
2429 cat "$storage/packages.list" >> "$tmp_dir/$flavor.pkglist"
2430 sed -i '/@include/d' "$tmp_dir/$flavor.pkglist"
2431 fi
2433 if grep -q ^ROOTFS_SELECTION "$storage/receipt"; then
2434 # Process multi-rootfs flavor
2435 . "$storage/receipt"
2436 set -- $ROOTFS_SELECTION
2437 [ -n "$FRUGAL_RAM" ] || FRUGAL_RAM=$1
2438 [ -f "$FLAVORS_REPOSITORY/$2/packages.list" ] || tazlito extract-flavor $2
2439 cp "$FLAVORS_REPOSITORY/$2/packages.list" "$tmp_dir/$flavor.pkglist"
2441 for i in rootcd rootfs; do
2442 mkdir "$tmp_dir/$i"
2443 # Copy extra files from the first flavor
2444 [ -d "$FLAVORS_REPOSITORY/$2/$i" ] &&
2445 cp -a "$FLAVORS_REPOSITORY/$2/$i" "$tmp_dir"
2446 # Overload extra files by meta flavor
2447 [ -d "$storage/$i" ] && cp -a "$storage/$i" "$tmp_dir"
2448 [ -n "$(ls $tmp_dir/$i)" ] &&
2449 (cd "$tmp_dir/$i"; find . | cpio -o -H newc 2>/dev/null ) | \
2450 dogzip "$tmp_dir/$flavor.$i"
2451 rm -rf "$tmp_dir/$i"
2452 done
2453 else
2454 # Process plain flavor
2455 for i in rootcd rootfs; do
2456 [ -d "$storage/$i" ] || continue
2457 (cd "$storage/$i";
2458 find . | cpio -o -H newc 2>/dev/null) | dogzip "$tmp_dir/$flavor.$i"
2459 done
2460 fi
2462 unset VERSION MAINTAINER ROOTFS_SELECTION
2463 set -- $(module calc_sizes "$tmp_dir" "$flavor")
2464 ROOTFS_SIZE="$1 (estimated)"
2465 INITRAMFS_SIZE="$2 (estimated)"
2466 ISO_SIZE="$3 (estimated)"
2467 PKGNUM="$4"
2468 . "$storage/receipt"
2470 sed '/: $/d' > "$tmp_dir/$flavor.desc" <<EOT
2471 Flavor : $FLAVOR
2472 Description : $SHORT_DESC
2473 Version : $VERSION
2474 Maintainer : $MAINTAINER
2475 LiveCD RAM size : $FRUGAL_RAM
2476 Rootfs list : $ROOTFS_SELECTION
2477 Build date : $(date '+%Y%m%d at %T')
2478 Packages : $PKGNUM
2479 Rootfs size : $ROOTFS_SIZE
2480 Initramfs size : $INITRAMFS_SIZE
2481 ISO image size : $ISO_SIZE
2482 ================================================================================
2484 EOT
2486 rm -f $tmp_dir/packages.list
2487 pack_flavor "$tmp_dir" "$flavor"
2488 status
2489 display_unknown "$tmp_dir/err"
2490 display_warn "$flv_dir/warn"
2491 cleanup
2492 ;;
2495 get-flavor)
2496 # Get a flavor's files and prepare for gen-distro.
2497 flavor=${2%.flavor}
2498 title 'Preparing %s distro flavor' "$flavor"
2499 set -e
2500 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2501 set +e
2503 action 'Cleaning %s...' "$DISTRO"
2504 [ -d "$DISTRO" ] && rm -r "$DISTRO"
2505 # Clean old files
2506 for i in non-free.list distro-packages.list distro.sh receipt mirrors err; do
2507 [ -f "$i" ] && rm "$i"
2508 done
2509 mkdir -p "$DISTRO"
2510 status
2512 [ -z "$noup" ] && tazlito upgrade-flavor "$flavor.flavor"
2514 action 'Extracting flavor %s...' "$flavor.flavor"
2515 flv_dir="$(extract_flavor "$flavor" info)"
2516 cp -a "$flv_dir"/* .
2517 mv packages.list distro-packages.list
2518 mv -f info /etc/tazlito
2519 status
2521 for i in rootcd rootfs; do
2522 if [ -d "$i" ]; then
2523 mkdir -p "$ADDFILES"; mv "$i" "$ADDFILES/$i"
2524 fi
2525 done
2527 sed '/^Rootfs list/!d;s/.*: //' description > /etc/tazlito/rootfs.list
2528 [ -s /etc/tazlito/rootfs.list ] || rm -f /etc/tazlito/rootfs.list
2530 action 'Updating %s...' 'tazlito.conf'
2531 [ -f tazlito.conf ] || cp /etc/tazlito/tazlito.conf .
2532 grep -v "^#VOLUM_NAME" < tazlito.conf | \
2533 sed "s/^VOLUM_NA/VOLUM_NAME=\"SliTaz $flavor\"\\n#VOLUM_NA/" \
2534 > tazlito.conf.$$ && mv tazlito.conf.$$ tazlito.conf
2535 sed -i "s/ISO_NAME=.*/ISO_NAME=\"slitaz-$flavor\"/" tazlito.conf
2536 status
2538 footer 'Flavor is ready to be generated by `tazlito gen-distro`'
2539 cleanup
2540 ;;
2543 iso2flavor)
2544 [ -z "$3" -o ! -s "$2" ] && die 'Usage: tazlito iso2flavor <image.iso> <flavor_name>' \
2545 '\n\nCreate a file <flavor_name>.flavor from the CD-ROM image file <image.iso>'
2547 FLAVOR=${3%.flavor}
2548 mkdir -p $TMP_DIR/iso $TMP_DIR/rootfs $TMP_DIR/flavor
2549 mount -o loop,ro $2 $TMP_DIR/iso
2550 flavordata $2 | (cd $TMP_DIR/flavor; cpio -i 2>/dev/null)
2551 if [ -s $TMP_DIR/iso/boot/rootfs1.gz -a \
2552 ! -s $TMP_DIR/flavor/*.desc ]; then
2553 _ 'META flavors are not supported.'
2554 umount -d $TMP_DIR/iso
2555 elif [ ! -s $TMP_DIR/iso/boot/rootfs.gz -a \
2556 ! -s $TMP_DIR/iso/boot/rootfs1.gz ]; then
2557 _ 'No %s in ISO image. Needs a SliTaz ISO.' '/boot/rootfs.gz'
2558 umount -d $TMP_DIR/iso
2559 else
2560 for i in $(ls -r $TMP_DIR/iso/boot/rootfs*z); do
2561 uncompress $i | \
2562 ( cd $TMP_DIR/rootfs ; cpio -idmu > /dev/null 2>&1 )
2563 done
2564 if [ ! -s $TMP_DIR/rootfs/etc/slitaz-release ]; then
2565 _ 'No file %s in %s of ISO image. Needs a non-loram SliTaz ISO.' \
2566 '/etc/slitaz-release' '/boot/rootfs.gz'
2567 umount -d $TMP_DIR/iso
2568 else
2569 ROOTFS_SIZE=$(du -hs $TMP_DIR/rootfs | awk '{ print $1 }')
2570 RAM_SIZE=$(du -s $TMP_DIR/rootfs | awk '{ print 32*int(($1+36000)/32768) "M" }')
2571 cp -a $TMP_DIR/iso $TMP_DIR/rootcd
2572 ISO_SIZE=$(df -h $TMP_DIR/iso | awk 'END { print $2 }')
2573 BUILD_DATE=$(date '+%Y%m%d at %T' -r "$TMP_DIR/iso/md5sum")
2574 umount -d $TMP_DIR/iso
2575 INITRAMFS_SIZE=$(du -chs $TMP_DIR/rootcd/boot/rootfs*.gz | awk 'END { print $1 }')
2576 rm -f $TMP_DIR/rootcd/boot/rootfs.gz $TMP_DIR/rootcd/md5sum
2577 mv $TMP_DIR/rootcd/boot $TMP_DIR/rootfs
2578 [ -d $TMP_DIR/rootcd/efi ] && mv $TMP_DIR/rootcd/efi $TMP_DIR/rootfs
2579 sed 's/.* \(.*\).tazpkg*/\1/' > $TMP_DIR/$FLAVOR.pkglist \
2580 < $TMP_DIR/rootfs$INSTALLED.md5
2581 PKGCNT=$(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l | awk '{ print $1 }')
2582 if [ -s $TMP_DIR/flavor/*desc ]; then
2583 cp $TMP_DIR/flavor/*.desc $TMP_DIR/$FLAVOR.desc
2584 [ -s $TMP_DIR/$FLAVOR.receipt ] &&
2585 cp $TMP_DIR/flavor/*.receipt $TMP_DIR/$FLAVOR.receipt
2586 for i in rootfs rootcd ; do
2587 [ -s $TMP_DIR/flavor/*.list$i ] &&
2588 sed 's/.\{1,45\}//;/^\.$/d' $TMP_DIR/flavor/*.list$i | \
2589 ( cd $TMP_DIR/$i ; cpio -o -H newc ) | dogzip $TMP_DIR/$FLAVOR.$i
2590 done
2591 else
2592 find_flavor_rootfs $TMP_DIR/rootfs
2593 [ -d $TMP_DIR/rootfs/boot ] && mv $TMP_DIR/rootfs/boot $TMP_DIR/rootcd
2594 [ -d $TMP_DIR/rootfs/efi ] && mv $TMP_DIR/rootfs/efi $TMP_DIR/rootcd
2595 for i in rootfs rootcd ; do
2596 [ "$(ls $TMP_DIR/$i)" ] &&
2597 ( cd "$TMP_DIR/$i"; find * | cpio -o -H newc ) | dogzip "$TMP_DIR/$FLAVOR.$i"
2598 done
2599 unset VERSION MAINTAINER
2600 echo -en "Flavor short description \007: "; read -t 30 DESCRIPTION
2601 if [ -n "$DESCRIPTION" ]; then
2602 _n 'Flavor version : '; read -t 30 VERSION
2603 _n 'Flavor maintainer (your email) : '; read -t 30 MAINTAINER
2604 fi
2606 cat > $TMP_DIR/$FLAVOR.desc <<EOT
2607 Flavor : $FLAVOR
2608 Description : ${DESCRIPTION:-SliTaz $FLAVOR flavor}
2609 Version : ${VERSION:-1.0}
2610 Maintainer : ${MAINTAINER:-nobody@slitaz.org}
2611 LiveCD RAM size : $RAM_SIZE
2612 Build date : $BUILD_DATE
2613 Packages : $PKGCNT
2614 Rootfs size : $ROOTFS_SIZE
2615 Initramfs size : $INITRAMFS_SIZE
2616 ISO image size : $ISO_SIZE
2617 ================================================================================
2619 EOT
2620 longline "Tazlito can't detect each file installed during \
2621 a package post_install. You should extract this flavor (tazlito extract-flavor \
2622 $FLAVOR), check the files in /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/rootfs \
2623 tree and remove files generated by post_installs.
2624 Check /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/receipt too and \
2625 repack the flavor (tazlito pack-flavor $FLAVOR)"
2626 fi
2627 ( cd $TMP_DIR; ls $FLAVOR.* | cpio -o -H newc ) | dogzip $FLAVOR.flavor
2628 fi
2629 fi
2630 rm -rf $TMP_DIR
2631 ;;
2634 gen-distro)
2635 # Generate a live distro tree with a set of packages.
2637 check_root
2638 start_time=$(date +%s)
2640 # Tazlito options: --iso or --cdrom
2641 CDROM=''
2642 [ -n "$iso" ] && CDROM="-o loop $iso"
2643 [ -n "$cdrom" ] && CDROM="/dev/cdrom"
2645 # Check if a package list was specified on cmdline.
2646 if [ -f "$2" ]; then
2647 LIST_NAME="$2"
2648 else
2649 LIST_NAME='distro-packages.list'
2650 fi
2652 [ -d "$ROOTFS" -a -z "$forced" ] && die "A rootfs exists in '$DISTRO'." \
2653 'Please clean the distro tree or change directory path.'
2654 [ -d "$ROOTFS" ] && rm -rf "$ROOTFS"
2655 [ -d "$ROOTCD" ] && rm -rf "$ROOTCD"
2657 # If list not given: build list with all installed packages
2658 if [ ! -f "$LIST_NAME" -a -f "$LOCALSTATE/installed.info" ]; then
2659 awk -F$'\t' '{print $1}' "$LOCALSTATE/installed.info" >> "$LIST_NAME"
2660 fi
2662 # Exit if no list name.
2663 [ ! -f "$LIST_NAME" ] && die 'No packages list found or specified. Please read the docs.'
2665 # Start generation.
2666 title 'Tazlito generating a distro'
2668 # Misc checks
2669 mkdir -p "$PACKAGES_REPOSITORY"
2670 REPACK=$(yesorno 'Repack packages from rootfs?' 'n')
2671 newline
2673 # Mount CD-ROM to be able to repack boot-loader packages
2674 if [ ! -e /boot -a -n "$CDROM" ]; then
2675 mkdir $TMP_MNT
2676 if mount -r "$CDROM $TMP_MNT" 2>/dev/null; then
2677 ln -s "$TMP_MNT/boot" /
2678 if [ ! -d "$ADDFILES/rootcd" ] ; then
2679 mkdir -p "$ADDFILES/rootcd"
2680 for i in $(ls $TMP_MNT); do
2681 [ "$i" == 'boot' ] && continue
2682 cp -a "$TMP_MNT/$i" "$ADDFILES/rootcd"
2683 done
2684 fi
2685 else
2686 rmdir "$TMP_MNT"
2687 fi
2688 fi
2690 # Rootfs stuff.
2691 echo 'Preparing the rootfs directory...'
2692 mkdir -p "$ROOTFS"
2693 export root="$ROOTFS"
2694 # pass current 'mirror' to the root
2695 mkdir -p $root/var/lib/tazpkg $root/etc
2696 cp -f /var/lib/tazpkg/mirror $root/var/lib/tazpkg/mirror
2697 cp -f /etc/slitaz-release $root/etc/slitaz-release
2698 strip_versions "$LIST_NAME"
2700 if [ "$REPACK" == 'y' ]; then
2701 # Determine full packages list with all dependencies
2702 tmp_dir="$(mktemp -d)"
2703 cp "$LIST_NAME" "$tmp_dir/flavor.pkglist"
2704 touch "$tmp_dir/full.pkglist"
2705 module calc_sizes "$tmp_dir" 'flavor' "$tmp_dir/full.pkglist" >/dev/null
2707 awk -F$'\t' '{printf "%s %s\n", $1, $2}' "$LOCALSTATE/installed.info" | \
2708 while read pkgname pkgver; do
2709 # Is package in full list?
2710 grep -q "^$pkgname$" "$tmp_dir/full.pkglist" || continue
2711 # Is package already repacked?
2712 [ -e "$PACKAGES_REPOSITORY/$pkgname-$pkgver.tazpkg" ] && continue
2713 _ 'Repacking %s...' "$pkgname-$pkgver"
2714 tazpkg repack "$pkgname" --quiet
2715 [ -f "$pkgname-$pkgver.tazpkg" ] && mv "$pkgname-$pkgver.tazpkg" "$PACKAGES_REPOSITORY"
2716 status
2717 done
2719 rm -r "$tmp_dir"
2720 fi
2722 if [ -f non-free.list ]; then
2723 # FIXME: working in the ROOTFS chroot?
2724 newline
2725 echo 'Preparing non-free packages...'
2726 cp 'non-free.list' "$ROOTFS/etc/tazlito/non-free.list"
2727 for pkg in $(cat 'non-free.list'); do
2728 if [ ! -d "$INSTALLED/$pkg" ]; then
2729 if [ ! -d "$INSTALLED/get-$pkg" ]; then
2730 tazpkg get-install get-$pkg
2731 fi
2732 get-$pkg "$ROOTFS"
2733 fi
2734 tazpkg repack $pkg
2735 pkg=$(ls $pkg*.tazpkg)
2736 grep -q "^$pkg$" $LIST_NAME || echo $pkg >> $LIST_NAME
2737 mv $pkg $PACKAGES_REPOSITORY
2738 done
2739 fi
2740 cp $LIST_NAME $DISTRO/distro-packages.list
2741 newline
2743 install_list_to_rootfs "$DISTRO/distro-packages.list" "$ROOTFS"
2745 cd $DISTRO
2746 cp distro-packages.list $ROOTFS/etc/tazlito
2747 # Copy all files from $ADDFILES/rootfs to the rootfs.
2748 if [ -d "$ADDFILES/rootfs" ] ; then
2749 action 'Copying addfiles content to the rootfs...'
2750 cp -a $ADDFILES/rootfs/* $ROOTFS
2751 status
2752 fi
2754 action 'Root filesystem is generated...'; status
2756 # Root CD part.
2757 action 'Preparing the rootcd directory...'
2758 mkdir -p $ROOTCD
2759 status
2761 # Move the boot dir with the Linux kernel from rootfs.
2762 # The efi & boot dirs go directly on the CD.
2763 if [ -d "$ROOTFS/efi" ] ; then
2764 action 'Moving the efi directory...'
2765 mv $ROOTFS/efi $ROOTCD
2766 status
2767 fi
2768 if [ -d "$ROOTFS/boot" ] ; then
2769 action 'Moving the boot directory...'
2770 mv $ROOTFS/boot $ROOTCD
2771 status
2772 fi
2773 cd $DISTRO
2774 # Copy all files from $ADDFILES/rootcd to the rootcd.
2775 if [ -d "$ADDFILES/rootcd" ] ; then
2776 action 'Copying addfiles content to the rootcd...'
2777 cp -a $ADDFILES/rootcd/* $ROOTCD
2778 status
2779 fi
2780 # Execute the distro script used to perform tasks in the rootfs
2781 # before compression. Give rootfs path in arg
2782 [ -z "$DISTRO_SCRIPT" ] && DISTRO_SCRIPT="$TOP_DIR/distro.sh"
2783 if [ -x "$DISTRO_SCRIPT" ]; then
2784 echo 'Executing distro script...'
2785 sh $DISTRO_SCRIPT $DISTRO
2786 fi
2788 # Execute the custom_rules() found in receipt.
2789 if [ -s "$TOP_DIR/receipt" ]; then
2790 if grep -q ^custom_rules "$TOP_DIR/receipt"; then
2791 echo -e "Executing: custom_rules()\n"
2792 . "$TOP_DIR/receipt"
2793 custom_rules || echo -e "\nERROR: custom_rules() failed\n"
2794 fi
2795 fi
2797 # Multi-rootfs
2798 if [ -s /etc/tazlito/rootfs.list ]; then
2800 FLAVOR_LIST="$(awk '{
2801 for (i = 2; i <= NF; i+=2)
2802 printf "%s ", $i;
2803 }' /etc/tazlito/rootfs.list)"
2805 [ -s "$ROOTCD/boot/isolinux/isolinux.msg" ] &&
2806 sed -i "s/ *//;s/)/), flavors $FLAVOR_LIST/" \
2807 "$ROOTCD/boot/isolinux/isolinux.msg" 2>/dev/null
2809 [ -f "$ROOTCD/boot/isolinux/ifmem.c32" -o \
2810 -f "$ROOTCD/boot/isolinux/c32box.c32" ] ||
2811 cp '/boot/isolinux/c32box.c32' "$ROOTCD/boot/isolinux" 2>/dev/null ||
2812 cp '/boot/isolinux/ifmem.c32' "$ROOTCD/boot/isolinux"
2814 n=0
2815 last=$ROOTFS
2816 while read flavor; do
2817 n=$(($n+1))
2818 mkdir ${ROOTFS}0$n
2819 export root="${ROOTFS}0$n"
2820 # initial tazpkg setup in empty rootfs
2821 tazpkg --root=$root >/dev/null 2>&1
2823 newline
2824 boldify "Building $flavor rootfs..."
2826 [ -s "$TOP_DIR/$flavor.flavor" ] &&
2827 cp "$TOP_DIR/$flavor.flavor" .
2829 if [ ! -s "$flavor.flavor" ]; then
2830 # We may have it in $FLAVORS_REPOSITORY
2831 if [ -d "$FLAVORS_REPOSITORY/$flavor" ]; then
2832 tazlito pack-flavor $flavor
2833 else
2834 download $flavor.flavor
2835 fi
2836 fi
2838 action 'Extracting %s and %s...' "$flavor.pkglist" "$flavor.rootfs"
2839 zcat $flavor.flavor | cpio -i --quiet $flavor.pkglist $flavor.rootfs
2840 cp $flavor.pkglist $DISTRO/list-packages0$n
2841 status
2843 strip_versions "$DISTRO/list-packages0$n"
2845 install_list_to_rootfs "$DISTRO/list-packages0$n" "${ROOTFS}0$n"
2847 action 'Updating the boot directory...'
2848 yes n | cp -ai ${ROOTFS}0$n/boot $ROOTCD 2> /dev/null
2849 rm -rf ${ROOTFS}0$n/boot
2851 cd $DISTRO
2852 if [ -s $flavor.rootfs ]; then
2853 _n 'Adding %s rootfs extra files...' "$flavor"
2854 zcat < $flavor.rootfs | ( cd ${ROOTFS}0$n ; cpio -idmu )
2855 fi
2857 action 'Moving %s to %s' "list-packages0$n" "rootfs0$n"
2858 mv "$DISTRO/list-packages0$n" "${ROOTFS}0$n/etc/tazlito/distro-packages.list"
2859 status
2861 rm -f $flavor.flavor install-list
2862 mergefs ${ROOTFS}0$n $last
2863 last=${ROOTFS}0$n
2864 done <<EOT
2865 $(awk '{ for (i = 4; i <= NF; i+=2) print $i; }' < /etc/tazlito/rootfs.list)
2866 EOT
2867 #'
2868 i=$(($n+1))
2869 while [ $n -gt 0 ]; do
2870 mv ${ROOTFS}0$n ${ROOTFS}$i
2871 _ 'Compressing %s (%s)...' "${ROOTFS}0$n" "$(du -hs ${ROOTFS}$i | awk '{ print $1 }')"
2872 gen_initramfs ${ROOTFS}$i
2873 n=$(($n-1))
2874 i=$(($i-1))
2875 export LZMA_HISTORY_BITS=26
2876 done
2877 mv $ROOTFS ${ROOTFS}$i
2878 gen_initramfs ${ROOTFS}$i
2879 update_bootconfig "$ROOTCD/boot/isolinux" "$(cat /etc/tazlito/rootfs.list)"
2880 ROOTFS=${ROOTFS}1
2881 else
2882 # Initramfs and ISO image stuff.
2883 gen_initramfs $ROOTFS
2884 fi
2885 gen_livecd_isolinux
2886 distro_stats
2887 cleanup
2888 ;;
2891 clean-distro)
2892 # Remove old distro tree.
2894 check_root
2895 title 'Cleaning: %s' "$DISTRO"
2896 if [ -d "$DISTRO" ] ; then
2897 if [ -d "$ROOTFS" ] ; then
2898 action 'Removing the rootfs...'
2899 rm -f $DISTRO/$INITRAMFS
2900 rm -rf $ROOTFS
2901 status
2902 fi
2903 if [ -d "$ROOTCD" ] ; then
2904 action 'Removing the rootcd...'
2905 rm -rf $ROOTCD
2906 status
2907 fi
2908 action 'Removing eventual ISO image...'
2909 rm -f $DISTRO/$ISO_NAME.iso
2910 rm -f $DISTRO/$ISO_NAME.md5
2911 status
2912 fi
2913 footer
2914 ;;
2917 check-distro)
2918 # Check for a few LiveCD needed files not installed by packages.
2920 # TODO: Remove this function.
2921 # First two files are maintained by tazpkg while it runs on rootfs,
2922 # while last one file should be maintained by tazlito itself.
2923 check_rootfs
2924 title 'Checking distro: %s' "$ROOTFS"
2925 # SliTaz release info.
2926 rel='/etc/slitaz-release'
2927 if [ ! -f "$ROOTFS$rel" ]; then
2928 _ 'Missing release info: %s' "$rel"
2929 else
2930 action 'Release : %s' "$(cat $ROOTFS$rel)"
2931 status
2932 fi
2933 # Tazpkg mirror.
2934 if [ ! -f "$ROOTFS$LOCALSTATE/mirror" ]; then
2935 action 'Mirror URL : Missing %s' "$LOCALSTATE/mirror"
2936 todomsg
2937 else
2938 action 'Mirror configuration exists...'
2939 status
2940 fi
2941 # Isolinux msg
2942 if grep -q "cooking-XXXXXXXX" /$ROOTCD/boot/isolinux/isolinux.*g; then
2943 action 'Isolinux msg : Missing cooking date XXXXXXXX (ex %s)' "$(date +%Y%m%d)"
2944 todomsg
2945 else
2946 action 'Isolinux message seems good...'
2947 status
2948 fi
2949 footer
2950 ;;
2953 writeiso)
2954 # Writefs to ISO image including /home unlike gen-distro we don't use
2955 # packages to generate a rootfs, we build a compressed rootfs with all
2956 # the current filesystem similar to 'tazusb writefs'.
2958 DISTRO='/home/slitaz/distro'
2959 ROOTCD="$DISTRO/rootcd"
2960 COMPRESSION="${2:-none}"
2961 ISO_NAME="${3:-slitaz}"
2962 check_root
2963 # Start info
2964 title 'Write filesystem to ISO'
2965 longline "The command writeiso will write the current filesystem into a \
2966 suitable cpio archive (rootfs.gz) and generate a bootable ISO image (slitaz.iso)."
2967 newline
2968 emsg "<b>Archive compression:</b> <c 36>$COMPRESSION</c>"
2970 [ "$COMPRESSION" == 'gzip' ] && colorize 31 "gzip-compressed rootfs unsupported and may fail to boot"
2971 # Save some space
2972 rm -rf /var/cache/tazpkg/*
2973 rm -f /var/lib/tazpkg/*.bak
2974 rm -rf $DISTRO
2976 # Optionally remove sound card selection and screen resolution.
2977 if [ -z $LaunchedByTazpanel ]; then
2978 anser=$(yesorno 'Do you wish to remove the sound card and screen configs?' 'n')
2979 case $anser in
2980 y)
2981 action 'Removing current sound card and screen configurations...'
2982 rm -f /var/lib/sound-card-driver
2983 rm -f /var/lib/alsa/asound.state
2984 rm -f /etc/X11/xorg.conf ;;
2985 *)
2986 action 'Keeping current sound card and screen configurations...' ;;
2987 esac
2988 status
2989 newline
2991 # Optionally remove i18n settings
2992 anser=$(yesorno 'Do you wish to remove locale/keymap settings?' 'n')
2993 case $anser in
2994 y)
2995 action 'Removing current locale/keymap settings...'
2996 newline > /etc/locale.conf
2997 newline > /etc/keymap.conf ;;
2998 *)
2999 action 'Keeping current locale/keymap settings...' ;;
3000 esac
3001 status
3002 fi
3004 # Clean-up files by default
3005 newline > /etc/udev/rules.d/70-persistent-net.rules
3006 newline > /etc/udev/rules.d/70-persistant-cd.rules
3008 # Create list of files including default user files since it is defined in /etc/passwd
3009 # and some new users might have been added.
3010 cd /
3011 echo 'init' > /tmp/list
3012 for dir in bin etc sbin var dev lib root usr home opt; do
3013 [ -d $dir ] && find $dir
3014 done >> /tmp/list
3016 for dir in proc sys tmp mnt media media/cdrom media/flash media/usbdisk run run/udev; do
3017 [ -d $dir ] && echo $dir
3018 done >> /tmp/list
3020 sed '/var\/run\/.*pid$/d ; /var\/run\/utmp/d ; /.*\/.gvfs/d ; /home\/.*\/.cache\/.*/d' -i /tmp/list
3022 #if [ ! $(find /var/log/slitaz/tazpkg.log -size +4k) = "" ]; then
3023 # sed -i "/var\/log\/slitaz\/tazpkg.log/d" /tmp/list
3024 #fi
3025 mv -f /var/log/wtmp /tmp/tazlito-wtmp
3026 touch /var/log/wtmp
3028 for removelog in auth boot messages dmesg daemon slim .*old Xorg tazpanel cups; do
3029 sed -i "/var\/log\/$removelog/d" /tmp/list
3030 done
3032 # Generate initramfs with specified compression and display rootfs
3033 # size in realtime.
3034 rm -f /tmp/.write-iso* /tmp/rootfs 2>/dev/null
3036 write_initramfs &
3037 sleep 2
3038 cd - > /dev/null
3039 echo -en "\nFilesystem size:"
3040 while [ ! -f /tmp/rootfs ]; do
3041 sleep 1
3042 echo -en "\\033[18G$(du -sh /$INITRAMFS | awk '{print $1}') "
3043 done
3044 mv -f /tmp/tazlito-wtmp /var/log/wtmp
3045 echo -e "\n"
3046 rm -f /tmp/rootfs
3048 # Move freshly generated rootfs to the cdrom.
3049 mkdir -p $ROOTCD/boot
3050 mv -f /$INITRAMFS $ROOTCD/boot
3051 _ 'Located in: %s' "$ROOTCD/boot/$INITRAMFS"
3053 # Now we need the kernel and isolinux files.
3054 copy_from_cd() {
3055 cp /media/cdrom/boot/bzImage* $ROOTCD/boot
3056 cp -a /media/cdrom/boot/isolinux $ROOTCD/boot
3057 unmeta_boot $ROOTCD
3058 umount /media/cdrom
3061 if mount /dev/cdrom /media/cdrom 2>/dev/null; then
3062 copy_from_cd;
3063 elif mount | grep /media/cdrom; then
3064 copy_from_cd;
3065 #elif [ -f "$bootloader" -a -f /boot/vmlinuz*slitaz* ]; then
3066 # [ -f /boot/*slitaz ] && cp /boot/vmlinuz*slitaz $ROOTCD/boot/bzImage
3067 # [ -f /boot/*slitaz64 ] && cp /boot/vmlinuz*slitaz64 $ROOTCD/boot/bzImage64
3068 else
3069 touch /tmp/.write-iso-error
3070 longline "When SliTaz is running in RAM the kernel and bootloader \
3071 files are kept on the CD-ROM. `boldify ' Please insert a Live CD or run:
3072 # mount -o loop slitaz.iso /media/cdrom ' ` to let Tazlito copy the files."
3073 echo -en "----\nENTER to continue..."; read i
3074 [ ! -d /media/cdrom/boot/isolinux ] && exit 1
3075 copy_from_cd
3076 fi
3078 # Generate the iso image.
3079 touch /tmp/.write-iso
3080 newline
3081 cd $DISTRO
3082 create_iso $ISO_NAME.iso $ROOTCD
3083 action 'Creating the ISO md5sum...'
3084 md5sum $ISO_NAME.iso > $ISO_NAME.md5
3085 status
3087 footer "ISO image: $(du -sh $DISTRO/$ISO_NAME.iso)"
3088 rm -f /tmp/.write-iso
3090 if [ -z $LaunchedByTazpanel ]; then
3091 anser=$(yesorno 'Burn ISO to CD-ROM?' 'n')
3092 case $anser in
3093 y)
3094 umount /dev/cdrom 2>/dev/null
3095 eject
3096 echo -n "Please insert a blank CD-ROM and press ENTER..."
3097 read i && sleep 2
3098 tazlito burn-iso $DISTRO/$ISO_NAME.iso
3099 echo -en "----\nENTER to continue..."; read i ;;
3100 *)
3101 exit 0 ;;
3102 esac
3103 fi
3104 ;;
3107 burn-iso)
3108 # Guess CD-ROM device, ask user and burn the ISO.
3110 check_root
3111 DRIVE_NAME=$(grep "drive name" /proc/sys/dev/cdrom/info | cut -f3)
3112 DRIVE_SPEED=$(grep "drive speed" /proc/sys/dev/cdrom/info | cut -f3)
3113 # We can specify an alternative ISO from the cmdline.
3114 iso="${2:-$DISTRO/$ISO_NAME.iso}"
3115 [ ! -f "$iso" ] && die "Unable to find ISO: $iso"
3117 title 'Tazlito burn ISO'
3118 echo "CD-ROM device : /dev/$DRIVE_NAME"
3119 echo "Drive speed : $DRIVE_SPEED"
3120 echo "ISO image : $iso"
3121 footer
3123 case $(yesorno 'Burn ISO image?' 'n') in
3124 y)
3125 title 'Starting Wodim to burn the ISO...'
3126 sleep 2
3127 wodim speed=$DRIVE_SPEED dev=/dev/$DRIVE_NAME $iso
3128 footer 'ISO image is burned to CD-ROM.'
3129 ;;
3130 *)
3131 die 'Exiting. No ISO burned.'
3132 ;;
3133 esac
3134 ;;
3137 merge)
3138 # Merge multiple rootfs into one iso.
3140 if [ -z "$2" ]; then
3141 cat <<EOT
3142 Usage: tazlito merge size1 iso size2 rootfs2 [sizeN rootfsN]...
3144 Merge multiple rootfs into one ISO. Rootfs are like russian dolls
3145 i.e: rootfsN is a subset of rootfsN-1
3146 rootfs1 is found in ISO, sizeN is the RAM size needed to launch rootfsN.
3147 The boot loader will select the rootfs according to the RAM size detected.
3149 Example:
3150 $ tazlito merge 160M slitaz-core.iso 96M rootfs-justx.gz 32M rootfs-base.gz
3152 Will start slitaz-core with 160M+ RAM, slitaz-justX with 96M-160M RAM,
3153 slitaz-base with 32M-96M RAM and display an error message if RAM < 32M.
3155 EOT
3156 exit 2
3157 fi
3159 shift # skip merge
3160 append="$1 slitaz1"
3161 shift # skip size1
3162 mkdir -p $TMP_DIR/mnt $TMP_DIR/rootfs1
3164 ISO=$1.merged
3166 # Extract filesystems
3167 action 'Mounting %s' "$1"
3168 mount -o loop,ro $1 $TMP_DIR/mnt 2> /dev/null
3169 status || cleanup_merge
3171 cp -a $TMP_DIR/mnt $TMP_DIR/iso
3172 make_bzImage_hardlink $TMP_DIR/iso/boot
3173 umount -d $TMP_DIR/mnt
3174 if [ -f $TMP_DIR/iso/boot/rootfs1.gz ]; then
3175 _ '%s is already a merged iso. Aborting.' "$1"
3176 cleanup_merge
3177 fi
3178 if [ ! -f $TMP_DIR/iso/boot/isolinux/ifmem.c32 -a
3179 ! -f $TMP_DIR/iso/boot/isolinux/c32box.c32 ]; then
3180 if [ ! -f /boot/isolinux/ifmem.c32 -a
3181 ! -f /boot/isolinux/c32box.c32 ]; then
3182 cat <<EOT
3183 No file /boot/isolinux/ifmem.c32
3184 Please install syslinux package !
3185 EOT
3186 rm -rf $TMP_DIR
3187 exit 1
3188 fi
3189 cp /boot/isolinux/c32box.c32 $TMP_DIR/iso/boot/isolinux 2> /dev/null ||
3190 cp /boot/isolinux/ifmem.c32 $TMP_DIR/iso/boot/isolinux
3191 fi
3193 action 'Extracting %s' 'iso/rootfs.gz'
3194 extract_rootfs $TMP_DIR/iso/boot/rootfs.gz $TMP_DIR/rootfs1 &&
3195 [ -d $TMP_DIR/rootfs1/etc ]
3196 status || cleanup_merge
3198 n=1
3199 while [ -n "$2" ]; do
3200 shift # skip rootfs N-1
3201 p=$n
3202 n=$(($n + 1))
3203 append="$append $1 slitaz$n"
3204 shift # skip size N
3205 mkdir -p $TMP_DIR/rootfs$n
3207 action 'Extracting %s' "$1"
3208 extract_rootfs $1 $TMP_DIR/rootfs$n &&
3209 [ -d "$TMP_DIR/rootfs$n/etc" ]
3210 status || cleanup_merge
3212 mergefs $TMP_DIR/rootfs$n $TMP_DIR/rootfs$p
3213 action 'Creating %s' "rootfs$p.gz"
3214 pack_rootfs "$TMP_DIR/rootfs$p" "$TMP_DIR/iso/boot/rootfs$p.gz"
3215 status
3216 done
3217 action 'Creating %s' "rootfs$n.gz"
3218 pack_rootfs "$TMP_DIR/rootfs$n" "$TMP_DIR/iso/boot/rootfs$n.gz"
3219 status
3220 rm -f $TMP_DIR/iso/boot/rootfs.gz
3221 update_bootconfig $TMP_DIR/iso/boot/isolinux "$append"
3222 create_iso $ISO $TMP_DIR/iso
3223 rm -rf $TMP_DIR
3224 ;;
3227 repack)
3228 # Repack an iso with maximum lzma compression ratio.
3230 ISO=$2
3231 mkdir -p $TMP_DIR/mnt
3233 # Extract filesystems
3234 action 'Mounting %s' "$ISO"
3235 mount -o loop,ro $ISO $TMP_DIR/mnt 2>/dev/null
3236 status || cleanup_merge
3238 cp -a $TMP_DIR/mnt $TMP_DIR/iso
3239 umount -d $TMP_DIR/mnt
3241 for i in $TMP_DIR/iso/boot/rootfs* ; do
3242 action 'Repacking %s' "$(basename $i)"
3243 uncompress $i 2>/dev/null > $TMP_DIR/rootfs
3244 lzma e $TMP_DIR/rootfs $i $(lzma_switches $TMP_DIR/rootfs)
3245 align_to_32bits $i
3246 status
3247 done
3249 create_iso $ISO $TMP_DIR/iso
3250 rm -rf $TMP_DIR
3251 ;;
3254 build-loram)
3255 # Build a Live CD for low RAM systems.
3257 ISO="$2"
3258 OUTPUT="$3"
3259 [ -z "$3" ] && \
3260 die "Usage: tazlito build-loram <input>.iso <output>.iso [cdrom|smallcdrom|http|ram]"
3261 mkdir -p "$TMP_DIR/iso"
3262 mount -o loop,ro -t iso9660 "$ISO" "$TMP_DIR/iso"
3263 loopdev=$( (losetup -a 2>/dev/null || losetup) | sed "/$(echo $ISO | sed 's|/|\\/|g')$/!d;s/:.*//;q")
3264 if ! check_iso_for_loram ; then
3265 umount -d "$TMP_DIR/iso"
3266 die "$ISO is not a valid SliTaz live CD. Abort."
3267 fi
3268 case "$4" in
3269 cdrom) build_loram_cdrom ;;
3270 http) build_loram_http ;;
3271 *) build_loram_ram "$5" ;;
3272 esac
3273 umount $TMP_DIR/iso # no -d: needs /proc
3274 losetup -d $loopdev
3275 rm -rf $TMP_DIR
3276 ;;
3279 emu-iso)
3280 # Emulate an ISO image with Qemu.
3281 iso="${2:-$DISTRO/$ISO_NAME.iso}"
3282 [ -f "$iso" ] || die "Unable to find ISO file '$iso'."
3283 [ -x '/usr/bin/qemu' ] || die "Unable to find Qemu binary. Please install package 'qemu'."
3284 echo -e "\nStarting Qemu emulator:\n"
3285 echo -e "qemu $QEMU_OPTS $iso\n"
3286 qemu $QEMU_OPTS $iso
3287 ;;
3290 deduplicate)
3291 # Deduplicate files in a tree
3292 shift
3293 deduplicate "$@"
3294 ;;
3297 usage|*)
3298 # Print usage also for all unknown commands.
3299 usage
3300 ;;
3301 esac
3303 exit 0