tazlito view tazlito @ rev 499

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