tazlito view tazlito @ rev 501

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