tazlito view tazlito @ rev 529

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