tazlito view tazlito @ rev 509

Take care of installed /boot/isolinux/efi.img
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Jun 03 14:17:50 2018 +0200 (18 months ago)
parents 8b6be2b2d776
children 3ab0aff91019
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 [ -x $2/boot/isolinux/efi.img ] && return
308 local n=$(get 19 "$2/boot/isolinux/efi.img")
309 [ $n -eq 0 ] && n=$(get 32 "$2/boot/isolinux/efi.img" 4)
310 efiblock=$(first_block "$2/boot/isolinux/efi.img")
311 fix_efi_img_size $(($n*512)) $1
312 fix_efi_boot_img_size $1 $2 $n $efiblock
314 # Build file list tree
315 resv=$(get 14 "$2/boot/isolinux/efi.img")
316 if [ $(get 57 "$2/boot/isolinux/efi.img" 1) -ne 49 ]; then
317 skiphead=5
318 fatsz=$(get 36 "$2/boot/isolinux/efi.img" 4)
319 basecluster=$((($resv+2*$fatsz)/4+$efiblock-2))
320 dd if=$1 bs=512 skip=$(($efiblock*4)) count=3 \
321 of=$1 seek=$(($efiblock*4+3)) conv=notrunc
322 else
323 skiphead=4
324 fatsz=$(get 22 "$2/boot/isolinux/efi.img")
325 basecluster=$((($resv+2*$fatsz)/4+$efiblock-1))
326 fi 2> /dev/null
327 hd "$2/boot/isolinux/efi.img" | awk 'BEGIN { skiphead='$skiphead' }
328 {
329 if (skiphead!=0) {
330 if ($1=="*") skiphead--
331 next
332 }
333 if (skipdot!=0) {
334 if (skipdot==2) up[cur]=$13 $12
335 else cur=$13 $12
336 skipdot=0
337 next
338 }
339 if (($2=="2e" && $3=="20") || ($2=="2e" && $3=="2e" && $4=="20")) {
340 if ($3=="2e") skipdot=2
341 else skipdot=1
342 next
343 }
344 if (gotname!=0) {
345 path=""
346 for (i=cur;i!="" && i!="0000";i=up[i]) path=dir[i] path
347 if (gotname==2) dir[$13 $12]=name
348 else print $1 " " $13 $12 " " path name
349 gotname=0
350 name=""
351 next
352 }
353 if (s!="") {
354 if (eos==0)
355 for (i=2;i<18;i+=2) {
356 if (i==12) i+=2
357 if ($i=="00") break
358 s=s substr($0,i+60,1)
359 }
360 name=s name
361 s=""
362 eos=0
363 next
364 }
365 if ($13=="0f") {
366 s=""
367 for (i=3;i<16;i+=2) {
368 if (i==13) i+=3
369 if ($i=="00") { eos=1; break }
370 s=s substr($0,i+60,1)
371 }
372 next
373 }
374 if ($13=="10") {
375 name=name "/"
376 gotname=2
377 next
378 }
379 if ($13=="20") {
380 gotname=1
381 next
382 }
383 }
384 ' | ( while read offset cluster file; do
385 cluster=$(($(first_block "$2/$file")-$basecluster))
386 set32 $(($efiblock*2048+0x$offset+10)) $cluster "$1" 16
387 set32 $(($efiblock*2048+0x$offset+4)) $(($cluster>>16)) "$1" 16
388 echo "$cluster $((($(stat -c %s "$2/$file")+2047)/2048)) $file"
389 done
391 # Update fat12 or fat16
392 get 57 "$2/boot/isolinux/efi.img"
393 dd if="$2/boot/isolinux/efi.img" bs=512 count=$fatsz skip=$resv 2> /dev/null | \
394 od -An -t u1 -w1 -v
395 ) | awk '
396 {
397 if (state==0) {
398 if ($2=="") {
399 if ($1==12849) fat=12
400 else if ($1==13873) fat=16
401 else fat=32
402 state++
403 }
404 else {
405 for (i=1;i<$2;i++) c[$1+i]=$1+i
406 c[$1+$2]=268435455
407 }
408 next
409 }
410 if (state==1) {
411 prev=$1
412 state++
413 next
414 }
415 if (state==2) {
416 if (fat==12) {
417 n=($1%16)*256+prev
418 if (n!=0) c[pos+1]=n
419 pos++
420 prev=int($1/16)
421 state++
422 next
423 }
424 n=$1*256+prev
425 if (fat==32) {
426 prev=n
427 state=13
428 next
429 }
430 }
431 else if (state==3) {
432 n=$1*16+prev
433 }
434 else if (state==13) {
435 prev=$1*65536+prev
436 state++
437 next
438 }
439 else n=$1*16777216+prev
440 if (n!=0) c[pos+1]=n
441 pos++
442 state=1
443 }
444 END {
445 for (i=1;i<=pos;i+=2) {
446 if (c[i]=="") c[i]=0
447 if (c[i+1]=="") c[i+1]=0
448 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
449 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
450 else {
451 printf "0 %02X %02X %02X %02X |\n",c[i]%256,(c[i]/256)%256,(c[i]/65536)%256,(c[i]/16777216)%256
452 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
453 }
454 }
455 }' | hexdump -R | dd of="$1" seek=$((4*$efiblock+$fatsz+$resv)) \
456 conv=notrunc bs=512 > /dev/null 2>&1
457 dd if="$1" of="$1" conv=notrunc bs=512 skip=$((4*$efiblock+$fatsz+$resv)) \
458 count=$fatsz seek=$((4*$efiblock+$resv)) > /dev/null 2>&1
460 # Cleanup cache
461 umount $2
462 mount -o loop,ro $1 $2
463 }
466 # allocate efi.img stub to share EFI files in the EFI boot partition
468 alloc_uefi_part() {
469 local basedir=$(dirname "$1")/..
470 if [ -s $basedir/boot/isolinux/efi.img ]; then
471 chmod +x $basedir/boot/isolinux/efi.img
472 return
473 fi
474 local fclust=$({
475 [ -d $basedir/efi ] &&
476 find $basedir/efi -type f -exec stat -c "%s %n" {} \;
477 while [ -s "$1" ]; do
478 local efifile
479 case "$1" in
480 *taz) efifile=bootia32.efi ;;
481 *taz64) efifile=bootx64.efi ;;
482 esac
483 if [ ! -s $basedir/efi/boot/$efifile ] &&
484 [ $(get $((0x82)) "$1") == $((0x4550)) ]; then
485 mkdir -p $basedir/efi/boot 2> /dev/null
486 ln "$1" "$basedir/efi/boot/$efifile"
487 stat -c "%s %n" "$1"
488 for i in $basedir/boot/rootfs* ; do
489 ln "$i" $basedir/efi/boot/ &&
490 stat -c "%s %n" "$i"
491 done 2> /dev/null
492 sed 's|/|\\|g' > $basedir/efi/boot/linux.cmdline <<EOT
493 rw root=0x100 autologin\
494 $( ( cd $basedir/efi/boot ; ls -r rootfs*gz ) | while read f ; do \
495 echo -n " initrd=/EFI/BOOT/$f";done)
496 EOT
497 fi
498 shift
499 done; } | sort | uniq | awk '{ n+=int(($1+2047)/2048) } END { print n+1 }')
500 [ ${fclust:-0} -eq 0 ] && return
501 local dclust=$( (cd $basedir; find efi -type d 2>/dev/null) | awk '
502 BEGIN {
503 FS="/"
504 }
505 NF > 1 {
506 d[NF $NF]+=2
507 d[NF-1 $(NF-1)]+=($NF+25)/13
508 }
509 END {
510 for (i in d)
511 n+=int((d[i]+63)/64)
512 print n
513 }')
514 local clusters=$(($fclust+$dclust))
515 if [ $clusters -lt 4068 ]; then
516 fsect=$(((($clusters+2)*3+1023)/1024))
517 ftype="31 32"
518 fhead="F8 FF FF"
519 rsect=$(( 1+ ((2*$fsect)-1)%4 ))
520 fsz="$(printf "%04X" $fsect | sed 's/\(..\)\(..\)/\2 \1/')"
521 rootsz=2
522 elif [ $clusters -lt 65525 ]; then
523 fsect=$((($clusters+2+255)/256))
524 ftype="31 36"
525 fhead="F8 FF FF FF"
526 rsect=$(( 1+ ((2*$fsect)-1)%4 ))
527 fsz="$(printf "%04X" $fsect | sed 's/\(..\)\(..\)/\2 \1/')"
528 rootsz=2
529 else
530 fsect=$((($clusters+2+127)/128))
531 ftype="33 32"
532 fhead="F8 FF FF 0F FF FF FF FF F8 FF FF 0F"
533 rsect=$(( 6+ ((2*$fsect)-6)%4 ))
534 fsz="$(printf "%08X" $fsect | sed 's/\(..\)\(..\)\(..\)\(..\)/\4 \3 \2 \1/')"
535 rootsz=1
536 fi
537 # reserved + fat*2 + root dir + dirs
538 count=$((($rsect + $fsect*2)/4 + $rootsz + $dclust ))
539 s=$((($count+$fclust)*4))
540 if [ $s -gt 65535 ]; then
541 size="00 00"
542 size32="$(printf "%02X %02X %02X %02X" $(($s%256)) \
543 $((($s>>8)%256)) $((($s>>16)%256)) $((($s>>24)%256)) )"
544 else
545 size="$(printf "%02X %02X" $(($s%256)) $((($s>>8)%256)) )"
546 size32="00 00 00 00"
547 fi
548 dd if=/dev/zero bs=512 of=$basedir/boot/isolinux/efi.img \
549 count=$s 2> /dev/null
551 # Create boot sector
552 if [ "$ftype" == "33 32" ]; then
553 hexdump -R <<EOT | dd of=$basedir/boot/isolinux/efi.img \
554 conv=notrunc
555 0 eb 58 90 53 6c 69 54 61 7a 00 00 00 02 04 $rsect 00 |
556 0 02 00 00 $size f8 00 00 20 00 40 00 00 00 00 00 |
557 0 $size32 $fsz 00 00 00 00 02 00 00 00 |
558 0 01 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 |
559 0 80 00 29 00 00 00 00 53 59 53 54 45 4d 00 00 00 |
560 0 00 00 46 41 54 $ftype 20 20 20 cd 18 cd 19 eb fa |
561 EOT
562 while read ofs data; do
563 echo "0 ${data//:/ } |" | hexdump -R | dd conv=notrunc \
564 bs=1 seek=$ofs of=$basedir/boot/isolinux/efi.img
565 done <<EOT
566 510 55:aa:52:52:61:41
567 996 72:72:41:61:ff:ff:ff:ff:02
568 1022 55:aa
569 EOT
570 else
571 echo -en '\x55\xAA' | dd of=$basedir/boot/isolinux/efi.img \
572 seek=510 bs=1 conv=notrunc
573 hexdump -R <<EOT | dd of=$basedir/boot/isolinux/efi.img \
574 conv=notrunc
575 0 eb 3c 90 53 6c 69 54 61 7a 00 00 00 02 04 $rsect 00 |
576 0 02 40 00 $size f8 $fsz 20 00 40 00 00 00 00 00 |
577 0 $size32 80 00 29 00 00 00 00 53 59 53 54 45 |
578 0 4d 20 20 20 20 20 46 41 54 $ftype 20 20 20 cd 18 |
579 0 cd 19 eb fa |
580 EOT
581 fi 2> /dev/null
583 # Create fats
584 echo "0 $fhead |" | hexdump -R | dd of=$basedir/boot/isolinux/efi.img \
585 seek=$(($rsect)) bs=512 conv=notrunc 2> /dev/null
586 echo "0 $fhead |" | hexdump -R | dd of=$basedir/boot/isolinux/efi.img \
587 seek=$(($rsect+$fsect)) bs=512 conv=notrunc 2> /dev/null
589 # Add label
590 echo "0 53 59 53 54 45 4d 20 20 20 20 20 08 |" | hexdump -R | \
591 dd of=$basedir/boot/isolinux/efi.img bs=512 conv=notrunc \
592 seek=$(($rsect+$fsect+$fsect)) 2> /dev/null
594 mkdir -p /tmp/mnt$$
595 mount -o loop $basedir/boot/isolinux/efi.img /tmp/mnt$$
596 ( cd $basedir; find efi -type d | cpio -o -H newc ) | \
597 ( cd /tmp/mnt$$ ; cpio -idmu 2> /dev/null )
598 sync
599 dd if=$basedir/boot/isolinux/efi.img of=/tmp/fat$$ \
600 skip=$rsect bs=512 count=$fsect 2> /dev/null
601 ( cd $basedir; find efi -type f | cpio -o -H newc ) | \
602 ( cd /tmp/mnt$$ ; cpio -idmu 2> /dev/null )
603 umount /tmp/mnt$$
604 cat /tmp/fat$$ /tmp/fat$$ | dd of=$basedir/boot/isolinux/efi.img \
605 seek=$rsect bs=512 conv=notrunc 2> /dev/null
606 rm /tmp/fat$$
607 rmdir /tmp/mnt$$
609 dd count=0 bs=2k of=$basedir/boot/isolinux/efi.img \
610 seek=$count 2> /dev/null
611 }
614 # isolinux.conf doesn't know the kernel version.
615 # We name the kernel image 'bzImage'.
616 # isolinux/syslinux first tries the '64' suffix with a 64bits cpu.
618 make_bzImage_hardlink() {
619 if [ -e ${1:-.}/vmlinuz*slitaz ]; then
620 rm -f ${1:-.}/bzImage 2>/dev/null
621 ln ${1:-.}/vmlinuz*slitaz ${1:-.}/bzImage
622 fi
623 if [ -e ${1:-.}/vmlinuz*slitaz64 ]; then
624 rm -f ${1:-.}/bzImage64 2> /dev/null
625 ln ${1:-.}/vmlinuz*slitaz64 ${1:-.}/bzImage64
626 fi
627 }
630 create_iso() {
631 cd $2
632 deduplicate
634 [ $(ls $2/boot/grub* 2> /dev/null | wc -l) -lt 2 ] && rm -rf $2/boot/grub*
635 make_bzImage_hardlink $2/boot
636 alloc_uefi_part $(ls -r $2/boot/vmlinuz*slitaz*)
638 cat > /tmp/cdsort$$ <<EOT
639 $PWD/boot/isolinux 100
640 $(ls -r $PWD/boot/rootfs* | awk 'BEGIN{n=149} { print $1 " " n-- }')
641 $(ls $PWD/boot/bzImage* | awk 'BEGIN{n=200} { print $1 " " n-- }')
642 $(find $PWD/efi -type f 2>/dev/null | sort -r | awk 'BEGIN{n=299} { print $1 " " n-- }')
643 $PWD/boot/isolinux/efi.img 300
644 $PWD/boot/isolinux/isolinux.bin 399
645 $PWD/boot/isolinux/boot.cat 400
646 EOT
648 action 'Computing md5...'
649 touch boot/isolinux/boot.cat
650 find * -type f ! -name md5sum ! -name 'vmlinuz-*' -exec md5sum {} \; | \
651 sort -k 2 > md5sum
652 status
654 cd - >/dev/null
655 title 'Generating ISO image'
657 _ 'Generating %s' "$1"
658 uefi="$(cd $2 ; ls boot/isolinux/efi.img 2> /dev/null)"
659 genisoimage -R -o $1 -hide-rr-moved -sort /tmp/cdsort$$ \
660 -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat \
661 -no-emul-boot -boot-load-size 4 -boot-info-table \
662 ${uefi:+-eltorito-alt-boot -efi-boot $uefi -no-emul-boot} \
663 -V "${VOLUM_NAME:-SliTaz}" -p "${PREPARED:-$(id -un)}" \
664 -volset "SliTaz $SLITAZ_VERSION" -input-charset utf-8 \
665 -A "tazlito $VERSION/$(genisoimage --version)" \
666 -copyright README -P "www.slitaz.org" -no-pad $2
667 rm -f /tmp/cdsort$$
668 dd if=/dev/zero bs=2k count=16 >> $1 2> /dev/null
670 mkdir /tmp/mnt$$
671 mount -o loop,ro $1 /tmp/mnt$$
672 fixup_uefi_part $1 /tmp/mnt$$
673 for i in boot/isolinux/isolinux.bin boot/isolinux/boot.cat \
674 ${uefi:+boot/isolinux/efi.img} ; do
675 sed -i "s|.* $i|$( cd /tmp/mnt$$ ; md5sum $i)|" $2/md5sum
676 done
677 dd if=$2/md5sum of=$1 conv=notrunc bs=2k \
678 seek=$(first_block /tmp/mnt$$/md5sum) 2> /dev/null
679 umount -d /tmp/mnt$$
680 rmdir /tmp/mnt$$
682 if [ -s '/etc/tazlito/info' ]; then
683 if [ $(stat -c %s /etc/tazlito/info) -lt $(( 31*1024 )) ]; then
684 action 'Storing ISO info...'
685 dd if=/etc/tazlito/info bs=1k seek=1 of=$1 conv=notrunc 2>/dev/null
686 status
687 fi
688 fi
690 if [ -x '/usr/bin/isohybrid' ]; then
691 action 'Creating hybrid ISO...'
692 isohybrid $1 $([ -n "$uefi" ] || echo -entry 2) 2>/dev/null
693 status
694 fi
696 if [ -x '/usr/bin/iso2exe' ]; then
697 echo 'Creating EXE header...'
698 /usr/bin/iso2exe $1 2>/dev/null
699 fi
700 }
703 # Generate a new ISO image using isolinux.
705 gen_livecd_isolinux() {
706 # Some packages may want to alter iso
707 genisohooks iso
708 [ ! -f "$ROOTCD/boot/isolinux/isolinux.bin" ] && die 'Unable to find isolinux binary.'
710 # Set date for boot msg.
711 if grep -q 'XXXXXXXX' "$ROOTCD/boot/isolinux/isolinux.cfg"; then
712 DATE=$(date +%Y%m%d)
713 action 'Setting build date to: %s...' "$DATE"
714 sed -i "s/XXXXXXXX/$DATE/" "$ROOTCD/boot/isolinux/isolinux.cfg"
715 status
716 fi
718 cd $DISTRO
719 create_iso $ISO_NAME.iso $ROOTCD
721 action 'Creating the ISO md5sum...'
722 md5sum $ISO_NAME.iso > $ISO_NAME.md5
723 status
725 separator
726 # Some packages may want to alter final iso
727 genisohooks final
728 }
731 lzma_history_bits() {
732 #
733 # This generates an ISO which boots with Qemu but gives
734 # rootfs errors in frugal or liveUSB mode.
735 #
736 # local n
737 # local sz
738 # n=20 # 1Mb
739 # sz=$(du -sk $1 | cut -f1)
740 # while [ $sz -gt 1024 -a $n -lt 28 ]; do
741 # n=$(( $n + 1 ))
742 # sz=$(( $sz / 2 ))
743 # done
744 # echo $n
745 echo ${LZMA_HISTORY_BITS:-24}
746 }
749 lzma_switches() {
750 local proc_num=$(grep -sc '^processor' /proc/cpuinfo)
751 echo "-d$(lzma_history_bits $1) -mt${proc_num:-1} -mc1000"
752 }
755 lzma_set_size() {
756 # Update size field for lzma'd file packed using -si switch
757 return # Need to fix kernel code?
759 local n i
760 n=$(unlzma < $1 | wc -c)
761 for i in $(seq 1 8); do
762 printf '\\\\x%02X' $(($n & 255))
763 n=$(($n >> 8))
764 done | xargs echo -en | dd of=$1 conv=notrunc bs=1 seek=5 2>/dev/null
765 }
768 align_to_32bits() {
769 local size=$(stat -c %s ${1:-/dev/null})
770 [ $((${size:-0} & 3)) -ne 0 ] &&
771 dd if=/dev/zero bs=1 count=$((4 - ($size & 3))) >> $1 2>/dev/null
772 }
775 dogzip() {
776 gzip -9 > $1
777 [ -x /usr/bin/advdef ] && advdef -qz4 $1
778 }
781 # Pack rootfs
783 pack_rootfs() {
784 ( cd $1; find . -print | cpio -o -H newc ) | \
785 case "$COMPRESSION" in
786 none)
787 _ 'Creating %s without compression...' 'initramfs'
788 cat > $2
789 ;;
790 gzip)
791 _ 'Creating %s with gzip compression...' 'initramfs'
792 dogzip $2
793 ;;
794 *)
795 _ 'Creating %s with lzma compression...' 'initramfs'
796 lzma e -si -so $(lzma_switches $1) > $2
797 lzma_set_size $2
798 ;;
799 esac
800 align_to_32bits $2
801 echo 1 > /tmp/rootfs
802 }
805 # Compression functions for writeiso.
807 write_initramfs() {
808 case "$COMPRESSION" in
809 lzma)
810 _n 'Creating %s with lzma compression...' "$INITRAMFS"
811 cpio -o -H newc | lzma e -si -so $(lzma_switches) > "/$INITRAMFS"
812 align='y'
813 lzma_set_size "/$INITRAMFS"
814 ;;
815 gzip)
816 _ 'Creating %s with gzip compression...' "$INITRAMFS"
817 cpio -o -H newc | dogzip "/$INITRAMFS"
818 ;;
819 *)
820 # align='y'
821 _ 'Creating %s without compression...' "$INITRAMFS"
822 cpio -o -H newc > "/$INITRAMFS"
823 ;;
824 esac < /tmp/list
825 [ "$align" == 'y' -a -z "$noalign" ] && align_to_32bits "/$INITRAMFS"
826 echo 1 > /tmp/rootfs
827 }
830 # Deduplicate files (MUST be on the same filesystem).
832 deduplicate() {
833 find "${@:-.}" -type f -size +0c -xdev -exec stat -c '%s-%a-%u-%g %i %h %n' {} \; | sort | \
834 (
835 save=0; hardlinks=0; old_attr=""; old_inode=""; old_link=""; old_file=""
836 while read attr inode link file; do
837 [ -L "$file" ] && continue
838 if [ "$attr" == "$old_attr" -a "$inode" != "$old_inode" ]; then
839 if cmp "$file" "$old_file" >/dev/null 2>&1 ; then
840 rm -f "$file"
841 if ln "$old_file" "$file" 2>/dev/null; then
842 inode="$old_inode"
843 [ "$link" -eq 1 ] && hardlinks=$(($hardlinks+1)) &&
844 save="$(($save+(${attr%%-*}+512)/1024))"
845 else
846 cp -a "$old_file" "$file"
847 fi
848 fi
849 fi
850 old_attr="$attr" ; old_inode="$inode" ; old_file="$file"
851 done
852 _ '%s Kbytes saved in %s duplicate files.' "$save" "$hardlinks"
853 )
855 find "$@" -type l -xdev -exec stat -c '%s-%u-%g-TARGET- %i %h %n' {} \; | sort | \
856 (
857 old_attr=""; hardlinks=0;
858 while read attr inode link file; do
859 attr="${attr/-TARGET-/-$(readlink $file)}"
860 if [ "$attr" == "$old_attr" ]; then
861 if [ "$inode" != "$old_inode" ]; then
862 rm -f "$file"
863 if ln "$old_file" "$file" 2>/dev/null; then
864 [ "$link" -eq 1 ] && hardlinks=$(($hardlinks+1))
865 else
866 cp -a "$old_file" "$file"
867 fi
868 fi
869 else
870 old_file="$file"
871 old_attr="$attr"
872 old_inode="$inode"
873 fi
874 done
875 _ '%s duplicate symlinks.' "$hardlinks"
876 )
877 }
880 # Generate a new initramfs from the root filesystem.
882 gen_initramfs() {
883 # Just in case CTRL+c
884 rm -f $DISTRO/gen
886 # Some packages may want to alter rootfs
887 genisohooks rootfs
888 cd $1
890 # Normalize file time
891 find $1 -newer $1 -exec touch -hr $1 {} \;
893 # Link duplicate files
894 deduplicate
896 # Use lzma if installed. Display rootfs size in realtime.
897 rm -f /tmp/rootfs 2>/dev/null
898 pack_rootfs . $DISTRO/$(basename $1).gz &
899 sleep 2
900 echo -en "\nFilesystem size:"
901 while [ ! -f /tmp/rootfs ]; do
902 sleep 1
903 echo -en "\\033[18G$(du -sh $DISTRO/$(basename $1).gz | awk '{print $1}') "
904 done
905 echo -e "\n"
906 rm -f /tmp/rootfs
907 cd $DISTRO
908 mv $(basename $1).gz $ROOTCD/boot
909 }
912 distro_sizes() {
913 if [ -n "$start_time" ]; then
914 time=$(($(date +%s) - $start_time))
915 sec=$time
916 div=$(( ($time + 30) / 60))
917 [ "$div" -ne 0 ] && min="~ ${div}m"
918 _ 'Build time : %ss %s' "$sec" "$min"
919 fi
920 cat <<EOT
921 Build date : $(date +%Y%m%d)
922 Packages : $(ls -1 $ROOTFS*$INSTALLED/*/receipt | wc -l)
923 Rootfs size : $(du -csh $ROOTFS*/ | awk 'END { print $1 }')
924 Initramfs size : $(du -csh $ROOTCD/boot/rootfs*.gz | awk 'END { print $1 }')
925 ISO image size : $(du -sh $ISO_NAME.iso | awk '{ print $1 }')
926 EOT
927 footer "Image is ready: $ISO_NAME.iso"
928 }
931 # Print ISO and rootfs size.
933 distro_stats() {
934 title 'Distro statistics: %s' "$DISTRO"
935 distro_sizes
936 }
939 # Create an empty configuration file.
941 empty_config_file() {
942 cat >> tazlito.conf <<"EOF"
943 # tazlito.conf: Tazlito (SliTaz Live Tool) configuration file.
944 #
946 # Name of the ISO image to generate.
947 ISO_NAME=""
949 # ISO image volume name.
950 VOLUM_NAME="SliTaz"
952 # Name of the preparer.
953 PREPARED="$USER"
955 # Path to the packages repository and the packages.list.
956 PACKAGES_REPOSITORY=""
958 # Path to the distro tree to gen-distro from a list of packages.
959 DISTRO=""
961 # Path to the directory containing additional files
962 # to copy into the rootfs and rootcd of the LiveCD.
963 ADDFILES="$DISTRO/addfiles"
965 # Default answer for binary question (Y or N)
966 DEFAULT_ANSWER="ASK"
968 # Compression utility (lzma, gzip or none)
969 COMPRESSION="lzma"
970 EOF
971 }
974 # Extract rootfs.gz somewhere
976 extract_rootfs() {
977 # Detect compression format: *.lzma.cpio, *.gzip.cpio, or *.cpio
978 # First part (lzcat or zcat) may not fail, but cpio will fail on incorrect format
979 (cd "$2"; lzcat "$1" | cpio -idm --quiet 2>/dev/null) && return
980 (cd "$2"; zcat "$1" | cpio -idm --quiet 2>/dev/null) && return
981 (cd "$2"; cat "$1" | cpio -idm --quiet 2>/dev/null)
982 }
985 # Extract flavor file to temp directory
987 extract_flavor() {
988 # Input: $1 - flavor name to extract;
989 # $2 = absent/empty: just extract 'outer layer'
990 # $2 = 'full': also extract 'inner' rootcd and rootfs archives, make files rename
991 # $2 = 'info': as 'full' and also make 'info' file to put into ISO
992 # Output: temp dir path where flavor was extracted
993 local f="$1.flavor" from to infos="$1.desc"
994 [ -f "$f" ] || die "File '$f' not found"
995 local dir="$(mktemp -d)"
996 zcat "$f" | (cd $dir; cpio -i --quiet >/dev/null)
998 if [ -n "$2" ]; then
999 cd $dir
1001 [ -s "$1.receipt" ] && infos="$infos\n$1.receipt"
1003 for i in rootcd rootfs; do
1004 [ -f "$1.$i" ] || continue
1005 mkdir "$i"
1006 zcat "$1.$i" | (cd "$i"; cpio -idm --quiet 2>/dev/null)
1007 zcat "$1.$i" | cpio -tv 2>/dev/null > "$1.list$i"; infos="$infos\n$1.list$i"
1008 rm "$1.$i"
1009 done
1010 touch -t 197001010100.00 $1.*
1011 # Info to be stored inside ISO
1012 [ "$2" == info ] && echo -e $infos | cpio -o -H newc | dogzip info
1013 rm $1.list*
1015 # Renames
1016 while read from to; do
1017 [ -f "$from" ] || continue
1018 mv "$from" "$to"
1019 done <<EOT
1020 $1.nonfree non-free.list
1021 $1.pkglist packages.list
1022 $1-distro.sh distro.sh
1023 $1.receipt receipt
1024 $1.mirrors mirrors
1025 $1.desc description
1026 EOT
1027 fi
1029 echo $dir
1033 # Pack flavor file from temp directory
1035 pack_flavor() {
1036 (cd "$1"; ls | grep -v err | cpio -o -H newc) | dogzip "$2.flavor"
1040 # Remove duplicate files
1042 files_match() {
1043 if [ -d "$1" ]; then
1044 return 1
1046 elif [ -L "$1" ] && [ -L "$2" ]; then
1047 [ "$(readlink "$1")" == "$(readlink "$2")" ] && return 0
1049 elif [ -f "$1" ] && [ -f "$2" ]; then
1050 cmp -s "$1" "$2" && return 0
1052 [ "$(basename "$3")" == 'volatile.cpio.gz' ] &&
1053 [ "$(dirname $(dirname "$3"))" == ".$INSTALLED" ] &&
1054 return 0
1056 elif [ "$(ls -l "$1"|cut -c1-10)$(stat -c '%a:%u:%g:%t:%T' "$1")" == \
1057 "$(ls -l "$2"|cut -c1-10)$(stat -c '%a:%u:%g:%t:%T' "$2")" ]; then
1058 return 0
1060 fi 2> /dev/null
1061 return 1
1064 remove_with_path() {
1065 dir="$(dirname $1)"
1066 rm -f "$1"
1067 while rmdir "$dir" 2> /dev/null; do
1068 dir="$(dirname $dir)"
1069 done
1072 mergefs() {
1073 # Note, many packages have files with spaces in the name
1074 IFS=$'\n'
1076 local size1=$(du -hs "$1" | awk '{ print $1 }')
1077 local size2=$(du -hs "$2" | awk '{ print $1 }')
1078 action 'Merge %s (%s) into %s (%s)' "$(basename "$1")" "$size1" "$(basename "$2")" "$size2"
1080 # merge symlinks files and devices
1081 ( cd "$1"; find ) | \
1082 while read file; do
1083 files_match "$1/$file" "$2/$file" "$file" &&
1084 remove_with_path "$2/$file"
1085 [ -d "$1/$file" ] && [ -d "$2/$file" ] && rmdir "$2/$file" 2>/dev/null
1086 done
1088 unset IFS
1089 status
1093 cleanup_merge() {
1094 rm -rf $TMP_DIR
1095 exit 1
1099 # Update isolinux config files for multiple rootfs
1101 update_bootconfig() {
1102 local files
1103 action 'Updating boot config files...'
1104 files="$(grep -l 'include common' $1/*.cfg)"
1105 for file in $files; do
1106 awk -v n=$(echo $2 | awk '{ print NF/2 }') '{
1107 if (/label/) label=$0;
1108 else if (/kernel/) kernel=$0;
1109 else if (/append/) {
1110 i=index($0,"rootfs.gz");
1111 append=substr($0,i+9);
1113 else if (/include/) {
1114 for (i = 1; i <= n; i++) {
1115 print label i
1116 print kernel;
1117 initrd="initrd=/boot/rootfs" n ".gz"
1118 for (j = n - 1; j >= i; j--) {
1119 initrd=initrd ",/boot/rootfs" j ".gz";
1121 printf "\tappend %s%s\n",initrd,append;
1122 print "";
1124 print;
1126 else print;
1127 }' < $file > $file.$$
1128 mv -f $file.$$ $file
1129 done
1130 sel="$(echo $2 | awk '{
1131 for (i=1; i<=NF; i++)
1132 if (i % 2 == 0) printf " slitaz%d", i/2
1133 else printf " %s", $i
1134 }')"
1136 [ -s $1/common.cfg ] && cat >> $1/common.cfg <<EOT
1138 label slitaz
1139 kernel /boot/isolinux/ifmem.c32
1140 append$sel noram
1142 label noram
1143 config noram.cfg
1145 EOT
1147 # Update vesamenu
1148 if [ -s "$1/isolinux.cfg" ]; then
1149 files="$files $1/isolinux.cfg"
1150 awk -v n=$(echo $2 | awk '{ print NF/2 }') -v "sel=$sel" '
1151 BEGIN {
1152 kernel = " COM32 c32box.c32"
1155 if (/ROWS/) print "MENU ROWS " n+$3;
1156 else if (/TIMEOUTROW/) print "MENU TIMEOUTROW " n+$3;
1157 else if (/TABMSGROW/) print "MENU TABMSGROW " n+$3;
1158 else if (/CMDLINEROW/) print "MENU CMDLINEROW " n+$3;
1159 else if (/VSHIFT/) {
1160 x = $3-n;
1161 if (x < 0) x = 0;
1162 print "MENU VSHIFT " x;
1164 else if (/rootfs.gz/) {
1165 linux = "";
1166 if (/bzImage/) linux = "linux /boot/bzImage ";
1167 i = index($0, "rootfs.gz");
1168 append = substr($0, i+9);
1169 printf "\tkernel /boot/isolinux/ifmem.c32\n";
1170 printf "\tappend%s noram\n", sel;
1171 printf "\nlabel noram\n\tMENU HIDE\n\tconfig noram.cfg\n\n";
1172 for (i = 1; i <= n; i++) {
1173 print "LABEL slitaz" i
1174 printf "\tMENU LABEL SliTaz slitaz%d Live\n", i;
1175 printf "%s\n", kernel;
1176 initrd = "initrd=/boot/rootfs" n ".gz"
1177 for (j = n - 1; j >= i; j--) {
1178 initrd = initrd ",/boot/rootfs" j ".gz";
1180 printf "\tappend %s%s%s\n\n", linux, initrd, append;
1183 else if (/bzImage/) kernel = $0;
1184 else print;
1185 }' < $1/isolinux.cfg > $1/isolinux.cfg.$$
1186 mv $1/isolinux.cfg.$$ $1/isolinux.cfg
1187 fi
1189 [ -s $1/c32box.c32 ] && sed -i -e '/kernel.*ifmem/d' \
1190 -e 's/append \([0-9]\)/append ifmem \1/' $1/isolinux.cfg
1191 cat > $1/noram.cfg <<EOT
1192 implicit 0
1193 prompt 1
1194 timeout 80
1195 $(grep '^F[0-9]' $1/isolinux.cfg)
1197 $([ -s $1/isolinux.msg ] && echo display isolinux.msg)
1198 say Not enough RAM to boot slitaz. Trying hacker mode...
1199 default hacker
1200 label hacker
1201 KERNEL /boot/bzImage
1202 append rw root=/dev/null vga=normal
1204 label reboot
1205 EOT
1207 if [ -s $1/c32box.c32 ]; then
1208 cat >> $1/noram.cfg <<EOT
1209 COM32 c32box.c32
1210 append reboot
1212 label poweroff
1213 COM32 c32box.c32
1214 append poweroff
1216 EOT
1217 else
1218 echo " com32 reboot.c32" >> $1/noram.cfg
1219 fi
1221 # Restore real label names
1222 [ -s $1/common.cfg ] && files="$1/common.cfg $files"
1223 echo $2 | awk '{ for (i=NF; i>1; i-=2) printf "%d/%s\n",i/2,$i }' | \
1224 while read pat; do
1225 sed -i "s/slitaz$pat/" $files
1226 done
1227 status
1231 # Uncompress rootfs or module to stdout
1233 uncompress() {
1234 zcat $1 2> /dev/null || xzcat $1 2> /dev/null ||
1235 { [ $(od -N 1 -An $1) -eq 135 ] && unlzma < $1; } || cat $1
1239 # Install a missing package
1241 install_package() {
1242 if [ -z "$2" ]; then
1243 answer=$(yesorno "$(_ 'Install package %s?' "$1")" 'n')
1244 else
1245 answer=$(yesorno "$(_n 'Install package %s for Kernel %s? ' "$1" "$2")" 'n')
1246 fi
1247 case "$answer" in
1248 y)
1249 # We don't want package on host cache.
1250 action 'Getting and installing package: %s' "$1"
1251 yes y | tazpkg get-install $1 --quiet 2>&1 >> $log || exit 1
1252 status ;;
1253 *)
1254 return 1 ;;
1255 esac
1259 # Check iso for loram transformation
1261 check_iso_for_loram() {
1262 [ -s "$TMP_DIR/iso/boot/rootfs.gz" ] ||
1263 [ -s "$TMP_DIR/iso/boot/rootfs1.gz" ]
1267 # Remove duplicated files in $1/efi/boot from $1/boot
1269 cleanup_efi_boot() {
1270 for i in $1/efi/boot/* ; do
1271 [ -f $i ] || continue
1272 case "$i" in
1273 */rootfs*) cmp $i ${i/\/efi\//\/} || continue ;;
1274 */bootia32.efi) cmp $i $1/boot/bzImage || continue
1275 rm $1/efi/boot/linux.cmdline ;;
1276 */bootx64.efi) cmp $i $1/boot/bzImage64 || continue
1277 rm $1/efi/boot/linux.cmdline* ;;
1278 esac
1279 rm -f $i
1280 rmdir $1/efi/boot && rmdir $1/efi
1281 done 2> /dev/null
1285 # Build initial rootfs for loram ISO ram/cdrom/http
1287 build_initfs() {
1288 urliso="mirror.switch.ch/ftp/mirror/slitaz \
1289 download.tuxfamily.org/slitaz mirror1.slitaz.org mirror2.slitaz.org \
1290 mirror3.slitaz.org mirror.slitaz.org"
1291 version=$(ls $TMP_DIR/iso/boot/vmlinuz-* | sed 's/.*vmlinuz-//')
1292 [ -z "$version" ] && die "Can't find the kernel version." \
1293 'No file /boot/vmlinuz-<version> in ISO image. Abort.'
1295 [ -s /usr/share/boot/busybox-static ] || install_package busybox-static
1296 need_lib=false
1297 for i in bin dev run mnt proc tmp sys lib/modules; do
1298 mkdir -p $TMP_DIR/initfs/$i
1299 done
1300 ln -s bin $TMP_DIR/initfs/sbin
1301 ln -s . $TMP_DIR/initfs/usr
1302 for aufs in aufs overlayfs; do
1303 [ -f /lib/modules/$version/kernel/fs/$aufs/$aufs.ko.?z ] && break
1304 install_package linux-$aufs $version && break
1305 install_package $aufs $version && break
1306 done || return 1
1307 [ -s /init ] || install_package slitaz-boot-scripts
1308 cp /init $TMP_DIR/initfs/
1309 cp /lib/modules/$version/kernel/fs/$aufs/$aufs.ko.?z \
1310 $TMP_DIR/initfs/lib/modules
1311 if [ "$1" == 'cdrom' ]; then
1312 sed -i '/mod squashfs/d' $TMP_DIR/initfs/init
1313 else
1314 [ ! -f /usr/sbin/mksquashfs ] && ! install_package squashfs && return 1
1315 while [ ! -f /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z ]; do
1316 install_package linux-squashfs $version || return 1
1317 done
1318 cp /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z \
1319 $TMP_DIR/initfs/lib/modules
1320 #ls /sbin/unsquashfs /usr/lib/liblzma.so* $INSTALLED/squashfs/* | \
1321 #cpio -o -H newc > $TMP_DIR/initfs/extractfs.cpio
1322 fi
1323 if [ "$1" == 'http' ]; then
1324 mkdir $TMP_DIR/initfs/etc $TMP_DIR/fs
1325 ln -s /proc/mounts $TMP_DIR/initfs/etc/mtab
1326 cp /usr/share/udhcpc/default.script $TMP_DIR/initfs/lib/udhcpc
1327 sed -i 's|/sbin/||;s/^logger/#&/' $TMP_DIR/initfs/lib/udhcpc
1328 cp -a /dev/fuse $TMP_DIR/initfs/dev
1329 if ! $need_lib && [ -x /usr/share/boot/fusermount-static ]; then
1330 cp /usr/share/boot/fusermount-static $TMP_DIR/initfs/bin/fusermount
1331 else
1332 need_lib=true
1333 fi
1334 if ! $need_lib && [ -x /usr/share/boot/httpfs-static ]; then
1335 cp /usr/share/boot/httpfs-static $TMP_DIR/initfs/bin/httpfs
1336 else
1337 [ ! -f /usr/bin/httpfs ] && ! install_package httpfs-fuse && return 1
1338 cp /usr/bin/httpfs $TMP_DIR/initfs/bin
1339 cp /usr/bin/fusermount $TMP_DIR/initfs/bin
1340 cp -a /lib/librt* $TMP_DIR/initfs/lib
1341 cp -a /lib/libdl* $TMP_DIR/initfs/lib
1342 cp -a /lib/libpthread* $TMP_DIR/initfs/lib
1343 cp -a /usr/lib/libfuse* $TMP_DIR/initfs/lib
1344 cp -a /lib/libresolv* $TMP_DIR/initfs/lib
1345 cp -a /lib/libnss_dns* $TMP_DIR/initfs/lib
1346 need_lib=true
1347 fi
1348 cd $TMP_DIR/fs
1349 echo 'Getting slitaz-release & ethernet modules...'
1350 for i in $(ls -r $TMP_DIR/iso/boot/rootfs*z); do
1351 uncompress $i | cpio -idmu etc/slitaz-release lib/modules rootfs*
1352 [ -s rootfs* ] || continue
1353 unsquashfs -f -d . rootfs* rootfs* etc/slitaz-release lib/modules &&
1354 rm -f rootfs*
1355 done 2>&1 > /dev/null
1356 cd - > /dev/null
1357 cp $TMP_DIR/fs/etc/slitaz-release $TMP_DIR/initfs/etc/
1358 find $TMP_DIR/fs/lib/modules/*/kernel/drivers/net/ethernet \
1359 -type f -name '*.ko*' | while read mod; do
1360 f=$TMP_DIR/initfs/lib/modules/$(basename $mod | sed s/..z$//)
1361 uncompress $mod > $f
1362 grep -q alias=pci: $f || rm -f $f
1363 done
1364 for i in $TMP_DIR/initfs/lib/modules/*.ko ; do
1365 f=$(basename $i)..z
1366 grep -q $f:$ $TMP_DIR/fs/lib/modules/*/modules.dep && continue
1367 deps="$(grep $f: $TMP_DIR/fs/lib/modules/*/modules.dep | sed 's/.*: //')"
1368 echo "$deps" | sed 's|kernel/[^ ]*/||g;s/.ko..z//g' > $TMP_DIR/initfs/lib/modules/$(basename $i .ko).dep
1369 for j in $deps; do
1370 mod=$(ls $TMP_DIR/fs/lib/modules/*/$j)
1371 uncompress $mod > $TMP_DIR/initfs/lib/modules/$(basename $j | sed s/..z$//)
1372 done
1373 done
1374 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"
1375 _n 'List of URLs to insert: '
1376 read -t 30 urliso2
1377 urliso="$urliso2 $urliso"
1378 fi
1379 if ! $need_lib && [ -x /usr/share/boot/busybox-static ]; then
1380 cp /usr/share/boot/busybox-static $TMP_DIR/initfs/bin/busybox
1381 sed -i 's/LD_T.*ot/echo/;s/".*ld-.*) /"/' $TMP_DIR/initfs/init
1382 else
1383 cp /bin/busybox $TMP_DIR/initfs/bin
1384 if ! cmp /bin/busybox /sbin/insmod > /dev/null ; then
1385 cp /sbin/insmod $TMP_DIR/initfs/bin
1386 cp -a /lib/libkmod.so.* $TMP_DIR/initfs/lib
1387 cp -a /usr/lib/liblzma.so.* $TMP_DIR/initfs/lib
1388 cp -a /usr/lib/libz.so.* $TMP_DIR/initfs/lib
1389 fi
1390 need_lib=true
1391 fi
1392 for i in $($TMP_DIR/initfs/bin/busybox | awk \
1393 '{ if (s) printf "%s",$0 } /Currently/ { s=1 }' | sed 's/,//g'); do
1394 ln $TMP_DIR/initfs/bin/busybox $TMP_DIR/initfs/bin/$i
1395 done
1396 # bootfloppybox will need floppy.ko.?z, /dev/fd0, /dev/tty0
1397 cp /lib/modules/$version/kernel/drivers/block/floppy.ko.?z \
1398 $TMP_DIR/initfs/lib/modules 2>/dev/null
1399 for i in /dev/console /dev/null /dev/tty /dev/tty0 /dev/zero \
1400 /dev/kmem /dev/mem /dev/random /dev/urandom; do
1401 cp -a $i $TMP_DIR/initfs/dev
1402 done
1403 grep -q '/sys/block/./dev' $TMP_DIR/initfs/init ||
1404 for i in /dev/fd0 /dev/[hs]d[a-f]* /dev/loop* ; do
1405 cp -a $i $TMP_DIR/initfs/dev
1406 done 2>/dev/null
1407 $need_lib && for i in /lib/ld-* /lib/lib[cm][-\.]* ; do
1408 cp -a $i $TMP_DIR/initfs/lib
1409 done
1410 [ "$1" == 'http' ] && cat > $TMP_DIR/initfs/init <<EOTEOT
1411 #!/bin/sh
1413 getarg() {
1414 grep -q " \$1=" /proc/cmdline || return 1
1415 eval \$2=\$(sed "s/.* \$1=\\\\([^ ]*\\\\).*/\\\\1/" < /proc/cmdline)
1416 return 0
1419 copy_rootfs() {
1420 total=\$(grep MemTotal /proc/meminfo | sed 's/[^0-9]//g')
1421 need=\$(du -c \${path}rootfs* | tail -n 1 | cut -f1)
1422 [ \$(( \$total / \$need )) -gt 1 ] || return 1
1423 if ! grep -q " keep-loram" /proc/cmdline && cp \${path}rootfs* /mnt; then
1424 path=/mnt/
1425 return 0
1426 else
1427 rm -f /mnt/rootfs*
1428 return 1
1429 fi
1432 echo "Switching / to tmpfs..."
1433 mount -t proc proc /proc
1434 size="\$(grep rootfssize= < /proc/cmdline | \\
1435 sed 's/.*rootfssize=\\([0-9]*[kmg%]\\).*/-o size=\\1/')"
1436 [ -n "\$size" ] || size="-o size=90%"
1438 mount -t sysfs sysfs /sys
1439 for i in /lib/modules/*.ko ; do
1440 echo -en "Probe \$i \\r"
1441 for j in \$(grep alias=pci: \$i | sed 's/alias//;s/\*/.*/g'); do
1442 grep -q "\$j" /sys/bus/pci/devices/*/uevent || continue
1443 for k in \$(cat \${i/ko/dep} 2> /dev/null); do
1444 insmod /lib/modules/\$k.ko 2> /dev/null
1445 done
1446 echo "Loading \$i"
1447 insmod \$i 2> /dev/null
1448 break
1449 done
1450 done
1451 umount /sys
1452 while read var default; do
1453 eval \$var=\$default
1454 getarg \$var \$var
1455 done <<EOT
1456 eth eth0
1457 dns 208.67.222.222,208.67.220.220
1458 netmask 255.255.255.0
1459 gw
1460 ip
1461 EOT
1462 grep -q \$eth /proc/net/dev || sh
1463 if [ -n "\$ip" ]; then
1464 ifconfig \$eth \$ip netmask \$netmask up
1465 route add default gateway \$gw
1466 for i in \$(echo \$dns | sed 's/,/ /g'); do
1467 echo "nameserver \$i" >> /etc/resolv.conf
1468 done
1469 else
1470 udhcpc -f -q -s /lib/udhcpc -i \$eth
1471 fi
1472 for i in $urliso ; do
1473 [ -n "\$URLISO" ] && URLISO="\$URLISO,"
1474 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"
1475 URLISO="\$URLISO,http://\$i/iso/rolling/slitaz-rolling-loram-cdrom.iso,http://\$i/iso/rolling/slitaz-rolling-loram.iso"
1476 done
1477 getarg urliso URLISO
1478 DIR=fs
1479 if getarg loram DIR; then
1480 DEVICE=\${DIR%,*}
1481 DIR=/\${DIR#*,}
1482 fi
1483 mount -t tmpfs \$size tmpfs /mnt
1484 path2=/mnt/.httpfs/
1485 path=/mnt/.cdrom/
1486 mkdir -p /mnt/.rw /mnt/.wd \$path \$path2
1487 while [ ! -d \$path/boot ]; do
1488 for i in \$(echo \$URLISO | sed 's/,/ /g'); do
1489 httpfs \$i \$path2 && echo \$i && break
1490 done
1491 mount -o loop,ro -t iso9660 \$path2/*.iso \$path || sh
1492 done
1494 memfree=\$(grep MemFree /proc/meminfo | sed 's/[^0-9]//g')
1495 umount /proc
1496 branch=:/mnt/.cdrom/\$DIR
1497 if [ ! -d /mnt/.cdrom/\$DIR/etc ]; then
1498 branch=
1499 lp=1
1500 insmod /lib/modules/squashfs.ko 2> /dev/null
1501 for i in \${path}boot/rootfs?.* ; do
1502 fs=\${i#*root}
1503 branch=\$branch:/mnt/.\$fs
1504 mkdir -p /mnt/.rw/mnt/.\$fs /mnt/.\$fs /mnt/.rw/mnt/.cdrom
1505 losetup -o 124 /dev/loop\$lp \$i
1506 mount -o loop,ro -t squashfs /dev/loop\$lp /mnt/.\$fs
1507 lp=\$((\$lp+1))
1508 done
1509 fi
1510 mkdir -p /mnt/.rw/mnt/.httpfs
1511 while read type opt; do
1512 insmod /lib/modules/\$type.ko && mount -t \$type -o \$opt none /mnt && break
1513 done <<EOT
1514 aufs br=/mnt/.rw\$branch
1515 overlayfs workdir=/mnt/.wd\${branch/:/,lowerdir=},upperdir=/mnt/.rw
1516 EOT
1517 rm -rf /lib/modules
1518 [ -x /bin/httpfs ] && sed -i 's/DHCP="yes"/DHCP="no"/' /mnt/etc/network.conf
1519 [ \$memfree -lt 30000 ] && sed -i 's/ slim//' /mnt/etc/rcS.conf
1520 [ -x /mnt/sbin/init ] && exec /bin/switch_root mnt /sbin/init || sh
1521 EOTEOT
1522 chmod +x $TMP_DIR/initfs/init
1523 for i in $TMP_DIR/initfs/lib/modules/*z ; do
1524 unxz $i || gunzip $i || lzma d $i ${i%.gz}
1525 rm -f $i
1526 done 2>/dev/null
1527 (cd $TMP_DIR/initfs; find | busybox cpio -o -H newc 2>/dev/null) | \
1528 lzma e $TMP_DIR/initfs.gz -si
1529 lzma_set_size $TMP_DIR/initfs.gz
1530 rm -rf $TMP_DIR/initfs
1531 align_to_32bits $TMP_DIR/initfs.gz
1532 return 0
1536 # Move each initramfs to squashfs
1538 build_loram_rootfs() {
1539 rootfs_sizes=""
1540 for i in $TMP_DIR/iso/boot/rootfs*; do
1541 mkdir -p $TMP_DIR/fs
1542 cd $TMP_DIR/fs
1543 uncompress $i | cpio -idm
1544 deduplicate
1545 cd - > /dev/null
1546 rootfs=$TMP_DIR/$(basename $i)
1547 /usr/sbin/mksquashfs $TMP_DIR/fs $rootfs -comp ${1:-xz -Xbcj x86}
1548 cd $TMP_DIR
1549 rootfs_sizes="$rootfs_sizes $(( $(du -s $TMP_DIR/fs | cut -f1) - $(du -s $rootfs | cut -f1) ))"
1550 ( cd $(dirname $rootfs); echo $(basename $rootfs) | cpio -o -H newc ) > $rootfs.cpio
1551 rm -f $rootfs
1552 mv $rootfs.cpio $rootfs
1553 cd - > /dev/null
1554 rm -rf $TMP_DIR/fs
1555 done
1559 # Move meta boot configuration files to basic configuration files
1560 # because meta loram flavor is useless when rootfs is not loaded in RAM
1562 unmeta_boot() {
1563 local root=${1:-$TMP_DIR/loramiso}
1564 if [ -f $root/boot/isolinux/noram.cfg ]; then
1565 # We keep enough information to do unloram...
1566 [ -s $root/boot/isolinux/common.cfg ] &&
1567 sed -i 's/label slitaz/label orgslitaz/' \
1568 $root/boot/isolinux/common.cfg
1569 set -- $(grep 'append ifmem [0-9]' $root/boot/isolinux/isolinux.cfg)
1570 shift
1571 sed -i '/ifmem/{NNNNNNNNd};/^LABEL/{N;/LABEL SliTaz [^L]/{NNNd}}' \
1572 $root/boot/isolinux/isolinux.cfg
1573 [ -n "$3" ] || set -- $(grep 'append [0-9]' $root/boot/isolinux/common.cfg)
1574 sed -i "s/label $3\$/label slitaz/;s|=\(.*rootfs\)\(.*\)\.gz |=\1.gz |" \
1575 $root/boot/isolinux/*.cfg
1576 fi
1580 # Move rootfs to squashfs filesystem(s) to the cdrom writeable with aufs/overlayfs.
1581 # These squashfs may be loaded in RAM at boot time.
1582 # Rootfs are also copied to CD-ROM for tiny ramsize systems.
1583 # Meta flavors are converted to normal flavors.
1585 build_loram_cdrom() {
1586 build_initfs cdrom || return 1
1587 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1588 cleanup_efi_boot $TMP_DIR/loramiso
1589 mkdir $TMP_DIR/loramiso/fs
1590 cd $TMP_DIR/loramiso/fs
1591 for i in $( ls ../boot/root* | sort -r ) ; do
1592 uncompress $i | cpio -idmu
1593 rm -f $i
1594 done
1595 mkdir -p $TMP_DIR/loramiso/fs/mnt/.cdrom
1596 cd - >/dev/null
1597 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1598 unmeta_boot
1599 VOLUM_NAME="SliTaz_LoRAM_CDROM"
1600 sed -i "s|root=|isofs= rodev=/dev/cdrom/fs &|;s/.ive/cdrom/" \
1601 $TMP_DIR/loramiso/boot/isolinux/*.cfg
1602 sed -i '/LABEL slitaz/{NNNNp;s|z cdrom|& text|;s|L slitaz|&text|;s|root=|screen=text &|;s|,[^ ]*||}' \
1603 $TMP_DIR/loramiso/boot/isolinux/*.cfg
1604 create_iso $OUTPUT $TMP_DIR/loramiso
1608 # Create http bootstrap to load and remove loram_cdrom
1609 # Meta flavors are converted to normal flavors.
1611 build_loram_http() {
1612 build_initfs http || return 1
1613 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1614 cleanup_efi_boot $TMP_DIR/loramiso
1615 rm -f $TMP_DIR/loramiso/boot/rootfs*
1616 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1617 unmeta_boot
1618 create_iso $OUTPUT $TMP_DIR/loramiso
1622 # Update meta flavor selection sizes.
1623 # Reduce sizes with rootfs gains.
1625 update_metaiso_sizes() {
1626 for cfg in $(grep -El '(append|ifmem) [0-9]' $TMP_DIR/loramiso/boot/isolinux/*.cfg)
1627 do
1628 local append="$(grep -E '(append|ifmem) [0-9]' $cfg)"
1629 local sizes="$rootfs_sizes"
1630 local new
1631 set -- $append
1632 shift
1633 [ "$1" == "ifmem" ] && shift
1634 new=""
1635 while [ -n "$2" ]; do
1636 local s
1637 case "$1" in
1638 *G) s=$(( ${1%G} * 1024 * 1024 ));;
1639 *M) s=$(( ${1%M} * 1024 ));;
1640 *) s=${1%K};;
1641 esac
1642 sizes=${sizes#* }
1643 for i in $sizes ; do
1644 s=$(( $s - $i ))
1645 done
1646 new="$new $s $2"
1647 shift 2
1648 done
1649 sed -i -e "/append [0-9]/s/append .*/append$new $1/" -e \
1650 "/append ifmem [0-9]/s/append .*/append ifmem$new $1/" $cfg
1651 sed -i 's|\(initrd=\)\([^r]*\)\(rootfs\)|\1\2rootfs.gz,\2\3|' $cfg
1652 sed -i '/LABEL base/{NNNNp;s|base .ive|cdrom|;s|base|cdrom|;s|,[^ ]*||}' $cfg
1653 sed -i '/LABEL cdrom/{NNNNp;s|z cdrom|& text|;s|L cdrom|&text|;s|root=|screen=text &|;s|,[^ ]*||}' $cfg
1654 done
1658 # Move rootfs to a squashfs filesystem into the initramfs writeable with aufs/overlayfs.
1659 # Meta flavor selection sizes are updated.
1661 build_loram_ram() {
1662 build_initfs ram || return 1
1663 build_loram_rootfs "$1"
1664 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1665 cleanup_efi_boot $TMP_DIR/loramiso
1666 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1667 cp $TMP_DIR/rootfs* $TMP_DIR/loramiso/boot
1668 update_metaiso_sizes
1669 create_iso $OUTPUT $TMP_DIR/loramiso
1673 # Remove files installed by packages
1675 find_flavor_rootfs() {
1676 for i in $1/etc/tazlito/*.extract; do
1677 [ -e $i ] || continue
1678 chroot $1 /bin/sh ${i#$1}
1679 done
1681 # Clean hardlinks and files patched by genisofs in /boot
1682 for i in isolinux/isolinux.bin isolinux/boot.cat bzImage ; do
1683 rm -f $1/boot/$i*
1684 done
1686 # Clean files generated in post_install
1687 rm -f $1/lib/modules/*/modules.* $1/etc/mtab \
1688 $1/dev/core $1/dev/fd $1/dev/std*
1690 # Verify md5
1691 cat $1$INSTALLED/*/md5sum | \
1692 while read md5 file; do
1693 [ -e "$1$file" ] || continue
1694 [ "$(md5sum < "$1$file")" == "$md5 -" ] &&
1695 rm -f "$1$file"
1696 done
1698 # Check configuration files
1699 for i in $1$INSTALLED/*/volatile.cpio.gz; do
1700 [ -e $i ] || continue
1701 mkdir /tmp/volatile$$
1702 zcat $i | ( cd /tmp/volatile$$ ; cpio -idmu > /dev/null 2>&1 )
1703 ( cd /tmp/volatile$$ ; find * -type f 2> /dev/null) | \
1704 while read file ; do
1705 [ -e "$1/$file" ] || continue
1706 cmp -s "/tmp/volatile$$/$file" "$1/$file" && rm -f "$1/$file"
1707 done
1708 rm -rf /tmp/volatile$$
1709 done
1711 # Remove other files blindly
1712 for i in $1$INSTALLED/*/files.list; do
1713 for file in $(cat "$i"); do
1714 [ "$1$file" -nt "$i" ] && continue
1715 [ -f "$1$file" -a ! -L "$1$file" ] && continue
1716 [ -d "$1$file" ] || rm -f "$1$file"
1717 done
1718 done
1720 # Remove tazpkg files and tmp files
1721 rm -rf $1$INSTALLED* $1/tmp $1/var/tmp
1722 rm -f $1$LOCALSTATE/*packages* $1$LOCALSTATE/files.list.lzma \
1723 $1$LOCALSTATE/mirror* $1/var/cache/*/* \
1724 $1/var/lock/* $1/var/log/* $1/var/run/* $1/var/run/*/* \
1725 $1/var/lib/* $1/var/lib/dbus/* 2>/dev/null
1727 # Cleanup directory tree
1728 cd $1
1729 find * -type d | sort -r | while read dir; do
1730 rmdir "$dir" 2>/dev/null
1731 done
1732 cd - > /dev/null
1736 # Get byte(s) from a binary file
1738 get() {
1739 od -v -j $1 -N ${3:-2} -t u${3:-2} -w${3:-2} -An $2 2>/dev/null | sed 's/ *//'
1743 # Get cpio flavor info from the ISO image
1745 flavordata() {
1746 [ $(get 1024 $1) -eq 35615 ] && n=2 || n=$((1+$(get 417 $1 1)))
1747 dd if=$1 bs=512 skip=$n count=20 2>/dev/null | zcat 2>/dev/null
1751 # Restore undigest mirrors
1753 restore_mirrors() {
1754 local undigest="$root$LOCALSTATE/undigest" priority="$root$LOCALSTATE/priority"
1755 [ -d "$undigest.bak" ] || [ -e "$priority.bak" ] || return
1757 action 'Restoring mirrors...'
1758 if [ -d "$undigest.bak" ]; then
1759 [ -d "$undigest" ] && rm -r "$undigest"
1760 mv "$undigest.bak" "$undigest"
1761 fi
1762 [ -e "$priority.bak" ] && mv -f "$priority.bak" "$priority"
1763 :; status
1767 # Setup undigest mirrors
1769 setup_mirrors() {
1770 # Setup mirrors in plain system or in chroot (with variable root=)
1771 local mirrorlist="$1" fresh repacked
1772 local undigest="$root$LOCALSTATE/undigest" priority="$root$LOCALSTATE/priority"
1774 # Restore mirrors first: in case of non-clear exits, hangs, etc.
1775 restore_mirrors
1777 _ 'Setting up mirrors for %s...' "$root/"
1778 # Backing up current undigest mirrors and priority
1779 [ -d "$undigest" ] && mv "$undigest" "$undigest.bak"
1780 [ -e "$priority" ] && mv "$priority" "$priority.bak"
1781 rm -rf '/var/www/tazlito/'
1782 mkdir -p '/var/www/tazlito/'
1784 # Packages produced by CookUtils: on Tank or local, or repacked packages: highest priority
1785 fresh='/home/slitaz/packages'
1786 if [ -d "$fresh" ]; then
1787 # Setup first undigest mirror
1788 mkdir -p "$undigest/fresh"
1789 echo "$fresh" > "$undigest/fresh/mirror"
1790 echo 'fresh' >> "$priority"
1791 # Rebuild mirror DB if needed
1792 [ ! -e "$fresh/IDs" ] && tazpkg mkdb "$fresh" --forced --root=''
1793 [ -n "$(find -L "$fresh" -name '*.tazpkg' -newer "$fresh/IDs")" ] && \
1794 tazpkg mkdb "$fresh" --forced --root=''
1795 cp -a "$fresh/files.list.lzma" "$fresh/files-list.lzma"
1796 fi
1798 # Repacked packages: high priority
1799 repacked="$PACKAGES_REPOSITORY"
1800 if [ -d "$repacked" -a "$repacked" != "$fresh" ] && ls "$repacked" | grep -q ".tazpkg"; then
1801 # According to Tazlito setup file (tazlito.conf):
1802 # WORK_DIR="/home/slitaz/$SLITAZ_VERSION"
1803 # or
1804 # WORK_DIR="/home/slitaz"
1805 # and
1806 # PACKAGES_REPOSITORY="$WORK_DIR/packages"
1807 # It MAY or MAY NOT match /home/slitaz/packages, so here we setup second repository
1809 # Setup second undigest mirror
1810 mkdir -p "$undigest/repacked"
1811 echo "$repacked" > "$undigest/repacked/mirror"
1812 echo 'repacked' >> "$priority"
1813 # Rebuild mirror DB if needed
1814 [ ! -e "$repacked/IDs" ] && tazpkg mkdb "$repacked" --forced --root=''
1815 [ -n "$(find -L "$repacked" -name '*.tazpkg' -newer "$repacked/IDs")" ] && \
1816 tazpkg mkdb "$repacked" --forced --root=''
1817 cp -a "$repacked/files.list.lzma" "$repacked/files-list.lzma"
1818 fi
1820 # All repositories listed in mirrors list: normal priority
1821 [ -e "$mirrorlist" ] && \
1822 while read mirror; do
1823 # Provide consistent mirror ID for caching purpose: /var/cache/tazpkg/<mirror ID>/packages
1824 mirrorid=$(echo "$mirror" | md5sum | cut -d' ' -f1)
1825 mkdir -p "$undigest/$mirrorid"
1826 echo "$mirror" > "$undigest/$mirrorid/mirror"
1827 echo "$mirrorid" >> "$priority"
1828 done < "$mirrorlist"
1830 # And, finally, main mirror with the lowest (failsafe) priority (nothing to do)
1832 # Show list of mirrors
1833 [ -f "$priority" ] && awk -vdb="$root$LOCALSTATE" '
1834 function show(num, name, url) {
1835 printf " %-1.1d. %32.32s %-44.44s\n", num, name " ...............................", url;
1838 num++;
1839 "cat " db "/undigest/" $0 "/mirror" | getline url;
1840 show(num, $0, url);
1842 END {
1843 num++;
1844 "cat " db "/mirror" | getline url;
1845 show(num, "main", url);
1846 }' "$priority"
1848 tazpkg recharge --quiet >/dev/null
1852 # Get list of 'packages.info' lists using priority
1854 pi_lists() {
1855 local pi
1856 [ -s "$root$LOCALSTATE/packages.info" ] || tazpkg recharge --root="$root" >/dev/null 2>&1
1857 local priority="$root$LOCALSTATE/priority"
1858 local undigest="$root$LOCALSTATE/undigest"
1861 [ -s "$priority" ] && cat "$priority"
1862 echo 'main'
1863 [ -d "$undigest" ] && ls "$undigest"
1864 } | awk -vun="$undigest/" '
1866 if (arr[$0] != 1) {
1867 arr[$0] = 1;
1868 print un $0 "/packages.info";
1870 }' | sed 's|/undigest/main||' | \
1871 while read pi; do
1872 [ -e "$pi" ] && echo "$pi"
1873 done
1877 # Strip versions from packages list
1879 strip_versions() {
1880 if [ -n "$stripped" ]; then
1881 action 'Consider list %s already stripped' "$(basename "$1")"
1882 status
1883 return 0
1884 fi
1885 action 'Strip versions from list %s...' "$(basename "$1")"
1886 local in_list="$1" tmp_list="$(mktemp)" namever pkg
1887 [ -f "$in_list" ] || die "List '$in_list' not found."
1889 # $pkg=<name>-<version> or $pkg=<name>; both <name> and <version> may contain dashes
1890 awk '
1892 if (FILENAME ~ "packages.info") {
1893 # Collect package names
1894 FS = "\t"; pkg[$1] = 1;
1895 } else {
1896 FS = OFS = "-"; $0 = $0; # Fix bug with FS for first record
1897 while (NF > 1 && ! pkg[$0])
1898 NF --;
1899 printf "%s\n", $0;
1901 }' $(pi_lists) "$in_list" > "$tmp_list"
1903 cat "$tmp_list" > "$in_list"
1904 rm "$tmp_list"
1905 status
1909 # Display list of unknown packages (informative)
1911 display_unknown() {
1912 [ -s "$1" ] || return
1913 echo "Unknown packages:" >&2
1914 cat "$1" >&2
1915 rm "$1"
1919 # Display warnings about critical packages absent (informative)
1921 display_warn() {
1922 [ -s "$1" ] || return
1923 echo "Absent critical packages:" >&2
1924 cat "$1" >&2
1925 rm "$1"
1926 echo "Probably ISO image will be unusable."
1930 # Install packages to rootfs
1932 install_list_to_rootfs() {
1933 local list="$1" rootfs="$2" pkg i ii
1934 local undigest="$rootfs/var/lib/tazpkg/undigest"
1936 # initial tazpkg setup in empty rootfs
1937 tazpkg --root=$rootfs >/dev/null 2>&1
1938 # pass current 'mirror' to the rootfs
1939 mkdir -p $rootfs/var/lib/tazpkg $rootfs/etc
1940 cp -f /var/lib/tazpkg/mirror $rootfs/var/lib/tazpkg/mirror
1941 cp -f /etc/slitaz-release $rootfs/etc/slitaz-release
1942 # link rootfs packages cache to the regular packages cache
1943 rm -r "$rootfs/var/cache/tazpkg"
1944 ln -s /var/cache/tazpkg "$rootfs/var/cache/tazpkg"
1946 setup_mirrors mirrors
1948 # Just in case if flavor doesn't contain "tazlito" package
1949 mkdir -p "$rootfs/etc/tazlito"
1951 newline
1953 # Choose detailed log with --detailed
1954 if [ -n "$detailed" ]; then
1955 while read pkg; do
1956 separator '-'
1957 echo $pkg
1958 tazpkg -gi $pkg --root=$rootfs --local --quiet --cookmode | tee -a $log
1959 done < $list
1960 separator '='
1961 else
1962 while read pkg; do
1963 action 'Installing package: %s' "$pkg"
1964 yes y | tazpkg -gi $pkg --root=$rootfs --quiet >> $log || exit 1
1965 status
1966 done < $list
1967 fi
1968 newline
1970 restore_mirrors
1971 # Remove 'fresh' and 'repacked' undigest repos leaving all other
1972 for i in fresh repacked; do
1973 ii="$undigest/$i"
1974 [ -d "$ii" ] && rm -rf "$ii"
1975 ii="$rootfs/var/lib/tazpkg/priority"
1976 if [ -f "$ii" ]; then
1977 sed -i "/$i/d" "$ii"
1978 [ -s "$ii" ] || rm "$ii"
1979 fi
1980 done
1981 [ -d "$undigest" ] && \
1982 for i in $(find "$undigest" -type f); do
1983 # Remove all undigest PKGDB files but 'mirror'
1984 [ "$(basename "$i")" != 'mirror' ] && rm "$i"
1985 done
1986 [ -d "$undigest" ] && \
1987 rmdir --ignore-fail-on-non-empty "$undigest"
1989 # Un-link packages cache
1990 rm "$rootfs/var/cache/tazpkg"
1992 # Clean /var/lib/tazpkg
1993 (cd $rootfs/var/lib/tazpkg; rm ID* descriptions.txt extra.list files* packages.* 2>/dev/null)
1999 ####################
2000 # Tazlito commands #
2001 ####################
2003 # /usr/bin/tazlito is linked with /usr/bin/reduplicate and /usr/bin/deduplicate
2004 case "$0" in
2005 *reduplicate)
2006 find ${@:-.} ! -type d -links +1 \
2007 -exec cp -a {} {}$$ \; -exec mv {}$$ {} \;
2008 exit 0 ;;
2009 *deduplicate)
2010 deduplicate "$@"
2011 exit 0 ;;
2012 esac
2015 case "$COMMAND" in
2016 stats)
2017 # Tazlito general statistics from the config file.
2019 title 'Tazlito statistics'
2020 optlist "\
2021 Config file : $CONFIG_FILE
2022 ISO name : $ISO_NAME.iso
2023 Volume name : $VOLUM_NAME
2024 Prepared : $PREPARED
2025 Packages repository : $PACKAGES_REPOSITORY
2026 Distro directory : $DISTRO
2027 Additional files : $ADDFILES
2028 " | sed '/: $/d'
2029 footer
2030 ;;
2033 list-addfiles)
2034 # Simple list of additional files in the rootfs
2035 newline
2036 if [ -d "$ADDFILES/rootfs" ]; then
2037 cd $ADDFILES
2038 find rootfs -type f
2039 else
2040 _ 'Additional files not found: %s' "$ADDFILES/rootfs/"
2041 fi
2042 newline
2043 ;;
2046 gen-config)
2047 # Generate a new config file in the current dir or the specified
2048 # directory by $2.
2050 if [ -n "$2" ]; then
2051 mkdir -p "$2" && cd "$2"
2052 fi
2054 newline
2055 action 'Generating empty tazlito.conf...'
2056 empty_config_file
2057 status
2059 separator
2060 if [ -f 'tazlito.conf' ] ; then
2061 _ 'Configuration file is ready to edit.'
2062 _ 'File location: %s' "$(pwd)/tazlito.conf"
2063 newline
2064 fi
2065 ;;
2068 configure)
2069 # Configure a tazlito.conf config file. Start by getting
2070 # a empty config file and sed it.
2072 if [ -f 'tazlito.conf' ]; then
2073 rm tazlito.conf
2074 else
2075 [ $(id -u) -ne 0 ] && die 'You must be root to configure the main config file' \
2076 'or in the same directory of the file you want to configure.'
2077 cd /etc
2078 fi
2080 empty_config_file
2082 title 'Configuring: %s' "$(pwd)/tazlito.conf"
2084 # ISO name.
2085 echo -n "ISO name : " ; read answer
2086 sed -i s#'ISO_NAME=\"\"'#"ISO_NAME=\"$answer\""# tazlito.conf
2087 # Volume name.
2088 echo -n "Volume name : " ; read answer
2089 sed -i s/'VOLUM_NAME=\"SliTaz\"'/"VOLUM_NAME=\"$answer\""/ tazlito.conf
2090 # Packages repository.
2091 echo -n "Packages repository : " ; read answer
2092 sed -i s#'PACKAGES_REPOSITORY=\"\"'#"PACKAGES_REPOSITORY=\"$answer\""# tazlito.conf
2093 # Distro path.
2094 echo -n "Distro path : " ; read answer
2095 sed -i s#'DISTRO=\"\"'#"DISTRO=\"$answer\""# tazlito.conf
2096 footer "Config file is ready to use."
2097 echo 'You can now extract an ISO or generate a distro.'
2098 newline
2099 ;;
2102 gen-iso)
2103 # Simply generate a new iso.
2105 check_root
2106 verify_rootcd
2107 gen_livecd_isolinux
2108 distro_stats
2109 ;;
2112 gen-initiso)
2113 # Simply generate a new initramfs with a new iso.
2115 check_root
2116 verify_rootcd
2117 gen_initramfs "$ROOTFS"
2118 gen_livecd_isolinux
2119 distro_stats
2120 ;;
2123 extract-distro|extract-iso)
2124 # Extract an ISO image to a directory and rebuild the LiveCD tree.
2126 check_root
2127 ISO_IMAGE="$2"
2128 [ -z "$ISO_IMAGE" ] && die 'Please specify the path to the ISO image.' \
2129 'Example:\n tazlito image.iso /path/target'
2131 # Set the distro path by checking for $3 on cmdline.
2132 TARGET="${3:-$DISTRO}"
2134 # Exit if existing distro is found.
2135 [ -d "$TARGET/rootfs" ] && die "A rootfs exists in '$TARGET'." \
2136 'Please clean the distro tree or change directory path.'
2138 title 'Tazlito extracting: %s' "$(basename $ISO_IMAGE)"
2140 # Start to mount the ISO.
2141 action 'Mounting ISO image...'
2142 mkdir -p "$TMP_DIR"
2143 # Get ISO file size.
2144 isosize=$(du -sh "$ISO_IMAGE" | cut -f1)
2145 mount -o loop -r "$ISO_IMAGE" "$TMP_DIR"
2146 sleep 2
2147 # Prepare target dir, copy the kernel and the rootfs.
2148 mkdir -p "$TARGET/rootfs" "$TARGET/rootcd/boot"
2149 status
2151 action 'Copying the Linux kernel...'
2152 if cp $TMP_DIR/boot/vmlinuz* "$TARGET/rootcd/boot" 2>/dev/null; then
2153 make_bzImage_hardlink "$TARGET/rootcd/boot"
2154 else
2155 cp "$TMP_DIR/boot/bzImage" "$TARGET/rootcd/boot"
2156 fi
2157 status
2159 for i in $(ls $TMP_DIR); do
2160 [ "$i" == 'boot' ] && continue
2161 cp -a "$TMP_DIR/$i" "$TARGET/rootcd"
2162 done
2164 for loader in isolinux syslinux extlinux grub; do
2165 [ -d "$TMP_DIR/boot/$loader" ] || continue
2166 action 'Copying %s files...' "$loader"
2167 cp -a "$TMP_DIR/boot/$loader" "$TARGET/rootcd/boot"
2168 status
2169 done
2171 action 'Copying the rootfs...'
2172 cp $TMP_DIR/boot/rootfs*.?z* "$TARGET/rootcd/boot"
2173 status
2175 cleanup_efi_boot "$TARGET/rootcd"
2177 # Extract initramfs.
2178 cd "$TARGET/rootfs"
2179 action 'Extracting the rootfs...'
2180 for i in $(ls -r $TARGET/rootcd/boot/rootfs*z); do
2181 extract_rootfs "$i" "$TARGET/rootfs"
2182 done
2183 # unpack /usr
2184 for i in etc/tazlito/*.extract; do
2185 [ -f "$i" ] && . $i ../rootcd
2186 done
2187 # Umount and remove temp directory and cd to $TARGET to get stats.
2188 umount "$TMP_DIR" && rm -rf "$TMP_DIR"
2189 cd ..
2190 status
2192 newline
2193 separator
2194 echo "Extracted : $(basename $ISO_IMAGE) ($isosize)"
2195 echo "Distro tree : $(pwd)"
2196 echo "Rootfs size : $(du -sh rootfs)"
2197 echo "Rootcd size : $(du -sh rootcd)"
2198 footer
2199 ;;
2202 list-flavors)
2203 # Show available flavors.
2204 list='/etc/tazlito/flavors.list'
2205 [ ! -s $list -o -n "$recharge" ] && download flavors.list -O - > $list
2206 title 'List of flavors'
2207 cat $list
2208 footer
2209 ;;
2212 show-flavor)
2213 # Show flavor descriptions.
2214 set -e
2215 flavor=${2%.flavor}
2216 flv_dir="$(extract_flavor "$flavor")"
2217 desc="$flv_dir/$flavor.desc"
2218 if [ -n "$brief" ]; then
2219 if [ -z "$noheader" ]; then
2220 printf "%-16.16s %6.6s %6.6s %s\n" 'Name' 'ISO' 'Rootfs' 'Description'
2221 separator
2222 fi
2223 printf "%-16.16s %6.6s %6.6s %s\n" "$flavor" \
2224 "$(field ISO "$desc")" \
2225 "$(field Rootfs "$desc")" \
2226 "$(field Description "$desc")"
2227 else
2228 separator
2229 cat "$desc"
2230 fi
2231 cleanup
2232 ;;
2235 gen-liveflavor)
2236 # Generate a new flavor from the live system.
2237 FLAVOR=${2%.flavor}
2238 [ -z "$FLAVOR" ] && die 'Please specify flavor name on the commandline.'
2240 case "$FLAVOR" in
2241 -?|-h*|--help)
2242 cat <<EOT
2243 SliTaz Live Tool - Version: $VERSION
2245 $(boldify 'Usage:') tazlito gen-liveflavor <flavor-name> [<flavor-patch-file>]
2247 $(boldify '<flavor-patch-file> format:')
2248 $(optlist "\
2249 code data
2250 + package to add
2251 - package to remove
2252 ! non-free package to add
2253 ? display message
2254 @ flavor description
2255 ")
2257 $(boldify 'Example:')
2258 $(optlist "\
2259 @ Developer tools for SliTaz maintainers
2260 + slitaz-toolchain
2261 + mercurial
2262 ")
2263 EOT
2264 exit 1
2265 ;;
2266 esac
2267 mv /etc/tazlito/distro-packages.list \
2268 /etc/tazlito/distro-packages.list.$$ 2>/dev/null
2269 rm -f distro-packages.list non-free.list 2>/dev/null
2270 tazpkg recharge
2272 DESC=""
2273 [ -n "$3" ] && \
2274 while read action pkg; do
2275 case "$action" in
2276 +) yes | tazpkg get-install $pkg 2>&1 >> $log || exit 1 ;;
2277 -) yes | tazpkg remove $pkg ;;
2278 !) echo $pkg >> non-free.list ;;
2279 @) DESC="$pkg" ;;
2280 \?) echo -en "$pkg"; read action ;;
2281 esac
2282 done < $3
2284 yes '' | tazlito gen-distro
2285 echo "$DESC" | tazlito gen-flavor "$FLAVOR"
2286 mv /etc/tazlito/distro-packages.list.$$ \
2287 /etc/tazlito/distro-packages.list 2>/dev/null
2288 ;;
2291 gen-flavor)
2292 # Generate a new flavor from the last ISO image generated
2293 FLAVOR=${2%.flavor}
2294 [ -z "$FLAVOR" ] && die 'Please specify flavor name on the commandline.'
2296 title 'Flavor generation'
2297 check_rootfs
2298 FILES="$FLAVOR.pkglist"
2300 action 'Creating file %s...' "$FLAVOR.flavor"
2301 for i in rootcd rootfs; do
2302 if [ -d "$ADDFILES/$i" ] ; then
2303 FILES="$FILES\n$FLAVOR.$i"
2304 ( cd "$ADDFILES/$i"; find . ) | cpio -o -H newc 2>/dev/null | dogzip $FLAVOR.$i
2305 fi
2306 done
2307 status
2309 answer=$(grep -s ^Description $FLAVOR.desc)
2310 answer=${answer#Description : }
2311 if [ -z "$answer" ]; then
2312 echo -n "Description: "
2313 read answer
2314 fi
2316 action 'Compressing flavor %s...' "$FLAVOR"
2317 echo "Flavor : $FLAVOR" > $FLAVOR.desc
2318 echo "Description : $answer" >> $FLAVOR.desc
2319 (cd $DISTRO; distro_sizes) >> $FLAVOR.desc
2320 \rm -f $FLAVOR.pkglist $FLAVOR.nonfree 2>/dev/null
2321 for i in $(ls $ROOTFS$INSTALLED); do
2322 eval $(grep ^VERSION= $ROOTFS$INSTALLED/$i/receipt)
2323 EXTRAVERSION=""
2324 eval $(grep ^EXTRAVERSION= $ROOTFS$INSTALLED/$i/receipt)
2325 eval $(grep ^CATEGORY= $ROOTFS$INSTALLED/$i/receipt)
2326 if [ "$CATEGORY" == 'non-free' -a "${i%%-*}" != 'get' ]; then
2327 echo "$i" >> $FLAVOR.nonfree
2328 else
2329 echo "$i-$VERSION$EXTRAVERSION" >> $FLAVOR.pkglist
2330 fi
2331 done
2332 [ -s $FLAVOR.nonfree ] && $FILES="$FILES\n$FLAVOR.nonfree"
2333 for i in $LOCALSTATE/undigest/*/mirror ; do
2334 [ -s $i ] && cat $i >> $FLAVOR.mirrors
2335 done
2336 [ -s $FLAVOR.mirrors ] && $FILES="$FILES\n$FLAVOR.mirrors"
2337 touch -t 197001010100.00 $FLAVOR.*
2338 echo -e "$FLAVOR.desc\n$FILES" | cpio -o -H newc 2>/dev/null | dogzip $FLAVOR.flavor
2339 rm $(echo -e $FILES)
2340 status
2342 footer "Flavor size: $(du -sh $FLAVOR.flavor)"
2343 ;;
2346 upgrade-flavor)
2347 # Strip versions from pkglist and update estimated numbers in flavor.desc
2348 flavor="${2%.flavor}"
2349 set -e
2350 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2351 set +e
2353 flv_dir="$(extract_flavor "$flavor")"
2355 strip_versions "$flv_dir/$flavor.pkglist"
2357 action 'Updating %s...' "$flavor.desc"
2359 [ -f "$flv_dir/$flavor.mirrors" ] && setup_mirrors "$flv_dir/$flavor.mirrors" >/dev/null
2360 set -- $(module calc_sizes "$flv_dir" "$flavor")
2361 restore_mirrors >/dev/null
2363 sed -i -e '/Image is ready/d' \
2364 -e "s|\(Rootfs size *:\).*$|\1 $1 (estimated)|" \
2365 -e "s|\(Initramfs size *:\).*$|\1 $2 (estimated)|" \
2366 -e "s|\(ISO image size *:\).*$|\1 $3 (estimated)|" \
2367 -e "s|\(Packages *:\).*$|\1 $4|" \
2368 -e "s|\(Build date *:\).*$|\1 $(date '+%Y%m%d at %T')|" \
2369 "$flv_dir/$flavor.desc"
2371 pack_flavor "$flv_dir" "$flavor"
2372 status
2373 display_unknown "$flv_dir/err"
2374 display_warn "$flv_dir/warn"
2375 cleanup
2376 ;;
2379 extract-flavor)
2380 # Extract a flavor into $FLAVORS_REPOSITORY
2381 flavor="${2%.flavor}"
2382 set -e
2383 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2384 set +e
2386 action 'Extracting %s...' "$flavor.flavor"
2387 flv_dir="$(extract_flavor "$flavor" full)"
2388 storage="$FLAVORS_REPOSITORY/$flavor"
2390 rm -rf "$storage" 2>/dev/null
2391 mkdir -p "$storage"
2392 cp -a "$flv_dir"/* "$storage"
2393 rm "$storage/description"
2394 status
2396 strip_versions "$storage/packages.list"
2398 cleanup
2399 ;;
2402 pack-flavor)
2403 # Create a flavor from $FLAVORS_REPOSITORY.
2404 flavor=${2%.flavor}
2405 storage="$FLAVORS_REPOSITORY/$flavor"
2407 [ -s "$storage/receipt" ] || die "No $flavor receipt in $FLAVORS_REPOSITORY."
2409 action 'Creating flavor %s...' "$flavor"
2410 tmp_dir="$(mktemp -d)"
2412 while read from to; do
2413 [ -s "$storage/$from" ] || continue
2414 cp -a "$storage/$from" "$tmp_dir/$to"
2415 done <<EOT
2416 mirrors $flavor.mirrors
2417 distro.sh $flavor-distro.sh
2418 receipt $flavor.receipt
2419 non-free.list $flavor.nonfree
2420 EOT
2422 # Build the package list.
2423 # It can include a list from another flavor with the keyword @include
2424 if [ -s "$storage/packages.list" ]; then
2425 include=$(grep '^@include' "$storage/packages.list")
2426 if [ -n "$include" ]; then
2427 include=${include#@include }
2428 if [ -s "$FLAVORS_REPOSITORY/$include/packages.list" ]; then
2429 cp -f "$FLAVORS_REPOSITORY/$include/packages.list" "$tmp_dir/$flavor.pkglist"
2430 else
2431 echo -e "\nERROR: Can't find include package list from $include\n"
2432 fi
2433 fi
2434 # Generate the final/initial package list
2435 [ -s "$storage/packages.list" ] && \
2436 cat "$storage/packages.list" >> "$tmp_dir/$flavor.pkglist"
2437 sed -i '/@include/d' "$tmp_dir/$flavor.pkglist"
2438 fi
2440 if grep -q ^ROOTFS_SELECTION "$storage/receipt"; then
2441 # Process multi-rootfs flavor
2442 . "$storage/receipt"
2443 set -- $ROOTFS_SELECTION
2444 [ -n "$FRUGAL_RAM" ] || FRUGAL_RAM=$1
2445 [ -f "$FLAVORS_REPOSITORY/$2/packages.list" ] || tazlito extract-flavor $2
2446 cp "$FLAVORS_REPOSITORY/$2/packages.list" "$tmp_dir/$flavor.pkglist"
2448 for i in rootcd rootfs; do
2449 mkdir "$tmp_dir/$i"
2450 # Copy extra files from the first flavor
2451 [ -d "$FLAVORS_REPOSITORY/$2/$i" ] &&
2452 cp -a "$FLAVORS_REPOSITORY/$2/$i" "$tmp_dir"
2453 # Overload extra files by meta flavor
2454 [ -d "$storage/$i" ] && cp -a "$storage/$i" "$tmp_dir"
2455 [ -n "$(ls $tmp_dir/$i)" ] &&
2456 (cd "$tmp_dir/$i"; find . | cpio -o -H newc 2>/dev/null ) | \
2457 dogzip "$tmp_dir/$flavor.$i"
2458 rm -rf "$tmp_dir/$i"
2459 done
2460 else
2461 # Process plain flavor
2462 for i in rootcd rootfs; do
2463 [ -d "$storage/$i" ] || continue
2464 (cd "$storage/$i";
2465 find . | cpio -o -H newc 2>/dev/null) | dogzip "$tmp_dir/$flavor.$i"
2466 done
2467 fi
2469 unset VERSION MAINTAINER ROOTFS_SELECTION
2470 set -- $(module calc_sizes "$tmp_dir" "$flavor")
2471 ROOTFS_SIZE="$1 (estimated)"
2472 INITRAMFS_SIZE="$2 (estimated)"
2473 ISO_SIZE="$3 (estimated)"
2474 PKGNUM="$4"
2475 . "$storage/receipt"
2477 sed '/: $/d' > "$tmp_dir/$flavor.desc" <<EOT
2478 Flavor : $FLAVOR
2479 Description : $SHORT_DESC
2480 Version : $VERSION
2481 Maintainer : $MAINTAINER
2482 LiveCD RAM size : $FRUGAL_RAM
2483 Rootfs list : $ROOTFS_SELECTION
2484 Build date : $(date '+%Y%m%d at %T')
2485 Packages : $PKGNUM
2486 Rootfs size : $ROOTFS_SIZE
2487 Initramfs size : $INITRAMFS_SIZE
2488 ISO image size : $ISO_SIZE
2489 ================================================================================
2491 EOT
2493 rm -f $tmp_dir/packages.list
2494 pack_flavor "$tmp_dir" "$flavor"
2495 status
2496 display_unknown "$tmp_dir/err"
2497 display_warn "$flv_dir/warn"
2498 cleanup
2499 ;;
2502 get-flavor)
2503 # Get a flavor's files and prepare for gen-distro.
2504 flavor=${2%.flavor}
2505 title 'Preparing %s distro flavor' "$flavor"
2506 set -e
2507 [ -f "$flavor.flavor" ] || download "$flavor.flavor"
2508 set +e
2510 action 'Cleaning %s...' "$DISTRO"
2511 [ -d "$DISTRO" ] && rm -r "$DISTRO"
2512 # Clean old files
2513 for i in non-free.list distro-packages.list distro.sh receipt mirrors err; do
2514 [ -f "$i" ] && rm "$i"
2515 done
2516 mkdir -p "$DISTRO"
2517 status
2519 [ -z "$noup" ] && tazlito upgrade-flavor "$flavor.flavor"
2521 action 'Extracting flavor %s...' "$flavor.flavor"
2522 flv_dir="$(extract_flavor "$flavor" info)"
2523 cp -a "$flv_dir"/* .
2524 mv packages.list distro-packages.list
2525 mv -f info /etc/tazlito
2526 status
2528 for i in rootcd rootfs; do
2529 if [ -d "$i" ]; then
2530 mkdir -p "$ADDFILES"; mv "$i" "$ADDFILES/$i"
2531 fi
2532 done
2534 sed '/^Rootfs list/!d;s/.*: //' description > /etc/tazlito/rootfs.list
2535 [ -s /etc/tazlito/rootfs.list ] || rm -f /etc/tazlito/rootfs.list
2537 action 'Updating %s...' 'tazlito.conf'
2538 [ -f tazlito.conf ] || cp /etc/tazlito/tazlito.conf .
2539 grep -v "^#VOLUM_NAME" < tazlito.conf | \
2540 sed "s/^VOLUM_NA/VOLUM_NAME=\"SliTaz $flavor\"\\n#VOLUM_NA/" \
2541 > tazlito.conf.$$ && mv tazlito.conf.$$ tazlito.conf
2542 sed -i "s/ISO_NAME=.*/ISO_NAME=\"slitaz-$flavor\"/" tazlito.conf
2543 status
2545 footer 'Flavor is ready to be generated by `tazlito gen-distro`'
2546 cleanup
2547 ;;
2550 iso2flavor)
2551 [ -z "$3" -o ! -s "$2" ] && die 'Usage: tazlito iso2flavor <image.iso> <flavor_name>' \
2552 '\n\nCreate a file <flavor_name>.flavor from the CD-ROM image file <image.iso>'
2554 FLAVOR=${3%.flavor}
2555 mkdir -p $TMP_DIR/iso $TMP_DIR/rootfs $TMP_DIR/flavor
2556 mount -o loop,ro $2 $TMP_DIR/iso
2557 flavordata $2 | (cd $TMP_DIR/flavor; cpio -i 2>/dev/null)
2558 if [ -s $TMP_DIR/iso/boot/rootfs1.gz -a \
2559 ! -s $TMP_DIR/flavor/*.desc ]; then
2560 _ 'META flavors are not supported.'
2561 umount -d $TMP_DIR/iso
2562 elif [ ! -s $TMP_DIR/iso/boot/rootfs.gz -a \
2563 ! -s $TMP_DIR/iso/boot/rootfs1.gz ]; then
2564 _ 'No %s in ISO image. Needs a SliTaz ISO.' '/boot/rootfs.gz'
2565 umount -d $TMP_DIR/iso
2566 else
2567 for i in $(ls -r $TMP_DIR/iso/boot/rootfs*z); do
2568 uncompress $i | \
2569 ( cd $TMP_DIR/rootfs ; cpio -idmu > /dev/null 2>&1 )
2570 done
2571 if [ ! -s $TMP_DIR/rootfs/etc/slitaz-release ]; then
2572 _ 'No file %s in %s of ISO image. Needs a non-loram SliTaz ISO.' \
2573 '/etc/slitaz-release' '/boot/rootfs.gz'
2574 umount -d $TMP_DIR/iso
2575 else
2576 ROOTFS_SIZE=$(du -hs $TMP_DIR/rootfs | awk '{ print $1 }')
2577 RAM_SIZE=$(du -s $TMP_DIR/rootfs | awk '{ print 32*int(($1+36000)/32768) "M" }')
2578 cp -a $TMP_DIR/iso $TMP_DIR/rootcd
2579 ISO_SIZE=$(df -h $TMP_DIR/iso | awk 'END { print $2 }')
2580 BUILD_DATE=$(date '+%Y%m%d at %T' -r "$TMP_DIR/iso/md5sum")
2581 umount -d $TMP_DIR/iso
2582 INITRAMFS_SIZE=$(du -chs $TMP_DIR/rootcd/boot/rootfs*.gz | awk 'END { print $1 }')
2583 rm -f $TMP_DIR/rootcd/boot/rootfs.gz $TMP_DIR/rootcd/md5sum
2584 mv $TMP_DIR/rootcd/boot $TMP_DIR/rootfs
2585 [ -d $TMP_DIR/rootcd/efi ] && mv $TMP_DIR/rootcd/efi $TMP_DIR/rootfs
2586 sed 's/.* \(.*\).tazpkg*/\1/' > $TMP_DIR/$FLAVOR.pkglist \
2587 < $TMP_DIR/rootfs$INSTALLED.md5
2588 PKGCNT=$(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l | awk '{ print $1 }')
2589 if [ -s $TMP_DIR/flavor/*desc ]; then
2590 cp $TMP_DIR/flavor/*.desc $TMP_DIR/$FLAVOR.desc
2591 [ -s $TMP_DIR/$FLAVOR.receipt ] &&
2592 cp $TMP_DIR/flavor/*.receipt $TMP_DIR/$FLAVOR.receipt
2593 for i in rootfs rootcd ; do
2594 [ -s $TMP_DIR/flavor/*.list$i ] &&
2595 sed 's/.\{1,45\}//;/^\.$/d' $TMP_DIR/flavor/*.list$i | \
2596 ( cd $TMP_DIR/$i ; cpio -o -H newc ) | dogzip $TMP_DIR/$FLAVOR.$i
2597 done
2598 else
2599 find_flavor_rootfs $TMP_DIR/rootfs
2600 [ -d $TMP_DIR/rootfs/boot ] && mv $TMP_DIR/rootfs/boot $TMP_DIR/rootcd
2601 [ -d $TMP_DIR/rootfs/efi ] && mv $TMP_DIR/rootfs/efi $TMP_DIR/rootcd
2602 for i in rootfs rootcd ; do
2603 [ "$(ls $TMP_DIR/$i)" ] &&
2604 ( cd "$TMP_DIR/$i"; find * | cpio -o -H newc ) | dogzip "$TMP_DIR/$FLAVOR.$i"
2605 done
2606 unset VERSION MAINTAINER
2607 echo -en "Flavor short description \007: "; read -t 30 DESCRIPTION
2608 if [ -n "$DESCRIPTION" ]; then
2609 _n 'Flavor version : '; read -t 30 VERSION
2610 _n 'Flavor maintainer (your email) : '; read -t 30 MAINTAINER
2611 fi
2613 cat > $TMP_DIR/$FLAVOR.desc <<EOT
2614 Flavor : $FLAVOR
2615 Description : ${DESCRIPTION:-SliTaz $FLAVOR flavor}
2616 Version : ${VERSION:-1.0}
2617 Maintainer : ${MAINTAINER:-nobody@slitaz.org}
2618 LiveCD RAM size : $RAM_SIZE
2619 Build date : $BUILD_DATE
2620 Packages : $PKGCNT
2621 Rootfs size : $ROOTFS_SIZE
2622 Initramfs size : $INITRAMFS_SIZE
2623 ISO image size : $ISO_SIZE
2624 ================================================================================
2626 EOT
2627 longline "Tazlito can't detect each file installed during \
2628 a package post_install. You should extract this flavor (tazlito extract-flavor \
2629 $FLAVOR), check the files in /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/rootfs \
2630 tree and remove files generated by post_installs.
2631 Check /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/receipt too and \
2632 repack the flavor (tazlito pack-flavor $FLAVOR)"
2633 fi
2634 ( cd $TMP_DIR; ls $FLAVOR.* | cpio -o -H newc ) | dogzip $FLAVOR.flavor
2635 fi
2636 fi
2637 rm -rf $TMP_DIR
2638 ;;
2641 gen-distro)
2642 # Generate a live distro tree with a set of packages.
2644 check_root
2645 start_time=$(date +%s)
2647 # Tazlito options: --iso or --cdrom
2648 CDROM=''
2649 [ -n "$iso" ] && CDROM="-o loop $iso"
2650 [ -n "$cdrom" ] && CDROM="/dev/cdrom"
2652 # Check if a package list was specified on cmdline.
2653 if [ -f "$2" ]; then
2654 LIST_NAME="$2"
2655 else
2656 LIST_NAME='distro-packages.list'
2657 fi
2659 [ -d "$ROOTFS" -a -z "$forced" ] && die "A rootfs exists in '$DISTRO'." \
2660 'Please clean the distro tree or change directory path.'
2661 [ -d "$ROOTFS" ] && rm -rf "$ROOTFS"
2662 [ -d "$ROOTCD" ] && rm -rf "$ROOTCD"
2664 # If list not given: build list with all installed packages
2665 if [ ! -f "$LIST_NAME" -a -f "$LOCALSTATE/installed.info" ]; then
2666 awk -F$'\t' '{print $1}' "$LOCALSTATE/installed.info" >> "$LIST_NAME"
2667 fi
2669 # Exit if no list name.
2670 [ ! -f "$LIST_NAME" ] && die 'No packages list found or specified. Please read the docs.'
2672 # Start generation.
2673 title 'Tazlito generating a distro'
2675 # Misc checks
2676 mkdir -p "$PACKAGES_REPOSITORY"
2677 REPACK=$(yesorno 'Repack packages from rootfs?' 'n')
2678 newline
2680 # Mount CD-ROM to be able to repack boot-loader packages
2681 if [ ! -e /boot -a -n "$CDROM" ]; then
2682 mkdir $TMP_MNT
2683 if mount -r "$CDROM $TMP_MNT" 2>/dev/null; then
2684 ln -s "$TMP_MNT/boot" /
2685 if [ ! -d "$ADDFILES/rootcd" ] ; then
2686 mkdir -p "$ADDFILES/rootcd"
2687 for i in $(ls $TMP_MNT); do
2688 [ "$i" == 'boot' ] && continue
2689 cp -a "$TMP_MNT/$i" "$ADDFILES/rootcd"
2690 done
2691 fi
2692 else
2693 rmdir "$TMP_MNT"
2694 fi
2695 fi
2697 # Rootfs stuff.
2698 echo 'Preparing the rootfs directory...'
2699 mkdir -p "$ROOTFS"
2700 export root="$ROOTFS"
2701 # pass current 'mirror' to the root
2702 mkdir -p $root/var/lib/tazpkg $root/etc
2703 cp -f /var/lib/tazpkg/mirror $root/var/lib/tazpkg/mirror
2704 cp -f /etc/slitaz-release $root/etc/slitaz-release
2705 strip_versions "$LIST_NAME"
2707 if [ "$REPACK" == 'y' ]; then
2708 # Determine full packages list with all dependencies
2709 tmp_dir="$(mktemp -d)"
2710 cp "$LIST_NAME" "$tmp_dir/flavor.pkglist"
2711 touch "$tmp_dir/full.pkglist"
2712 module calc_sizes "$tmp_dir" 'flavor' "$tmp_dir/full.pkglist" >/dev/null
2714 awk -F$'\t' '{printf "%s %s\n", $1, $2}' "$LOCALSTATE/installed.info" | \
2715 while read pkgname pkgver; do
2716 # Is package in full list?
2717 grep -q "^$pkgname$" "$tmp_dir/full.pkglist" || continue
2718 # Is package already repacked?
2719 [ -e "$PACKAGES_REPOSITORY/$pkgname-$pkgver.tazpkg" ] && continue
2720 _ 'Repacking %s...' "$pkgname-$pkgver"
2721 tazpkg repack "$pkgname" --quiet
2722 [ -f "$pkgname-$pkgver.tazpkg" ] && mv "$pkgname-$pkgver.tazpkg" "$PACKAGES_REPOSITORY"
2723 status
2724 done
2726 rm -r "$tmp_dir"
2727 fi
2729 if [ -f non-free.list ]; then
2730 # FIXME: working in the ROOTFS chroot?
2731 newline
2732 echo 'Preparing non-free packages...'
2733 cp 'non-free.list' "$ROOTFS/etc/tazlito/non-free.list"
2734 for pkg in $(cat 'non-free.list'); do
2735 if [ ! -d "$INSTALLED/$pkg" ]; then
2736 if [ ! -d "$INSTALLED/get-$pkg" ]; then
2737 tazpkg get-install get-$pkg
2738 fi
2739 get-$pkg "$ROOTFS"
2740 fi
2741 tazpkg repack $pkg
2742 pkg=$(ls $pkg*.tazpkg)
2743 grep -q "^$pkg$" $LIST_NAME || echo $pkg >> $LIST_NAME
2744 mv $pkg $PACKAGES_REPOSITORY
2745 done
2746 fi
2747 cp $LIST_NAME $DISTRO/distro-packages.list
2748 newline
2750 install_list_to_rootfs "$DISTRO/distro-packages.list" "$ROOTFS"
2752 cd $DISTRO
2753 cp distro-packages.list $ROOTFS/etc/tazlito
2754 # Copy all files from $ADDFILES/rootfs to the rootfs.
2755 if [ -d "$ADDFILES/rootfs" ] ; then
2756 action 'Copying addfiles content to the rootfs...'
2757 cp -a $ADDFILES/rootfs/* $ROOTFS
2758 status
2759 fi
2761 action 'Root filesystem is generated...'; status
2763 # Root CD part.
2764 action 'Preparing the rootcd directory...'
2765 mkdir -p $ROOTCD
2766 status
2768 # Move the boot dir with the Linux kernel from rootfs.
2769 # The efi & boot dirs go directly on the CD.
2770 if [ -d "$ROOTFS/efi" ] ; then
2771 action 'Moving the efi directory...'
2772 mv $ROOTFS/efi $ROOTCD
2773 status
2774 fi
2775 if [ -d "$ROOTFS/boot" ] ; then
2776 action 'Moving the boot directory...'
2777 mv $ROOTFS/boot $ROOTCD
2778 status
2779 fi
2780 cd $DISTRO
2781 # Copy all files from $ADDFILES/rootcd to the rootcd.
2782 if [ -d "$ADDFILES/rootcd" ] ; then
2783 action 'Copying addfiles content to the rootcd...'
2784 cp -a $ADDFILES/rootcd/* $ROOTCD
2785 status
2786 fi
2787 # Execute the distro script used to perform tasks in the rootfs
2788 # before compression. Give rootfs path in arg
2789 [ -z "$DISTRO_SCRIPT" ] && DISTRO_SCRIPT="$TOP_DIR/distro.sh"
2790 if [ -x "$DISTRO_SCRIPT" ]; then
2791 echo 'Executing distro script...'
2792 sh $DISTRO_SCRIPT $DISTRO
2793 fi
2795 # Execute the custom_rules() found in receipt.
2796 if [ -s "$TOP_DIR/receipt" ]; then
2797 if grep -q ^custom_rules "$TOP_DIR/receipt"; then
2798 echo -e "Executing: custom_rules()\n"
2799 . "$TOP_DIR/receipt"
2800 custom_rules || echo -e "\nERROR: custom_rules() failed\n"
2801 fi
2802 fi
2804 # Multi-rootfs
2805 if [ -s /etc/tazlito/rootfs.list ]; then
2807 FLAVOR_LIST="$(awk '{
2808 for (i = 2; i <= NF; i+=2)
2809 printf "%s ", $i;
2810 }' /etc/tazlito/rootfs.list)"
2812 [ -s "$ROOTCD/boot/isolinux/isolinux.msg" ] &&
2813 sed -i "s/ *//;s/)/), flavors $FLAVOR_LIST/" \
2814 "$ROOTCD/boot/isolinux/isolinux.msg" 2>/dev/null
2816 [ -f "$ROOTCD/boot/isolinux/ifmem.c32" -o \
2817 -f "$ROOTCD/boot/isolinux/c32box.c32" ] ||
2818 cp '/boot/isolinux/c32box.c32' "$ROOTCD/boot/isolinux" 2>/dev/null ||
2819 cp '/boot/isolinux/ifmem.c32' "$ROOTCD/boot/isolinux"
2821 n=0
2822 last=$ROOTFS
2823 while read flavor; do
2824 n=$(($n+1))
2825 mkdir ${ROOTFS}0$n
2826 export root="${ROOTFS}0$n"
2827 # initial tazpkg setup in empty rootfs
2828 tazpkg --root=$root >/dev/null 2>&1
2830 newline
2831 boldify "Building $flavor rootfs..."
2833 [ -s "$TOP_DIR/$flavor.flavor" ] &&
2834 cp "$TOP_DIR/$flavor.flavor" .
2836 if [ ! -s "$flavor.flavor" ]; then
2837 # We may have it in $FLAVORS_REPOSITORY
2838 if [ -d "$FLAVORS_REPOSITORY/$flavor" ]; then
2839 tazlito pack-flavor $flavor
2840 else
2841 download $flavor.flavor
2842 fi
2843 fi
2845 action 'Extracting %s and %s...' "$flavor.pkglist" "$flavor.rootfs"
2846 zcat $flavor.flavor | cpio -i --quiet $flavor.pkglist $flavor.rootfs
2847 cp $flavor.pkglist $DISTRO/list-packages0$n
2848 status
2850 strip_versions "$DISTRO/list-packages0$n"
2852 install_list_to_rootfs "$DISTRO/list-packages0$n" "${ROOTFS}0$n"
2854 action 'Updating the boot directory...'
2855 yes n | cp -ai ${ROOTFS}0$n/boot $ROOTCD 2> /dev/null
2856 rm -rf ${ROOTFS}0$n/boot
2858 cd $DISTRO
2859 if [ -s $flavor.rootfs ]; then
2860 _n 'Adding %s rootfs extra files...' "$flavor"
2861 zcat < $flavor.rootfs | ( cd ${ROOTFS}0$n ; cpio -idmu )
2862 fi
2864 action 'Moving %s to %s' "list-packages0$n" "rootfs0$n"
2865 mv "$DISTRO/list-packages0$n" "${ROOTFS}0$n/etc/tazlito/distro-packages.list"
2866 status
2868 rm -f $flavor.flavor install-list
2869 mergefs ${ROOTFS}0$n $last
2870 last=${ROOTFS}0$n
2871 done <<EOT
2872 $(awk '{ for (i = 4; i <= NF; i+=2) print $i; }' < /etc/tazlito/rootfs.list)
2873 EOT
2874 #'
2875 i=$(($n+1))
2876 while [ $n -gt 0 ]; do
2877 mv ${ROOTFS}0$n ${ROOTFS}$i
2878 _ 'Compressing %s (%s)...' "${ROOTFS}0$n" "$(du -hs ${ROOTFS}$i | awk '{ print $1 }')"
2879 gen_initramfs ${ROOTFS}$i
2880 n=$(($n-1))
2881 i=$(($i-1))
2882 export LZMA_HISTORY_BITS=26
2883 done
2884 mv $ROOTFS ${ROOTFS}$i
2885 gen_initramfs ${ROOTFS}$i
2886 update_bootconfig "$ROOTCD/boot/isolinux" "$(cat /etc/tazlito/rootfs.list)"
2887 ROOTFS=${ROOTFS}1
2888 else
2889 # Initramfs and ISO image stuff.
2890 gen_initramfs $ROOTFS
2891 fi
2892 gen_livecd_isolinux
2893 distro_stats
2894 cleanup
2895 ;;
2898 clean-distro)
2899 # Remove old distro tree.
2901 check_root
2902 title 'Cleaning: %s' "$DISTRO"
2903 if [ -d "$DISTRO" ] ; then
2904 if [ -d "$ROOTFS" ] ; then
2905 action 'Removing the rootfs...'
2906 rm -f $DISTRO/$INITRAMFS
2907 rm -rf $ROOTFS
2908 status
2909 fi
2910 if [ -d "$ROOTCD" ] ; then
2911 action 'Removing the rootcd...'
2912 rm -rf $ROOTCD
2913 status
2914 fi
2915 action 'Removing eventual ISO image...'
2916 rm -f $DISTRO/$ISO_NAME.iso
2917 rm -f $DISTRO/$ISO_NAME.md5
2918 status
2919 fi
2920 footer
2921 ;;
2924 check-distro)
2925 # Check for a few LiveCD needed files not installed by packages.
2927 # TODO: Remove this function.
2928 # First two files are maintained by tazpkg while it runs on rootfs,
2929 # while last one file should be maintained by tazlito itself.
2930 check_rootfs
2931 title 'Checking distro: %s' "$ROOTFS"
2932 # SliTaz release info.
2933 rel='/etc/slitaz-release'
2934 if [ ! -f "$ROOTFS$rel" ]; then
2935 _ 'Missing release info: %s' "$rel"
2936 else
2937 action 'Release : %s' "$(cat $ROOTFS$rel)"
2938 status
2939 fi
2940 # Tazpkg mirror.
2941 if [ ! -f "$ROOTFS$LOCALSTATE/mirror" ]; then
2942 action 'Mirror URL : Missing %s' "$LOCALSTATE/mirror"
2943 todomsg
2944 else
2945 action 'Mirror configuration exists...'
2946 status
2947 fi
2948 # Isolinux msg
2949 if grep -q "cooking-XXXXXXXX" /$ROOTCD/boot/isolinux/isolinux.*g; then
2950 action 'Isolinux msg : Missing cooking date XXXXXXXX (ex %s)' "$(date +%Y%m%d)"
2951 todomsg
2952 else
2953 action 'Isolinux message seems good...'
2954 status
2955 fi
2956 footer
2957 ;;
2960 writeiso)
2961 # Writefs to ISO image including /home unlike gen-distro we don't use
2962 # packages to generate a rootfs, we build a compressed rootfs with all
2963 # the current filesystem similar to 'tazusb writefs'.
2965 DISTRO='/home/slitaz/distro'
2966 ROOTCD="$DISTRO/rootcd"
2967 COMPRESSION="${2:-none}"
2968 ISO_NAME="${3:-slitaz}"
2969 check_root
2970 # Start info
2971 title 'Write filesystem to ISO'
2972 longline "The command writeiso will write the current filesystem into a \
2973 suitable cpio archive (rootfs.gz) and generate a bootable ISO image (slitaz.iso)."
2974 newline
2975 emsg "<b>Archive compression:</b> <c 36>$COMPRESSION</c>"
2977 [ "$COMPRESSION" == 'gzip' ] && colorize 31 "gzip-compressed rootfs unsupported and may fail to boot"
2978 # Save some space
2979 rm -rf /var/cache/tazpkg/*
2980 rm -f /var/lib/tazpkg/*.bak
2981 rm -rf $DISTRO
2983 # Optionally remove sound card selection and screen resolution.
2984 if [ -z $LaunchedByTazpanel ]; then
2985 anser=$(yesorno 'Do you wish to remove the sound card and screen configs?' 'n')
2986 case $anser in
2987 y)
2988 action 'Removing current sound card and screen configurations...'
2989 rm -f /var/lib/sound-card-driver
2990 rm -f /var/lib/alsa/asound.state
2991 rm -f /etc/X11/xorg.conf ;;
2992 *)
2993 action 'Keeping current sound card and screen configurations...' ;;
2994 esac
2995 status
2996 newline
2998 # Optionally remove i18n settings
2999 anser=$(yesorno 'Do you wish to remove locale/keymap settings?' 'n')
3000 case $anser in
3001 y)
3002 action 'Removing current locale/keymap settings...'
3003 newline > /etc/locale.conf
3004 newline > /etc/keymap.conf ;;
3005 *)
3006 action 'Keeping current locale/keymap settings...' ;;
3007 esac
3008 status
3009 fi
3011 # Clean-up files by default
3012 newline > /etc/udev/rules.d/70-persistent-net.rules
3013 newline > /etc/udev/rules.d/70-persistant-cd.rules
3015 # Create list of files including default user files since it is defined in /etc/passwd
3016 # and some new users might have been added.
3017 cd /
3018 echo 'init' > /tmp/list
3019 for dir in bin etc sbin var dev lib root usr home opt; do
3020 [ -d $dir ] && find $dir
3021 done >> /tmp/list
3023 for dir in proc sys tmp mnt media media/cdrom media/flash media/usbdisk run run/udev; do
3024 [ -d $dir ] && echo $dir
3025 done >> /tmp/list
3027 sed '/var\/run\/.*pid$/d ; /var\/run\/utmp/d ; /.*\/.gvfs/d ; /home\/.*\/.cache\/.*/d' -i /tmp/list
3029 #if [ ! $(find /var/log/slitaz/tazpkg.log -size +4k) = "" ]; then
3030 # sed -i "/var\/log\/slitaz\/tazpkg.log/d" /tmp/list
3031 #fi
3032 mv -f /var/log/wtmp /tmp/tazlito-wtmp
3033 touch /var/log/wtmp
3035 for removelog in auth boot messages dmesg daemon slim .*old Xorg tazpanel cups; do
3036 sed -i "/var\/log\/$removelog/d" /tmp/list
3037 done
3039 # Generate initramfs with specified compression and display rootfs
3040 # size in realtime.
3041 rm -f /tmp/.write-iso* /tmp/rootfs 2>/dev/null
3043 write_initramfs &
3044 sleep 2
3045 cd - > /dev/null
3046 echo -en "\nFilesystem size:"
3047 while [ ! -f /tmp/rootfs ]; do
3048 sleep 1
3049 echo -en "\\033[18G$(du -sh /$INITRAMFS | awk '{print $1}') "
3050 done
3051 mv -f /tmp/tazlito-wtmp /var/log/wtmp
3052 echo -e "\n"
3053 rm -f /tmp/rootfs
3055 # Move freshly generated rootfs to the cdrom.
3056 mkdir -p $ROOTCD/boot
3057 mv -f /$INITRAMFS $ROOTCD/boot
3058 _ 'Located in: %s' "$ROOTCD/boot/$INITRAMFS"
3060 # Now we need the kernel and isolinux files.
3061 copy_from_cd() {
3062 cp /media/cdrom/boot/bzImage* $ROOTCD/boot
3063 cp -a /media/cdrom/boot/isolinux $ROOTCD/boot
3064 unmeta_boot $ROOTCD
3065 umount /media/cdrom
3068 if mount /dev/cdrom /media/cdrom 2>/dev/null; then
3069 copy_from_cd;
3070 elif mount | grep /media/cdrom; then
3071 copy_from_cd;
3072 #elif [ -f "$bootloader" -a -f /boot/vmlinuz*slitaz* ]; then
3073 # [ -f /boot/*slitaz ] && cp /boot/vmlinuz*slitaz $ROOTCD/boot/bzImage
3074 # [ -f /boot/*slitaz64 ] && cp /boot/vmlinuz*slitaz64 $ROOTCD/boot/bzImage64
3075 else
3076 touch /tmp/.write-iso-error
3077 longline "When SliTaz is running in RAM the kernel and bootloader \
3078 files are kept on the CD-ROM. `boldify ' Please insert a Live CD or run:
3079 # mount -o loop slitaz.iso /media/cdrom ' ` to let Tazlito copy the files."
3080 echo -en "----\nENTER to continue..."; read i
3081 [ ! -d /media/cdrom/boot/isolinux ] && exit 1
3082 copy_from_cd
3083 fi
3085 # Generate the iso image.
3086 touch /tmp/.write-iso
3087 newline
3088 cd $DISTRO
3089 create_iso $ISO_NAME.iso $ROOTCD
3090 action 'Creating the ISO md5sum...'
3091 md5sum $ISO_NAME.iso > $ISO_NAME.md5
3092 status
3094 footer "ISO image: $(du -sh $DISTRO/$ISO_NAME.iso)"
3095 rm -f /tmp/.write-iso
3097 if [ -z $LaunchedByTazpanel ]; then
3098 anser=$(yesorno 'Burn ISO to CD-ROM?' 'n')
3099 case $anser in
3100 y)
3101 umount /dev/cdrom 2>/dev/null
3102 eject
3103 echo -n "Please insert a blank CD-ROM and press ENTER..."
3104 read i && sleep 2
3105 tazlito burn-iso $DISTRO/$ISO_NAME.iso
3106 echo -en "----\nENTER to continue..."; read i ;;
3107 *)
3108 exit 0 ;;
3109 esac
3110 fi
3111 ;;
3114 burn-iso)
3115 # Guess CD-ROM device, ask user and burn the ISO.
3117 check_root
3118 DRIVE_NAME=$(grep "drive name" /proc/sys/dev/cdrom/info | cut -f3)
3119 DRIVE_SPEED=$(grep "drive speed" /proc/sys/dev/cdrom/info | cut -f3)
3120 # We can specify an alternative ISO from the cmdline.
3121 iso="${2:-$DISTRO/$ISO_NAME.iso}"
3122 [ ! -f "$iso" ] && die "Unable to find ISO: $iso"
3124 title 'Tazlito burn ISO'
3125 echo "CD-ROM device : /dev/$DRIVE_NAME"
3126 echo "Drive speed : $DRIVE_SPEED"
3127 echo "ISO image : $iso"
3128 footer
3130 case $(yesorno 'Burn ISO image?' 'n') in
3131 y)
3132 title 'Starting Wodim to burn the ISO...'
3133 sleep 2
3134 wodim speed=$DRIVE_SPEED dev=/dev/$DRIVE_NAME $iso
3135 footer 'ISO image is burned to CD-ROM.'
3136 ;;
3137 *)
3138 die 'Exiting. No ISO burned.'
3139 ;;
3140 esac
3141 ;;
3144 merge)
3145 # Merge multiple rootfs into one iso.
3147 if [ -z "$2" ]; then
3148 cat <<EOT
3149 Usage: tazlito merge size1 iso size2 rootfs2 [sizeN rootfsN]...
3151 Merge multiple rootfs into one ISO. Rootfs are like russian dolls
3152 i.e: rootfsN is a subset of rootfsN-1
3153 rootfs1 is found in ISO, sizeN is the RAM size needed to launch rootfsN.
3154 The boot loader will select the rootfs according to the RAM size detected.
3156 Example:
3157 $ tazlito merge 160M slitaz-core.iso 96M rootfs-justx.gz 32M rootfs-base.gz
3159 Will start slitaz-core with 160M+ RAM, slitaz-justX with 96M-160M RAM,
3160 slitaz-base with 32M-96M RAM and display an error message if RAM < 32M.
3162 EOT
3163 exit 2
3164 fi
3166 shift # skip merge
3167 append="$1 slitaz1"
3168 shift # skip size1
3169 mkdir -p $TMP_DIR/mnt $TMP_DIR/rootfs1
3171 ISO=$1.merged
3173 # Extract filesystems
3174 action 'Mounting %s' "$1"
3175 mount -o loop,ro $1 $TMP_DIR/mnt 2> /dev/null
3176 status || cleanup_merge
3178 cp -a $TMP_DIR/mnt $TMP_DIR/iso
3179 make_bzImage_hardlink $TMP_DIR/iso/boot
3180 umount -d $TMP_DIR/mnt
3181 if [ -f $TMP_DIR/iso/boot/rootfs1.gz ]; then
3182 _ '%s is already a merged iso. Aborting.' "$1"
3183 cleanup_merge
3184 fi
3185 if [ ! -f $TMP_DIR/iso/boot/isolinux/ifmem.c32 -a
3186 ! -f $TMP_DIR/iso/boot/isolinux/c32box.c32 ]; then
3187 if [ ! -f /boot/isolinux/ifmem.c32 -a
3188 ! -f /boot/isolinux/c32box.c32 ]; then
3189 cat <<EOT
3190 No file /boot/isolinux/ifmem.c32
3191 Please install syslinux package !
3192 EOT
3193 rm -rf $TMP_DIR
3194 exit 1
3195 fi
3196 cp /boot/isolinux/c32box.c32 $TMP_DIR/iso/boot/isolinux 2> /dev/null ||
3197 cp /boot/isolinux/ifmem.c32 $TMP_DIR/iso/boot/isolinux
3198 fi
3200 action 'Extracting %s' 'iso/rootfs.gz'
3201 extract_rootfs $TMP_DIR/iso/boot/rootfs.gz $TMP_DIR/rootfs1 &&
3202 [ -d $TMP_DIR/rootfs1/etc ]
3203 status || cleanup_merge
3205 n=1
3206 while [ -n "$2" ]; do
3207 shift # skip rootfs N-1
3208 p=$n
3209 n=$(($n + 1))
3210 append="$append $1 slitaz$n"
3211 shift # skip size N
3212 mkdir -p $TMP_DIR/rootfs$n
3214 action 'Extracting %s' "$1"
3215 extract_rootfs $1 $TMP_DIR/rootfs$n &&
3216 [ -d "$TMP_DIR/rootfs$n/etc" ]
3217 status || cleanup_merge
3219 mergefs $TMP_DIR/rootfs$n $TMP_DIR/rootfs$p
3220 action 'Creating %s' "rootfs$p.gz"
3221 pack_rootfs "$TMP_DIR/rootfs$p" "$TMP_DIR/iso/boot/rootfs$p.gz"
3222 status
3223 done
3224 action 'Creating %s' "rootfs$n.gz"
3225 pack_rootfs "$TMP_DIR/rootfs$n" "$TMP_DIR/iso/boot/rootfs$n.gz"
3226 status
3227 rm -f $TMP_DIR/iso/boot/rootfs.gz
3228 update_bootconfig $TMP_DIR/iso/boot/isolinux "$append"
3229 create_iso $ISO $TMP_DIR/iso
3230 rm -rf $TMP_DIR
3231 ;;
3234 repack)
3235 # Repack an iso with maximum lzma compression ratio.
3237 ISO=$2
3238 mkdir -p $TMP_DIR/mnt
3240 # Extract filesystems
3241 action 'Mounting %s' "$ISO"
3242 mount -o loop,ro $ISO $TMP_DIR/mnt 2>/dev/null
3243 status || cleanup_merge
3245 cp -a $TMP_DIR/mnt $TMP_DIR/iso
3246 umount -d $TMP_DIR/mnt
3248 for i in $TMP_DIR/iso/boot/rootfs* ; do
3249 action 'Repacking %s' "$(basename $i)"
3250 uncompress $i 2>/dev/null > $TMP_DIR/rootfs
3251 lzma e $TMP_DIR/rootfs $i $(lzma_switches $TMP_DIR/rootfs)
3252 align_to_32bits $i
3253 status
3254 done
3256 create_iso $ISO $TMP_DIR/iso
3257 rm -rf $TMP_DIR
3258 ;;
3261 build-loram)
3262 # Build a Live CD for low RAM systems.
3264 ISO="$2"
3265 OUTPUT="$3"
3266 [ -z "$3" ] && \
3267 die "Usage: tazlito build-loram <input>.iso <output>.iso [cdrom|smallcdrom|http|ram]"
3268 mkdir -p "$TMP_DIR/iso"
3269 mount -o loop,ro -t iso9660 "$ISO" "$TMP_DIR/iso"
3270 loopdev=$( (losetup -a 2>/dev/null || losetup) | sed "/$(echo $ISO | sed 's|/|\\/|g')$/!d;s/:.*//;q")
3271 if ! check_iso_for_loram ; then
3272 umount -d "$TMP_DIR/iso"
3273 die "$ISO is not a valid SliTaz live CD. Abort."
3274 fi
3275 case "$4" in
3276 cdrom) build_loram_cdrom ;;
3277 http) build_loram_http ;;
3278 *) build_loram_ram "$5" ;;
3279 esac
3280 umount $TMP_DIR/iso # no -d: needs /proc
3281 losetup -d $loopdev
3282 rm -rf $TMP_DIR
3283 ;;
3286 emu-iso)
3287 # Emulate an ISO image with Qemu.
3288 iso="${2:-$DISTRO/$ISO_NAME.iso}"
3289 [ -f "$iso" ] || die "Unable to find ISO file '$iso'."
3290 [ -x '/usr/bin/qemu' ] || die "Unable to find Qemu binary. Please install package 'qemu'."
3291 echo -e "\nStarting Qemu emulator:\n"
3292 echo -e "qemu $QEMU_OPTS $iso\n"
3293 qemu $QEMU_OPTS $iso
3294 ;;
3297 deduplicate)
3298 # Deduplicate files in a tree
3299 shift
3300 deduplicate "$@"
3301 ;;
3304 usage|*)
3305 # Print usage also for all unknown commands.
3306 usage
3307 ;;
3308 esac
3310 exit 0