tazlito rev 412

Rewrite some parts of tazlito, add man pages. Working in progress...
author Aleksej Bobylev <al.bobylev@gmail.com>
date Sat Feb 20 17:06:44 2016 +0200 (2016-02-20)
parents e531b58ef2dc
children bd4b1f42430b
files AUTHORS man/flavor.5 man/tazlito.1 man/tazlito.conf.5 tazlito
line diff
     1.1 --- a/AUTHORS	Thu Jan 07 00:24:41 2016 +0000
     1.2 +++ b/AUTHORS	Sat Feb 20 17:06:44 2016 +0200
     1.3 @@ -3,3 +3,4 @@
     1.4  Paul Issott <paul@slitaz.org>
     1.5  Eric Joseph-Alexandre <erjo@slitaz.org>
     1.6  Claudinei Pereira <claudinei@slitaz.org>
     1.7 +Aleksej Bobylev <al.bobylev@gmail.com>
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/man/flavor.5	Sat Feb 20 17:06:44 2016 +0200
     2.3 @@ -0,0 +1,202 @@
     2.4 +.TH "TazLiTo flavor" "1" "17.02.2016"
     2.5 +.SH NAME
     2.6 +Tazlito flavor file (\fB.flavor\fR).
     2.7 +.SH SYNOPSIS
     2.8 +\fIname\fB.flavor\fR
     2.9 +.SH DESCRIPTION
    2.10 +A \fB.flavor\fR is a small file contains information needed to (re)manufacture
    2.11 +a custom LiveCD of SliTaz.
    2.12 +.PP
    2.13 +.IB flavor .flavor
    2.14 +file is a cpio.gzip archive that contains next files inside:
    2.15 +.TP
    2.16 +.IB flavor .receipt
    2.17 +File describing the flavor using the variables:
    2.18 +.Bl -bullet
    2.19 +.It
    2.20 +FLAVOR: the flavor name
    2.21 +.It
    2.22 +SHORT_DESC: short description
    2.23 +.It
    2.24 +VERSION: free format
    2.25 +.It
    2.26 +MAINTAINER: e-mail address of the flavor maintainer
    2.27 +.It
    2.28 +FRUGAL_RAM: minimum RAM required (optional)
    2.29 +.It
    2.30 +ROOTFS_SIZE: size of rootfs.gz decompressed into RAM (optional)
    2.31 +.It
    2.32 +INITRAMFS_SIZE: size of rootfs.gz on the CD-ROM (optional)
    2.33 +.It
    2.34 +ISO_SIZE: size of CD-ROM (optional)
    2.35 +.It
    2.36 +ROOTFS_SELECTION: optional, see \fBMeta flavor below\fR.
    2.37 +.El
    2.38 +Receipt may contain function \fIcustom_rules()\fR executed after installing all
    2.39 +packages, adding custom rootfs files, and executing \fIdistro.sh\fR script.
    2.40 +.TP
    2.41 +.IB flavor .desc
    2.42 +File describing the flavor (the most of the information is taken from the
    2.43 +receipt): flavor name, description, version, maintainer e-mail, Live CD RAM
    2.44 +size, build date, number of the packages, rootFS size, initRAMFS size, ISO
    2.45 +image size.
    2.46 +.TP
    2.47 +.IB flavor .pkglist
    2.48 +List of packages without specifying the version (tazlito uses the latest
    2.49 +available). This file is missing if ROOTFS_SELECTION exists in the receipt.
    2.50 +.TP
    2.51 +.IB flavor .nonfree
    2.52 +Optional list of non-free packages.
    2.53 +.TP
    2.54 +.IB flavor -distro.sh
    2.55 +Optional script executed after installing all packages and adding custom rootfs
    2.56 +files to perform tasks in the rootfs before compression. Script executed with
    2.57 +argument $DISTRO defined in the tazlito.conf(5).
    2.58 +.TP
    2.59 +.IB flavor .mirrors
    2.60 +Optional file containing the list of undigest (unofficial) mirrors to be added
    2.61 +to include personal packages.
    2.62 +.TP
    2.63 +.IB flavor .rootfs
    2.64 +Optional cpio.gzip archive containing the root filesystem tree (so it should
    2.65 +contain all the necessary top-level directories such as bin, etc, usr...).
    2.66 +Files contained in this archive will be directly extracted to the root
    2.67 +filesystem of the prepared flavor (configuration files usually).
    2.68 +.TP
    2.69 +.IB flavor .rootcd
    2.70 +Optional cpio.gzip archive that files and folders will be directly extracted to
    2.71 +the root of the CD-ROM.
    2.72 +.SH WORKING WITH FLAVORS
    2.73 +.SS Manufacture a flavor
    2.74 +You can choose the flavor to (re)manufacture from among those available:
    2.75 +.nf
    2.76 +$ tazlito list-flavors
    2.77 +.fi
    2.78 +.B List of flavors
    2.79 +.TS
    2.80 +l r r l.
    2.81 +\fBName\fR	\fBISO\fR	\fBRootfs\fR	\fBDescription\fR
    2.82 +_
    2.83 +base	12.0M	21.0M	Minimal set of packages to boot
    2.84 +core-4in1	42.0M	152.4M	SliTaz core system with justX and base alternatives
    2.85 +core	31.5M	104.6M	SliTaz core system
    2.86 +eeepc	31.2M	105.4M	SliTaz eeepc system
    2.87 +justX	16.1M	51.2M	SliTaz with a minimal X environment
    2.88 +.TE
    2.89 +.PP
    2.90 +We will start by remanufacturing the
    2.91 +.I eeepc
    2.92 +flavor which uses 105.4M of RAM and has a CD-ROM size of 31.2M:
    2.93 +.nf
    2.94 +# tazlito clean-distro
    2.95 +# tazlito get-flavor \fIeeepc\fR
    2.96 +# tazlito gen-distro
    2.97 +.fi
    2.98 +.SS Create a flavor
    2.99 +To create a flavor, you must:
   2.100 +.Bl -bullet
   2.101 +.It
   2.102 +Either create an ISO image with
   2.103 +.B tazlito gen-distro
   2.104 +and then create a flavor file with
   2.105 +.B tazlito gen-flavor
   2.106 +.It
   2.107 +Either directly create the tree structure that defines the flavor (see
   2.108 +.BR "tazlito extract-flavor" )
   2.109 +and then create the flavor with
   2.110 +.B tazlito pack-flavor
   2.111 +.It
   2.112 +Either use the
   2.113 +.B online builder
   2.114 +http://pizza.slitaz.org/
   2.115 +.El
   2.116 +.SS Post a flavor
   2.117 +Because a
   2.118 +.I .flavor
   2.119 +file contains just a few KB, it can be easily sent via the
   2.120 +mailing list
   2.121 +.RI ( http://www.slitaz.org/en/mailing-list.php ).
   2.122 +.PP
   2.123 +The results of
   2.124 +.B tazlito extract-flavor
   2.125 +can also be put in mercurial
   2.126 +.RI ( http://hg.slitaz.org/flavors ).
   2.127 +This method is preferred because the tree will be directly visible with the
   2.128 +mercurial web interface
   2.129 +.RI ( http://hg.slitaz.org/flavors/file/tip ).
   2.130 +.PP
   2.131 +This tree includes:
   2.132 +.Bl -bullet
   2.133 +.It
   2.134 +A \fBreceipt\fR file describing the flavor thanks to the variables:
   2.135 +.Bl -bullet
   2.136 +.It
   2.137 +FLAVOR: The flavor name.
   2.138 +.It
   2.139 +SHORT_DESC: Short description.
   2.140 +.It
   2.141 +VERSION: Free format.
   2.142 +.It
   2.143 +MAINTAINER: Email address of maintainer.
   2.144 +.It
   2.145 +FRUGAL_RAM: Minimum RAM required (optional).
   2.146 +.It
   2.147 +ROOTFS_SIZE: Size of rootfs.gz decompressed into RAM (optional).
   2.148 +.It
   2.149 +INITRAMFS_SIZE: Size of rootfs.gz on the CD-ROM (optional).
   2.150 +.It
   2.151 +ISO_SIZE: Size of CD-ROM (optional).
   2.152 +.It
   2.153 +ROOTFS_SELECTION: Optional, see \fBMeta flavor\fR below.
   2.154 +.El
   2.155 +.It
   2.156 +The file \fBpackages.list\fR containing the list of packages without specifying
   2.157 +the version (tazlito uses the latest available). This file is missing if
   2.158 +ROOTFS_SELECTION exists in the receipt.
   2.159 +.It
   2.160 +The optional \fBmirrors\fR file containing the list of unofficial mirrors
   2.161 +(undigest) to be added to include personal packages.
   2.162 +.It
   2.163 +The optional directory \fBrootfs\fR containing the tree to add to the root
   2.164 +filesystem rootfs.gz (configuration files usually).
   2.165 +.It
   2.166 +The optional directory \fBrootcd\fR containing the tree to add to the root of
   2.167 +the CD-ROM.
   2.168 +.El
   2.169 +.SS Adapt a flavor
   2.170 +It is often easier to modify an existing flavor than to create one from
   2.171 +scratch. To adapt the eeepc flavor for example:
   2.172 +.nf
   2.173 +# tazpkg get-install mercurial
   2.174 +# cd /home/slitaz
   2.175 +# hg clone http://hg.slitaz.org/flavors
   2.176 +# cd flavors
   2.177 +# cp -a \fIeeepc myslitaz\fR
   2.178 +.fi
   2.179 +Files in \fImyslitaz\fR can then be changed, and:
   2.180 +.nf
   2.181 +# tazlito pack-flavor \fImyslitaz\fR
   2.182 +.fi
   2.183 +Will simply create the new flavor.
   2.184 +.PP
   2.185 +Tip: you can skip mercurial installation by extracting a flavor. Using the
   2.186 +previous example:
   2.187 +.nf
   2.188 +# tazlito get-flavor \fIeeepc\fR
   2.189 +# tazlito extract-flavor \fIeeepc.flavor\fR
   2.190 +# cd /home/slitaz/flavors
   2.191 +# cp -a \fIeeepc myslitaz\fR
   2.192 +.fi
   2.193 +.SS Meta flavor
   2.194 +A meta flavor contains several flavors like nested Russian dolls. The flavor
   2.195 +will be launched at startup according to the amount of RAM available. The
   2.196 +ROOTFS_SELECTION variable defines the minimum RAM and corresponding flavor
   2.197 +parameters, example
   2.198 +.RI ( http://hg.slitaz.org/flavors/file/tip/core-4in1/receipt ):
   2.199 +.nf
   2.200 +ROOTFS_SELECTION="160M core 96M justX 32M base"
   2.201 +.fi
   2.202 +A meta flavor doesn't contain a list of packages (\fIpackages.list\fR). SliTaz
   2.203 +kernels prior to 2.6.30 do not support meta flavors.
   2.204 +.SH SEE ALSO
   2.205 +tazlito(1), tazlito.conf(5).
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/man/tazlito.1	Sat Feb 20 17:06:44 2016 +0200
     3.3 @@ -0,0 +1,352 @@
     3.4 +.TH TazLiTo "1" "29.01.2016"
     3.5 +.SH NAME
     3.6 +Tazlito \(em SliTaz Live Tool.
     3.7 +.SH SYNTAX
     3.8 +.nf
     3.9 +.RI "tazlito [" command "] [" list | iso | flavor "] [" dir ]
    3.10 +.fi
    3.11 +.SH DESCRIPTION
    3.12 +Tazlito is a small utility to extract a Live CD, rebuild the ISO image and
    3.13 +regenerate the root filesystem of the Live CD. Tazlito can also generate a
    3.14 +distribution from a list of packages previously downloaded. Tazlito uses the
    3.15 +configuration file
    3.16 +.IR tazlito.conf (5).
    3.17 +.PP
    3.18 +Tazlito installed by default on SliTaz and installed/successfully tested on
    3.19 +Debian GNU/Linux. You will find additional information about creating a LiveCD
    3.20 +in the Handbook.
    3.21 +.SH COMMANDS
    3.22 +.SS usage
    3.23 +Display a summary of available commands with a short description.
    3.24 +.nf
    3.25 +$ tazlito usage
    3.26 +.fi
    3.27 +.SS stats
    3.28 +Display the configuration variables, the paths to the various files and
    3.29 +directories, and information on the ISO image.
    3.30 +.nf
    3.31 +$ tazlito stats
    3.32 +.fi
    3.33 +.SS list-addfiles
    3.34 +Display the list of additional files in the rootfs.
    3.35 +.nf
    3.36 +$ tazlito list-addfiles
    3.37 +.fi
    3.38 +.SS gen-config
    3.39 +Generate a configuration file ready to be edited.
    3.40 +.PP
    3.41 +By default the file is created in the current directory, but can be in another
    3.42 +directory if specified via the command line.
    3.43 +.nf
    3.44 +$ tazlito gen-config
    3.45 +$ tazlito gen-config \fI/path/to/distro\fR
    3.46 +.fi
    3.47 +.SS configure
    3.48 +Configure the system configuration file or one found in the current directory.
    3.49 +.PP
    3.50 +You will be asked for ISO name, volume name, paths to packages repository and
    3.51 +to distro.
    3.52 +.nf
    3.53 +# tazlito configure
    3.54 +.fi
    3.55 +.SS gen-iso
    3.56 +Generate a new Live CD image following modifications and additions to the root
    3.57 +filesystem of the CD-ROM.
    3.58 +.PP
    3.59 +To function, this command needs a directory containing the distro-tree of the
    3.60 +Live system. This tree can easily be built with the
    3.61 +.B extract-distro
    3.62 +command, modified and rebuilt via:
    3.63 +.nf
    3.64 +# tazlito gen-iso
    3.65 +.fi
    3.66 +.SS gen-initiso
    3.67 +The same as
    3.68 +.BR gen-iso ,
    3.69 +but it rebuilds the initramfs compressed system prior.
    3.70 +.PP
    3.71 +The initramfs contains the root filesystem and must be rebuilt if modified.
    3.72 +.nf
    3.73 +# tazlito gen-initiso
    3.74 +.fi
    3.75 +.SS list-flavors
    3.76 +Download (if necessary) and display a list of the different flavors available.
    3.77 +.PP
    3.78 +You can force the download with the
    3.79 +.I --recharge
    3.80 +option.
    3.81 +.nf
    3.82 +$ tazlito list-flavors
    3.83 +# tazlito list-flavors --recharge
    3.84 +.fi
    3.85 +.SS get-flavor
    3.86 +Download (if necessary) and prepares the files for
    3.87 +.B gen-distro
    3.88 +to generate an ISO image.
    3.89 +.PP
    3.90 +Option
    3.91 +.I --noup
    3.92 +can be used to skip updating flavor (see
    3.93 +.B upgrade-flavor
    3.94 +command).
    3.95 +.nf
    3.96 +# tazlito get-flavor \fIcore\fR
    3.97 +.fi
    3.98 +.SS show-flavor
    3.99 +Display the description of the flavor and its size after regeneration.
   3.100 +.PP
   3.101 +The options
   3.102 +.IR --brief " and " --noheader
   3.103 +reduce the output displayed.
   3.104 +.nf
   3.105 +$ tazlito show-flavor \fIbase\fR
   3.106 +$ tazlito show-flavor \fIjustx\fR --brief
   3.107 +$ tazlito show-flavor \fIcore\fR --brief --noheader
   3.108 +.fi
   3.109 +.SS gen-flavor
   3.110 +Create a description file of a new flavor from the results of generating a
   3.111 +distro
   3.112 +.RB ( gen-distro ).
   3.113 +The
   3.114 +.I .flavor
   3.115 +file can then be sent to slitaz.org.
   3.116 +.nf
   3.117 +# tazlito gen-flavor \fInew-flavor\fR
   3.118 +.fi
   3.119 +.SS gen-liveflavor
   3.120 +Create a description file of a new flavor from the results of generating a
   3.121 +distro based on the current system.
   3.122 +.PP
   3.123 +The
   3.124 +.I --help
   3.125 +option provides more information.
   3.126 +.nf
   3.127 +# tazlito gen-liveflavor --help
   3.128 +# tazlito gen-liveflavor \fIflavor-name\fR
   3.129 +# tazlito gen-liveflavor \fIflavor-name flavor-patch-file\fR
   3.130 +.fi
   3.131 +Format of the flavor-patch-file:
   3.132 +.TS
   3.133 +c l.
   3.134 +\fBcode\fR	\fBdata\fR
   3.135 +_
   3.136 +@	flavor description
   3.137 ++	package to add
   3.138 +-	package to remove
   3.139 +!	non-free package to add
   3.140 +?	display message
   3.141 +.TE
   3.142 +Example:
   3.143 +.nf
   3.144 +@ Developer tools for SliTaz maintainers
   3.145 ++ slitaz-toolchain
   3.146 ++ mercurial
   3.147 +.fi
   3.148 +.SS iso2flavor
   3.149 +Create a flavor file from the ISO image.
   3.150 +.nf
   3.151 +# tazlito iso2flavor \fIslitaz-cooking.iso mycooking\fR
   3.152 +.fi
   3.153 +.SS upgrade-flavor
   3.154 +Refresh a flavor description file. Sizes and actual number of packages will be
   3.155 +re-calculated. List of unknown packages will be displayed if any, as well as
   3.156 +list of important packages missed in the flavor (like
   3.157 +.BR syslinux " or " linux ).
   3.158 +Packages versions (presented in the legacy flavor format) will be stripped from
   3.159 +the flavor package list.
   3.160 +.nf
   3.161 +# tazlito upgrade-flavor \fIcore\fR
   3.162 +.fi
   3.163 +.SS extract-flavor
   3.164 +Convert a flavor into an easily modifiable tree structure. Path to the
   3.165 +extracted flavors repository specified by variable
   3.166 +.I FLAVORS_REPOSITORY
   3.167 +in the tazlito.conf(5) (by default
   3.168 +.IR /home/slitaz/cooking/flavors ).
   3.169 +.PP
   3.170 +This repository can be managed with mercurial: http://hg.slitaz.org/flavors .
   3.171 +.nf
   3.172 +# tazlito extract-flavor \fIcore\fR
   3.173 +.fi
   3.174 +.SS pack-flavor
   3.175 +Convert a tree structure, extracted by
   3.176 +.B extract-flavor
   3.177 +into a flavor file
   3.178 +.RI ( .flavor ).
   3.179 +.nf
   3.180 +# tazlito pack-flavor \fIcore\fR
   3.181 +.fi
   3.182 +Execute this command after changing existing flavor, or after preparing new
   3.183 +flavor. File
   3.184 +.I packages.list
   3.185 +inside flavor tree structure can contain include directive at the beginning,
   3.186 +for example:
   3.187 +.nf
   3.188 +@include \fIjustx\fR
   3.189 +.fi
   3.190 +to include all the packages listed in the
   3.191 +.I justx
   3.192 +flavor.
   3.193 +.SS extract-distro
   3.194 +Extract an ISO image from the Live CD to rebuild the structure of the root
   3.195 +CD-ROM and system. It is then possible to make the desired changes or additions
   3.196 +and rebuild the ISO image via
   3.197 +.BR gen-iso " or " gen-initiso .
   3.198 +.PP
   3.199 +ISO image is extracted by default to the path specified by variable
   3.200 +.I DISTRO
   3.201 +in the tazlito.conf(5). Desired path may be specified in the second argument.
   3.202 +.nf
   3.203 +# tazlito extract-distro \fI/tmp/slitaz-cooking.iso\fR
   3.204 +# tazlito extract-distro \fI/tmp/slitaz-cooking.iso\fR \fI/tmp/extracted\fR
   3.205 +.fi
   3.206 +.SS gen-distro
   3.207 +Generate the distro-tree and an ISO image via a list of packages.
   3.208 +.PP
   3.209 +To function, this command needs a list of packages and other files provided by
   3.210 +command
   3.211 +.BR get-flavor .
   3.212 +List is expected to be the file
   3.213 +.I distro-packages.list
   3.214 +in the current directory, or can be specified in the command argument.
   3.215 +If package list not given, new list
   3.216 +.I distro-packages.list
   3.217 +will be re-created in the current directory using all currently installed
   3.218 +packages.
   3.219 +.PP
   3.220 +If one uses the Live CD, the options
   3.221 +.IR --cdrom " and " --iso=
   3.222 +allows the regeneration of packages that place files in
   3.223 +.I /boot
   3.224 +without being obliged to download them and recovers the additional files of the
   3.225 +Live CD.
   3.226 +.PP
   3.227 +The path to the various directories are configured in the tazlito.conf(5)
   3.228 +and packages can be downloaded from the SliTaz mirrors or generated by
   3.229 +Cookutils.
   3.230 +.nf
   3.231 +# tazlito gen-distro
   3.232 +# tazlito gen-distro --cdrom
   3.233 +# tazlito gen-distro --iso=\fIslitaz.iso\fR
   3.234 +# tazlito gen-distro \fIpackage-list\fR
   3.235 +.fi
   3.236 +.SS clean-distro
   3.237 +Remove all files generated or extracts of the structure of the LiveCD.
   3.238 +.nf
   3.239 +# tazlito clean-distro
   3.240 +.fi
   3.241 +.SS check-distro
   3.242 +Verify few configuration files in the generated rootfs
   3.243 +.RI ( /etc/slitaz-release ", " /var/lib/tazpkg/mirror ,
   3.244 +.IR /boot/isolinux/isolinux.cfg ).
   3.245 +.PP
   3.246 +.B TODO:
   3.247 +Remove this function. First two files are maintained by tazpkg while it runs on
   3.248 +rootfs, while last one file should be maintained by tazlito itself.
   3.249 +.nf
   3.250 +# tazlito check-distro
   3.251 +.fi
   3.252 +.SS writeiso
   3.253 +Write the current filesystem to a cpio archive
   3.254 +.RI ( rootfs.gz )
   3.255 +and then generate a bootable ISO image. Writeiso can be used in a HD install or
   3.256 +in live mode and will also archive your current
   3.257 +.I /home
   3.258 +directory.
   3.259 +.PP
   3.260 +This command lets you easily remaster and build your own Live CD image, just
   3.261 +boot, modify any files, and then:
   3.262 +.nf
   3.263 +# tazlito writeiso [gzip|lzma|none]
   3.264 +# tazlito writeiso gzip
   3.265 +# tazlito writeiso gzip \fIimage-name\fR
   3.266 +.fi
   3.267 +.SS repack
   3.268 +Recompress the rootfs with the best possible compression.
   3.269 +.nf
   3.270 +# tazlito repack \fIslitaz.iso\fR
   3.271 +.fi
   3.272 +.SS merge
   3.273 +Combine several flavors like nested Russian dolls. Each rootfs is a subset of
   3.274 +the previous. The first rootfs is extracted from the ISO image used in the
   3.275 +third argument. The flavor will then be chosen to launch at startup according
   3.276 +to the amount of RAM available.
   3.277 +.nf
   3.278 +# tazlito merge \fI160M slitaz-core.iso 96M rootfs-justx.gz 32M rootfs-base.gz\fR
   3.279 +.fi
   3.280 +.SS build-loram
   3.281 +Create an ISO image flavor for low RAM systems from a SliTaz ISO image. You can
   3.282 +build a flavor with
   3.283 +.I /
   3.284 +always in RAM or where
   3.285 +.I /
   3.286 +resides on the CD-ROM:
   3.287 +.nf
   3.288 +# tazlito build-loram \fIslitaz.iso loram.iso\fR
   3.289 +# tazlito build-loram \fIslitaz.iso loram-cdrom.iso\fR cdrom
   3.290 +.fi
   3.291 +Third argument can be one of the:
   3.292 +.TP
   3.293 +.I cdrom
   3.294 +Move rootfs to squashfs filesystem(s) to the CD-ROM writeable with
   3.295 +aufs/overlayfs. These squashfs may be loaded in RAM at boot time. Rootfs are also
   3.296 +copied to CD-ROM for tiny ramsize systems. Meta flavors are converted to normal
   3.297 +flavors.
   3.298 +.TP
   3.299 +.I smallcdrom
   3.300 +TODO.
   3.301 +.TP
   3.302 +.I http
   3.303 +Create http bootstrap to load and remove loram_cdrom. Meta flavors are converted
   3.304 +to normal flavors.
   3.305 +.TP
   3.306 +.I ram
   3.307 +Move rootfs to a squashfs filesystem into the initramfs writeable with
   3.308 +aufs/overlayfs. Meta flavor selection sizes are updated.
   3.309 +.SS emu-iso
   3.310 +Use the QEMU emulator to start and run SliTaz.
   3.311 +.PP
   3.312 +QEMU is used to test the newly built ISO image without burning to a CD-ROM or
   3.313 +booting into frugal mode.
   3.314 +.nf
   3.315 +# tazlito emu-iso
   3.316 +# tazlito emu-iso path/to/image.iso
   3.317 +.fi
   3.318 +.SS burn-iso
   3.319 +Burn an ISO image guessing the CD-ROM device and its speed.
   3.320 +.PP
   3.321 +The default ISO image is the one located in the current configuration file, but
   3.322 +it's possible to specify a different image via the command line:
   3.323 +.nf
   3.324 +# tazlito burn-iso
   3.325 +# tazlito burn-iso \fIslitaz-hacked.iso\fR
   3.326 +.fi
   3.327 +.SH LICENSE
   3.328 +Tazlito is free software; you can redistribute it and/or modify it under the
   3.329 +terms of the GNU General Public License as published by the Free Software
   3.330 +Foundation; either version 3 of the License, or (at your option) any later
   3.331 +version.
   3.332 +.PP
   3.333 +Tazlito is distributed in the hope that it will be useful, but
   3.334 +.BR "without any warranty" ;
   3.335 +without even the implied warranty of
   3.336 +.BR merchantability " or " "fitness for a particular purpose" .
   3.337 +See the GNU General Public License for more details.
   3.338 +.SH AUTHORS
   3.339 +Christophe Lincoln <pankso@slitaz.org>
   3.340 +.br
   3.341 +Pascal Bellard <pascal.bellard@ads-lu.com>
   3.342 +.br
   3.343 +Paul Issott <paul@slitaz.org>
   3.344 +.br
   3.345 +Eric Joseph-Alexandre <erjo@slitaz.org>
   3.346 +.br
   3.347 +Claudinei Pereira <claudinei@slitaz.org>
   3.348 +.br
   3.349 +Aleksej Bobylev <al.bobylev@gmail.com>
   3.350 +.SH MAINTAINERS
   3.351 +Christophe Lincoln <pankso@slitaz.org>
   3.352 +.br
   3.353 +Pascal Bellard <pascal.bellard@slitaz.org>
   3.354 +.SH SEE ALSO
   3.355 +tazlito.conf(5), flavor(5).
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/man/tazlito.conf.5	Sat Feb 20 17:06:44 2016 +0200
     4.3 @@ -0,0 +1,85 @@
     4.4 +.TH "tazlito.conf" "5" "17 Feb 2016"
     4.5 +.SH NAME
     4.6 +tazlito.conf \(em configuration for Tazlito
     4.7 +.SH SYNOPSIS
     4.8 +.B tazlito.conf
     4.9 +.SH DESCRIPTON
    4.10 +tazlito(1) uses this configuration file to work. If current directory contains
    4.11 +.IR tazlito.conf ,
    4.12 +it will be used, otherwise system-wide file
    4.13 +.I /etc/tazlito/tazlito.conf
    4.14 +will be used.
    4.15 +.PP
    4.16 +It have shell script syntax, so empty lines and lines starting with \(lq#\(rq
    4.17 +are ignored.
    4.18 +.SH VARIABLES
    4.19 +.TP
    4.20 +.B SLITAZ_VERSION
    4.21 +SliTaz version to use for ISO name and files path.
    4.22 +.sp
    4.23 +Default value is the current SliTaz system version (determined by
    4.24 +.I /etc/slitaz-release
    4.25 +file content), for example, \(lq5.0\(rq.
    4.26 +.TP
    4.27 +.B ISO_NAME
    4.28 +Name of the ISO image to generate.
    4.29 +.sp
    4.30 +Default value is
    4.31 +.RI \(lqslitaz- SLITAZ_VERSION \(rq
    4.32 +(is \(lqslitaz-5.0\(rq).
    4.33 +.TP
    4.34 +.B VOLUM_NAME
    4.35 +ISO image volume name.
    4.36 +.sp
    4.37 +Default value is \(lqSliTaz LiveCD\(rq.
    4.38 +.TP
    4.39 +.B PREPARED
    4.40 +Name of the preparer.
    4.41 +.sp
    4.42 +Default value is the login name of the user prepared the ISO (determined by the
    4.43 +content of the environment variable
    4.44 +.IR USER ),
    4.45 +for example \(lqtux\(rq.
    4.46 +.TP
    4.47 +.B WORK_DIR
    4.48 +Tazlito working directory containing flavors, distro and packages files.
    4.49 +.sp
    4.50 +Default value is
    4.51 +.RI \(lq/home/slitaz/ SLITAZ_VERSION \(rq
    4.52 +(is \(lq/home/slitaz/5.0\(rq).
    4.53 +.TP
    4.54 +.B PACKAGES_REPOSITORY
    4.55 +Path to the packages repository.
    4.56 +.sp
    4.57 +Default value is
    4.58 +.RI \(lq WORK_DIR /packages\(rq,
    4.59 +(is \(lq/home/slitaz/5.0/packages\(rq).
    4.60 +.TP
    4.61 +.B DISTRO
    4.62 +Path to the distro tree to gen-distro from a list of packages.
    4.63 +.sp
    4.64 +Default value is
    4.65 +.RI \(lq WORK_DIR /distro\(rq
    4.66 +(is \(lq/home/slitaz/5.0/distro\(rq).
    4.67 +.TP
    4.68 +.B FLAVORS_REPOSITORY
    4.69 +Path to the Live CD flavors files ( http://hg.slitaz.org/flavors ).
    4.70 +.sp
    4.71 +Default value is
    4.72 +.RI \(lq WORK_DIR /flavors\(rq
    4.73 +(is \(lq/home/slitaz/5.0/flavors\(rq).
    4.74 +.TP
    4.75 +.B ADDFILES
    4.76 +Path to the directory containing additional files to copy into the rootfs and
    4.77 +rootcd of the Live CD.
    4.78 +.sp
    4.79 +Default value is
    4.80 +.RI \(lq DISTRO /addfiles\(rq
    4.81 +(is \(lq/home/slitaz/5.0/distro/addfiles\(rq).
    4.82 +.TP
    4.83 +.B QEMU_OPTS
    4.84 +QEMU emulator options for the tazlito command \(lqemu-iso\(rq.
    4.85 +.sp
    4.86 +Default value is \(lq-m 256\(rq. See the QEMU documentation for details.
    4.87 +.SH SEE ALSO
    4.88 +tazlito(1), flavor(5)
     5.1 --- a/tazlito	Thu Jan 07 00:24:41 2016 +0000
     5.2 +++ b/tazlito	Sat Feb 20 17:06:44 2016 +0200
     5.3 @@ -1,438 +1,479 @@
     5.4  #!/bin/sh
     5.5  # TazLito - SliTaz Live Tool.
     5.6  #
     5.7 -# Tazlito is a tool to help generate and configure SliTaz LiveCD
     5.8 +# Tazlito is a tool to help generate and configure SliTaz Live CD
     5.9  # ISO images. You can create a custom distro in one command from a list of
    5.10  # packages, extract an existing ISO image to hack it, create a new initramfs
    5.11  # and/or a new ISO. Most commands must be run by root, except the stats
    5.12  # and the configuration file manipulation.
    5.13  #
    5.14 -# (C) 2007-2015 SliTaz - GNU General Public License.
    5.15 +# (C) 2007-2016 SliTaz - GNU General Public License.
    5.16  #
    5.17 -# Authors : Christophe Lincoln <pankso@slitaz.org>
    5.18 -#           Pascal Bellard <pascal.bellard@slitaz.org>
    5.19 +# Authors: see the AUTHORS file
    5.20  #
    5.21 -VERSION=5.2.6
    5.22 +
    5.23 +VERSION='6.0'
    5.24  
    5.25  . /lib/libtaz.sh
    5.26 +# Force to use Busybox cpio and wget
    5.27 +alias cpio='busybox cpio'
    5.28 +alias wget='busybox wget'
    5.29  
    5.30  # Tazlito configuration variables to be shorter
    5.31  # and to use words rather than numbers.
    5.32 -COMMAND=$1
    5.33 -LIST_NAME=$2
    5.34 -TMP_DIR=/tmp/tazlito-$$-$RANDOM
    5.35 -TMP_MNT=/media/tazlito-$$-$RANDOM
    5.36 -TOP_DIR=`pwd`
    5.37 -INITRAMFS=rootfs.gz
    5.38 -LOCALSTATE=/var/lib/tazpkg
    5.39 -INSTALLED=$LOCALSTATE/installed
    5.40 -CACHE_DIR=/var/cache/tazpkg
    5.41 -MIRROR=$LOCALSTATE/mirror
    5.42 -DEFAULT_MIRROR="http://mirror.slitaz.org/packages/`cat /etc/slitaz-release`/"
    5.43 -
    5.44 -log=/var/log/tazlito.log
    5.45 -if check_root; then
    5.46 +COMMAND="$1"
    5.47 +LIST_NAME="$2"
    5.48 +TMP_DIR="/tmp/tazlito-$$-$RANDOM"
    5.49 +TMP_MNT="/media/tazlito-$$-$RANDOM"
    5.50 +TOP_DIR="$(pwd)"
    5.51 +INITRAMFS='rootfs.gz'
    5.52 +LOCALSTATE='/var/lib/tazpkg'
    5.53 +INSTALLED="$LOCALSTATE/installed"
    5.54 +CACHE_DIR='/var/cache/tazpkg'
    5.55 +MIRROR="$LOCALSTATE/mirror"
    5.56 +DEFAULT_MIRROR="http://mirror.slitaz.org/packages/$(cat /etc/slitaz-release)/"
    5.57 +
    5.58 +log='/var/log/tazlito.log'
    5.59 +if [ $(id -u) -eq 0 ]; then
    5.60  	newline > $log
    5.61  fi
    5.62  
    5.63 -# Try to include config file, continue if command is gen-config or exit.
    5.64 -# The main config used by default is in /etc/tazlito.
    5.65 -if [ -f "/etc/tazlito/tazlito.conf" ] ; then
    5.66 -	CONFIG_FILE="/etc/tazlito/tazlito.conf"
    5.67 -fi
    5.68 -# Specific distro config file can be put in a distro tree.
    5.69 -if [ -f "$TOP_DIR/tazlito.conf" ] ; then
    5.70 -	CONFIG_FILE="$TOP_DIR/tazlito.conf"
    5.71 -fi
    5.72 -if [ ! "$CONFIG_FILE" = "" ] ; then
    5.73 -	. $CONFIG_FILE
    5.74 -else
    5.75 -	if [ "$COMMAND" = "gen-config" ] ; then
    5.76 -		continue
    5.77 -	else
    5.78 -		echo "Unable to find any configuration file. Please read the docs"
    5.79 -		echo "or run '`basename $0` gen-config' to get an empty config file."
    5.80 -		exit 0
    5.81 -	fi
    5.82 -fi
    5.83 -
    5.84 -# While Tazpkg is not used the default mirror url file does not exist
    5.85 -# and user can't recharge the list of flavors.
    5.86 -if test $(id -u) = 0 ; then
    5.87 -	if [ ! -f "$MIRROR" ]; then
    5.88 -		echo "$DEFAULT_MIRROR" > $MIRROR
    5.89 -	fi
    5.90 -fi
    5.91 -
    5.92 -# Set the rootfs and rootcd path with $DISTRO
    5.93 -# configuration variable.
    5.94 -ROOTFS=$DISTRO/rootfs
    5.95 -ROOTCD=$DISTRO/rootcd
    5.96 -
    5.97 -#####################
    5.98 -# Tazlito functions #
    5.99 -#####################
   5.100 -
   5.101 -# Print the usage.
   5.102 -usage () {
   5.103 -	cat <<EOT
   5.104 -
   5.105 -SliTaz Live Tool - Version: $(colorize 34 "$VERSION")
   5.106 -
   5.107 -$(boldify "Usage:") $(basename $0) [command] [list|iso|flavor|compression] [dir|iso]
   5.108 -
   5.109 -$(boldify "Commands:")
   5.110 -  usage           Print this short usage.
   5.111 -  stats           View Tazlito and distro configuration statistics.
   5.112 -  gen-config      Generate a new configuration file for a distro.
   5.113 -  configure       Configure the main config file or a specific tazlito.conf.
   5.114 -  gen-iso         Generate a new ISO from a distro tree.
   5.115 -  gen-initiso     Generate a new initramfs and ISO from the distro tree.
   5.116 -  list-flavors    List all available package lists on the mirror.
   5.117 -  gen-flavor      Generate a new live-CD description.
   5.118 -  gen-liveflavor  Generate a live-CD description from current system.
   5.119 -  show-flavor     Show live-CD description.
   5.120 -  get-flavor      Get a flavor's list of packages ( --noup to skip upgrade).
   5.121 -  upgrade-flavor  Update package list to the latest available versions.
   5.122 -  extract-flavor  Extract a (*.flavor) flavor into $FLAVORS_REPOSITORY.
   5.123 -  pack-flavor     Pack (and update) a flavor from $FLAVORS_REPOSITORY.
   5.124 -  iso2flavor      Create a flavor file from a SliTaz iso image.
   5.125 -  check-list      Check a distro-packages.list for updates.
   5.126 -  extract-distro  Extract an ISO to a directory and rebuild LiveCD tree.
   5.127 -  gen-distro      Generate a Live distro and ISO from a list of packages.
   5.128 -  clean-distro    Remove all files generated by gen-distro.
   5.129 -  check-distro    Help to check if distro is ready to release.
   5.130 -  writeiso        Use running system to generate a bootable ISO (with /home).
   5.131 -  merge           Merge multiple rootfs into one iso.
   5.132 -  deduplicate	  Deduplicate files in a tree.
   5.133 -  repack          Recompress rootfs into iso with maximum ratio.
   5.134 -  build-loram     Generate a live-CD for low ram systems.
   5.135 -  emu-iso         Emulate an ISO image with Qemu.
   5.136 -  burn-iso        Burn ISO image to a cdrom using Wodim.
   5.137 -
   5.138 -EOT
   5.139 -}
   5.140 -
   5.141 -yesorno() {
   5.142 -	echo -n "$1"
   5.143 -	case "$DEFAULT_ANSWER" in
   5.144 -		Y|y) answer="y";;
   5.145 -		N|n) answer="n";;
   5.146 -		*) read answer;;
   5.147 -	esac
   5.148 -}
   5.149 -
   5.150 -field() {
   5.151 -	grep "^$1" "$2" | sed 's/.*: \([0-9KMG\.]*\).*/\1/'
   5.152 -}
   5.153 -
   5.154 -todomsg() {
   5.155 -	echo -e "\\033[70G[ \\033[1;31mTODO\\033[0;39m ]"
   5.156 -}
   5.157 -
   5.158 -# Download a file from this mirror
   5.159 -download_from() {
   5.160 -	local i
   5.161 -	local mirrors
   5.162 -	mirrors="$1"
   5.163 -	shift
   5.164 -	for i in $mirrors; do
   5.165 -		case "$i" in
   5.166 -		http://*|ftp://*) busybox wget -c $i$@ && break;;
   5.167 -		*) cp $i/$1 . && break;;
   5.168 -		esac
   5.169 -	done
   5.170 -}
   5.171 -
   5.172 -# Download a file trying all mirrors
   5.173 -download() {
   5.174 -	local i
   5.175 -	for i in $(cat $MIRROR $LOCALSTATE/undigest/*/mirror 2> /dev/null); do
   5.176 -		download_from "$i" "$@" && break
   5.177 -	done
   5.178 -}
   5.179 -
   5.180 -# Execute hooks provided by some packages
   5.181 -genisohooks() {
   5.182 -	local here=`pwd`
   5.183 -	for i in $(ls $ROOTFS/etc/tazlito/*.$1 2> /dev/null); do
   5.184 -		cd $ROOTFS
   5.185 -		. $i $ROOTCD
   5.186 -	done
   5.187 -	cd $here
   5.188 -}
   5.189  
   5.190  cleanup() {
   5.191 -	if [ -d $TMP_MNT ]; then
   5.192 +	if [ -d "$TMP_MNT" ]; then
   5.193  		umount $TMP_MNT
   5.194  		rmdir $TMP_MNT
   5.195  		rm -f /boot
   5.196  	fi
   5.197 +	[ -d "$tmp_dir" ] && rm -r "$tmp_dir"
   5.198 +	[ -d "$flv_dir" ] && rm -r "$flv_dir"
   5.199  }
   5.200  
   5.201 +
   5.202 +# Report error and finish work
   5.203 +
   5.204 +die() {
   5.205 +	emsg "<n>$(longline "$@")<n> " >&2
   5.206 +	cleanup
   5.207 +	exit 1
   5.208 +}
   5.209 +
   5.210 +
   5.211 +
   5.212 +# Try to include config file, continue if command is gen-config or exit.
   5.213 +# The main config used by default is in /etc/tazlito.
   5.214 +# Specific distro config file can be put in a distro tree.
   5.215 +for i in /etc/tazlito "$TOP_DIR"; do
   5.216 +	[ -f "$i/tazlito.conf" ] && CONFIG_FILE="$i/tazlito.conf"
   5.217 +done
   5.218 +
   5.219 +[ -z "$CONFIG_FILE" -a "$COMMAND" != 'gen-config' ] && \
   5.220 +	die 'Unable to find any configuration file.' \
   5.221 +		'Please read the docs or run `tazlito gen-config` to get an empty config file.'
   5.222 +
   5.223 +. $CONFIG_FILE
   5.224 +
   5.225 +# While Tazpkg is not used the default mirror URL file does not exist
   5.226 +# and user can't recharge the list of flavors.
   5.227 +[ $(id -u) -eq 0  -a  ! -f "$MIRROR" ] && echo "$DEFAULT_MIRROR" > $MIRROR
   5.228 +
   5.229 +# Set the rootfs and rootcd path with $DISTRO
   5.230 +# configuration variable.
   5.231 +ROOTFS="$DISTRO/rootfs"
   5.232 +ROOTCD="$DISTRO/rootcd"
   5.233 +
   5.234 +
   5.235 +
   5.236 +
   5.237 +#####################
   5.238 +# Tazlito functions #
   5.239 +#####################
   5.240 +
   5.241 +
   5.242 +# Print the usage.
   5.243 +
   5.244 +usage () {
   5.245 +	[ $(basename $0) == 'tazlito' ] && cat <<EOT
   5.246 +
   5.247 +SliTaz Live Tool - Version: $(colorize 34 "$VERSION")
   5.248 +
   5.249 +$(boldify "Usage:") tazlito [command] [list|iso|flavor|compression] [dir|iso]
   5.250 +
   5.251 +$(boldify "Commands:")
   5.252 +EOT
   5.253 +optlist "\
   5.254 +usage			Print this short usage.
   5.255 +stats			View Tazlito and distro configuration statistics.
   5.256 +list-addfiles	Simple list of additional files in the rootfs.
   5.257 +gen-config		Generate a new configuration file for a distro.
   5.258 +configure		Configure the main config file or a specific tazlito.conf.
   5.259 +gen-iso			Generate a new ISO from a distro tree.
   5.260 +gen-initiso		Generate a new initramfs and ISO from the distro tree.
   5.261 +list-flavors	List all flavors available on the mirror.
   5.262 +gen-flavor		Generate a new Live CD description.
   5.263 +gen-liveflavor	Generate a Live CD description from current system.
   5.264 +show-flavor		Show Live CD description.
   5.265 +get-flavor		Get a flavor's list of packages (--noup to skip update).
   5.266 +upgrade-flavor	Update package list to the latest available versions.
   5.267 +extract-flavor	Extract a *.flavor file into $FLAVORS_REPOSITORY.
   5.268 +pack-flavor		Pack (and update) a flavor from $FLAVORS_REPOSITORY.
   5.269 +iso2flavor		Create a flavor file from a SliTaz ISO image.
   5.270 +extract-distro	Extract an ISO to a directory and rebuild Live CD tree.
   5.271 +gen-distro		Generate a Live distro and ISO from a list of packages.
   5.272 +clean-distro	Remove all files generated by gen-distro.
   5.273 +check-distro	Help to check if distro is ready to release.
   5.274 +writeiso		Use running system to generate a bootable ISO (with /home).
   5.275 +merge			Merge multiple rootfs into one ISO.
   5.276 +deduplicate		Deduplicate files in a tree.
   5.277 +repack			Recompress rootfs into ISO with maximum ratio.
   5.278 +build-loram		Generate a Live CD for low-RAM systems.
   5.279 +emu-iso			Emulate an ISO image with QEMU.
   5.280 +burn-iso		Burn ISO image to a CD-ROM using Wodim.
   5.281 +"
   5.282 +}
   5.283 +
   5.284 +
   5.285 +yesorno() {
   5.286 +	local answer
   5.287 +	echo -n "$1 (y=yes, n=no) [$2] " >&2
   5.288 +	case "$DEFAULT_ANSWER" in
   5.289 +		Y|y) answer="y";;
   5.290 +		N|n) answer="n";;
   5.291 +		*)
   5.292 +			read answer
   5.293 +			[ -z "$answer" ] && answer="$2"
   5.294 +			[ "$answer" != 'y' -a "$answer" != 'n' ] && answer="$2"
   5.295 +			;;
   5.296 +	esac
   5.297 +	echo "$answer"
   5.298 +}
   5.299 +
   5.300 +
   5.301 +field() {
   5.302 +	grep "^$1" "$2" | \
   5.303 +	case "$1" in
   5.304 +		Desc*) sed 's|^.*: *||';;
   5.305 +		*)     sed 's/.*: \([0-9KMG\.]*\).*/\1/';;
   5.306 +	esac
   5.307 +}
   5.308 +
   5.309 +
   5.310 +todomsg() {
   5.311 +	echo -e "\\033[70G[ \\033[1;31mTODO\\033[0;39m ]"
   5.312 +}
   5.313 +
   5.314 +
   5.315 +# Download a file from this mirror
   5.316 +
   5.317 +download_from() {
   5.318 +	local i mirrors="$1"
   5.319 +	shift
   5.320 +	for i in $mirrors; do
   5.321 +		case "$i" in
   5.322 +			http://*|ftp://*|https://*)
   5.323 +				wget -c $i$@ && break;;
   5.324 +			*)
   5.325 +				cp $i/$1 . && break;;
   5.326 +		esac
   5.327 +	done
   5.328 +}
   5.329 +
   5.330 +
   5.331 +# Download a file trying all mirrors
   5.332 +
   5.333 +download() {
   5.334 +	local i
   5.335 +	for i in $(cat $MIRROR $LOCALSTATE/undigest/*/mirror 2>/dev/null); do
   5.336 +		download_from "$i" "$@" && break
   5.337 +	done
   5.338 +}
   5.339 +
   5.340 +
   5.341 +# Execute hooks provided by some packages
   5.342 +
   5.343 +genisohooks() {
   5.344 +	local here="$(pwd)"
   5.345 +	for i in $(ls $ROOTFS/etc/tazlito/*.$1 2>/dev/null); do
   5.346 +		cd $ROOTFS
   5.347 +		. $i $ROOTCD
   5.348 +	done
   5.349 +	cd "$here"
   5.350 +}
   5.351 +
   5.352 +
   5.353  # Echo the package name if the tazpkg is already installed
   5.354 +
   5.355  installed_package_name() {
   5.356 -	local tazpkg
   5.357 -	local package
   5.358 -	local VERSION
   5.359 -	local EXTRAVERSION
   5.360 -	tazpkg=$1
   5.361 +	local tazpkg="$1" package VERSION EXTRAVERSION
   5.362 +
   5.363  	# Try to find package name and version to be able
   5.364  	# to repack it from installation
   5.365  	# A dash (-) can exist in name *and* in version
   5.366  	package=${tazpkg%-*}
   5.367  	i=$package
   5.368  	while true; do
   5.369 -		VERSION=""
   5.370 -		eval $(grep -s ^VERSION= $INSTALLED/$i/receipt)
   5.371 -		EXTRAVERSION=""
   5.372 +		unset VERSION EXTRAVERSION
   5.373 +		eval $(grep -s ^VERSION=      $INSTALLED/$i/receipt)
   5.374  		eval $(grep -s ^EXTRAVERSION= $INSTALLED/$i/receipt)
   5.375 -		if [ "$i-$VERSION$EXTRAVERSION" = "$tazpkg" ]; then
   5.376 +		if [ "$i-$VERSION$EXTRAVERSION" == "$tazpkg" ]; then
   5.377  			echo $i
   5.378  			break
   5.379  		fi
   5.380  		case "$i" in
   5.381 -		*-*);;
   5.382 -		*) break;;
   5.383 +			*-*);;
   5.384 +			*) break;;
   5.385  		esac
   5.386  		i=${i%-*}
   5.387  	done
   5.388  }
   5.389  
   5.390 +
   5.391  # Check for the rootfs tree.
   5.392 +
   5.393  check_rootfs() {
   5.394 -	if [ ! -d "$ROOTFS/etc" ] ; then
   5.395 -		echo -e "\nUnable to find a distro rootfs...\n"
   5.396 -		exit 0
   5.397 -	fi
   5.398 +	[ -d "$ROOTFS/etc" ] || die 'Unable to find a distro rootfs...'
   5.399  }
   5.400  
   5.401 +
   5.402  # Check for the boot dir into the root CD tree.
   5.403 -verify_rootcd()
   5.404 -{
   5.405 -	if [ ! -d "$ROOTCD/boot" ] ; then
   5.406 -		echo -e "\nUnable to find the rootcd boot directory...\n"
   5.407 -		exit 0
   5.408 -	fi
   5.409 +
   5.410 +verify_rootcd() {
   5.411 +	[ -d "$ROOTCD/boot" ] || die 'Unable to find the rootcd boot directory...'
   5.412  }
   5.413  
   5.414 +
   5.415  # isolinux.conf doesn't know the kernel version.
   5.416  # We name the kernel image 'bzImage'.
   5.417  # isolinux/syslinux first tries the '64' suffix with a 64bits cpu.
   5.418 -make_bzImage_hardlink()
   5.419 -{
   5.420 -	if [ -s ${1:-.}/vmlinuz*slitaz ]; then
   5.421 -		rm -f ${1:-.}/bzImage 2> /dev/null
   5.422 -		ln ${1:-.}/vmlinuz*slitaz ${1:-.}/bzImage
   5.423 +
   5.424 +make_bzImage_hardlink() {
   5.425 +	if [   -s ${1:-.}/vmlinuz*slitaz ]; then
   5.426 +		rm -f ${1:-.}/bzImage 2>/dev/null
   5.427 +		ln    ${1:-.}/vmlinuz*slitaz ${1:-.}/bzImage
   5.428  	fi
   5.429 -	if [ -s ${1:-.}/vmlinuz*slitaz64 ]; then
   5.430 +	if [   -s ${1:-.}/vmlinuz*slitaz64 ]; then
   5.431  		rm -f ${1:-.}/bzImage64 2> /dev/null
   5.432 -		ln ${1:-.}/vmlinuz*slitaz64 ${1:-.}/bzImage64
   5.433 +		ln    ${1:-.}/vmlinuz*slitaz64 ${1:-.}/bzImage64
   5.434  	fi
   5.435  }
   5.436  
   5.437 -create_iso()
   5.438 -{
   5.439 +
   5.440 +create_iso() {
   5.441  	cd $2
   5.442  	deduplicate
   5.443 -	echo -n "Computing md5..."
   5.444 +
   5.445 +	action 'Computing md5...'
   5.446  	find * -type f ! -name md5sum ! -name 'vmlinuz*' -exec md5sum {} \; > md5sum
   5.447 -	sed -i  -e '/  boot\/isolinux\/isolinux.bin$/d' \
   5.448 -		-e '/  boot\/isolinux\/boot.cat$/d' md5sum
   5.449 +	sed -i -e '/  boot\/isolinux\/isolinux.bin$/d' \
   5.450 +		   -e '/  boot\/isolinux\/boot.cat$/d' md5sum
   5.451  	status
   5.452 -	cd - > /dev/null
   5.453 -	newline
   5.454 -	boldify "Generating ISO image"
   5.455 -	separator
   5.456 +
   5.457 +	cd - >/dev/null
   5.458 +	title 'Generating ISO image'
   5.459 +
   5.460  	echo "Generating $1"
   5.461  	make_bzImage_hardlink $2/boot
   5.462 -	genisoimage -R -o $1 -b boot/isolinux/isolinux.bin \
   5.463 - 		-c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
   5.464 -		-V "$VOLUM_NAME" -p "$PREPARED" -input-charset iso8859-1 \
   5.465 -		-copyright README -P "www.slitaz.org" -boot-info-table $2
   5.466 -	if [ -x /usr/bin/isohybrid ]; then
   5.467 -		echo -n "Creating hybrid ISO..."
   5.468 -		/usr/bin/isohybrid $1 -entry 2 2> /dev/null
   5.469 +	genisoimage -R   -o $1   -b boot/isolinux/isolinux.bin \
   5.470 +		-c boot/isolinux/boot.cat   -no-emul-boot   -boot-load-size 4 \
   5.471 +		-V "$VOLUM_NAME"   -p "$PREPARED"   -input-charset utf-8 \
   5.472 +		-copyright README   -P "www.slitaz.org"   -boot-info-table $2
   5.473 +
   5.474 +	if [ -x '/usr/bin/isohybrid' ]; then
   5.475 +		action 'Creating hybrid ISO...'
   5.476 +		/usr/bin/isohybrid $1 -entry 2 2>/dev/null
   5.477  		status
   5.478  	fi
   5.479 -	if [ -s /etc/tazlito/info ]; then
   5.480 +
   5.481 +	if [ -s '/etc/tazlito/info' ]; then
   5.482  		if [ $(stat -c %s /etc/tazlito/info) -lt $(( 31*1024 )) ]; then
   5.483 -			echo -n "Storing ISO info..."
   5.484 -			dd if=/etc/tazlito/info bs=1k seek=1 of=$1 \
   5.485 -				conv=notrunc 2> /dev/null
   5.486 +			action 'Storing ISO info...'
   5.487 +			dd if=/etc/tazlito/info bs=1k seek=1 of=$1 conv=notrunc 2>/dev/null
   5.488  			status
   5.489  		fi
   5.490  	fi
   5.491 -	if [ -x /usr/bin/iso2exe ]; then
   5.492 -		echo "Creating EXE header..."
   5.493 -		/usr/bin/iso2exe $1 2> /dev/null
   5.494 +
   5.495 +	if [ -x '/usr/bin/iso2exe' ]; then
   5.496 +		echo 'Creating EXE header...'
   5.497 +		/usr/bin/iso2exe $1 2>/dev/null
   5.498  	fi
   5.499  }
   5.500  
   5.501 +
   5.502  # Generate a new ISO image using isolinux.
   5.503 -gen_livecd_isolinux()
   5.504 -{
   5.505 +
   5.506 +gen_livecd_isolinux() {
   5.507  	# Some packages may want to alter iso
   5.508  	genisohooks iso
   5.509 -	if [ ! -f "$ROOTCD/boot/isolinux/isolinux.bin" ]; then
   5.510 -		echo -e "\nUnable to find isolinux binary.\n"
   5.511 -		cleanup
   5.512 -		exit 0
   5.513 -	fi
   5.514 +	[ ! -f "$ROOTCD/boot/isolinux/isolinux.bin" ] && die 'Unable to find isolinux binary.'
   5.515 +
   5.516  	# Set date for boot msg.
   5.517 -	if grep -q 'XXXXXXXX' $ROOTCD/boot/isolinux/isolinux.*g; then
   5.518 -		DATE=`date +%Y%m%d`
   5.519 -		echo -n "Setting build date to: $DATE..."
   5.520 -		sed -i "s/XXXXXXXX/$DATE/" $ROOTCD/boot/isolinux/isolinux.*g
   5.521 +	if grep -q 'XXXXXXXX' "$ROOTCD/boot/isolinux/isolinux.cfg"; then
   5.522 +		DATE=$(date +%Y%m%d)
   5.523 +		action 'Setting build date to: %s...' "$DATE"
   5.524 +		sed -i "s/XXXXXXXX/$DATE/" "$ROOTCD/boot/isolinux/isolinux.cfg"
   5.525  		status
   5.526  	fi
   5.527 +
   5.528  	cd $DISTRO
   5.529  	create_iso $ISO_NAME.iso $ROOTCD
   5.530 -	echo -n "Creating the ISO md5sum..."
   5.531 +
   5.532 +	action 'Creating the ISO md5sum...'
   5.533  	md5sum $ISO_NAME.iso > $ISO_NAME.md5
   5.534  	status
   5.535 +
   5.536  	separator
   5.537  	# Some packages may want to alter final iso
   5.538  	genisohooks final
   5.539  }
   5.540  
   5.541 -lzma_history_bits()
   5.542 -{
   5.543 +
   5.544 +lzma_history_bits() {
   5.545  	#
   5.546  	# This generates an ISO which boots with Qemu but gives
   5.547  	# rootfs errors in frugal or liveUSB mode.
   5.548  	#
   5.549 -	#local n
   5.550 -	#local sz
   5.551 -	#n=20	# 1Mb
   5.552 -	#sz=$(du -sk $1 | cut -f1)
   5.553 -	#while [ $sz -gt 1024 -a $n -lt 28 ]; do
   5.554 -		#n=$(( $n + 1 ))
   5.555 -		#sz=$(( $sz / 2 ))
   5.556 -	#done
   5.557 -	#echo $n
   5.558 +#	local n
   5.559 +#	local sz
   5.560 +#	n=20	# 1Mb
   5.561 +#	sz=$(du -sk $1 | cut -f1)
   5.562 +#	while [ $sz -gt 1024 -a $n -lt 28 ]; do
   5.563 +#		n=$(( $n + 1 ))
   5.564 +#		sz=$(( $sz / 2 ))
   5.565 +#	done
   5.566 +#	echo $n
   5.567  	echo 24
   5.568  }
   5.569  
   5.570 -lzma_switches()
   5.571 -{
   5.572 -	local proc=$(grep -s '^processor' < /proc/cpuinfo | wc -l)
   5.573 -	echo "-d$(lzma_history_bits $1) -mt${proc:-1}"
   5.574 +
   5.575 +lzma_switches() {
   5.576 +	local proc_num=$(grep -sc '^processor' /proc/cpuinfo)
   5.577 +	echo "-d$(lzma_history_bits $1) -mt${proc_num:-1}"
   5.578  }
   5.579  
   5.580 -lzma_set_size()
   5.581 -{
   5.582 +
   5.583 +lzma_set_size() {
   5.584  	# Update size field for lzma'd file packed using -si switch
   5.585 -	local n
   5.586 -	local i
   5.587 -	return # Need to fix kernel code ?
   5.588 +	return # Need to fix kernel code?
   5.589 +
   5.590 +	local n i
   5.591  	n=$(unlzma < $1 | wc -c)
   5.592  	for i in $(seq 1 8); do
   5.593  		printf '\\\\x%02X' $(($n & 255))
   5.594  		n=$(($n >> 8))
   5.595 -	done | xargs echo -en | dd of=$1 conv=notrunc bs=1 seek=5 2> /dev/null
   5.596 +	done | xargs echo -en | dd of=$1 conv=notrunc bs=1 seek=5 2>/dev/null
   5.597  }
   5.598  
   5.599 -align_to_32bits()
   5.600 -{
   5.601 -	local size
   5.602 -	size=$(stat -c %s ${1:-/dev/null})
   5.603 +
   5.604 +align_to_32bits() {
   5.605 +	local size=$(stat -c %s ${1:-/dev/null})
   5.606  	[ $((${size:-0} & 3)) -ne 0 ] &&
   5.607 -	dd if=/dev/zero bs=1 count=$((4 - ($size & 3))) >> $1 2> /dev/null
   5.608 +		dd if=/dev/zero bs=1 count=$((4 - ($size & 3))) >> $1 2>/dev/null
   5.609  }
   5.610  
   5.611 +
   5.612  # Pack rootfs
   5.613 -pack_rootfs()
   5.614 -{
   5.615 -	( cd $1 ; find . -print | cpio -o -H newc ) | \
   5.616 -	if [ "$COMPRESSION" = "none" ]; then
   5.617 -		echo "Generating uncompressed initramfs... "
   5.618 -		cat > $2
   5.619 -	elif [ -x /usr/bin/lzma -a "$COMPRESSION" != "gzip" ]; then
   5.620 -		echo -n "Generating lzma'ed initramfs... "
   5.621 -		lzma e -si -so $(lzma_switches $1) > $2
   5.622 -		lzma_set_size $2
   5.623 -	else
   5.624 -		echo "Generating gziped initramfs... "
   5.625 -		gzip -9 > $2
   5.626 -	fi
   5.627 +
   5.628 +pack_rootfs() {
   5.629 +	( cd $1; find . -print | cpio -o -H newc ) | \
   5.630 +	case "$COMPRESSION" in
   5.631 +		none)
   5.632 +			_ 'Creating %s without compression...' 'initramfs'
   5.633 +			cat > $2
   5.634 +			;;
   5.635 +		gzip)
   5.636 +			_ 'Creating %s with gzip compression...' 'initramfs'
   5.637 +			gzip -9 > $2
   5.638 +			;;
   5.639 +		*)
   5.640 +			_ 'Creating %s with lzma compression...' 'initramfs'
   5.641 +			lzma e -si -so $(lzma_switches $1) > $2
   5.642 +			lzma_set_size $2
   5.643 +			;;
   5.644 +	esac
   5.645  	align_to_32bits $2
   5.646  	echo 1 > /tmp/rootfs
   5.647  }
   5.648  
   5.649 +
   5.650  # Compression functions for writeiso.
   5.651 -write_initramfs()
   5.652 -{
   5.653 -	if [ "$COMPRESSION" = "lzma" ]; then
   5.654 -		echo -n "Creating rootfs.gz with lzma compression... "
   5.655 -		cpio -o -H newc | lzma e -si -so $(lzma_switches) > /rootfs.gz
   5.656 -		align='y'
   5.657 -		lzma_set_size /rootfs.gz
   5.658 -	elif [ "$COMPRESSION" = "gzip" ]; then
   5.659 -		echo "Creating rootfs.gz with gzip compression... "
   5.660 -		cpio -o -H newc | gzip -9 > /rootfs.gz
   5.661 -		[ -x /usr/bin/advdef ] && advdef -z4 /rootfs.gz
   5.662 -	else
   5.663 -		# align='y'
   5.664 -		echo "Creating rootfs.gz without compression... "
   5.665 -		cpio -o -H newc > /rootfs.gz
   5.666 -	fi < /tmp/list
   5.667 -	[ $align == 'y' -a -z "$noalign" ] && align_to_32bits /rootfs.gz
   5.668 +
   5.669 +write_initramfs() {
   5.670 +	case "$COMPRESSION" in
   5.671 +		lzma)
   5.672 +			_n 'Creating %s with lzma compression...' "$INITRAMFS"
   5.673 +			cpio -o -H newc | lzma e -si -so $(lzma_switches) > "/$INITRAMFS"
   5.674 +			align='y'
   5.675 +			lzma_set_size "/$INITRAMFS"
   5.676 +			;;
   5.677 +		gzip)
   5.678 +			_ 'Creating %s with gzip compression...' "$INITRAMFS"
   5.679 +			cpio -o -H newc | gzip -9 > "/$INITRAMFS"
   5.680 +			[ -x /usr/bin/advdef ] && advdef -z4 "/$INITRAMFS"
   5.681 +			;;
   5.682 +		*)
   5.683 +			# align='y'
   5.684 +			_ 'Creating %s without compression...' "$INITRAMFS"
   5.685 +			cpio -o -H newc > "/$INITRAMFS"
   5.686 +			;;
   5.687 +	esac < /tmp/list
   5.688 +	[ "$align" == 'y' -a -z "$noalign" ] && align_to_32bits "/$INITRAMFS"
   5.689  	echo 1 > /tmp/rootfs
   5.690  }
   5.691  
   5.692 +
   5.693  # Deduplicate files (MUST be on the same filesystem).
   5.694 -deduplicate()
   5.695 -{
   5.696 -	find "${@:-.}" -type f -size +0c -xdev \
   5.697 -		-exec stat -c '%s-%a-%u-%g %i %h %n' {} \; | sort | \
   5.698 -	( save=0; hardlinks=0; old_attr=""; old_inode=""; old_link=""; old_file=""
   5.699 -	   while read attr inode link file; do
   5.700 -		[ -L "$file" ] && continue
   5.701 -		if [ "$attr" = "$old_attr" -a "$inode" != "$old_inode" ]; then
   5.702 -			if cmp "$file" "$old_file" >/dev/null 2>&1 ; then
   5.703 -				rm -f "$file"
   5.704 -				if ln "$old_file" "$file" 2> /dev/null; then
   5.705 -					inode="$old_inode"
   5.706 -					[ "$link" = "1" ] && 
   5.707 -					hardlinks=$(($hardlinks+1)) &&
   5.708 -					save="$(($save+(${attr%%-*}+512)/1024))"
   5.709 +
   5.710 +deduplicate() {
   5.711 +	find "${@:-.}" -type f -size +0c -xdev -exec stat -c '%s-%a-%u-%g %i %h %n' {} \; | sort | \
   5.712 +		(
   5.713 +			save=0; hardlinks=0; old_attr=""; old_inode=""; old_link=""; old_file=""
   5.714 +			while read attr inode link file; do
   5.715 +				[ -L "$file" ] && continue
   5.716 +				if [ "$attr" == "$old_attr" -a "$inode" != "$old_inode" ]; then
   5.717 +					if cmp "$file" "$old_file" >/dev/null 2>&1 ; then
   5.718 +						rm -f "$file"
   5.719 +						if ln "$old_file" "$file" 2>/dev/null; then
   5.720 +							inode="$old_inode"
   5.721 +							[ "$link" -eq 1 ] && hardlinks=$(($hardlinks+1)) &&
   5.722 +								save="$(($save+(${attr%%-*}+512)/1024))"
   5.723 +						else
   5.724 +							cp -a "$old_file" "$file"
   5.725 +						fi
   5.726 +					fi
   5.727 +				fi
   5.728 +				old_attr="$attr" ; old_inode="$inode" ; old_file="$file"
   5.729 +			done
   5.730 +			echo "$save Kbytes saved in $hardlinks duplicate files."
   5.731 +		)
   5.732 +
   5.733 +	find "$@" -type l -xdev -exec stat -c '%s-%u-%g-TARGET- %i %h %n' {} \; | sort | \
   5.734 +		(
   5.735 +			old_attr=""; hardlinks=0;
   5.736 +			while read attr inode link file; do
   5.737 +				attr="${attr/-TARGET-/-$(readlink $file)}"
   5.738 +				if [ "$attr" == "$old_attr" ]; then
   5.739 +					if [ "$inode" != "$old_inode" ]; then
   5.740 +						rm -f "$file"
   5.741 +						if ln "$old_file" "$file" 2>/dev/null; then
   5.742 +							[ "$link" -eq 1 ] && hardlinks=$(($hardlinks+1))
   5.743 +						else
   5.744 +							cp -a "$old_file" "$file"
   5.745 +						fi
   5.746 +					fi
   5.747  				else
   5.748 -					cp -a "$old_file" "$file"
   5.749 +					old_file="$file"
   5.750 +					old_attr="$attr"
   5.751 +					old_inode="$inode"
   5.752  				fi
   5.753 -			fi
   5.754 -		fi
   5.755 -		old_attr="$attr" ; old_inode="$inode" ; old_file="$file"
   5.756 -	   done
   5.757 -	   echo "$save Kbytes saved in $hardlinks duplicate files."
   5.758 -	)
   5.759 -	find "$@" -type l -xdev \
   5.760 -		-exec stat -c '%s-%u-%g-TARGET- %i %h %n' {} \; | sort | \
   5.761 -	( old_attr=""; hardlinks=0; while read attr inode link file; do
   5.762 -		attr="${attr/-TARGET-/-$(readlink $file)}"
   5.763 -		if [ "$attr" = "$old_attr" ]; then
   5.764 -			if [ "$inode" != "$old_inode" ]; then
   5.765 -				rm -f "$file"
   5.766 -				if ln "$old_file" "$file" 2> /dev/null; then
   5.767 -					[ "$link" = "1" ] && 
   5.768 -					hardlinks=$(($hardlinks+1))
   5.769 -				else
   5.770 -					cp -a "$old_file" "$file"
   5.771 -				fi
   5.772 -			fi
   5.773 -		else
   5.774 -			old_file="$file"
   5.775 -			old_attr="$attr"
   5.776 -			old_inode="$inode"
   5.777 -		fi
   5.778 -	   done
   5.779 -	   echo "$hardlinks duplicate symlinks."
   5.780 -	)
   5.781 +			done
   5.782 +			echo "$hardlinks duplicate symlinks."
   5.783 +		)
   5.784  }
   5.785  
   5.786 +
   5.787  # Generate a new initramfs from the root filesystem.
   5.788 -gen_initramfs()
   5.789 -{
   5.790 +
   5.791 +gen_initramfs() {
   5.792  	# Just in case CTRL+c
   5.793  	rm -f $DISTRO/gen
   5.794  
   5.795 @@ -444,14 +485,13 @@
   5.796  	deduplicate
   5.797  
   5.798  	# Use lzma if installed. Display rootfs size in realtime.
   5.799 -	rm -f /tmp/rootfs 2> /dev/null
   5.800 +	rm -f /tmp/rootfs 2>/dev/null
   5.801  	pack_rootfs . $DISTRO/$(basename $1).gz &
   5.802  	sleep 2
   5.803  	echo -en "\nFilesystem size:"
   5.804 -	while [ ! -f /tmp/rootfs ]
   5.805 -	do
   5.806 +	while [ ! -f /tmp/rootfs ]; do
   5.807  		sleep 1
   5.808 -		echo -en "\\033[18G`du -sh $DISTRO/$(basename $1).gz | awk '{print $1}'`    "
   5.809 +		echo -en "\\033[18G$(du -sh $DISTRO/$(basename $1).gz | awk '{print $1}')    "
   5.810  	done
   5.811  	echo -e "\n"
   5.812  	rm -f /tmp/rootfs
   5.813 @@ -459,37 +499,37 @@
   5.814  	mv $(basename $1).gz $ROOTCD/boot
   5.815  }
   5.816  
   5.817 +
   5.818  distro_sizes() {
   5.819 -	if [ "$time" ]; then
   5.820 -		time=$(($(date +%s) - $time))
   5.821 +	if [ -n "$start_time" ]; then
   5.822 +		time=$(($(date +%s) - $start_time))
   5.823  		sec=$time
   5.824  		div=$(( ($time + 30) / 60))
   5.825 -		[ "$div" != 0 ] && min="~ ${div}m"
   5.826 +		[ "$div" -ne 0 ] && min="~ ${div}m"
   5.827  		echo "Build time      : ${sec}s $min"
   5.828  	fi
   5.829  	cat <<EOT
   5.830  Build date      : $(date +%Y%m%d)
   5.831 -Packages        : $(ls -1 $ROOTFS*$INSTALLED/*/receipt | wc -l)
   5.832 -Rootfs size     : $(du -csh $ROOTFS*/ | awk '{ s=$1 } END { print s }')
   5.833 -Initramfs size  : $(du -csh $ROOTCD/boot/rootfs*.gz | awk '{ s=$1 } END { print s }')
   5.834 -ISO image size  : $(du -sh $ISO_NAME.iso | awk '{ print $1 }')
   5.835 +Packages        : $(ls -1   $ROOTFS*$INSTALLED/*/receipt | wc -l)
   5.836 +Rootfs size     : $(du -csh $ROOTFS*/                    | awk 'END { print $1 }')
   5.837 +Initramfs size  : $(du -csh $ROOTCD/boot/rootfs*.gz      | awk 'END { print $1 }')
   5.838 +ISO image size  : $(du  -sh $ISO_NAME.iso                | awk '{ print $1 }')
   5.839  EOT
   5.840 -	separator
   5.841 -	echo "Image is ready: $ISO_NAME.iso"
   5.842 -	newline
   5.843 +	footer "Image is ready: $ISO_NAME.iso"
   5.844  }
   5.845  
   5.846 +
   5.847  # Print ISO and rootfs size.
   5.848 +
   5.849  distro_stats() {
   5.850 -	newline
   5.851 -	echo "$(boldify 'Distro statistics:') $DISTRO"
   5.852 -	separator
   5.853 +	title 'Distro statistics: %s' "$DISTRO"
   5.854  	distro_sizes
   5.855  }
   5.856  
   5.857 +
   5.858  # Create an empty configuration file.
   5.859 -empty_config_file()
   5.860 -{
   5.861 +
   5.862 +empty_config_file() {
   5.863  	cat >> tazlito.conf <<"EOF"
   5.864  # tazlito.conf: Tazlito (SliTaz Live Tool) configuration file.
   5.865  #
   5.866 @@ -506,8 +546,7 @@
   5.867  # Path to the packages repository and the packages.list.
   5.868  PACKAGES_REPOSITORY=""
   5.869  
   5.870 -# Path to the distro tree to gen-distro from a
   5.871 -# list of packages.
   5.872 +# Path to the distro tree to gen-distro from a list of packages.
   5.873  DISTRO=""
   5.874  
   5.875  # Path to the directory containing additional files
   5.876 @@ -522,148 +561,166 @@
   5.877  EOF
   5.878  }
   5.879  
   5.880 -# extract rootfs.gz somewhere
   5.881 -extract_rootfs()
   5.882 -{
   5.883 -	(zcat $1 || unlzma < $1 || cat $1) 2>/dev/null | \
   5.884 -		(cd $2; cpio -idm > /dev/null)
   5.885 +
   5.886 +# Extract rootfs.gz somewhere
   5.887 +
   5.888 +extract_rootfs() {
   5.889 +	# Detect compression format: *.lzma.cpio, *.gzip.cpio, or *.cpio
   5.890 +	# First part (lzcat or zcat) may not fail, but cpio will fail on uncorrect format
   5.891 +	(cd "$2"; lzcat "$1" | cpio -idm --quiet 2>/dev/null) && return
   5.892 +	(cd "$2";  zcat "$1" | cpio -idm --quiet 2>/dev/null) && return
   5.893 +	(cd "$2";   cat "$1" | cpio -idm --quiet 2>/dev/null)
   5.894  }
   5.895  
   5.896 +
   5.897 +# Extract flavor file to temp directory
   5.898 +
   5.899 +extract_flavor() {
   5.900 +	# Input: $1 - flavor name to extract;
   5.901 +	#        $2 = absent/empty: just extract 'outer layer'
   5.902 +	#        $2 = 'full': also extract 'inner' rootcd and rootfs archives, make files rename
   5.903 +	#        $2 = 'info': as 'full' and also make 'info' file to put into ISO
   5.904 +	# Output: temp dir path where flavor was extracted
   5.905 +	local f="$1.flavor" from to infos="$1.desc"
   5.906 +	[ -f "$f" ] || die "File '$f' not found"
   5.907 +	local dir="$(mktemp -d)"
   5.908 +	zcat "$f" | (cd $dir; cpio -i --quiet >/dev/null)
   5.909 +
   5.910 +	if [ -n "$2" ]; then
   5.911 +		cd $dir
   5.912 +
   5.913 +		[ -s "$1.receipt" ] && infos="$infos\n$1.receipt"
   5.914 +
   5.915 +		for i in rootcd rootfs; do
   5.916 +			[ -f "$1.$i" ] || continue
   5.917 +			mkdir "$i"
   5.918 +			zcat "$1.$i" | (cd "$i"; cpio -idm --quiet 2>/dev/null)
   5.919 +			zcat "$1.$i" | cpio -tv 2>/dev/null > "$1.list$i"; infos="$infos\n$1.list$i"
   5.920 +			rm "$1.$i"
   5.921 +		done
   5.922 +		# Info to be stored inside ISO
   5.923 +		[ "$2" == info ] && echo -e $infos | cpio -o -H newc | gzip -9 > info
   5.924 +		rm $1.list*
   5.925 +
   5.926 +		# Renames
   5.927 +		while read from to; do
   5.928 +			[ -f "$from" ] || continue
   5.929 +			mv "$from" "$to"
   5.930 +		done <<EOT
   5.931 +$1.nonfree    non-free.list
   5.932 +$1.pkglist    packages.list
   5.933 +$1-distro.sh  distro.sh
   5.934 +$1.receipt    receipt
   5.935 +$1.mirrors    mirrors
   5.936 +$1.desc       description
   5.937 +EOT
   5.938 +	fi
   5.939 +
   5.940 +	echo $dir
   5.941 +}
   5.942 +
   5.943 +
   5.944 +# Pack flavor file from temp directory
   5.945 +
   5.946 +pack_flavor() {
   5.947 +	(cd "$1"; ls | grep -v err | cpio -o -H newc) | gzip -9 > "$2.flavor"
   5.948 +}
   5.949 +
   5.950 +
   5.951  # Remove duplicate files
   5.952 -mergefs()
   5.953 -{
   5.954 +
   5.955 +mergefs() {
   5.956  	# Note, many packages have files with spaces in the name
   5.957  	IFS=$'\n'
   5.958  
   5.959 -	echo -n "Merge $(basename "$1") ($(du -hs "$1" | awk '{ print $1}')) into "
   5.960 -	echo -n       "$(basename "$2") ($(du -hs "$2" | awk '{ print $1}'))"
   5.961 +	local size1=$(du -hs "$1" | awk '{ print $1 }')
   5.962 +	local size2=$(du -hs "$2" | awk '{ print $1 }')
   5.963 +	action 'Merge %s (%s) into %s (%s)' "$(basename "$1")" "$size1" "$(basename "$2")" "$size2"
   5.964 +
   5.965  	# merge symlinks files and devices
   5.966 -	( cd "$1"; find ) | while read file; do
   5.967 -		if [ -L "$1/$file" ]; then
   5.968 -			[ -L "$2/$file" ] &&
   5.969 -			[ "$(readlink "$1/$file")" == "$(readlink "$2/$file")" ] &&
   5.970 -			rm -f "$2/$file"
   5.971 +	( cd "$1"; find ) | \
   5.972 +	while read file; do
   5.973 +		if  [ -L "$1/$file" ]; then
   5.974 +			[ -L "$2/$file"  -a  "$(readlink "$1/$file")" == "$(readlink "$2/$file")" ] &&
   5.975 +				rm -f "$2/$file"
   5.976 +
   5.977  		elif [ -f "$1/$file" ]; then
   5.978 -			[ -f "$2/$file" ] &&
   5.979 -			cmp "$1/$file" "$2/$file" >/dev/null 2>&1 && rm -f "$2/$file"
   5.980 +			 [ -f "$2/$file" ] && cmp -s "$1/$file" "$2/$file" &&
   5.981 +				rm -f "$2/$file"
   5.982 +
   5.983  			[ -f "$2/$file" ] &&
   5.984  			[ "$(basename "$file")" == 'volatile.cpio.gz' ] &&
   5.985 -			[ "$(dirname $(dirname "$file"))" == \
   5.986 -			  ".$INSTALLED" ] && rm -f "$2/$file"
   5.987 +			[ "$(dirname $(dirname "$file"))" == ".$INSTALLED" ] &&
   5.988 +				rm -f "$2/$file"
   5.989 +
   5.990  		elif [ -b "$1/$file" ]; then
   5.991 -			[ -b "$2/$file" ] &&
   5.992 +			 [ -b "$2/$file" ] &&
   5.993  			[ "$(stat -c '%a:%u:%g:%t:%T' "$1/$file")" == \
   5.994  			  "$(stat -c '%a:%u:%g:%t:%T' "$2/$file")" ] &&
   5.995 -			rm -f "$2/$file"
   5.996 +				rm -f "$2/$file"
   5.997 +
   5.998  		elif [ -c "$1/$file" ]; then
   5.999 -			[ -c "$2/$file" ] &&
  5.1000 +			 [ -c "$2/$file" ] &&
  5.1001  			[ "$(stat -c '%a:%u:%g:%t:%T' "$1/$file")" == \
  5.1002  			  "$(stat -c '%a:%u:%g:%t:%T' "$2/$file")" ] &&
  5.1003 -			rm -f "$2/$file"
  5.1004 +				rm -f "$2/$file"
  5.1005  		fi
  5.1006  	done
  5.1007  
  5.1008 -	# cleanup directories
  5.1009 -	( cd "$1"; find . -type d ) | sed '1!G;h;$!d' | while read file; do
  5.1010 +	# cleanup directories; TODO: simplify
  5.1011 +	( cd "$1"; find . -type d ) | sed '1!G;h;$!d' | \
  5.1012 +	while read file; do
  5.1013  		[ -d "$2/$file" ] && rmdir "$2/$file" 2>/dev/null
  5.1014  	done
  5.1015 -	true
  5.1016 +
  5.1017 +	unset IFS
  5.1018  	status
  5.1019 -	unset IFS
  5.1020  }
  5.1021  
  5.1022 -cleanup_merge()
  5.1023 -{
  5.1024 +
  5.1025 +cleanup_merge() {
  5.1026  	rm -rf $TMP_DIR
  5.1027  	exit 1
  5.1028  }
  5.1029  
  5.1030 -human2cent()
  5.1031 -{
  5.1032 -case "$1" in
  5.1033 -*k) echo $1 | sed 's/\(.*\).\(.\)k/\1\2/';;
  5.1034 -*M) echo $(( $(echo $1 | sed 's/\(.*\).\(.\)M/\1\2/') * 1024));;
  5.1035 -*G) echo $(( $(echo $1 | sed 's/\(.*\).\(.\)G/\1\2/') * 1024 * 1024));;
  5.1036 -esac
  5.1037 -}
  5.1038 -
  5.1039 -cent2human()
  5.1040 -{
  5.1041 -if [ $1 -lt 10000 ]; then
  5.1042 -  echo "$(($1 / 10)).$(($1 % 10))k"
  5.1043 -elif [ $1 -lt 10000000 ]; then
  5.1044 -  echo "$(($1 / 10240)).$(( ($1/1024) % 10))M"
  5.1045 -else
  5.1046 -  echo "$(($1 / 10485760)).$(( ($1/1048576) % 10))G"
  5.1047 -fi
  5.1048 -}
  5.1049 -
  5.1050 -get_size()
  5.1051 -{
  5.1052 -cat $LOCALSTATE/packages.list $TMP_DIR/packages.list 2>/dev/null | awk "{ \
  5.1053 -if (/^$(echo $1 | sed 's/[$+.\]/\\&/g')$/) get=1; \
  5.1054 -if (/installed/ && get == 1) { print ; get++ } \
  5.1055 -}
  5.1056 -END { if (get < 2) print \" 0.0k  (0.0k installed)\" }" | \
  5.1057 -sed 's/ *\(.*\) .\(.*\) installed./\1 \2/' | while read packed unpacked; do
  5.1058 -  echo "$(human2cent $packed) $(human2cent $unpacked)"
  5.1059 -done
  5.1060 -}
  5.1061 -
  5.1062 -# Display package list with version, set packed_size and unpacked_size
  5.1063 -get_pkglist()
  5.1064 -{
  5.1065 -packed_size=0; unpacked_size=0
  5.1066 -grep -v ^#  $FLAVORS_REPOSITORY/$1/packages.list > $TMP_DIR/flavor.pkg
  5.1067 -while read pkg; do
  5.1068 -	set -- $(get_size $pkg)
  5.1069 -	packed_size=$(( $packed_size + $1 ))
  5.1070 -	unpacked_size=$(( $unpacked_size + $2 ))
  5.1071 -	for i in $(grep -hs ^$pkg $LOCALSTATE/packages.list \
  5.1072 -				  $TMP_DIR/packages.list); do
  5.1073 -		echo $i
  5.1074 -		break
  5.1075 -	done
  5.1076 -done < $TMP_DIR/flavor.pkg
  5.1077 -rm -f $TMP_DIR/flavor.pkg
  5.1078 -}
  5.1079  
  5.1080  # Update isolinux config files for multiple rootfs
  5.1081 -update_bootconfig()
  5.1082 -{
  5.1083 +
  5.1084 +update_bootconfig() {
  5.1085  	local files
  5.1086  	echo -n "Updating boot config files..."
  5.1087  	files="$(grep -l 'include common' $1/*.cfg)"
  5.1088 -	for file in $files ; do
  5.1089 -			awk -v n=$(echo $2 | awk '{ print NF/2 }') '{
  5.1090 -if (/label/) label=$0;
  5.1091 -else if (/kernel/) kernel=$0;
  5.1092 -else if (/append/) {
  5.1093 -	i=index($0,"rootfs.gz");
  5.1094 -	append=substr($0,i+9);
  5.1095 -}
  5.1096 -else if (/include/) {
  5.1097 -	for (i = 1; i <= n; i++) {
  5.1098 -		print label i
  5.1099 -		print kernel;
  5.1100 -		initrd="initrd=/boot/rootfs" n ".gz"
  5.1101 -		for (j = n - 1; j >= i; j--) {
  5.1102 -			initrd=initrd ",/boot/rootfs" j ".gz";
  5.1103 -		}
  5.1104 -		printf "\tappend %s%s\n",initrd,append;
  5.1105 -		print "";
  5.1106 -	}
  5.1107 -	print;
  5.1108 -}
  5.1109 -else print;
  5.1110 -}' < $file > $file.$$
  5.1111 -			mv -f $file.$$ $file
  5.1112 +	for file in $files; do
  5.1113 +		awk -v n=$(echo $2 | awk '{ print NF/2 }') '{
  5.1114 +			if (/label/) label=$0;
  5.1115 +			else if (/kernel/) kernel=$0;
  5.1116 +			else if (/append/) {
  5.1117 +				i=index($0,"rootfs.gz");
  5.1118 +				append=substr($0,i+9);
  5.1119 +			}
  5.1120 +			else if (/include/) {
  5.1121 +				for (i = 1; i <= n; i++) {
  5.1122 +					print label i
  5.1123 +					print kernel;
  5.1124 +					initrd="initrd=/boot/rootfs" n ".gz"
  5.1125 +					for (j = n - 1; j >= i; j--) {
  5.1126 +						initrd=initrd ",/boot/rootfs" j ".gz";
  5.1127 +					}
  5.1128 +					printf "\tappend %s%s\n",initrd,append;
  5.1129 +					print "";
  5.1130 +				}
  5.1131 +				print;
  5.1132 +			}
  5.1133 +			else print;
  5.1134 +		}' < $file > $file.$$
  5.1135 +		mv -f $file.$$ $file
  5.1136  	done
  5.1137  	sel="$(echo $2 | awk '{
  5.1138 -  for (i=1; i<=NF; i++)
  5.1139 -     if (i % 2 == 0) printf " slitaz%d",i/2
  5.1140 -     else printf " %s",$i
  5.1141 -}')"
  5.1142 +		for (i=1; i<=NF; i++)
  5.1143 +			if (i % 2 == 0) printf " slitaz%d", i/2
  5.1144 +			else printf " %s", $i
  5.1145 +	}')"
  5.1146 +
  5.1147  	[ -s $1/common.cfg ] && cat >> $1/common.cfg <<EOT
  5.1148  
  5.1149  label slitaz
  5.1150 @@ -674,54 +731,54 @@
  5.1151  	config noram.cfg
  5.1152  
  5.1153  EOT
  5.1154 +
  5.1155  	# Update vesamenu
  5.1156 -	if [ -s $1/isolinux.cfg ]; then
  5.1157 +	if [ -s "$1/isolinux.cfg" ]; then
  5.1158  		files="$files $1/isolinux.cfg"
  5.1159  		awk -v n=$(echo $2 | awk '{ print NF/2 }') -v "sel=$sel" '
  5.1160 -BEGIN {
  5.1161 -	kernel="	COM32 c32box.c32"
  5.1162 -}
  5.1163 -{
  5.1164 -if (/ROWS/) print "MENU ROWS " n+$3;
  5.1165 -else if (/TIMEOUTROW/) print "MENU TIMEOUTROW " n+$3;
  5.1166 -else if (/TABMSGROW/) print "MENU TABMSGROW " n+$3;
  5.1167 -else if (/CMDLINEROW/) print "MENU CMDLINEROW " n+$3;
  5.1168 -else if (/VSHIFT/) {
  5.1169 -	x=$3-n;
  5.1170 -	if (x < 0) x=0;
  5.1171 -	print "MENU VSHIFT " x;
  5.1172 -}
  5.1173 -else if (/rootfs.gz/) {
  5.1174 -	linux=""
  5.1175 -	if (/bzImage/) {
  5.1176 -		linux="linux /boot/bzImage "
  5.1177 -	}
  5.1178 -	i=index($0,"rootfs.gz");
  5.1179 -	append=substr($0,i+9);
  5.1180 -	print	"	kernel /boot/isolinux/ifmem.c32"
  5.1181 -	print	"	append" sel " noram"
  5.1182 -	print	""
  5.1183 -	print	"label noram"
  5.1184 -	print	"	MENU HIDE"
  5.1185 -	print	"	config noram.cfg"
  5.1186 -	print	""
  5.1187 -	for (i = 1; i <= n; i++) {
  5.1188 -		print "LABEL slitaz" i
  5.1189 -		print "	MENU LABEL SliTaz slitaz" i " Live"
  5.1190 -		print kernel;
  5.1191 -		initrd="initrd=/boot/rootfs" n ".gz"
  5.1192 -		for (j = n - 1; j >= i; j--) {
  5.1193 -			initrd=initrd ",/boot/rootfs" j ".gz";
  5.1194 +		BEGIN {
  5.1195 +			kernel = "	COM32 c32box.c32"
  5.1196  		}
  5.1197 -		printf "\tappend %s%s%s\n",linux,initrd,append;
  5.1198 -		print "";
  5.1199 -	}
  5.1200 -}
  5.1201 -else if (/bzImage/) kernel=$0;
  5.1202 -else print;
  5.1203 -}' < $1/isolinux.cfg > $1/isolinux.cfg.$$
  5.1204 +		{
  5.1205 +			     if (/ROWS/)       print "MENU ROWS "       n+$3;
  5.1206 +			else if (/TIMEOUTROW/) print "MENU TIMEOUTROW " n+$3;
  5.1207 +			else if (/TABMSGROW/)  print "MENU TABMSGROW "  n+$3;
  5.1208 +			else if (/CMDLINEROW/) print "MENU CMDLINEROW " n+$3;
  5.1209 +			else if (/VSHIFT/) {
  5.1210 +				x = $3-n;
  5.1211 +				if (x < 0) x = 0;
  5.1212 +				print "MENU VSHIFT " x;
  5.1213 +			}
  5.1214 +			else if (/rootfs.gz/) {
  5.1215 +				linux = "";
  5.1216 +				if (/bzImage/) linux = "linux /boot/bzImage ";
  5.1217 +				i = index($0, "rootfs.gz");
  5.1218 +				append = substr($0, i+9);
  5.1219 +				print "	kernel /boot/isolinux/ifmem.c32"
  5.1220 +				printf "\tappend%s noram", sel;
  5.1221 +				print ""
  5.1222 +				print "label noram"
  5.1223 +				print "	MENU HIDE"
  5.1224 +				print "	config noram.cfg"
  5.1225 +				print ""
  5.1226 +				for (i = 1; i <= n; i++) {
  5.1227 +					print "LABEL slitaz" i
  5.1228 +					printf "\tMENU LABEL SliTaz slitaz%d Live", i;
  5.1229 +					print kernel;
  5.1230 +					initrd = "initrd=/boot/rootfs" n ".gz"
  5.1231 +					for (j = n - 1; j >= i; j--) {
  5.1232 +						initrd = initrd ",/boot/rootfs" j ".gz";
  5.1233 +					}
  5.1234 +					printf "\tappend %s%s%s\n", linux, initrd, append;
  5.1235 +					print "";
  5.1236 +				}
  5.1237 +			}
  5.1238 +			else if (/bzImage/) kernel = $0;
  5.1239 +			else print;
  5.1240 +		}' < $1/isolinux.cfg > $1/isolinux.cfg.$$
  5.1241  		mv $1/isolinux.cfg.$$ $1/isolinux.cfg
  5.1242  	fi
  5.1243 +
  5.1244  	[ -s $1/c32box.c32 ] && sed -i -e '/kernel.*ifmem/d' \
  5.1245  		-e 's/append \([0-9]\)/append ifmem \1/' $1/isolinux.cfg
  5.1246  	cat > $1/noram.cfg <<EOT
  5.1247 @@ -739,6 +796,7 @@
  5.1248  
  5.1249  label reboot
  5.1250  EOT
  5.1251 +
  5.1252  	if [ -s $1/c32box.c32 ]; then
  5.1253  		cat >> $1/noram.cfg <<EOT
  5.1254  	COM32 c32box.c32
  5.1255 @@ -752,6 +810,7 @@
  5.1256  	else
  5.1257  		echo "	com32 reboot.c32" >> $1/noram.cfg
  5.1258  	fi
  5.1259 +
  5.1260  	# Restore real label names
  5.1261  	[ -s $1/common.cfg ] && files="$1/common.cfg $files"
  5.1262  	echo $2 | awk '{ for (i=NF; i>1; i-=2) printf "%d/%s\n",i/2,$i }' | \
  5.1263 @@ -761,64 +820,65 @@
  5.1264  	status
  5.1265  }
  5.1266  
  5.1267 +
  5.1268  # Install a missing package
  5.1269 -install_package()
  5.1270 -{
  5.1271 -	echo -n "Install package $1 "
  5.1272 -	[ -n "$2" ] && echo -n "for kernel $2 "
  5.1273 -	echo -n "?"
  5.1274 +
  5.1275 +install_package() {
  5.1276 +	if [ -z "$2" ]; then
  5.1277 +		_n 'Install package %s? ' "$1"
  5.1278 +	else
  5.1279 +		_n 'Install package %s for Kernel %s? ' "$1" "$2"
  5.1280 +	fi
  5.1281 +	echo -n '[y = yes] '
  5.1282  	read answer
  5.1283  	case "$answer" in
  5.1284 -	y*|Y*|o*|O*)
  5.1285 -		# We dont want package on host cache.
  5.1286 -		echo -n "Getting and installing package: $1"
  5.1287 -		yes y | tazpkg get-install $1 2>&1 >> $log || exit 1
  5.1288 -		status ;;
  5.1289 -	*)
  5.1290 -		return 1 ;;
  5.1291 +		y*|Y*|o*|O*)
  5.1292 +			# We don't want package on host cache.
  5.1293 +			action 'Getting and installing package: %s' "$1"
  5.1294 +			yes y | tazpkg get-install $1 --quiet 2>&1 >> $log || exit 1
  5.1295 +			status ;;
  5.1296 +		*)
  5.1297 +			return 1 ;;
  5.1298  	esac
  5.1299  }
  5.1300  
  5.1301 +
  5.1302  # Check iso for loram transformation
  5.1303 -check_iso_for_loram()
  5.1304 -{
  5.1305 -	[ -s $TMP_DIR/iso/boot/rootfs.gz ] ||
  5.1306 -	[ -s $TMP_DIR/iso/boot/rootfs1.gz ]
  5.1307 +
  5.1308 +check_iso_for_loram() {
  5.1309 +	[ -s "$TMP_DIR/iso/boot/rootfs.gz" ] ||
  5.1310 +	[ -s "$TMP_DIR/iso/boot/rootfs1.gz" ]
  5.1311  }
  5.1312  
  5.1313 +
  5.1314  # Build initial rootfs for loram ISO ram/cdrom/http
  5.1315 -build_initfs()
  5.1316 -{
  5.1317 +
  5.1318 +build_initfs() {
  5.1319  	urliso="mirror.slitaz.org mirror.switch.ch/ftp/mirror/slitaz \
  5.1320  download.tuxfamily.org/slitaz slitaz.c3sl.ufpr.br"
  5.1321  	version=$(ls $TMP_DIR/iso/boot/vmlinuz-* | sed 's/.*vmlinuz-//')
  5.1322 -	if [ -z "$version" ]; then
  5.1323 -		cat <<EOT
  5.1324 -Can't find the kernel version.
  5.1325 -No file /boot/vmlinuz-<version> in ISO image.
  5.1326 -Abort.
  5.1327 -EOT
  5.1328 -		exit 1
  5.1329 -	fi
  5.1330 +	[ -z "$version" ] && die "Can't find the kernel version." \
  5.1331 +		'No file /boot/vmlinuz-<version> in ISO image. Abort.'
  5.1332 +
  5.1333  	[ -s /usr/share/boot/busybox-static ] || install_package busybox-static
  5.1334  	need_lib=false
  5.1335 -	mkdir -p $TMP_DIR/initfs/bin $TMP_DIR/initfs/dev $TMP_DIR/initfs/run \
  5.1336 -		 $TMP_DIR/initfs/mnt $TMP_DIR/initfs/proc $TMP_DIR/initfs/tmp \
  5.1337 -		 $TMP_DIR/initfs/sys $TMP_DIR/initfs/lib/modules
  5.1338 +	for i in bin dev run mnt proc tmp sys lib/modules; do
  5.1339 +		mkdir -p $TMP_DIR/initfs/$i
  5.1340 +	done
  5.1341  	ln -s bin $TMP_DIR/initfs/sbin
  5.1342 -	ln -s . $TMP_DIR/initfs/usr
  5.1343 -	for aufs in aufs overlayfs ; do
  5.1344 +	ln -s .   $TMP_DIR/initfs/usr
  5.1345 +	for aufs in aufs overlayfs; do
  5.1346  		[ ! -f /lib/modules/$version/kernel/fs/$aufs/$aufs.ko.?z ] &&
  5.1347  		install_package $aufs $version && break
  5.1348  	done || return 1
  5.1349  	cp /init $TMP_DIR/initfs/
  5.1350  	# bootfloppybox will need floppy.ko.?z, /dev/fd0, /dev/tty0
  5.1351  	cp /lib/modules/$version/kernel/drivers/block/floppy.ko.?z \
  5.1352 -		$TMP_DIR/initfs/lib/modules 2> /dev/null
  5.1353 -	cp -a /dev/tty0 /dev/fd0 $TMP_DIR/initfs/dev 2> /dev/null
  5.1354 +		$TMP_DIR/initfs/lib/modules 2>/dev/null
  5.1355 +	cp -a /dev/tty0 /dev/fd0 $TMP_DIR/initfs/dev 2>/dev/null
  5.1356  	cp /lib/modules/$version/kernel/fs/$aufs/$aufs.ko.?z \
  5.1357  		$TMP_DIR/initfs/lib/modules
  5.1358 -	if [ "$1" == "cdrom" ]; then
  5.1359 +	if [ "$1" == 'cdrom' ]; then
  5.1360  		sed -i '/mod squashfs/d' $TMP_DIR/initfs/init
  5.1361  	else
  5.1362  		[ ! -f /usr/sbin/mksquashfs ] && ! install_package squashfs && return 1
  5.1363 @@ -826,14 +886,14 @@
  5.1364  			install_package linux-squashfs $version || return 1
  5.1365  		done
  5.1366  		cp /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z \
  5.1367 -			 $TMP_DIR/initfs/lib/modules
  5.1368 +			$TMP_DIR/initfs/lib/modules
  5.1369  		ls /sbin/unsquashfs /usr/lib/liblzma.so* $INSTALLED/squashfs/* | \
  5.1370  		cpio -o -H newc > $TMP_DIR/initfs/extractfs.cpio
  5.1371  	fi
  5.1372  	for i in $(ls /dev/[hs]d[a-f]*); do
  5.1373  		cp -a $i $TMP_DIR/initfs/dev
  5.1374  	done
  5.1375 -	if [ "$1" == "http" ]; then
  5.1376 +	if [ "$1" == 'http' ]; then
  5.1377  		mkdir $TMP_DIR/initfs/etc
  5.1378  		ln -s /proc/mounts $TMP_DIR/initfs/etc/mtab
  5.1379  		cp /usr/share/udhcpc/default.script $TMP_DIR/initfs/lib/udhcpc
  5.1380 @@ -859,14 +919,13 @@
  5.1381  			need_lib=true
  5.1382  		fi
  5.1383  		cd $TMP_DIR/initfs
  5.1384 -		echo "Getting slitaz-release..."
  5.1385 +		echo 'Getting slitaz-release...'
  5.1386  		for i in $TMP_DIR/iso/boot/rootfs*.gz; do
  5.1387 -			( zcat $i 2> /dev/null || unlzma < $i) | \
  5.1388 -			cpio -idmu etc/slitaz-release > /dev/null
  5.1389 +			(zcat $i 2>/dev/null || unlzma < $i) | cpio -idmu etc/slitaz-release >/dev/null
  5.1390  		done
  5.1391  		cd - > /dev/null
  5.1392 -		echo "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"
  5.1393 -		echo -n "List of urls to insert: "
  5.1394 +		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"
  5.1395 +		echo -n "List of URLs to insert: "
  5.1396  		read -t 30 urliso2
  5.1397  		urliso="$urliso2 $urliso"
  5.1398  	fi
  5.1399 @@ -888,18 +947,16 @@
  5.1400  	$need_lib && for i in /lib/ld-* /lib/lib[cm].so* /lib/lib[cm]-* ; do
  5.1401  		cp -a $i $TMP_DIR/initfs/lib
  5.1402  	done
  5.1403 -	[ "$1" == "http" ] && cat > $TMP_DIR/initfs/init <<EOTEOT
  5.1404 +	[ "$1" == 'http' ] && cat > $TMP_DIR/initfs/init <<EOTEOT
  5.1405  #!/bin/sh
  5.1406  
  5.1407 -getarg()
  5.1408 -{
  5.1409 +getarg() {
  5.1410  	grep -q " \$1=" /proc/cmdline || return 1
  5.1411  	eval \$2=\$(sed "s/.* \$1=\\\\([^ ]*\\\\).*/\\\\1/" < /proc/cmdline)
  5.1412  	return 0
  5.1413  }
  5.1414  
  5.1415 -copy_rootfs()
  5.1416 -{
  5.1417 +copy_rootfs() {
  5.1418  	total=\$(grep MemTotal /proc/meminfo | sed 's/[^0-9]//g')
  5.1419  	need=\$(du -c \${path}rootfs* | tail -n 1 | cut -f1)
  5.1420  	[ \$(( \$total / \$need )) -gt 1 ] || return 1
  5.1421 @@ -988,8 +1045,8 @@
  5.1422  		unxz $i || gunzip $i || lzma d $i ${i%.gz}
  5.1423  		rm -f $i
  5.1424  		gzip -9 ${i%.gz}
  5.1425 -	done 2> /dev/null
  5.1426 -	( cd $TMP_DIR/initfs ; find | busybox cpio -o -H newc 2> /dev/null) | \
  5.1427 +	done 2>/dev/null
  5.1428 +	(cd $TMP_DIR/initfs; find | busybox cpio -o -H newc 2>/dev/null) | \
  5.1429  	lzma e $TMP_DIR/initfs.gz -si
  5.1430  	lzma_set_size $TMP_DIR/initfs.gz
  5.1431  	rm -rf $TMP_DIR/initfs
  5.1432 @@ -997,21 +1054,21 @@
  5.1433  	return 0
  5.1434  }
  5.1435  
  5.1436 +
  5.1437  # Move each initramfs to squashfs
  5.1438 -build_loram_rootfs()
  5.1439 -{
  5.1440 +
  5.1441 +build_loram_rootfs() {
  5.1442  	rootfs_sizes=""
  5.1443  	for i in $TMP_DIR/iso/boot/rootfs*.gz; do
  5.1444  		mkdir -p $TMP_DIR/fs
  5.1445  		cd $TMP_DIR/fs
  5.1446 -		( zcat $i 2> /dev/null || unlzma < $i) | cpio -idm
  5.1447 +		(zcat $i 2>/dev/null || unlzma < $i) | cpio -idm
  5.1448  		cd - > /dev/null
  5.1449  		rootfs=$TMP_DIR/$(basename $i)
  5.1450  		/usr/sbin/mksquashfs $TMP_DIR/fs $rootfs -comp xz -Xbcj x86
  5.1451  		cd $TMP_DIR
  5.1452  		rootfs_sizes="$rootfs_sizes $(( $(du -s $TMP_DIR/fs | cut -f1) - $(du -s $rootfs | cut -f1) ))"
  5.1453 -		( cd $(dirname $rootfs); echo $(basename $rootfs) | \
  5.1454 -			  cpio -o -H newc ) > $rootfs.cpio
  5.1455 +		( cd $(dirname $rootfs); echo $(basename $rootfs) | cpio -o -H newc ) > $rootfs.cpio
  5.1456  		rm -f $rootfs
  5.1457  		mv $rootfs.cpio $rootfs
  5.1458  		cd - > /dev/null
  5.1459 @@ -1019,10 +1076,11 @@
  5.1460  	done
  5.1461  }
  5.1462  
  5.1463 +
  5.1464  # Move meta boot configuration files to basic configuration files
  5.1465 -# because meta loram flavor is useless when rootfs is not loaded in ram
  5.1466 -unmeta_boot()
  5.1467 -{
  5.1468 +# because meta loram flavor is useless when rootfs is not loaded in RAM
  5.1469 +
  5.1470 +unmeta_boot() {
  5.1471  	local root=${1:-$TMP_DIR/loramiso}
  5.1472  	if [ -f $root/boot/isolinux/noram.cfg ]; then
  5.1473  		# We keep enough information to do unloram...
  5.1474 @@ -1039,22 +1097,23 @@
  5.1475  	fi
  5.1476  }
  5.1477  
  5.1478 +
  5.1479  # Move rootfs to squashfs filesystem(s) to the cdrom writeable with aufs/overlayfs.
  5.1480 -# These squashfs may be loaded in ram at boot time.
  5.1481 -# Rootfs are also copied to cdrom for tiny ramsize systems.
  5.1482 +# These squashfs may be loaded in RAM at boot time.
  5.1483 +# Rootfs are also copied to CD-ROM for tiny ramsize systems.
  5.1484  # Meta flavors are converted to normal flavors.
  5.1485 -build_loram_cdrom()
  5.1486 -{
  5.1487 +
  5.1488 +build_loram_cdrom() {
  5.1489  	build_initfs cdrom || return 1
  5.1490  	cp -a $TMP_DIR/iso $TMP_DIR/loramiso
  5.1491  	mkdir $TMP_DIR/loramiso/fs
  5.1492  	cd $TMP_DIR/loramiso/fs
  5.1493  	for i in $( ls ../boot/root* | sort -r ) ; do
  5.1494 -		( zcat $i 2> /dev/null || unlzma < $i ) | cpio -idmu
  5.1495 +		(zcat $i 2>/dev/null || unlzma < $i) | cpio -idmu
  5.1496  		rm -f $i
  5.1497  	done
  5.1498  	mkdir -p $TMP_DIR/loramiso/fs/mnt/.cdrom
  5.1499 -	cd - > /dev/null
  5.1500 +	cd - >/dev/null
  5.1501  	mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
  5.1502  	unmeta_boot
  5.1503  	VOLUM_NAME="SliTaz_LoRAM_CDROM"
  5.1504 @@ -1063,10 +1122,11 @@
  5.1505  	create_iso $OUTPUT $TMP_DIR/loramiso
  5.1506  }
  5.1507  
  5.1508 +
  5.1509  # Create http bootstrap to load and remove loram_cdrom
  5.1510  # Meta flavors are converted to normal flavors.
  5.1511 -build_loram_http()
  5.1512 -{
  5.1513 +
  5.1514 +build_loram_http() {
  5.1515  	build_initfs http || return 1
  5.1516  	cp -a $TMP_DIR/iso $TMP_DIR/loramiso
  5.1517  	rm -f $TMP_DIR/loramiso/boot/rootfs*
  5.1518 @@ -1075,10 +1135,11 @@
  5.1519  	create_iso $OUTPUT $TMP_DIR/loramiso
  5.1520  }
  5.1521  
  5.1522 +
  5.1523  # Update meta flavor selection sizes.
  5.1524  # Reduce sizes with rootfs gains.
  5.1525 -update_metaiso_sizes()
  5.1526 -{
  5.1527 +
  5.1528 +update_metaiso_sizes() {
  5.1529  	for cfg in $(grep -El '(append|ifmem) [0-9]' $TMP_DIR/loramiso/boot/isolinux/*.cfg)
  5.1530  	do
  5.1531  		local append="$(grep -E '(append|ifmem) [0-9]' $cfg)"
  5.1532 @@ -1091,9 +1152,9 @@
  5.1533  		while [ -n "$2" ]; do
  5.1534  			local s
  5.1535  			case "$1" in
  5.1536 -			*G) s=$(( ${1%G} * 1024 * 1024 ));;
  5.1537 -			*M) s=$(( ${1%M} * 1024 ));;
  5.1538 -			*)  s=${1%K};;
  5.1539 +				*G) s=$(( ${1%G} * 1024 * 1024 ));;
  5.1540 +				*M) s=$(( ${1%M} * 1024 ));;
  5.1541 +				*)  s=${1%K};;
  5.1542  			esac
  5.1543  			sizes=${sizes#* }
  5.1544  			for i in $sizes ; do
  5.1545 @@ -1109,23 +1170,25 @@
  5.1546  	done
  5.1547  }
  5.1548  
  5.1549 +
  5.1550  # Move rootfs to a squashfs filesystem into the initramfs writeable with aufs/overlayfs.
  5.1551  # Meta flavor selection sizes are updated.
  5.1552 -build_loram_ram()
  5.1553 -{
  5.1554 +
  5.1555 +build_loram_ram() {
  5.1556  	build_initfs ram || return 1
  5.1557  	build_loram_rootfs
  5.1558 -	cp -a $TMP_DIR/iso $TMP_DIR/loramiso
  5.1559 +	cp -a $TMP_DIR/iso    $TMP_DIR/loramiso
  5.1560  	make_bzImage_hardlink $TMP_DIR/loramiso/boot
  5.1561  	mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
  5.1562 -	cp $TMP_DIR/rootfs* $TMP_DIR/loramiso/boot
  5.1563 +	cp $TMP_DIR/rootfs*   $TMP_DIR/loramiso/boot
  5.1564  	update_metaiso_sizes
  5.1565 -	create_iso $OUTPUT $TMP_DIR/loramiso
  5.1566 +	create_iso $OUTPUT    $TMP_DIR/loramiso
  5.1567  }
  5.1568  
  5.1569 +
  5.1570  # Remove files installed by packages
  5.1571 -find_flavor_rootfs()
  5.1572 -{
  5.1573 +
  5.1574 +find_flavor_rootfs() {
  5.1575  	for i in $1/etc/tazlito/*.extract; do
  5.1576  		[ -e $i ] || continue
  5.1577  		chroot $1 /bin/sh ${i#$1}
  5.1578 @@ -1175,34 +1238,348 @@
  5.1579  	rm -f $1$LOCALSTATE/*packages* $1$LOCALSTATE/files.list.lzma \
  5.1580  		$1$LOCALSTATE/mirror*  $1/var/cache/*/* \
  5.1581  		$1/var/lock/* $1/var/log/* $1/var/run/* $1/var/run/*/* \
  5.1582 -		$1/var/lib/*  $1/var/lib/dbus/* 2> /dev/null
  5.1583 +		$1/var/lib/*  $1/var/lib/dbus/* 2>/dev/null
  5.1584  
  5.1585  	# Cleanup directory tree
  5.1586  	cd $1
  5.1587  	find * -type d | sort -r | while read dir; do
  5.1588 -		rmdir "$dir" 2> /dev/null
  5.1589 +		rmdir "$dir" 2>/dev/null
  5.1590  	done
  5.1591  	cd - > /dev/null
  5.1592  }
  5.1593  
  5.1594 -# get byte(s) form a binary file 
  5.1595 -get()
  5.1596 -{
  5.1597 +
  5.1598 +# Get byte(s) from a binary file
  5.1599 +
  5.1600 +get() {
  5.1601  	od -v -j $1 -N ${3:-2} -t u${3:-2} -w${3:-2} -An $2 2>/dev/null
  5.1602  }
  5.1603  
  5.1604 -# get cpio flavor info from the ISO image
  5.1605 -flavordata()
  5.1606 -{
  5.1607 +
  5.1608 +# Get cpio flavor info from the ISO image
  5.1609 +
  5.1610 +flavordata() {
  5.1611  	[ $(get 1024 $1) -eq 35615 ] && n=2 || n=$((1+$(get 417 $1 1)))
  5.1612  	dd if=$1 bs=512 skip=$n count=20 2>/dev/null | zcat 2>/dev/null
  5.1613  }
  5.1614  
  5.1615  
  5.1616 +# Restore undigest mirrors
  5.1617 +
  5.1618 +restore_mirrors() {
  5.1619 +	local undigest="$root$LOCALSTATE/undigest" priority="$root$LOCALSTATE/priority"
  5.1620 +	[ -d "$undigest.bak" ] || [ -e "$priority.bak" ] || return
  5.1621 +
  5.1622 +	action 'Restoring mirrors...'
  5.1623 +	if [  -d "$undigest.bak" ]; then
  5.1624 +		[ -d "$undigest" ] && rm -r "$undigest"
  5.1625 +		mv   "$undigest.bak" "$undigest"
  5.1626 +	fi
  5.1627 +	[ -e "$priority.bak" ] && mv -f "$priority.bak" "$priority"
  5.1628 +	:; status
  5.1629 +}
  5.1630 +
  5.1631 +
  5.1632 +# Setup undigest mirrors
  5.1633 +
  5.1634 +setup_mirrors() {
  5.1635 +	# Setup mirrors in plain system or in chroot (with variable root=)
  5.1636 +	#
  5.1637 +	# Note, difficulties exists in using local-filesystem-mirrors (when content
  5.1638 +	# of the 'mirror' file is point to folder somewhere in the FS) inside chroot,
  5.1639 +	# because mirror should be in the chroot too. We make local mirrors to be
  5.1640 +	# accessible via http://localhost/... using built-in SliTaz web server.
  5.1641 +	local mirrorlist="$1" fresh repacked
  5.1642 +	local undigest="$root$LOCALSTATE/undigest" priority="$root$LOCALSTATE/priority"
  5.1643 +
  5.1644 +	# Restore mirrors first: in case of non-clear exits, hangs, etc.
  5.1645 +	restore_mirrors
  5.1646 +
  5.1647 +	_ 'Setting up mirrors for %s...' "$root/"
  5.1648 +	# Backing up current undigest mirrors and priority
  5.1649 +	[ -d "$undigest" ] && mv "$undigest" "$undigest.bak"
  5.1650 +	[ -e "$priority" ] && mv "$priority" "$priority.bak"
  5.1651 +	rm -rf '/var/www/tazlito/'
  5.1652 +	mkdir -p '/var/www/tazlito/'
  5.1653 +
  5.1654 +	# Packages produced by CookUtils: on Tank or local, or repacked packages: highest priority
  5.1655 +	fresh='/home/slitaz/packages'
  5.1656 +	if [ -d "$fresh" ]; then
  5.1657 +		# Make this mirror accessible using http://localhost/tazlito/fresh
  5.1658 +		ln -s "$fresh" '/var/www/tazlito/fresh'
  5.1659 +		# Setup first undigest mirror
  5.1660 +		mkdir -p "$undigest/fresh"
  5.1661 +		echo "http://localhost/tazlito/fresh/" > "$undigest/fresh/mirror"
  5.1662 +		echo 'fresh' >> "$priority"
  5.1663 +		# Rebuild mirror DB if needed
  5.1664 +		[ ! -e "$fresh/IDs" ] && tazpkg mkdb "$fresh" --forced --root=''
  5.1665 +		[ -n "$(find -L "$fresh" -name '*.tazpkg' -newer "$fresh/IDs")" ] && \
  5.1666 +			tazpkg mkdb "$fresh" --forced --root=''
  5.1667 +		cp -a "$fresh/files.list.lzma" "$fresh/files-list.lzma"
  5.1668 +	fi
  5.1669 +
  5.1670 +	# Repacked packages: high priority
  5.1671 +	repacked="$PACKAGES_REPOSITORY"
  5.1672 +	if [ -d "$repacked" -a "$repacked" != "$fresh" ] && ls "$repacked" | grep -q ".tazpkg"; then
  5.1673 +		# According to Tazlito setup file (tazlito.conf):
  5.1674 +		# WORK_DIR="/home/slitaz/$SLITAZ_VERSION"
  5.1675 +		# or
  5.1676 +		# WORK_DIR="/home/slitaz"
  5.1677 +		# and
  5.1678 +		# PACKAGES_REPOSITORY="$WORK_DIR/packages"
  5.1679 +		# It MAY or MAY NOT match /home/slitaz/packages, so here we setup second repository
  5.1680 +
  5.1681 +		# Make this mirror accessible using http://localhost/tazlito/repacked
  5.1682 +		ln -s "$repacked" '/var/www/tazlito/repacked'
  5.1683 +		# Setup second undigest mirror
  5.1684 +		mkdir -p "$undigest/repacked"
  5.1685 +		echo "http://localhost/tazlito/repacked/" > "$undigest/repacked/mirror"
  5.1686 +		echo 'repacked' >> "$priority"
  5.1687 +		# Rebuild mirror DB if needed
  5.1688 +		[ ! -e "$repacked/IDs" ] && tazpkg mkdb "$repacked" --forced --root=''
  5.1689 +		[ -n "$(find -L "$repacked" -name '*.tazpkg' -newer "$repacked/IDs")" ] && \
  5.1690 +			tazpkg mkdb "$repacked" --forced --root=''
  5.1691 +		cp -a "$repacked/files.list.lzma" "$repacked/files-list.lzma"
  5.1692 +	fi
  5.1693 +
  5.1694 +	# All repositories listed in mirrors list: normal priority
  5.1695 +	[ -e "$mirrorlist" ] && \
  5.1696 +	while read mirror; do
  5.1697 +		# Provide consistent mirror ID for caching purpose: /var/cache/tazpkg/<mirror ID>/packages
  5.1698 +		mirrorid=$(echo "$mirror" | md5sum | cut -d' ' -f1)
  5.1699 +		mkdir -p            "$undigest/$mirrorid"
  5.1700 +		echo "$mirror"    > "$undigest/$mirrorid/mirror"
  5.1701 +		echo "$mirrorid" >> "$priority"
  5.1702 +	done < "$mirrorlist"
  5.1703 +
  5.1704 +	# And, finally, main mirror with the lowest (failsafe) priority (nothing to do)
  5.1705 +
  5.1706 +	# Show list of mirrors
  5.1707 +	awk -vdb="$root$LOCALSTATE" '
  5.1708 +	function show(num, name, url,   pad, len) {
  5.1709 +		pad = "................................";
  5.1710 +		len = (32 - length(name));
  5.1711 +		printf " %-1.1d. %s%*.*s %-44.44s\n", num, name, len, len, pad, url;
  5.1712 +	}
  5.1713 +	{
  5.1714 +		num++;
  5.1715 +		"cat " db "/undigest/" $0 "/mirror" | getline url;
  5.1716 +		show(num, $0, url);
  5.1717 +	}
  5.1718 +	END {
  5.1719 +		num++;
  5.1720 +		"cat " db "/mirror" | getline url;
  5.1721 +		show(num, "main", url);
  5.1722 +	}' "$priority"
  5.1723 +
  5.1724 +	tazpkg recharge --quiet
  5.1725 +}
  5.1726 +
  5.1727 +
  5.1728 +# Get list of 'packages.info' lists using priority
  5.1729 +
  5.1730 +pi_lists() {
  5.1731 +	local pi
  5.1732 +	[ -s "$root$LOCALSTATE/packages.info" ] || tazpkg recharge >/dev/null 2>&1
  5.1733 +	local priority="$root$LOCALSTATE/priority"
  5.1734 +	local undigest="$root$LOCALSTATE/undigest"
  5.1735 +
  5.1736 +	{
  5.1737 +		[ -s "$priority" ] && cat "$priority"
  5.1738 +		echo 'main'
  5.1739 +		[ -d "$undigest" ] && ls "$undigest"
  5.1740 +	} | awk -vun="$undigest/" '
  5.1741 +	{
  5.1742 +		if (arr[$0] != 1) {
  5.1743 +			arr[$0]  = 1;
  5.1744 +			print un $0 "/packages.info";
  5.1745 +		}
  5.1746 +	}' | sed 's|/undigest/main||' | \
  5.1747 +	while read pi; do
  5.1748 +		[ -e "$pi" ] && echo "$pi"
  5.1749 +	done
  5.1750 +}
  5.1751 +
  5.1752 +
  5.1753 +# Strip versions from packages list
  5.1754 +
  5.1755 +strip_versions() {
  5.1756 +	action 'Strip versions from list %s...' "$(basename "$1")"
  5.1757 +	local in_list="$1" tmp_list="$(mktemp)" namever pkg
  5.1758 +	[ -f "$in_list" ] || die "List '$in_list' not found."
  5.1759 +
  5.1760 +	# $pkg=<name>-<version> or $pkg=<name>; both <name> and <version> may contain dashes
  5.1761 +	awk '
  5.1762 +	{
  5.1763 +		if (FILENAME ~ "packages.info") {
  5.1764 +			# Collect package names
  5.1765 +			FS = "\t"; pkg[$1] = 1;
  5.1766 +		} else {
  5.1767 +			FS = "-"; OFS = "-"; $0 = $0;		# Fix bug with FS for first record
  5.1768 +			while (NF > 1 && ! pkg[$0])
  5.1769 +				NF --;
  5.1770 +			printf "%s\n", $0;
  5.1771 +		}
  5.1772 +	}' $(pi_lists) "$in_list" > "$tmp_list"
  5.1773 +
  5.1774 +	cat "$tmp_list" > "$in_list"
  5.1775 +	rm "$tmp_list"
  5.1776 +	status
  5.1777 +}
  5.1778 +
  5.1779 +
  5.1780 +# Calculate sizes (estimated) and real packages number (including all dependencies)
  5.1781 +# using given extracted flavor and current mirrors.
  5.1782 +#
  5.1783 +# Input: <unpacked flavor dir> <flavor name> [<output full list file>]
  5.1784 +# Output in human readable form:
  5.1785 +# <unpacked size> <packed size> <size of ISO> <number of packages>
  5.1786 +# File $1/err output: unknown packages
  5.1787 +# File $1/warn output: warnings about missing packages
  5.1788 +# TODO: use 'equivalent packages' rules
  5.1789 +
  5.1790 +calc_sizes() {
  5.1791 +	local dir="$1" flavor="$2" outfile="$3"
  5.1792 +	local rootfs_packed=0 rootfs_unpacked=0 rootcd_unpacked=0
  5.1793 +
  5.1794 +	if [ -s "$dir/$flavor.rootfs" ]; then
  5.1795 +		rootfs_packed="$(wc -c < "$dir/$flavor.rootfs")";
  5.1796 +		rootfs_unpacked="$(zcat  "$dir/$flavor.rootfs" | wc -c)";
  5.1797 +	fi
  5.1798 +	if [ -s "$dir/$flavor.rootcd" ]; then
  5.1799 +		rootcd_unpacked="$(zcat  "$dir/$flavor.rootcd" | wc -c)";
  5.1800 +	fi
  5.1801 +
  5.1802 +	awk -F$'\t' \
  5.1803 +	-vrootfs_p="$rootfs_packed" -vrootfs_u="$rootfs_unpacked" -vrootcd_u="$rootcd_unpacked" \
  5.1804 +	-voutfile="$outfile" -verrfile="$dir/err" -vwarnfile="$dir/warn" '
  5.1805 +	BEGIN {
  5.1806 +		K = 1024; M = K * 1024; G = M * 1024;
  5.1807 +	}
  5.1808 +	function h2b(h) {
  5.1809 +		# Convert human-readable format to bytes
  5.1810 +		if (h ~ "K")	return h * K;
  5.1811 +		if (h ~ "M")	return h * M;
  5.1812 +		if (h ~ "G")	return h * G;
  5.1813 +						return h;
  5.1814 +	}
  5.1815 +	function b2h(b,   p) {
  5.1816 +		# Convert bytes to human-readable format
  5.1817 +		     if (b >= G)	{ b /= G; p = "G"; }
  5.1818 +		else if (b >= M)	{ b /= M; p = "M"; }
  5.1819 +		else				{ b /= K; p = "K"; }
  5.1820 +		if (b >= 100)	printf   "%d%s\n", b, p;
  5.1821 +		else			printf "%.1f%s\n", b, p;
  5.1822 +	}
  5.1823 +	function mark_deps(pkg,   localdepend, localdepends) {
  5.1824 +		# Mark package with its dependencies (to be processed later)
  5.1825 +		if (sizes[pkg]) {
  5.1826 +			if (! pkgs[pkg]) {
  5.1827 +				pkgs[pkg] = sizes[pkg];
  5.1828 +
  5.1829 +				if (depends[pkg]) {
  5.1830 +					split(depends[pkg], localdepends, " ");
  5.1831 +					# Recursive call
  5.1832 +					for (localdepend in localdepends)
  5.1833 +						mark_deps(localdepends[localdepend]);
  5.1834 +				}
  5.1835 +			}
  5.1836 +		} else {
  5.1837 +			printf "  %s\n", $1 >> errfile;
  5.1838 +		}
  5.1839 +	}
  5.1840 +	function calc(pkg, size_u, size_p) {
  5.1841 +		# Calculate unpacked and packed sizes of /boot
  5.1842 +		if (pkgs[pkg]) { boot_u += h2b(size_u); boot_p += h2b(size_p); }
  5.1843 +	}
  5.1844 +	# main loop
  5.1845 +	{
  5.1846 +		if (FILENAME ~ "packages.info") {
  5.1847 +			# Step #1: fill arrays "sizes" and "depends"
  5.1848 +			if (! sizes[$1]) {
  5.1849 +				  sizes[$1] = $7;
  5.1850 +				depends[$1] = $8;
  5.1851 +			}
  5.1852 +		} else {
  5.1853 +			# Step #2: mark packages and its dependencies
  5.1854 +			mark_deps($1);
  5.1855 +		}
  5.1856 +	}
  5.1857 +	END {
  5.1858 +		# Calculate sums for all marked packages and its deps
  5.1859 +		for (pkg in pkgs) {
  5.1860 +			num_pkgs ++;
  5.1861 +			split(pkgs[pkg], s, " ");
  5.1862 +			size_packed   += h2b(s[1]);
  5.1863 +			size_unpacked += h2b(s[2]);
  5.1864 +			if (outfile) print pkg >> outfile;
  5.1865 +		}
  5.1866 +		# Add files placed in flavor.rootfs
  5.1867 +		size_packed   += rootfs_p;
  5.1868 +		size_unpacked += rootfs_u;
  5.1869 +
  5.1870 +		# Check critical packages: "syslinux" and one of the packages containing "vmlinuz*"
  5.1871 +		printf "" > warnfile;
  5.1872 +		if (! pkgs["syslinux"]) printf "  * Syslinux\n" >> warnfile;
  5.1873 +		if (! pkgs["linux"]       && ! pkgs["linux-without-modules"] && \
  5.1874 +			! pkgs["linux64"]     && ! pkgs["linux64-without-modules"] && \
  5.1875 +			! pkgs["linux-libre"] && ! pkgs["linux-libre-without-modules"] && \
  5.1876 +			! pkgs["linux-uml"]) printf "  * Linux kernel\n" >> warnfile;
  5.1877 +
  5.1878 +		# Calculate unpacked and packed sizes of /boot
  5.1879 +		calc("syslinux",					"156K",  "120K" );
  5.1880 +		calc("gpxe",						"196K",  "188K" );
  5.1881 +		calc("ipxe",						"316K",  "312K" );
  5.1882 +		calc("memtest",						"52K",   "48K"  );
  5.1883 +		calc("memtest-serial",				"52K",   "48K"  );
  5.1884 +		calc("slitaz-configs-base",			"36K",   "28K"  );
  5.1885 +		calc("linux",						"2.8M",  "2.8M" );
  5.1886 +		calc("linux-without-modules",		"12.6M", "12.8M");
  5.1887 +		calc("linux64",						"3.0M",  "3.0M" );
  5.1888 +		calc("linux64-without-modules",		"13.2M", "13.4M");
  5.1889 +		calc("linux-libre",					"2.3M",  "2.3M" );
  5.1890 +		calc("linux-libre-without-modules",	"6.9M",  "6.9M" );
  5.1891 +		calc("linux-uml",					"3.0M",  "1.1M" );
  5.1892 +
  5.1893 +		# /boot is moved away from rootfs
  5.1894 +		size_packed   -= boot_p;
  5.1895 +		size_unpacked -= boot_u;
  5.1896 +
  5.1897 +		# Add rootcd payload and /boot content sizes
  5.1898 +		size_iso = size_packed + rootcd_u + boot_u;
  5.1899 +
  5.1900 +		printf "%s %s ",  b2h(size_unpacked), b2h(size_packed);
  5.1901 +		printf "%s %d\n", b2h(size_iso), num_pkgs;
  5.1902 +	}' $(pi_lists) "$dir/$flavor.pkglist"
  5.1903 +}
  5.1904 +
  5.1905 +
  5.1906 +# Display list of unknown packages (informative)
  5.1907 +display_unknown() {
  5.1908 +	[ -s "$1" ] || return
  5.1909 +	echo "Unknown packages:" >&2
  5.1910 +	cat "$1" >&2
  5.1911 +	rm  "$1"
  5.1912 +}
  5.1913 +
  5.1914 +
  5.1915 +# Display warnings about critical packages absent (informative)
  5.1916 +display_warn() {
  5.1917 +	[ -s "$1" ] || return
  5.1918 +	echo "Absent critical packages:" >&2
  5.1919 +	cat "$1" >&2
  5.1920 +	rm  "$1"
  5.1921 +	echo "Probably ISO image will be unusable."
  5.1922 +}
  5.1923 +
  5.1924 +
  5.1925 +
  5.1926 +
  5.1927  ####################
  5.1928  # Tazlito commands #
  5.1929  ####################
  5.1930  
  5.1931 +# /usr/bin/tazlito is linked with /usr/bin/reduplicate and /usr/bin/deduplicate
  5.1932  case "$0" in
  5.1933  	*reduplicate)
  5.1934  		find ${@:-.} ! -type d -links +1 \
  5.1935 @@ -1213,68 +1590,76 @@
  5.1936  		exit 0 ;;
  5.1937  esac
  5.1938  
  5.1939 +
  5.1940  case "$COMMAND" in
  5.1941  	stats)
  5.1942  		# Tazlito general statistics from the config file.
  5.1943  		#
  5.1944 -		newline
  5.1945 -		boldify "Tazlito statistics"
  5.1946 -		separator
  5.1947 -		echo "\
  5.1948 -Config file         : $CONFIG_FILE
  5.1949 -ISO name            : $ISO_NAME.iso
  5.1950 -Volume name         : $VOLUM_NAME
  5.1951 -Prepared            : $PREPARED
  5.1952 -Packages repository : $PACKAGES_REPOSITORY
  5.1953 -Distro directory    : $DISTRO"
  5.1954 -		if [ ! "$ADDFILES" = "" ] ; then
  5.1955 -			echo -e "Additional files    : $ADDFILES"
  5.1956 -		fi
  5.1957 -		separator && newline ;;
  5.1958 -	
  5.1959 +		title 'Tazlito statistics'
  5.1960 +		optlist "\
  5.1961 +Config file			: $CONFIG_FILE
  5.1962 +ISO name			: $ISO_NAME.iso
  5.1963 +Volume name			: $VOLUM_NAME
  5.1964 +Prepared			: $PREPARED
  5.1965 +Packages repository	: $PACKAGES_REPOSITORY
  5.1966 +Distro directory	: $DISTRO
  5.1967 +Additional files	: $ADDFILES
  5.1968 +" | sed '/: $/d'
  5.1969 +		footer
  5.1970 +		;;
  5.1971 +
  5.1972 +
  5.1973  	list-addfiles)
  5.1974  		# Simple list of additional files in the rootfs
  5.1975  		newline
  5.1976 -		cd $ADDFILES
  5.1977 -		find rootfs -type f
  5.1978 -		newline ;;
  5.1979 -	
  5.1980 +		if [ -d "$ADDFILES/rootfs" ]; then
  5.1981 +			cd $ADDFILES
  5.1982 +			find rootfs -type f
  5.1983 +		else
  5.1984 +			_ 'Additional files not found: %s' "$ADDFILES/rootfs/"
  5.1985 +		fi
  5.1986 +		newline
  5.1987 +		;;
  5.1988 +
  5.1989 +
  5.1990  	gen-config)
  5.1991  		# Generate a new config file in the current dir or the specified
  5.1992  		# directory by $2.
  5.1993  		#
  5.1994 -		if [ -n "$2" ] ; then
  5.1995 -			mkdir -p $2 && cd $2
  5.1996 +		if [ -n "$2" ]; then
  5.1997 +			mkdir -p "$2" && cd "$2"
  5.1998  		fi
  5.1999 -		echo -n "Generating empty tazlito.conf..."
  5.2000 +
  5.2001 +		newline
  5.2002 +		action 'Generating empty tazlito.conf...'
  5.2003  		empty_config_file
  5.2004  		status
  5.2005 -		newline
  5.2006 -		if [ -f "tazlito.conf" ] ; then
  5.2007 -			echo "Configuration file is ready to edit."
  5.2008 -			echo "File location : `pwd`/tazlito.conf"
  5.2009 +
  5.2010 +		separator
  5.2011 +		if [ -f 'tazlito.conf' ] ; then
  5.2012 +			_ 'Configuration file is ready to edit.'
  5.2013 +			_ 'File location: %s' "$(pwd)/tazlito.conf"
  5.2014  			newline
  5.2015 -		fi ;;
  5.2016 -	
  5.2017 +		fi
  5.2018 +		;;
  5.2019 +
  5.2020 +
  5.2021  	configure)
  5.2022  		# Configure a tazlito.conf config file. Start by getting
  5.2023  		# a empty config file and sed it.
  5.2024  		#
  5.2025 -		if [ -f "tazlito.conf" ] ; then
  5.2026 +		if [ -f 'tazlito.conf' ]; then
  5.2027  			rm tazlito.conf
  5.2028  		else
  5.2029 -			if test $(id -u) = 0 ; then
  5.2030 -				cd /etc
  5.2031 -			else
  5.2032 -				echo "You must be root to configure the main config file or in"
  5.2033 -				echo "the same directory of the file you want to configure."
  5.2034 -				exit 0
  5.2035 -			fi
  5.2036 +			[ $(id -u) -ne 0 ] && die 'You must be root to configure the main config file' \
  5.2037 +				'or in the same directory of the file you want to configure.'
  5.2038 +			cd /etc
  5.2039  		fi
  5.2040 +
  5.2041  		empty_config_file
  5.2042 -		echo""
  5.2043 -		echo -e "\033[1mConfiguring :\033[0m `pwd`/tazlito.conf"
  5.2044 -		separator
  5.2045 +
  5.2046 +		title 'Configuring: %s' "$(pwd)/tazlito.conf"
  5.2047 +
  5.2048  		# ISO name.
  5.2049  		echo -n "ISO name            : " ; read answer
  5.2050  		sed -i s#'ISO_NAME=\"\"'#"ISO_NAME=\"$answer\""# tazlito.conf
  5.2051 @@ -1287,237 +1672,233 @@
  5.2052  		# Distro path.
  5.2053  		echo -n "Distro path         : " ; read answer
  5.2054  		sed -i s#'DISTRO=\"\"'#"DISTRO=\"$answer\""# tazlito.conf
  5.2055 -		separator
  5.2056 -		echo "Config file is ready to use."
  5.2057 -		echo "You can now extract an ISO or generate a distro."
  5.2058 -		newline ;;
  5.2059 -	
  5.2060 +		footer "Config file is ready to use."
  5.2061 +		echo 'You can now extract an ISO or generate a distro.'
  5.2062 +		newline
  5.2063 +		;;
  5.2064 +
  5.2065 +
  5.2066  	gen-iso)
  5.2067  		# Simply generate a new iso.
  5.2068  		#
  5.2069  		check_root
  5.2070  		verify_rootcd
  5.2071  		gen_livecd_isolinux
  5.2072 -		distro_stats ;;
  5.2073 -	
  5.2074 +		distro_stats
  5.2075 +		;;
  5.2076 +
  5.2077 +
  5.2078  	gen-initiso)
  5.2079  		# Simply generate a new initramfs with a new iso.
  5.2080  		#
  5.2081  		check_root
  5.2082  		verify_rootcd
  5.2083 -		gen_initramfs $ROOTFS
  5.2084 +		gen_initramfs "$ROOTFS"
  5.2085  		gen_livecd_isolinux
  5.2086 -		distro_stats ;;
  5.2087 -	
  5.2088 +		distro_stats
  5.2089 +		;;
  5.2090 +
  5.2091 +
  5.2092  	extract-distro)
  5.2093  		# Extract an ISO image to a directory and rebuild the LiveCD tree.
  5.2094  		#
  5.2095  		check_root
  5.2096 -		ISO_IMAGE=$2
  5.2097 -		if [ -z "$ISO_IMAGE" ] ; then
  5.2098 -			echo -e "\nPlease specify the path to the ISO image."
  5.2099 -			echo -e "Example : `basename $0` image.iso /path/target\n"
  5.2100 -			exit 0
  5.2101 -		fi
  5.2102 +		ISO_IMAGE="$2"
  5.2103 +		[ -z "$ISO_IMAGE" ] && die 'Please specify the path to the ISO image.' \
  5.2104 +			'Example:\n  tazlito image.iso /path/target'
  5.2105 +
  5.2106  		# Set the distro path by checking for $3 on cmdline.
  5.2107 -		if [ -n "$3" ] ; then
  5.2108 -			TARGET=$3
  5.2109 -		else
  5.2110 -			TARGET=$DISTRO
  5.2111 -		fi
  5.2112 +		TARGET="${3:-$DISTRO}"
  5.2113 +
  5.2114  		# Exit if existing distro is found.
  5.2115 -		if [ -d "$TARGET/rootfs" ] ; then
  5.2116 -			echo -e "\nA rootfs exists in : $TARGET"
  5.2117 -			echo -e "Please clean the distro tree or change directory path.\n"
  5.2118 -			exit 0
  5.2119 -		fi
  5.2120 -		newline
  5.2121 -		echo -e "\033[1mTazlito extracting :\033[0m `basename $ISO_IMAGE`"
  5.2122 -		separator
  5.2123 +		[ -d "$TARGET/rootfs" ] && die "A rootfs exists in '$TARGET'." \
  5.2124 +			'Please clean the distro tree or change directory path.'
  5.2125 +
  5.2126 +		title 'Tazlito extracting: %s' "$(basename $ISO_IMAGE)"
  5.2127 +
  5.2128  		# Start to mount the ISO.
  5.2129 -		newline
  5.2130 -		echo "Mounting ISO image..."
  5.2131 -		mkdir -p $TMP_DIR
  5.2132 +		action 'Mounting ISO image...'
  5.2133 +		mkdir -p "$TMP_DIR"
  5.2134  		# Get ISO file size.
  5.2135 -		isosize=`du -sh $ISO_IMAGE | cut -f1`
  5.2136 -		mount -o loop $ISO_IMAGE $TMP_DIR
  5.2137 +		isosize=$(du -sh "$ISO_IMAGE" | cut -f1)
  5.2138 +		mount -o loop -r "$ISO_IMAGE" "$TMP_DIR"
  5.2139  		sleep 2
  5.2140  		# Prepare target dir, copy the kernel and the rootfs.
  5.2141 -		mkdir -p $TARGET/rootfs
  5.2142 -		mkdir -p $TARGET/rootcd/boot
  5.2143 -		echo -n "Copying the Linux kernel..."
  5.2144 -		if cp $TMP_DIR/boot/vmlinuz* $TARGET/rootcd/boot 2> /dev/null; then
  5.2145 -			make_bzImage_hardlink $TARGET/rootcd/boot
  5.2146 +		mkdir -p "$TARGET/rootfs" "$TARGET/rootcd/boot"
  5.2147 +		status
  5.2148 +
  5.2149 +		action 'Copying the Linux kernel...'
  5.2150 +		if cp $TMP_DIR/boot/vmlinuz* "$TARGET/rootcd/boot" 2>/dev/null; then
  5.2151 +			make_bzImage_hardlink "$TARGET/rootcd/boot"
  5.2152  		else
  5.2153 -			cp $TMP_DIR/boot/bzImage $TARGET/rootcd/boot
  5.2154 +			cp "$TMP_DIR/boot/bzImage" "$TARGET/rootcd/boot"
  5.2155  		fi
  5.2156  		status
  5.2157 -		echo -n "Copying isolinux files..."
  5.2158 -		cp -a $TMP_DIR/boot/isolinux $TARGET/rootcd/boot
  5.2159 +
  5.2160  		for i in $(ls $TMP_DIR); do
  5.2161 -			[ "$i" = "boot" ] && continue
  5.2162 -			cp -a $TMP_DIR/$i $TARGET/rootcd
  5.2163 +			[ "$i" == 'boot' ] && continue
  5.2164 +			cp -a "$TMP_DIR/$i" "$TARGET/rootcd"
  5.2165  		done
  5.2166 +
  5.2167 +		for loader in isolinux syslinux extlinux grub; do
  5.2168 +			[ -d "$TMP_DIR/boot/$loader" ] || continue
  5.2169 +			action 'Copying %s files...' "$loader"
  5.2170 +			cp -a "$TMP_DIR/boot/$loader" "$TARGET/rootcd/boot"
  5.2171 +			status
  5.2172 +		done
  5.2173 +
  5.2174 +		action 'Copying the rootfs...'
  5.2175 +		cp $TMP_DIR/boot/rootfs.?z "$TARGET/rootcd/boot"
  5.2176  		status
  5.2177 -		if [ -d $TMP_DIR/boot/syslinux ]; then
  5.2178 -			echo -n "Copying syslinux files..."
  5.2179 -			cp -a $TMP_DIR/boot/syslinux $TARGET/rootcd/boot
  5.2180 -			status
  5.2181 -		fi
  5.2182 -		if [ -d $TMP_DIR/boot/extlinux ]; then
  5.2183 -			echo -n "Copying extlinux files..."
  5.2184 -			cp -a $TMP_DIR/boot/extlinux $TARGET/rootcd/boot
  5.2185 -			status
  5.2186 -		fi
  5.2187 -		if [ -d $TMP_DIR/boot/grub ]; then
  5.2188 -			echo -n "Copying GRUB files..."
  5.2189 -			cp -a $TMP_DIR/boot/grub $TARGET/rootcd/boot
  5.2190 -			status
  5.2191 -		fi
  5.2192 -
  5.2193 -		echo -n "Copying the rootfs..."
  5.2194 -		cp $TMP_DIR/boot/rootfs.?z $TARGET/rootcd/boot
  5.2195 -		status
  5.2196 +
  5.2197  		# Extract initramfs.
  5.2198 -		cd $TARGET/rootfs
  5.2199 -		echo -n "Extracting the rootfs... "
  5.2200 -		extract_rootfs ../rootcd/boot/rootfs.gz $TARGET/rootfs
  5.2201 +		cd "$TARGET/rootfs"
  5.2202 +		action 'Extracting the rootfs...'
  5.2203 +		extract_rootfs "$TARGET/rootcd/boot/$INITRAMFS" "$TARGET/rootfs"
  5.2204  		# unpack /usr
  5.2205  		for i in etc/tazlito/*.extract; do
  5.2206  			[ -f "$i" ] && . $i ../rootcd
  5.2207  		done
  5.2208  		# Umount and remove temp directory and cd to $TARGET to get stats.
  5.2209 -		umount $TMP_DIR && rm -rf $TMP_DIR
  5.2210 +		umount "$TMP_DIR" && rm -rf "$TMP_DIR"
  5.2211  		cd ..
  5.2212 +		status
  5.2213 +
  5.2214  		newline
  5.2215  		separator
  5.2216 -		echo "Extracted       : `basename $ISO_IMAGE` ($isosize)"
  5.2217 -		echo "Distro tree     : `pwd`"
  5.2218 -		echo "Rootfs size     : `du -sh rootfs`"
  5.2219 -		echo "Rootcd size     : `du -sh rootcd`"
  5.2220 -		separator
  5.2221 -		newline ;;
  5.2222 -	
  5.2223 +		echo "Extracted       : $(basename $ISO_IMAGE) ($isosize)"
  5.2224 +		echo "Distro tree     : $(pwd)"
  5.2225 +		echo "Rootfs size     : $(du -sh rootfs)"
  5.2226 +		echo "Rootcd size     : $(du -sh rootcd)"
  5.2227 +		footer
  5.2228 +		;;
  5.2229 +
  5.2230 +
  5.2231  	list-flavors)
  5.2232  		# Show available flavors.
  5.2233 -		if [ ! -s /etc/tazlito/flavors.list -o "$2" == "--recharge" ]; then
  5.2234 -			download flavors.list -O - > /etc/tazlito/flavors.list
  5.2235 -		fi
  5.2236 -		newline
  5.2237 -		boldify "List of flavors"
  5.2238 -		separator
  5.2239 -		cat /etc/tazlito/flavors.list
  5.2240 -		newline ;;
  5.2241 -		
  5.2242 +		local list='/etc/tazlito/flavors.list'
  5.2243 +		[ ! -s $list -o -n "$recharge" ] && download flavors.list -O - > $list
  5.2244 +		title 'List of flavors'
  5.2245 +		cat $list
  5.2246 +		footer
  5.2247 +		;;
  5.2248 +
  5.2249 +
  5.2250  	show-flavor)
  5.2251  		# Show flavor description.
  5.2252 -		FLAVOR=${2%.flavor}
  5.2253 -		if [ ! -f "$FLAVOR.flavor" ]; then
  5.2254 -			echo "File $FLAVOR.flavor not found."
  5.2255 -			exit 1
  5.2256 -		fi
  5.2257 -		mkdir $TMP_DIR
  5.2258 -		zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i > /dev/null)
  5.2259 -		if [ "$3" = "--brief" ]; then
  5.2260 -			if [ "$4" != "--noheader" ]; then
  5.2261 -				echo "Name              ISO   Rootfs  Description"
  5.2262 +		set -e
  5.2263 +		flavor=${2%.flavor}
  5.2264 +		flv_dir="$(extract_flavor "$flavor")"
  5.2265 +		desc="$flv_dir/$flavor.desc"
  5.2266 +		if [ -n "$brief" ]; then
  5.2267 +			if [ -z "$noheader" ]; then
  5.2268 +				printf "%-16.16s %6.6s %6.6s %s\n" 'Name' 'ISO' 'Rootfs' 'Description'
  5.2269  				separator
  5.2270  			fi
  5.2271 -			printf "%-16.16s %6.6s %6.6s %s\n" "$FLAVOR" \
  5.2272 -				"$(field ISO $TMP_DIR/$FLAVOR.desc)" \
  5.2273 -				"$(field 'Rootfs size' $TMP_DIR/$FLAVOR.desc)" \
  5.2274 -				"$(grep ^Description $TMP_DIR/$FLAVOR.desc | cut -d: -f2)"
  5.2275 +			printf "%-16.16s %6.6s %6.6s %s\n" "$flavor" \
  5.2276 +				"$(field ISO         "$desc")" \
  5.2277 +				"$(field Rootfs      "$desc")" \
  5.2278 +				"$(field Description "$desc")"
  5.2279  		else
  5.2280  			separator
  5.2281 -			cat $TMP_DIR/$FLAVOR.desc
  5.2282 +			cat "$desc"
  5.2283  		fi
  5.2284 -		rm -Rf $TMP_DIR ;;
  5.2285 -		
  5.2286 +		cleanup
  5.2287 +		;;
  5.2288 +
  5.2289 +
  5.2290  	gen-liveflavor)
  5.2291  		# Generate a new flavor from the live system.
  5.2292  		FLAVOR=${2%.flavor}
  5.2293 -		DESC=""
  5.2294 +		[ -z "$FLAVOR" ] && die 'Please specify flavor name on the commandline.'
  5.2295 +
  5.2296  		case "$FLAVOR" in
  5.2297 -		'')	echo -n "Flavor name : "
  5.2298 -			read FLAVOR
  5.2299 -			[ -z "$FLAVOR" ] && exit 1;;
  5.2300 -		-?|-h*|--help) echo -e "
  5.2301 -
  5.2302 +			-?|-h*|--help)
  5.2303 +				cat <<EOT
  5.2304  SliTaz Live Tool - Version: $VERSION
  5.2305 -\033[1mUsage: \033[0m `basename $0` gen-liveflavor flavor-name [flavor-patch-file]
  5.2306 -\033[1mflavor-patch-file format: \033[0m
  5.2307 +
  5.2308 +$(boldify 'Usage:') tazlito gen-liveflavor <flavor-name> [<flavor-patch-file>]
  5.2309 +
  5.2310 +$(boldify '<flavor-patch-file> format:')
  5.2311 +$(optlist "\
  5.2312  code	data
  5.2313  +	package to add
  5.2314  -	package to remove
  5.2315  !	non-free package to add
  5.2316  ?	display message
  5.2317  @	flavor description
  5.2318 -
  5.2319 -\033[1mExample: \033[0m
  5.2320 -@	Developer tools for slitaz maintainers
  5.2321 +")
  5.2322 +
  5.2323 +$(boldify 'Example:')
  5.2324 +$(optlist "\
  5.2325 +@	Developer tools for SliTaz maintainers
  5.2326  +	slitaz-toolchain
  5.2327  +	mercurial
  5.2328 -"
  5.2329 -			exit 1;;
  5.2330 +")
  5.2331 +EOT
  5.2332 +				exit 1
  5.2333 +				;;
  5.2334  		esac
  5.2335  		mv /etc/tazlito/distro-packages.list \
  5.2336 -		   /etc/tazlito/distro-packages.list.$$ 2> /dev/null
  5.2337 -		rm -f distro-packages.list non-free.list 2> /dev/null
  5.2338 +		   /etc/tazlito/distro-packages.list.$$ 2>/dev/null
  5.2339 +		rm -f distro-packages.list non-free.list 2>/dev/null
  5.2340  		tazpkg recharge
  5.2341 -		[ -n "$3" ] && while read action pkg; do
  5.2342 +
  5.2343 +		DESC=""
  5.2344 +		[ -n "$3" ] && \
  5.2345 +		while read action pkg; do
  5.2346  			case "$action" in
  5.2347 -			+)	yes | tazpkg get-install $pkg 2>&1 >> $log || exit 1 ;;
  5.2348 -			-)	yes | tazpkg remove $pkg ;;
  5.2349 -			!)	echo $pkg >> non-free.list ;;
  5.2350 -			@)	DESC="$pkg" ;;
  5.2351 -			\?)	echo -en "$pkg"; read action ;;
  5.2352 +				+)	yes | tazpkg get-install $pkg 2>&1 >> $log || exit 1 ;;
  5.2353 +				-)	yes | tazpkg remove $pkg ;;
  5.2354 +				!)	echo $pkg >> non-free.list ;;
  5.2355 +				@)	DESC="$pkg" ;;
  5.2356 +				\?)	echo -en "$pkg"; read action ;;
  5.2357  			esac
  5.2358  		done < $3
  5.2359 +
  5.2360  		yes '' | tazlito gen-distro
  5.2361  		echo "$DESC" | tazlito gen-flavor "$FLAVOR"
  5.2362  		mv /etc/tazlito/distro-packages.list.$$ \
  5.2363 -		   /etc/tazlito/distro-packages.list 2> /dev/null ;;
  5.2364 -		
  5.2365 +		   /etc/tazlito/distro-packages.list 2>/dev/null
  5.2366 +		;;
  5.2367 +
  5.2368 +
  5.2369  	gen-flavor)
  5.2370 -		# Generate a new flavor from the last iso image generated.
  5.2371 +		# Generate a new flavor from the last ISO image generated
  5.2372  		FLAVOR=${2%.flavor}
  5.2373 -		newline
  5.2374 -		boldify "Flavor generation"
  5.2375 -		separator
  5.2376 -		if [ -z "$FLAVOR" ]; then
  5.2377 -			echo -n "Flavor name : "
  5.2378 -			read FLAVOR
  5.2379 -			[ -z "$FLAVOR" ] && exit 1
  5.2380 -		fi
  5.2381 +		[ -z "$FLAVOR" ] && die 'Please specify flavor name on the commandline.'
  5.2382 +
  5.2383 +		title 'Flavor generation'
  5.2384  		check_rootfs
  5.2385  		FILES="$FLAVOR.pkglist"
  5.2386 -		echo -n "Creating file $FLAVOR.flavor..."
  5.2387 +
  5.2388 +		action 'Creating file %s...' "$FLAVOR.flavor"
  5.2389  		for i in rootcd rootfs; do
  5.2390  			if [ -d "$ADDFILES/$i" ] ; then
  5.2391  				FILES="$FILES\n$FLAVOR.$i"
  5.2392 -				( cd "$ADDFILES/$i"; find . | \
  5.2393 -				  cpio -o -H newc 2> /dev/null | gzip -9 ) > $FLAVOR.$i
  5.2394 +				(cd "$ADDFILES/$i"; find . | cpio -o -H newc 2>/dev/null | gzip -9) > $FLAVOR.$i
  5.2395  			fi
  5.2396  		done
  5.2397  		status
  5.2398 -		answer=`grep -s ^Description $FLAVOR.desc`
  5.2399 +
  5.2400 +		answer=$(grep -s ^Description $FLAVOR.desc)
  5.2401  		answer=${answer#Description     : }
  5.2402  		if [ -z "$answer" ]; then
  5.2403 -			echo -n "Description : "
  5.2404 +			echo -n "Description: "
  5.2405  			read answer
  5.2406  		fi
  5.2407 -		echo -n "Compressing flavor $FLAVOR..."
  5.2408 -		echo "Flavor          : $FLAVOR" > $FLAVOR.desc
  5.2409 +
  5.2410 +		action 'Compressing flavor %s...' "$FLAVOR"
  5.2411 +		echo "Flavor          : $FLAVOR"  > $FLAVOR.desc
  5.2412  		echo "Description     : $answer" >> $FLAVOR.desc
  5.2413 -		( cd $DISTRO; distro_sizes) >> $FLAVOR.desc
  5.2414 -		\rm -f $FLAVOR.pkglist $FLAVOR.nonfree 2> /dev/null
  5.2415 +		(cd $DISTRO; distro_sizes) >> $FLAVOR.desc
  5.2416 +		\rm -f $FLAVOR.pkglist $FLAVOR.nonfree 2>/dev/null
  5.2417  		for i in $(ls $ROOTFS$INSTALLED); do
  5.2418  			eval $(grep ^VERSION= $ROOTFS$INSTALLED/$i/receipt)
  5.2419  			EXTRAVERSION=""
  5.2420  			eval $(grep ^EXTRAVERSION= $ROOTFS$INSTALLED/$i/receipt)
  5.2421  			eval $(grep ^CATEGORY= $ROOTFS$INSTALLED/$i/receipt)
  5.2422 -			if [ "$CATEGORY" = "non-free" -a "${i%%-*}" != "get" ]
  5.2423 -			then
  5.2424 +			if [ "$CATEGORY" == 'non-free' -a "${i%%-*}" != 'get' ]; then
  5.2425  				echo "$i" >> $FLAVOR.nonfree
  5.2426  			else
  5.2427  				echo "$i-$VERSION$EXTRAVERSION" >> $FLAVOR.pkglist
  5.2428 @@ -1528,346 +1909,234 @@
  5.2429  			[ -s $i ] && cat $i >> $FLAVOR.mirrors
  5.2430  		done
  5.2431  		[ -s $FLAVOR.mirrors ] && $FILES="$FILES\n$FLAVOR.mirrors"
  5.2432 -		echo -e "$FLAVOR.desc\n$FILES" | cpio -o -H newc 2>/dev/null | \
  5.2433 -			gzip -9 > $FLAVOR.flavor
  5.2434 -		rm `echo -e $FILES`
  5.2435 +		echo -e "$FLAVOR.desc\n$FILES" | cpio -o -H newc 2>/dev/null | gzip -9 > $FLAVOR.flavor
  5.2436 +		rm $(echo -e $FILES)
  5.2437  		status
  5.2438 -		separator
  5.2439 -		echo "Flavor size : `du -sh $FLAVOR.flavor`"
  5.2440 -		newline ;;
  5.2441 -		
  5.2442 +
  5.2443 +		footer "Flavor size: $(du -sh $FLAVOR.flavor)"
  5.2444 +		;;
  5.2445 +
  5.2446 +
  5.2447  	upgrade-flavor)
  5.2448 -		# Update package list to the latest versions available.
  5.2449 -		[ -s /home/slitaz/packages/packages.list -a -z $systemrepos ] && \
  5.2450 -			LOCALSTATE='/home/slitaz/packages'
  5.2451 -		FLAVOR=${2%.flavor}
  5.2452 -		if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
  5.2453 -			mkdir $TMP_DIR
  5.2454 -			zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i >/dev/null )
  5.2455 -			echo -n "Updating $FLAVOR package list..."
  5.2456 -			[ -s $LOCALSTATE/packages.list ] || tazpkg recharge
  5.2457 -			packed_size=0; unpacked_size=0
  5.2458 -			while read org; do
  5.2459 -				i=0
  5.2460 -				pkg=$org
  5.2461 -				while ! grep -q ^$pkg$ $LOCALSTATE/packages.txt; do
  5.2462 -					pkg=${pkg%-*}
  5.2463 -					i=$(($i + 1))
  5.2464 -					[ $i -gt 5 ] && break;
  5.2465 -				done
  5.2466 -				set -- $(get_size $pkg)
  5.2467 -				packed_size=$(( $packed_size + $1 ))
  5.2468 -				unpacked_size=$(( $unpacked_size + $2 ))
  5.2469 -				for i in $(grep ^$pkg $LOCALSTATE/packages.list); do
  5.2470 -					echo $i
  5.2471 -					break
  5.2472 -				done
  5.2473 -			done <  $TMP_DIR/$FLAVOR.pkglist \
  5.2474 -			     > $TMP_DIR/$FLAVOR.pkglist.$$
  5.2475 -			mv -f $TMP_DIR/$FLAVOR.pkglist.$$ $TMP_DIR/$FLAVOR.pkglist
  5.2476 -			if [ -s $TMP_DIR/$FLAVOR.rootfs ]; then
  5.2477 -				packed_size=$(($packed_size \
  5.2478 -					+ $(wc -c < $TMP_DIR/$FLAVOR.rootfs) / 100 ))
  5.2479 -				unpacked_size=$(($unpacked_size \
  5.2480 -					+ $(zcat < $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
  5.2481 -			fi
  5.2482 -			# Estimate lzma
  5.2483 -			packed_size=$(($packed_size * 2 / 3))
  5.2484 -			iso_size=$(( $packed_size + 26000 ))
  5.2485 -			if [ -s $TMP_DIR/$FLAVOR.rootcd ]; then
  5.2486 -				iso_size=$(($iso_size \
  5.2487 -					+ $(zcat < $TMP_DIR/$FLAVOR.rootcd | wc -c ) / 100 ))
  5.2488 -			fi
  5.2489 -			sed -i -e '/Image is ready/d' \
  5.2490 -			       -e "s/Rootfs size\( *:\) \(.*\)/Rootfs size\1 $(cent2human $unpacked_size)  (estimated)/" \
  5.2491 -			       -e "s/Initramfs size\( *:\) \(.*\)/Initramfs size\1 $(cent2human $packed_size)  (estimated)/" \
  5.2492 -			       -e "s/ISO image size\( *:\) \(.*\)/ISO image size\1 $(cent2human $iso_size)  (estimated)/" \
  5.2493 -			       -e "s/date\( *:\) \(.*\)/date\1 $(date +%Y%m%d\ \at\ \%H:%M:%S)/" \
  5.2494 -					$TMP_DIR/$FLAVOR.desc
  5.2495 -			( cd $TMP_DIR ; ls | cpio -o -H newc ) | gzip -9 > \
  5.2496 -				$FLAVOR.flavor
  5.2497 -			status
  5.2498 -			rm -Rf $TMP_DIR
  5.2499 -		fi ;;
  5.2500 -	
  5.2501 +		# Strip versions from pkglist and update estimated numbers in flavor.desc
  5.2502 +		flavor="${2%.flavor}"
  5.2503 +		set -e
  5.2504 +		[ -f "$flavor.flavor" ] || download "$flavor.flavor"
  5.2505 +		set +e
  5.2506 +
  5.2507 +		flv_dir="$(extract_flavor "$flavor")"
  5.2508 +
  5.2509 +		strip_versions "$flv_dir/$flavor.pkglist"
  5.2510 +
  5.2511 +		action 'Updating %s...' "$flavor.desc"
  5.2512 +
  5.2513 +		[ -f "$flv_dir/$flavor.mirrors" ] && setup_mirrors "$flv_dir/$flavor.mirrors" >/dev/null
  5.2514 +		set -- $(calc_sizes "$flv_dir" "$flavor")
  5.2515 +		restore_mirrors >/dev/null
  5.2516 +
  5.2517 +		sed -i -e '/Image is ready/d' \
  5.2518 +		       -e "s|\(Rootfs size *:\).*$|\1 $1  (estimated)|" \
  5.2519 +		       -e "s|\(Initramfs size *:\).*$|\1 $2  (estimated)|" \
  5.2520 +		       -e "s|\(ISO image size *:\).*$|\1 $3  (estimated)|" \
  5.2521 +		       -e "s|\(Packages *:\).*$|\1 $4|" \
  5.2522 +		       -e "s|\(Build date *:\).*$|\1 $(date '+%Y%m%d at %T')|" \
  5.2523 +				"$flv_dir/$flavor.desc"
  5.2524 +
  5.2525 +		pack_flavor "$flv_dir" "$flavor"
  5.2526 +		status
  5.2527 +		display_unknown "$flv_dir/err"
  5.2528 +		display_warn    "$flv_dir/warn"
  5.2529 +		cleanup
  5.2530 +		;;
  5.2531 +
  5.2532 +
  5.2533  	extract-flavor)
  5.2534 -		# Extract a flavor into $FLAVORS_REPOSITORY.
  5.2535 -		FLAVOR=${2%.flavor}
  5.2536 -		if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
  5.2537 -			mkdir $TMP_DIR
  5.2538 -			zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i >/dev/null )
  5.2539 -			echo -n "Extracting $FLAVOR..."
  5.2540 -			rm -rf $FLAVORS_REPOSITORY/$FLAVOR 2> /dev/null
  5.2541 -			mkdir -p $FLAVORS_REPOSITORY/$FLAVOR
  5.2542 -			cp $TMP_DIR/$FLAVOR.receipt $FLAVORS_REPOSITORY/$FLAVOR/receipt
  5.2543 -			#~ echo "FLAVOR=\"$FLAVOR\"" > $FLAVORS_REPOSITORY/$FLAVOR/receipt
  5.2544 -			#~ grep ^Description $TMP_DIR/$FLAVOR.desc | \
  5.2545 -				#~ sed 's/.*: \(.*\)$/SHORT_DESC="\1"/' >> \
  5.2546 -				#~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
  5.2547 -			#~ grep ^Version $TMP_DIR/$FLAVOR.desc | \
  5.2548 -				#~ sed 's/.*: \(.*\)$/VERSION="\1"/' >> \
  5.2549 -				#~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
  5.2550 -			#~ grep ^Maintainer $TMP_DIR/$FLAVOR.desc | \
  5.2551 -				#~ sed 's/.*: \(.*\)$/MAINTAINER="\1"/' >> \
  5.2552 -				#~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
  5.2553 -			#~ grep -q '^Rootfs list' $TMP_DIR/$FLAVOR.desc && \
  5.2554 -			#~ grep '^Rootfs list' $TMP_DIR/$FLAVOR.desc | \
  5.2555 -				#~ sed 's/.*: \(.*\)$/ROOTFS_SELECTION="\1"/' >> \
  5.2556 -				#~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
  5.2557 -			#~ grep '^Rootfs size' $TMP_DIR/$FLAVOR.desc | \
  5.2558 -				#~ sed 's/.*: \(.*\)$/ROOTFS_SIZE="\1"/' >> \
  5.2559 -				#~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
  5.2560 -			#~ grep ^Initramfs $TMP_DIR/$FLAVOR.desc | \
  5.2561 -				#~ sed 's/.*: \(.*\)$/INITRAMFS_SIZE="\1"/' >> \
  5.2562 -				#~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
  5.2563 -			#~ grep ^ISO $TMP_DIR/$FLAVOR.desc | \
  5.2564 -				#~ sed 's/.*: \(.*\)$/ISO_SIZE="\1"/' >> \
  5.2565 -				#~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
  5.2566 -			for i in rootcd rootfs; do
  5.2567 -				[ -f $TMP_DIR/$FLAVOR.$i ] || continue
  5.2568 -				mkdir $FLAVORS_REPOSITORY/$FLAVOR/$i
  5.2569 -				zcat < $TMP_DIR/$FLAVOR.$i | \
  5.2570 -				  (cd $FLAVORS_REPOSITORY/$FLAVOR/$i; \
  5.2571 -				   cpio -idm > /dev/null)
  5.2572 -			done
  5.2573 -			[ -s $TMP_DIR/$FLAVOR.mirrors ] &&
  5.2574 -				cp $TMP_DIR/$FLAVOR.mirrors \
  5.2575 -					$FLAVORS_REPOSITORY/$FLAVOR/mirrors
  5.2576 -			[ -s $LOCALSTATE/packages.list ] || tazpkg recharge
  5.2577 -			while read org; do
  5.2578 -				i=0
  5.2579 -				pkg=$org
  5.2580 -				while ! grep -q ^$pkg$ $LOCALSTATE/packages.txt; do
  5.2581 -					pkg=${pkg%-*}
  5.2582 -					i=$(($i + 1))
  5.2583 -					[ $i -gt 5 ] && break;
  5.2584 -				done
  5.2585 -				echo $pkg
  5.2586 -			done <  $TMP_DIR/$FLAVOR.pkglist \
  5.2587 -			     > $FLAVORS_REPOSITORY/$FLAVOR/packages.list
  5.2588 -			status
  5.2589 -			rm -Rf $TMP_DIR
  5.2590 -		fi ;;
  5.2591 -	
  5.2592 +		# Extract a flavor into $FLAVORS_REPOSITORY
  5.2593 +		flavor="${2%.flavor}"
  5.2594 +		set -e
  5.2595 +		[ -f "$flavor.flavor" ] || download "$flavor.flavor"
  5.2596 +		set +e
  5.2597 +
  5.2598 +		action 'Extracting %s...' "$flavor.flavor"
  5.2599 +		flv_dir="$(extract_flavor "$flavor" full)"
  5.2600 +		storage="$FLAVORS_REPOSITORY/$flavor"
  5.2601 +
  5.2602 +		rm    -rf "$storage" 2>/dev/null
  5.2603 +		mkdir -p  "$storage"
  5.2604 +		cp -a "$flv_dir"/* "$storage"
  5.2605 +		rm "$storage/description"
  5.2606 +		status
  5.2607 +
  5.2608 +		strip_versions "$storage/packages.list"
  5.2609 +
  5.2610 +		cleanup
  5.2611 +		;;
  5.2612 +
  5.2613 +
  5.2614  	pack-flavor)
  5.2615  		# Create a flavor from $FLAVORS_REPOSITORY.
  5.2616 -		FLAVOR=${2%.flavor}
  5.2617 -		if [ -s $FLAVORS_REPOSITORY/$FLAVOR/receipt ]; then
  5.2618 -			mkdir $TMP_DIR
  5.2619 -			echo -n "Creating flavor $FLAVOR..."
  5.2620 -
  5.2621 -			# Use latest local packages if possible (don't download from unsynced mirror)
  5.2622 -			[ -s /home/slitaz/packages/packages.list -a -z $systemrepos ] && \
  5.2623 -			LOCALSTATE='/home/slitaz/packages'
  5.2624 -
  5.2625 -			[ -s $LOCALSTATE/packages.list ] || tazpkg recharge
  5.2626 -			if [ -s $FLAVORS_REPOSITORY/$FLAVOR/mirrors ]; then
  5.2627 -				cp $FLAVORS_REPOSITORY/$FLAVOR/mirrors \
  5.2628 -					$TMP_DIR/$FLAVOR.mirrors
  5.2629 -				for i in $(cat $TMP_DIR/$FLAVOR.mirrors); do
  5.2630 -					wget -O - $i/packages.list >> $TMP_DIR/packages.list
  5.2631 -				done
  5.2632 +		flavor=${2%.flavor}
  5.2633 +		storage="$FLAVORS_REPOSITORY/$flavor"
  5.2634 +
  5.2635 +		[ -s "$storage/receipt" ] || die "No $flavor receipt in $FLAVORS_REPOSITORY."
  5.2636 +
  5.2637 +		action 'Creating flavor %s...' "$flavor"
  5.2638 +		tmp_dir="$(mktemp -d)"
  5.2639 +
  5.2640 +		while read from to; do
  5.2641 +			[  -s "$storage/$from" ] || continue
  5.2642 +			cp -a "$storage/$from" "$tmp_dir/$to"
  5.2643 +		done <<EOT
  5.2644 +mirrors        $flavor.mirrors
  5.2645 +distro.sh      $flavor-distro.sh
  5.2646 +receipt        $flavor.receipt
  5.2647 +non-free.list  $flavor.nonfree
  5.2648 +EOT
  5.2649 +
  5.2650 +		# Build the package list.
  5.2651 +		# It can include a list from another flavor with the keyword @include
  5.2652 +		if [ -s "$storage/packages.list" ]; then
  5.2653 +			include=$(grep '^@include' "$storage/packages.list")
  5.2654 +			if [ -n "$include" ]; then
  5.2655 +				include=${include#@include }
  5.2656 +				if [   -s "$FLAVORS_REPOSITORY/$include/packages.list" ]; then
  5.2657 +					cp -f "$FLAVORS_REPOSITORY/$include/packages.list" "$tmp_dir/$flavor.pkglist"
  5.2658 +				else
  5.2659 +					echo -e "\nERROR: Can't find include package list from $include\n"
  5.2660 +				fi
  5.2661  			fi
  5.2662 -			# add distro.sh if exists
  5.2663 -			if [ -s $FLAVORS_REPOSITORY/$FLAVOR/distro.sh ]; then
  5.2664 -				cp $FLAVORS_REPOSITORY/$FLAVOR/distro.sh $TMP_DIR/$FLAVOR-distro.sh
  5.2665 -			fi
  5.2666 -			
  5.2667 -			# Get receipt in .flavor
  5.2668 -			if [ -s $FLAVORS_REPOSITORY/$FLAVOR/receipt ]; then
  5.2669 -				cp $FLAVORS_REPOSITORY/$FLAVOR/receipt $TMP_DIR/$FLAVOR.receipt
  5.2670 -			fi
  5.2671 -
  5.2672 -			# Build the package list.
  5.2673 -			#
  5.2674 -			# On peut inclure une liste venant d'une autre saveur avec le mot clé @include
  5.2675 -			if [ -s $FLAVORS_REPOSITORY/$FLAVOR/packages.list ]; then
  5.2676 -				INCLUDE=$(grep '^@include' $FLAVORS_REPOSITORY/$FLAVOR/packages.list)
  5.2677 -				if [ ! -z "$INCLUDE" ]; then
  5.2678 -					INCLUDE=${INCLUDE#@include }
  5.2679 -					[ -s "$FLAVORS_REPOSITORY/$INCLUDE/packages.list" ] && \
  5.2680 -						get_pkglist $INCLUDE > $TMP_DIR/$FLAVOR.pkglist || \
  5.2681 -						echo -e "\nERROR: Can't find include package list from $INCLUDE\n"
  5.2682 -				fi
  5.2683 -				# Generate the final/initial package list 
  5.2684 -				[ -s $FLAVORS_REPOSITORY/$FLAVOR/packages.list ] && \
  5.2685 -					get_pkglist $FLAVOR >> $TMP_DIR/$FLAVOR.pkglist
  5.2686 -			fi
  5.2687 -			if grep -q ^ROOTFS_SELECTION \
  5.2688 -				$FLAVORS_REPOSITORY/$FLAVOR/receipt; then
  5.2689 -				. $FLAVORS_REPOSITORY/$FLAVOR/receipt
  5.2690 -				set -- $ROOTFS_SELECTION
  5.2691 -				[ -n "$FRUGAL_RAM" ] || FRUGAL_RAM=$1
  5.2692 -				[ -f $FLAVORS_REPOSITORY/$2/packages.list ] ||
  5.2693 -					tazlito extract-flavor $2
  5.2694 -				get_pkglist $2 > $TMP_DIR/$FLAVOR.pkglist
  5.2695 -				for i in rootcd rootfs; do
  5.2696 -					mkdir $TMP_DIR/$i
  5.2697 -					# Copy extra files from the first flavor
  5.2698 -					[ -d $FLAVORS_REPOSITORY/$2/$i ] &&
  5.2699 -					cp -a $FLAVORS_REPOSITORY/$2/$i $TMP_DIR
  5.2700 -					# Overload extra files by meta flavor
  5.2701 -					[ -d $FLAVORS_REPOSITORY/$FLAVOR/$i ] &&
  5.2702 -					cp -a $FLAVORS_REPOSITORY/$FLAVOR/$i $TMP_DIR
  5.2703 -					[ -n "$(ls $TMP_DIR/$i)" ] &&
  5.2704 -					( cd $TMP_DIR/$i ; find . | cpio -o -H newc 2> /dev/null ) | \
  5.2705 -					gzip -9 >$TMP_DIR/$FLAVOR.$i
  5.2706 -					rm -rf $TMP_DIR/$i
  5.2707 -				done
  5.2708 -			else
  5.2709 -				for i in rootcd rootfs; do
  5.2710 -					[ -d $FLAVORS_REPOSITORY/$FLAVOR/$i ] || \
  5.2711 -						continue
  5.2712 -					( cd $FLAVORS_REPOSITORY/$FLAVOR/$i ; \
  5.2713 -					find . | cpio -o -H newc 2> /dev/null ) | \
  5.2714 -					gzip -9 >$TMP_DIR/$FLAVOR.$i
  5.2715 -				done
  5.2716 -			fi
  5.2717 -			if [ -s $TMP_DIR/$FLAVOR.rootfs ]; then
  5.2718 -				packed_size=$(($packed_size \
  5.2719 -					+ $(wc -c < $TMP_DIR/$FLAVOR.rootfs) / 100 ))
  5.2720 -				unpacked_size=$(($unpacked_size \
  5.2721 -					+ $(zcat < $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
  5.2722 -			fi
  5.2723 -			# Estimate lzma
  5.2724 -			packed_size=$(($packed_size * 2 / 3))
  5.2725 -			iso_size=$(( $packed_size + 26000 ))
  5.2726 -			if [ -s $TMP_DIR/$FLAVOR.rootcd ]; then
  5.2727 -				iso_size=$(($iso_size \
  5.2728 -					+ $(zcat < $TMP_DIR/$FLAVOR.rootcd | wc -c ) / 100 ))
  5.2729 -			fi
  5.2730 -			VERSION=""
  5.2731 -			MAINTAINER=""
  5.2732 -			ROOTFS_SELECTION=""
  5.2733 -			ROOTFS_SIZE="$(cent2human $unpacked_size) (estimated)"
  5.2734 -			INITRAMFS_SIZE="$(cent2human $packed_size) (estimated)"
  5.2735 -			ISO_SIZE="$(cent2human $iso_size) (estimated)"
  5.2736 -			. $FLAVORS_REPOSITORY/$FLAVOR/receipt
  5.2737 -			cat > $TMP_DIR/$FLAVOR.desc <<EOT
  5.2738 +			# Generate the final/initial package list
  5.2739 +			[ -s "$storage/packages.list" ] && \
  5.2740 +				cat "$storage/packages.list" >> "$tmp_dir/$flavor.pkglist"
  5.2741 +			sed -i '/@include/d' "$tmp_dir/$flavor.pkglist"
  5.2742 +		fi
  5.2743 +
  5.2744 +		if grep -q ^ROOTFS_SELECTION "$storage/receipt"; then
  5.2745 +			# Process multi-rootfs flavor
  5.2746 +			. "$storage/receipt"
  5.2747 +			set -- $ROOTFS_SELECTION
  5.2748 +			[ -n "$FRUGAL_RAM" ] || FRUGAL_RAM=$1
  5.2749 +			[ -f "$FLAVORS_REPOSITORY/$2/packages.list" ] || tazlito extract-flavor $2
  5.2750 +			cp "$FLAVORS_REPOSITORY/$2/packages.list" "$tmp_dir/$flavor.pkglist"
  5.2751 +
  5.2752 +			for i in rootcd rootfs; do
  5.2753 +				mkdir "$tmp_dir/$i"
  5.2754 +				# Copy extra files from the first flavor
  5.2755 +				[ -d "$FLAVORS_REPOSITORY/$2/$i" ] &&
  5.2756 +					cp -a "$FLAVORS_REPOSITORY/$2/$i" "$tmp_dir"
  5.2757 +				# Overload extra files by meta flavor
  5.2758 +				[ -d "$storage/$i" ] && cp -a "$storage/$i" "$tmp_dir"
  5.2759 +				[ -n "$(ls $tmp_dir/$i)" ] &&
  5.2760 +					(cd "$tmp_dir/$i"; find . | cpio -o -H newc 2>/dev/null ) | \
  5.2761 +					gzip -9 > "$tmp_dir/$flavor.$i"
  5.2762 +				rm -rf "$tmp_dir/$i"
  5.2763 +			done
  5.2764 +		else
  5.2765 +			# Process plain flavor
  5.2766 +			for i in rootcd rootfs; do
  5.2767 +				[ -d "$storage/$i" ] || continue
  5.2768 +				(cd  "$storage/$i";
  5.2769 +					find . | cpio -o -H newc 2>/dev/null) | gzip -9 > "$tmp_dir/$flavor.$i"
  5.2770 +			done
  5.2771 +		fi
  5.2772 +
  5.2773 +		unset VERSION MAINTAINER ROOTFS_SELECTION
  5.2774 +		set -- $(calc_sizes "$tmp_dir" "$flavor")
  5.2775 +		ROOTFS_SIZE="$1 (estimated)"
  5.2776 +		INITRAMFS_SIZE="$2 (estimated)"
  5.2777 +		ISO_SIZE="$3 (estimated)"
  5.2778 +		PKGNUM="$4"
  5.2779 +		. "$storage/receipt"
  5.2780 +
  5.2781 +		sed '/: $/d' > "$tmp_dir/$flavor.desc" <<EOT
  5.2782  Flavor          : $FLAVOR
  5.2783  Description     : $SHORT_DESC
  5.2784 -EOT
  5.2785 -			[ -n "$VERSION" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
  5.2786  Version         : $VERSION
  5.2787 -EOT
  5.2788 -			[ -n "$MAINTAINER" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
  5.2789  Maintainer      : $MAINTAINER
  5.2790 -EOT
  5.2791 -			[ -n "$FRUGAL_RAM" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
  5.2792  LiveCD RAM size : $FRUGAL_RAM
  5.2793 -EOT
  5.2794 -			[ -n "$ROOTFS_SELECTION" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
  5.2795  Rootfs list     : $ROOTFS_SELECTION
  5.2796 -EOT
  5.2797 -			cat >> $TMP_DIR/$FLAVOR.desc <<EOT
  5.2798 -Build date      : $(date +%Y%m%d\ \at\ \%H:%M:%S)
  5.2799 -Packages        : $(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l)
  5.2800 +Build date      : $(date '+%Y%m%d at %T')
  5.2801 +Packages        : $PKGNUM
  5.2802  Rootfs size     : $ROOTFS_SIZE
  5.2803  Initramfs size  : $INITRAMFS_SIZE
  5.2804  ISO image size  : $ISO_SIZE
  5.2805  ================================================================================
  5.2806  
  5.2807  EOT
  5.2808 -			rm -f $TMP_DIR/packages.list
  5.2809 -			( cd $TMP_DIR ; ls | cpio -o -H newc 2> /dev/null) | \
  5.2810 -				gzip -9 > $FLAVOR.flavor
  5.2811 -			status
  5.2812 -			rm -Rf $TMP_DIR
  5.2813 -		else
  5.2814 -			echo "No $FLAVOR flavor in $FLAVORS_REPOSITORY."
  5.2815 -		fi ;;
  5.2816 -	
  5.2817 +
  5.2818 +		rm -f $tmp_dir/packages.list
  5.2819 +		pack_flavor "$tmp_dir" "$flavor"
  5.2820 +		status
  5.2821 +		display_unknown "$tmp_dir/err"
  5.2822 +		display_warn    "$flv_dir/warn"
  5.2823 +		cleanup
  5.2824 +		;;
  5.2825 +
  5.2826 +
  5.2827  	get-flavor)
  5.2828  		# Get a flavor's files and prepare for gen-distro.
  5.2829 -		FLAVOR=${2%.flavor}
  5.2830 -		echo -e "\n\033[1mPreparing $FLAVOR distro flavor\033[0m"
  5.2831 -		separator
  5.2832 -		if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
  5.2833 -			echo -n "Cleaning $DISTRO..."
  5.2834 -			rm -R $DISTRO 2> /dev/null
  5.2835 -			mkdir -p $DISTRO
  5.2836 -			status
  5.2837 -			mkdir $TMP_DIR
  5.2838 -			[ -z $noup ] && tazlito upgrade-flavor $FLAVOR.flavor
  5.2839 -			echo -n "Extracting flavor $FLAVOR.flavor... "
  5.2840 -			zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i --quiet >/dev/null )
  5.2841 -			status
  5.2842 -			echo -n "Creating distro-packages.list..."
  5.2843 -			mv $TMP_DIR/$FLAVOR.nonfree non-free.list 2> /dev/null
  5.2844 -			mv $TMP_DIR/$FLAVOR.pkglist distro-packages.list
  5.2845 -			status
  5.2846 -			if [ -f "$TMP_DIR/$FLAVOR-distro.sh" ]; then
  5.2847 -				echo -n "Extracting distro.sh... "
  5.2848 -				mv $TMP_DIR/$FLAVOR-distro.sh  distro.sh 2> /dev/null
  5.2849 -				status
  5.2850 +		flavor=${2%.flavor}
  5.2851 +		title 'Preparing %s distro flavor' "$flavor"
  5.2852 +		set -e
  5.2853 +		[ -f "$flavor.flavor" ] || download "$flavor.flavor"
  5.2854 +		set +e
  5.2855 +
  5.2856 +		action 'Cleaning %s...' "$DISTRO"
  5.2857 +		[ -d "$DISTRO" ] && rm -r "$DISTRO"
  5.2858 +		# Clean old files
  5.2859 +		for i in non-free.list distro-packages.list distro.sh receipt mirrors err; do
  5.2860 +			[ -f "$i" ] && rm "$i"
  5.2861 +		done
  5.2862 +		mkdir -p "$DISTRO"
  5.2863 +		status
  5.2864 +
  5.2865 +		[ -z "$noup" ] && tazlito upgrade-flavor "$flavor.flavor"
  5.2866 +
  5.2867 +		action 'Extracting flavor %s...' "$flavor.flavor"
  5.2868 +		flv_dir="$(extract_flavor "$flavor" info)"
  5.2869 +		cp -a "$flv_dir"/* .
  5.2870 +		mv packages.list distro-packages.list
  5.2871 +		mv -f info /etc/tazlito
  5.2872 +		status
  5.2873 +
  5.2874 +		for i in rootcd rootfs; do
  5.2875 +			if [ -d "$i" ]; then
  5.2876 +				mkdir -p "$ADDFILES"; mv "$i" "$ADDFILES/$i"
  5.2877  			fi
  5.2878 -			if [ -f "$TMP_DIR/$FLAVOR.receipt" ]; then
  5.2879 -				echo -n "Extracting receipt... "
  5.2880 -				cp $TMP_DIR/$FLAVOR.receipt  receipt 2> /dev/null
  5.2881 -				status
  5.2882 -			fi
  5.2883 -			infos="$FLAVOR.desc"
  5.2884 -			[ -s $TMP_DIR/$FLAVOR.receipt ] && infos="$infos\n$FLAVOR.receipt"
  5.2885 -			for i in rootcd rootfs; do
  5.2886 -				if [ -f $TMP_DIR/$FLAVOR.$i ]; then
  5.2887 -					echo -n "Adding $i files... "
  5.2888 -					mkdir -p "$ADDFILES/$i"
  5.2889 -					zcat < $TMP_DIR/$FLAVOR.$i | \
  5.2890 -						( cd "$ADDFILES/$i"; cpio -id --quiet > /dev/null)
  5.2891 -					zcat < $TMP_DIR/$FLAVOR.$i | cpio -tv 2> /dev/null \
  5.2892 -						> $TMP_DIR/$FLAVOR.list$i
  5.2893 -					infos="$infos\n$FLAVOR.list$i"
  5.2894 -					status
  5.2895 -				fi
  5.2896 -			done
  5.2897 -			if [ -s $TMP_DIR/$FLAVOR.mirrors ]; then
  5.2898 -				n=""
  5.2899 -				while read line; do
  5.2900 -					mkdir -p $LOCALSTATE/undigest/$FLAVOR$n
  5.2901 -					echo "$line" > $LOCALSTATE/undigest/$FLAVOR$n/mirror
  5.2902 -					n=$(( $n + 1 ))
  5.2903 -				done < $TMP_DIR/$FLAVOR.mirrors
  5.2904 -				infos="$infos\n$FLAVOR.mirrors"
  5.2905 -				tazpkg recharge
  5.2906 -			fi
  5.2907 -			rm -f /etc/tazlito/rootfs.list
  5.2908 -			grep -q '^Rootfs list' $TMP_DIR/$FLAVOR.desc &&
  5.2909 -				grep '^Rootfs list' $TMP_DIR/$FLAVOR.desc | \
  5.2910 -				sed 's/.*: \(.*\)$/\1/' > /etc/tazlito/rootfs.list
  5.2911 -			echo -n "Updating tazlito.conf..."
  5.2912 -			[ -f tazlito.conf ] || cp /etc/tazlito/tazlito.conf .
  5.2913 -			grep -v "^#VOLUM_NAME" < tazlito.conf | \
  5.2914 -			sed "s/^VOLUM_NA/VOLUM_NAME=\"SliTaz $FLAVOR\"\\n#VOLUM_NA/" \
  5.2915 -				> tazlito.conf.$$ && mv tazlito.conf.$$ tazlito.conf
  5.2916 -			sed -i "s/ISO_NAME=.*/ISO_NAME=\"slitaz-$FLAVOR\"/" tazlito.conf
  5.2917 -			status
  5.2918 -			( cd $TMP_DIR ; echo -e $infos | cpio -o -H newc ) | \
  5.2919 -				gzip -9 > /etc/tazlito/info
  5.2920 -			rm -Rf $TMP_DIR
  5.2921 -		fi
  5.2922 -		separator
  5.2923 -		echo -e "Flavor is ready to be generated by: tazlito gen-distro\n" ;;
  5.2924 +		done
  5.2925 +
  5.2926 +		rm -f /etc/tazlito/rootfs.list
  5.2927 +		grep -q  '^Rootfs list' description &&
  5.2928 +			grep '^Rootfs list' description | sed 's/.*: \(.*\)$/\1/' > /etc/tazlito/rootfs.list
  5.2929 +
  5.2930 +		action 'Updating tazlito.conf...'
  5.2931 +		[ -f tazlito.conf ] || cp /etc/tazlito/tazlito.conf .
  5.2932 +		grep -v "^#VOLUM_NAME" < tazlito.conf | \
  5.2933 +		sed "s/^VOLUM_NA/VOLUM_NAME=\"SliTaz $flavor\"\\n#VOLUM_NA/" \
  5.2934 +			> tazlito.conf.$$ && mv tazlito.conf.$$ tazlito.conf
  5.2935 +		sed -i "s/ISO_NAME=.*/ISO_NAME=\"slitaz-$flavor\"/" tazlito.conf
  5.2936 +		status
  5.2937 +
  5.2938 +		footer 'Flavor is ready to be generated by `tazlito gen-distro`'
  5.2939 +		cleanup
  5.2940 +		;;
  5.2941 +
  5.2942  
  5.2943  	iso2flavor)
  5.2944 -		if [ -z "$3" -o ! -s "$2" ]; then
  5.2945 -			cat <<EOT
  5.2946 -Usage : tazlito iso2flavor image.iso flavor_name
  5.2947 -
  5.2948 -Create a file flavor_name.flavor from the cdrom image file image.iso
  5.2949 -EOT
  5.2950 -			exit 1
  5.2951 -		fi
  5.2952 +		[ -z "$3" -o ! -s "$2" ] && die 'Usage: tazlito iso2flavor <image.iso> <flavor_name>' \
  5.2953 +			'\n\nCreate a file <flavor_name>.flavor from the CD-ROM image file <image.iso>'
  5.2954 +
  5.2955  		FLAVOR=${3%.flavor}
  5.2956  		mkdir -p $TMP_DIR/iso $TMP_DIR/rootfs $TMP_DIR/flavor
  5.2957  		mount -o loop,ro $2 $TMP_DIR/iso
  5.2958 -		flavordata $2 | (cd $TMP_DIR/flavor ; cpio -i 2> /dev/null)
  5.2959 +		flavordata $2 | (cd $TMP_DIR/flavor; cpio -i 2>/dev/null)
  5.2960  		if [ -s $TMP_DIR/iso/boot/rootfs1.gz -a \
  5.2961 -		     ! -s $TMP_DIR/flavor/*.desc ]; then
  5.2962 +		   ! -s $TMP_DIR/flavor/*.desc ]; then
  5.2963  			echo "META flavors are not supported."
  5.2964  			umount -d $TMP_DIR/iso
  5.2965  		elif [ ! -s $TMP_DIR/iso/boot/rootfs.gz -a \
  5.2966  		       ! -s $TMP_DIR/iso/boot/rootfs1.gz ]; then
  5.2967 -			echo "No /boot/rootfs.gz in iso image. Needs a SliTaz iso."
  5.2968 +			echo "No /boot/rootfs.gz in ISO image. Needs a SliTaz ISO."
  5.2969  			umount -d $TMP_DIR/iso
  5.2970  		else
  5.2971  			for i in $(ls -r $TMP_DIR/iso/boot/rootfs*gz); do
  5.2972 @@ -1882,7 +2151,7 @@
  5.2973  				RAM_SIZE=$(du -s $TMP_DIR/rootfs | awk '{ print 32*int(($1+36000)/32768) "M" }')
  5.2974  				cp -a $TMP_DIR/iso $TMP_DIR/rootcd
  5.2975  				ISO_SIZE=$(df -h $TMP_DIR/iso | awk 'END { print $2 }')
  5.2976 -				BUILD_DATE=$(date +%Y%m%d\ \at\ \%H:%M:%S -r $TMP_DIR/iso/md5sum)
  5.2977 +				BUILD_DATE=$(date '+%Y%m%d at %T' -r "$TMP_DIR/iso/md5sum")
  5.2978  				umount -d $TMP_DIR/iso
  5.2979  				INITRAMFS_SIZE=$(du -chs $TMP_DIR/rootcd/boot/rootfs*.gz | awk 'END { print $1 }')
  5.2980  				rm -f $TMP_DIR/rootcd/boot/rootfs.gz $TMP_DIR/rootcd/md5sum
  5.2981 @@ -1896,29 +2165,28 @@
  5.2982  					cp $TMP_DIR/flavor/*.receipt $TMP_DIR/$FLAVOR.receipt
  5.2983  					for i in rootfs rootcd ; do
  5.2984  						[ -s $TMP_DIR/flavor/*.list$i ] &&
  5.2985 -						sed 's/.\{1,45\}//;/^\.$/d' $TMP_DIR/flavor/*.list$i | ( cd $TMP_DIR/$i ; cpio -o -H newc ) | gzip -9 > $TMP_DIR/$FLAVOR.$i
  5.2986 +						sed 's/.\{1,45\}//;/^\.$/d' $TMP_DIR/flavor/*.list$i | \
  5.2987 +							( cd $TMP_DIR/$i ; cpio -o -H newc ) | gzip -9 > $TMP_DIR/$FLAVOR.$i
  5.2988  					done
  5.2989  				else
  5.2990  					find_flavor_rootfs $TMP_DIR/rootfs
  5.2991  					[ -d $TMP_DIR/rootfs/boot ] && mv $TMP_DIR/rootfs/boot $TMP_DIR/rootcd
  5.2992  					for i in rootfs rootcd ; do
  5.2993  						[ "$(ls $TMP_DIR/$i)" ] &&
  5.2994 -						( cd $TMP_DIR/$i ; find * | cpio -o -H newc ) | gzip -9 > $TMP_DIR/$FLAVOR.$i
  5.2995 +						( cd "$TMP_DIR/$i"; find * | cpio -o -H newc ) | gzip -9 > "$TMP_DIR/$FLAVOR.$i"
  5.2996  					done
  5.2997 -					VERSION=""; MAINTAINER=""
  5.2998 +					unset VERSION MAINTAINER
  5.2999  					echo -en "Flavor short description \007: "; read -t 30 DESCRIPTION
  5.3000  					if [ -n "$DESCRIPTION" ]; then
  5.3001  						echo -en "Flavor version : "; read -t 30 VERSION
  5.3002  						echo -en "Flavor maintainer (your email) : "; read -t 30 MAINTAINER
  5.3003  					fi
  5.3004 -					[ -n "$DESCRIPTION" ] || DESCRIPTION="Slitaz $FLAVOR flavor"
  5.3005 -					[ -n "$VERSION" ] || VERSION="1.0"
  5.3006 -					[ -n "$MAINTAINER" ] || MAINTAINER="nobody@slitaz.org"
  5.3007 +
  5.3008  					cat > $TMP_DIR/$FLAVOR.desc <<EOT
  5.3009  Flavor          : $FLAVOR
  5.3010 -Description     : $DESCRIPTION
  5.3011 -Version         : $VERSION
  5.3012 -Maintainer      : $MAINTAINER
  5.3013 +Description     : ${DESCRIPTION:-SliTaz $FLAVOR flavor}
  5.3014 +Version         : ${VERSION:-1.0}
  5.3015 +Maintainer      : ${MAINTAINER:-nobody@slitaz.org}
  5.3016  LiveCD RAM size : $RAM_SIZE
  5.3017  Build date      : $BUILD_DATE
  5.3018  Packages        : $PKGCNT
  5.3019 @@ -1928,236 +2196,180 @@
  5.3020  ================================================================================
  5.3021  
  5.3022  EOT
  5.3023 -					cat <<EOT
  5.3024 -Tazlito can't detect each file installed during a package post_install.
  5.3025 -You should extract this flavor (tazlito extract-flavor $FLAVOR),
  5.3026 -check the files in /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/rootfs tree and remove
  5.3027 -files generated by post_installs.
  5.3028 -Check /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/receipt too and repack the flavor
  5.3029 -(tazlito pack-flavor $FLAVOR)
  5.3030 -EOT
  5.3031 +					longline "Tazlito can't detect each file installed during \
  5.3032 +a package post_install. You should extract this flavor (tazlito extract-flavor \
  5.3033 +$FLAVOR), check the files in /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/rootfs \
  5.3034 +tree and remove files generated by post_installs.
  5.3035 +Check /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/receipt too and \
  5.3036 +repack the flavor (tazlito pack-flavor $FLAVOR)"
  5.3037  				fi
  5.3038 -				( cd $TMP_DIR ; ls $FLAVOR.* | cpio -o -H newc ) | gzip -9 > $FLAVOR.flavor
  5.3039 +				( cd $TMP_DIR; ls $FLAVOR.* | cpio -o -H newc ) | gzip -9 > $FLAVOR.flavor
  5.3040  			fi
  5.3041  		fi
  5.3042 -		rm -rf $TMP_DIR ;;
  5.3043 -
  5.3044 -	check-list)
  5.3045 -		# Use current packages list in $PWD by default.
  5.3046 -		DISTRO_PKGS_LIST=distro-packages.list
  5.3047 -		[ -d "$2" ] && DISTRO_PKGS_LIST=$2/distro-packages.list
  5.3048 -		[ -f "$2" ] && DISTRO_PKGS_LIST=$2
  5.3049 -		[ ! -f $DISTRO_PKGS_LIST ] && echo "No packages list found." && exit 0
  5.3050 -		newline
  5.3051 -		boldify "LiveCD packages list check"
  5.3052 -		separator
  5.3053 -		for pkg in $(cat $DISTRO_PKGS_LIST)
  5.3054 -		do
  5.3055 -			if ! grep -q "$pkg" $LOCALSTATE/packages.list; then
  5.3056 -				echo "Updating: $pkg"
  5.3057 -				up=$(($up + 1))
  5.3058 -			fi
  5.3059 -		done
  5.3060 -		[ -z $up ] && echo -e "List is up-to-date\n" && exit 0
  5.3061 -		separator
  5.3062 -		echo -e "Updates: $up\n" ;;
  5.3063 -	
  5.3064 +		rm -rf $TMP_DIR
  5.3065 +		;;
  5.3066 +
  5.3067 +
  5.3068  	gen-distro)
  5.3069  		# Generate a live distro tree with a set of packages.
  5.3070  		#
  5.3071  		check_root
  5.3072 -		time=$(date +%s)
  5.3073 -
  5.3074 -		# Libtaz will set $iso or $cdrom
  5.3075 -		CDROM=""
  5.3076 -		[ "$iso" ] && CDROM="-o loop $iso"
  5.3077 -		[ "$cdrom" ] && CDROM="/dev/cdrom"
  5.3078 +		start_time=$(date +%s)
  5.3079 +
  5.3080 +		# Tazlito options: --iso or --cdrom
  5.3081 +		CDROM=''
  5.3082 +		[ -n "$iso"   ] && CDROM="-o loop $iso"
  5.3083 +		[ -n "$cdrom" ] && CDROM="/dev/cdrom"
  5.3084 +
  5.3085  		# Check if a package list was specified on cmdline.
  5.3086  		if [ -f "$2" ]; then
  5.3087 -			LIST_NAME=$2
  5.3088 +			LIST_NAME="$2"
  5.3089  		else
  5.3090 -			LIST_NAME="distro-packages.list"
  5.3091 +			LIST_NAME='distro-packages.list'
  5.3092  		fi
  5.3093  
  5.3094 -		if [ -d "$ROOTFS" ] ; then
  5.3095 -			# Delete $ROOTFS if --force is set on command line
  5.3096 -			if [ "$forced" ]; then
  5.3097 -				rm -rf $ROOTFS $ROOTCD
  5.3098 -			else
  5.3099 -				echo -e "\nA rootfs exists in : $DISTRO"
  5.3100 -				echo -e "Please clean the distro tree or change directory path.\n"
  5.3101 -				exit 0
  5.3102 -			fi
  5.3103 +		[ -d "$ROOTFS" -a -z "$forced" ] && die "A rootfs exists in '$DISTRO'." \
  5.3104 +			'Please clean the distro tree or change directory path.'
  5.3105 +		[ -d "$ROOTFS" ] && rm -rf "$ROOTFS"
  5.3106 +		[ -d "$ROOTCD" ] && rm -rf "$ROOTCD"
  5.3107 +
  5.3108 +		# If list not given: build list with all installed packages
  5.3109 +		if [ ! -f "$LIST_NAME" -a -f "$LOCALSTATE/installed.info" ]; then
  5.3110 +			awk -F$'\t' '{print $1}' "$LOCALSTATE/installed.info" >> "$LIST_NAME"
  5.3111  		fi
  5.3112 -		
  5.3113 -		# Build list with installed packages
  5.3114 -		if [ ! -f "$LIST_NAME" -a -d $INSTALLED ] ; then
  5.3115 -			for i in $(ls $INSTALLED); do
  5.3116 -				if grep -q ^_realver $INSTALLED/$i/receipt ; then
  5.3117 -					VERSION=$(. $INSTALLED/$i/receipt 2>/dev/null ; echo $VERSION) 
  5.3118 -				else
  5.3119 -					eval $(grep ^VERSION= $INSTALLED/$i/receipt)
  5.3120 -				fi
  5.3121 -				EXTRAVERSION=""
  5.3122 -				eval $(grep ^EXTRAVERSION= $INSTALLED/$i/receipt)
  5.3123 -				echo "$i-$VERSION$EXTRAVERSION" >> $LIST_NAME
  5.3124 -			done
  5.3125 -		fi
  5.3126 +
  5.3127  		# Exit if no list name.
  5.3128 -		if [ ! -f "$LIST_NAME" ]; then
  5.3129 -			echo -e "\nNo packages list found or specified. Please read the docs.\n"
  5.3130 -			exit 0
  5.3131 -		fi
  5.3132 +		[ ! -f "$LIST_NAME" ] && die 'No packages list found or specified. Please read the docs.'
  5.3133 +
  5.3134  		# Start generation.
  5.3135 -		newline
  5.3136 -		boldify "Tazlito generating a distro"
  5.3137 -		separator
  5.3138 +		title 'Tazlito generating a distro'
  5.3139 +
  5.3140  		# Misc checks
  5.3141 -		[ -n "$PACKAGES_REPOSITORY" ] || PACKAGES_REPOSITORY="."
  5.3142 -		[ -d $PACKAGES_REPOSITORY ] || mkdir -p $PACKAGES_REPOSITORY
  5.3143 -		# Get the list of packages using cat for a file list.
  5.3144 -		LIST=`cat $LIST_NAME`
  5.3145 -		# Verify if all packages in list are present in $PACKAGES_REPOSITORY.
  5.3146 -		REPACK=""
  5.3147 -		DOWNLOAD=""
  5.3148 -		for pkg in $LIST
  5.3149 -		do
  5.3150 -			[ "$pkg" = "" ] && continue
  5.3151 -			pkg=${pkg%.tazpkg}
  5.3152 -			[ -f $PACKAGES_REPOSITORY/$pkg.tazpkg ] && continue
  5.3153 -			PACKAGE=$(installed_package_name $pkg)
  5.3154 -			[ -n "$PACKAGE" -a "$REPACK" = "y" ] && continue
  5.3155 -			[ -z "$PACKAGE" -a -n "$DOWNLOAD" ] && continue
  5.3156 -			echo -e "\nUnable to find $pkg in the repository."
  5.3157 -			echo -e "Path : $PACKAGES_REPOSITORY\n"
  5.3158 -			if [ -n "$PACKAGE" -a -z "$REPACK" ]; then
  5.3159 -				yesorno "Repack packages from rootfs (y/N) ? "
  5.3160 -				REPACK="$answer"
  5.3161 -				[ "$answer" = "y" ] || REPACK="n"
  5.3162 -				[ "$DOWNLOAD" = "y" ] && break
  5.3163 -			fi
  5.3164 -			if [ -f $MIRROR -a -z "$DOWNLOAD" ]; then
  5.3165 -				yesorno "Download packages from mirror (Y/n) ? "
  5.3166 -				DOWNLOAD="$answer"
  5.3167 -				if [ "$answer" = "n" ]; then
  5.3168 -					[ -z "$PACKAGE" ] && exit 1
  5.3169 -				else
  5.3170 -					DOWNLOAD="y"
  5.3171 -					[ -n "$REPACK" ] && break
  5.3172 -				fi
  5.3173 -			fi
  5.3174 -			[ "$REPACK" = "n" -a "$DOWNLOAD" = "n" ] && exit 1
  5.3175 -		done
  5.3176 -
  5.3177 -		# Mount cdrom to be able to repack boot-loader packages
  5.3178 +		mkdir -p "$PACKAGES_REPOSITORY"
  5.3179 +		REPACK=$(yesorno 'Repack packages from rootfs?' 'n')
  5.3180 +
  5.3181 +		# Mount CD-ROM to be able to repack boot-loader packages
  5.3182  		if [ ! -e /boot -a -n "$CDROM" ]; then
  5.3183  			mkdir $TMP_MNT
  5.3184 -			if mount -r $CDROM $TMP_MNT 2> /dev/null; then
  5.3185 -				ln -s $TMP_MNT/boot /
  5.3186 +			if mount -r "$CDROM $TMP_MNT" 2>/dev/null; then
  5.3187 +				ln -s "$TMP_MNT/boot" /
  5.3188  				if [ ! -d "$ADDFILES/rootcd" ] ; then
  5.3189 -					mkdir -p $ADDFILES/rootcd
  5.3190 +					mkdir -p "$ADDFILES/rootcd"
  5.3191  					for i in $(ls $TMP_MNT); do
  5.3192 -						[ "$i" = "boot" ] && continue
  5.3193 -						cp -a $TMP_MNT/$i $ADDFILES/rootcd
  5.3194 +						[ "$i" == 'boot' ] && continue
  5.3195 +						cp -a "$TMP_MNT/$i" "$ADDFILES/rootcd"
  5.3196  					done
  5.3197  				fi
  5.3198  			else
  5.3199 -				rmdir $TMP_MNT
  5.3200 +				rmdir "$TMP_MNT"
  5.3201  			fi
  5.3202  		fi
  5.3203  
  5.3204  		# Rootfs stuff.
  5.3205 -		echo "Preparing the rootfs directory..."
  5.3206 -		mkdir -p $ROOTFS
  5.3207 -		for pkg in $LIST
  5.3208 -		do
  5.3209 -			[ "$pkg" = "" ] && continue
  5.3210 -			# First copy and extract the package in tmp dir.
  5.3211 -			pkg=${pkg%.tazpkg}
  5.3212 -			PACKAGE=$(installed_package_name $pkg)
  5.3213 -			mkdir -p $TMP_DIR
  5.3214 -			if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
  5.3215 -				# Look for package in cache
  5.3216 -				if [ -f $CACHE_DIR/$pkg.tazpkg ]; then
  5.3217 -					ln -s $CACHE_DIR/$pkg.tazpkg $PACKAGES_REPOSITORY
  5.3218 -				# Look for package in running distribution
  5.3219 -				elif [ -n "$PACKAGE" -a "$REPACK" = "y" ]; then
  5.3220 -					tazpkg repack $PACKAGE && \
  5.3221 -					  mv $pkg.tazpkg $PACKAGES_REPOSITORY
  5.3222 -				fi
  5.3223 -			fi
  5.3224 -			if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
  5.3225 -				# Get package from mirror
  5.3226 -				[ "$DOWNLOAD" = "y" ] && \
  5.3227 -				download $pkg.tazpkg && \
  5.3228 -				mv $pkg.tazpkg $PACKAGES_REPOSITORY
  5.3229 -			fi
  5.3230 -			if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
  5.3231 -				echo "Missing package: $pkg"
  5.3232 -				cleanup
  5.3233 -				exit 1
  5.3234 -			fi
  5.3235 -		done
  5.3236 +		echo 'Preparing the rootfs directory...'
  5.3237 +		mkdir -p "$ROOTFS"
  5.3238 +		mkdir -p "$TMP_DIR"
  5.3239 +
  5.3240 +		strip_versions "$LIST_NAME"
  5.3241 +
  5.3242 +		if [ "$REPACK" == 'y' ]; then
  5.3243 +			# Determine full packages list with all dependencies
  5.3244 +			tmp_dir="$(mktemp -d)"
  5.3245 +			cp "$LIST_NAME" "$tmp_dir/flavor.pkglist"
  5.3246 +			touch "$tmp_dir/full.pkglist"
  5.3247 +			calc_sizes "$tmp_dir" 'flavor' "$tmp_dir/full.pkglist" >/dev/null
  5.3248 +
  5.3249 +			awk -F$'\t' '{printf "%s %s\n", $1, $2}' "$LOCALSTATE/installed.info" | \
  5.3250 +			while read pkgname pkgver; do
  5.3251 +				# Is package in full list?
  5.3252 +				grep -q "^$pkgname$" "$tmp_dir/full.pkglist" || continue
  5.3253 +				# Is package already repacked?
  5.3254 +				[ -e "$PACKAGES_REPOSITORY/$pkgname-$pkgver.tazpkg" ] && continue
  5.3255 +				_ 'Repacking %s...' "$pkgname-$pkgver"
  5.3256 +				tazpkg repack "$pkgname" --quiet
  5.3257 +				[ -f "$pkgname-$pkgver.tazpkg" ] && mv "$pkgname-$pkgver.tazpkg" "$PACKAGES_REPOSITORY"
  5.3258 +				status
  5.3259 +			done
  5.3260 +
  5.3261 +			rm -r "$tmp_dir"
  5.3262 +		fi
  5.3263 +
  5.3264 +		# initial tazpkg setup in empty rootfs
  5.3265 +		export root="$ROOTFS"
  5.3266 +		tazpkg >/dev/null 2>&1
  5.3267 +		# link rootfs packages cache to the regular packages cache
  5.3268 +		rm -r "$ROOTFS/var/cache/tazpkg"
  5.3269 +		ln -s /var/cache/tazpkg "$ROOTFS/var/cache/tazpkg"
  5.3270 +
  5.3271 +		setup_mirrors mirrors
  5.3272 +
  5.3273 +		# Just in case if flavor not contains "tazlito" package
  5.3274 +		mkdir -p "$ROOTFS/etc/tazlito"
  5.3275 +
  5.3276  		if [ -f non-free.list ]; then
  5.3277 -			echo "Preparing non-free packages..."
  5.3278 -			cp non-free.list $ROOTFS/etc/tazlito/non-free.list
  5.3279 -			for pkg in $(cat non-free.list); do
  5.3280 -				if [ ! -d $INSTALLED/$pkg ]; then
  5.3281 -					if [ ! -d $INSTALLED/get-$pkg ]; then
  5.3282 +			# FIXME: working in the ROOTFS chroot?
  5.3283 +			newline
  5.3284 +			echo 'Preparing non-free packages...'
  5.3285 +			cp 'non-free.list' "$ROOTFS/etc/tazlito/non-free.list"
  5.3286 +			for pkg in $(cat 'non-free.list'); do
  5.3287 +				if [ ! -d "$INSTALLED/$pkg" ]; then
  5.3288 +					if [ ! -d "$INSTALLED/get-$pkg" ]; then
  5.3289  						tazpkg get-install get-$pkg
  5.3290  					fi
  5.3291 -					get-$pkg
  5.3292 +					get-$pkg "$ROOTFS"
  5.3293  				fi
  5.3294  				tazpkg repack $pkg
  5.3295  				pkg=$(ls $pkg*.tazpkg)
  5.3296 -				grep -q "^$pkg$" $LIST_NAME || \
  5.3297 -					echo $pkg >>$LIST_NAME
  5.3298 +				grep -q "^$pkg$" $LIST_NAME || echo $pkg >> $LIST_NAME
  5.3299  				mv $pkg $PACKAGES_REPOSITORY
  5.3300  			done
  5.3301  		fi
  5.3302  		cp $LIST_NAME $DISTRO/distro-packages.list
  5.3303 -		sed 's/\(.*\)/\1.tazpkg/' < $DISTRO/distro-packages.list > $DISTRO/list-packages
  5.3304 -		cd $PACKAGES_REPOSITORY
  5.3305 -
  5.3306 -		# Use packages repository as mirror, don't download unsynced packages from mirror server
  5.3307 -		mkdir -p $ROOTFS/home/slitaz; ln -s ../../../../packages $ROOTFS/home/slitaz/packages
  5.3308 -		mkdir -p "$ROOTFS/var/lib/tazpkg"; echo '/home/slitaz/packages' > "$ROOTFS/var/lib/tazpkg/mirror"
  5.3309 -		tazpkg --root=$ROOTFS >/dev/null 2>&1 # initial tazpkg setup in empty rootfs
  5.3310 -
  5.3311 -		for pkg in $(cat $DISTRO/list-packages)
  5.3312 -		do
  5.3313 -			echo -n "Installing package: $pkg"
  5.3314 -			yes y | tazpkg -i $pkg --root=$ROOTFS 2>&1 >> $log || exit 1
  5.3315 +		newline
  5.3316 +
  5.3317 +		for pkg in $(cat $DISTRO/distro-packages.list); do
  5.3318 +			action 'Installing package: %s' "$pkg"
  5.3319 +			yes y | tazpkg -gi $pkg --root=$ROOTFS --quiet >> $log || exit 1
  5.3320  			status
  5.3321  		done
  5.3322 -
  5.3323 -		# Clean packages cache
  5.3324 -		find $ROOTFS/var/cache/tazpkg -name '*.tazpkg' -delete
  5.3325 +		newline
  5.3326 +
  5.3327 +		restore_mirrors
  5.3328 +
  5.3329 +		# Un-link packages cache
  5.3330 +		rm $ROOTFS/var/cache/tazpkg
  5.3331  		# Clean /var/lib/tazpkg
  5.3332 -		rm $ROOTFS/var/lib/tazpkg/ID* $ROOTFS/var/lib/tazpkg/descriptions.txt \
  5.3333 -			$ROOTFS/var/lib/tazpkg/extra.list $ROOTFS/var/lib/tazpkg/files* \
  5.3334 -			$ROOTFS/var/lib/tazpkg/packages* 2>/dev/null
  5.3335 +		rm  $ROOTFS/var/lib/tazpkg/ID* \
  5.3336 +			$ROOTFS/var/lib/tazpkg/descriptions.txt \
  5.3337 +			$ROOTFS/var/lib/tazpkg/extra.list \
  5.3338 +			$ROOTFS/var/lib/tazpkg/files* \
  5.3339 +			$ROOTFS/var/lib/tazpkg/packages* \
  5.3340 +			$ROOTFS/var/lib/tazpkg/priority \
  5.3341 +		-rf $ROOTFS/var/lib/tazpkg/undigest \
  5.3342 +			2>/dev/null
  5.3343  		# Back to default mirror
  5.3344 -		rm -rf $ROOTFS/home/slitaz
  5.3345  		echo "$DEFAULT_MIRROR" > $ROOTFS/var/lib/tazpkg/mirror
  5.3346  
  5.3347  		cd $DISTRO
  5.3348  		cp distro-packages.list $ROOTFS/etc/tazlito
  5.3349  		# Copy all files from $ADDFILES/rootfs to the rootfs.
  5.3350  		if [ -d "$ADDFILES/rootfs" ] ; then
  5.3351 -			echo -n "Copying addfiles content to the rootfs... "
  5.3352 +			action 'Copying addfiles content to the rootfs...'
  5.3353  			cp -a $ADDFILES/rootfs/* $ROOTFS
  5.3354  			status
  5.3355  		fi
  5.3356 -		echo -n "Root filesystem is generated..." && status
  5.3357 +
  5.3358 +		action 'Root filesystem is generated...'; status
  5.3359 +
  5.3360  		# Root CD part.
  5.3361 -		echo -n "Preparing the rootcd directory..."
  5.3362 +		action 'Preparing the rootcd directory...'
  5.3363  		mkdir -p $ROOTCD
  5.3364  		status
  5.3365 +
  5.3366  		# Move the boot dir with the Linux kernel from rootfs.
  5.3367  		# The boot dir goes directly on the CD.
  5.3368  		if [ -d "$ROOTFS/boot" ] ; then
  5.3369 -			echo -n "Moving the boot directory..."
  5.3370 +			action 'Moving the boot directory...'
  5.3371  			mv $ROOTFS/boot $ROOTCD
  5.3372  			cd $ROOTCD/boot
  5.3373  			make_bzImage_hardlink
  5.3374 @@ -2166,41 +2378,43 @@
  5.3375  		cd $DISTRO
  5.3376  		# Copy all files from $ADDFILES/rootcd to the rootcd.
  5.3377  		if [ -d "$ADDFILES/rootcd" ] ; then
  5.3378 -			echo -n "Copying addfiles content to the rootcd... "
  5.3379 +			action 'Copying addfiles content to the rootcd...'
  5.3380  			cp -a $ADDFILES/rootcd/* $ROOTCD
  5.3381  			status
  5.3382  		fi
  5.3383  		# Execute the distro script used to perform tasks in the rootfs
  5.3384  		# before compression. Give rootfs path in arg
  5.3385 -		[ -z $DISTRO_SCRIPT ] && DISTRO_SCRIPT=$TOP_DIR/distro.sh
  5.3386 -		if [ -x $DISTRO_SCRIPT ]; then
  5.3387 -			echo "Executing distro script..."
  5.3388 +		[ -z "$DISTRO_SCRIPT" ] && DISTRO_SCRIPT="$TOP_DIR/distro.sh"
  5.3389 +		if [ -x "$DISTRO_SCRIPT" ]; then
  5.3390 +			echo 'Executing distro script...'
  5.3391  			sh $DISTRO_SCRIPT $DISTRO
  5.3392  		fi
  5.3393 -		
  5.3394 -		# Execute the custom_rules found in receipt.
  5.3395 -		if [ -s $TOP_DIR/receipt ]; then
  5.3396 -			if grep -q ^custom_rules $TOP_DIR/receipt; then
  5.3397 -				echo -e "Executing: custom_rules\n"
  5.3398 -				. $TOP_DIR/receipt
  5.3399 -				custom_rules || echo -e "\nERROR: custom_rules failed\n" 
  5.3400 +
  5.3401 +		# Execute the custom_rules() found in receipt.
  5.3402 +		if [ -s "$TOP_DIR/receipt" ]; then
  5.3403 +			if grep -q ^custom_rules "$TOP_DIR/receipt"; then
  5.3404 +				echo -e "Executing: custom_rules()\n"
  5.3405 +				. "$TOP_DIR/receipt"
  5.3406 +				custom_rules || echo -e "\nERROR: custom_rules() failed\n" 
  5.3407  			fi
  5.3408 -		fi 
  5.3409 -		
  5.3410 +		fi
  5.3411 +
  5.3412  		# Multi-rootfs
  5.3413  		if [ -s /etc/tazlito/rootfs.list ]; then
  5.3414  
  5.3415 -			FLAVOR_LIST="$(awk '{ for (i = 2; i <= NF; i+=2) \
  5.3416 -			  printf("%s ",$i) }' < /etc/tazlito/rootfs.list)"
  5.3417 -
  5.3418 -			[ -s $ROOTCD/boot/isolinux/isolinux.msg ] &&
  5.3419 -			sed -i "s/ *//;s/)/), flavors $FLAVOR_LIST/" \
  5.3420 -			  $ROOTCD/boot/isolinux/isolinux.msg 2> /dev/null
  5.3421 -
  5.3422 -			[ -f $ROOTCD/boot/isolinux/ifmem.c32 -o \
  5.3423 -			  -f $ROOTCD/boot/isolinux/c32box.c32 ] ||
  5.3424 -			cp /boot/isolinux/c32box.c32 $ROOTCD/boot/isolinux 2> /dev/null ||
  5.3425 -			cp /boot/isolinux/ifmem.c32 $ROOTCD/boot/isolinux
  5.3426 +			FLAVOR_LIST="$(awk '{
  5.3427 +				for (i = 2; i <= NF; i+=2)
  5.3428 +					printf "%s ", i;
  5.3429 +			}' /etc/tazlito/rootfs.list)"
  5.3430 +
  5.3431 +			[ -s "$ROOTCD/boot/isolinux/isolinux.msg" ] &&
  5.3432 +				sed -i "s/ *//;s/)/), flavors $FLAVOR_LIST/" \
  5.3433 +					"$ROOTCD/boot/isolinux/isolinux.msg" 2>/dev/null
  5.3434 +
  5.3435 +			[ -f "$ROOTCD/boot/isolinux/ifmem.c32" -o \
  5.3436 +			  -f "$ROOTCD/boot/isolinux/c32box.c32" ] ||
  5.3437 +			cp '/boot/isolinux/c32box.c32' "$ROOTCD/boot/isolinux" 2>/dev/null ||
  5.3438 +			cp '/boot/isolinux/ifmem.c32'  "$ROOTCD/boot/isolinux"
  5.3439  
  5.3440  			n=0
  5.3441  			last=$ROOTFS
  5.3442 @@ -2209,10 +2423,10 @@
  5.3443  				newline
  5.3444  				boldify "Building $flavor rootfs..."
  5.3445  
  5.3446 -				[ -s $TOP_DIR/$flavor.flavor ] &&
  5.3447 -					cp $TOP_DIR/$flavor.flavor .
  5.3448 -
  5.3449 -				if [ ! -s $flavor.flavor ]; then
  5.3450 +				[ -s   "$TOP_DIR/$flavor.flavor" ] &&
  5.3451 +					cp "$TOP_DIR/$flavor.flavor" .
  5.3452 +
  5.3453 +				if [ ! -s "$flavor.flavor" ]; then
  5.3454  					# We may have it in $FLAVORS_REPOSITORY
  5.3455  					if [ -d "$FLAVORS_REPOSITORY/$flavor" ]; then
  5.3456  						tazlito pack-flavor $flavor
  5.3457 @@ -2221,49 +2435,67 @@
  5.3458  					fi
  5.3459  				fi
  5.3460  
  5.3461 -				echo -n "Extracting $flavor.pkglist and $flavor.rootfs..."
  5.3462 -				zcat < $flavor.flavor | cpio -i --quiet \
  5.3463 -					$flavor.pkglist $flavor.rootfs
  5.3464 -				sed 's/.*/&.tazpkg/' < $flavor.pkglist \
  5.3465 -					> $DISTRO/list-packages0$n
  5.3466 +				action 'Extracting %s and %s...' "$flavor.pkglist" "$flavor.rootfs"
  5.3467 +				zcat $flavor.flavor | cpio -i --quiet $flavor.pkglist $flavor.rootfs
  5.3468 +				sed 's/.*/&.tazpkg/' < $flavor.pkglist > $DISTRO/list-packages0$n
  5.3469  				status
  5.3470  
  5.3471 +				strip_versions "$DISTRO/list-packages0$n"
  5.3472 +
  5.3473  				mkdir ${ROOTFS}0$n
  5.3474  				# Install packages
  5.3475 -				cd ${PACKAGES_REPOSITORY}
  5.3476 -
  5.3477 -				# Use packages repository as mirror, don't download unsynced packages from mirror server
  5.3478 -				mkdir -p ${ROOTFS}0$n/home/slitaz; ln -s ../../../../packages ${ROOTFS}0$n/home/slitaz/packages
  5.3479 -				mkdir -p "${ROOTFS}0$n/var/lib/tazpkg"
  5.3480 -				echo '/home/slitaz/packages' > "${ROOTFS}0$n/var/lib/tazpkg/mirror"
  5.3481 -				tazpkg --root=${ROOTFS}0$n >/dev/null 2>&1 # initial tazpkg setup in empty rootfs
  5.3482 -
  5.3483 -				for pkg in $(cat $DISTRO/list-packages0$n)
  5.3484 -				do
  5.3485 -					echo -n "Installing package: $pkg"
  5.3486 -					yes y | tazpkg -i $pkg --root=${ROOTFS}0$n 2>&1 >> $log || exit 1
  5.3487 +				cd $PACKAGES_REPOSITORY
  5.3488 +
  5.3489 +				# initial tazpkg setup in empty rootfs
  5.3490 +				export root="${ROOTFS}0$n"
  5.3491 +				tazpkg >/dev/null 2>&1
  5.3492 +				# link rootfs packages cache to the regular packages cache
  5.3493 +				rm -r "${ROOTFS}0$n/var/cache/tazpkg"
  5.3494 +				ln -s /var/cache/tazpkg "${ROOTFS}0$n/var/cache/tazpkg"
  5.3495 +
  5.3496 +				setup_mirrors mirrors
  5.3497 +
  5.3498 +				# Just in case if flavor not contains "tazlito" package
  5.3499 +				mkdir -p "${ROOTFS}0$n/etc/tazlito"
  5.3500 +
  5.3501 +
  5.3502 +				for pkg in $(cat $DISTRO/list-packages0$n); do
  5.3503 +					action 'Installing package: %s' "$pkg"
  5.3504 +					yes y | tazpkg -gi $pkg --root=${ROOTFS}0$n --quiet >> $log || exit 1
  5.3505  					status
  5.3506  				done
  5.3507  
  5.3508 -				rm -rf ${ROOTFS}0$n/boot ${ROOTFS}0$n/var/lib/tazpkg/packages.*
  5.3509 -				# Clean packages cache
  5.3510 -				find ${ROOTFS}0$n/var/cache/tazpkg -name '*.tazpkg' -delete
  5.3511 +				restore_mirrors
  5.3512 +
  5.3513 +				rm -rf ${ROOTFS}0$n/boot
  5.3514 +
  5.3515 +				# Un-link packages cache
  5.3516 +				rm ${ROOTFS}0$n/var/cache/tazpkg
  5.3517 +
  5.3518  				# Clean /var/lib/tazpkg
  5.3519 -				rm ${ROOTFS}0$n/var/lib/tazpkg/ID* ${ROOTFS}0$n/var/lib/tazpkg/descriptions.txt \
  5.3520 -					${ROOTFS}0$n/var/lib/tazpkg/extra.list ${ROOTFS}0$n/var/lib/tazpkg/files* \
  5.3521 +				rm  ${ROOTFS}0$n/var/lib/tazpkg/ID* \
  5.3522 +					${ROOTFS}0$n/var/lib/tazpkg/descriptions.txt \
  5.3523 +					${ROOTFS}0$n/var/lib/tazpkg/extra.list \
  5.3524 +					${ROOTFS}0$n/var/lib/tazpkg/files* \
  5.3525 +					${ROOTFS}0$n/var/lib/tazpkg/packages.* \
  5.3526 +					${ROOTFS}0$n/var/lib/tazpkg/priority \
  5.3527 +				-rf ${ROOTFS}0$n/var/lib/tazpkg/undigest \
  5.3528  					2>/dev/null
  5.3529 +
  5.3530  				# Back to default mirror
  5.3531 -				rm -rf ${ROOTFS}0$n/home/slitaz
  5.3532  				echo "$DEFAULT_MIRROR" > ${ROOTFS}0$n/var/lib/tazpkg/mirror
  5.3533  
  5.3534 +
  5.3535  				cd $DISTRO
  5.3536  				if [ -s $flavor.rootfs ]; then
  5.3537  					echo -n "Adding $flavor rootfs extra files..."
  5.3538  					zcat < $flavor.rootfs | ( cd ${ROOTFS}0$n ; cpio -idmu )
  5.3539  				fi
  5.3540 -				echo -n "Moving list-packages0$n to rootfs0$n"
  5.3541 +
  5.3542 +				action 'Moving %s to %s' "list-packages0$n" "rootfs0$n"
  5.3543  				mv $DISTRO/list-packages0$n ${ROOTFS}0$n/etc/tazlito/distro-packages.list
  5.3544  				status
  5.3545 +
  5.3546  				rm -f $flavor.flavor install-list
  5.3547  				mergefs ${ROOTFS}0$n $last
  5.3548  				last=${ROOTFS}0$n
  5.3549 @@ -2289,47 +2521,49 @@
  5.3550  		fi
  5.3551  		gen_livecd_isolinux
  5.3552  		distro_stats
  5.3553 -		cleanup ;;
  5.3554 -		
  5.3555 +		cleanup
  5.3556 +		;;
  5.3557 +
  5.3558 +
  5.3559  	clean-distro)
  5.3560  		# Remove old distro tree.
  5.3561  		#
  5.3562  		check_root
  5.3563 -		newline
  5.3564 -		boldify "Cleaning : $DISTRO"
  5.3565 -		separator
  5.3566 +		title 'Cleaning: %s' "$DISTRO"
  5.3567  		if [ -d "$DISTRO" ] ; then
  5.3568  			if [ -d "$ROOTFS" ] ; then
  5.3569 -				echo -n "Removing the rootfs..."
  5.3570 -				rm -f $DISTRO/$INITRAMFS
  5.3571 +				action 'Removing the rootfs...'
  5.3572 +				rm -f  $DISTRO/$INITRAMFS
  5.3573  				rm -rf $ROOTFS
  5.3574  				status
  5.3575  			fi
  5.3576  			if [ -d "$ROOTCD" ] ; then
  5.3577 -				echo -n "Removing the rootcd..."
  5.3578 +				action 'Removing the rootcd...'
  5.3579  				rm -rf $ROOTCD
  5.3580  				status
  5.3581  			fi
  5.3582 -			echo -n "Removing eventual ISO image..."
  5.3583 +			action 'Removing eventual ISO image...'
  5.3584  			rm -f $DISTRO/$ISO_NAME.iso
  5.3585  			rm -f $DISTRO/$ISO_NAME.md5
  5.3586  			status
  5.3587  		fi
  5.3588 -		separator
  5.3589 -		newline ;;
  5.3590 -	
  5.3591 +		footer
  5.3592 +		;;
  5.3593 +
  5.3594 +
  5.3595  	check-distro)
  5.3596  		# Check for a few LiveCD needed files not installed by packages.
  5.3597  		#
  5.3598 +		# TODO: Remove this function.
  5.3599 +		# First two files are maintained by tazpkg while it runs on rootfs,
  5.3600 +		# while last one file should be maintained by tazlito itself.
  5.3601  		check_rootfs
  5.3602 -		newline
  5.3603 -		echo -e "\033[1mChecking distro :\033[0m $ROOTFS"
  5.3604 -		separator
  5.3605 +		title 'Checking distro: %s' "$ROOTFS"
  5.3606  		# SliTaz release info.
  5.3607  		if [ ! -f "$ROOTFS/etc/slitaz-release" ]; then
  5.3608  			echo "Missing release info : /etc/slitaz-release"
  5.3609  		else
  5.3610 -			release=`cat $ROOTFS/etc/slitaz-release`
  5.3611 +			release=$(cat $ROOTFS/etc/slitaz-release)
  5.3612  			echo -n "Release      : $release"
  5.3613  			status
  5.3614  		fi
  5.3615 @@ -2338,53 +2572,42 @@
  5.3616  			echo -n "Mirror URL   : Missing $LOCALSTATE/mirror"
  5.3617  			todomsg
  5.3618  		else
  5.3619 -			echo -n "Mirror configuration exists..."
  5.3620 +			action 'Mirror configuration exists...'
  5.3621  			status
  5.3622  		fi
  5.3623  		# Isolinux msg
  5.3624  		if grep -q "cooking-XXXXXXXX" /$ROOTCD/boot/isolinux/isolinux.*g; then
  5.3625 -			echo -n "Isolinux msg : Missing cooking date XXXXXXXX (ex `date +%Y%m%d`)"
  5.3626 +			echo -n "Isolinux msg : Missing cooking date XXXXXXXX (ex $(date +%Y%m%d))"
  5.3627  			todomsg
  5.3628  		else
  5.3629 -			echo -n "Isolinux message seems good..."
  5.3630 +			action 'Isolinux message seems good...'
  5.3631  			status
  5.3632  		fi
  5.3633 -		separator
  5.3634 -		newline ;;
  5.3635 -	
  5.3636 +		footer
  5.3637 +		;;
  5.3638 +
  5.3639 +
  5.3640  	writeiso)
  5.3641 -		# Writefs to ISO image including /home unlike gen-distro we dont use
  5.3642 +		# Writefs to ISO image including /home unlike gen-distro we don't use
  5.3643  		# packages to generate a rootfs, we build a compressed rootfs with all
  5.3644  		# the current filesystem similar to 'tazusb writefs'.
  5.3645  		#
  5.3646 -		DISTRO="/home/slitaz/distro"
  5.3647 +		DISTRO='/home/slitaz/distro'
  5.3648  		ROOTCD="$DISTRO/rootcd"
  5.3649 -		if [ -z $2 ]; then
  5.3650 -			COMPRESSION=none
  5.3651 -		else
  5.3652 -			COMPRESSION=$2
  5.3653 -		fi
  5.3654 -		if [ -z "$3" ]; then
  5.3655 -			ISO_NAME="slitaz"
  5.3656 -		else
  5.3657 -			ISO_NAME="$3"
  5.3658 -		fi
  5.3659 +		COMPRESSION="${2:-none}"
  5.3660 +		ISO_NAME="${3:-slitaz}"
  5.3661  		check_root
  5.3662  		# Start info
  5.3663 +		title 'Write filesystem to ISO'
  5.3664 +		longline "The command writeiso will write the current filesystem into a \
  5.3665 +suitable cpio archive (rootfs.gz) and generate a bootable ISO image (slitaz.iso)."
  5.3666  		newline
  5.3667 -		boldify "Write filesystem to ISO"
  5.3668 -		separator
  5.3669 -		cat <<EOT
  5.3670 -The command writeiso will write the current filesystem into a suitable cpio
  5.3671 -archive (rootfs.gz) and generate a bootable ISO image (slitaz.iso).
  5.3672 -
  5.3673 -$(boldify "Archive compression:") $(colorize 36 "$COMPRESSION")
  5.3674 -
  5.3675 -EOT
  5.3676 -		[ $COMPRESSION == "gzip" ] && colorize 31 "gzip-compressed rootfs unsupported and may fail to boot"
  5.3677 +		emsg "<b>Archive compression:</b> <c 36>$COMPRESSION</c>"
  5.3678 +
  5.3679 +		[ "$COMPRESSION" == 'gzip' ] && colorize 31 "gzip-compressed rootfs unsupported and may fail to boot"
  5.3680  		# Save some space
  5.3681 -		rm /var/cache/tazpkg/* -r -f
  5.3682 -		rm /var/lib/tazpkg/*.bak -f
  5.3683 +		rm -rf /var/cache/tazpkg/*
  5.3684 +		rm -f  /var/lib/tazpkg/*.bak
  5.3685  		rm -rf $DISTRO
  5.3686  
  5.3687  		# Optionally remove sound card selection and screen resolution.
  5.3688 @@ -2403,8 +2626,9 @@
  5.3689  			*)
  5.3690  				echo -n "Keeping current sound card and screen configurations..." ;;
  5.3691  		esac
  5.3692 -		status && newline
  5.3693 -		
  5.3694 +		status
  5.3695 +		newline
  5.3696 +
  5.3697  		# Optionally remove i18n settings
  5.3698  		echo "Do you wish to remove local/keymap settings ? "
  5.3699  		echo -n "Press ENTER to keep or answer (No|yes|exit): "
  5.3700 @@ -2421,7 +2645,7 @@
  5.3701  		esac
  5.3702  		status
  5.3703  		fi
  5.3704 -		
  5.3705 +
  5.3706  		# Clean-up files by default
  5.3707  		newline > /etc/udev/rules.d/70-persistent-net.rules
  5.3708  		newline > /etc/udev/rules.d/70-persistant-cd.rules
  5.3709 @@ -2430,16 +2654,13 @@
  5.3710  		# and some new users might have been added.
  5.3711  		cd /
  5.3712  		echo 'init' > /tmp/list
  5.3713 -		for dir in bin etc sbin var dev lib root usr home opt
  5.3714 -		do
  5.3715 +		for dir in bin etc sbin var dev lib root usr home opt; do
  5.3716  			[ -d $dir ] && find $dir
  5.3717 -		done >>/tmp/list
  5.3718 -
  5.3719 -		for dir in proc sys tmp mnt media media/cdrom media/flash \
  5.3720 -			media/usbdisk run run/udev
  5.3721 -		do
  5.3722 +		done >> /tmp/list
  5.3723 +
  5.3724 +		for dir in proc sys tmp mnt media media/cdrom media/flash media/usbdisk run run/udev; do
  5.3725  			[ -d $dir ] && echo $dir
  5.3726 -		done >>/tmp/list
  5.3727 +		done >> /tmp/list
  5.3728  
  5.3729  		sed '/var\/run\/.*pid$/d ; /var\/run\/utmp/d ; /.*\/.gvfs/d ; /home\/.*\/.cache\/.*/d' -i /tmp/list
  5.3730  		
  5.3731 @@ -2449,8 +2670,7 @@
  5.3732  		mv -f /var/log/wtmp /tmp/tazlito-wtmp
  5.3733  		touch /var/log/wtmp
  5.3734  		
  5.3735 -		for removelog in \
  5.3736 -		auth boot messages dmesg daemon slim .*old Xorg tazpanel cups; do
  5.3737 +		for removelog in auth boot messages dmesg daemon slim .*old Xorg tazpanel cups; do
  5.3738  			sed -i "/var\/log\/$removelog/d" /tmp/list
  5.3739  		done
  5.3740  
  5.3741 @@ -2462,10 +2682,9 @@
  5.3742  		sleep 2
  5.3743  		cd - > /dev/null
  5.3744  		echo -en "\nFilesystem size:"
  5.3745 -		while [ ! -f /tmp/rootfs ]
  5.3746 -		do
  5.3747 +		while [ ! -f /tmp/rootfs ]; do
  5.3748  			sleep 1
  5.3749 -			echo -en "\\033[18G`du -sh /rootfs.gz | awk '{print $1}'`    "
  5.3750 +			echo -en "\\033[18G$(du -sh /$INITRAMFS | awk '{print $1}')    "
  5.3751  		done
  5.3752  		mv -f /tmp/tazlito-wtmp /var/log/wtmp
  5.3753  		echo -e "\n"
  5.3754 @@ -2473,21 +2692,21 @@
  5.3755  
  5.3756  		# Move freshly generated rootfs to the cdrom.
  5.3757  		mkdir -p $ROOTCD/boot
  5.3758 -		mv -f /rootfs.gz $ROOTCD/boot
  5.3759 -		echo "Located in: $ROOTCD/boot/rootfs.gz"
  5.3760 +		mv -f /$INITRAMFS $ROOTCD/boot
  5.3761 +		echo "Located in: $ROOTCD/boot/$INITRAMFS"
  5.3762  
  5.3763  		# Now we need the kernel and isolinux files.
  5.3764 -		copy_from_cd()
  5.3765 -		{
  5.3766 +		copy_from_cd() {
  5.3767  			cp /media/cdrom/boot/bzImage* $ROOTCD/boot
  5.3768  			cp -a /media/cdrom/boot/isolinux $ROOTCD/boot
  5.3769  			unmeta_boot $ROOTCD
  5.3770  			umount /media/cdrom
  5.3771  		}
  5.3772 -		bootloader="/var/lib/tazpkg/installed/syslinux/volatile.cpio.gz"
  5.3773 +
  5.3774 +		bootloader='/var/lib/tazpkg/installed/syslinux/volatile.cpio.gz'
  5.3775  		if  mount /dev/cdrom /media/cdrom 2>/dev/null; then
  5.3776  			copy_from_cd;
  5.3777 -		elif  mount |grep /media/cdrom; then
  5.3778 +		elif  mount | grep /media/cdrom; then
  5.3779  			copy_from_cd;
  5.3780  		elif [ -f "$bootloader" -a -f /boot/vmlinuz*slitaz* ]; then
  5.3781  			cp $bootloader $ROOTCD
  5.3782 @@ -2500,11 +2719,10 @@
  5.3783  				cp /boot/vmlinuz*slitaz64 $ROOTCD/boot/bzImage64
  5.3784  		else
  5.3785  			touch /tmp/.write-iso-error
  5.3786 -			echo -e "
  5.3787 -When SliTaz is running in RAM the kernel and bootloader files are kept
  5.3788 -on the cdrom. Please insert a LiveCD or loop mount the slitaz.iso to
  5.3789 -/media/cdrom (run # mount -o loop slitaz-rolling.iso /media/cdrom )
  5.3790 -or # (tazpkg -gi linux --forced) to let Tazlito copy the files.\n"
  5.3791 +			longline "When SliTaz is running in RAM the kernel and bootloader \
  5.3792 +files are kept on the CD-ROM. Please insert a Live CD or loop mount the \
  5.3793 +slitaz.iso to /media/cdrom (run # mount -o loop slitaz-rolling.iso /media/cdrom ) \
  5.3794 +or # (tazpkg -gi linux --forced) to let Tazlito copy the files."
  5.3795  			echo -en "----\nENTER to continue..."; read i
  5.3796  			[ ! -d /media/cdrom/boot/isolinux ] && exit 1
  5.3797  			copy_from_cd
  5.3798 @@ -2515,21 +2733,21 @@
  5.3799  		newline
  5.3800  		cd $DISTRO
  5.3801  		echo "Generating ISO image..."
  5.3802 -		genisoimage -R -o $ISO_NAME.iso -b boot/isolinux/isolinux.bin \
  5.3803 -		-c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
  5.3804 -		-V "SliTaz" -p "$(id -un)" -input-charset iso8859-1 \
  5.3805 -		-P "$(hostname)" -boot-info-table $ROOTCD
  5.3806 +		genisoimage -R   -o $ISO_NAME.iso   -b boot/isolinux/isolinux.bin \
  5.3807 +		-c boot/isolinux/boot.cat   -no-emul-boot   -boot-load-size 4 \
  5.3808 +		-V "SliTaz"   -p "$(id -un)"   -input-charset utf-8 \
  5.3809 +		-P "$(hostname)"   -boot-info-table $ROOTCD
  5.3810  		if [ -x /usr/bin/isohybrid ]; then
  5.3811 -			echo -n "Creating hybrid ISO/disk..."
  5.3812 -			/usr/bin/isohybrid $ISO_NAME.iso -entry 2 2> /dev/null
  5.3813 +			action 'Creating hybrid ISO/disk...'
  5.3814 +			/usr/bin/isohybrid $ISO_NAME.iso -entry 2 2>/dev/null
  5.3815  			status
  5.3816  		fi
  5.3817  		if [ -x /usr/bin/iso2exe ]; then
  5.3818 -			echo -n "Creating hybrid ISO/EXE..."
  5.3819 -			/usr/bin/iso2exe $ISO_NAME.iso 2> /dev/null
  5.3820 +			action 'Creating hybrid ISO/EXE...'
  5.3821 +			/usr/bin/iso2exe $ISO_NAME.iso 2>/dev/null
  5.3822  			status
  5.3823  		fi
  5.3824 -		echo -n "Creating the ISO md5sum..."
  5.3825 +		action 'Creating the ISO md5sum...'
  5.3826  		md5sum $ISO_NAME.iso > $ISO_NAME.md5
  5.3827  		status
  5.3828  
  5.3829 @@ -2538,57 +2756,52 @@
  5.3830  		rm -f /tmp/.write-iso
  5.3831  		newline
  5.3832  		if [ -z $LaunchedByTazpanel ]; then
  5.3833 -		echo -n "Exit or burn ISO to cdrom (Exit|burn)? "; read anser
  5.3834 +		echo -n "Exit or burn ISO to CD-ROM (Exit|burn)? "; read anser
  5.3835  		case $anser in
  5.3836  			burn)
  5.3837 -				umount /dev/cdrom 2> /dev/null
  5.3838 +				umount /dev/cdrom 2>/dev/null
  5.3839  				eject
  5.3840 -				echo -n "Please insert a blank cdrom and press ENTER..."
  5.3841 +				echo -n "Please insert a blank CD-ROM and press ENTER..."
  5.3842  				read i && sleep 2
  5.3843  				tazlito burn-iso $DISTRO/$ISO_NAME.iso
  5.3844  				echo -en "----\nENTER to continue..."; read i ;;
  5.3845  			*)
  5.3846  				exit 0 ;;
  5.3847  		esac
  5.3848 -		fi ;;
  5.3849 -	
  5.3850 +		fi
  5.3851 +		;;
  5.3852 +
  5.3853 +
  5.3854  	burn-iso)
  5.3855 -		# Guess cdrom device, ask user and burn the ISO.
  5.3856 +		# Guess CD-ROM device, ask user and burn the ISO.
  5.3857  		#
  5.3858  		check_root
  5.3859 -		DRIVE_NAME=$(grep "drive name" < /proc/sys/dev/cdrom/info | cut -f 3)
  5.3860 -		DRIVE_SPEED=$(grep "drive speed" < /proc/sys/dev/cdrom/info | cut -f 3)
  5.3861 +		DRIVE_NAME=$(grep  "drive name"  /proc/sys/dev/cdrom/info | cut -f3)
  5.3862 +		DRIVE_SPEED=$(grep "drive speed" /proc/sys/dev/cdrom/info | cut -f3)
  5.3863  		# We can specify an alternative ISO from the cmdline.
  5.3864 -		if [ -n "$2" ] ; then
  5.3865 -			iso=$2
  5.3866 -		else
  5.3867 -			iso=$DISTRO/$ISO_NAME.iso
  5.3868 -		fi
  5.3869 -		if [ ! -f "$iso" ]; then
  5.3870 -			echo -e "\nUnable to find ISO : $iso\n"
  5.3871 -			exit 0
  5.3872 -		fi
  5.3873 -		newline
  5.3874 -		boldify "Tazlito burn ISO"
  5.3875 -		separator
  5.3876 -		echo "Cdrom device  : /dev/$DRIVE_NAME"
  5.3877 +		iso="${2:-$DISTRO/$ISO_NAME.iso}"
  5.3878 +		[ ! -f "$iso" ] && die "Unable to find ISO: $iso"
  5.3879 +
  5.3880 +		title 'Tazlito burn ISO'
  5.3881 +		echo "CD-ROM device : /dev/$DRIVE_NAME"
  5.3882  		echo "Drive speed   : $DRIVE_SPEED"
  5.3883  		echo "ISO image     : $iso"
  5.3884 -		separator
  5.3885 -		newline
  5.3886 -		yesorno "Burn ISO image (y/N) ? "
  5.3887 -		if [ "$answer" == "y" ]; then
  5.3888 -			newline
  5.3889 -			echo "Starting Wodim to burn the iso..." && sleep 2
  5.3890 -			separator
  5.3891 -			wodim speed=$DRIVE_SPEED dev=/dev/$DRIVE_NAME $iso
  5.3892 -			separator
  5.3893 -			echo "ISO image is burned to cdrom."
  5.3894 -		else
  5.3895 -			echo -e "\nExiting. No ISO burned."
  5.3896 -		fi
  5.3897 -		newline ;;
  5.3898 -	
  5.3899 +		footer
  5.3900 +
  5.3901 +		case $(yesorno 'Burn ISO image?' 'n') in
  5.3902 +			y)
  5.3903 +				title 'Starting Wodim to burn the ISO...'
  5.3904 +				sleep 2
  5.3905 +				wodim speed=$DRIVE_SPEED dev=/dev/$DRIVE_NAME $iso
  5.3906 +				footer 'ISO image is burned to CD-ROM.'
  5.3907 +				;;
  5.3908 +			*)
  5.3909 +				die 'Exiting. No ISO burned.'
  5.3910 +				;;
  5.3911 +		esac
  5.3912 +		;;
  5.3913 +
  5.3914 +
  5.3915  	merge)
  5.3916  		# Merge multiple rootfs into one iso.
  5.3917  		#
  5.3918 @@ -2596,9 +2809,9 @@
  5.3919  			cat <<EOT
  5.3920  Usage: tazlito merge size1 iso size2 rootfs2 [sizeN rootfsN]...
  5.3921  
  5.3922 -Merge multiple rootfs into one iso. Rootfs are like russian dolls
  5.3923 +Merge multiple rootfs into one ISO. Rootfs are like russian dolls
  5.3924  i.e: rootfsN is a subset of rootfsN-1
  5.3925 -rootfs1 is found in iso, sizeN is the RAM size needed to launch rootfsN.
  5.3926 +rootfs1 is found in ISO, sizeN is the RAM size needed to launch rootfsN.
  5.3927  The boot loader will select the rootfs according to the RAM size detected.
  5.3928  
  5.3929  Example:
  5.3930 @@ -2617,10 +2830,12 @@
  5.3931  		mkdir -p $TMP_DIR/mnt $TMP_DIR/rootfs1
  5.3932  
  5.3933  		ISO=$1.merged
  5.3934 +
  5.3935  		# Extract filesystems
  5.3936 -		echo -n "Mounting $1"
  5.3937 +		action 'Mounting %s' "$1"
  5.3938  		mount -o loop,ro $1 $TMP_DIR/mnt 2> /dev/null
  5.3939  		status || cleanup_merge
  5.3940 +
  5.3941  		cp -a $TMP_DIR/mnt $TMP_DIR/iso
  5.3942  		make_bzImage_hardlink $TMP_DIR/iso/boot
  5.3943  		umount -d $TMP_DIR/mnt
  5.3944 @@ -2643,10 +2858,11 @@
  5.3945  			cp /boot/isolinux/ifmem.c32 $TMP_DIR/iso/boot/isolinux
  5.3946  		fi
  5.3947  
  5.3948 -		echo -n "Extracting iso/rootfs.gz"
  5.3949 +		action 'Extracting iso/rootfs.gz'
  5.3950  		extract_rootfs $TMP_DIR/iso/boot/rootfs.gz $TMP_DIR/rootfs1 &&
  5.3951 -		[ -d $TMP_DIR/rootfs1/etc ]
  5.3952 +			[ -d $TMP_DIR/rootfs1/etc ]
  5.3953  		status || cleanup_merge
  5.3954 +
  5.3955  		n=1
  5.3956  		while [ -n "$2" ]; do
  5.3957  			shift	# skip rootfs N-1
  5.3958 @@ -2655,103 +2871,101 @@
  5.3959  			append="$append $1 slitaz$n"
  5.3960  			shift	# skip size N
  5.3961  			mkdir -p $TMP_DIR/rootfs$n
  5.3962 -			echo -n "Extracting $1"
  5.3963 +
  5.3964 +			action 'Extracting %s' "$1"
  5.3965  			extract_rootfs $1 $TMP_DIR/rootfs$n &&
  5.3966 -			[ -d $TMP_DIR/rootfs$n/etc ]
  5.3967 +			[ -d "$TMP_DIR/rootfs$n/etc" ]
  5.3968  			status || cleanup_merge
  5.3969 +
  5.3970  			mergefs $TMP_DIR/rootfs$n $TMP_DIR/rootfs$p
  5.3971 -			echo "Creating rootfs$p.gz"
  5.3972 -			pack_rootfs $TMP_DIR/rootfs$p $TMP_DIR/iso/boot/rootfs$p.gz
  5.3973 +			action 'Creating rootfs%s.gz' "$p"
  5.3974 +			pack_rootfs "$TMP_DIR/rootfs$p" "$TMP_DIR/iso/boot/rootfs$p.gz"
  5.3975  			status
  5.3976  		done
  5.3977 -		echo "Creating rootfs$n.gz"
  5.3978 -		pack_rootfs $TMP_DIR/rootfs$n $TMP_DIR/iso/boot/rootfs$n.gz
  5.3979 +		action 'Creating rootfs%s.gz' "$n"
  5.3980 +		pack_rootfs "$TMP_DIR/rootfs$n" "$TMP_DIR/iso/boot/rootfs$n.gz"
  5.3981  		status
  5.3982  		rm -f $TMP_DIR/iso/boot/rootfs.gz
  5.3983  		update_bootconfig $TMP_DIR/iso/boot/isolinux "$append"
  5.3984  		create_iso $ISO $TMP_DIR/iso
  5.3985 -		rm -rf $TMP_DIR ;;
  5.3986 +		rm -rf $TMP_DIR
  5.3987 +		;;
  5.3988 +
  5.3989  
  5.3990  	repack)
  5.3991  		# Repack an iso with maximum lzma compression ratio.
  5.3992  		#
  5.3993  		ISO=$2
  5.3994  		mkdir -p $TMP_DIR/mnt
  5.3995 -		
  5.3996 +
  5.3997  		# Extract filesystems
  5.3998 -		echo -n "Mounting $ISO"
  5.3999 -		mount -o loop,ro $ISO $TMP_DIR/mnt 2> /dev/null
  5.4000 +		action 'Mounting %s' "$ISO"
  5.4001 +		mount -o loop,ro $ISO $TMP_DIR/mnt 2>/dev/null
  5.4002  		status || cleanup_merge
  5.4003 +
  5.4004  		cp -a $TMP_DIR/mnt $TMP_DIR/iso
  5.4005  		umount -d $TMP_DIR/mnt
  5.4006  
  5.4007  		for i in $TMP_DIR/iso/boot/rootfs* ; do
  5.4008 -			echo -n "Repacking $(basename $i)"
  5.4009 -			(zcat $i 2> /dev/null || unlzma < $i || cat $i) \
  5.4010 -				2>/dev/null > $TMP_DIR/rootfs
  5.4011 -			lzma e $TMP_DIR/rootfs $i \
  5.4012 -				 $(lzma_switches $TMP_DIR/rootfs)
  5.4013 +			action 'Repacking %s' "$(basename $i)"
  5.4014 +			(zcat $i 2>/dev/null || unlzma < $i || cat $i) 2>/dev/null > $TMP_DIR/rootfs
  5.4015 +			lzma e $TMP_DIR/rootfs $i $(lzma_switches $TMP_DIR/rootfs)
  5.4016  			align_to_32bits $i
  5.4017  			status
  5.4018  		done
  5.4019  
  5.4020  		create_iso $ISO $TMP_DIR/iso
  5.4021 -		rm -rf $TMP_DIR ;;
  5.4022 +		rm -rf $TMP_DIR
  5.4023 +		;;
  5.4024 +
  5.4025  
  5.4026  	build-loram)
  5.4027 -		# Build a Live CD for low ram systems.
  5.4028 +		# Build a Live CD for low RAM systems.
  5.4029  		#
  5.4030 -		ISO=$2
  5.4031 -		OUTPUT=$3
  5.4032 -		if [ -z "$3" ]; then
  5.4033 -			echo "Usage: tazlito $1 input.iso output.iso [cdrom|smallcdrom|http|ram]"
  5.4034 -			exit 1
  5.4035 -		fi
  5.4036 -		mkdir -p $TMP_DIR/iso
  5.4037 -		mount -o loop,ro -t iso9660 $ISO $TMP_DIR/iso
  5.4038 +		ISO="$2"
  5.4039 +		OUTPUT="$3"
  5.4040 +		[ -z "$3" ] && \
  5.4041 +			die "Usage: tazlito build-loram <input>.iso <output>.iso [cdrom|smallcdrom|http|ram]"
  5.4042 +		mkdir -p "$TMP_DIR/iso"
  5.4043 +		mount -o loop,ro -t iso9660 "$ISO" "$TMP_DIR/iso"
  5.4044  		loopdev=$( (losetup -a 2>/dev/null || losetup) | sed "/$ISO$/!d;s/:.*//;q")
  5.4045  		if ! check_iso_for_loram ; then
  5.4046 -			echo "$2 is not a valid SliTaz live CD. Abort."
  5.4047 -			umount -d $TMP_DIR/iso
  5.4048 -			rm -rf $TMP_DIR
  5.4049 -			exit 1
  5.4050 +			umount -d "$TMP_DIR/iso"
  5.4051 +			die "$ISO is not a valid SliTaz live CD. Abort."
  5.4052  		fi
  5.4053  		case "$4" in
  5.4054  			cdrom)		build_loram_cdrom ;;
  5.4055  			http)		build_loram_http ;;
  5.4056 -			*)		build_loram_ram ;;
  5.4057 +			*)			build_loram_ram ;;
  5.4058  		esac
  5.4059  		umount $TMP_DIR/iso	# no -d: needs /proc
  5.4060  		losetup -d $loopdev
  5.4061 -		rm -rf $TMP_DIR ;;
  5.4062 +		rm -rf $TMP_DIR
  5.4063 +		;;
  5.4064 +
  5.4065  
  5.4066  	emu-iso)
  5.4067  		# Emulate an ISO image with Qemu.
  5.4068 -		if [ -n "$2" ] ; then
  5.4069 -			iso=$2
  5.4070 -		else
  5.4071 -			iso=$DISTRO/$ISO_NAME.iso
  5.4072 -		fi
  5.4073 -		if [ ! -f "$iso" ]; then
  5.4074 -			echo -e "\nUnable to find ISO : $iso\n"
  5.4075 -			exit 0
  5.4076 -		fi
  5.4077 -		if [ ! -x "/usr/bin/qemu" ]; then
  5.4078 -			echo -e "\nUnable to find Qemu binary. Please install: qemu\n"
  5.4079 -			exit 0
  5.4080 -		fi
  5.4081 +		iso="${2:-$DISTRO/$ISO_NAME.iso}"
  5.4082 +		[ -f "$iso" ] || die "Unable to find ISO file '$iso'."
  5.4083 +		[ -x '/usr/bin/qemu' ] || die "Unable to find Qemu binary. Please install package 'qemu'."
  5.4084  		echo -e "\nStarting Qemu emulator:\n"
  5.4085  		echo -e "qemu $QEMU_OPTS $iso\n"
  5.4086 -		qemu $QEMU_OPTS $iso ;;
  5.4087 +		qemu $QEMU_OPTS $iso
  5.4088 +		;;
  5.4089 +
  5.4090  
  5.4091  	deduplicate)
  5.4092  		# Deduplicate files in a tree
  5.4093  		shift
  5.4094 -		deduplicate "$@" ;;
  5.4095 -	
  5.4096 +		deduplicate "$@"
  5.4097 +		;;
  5.4098 +
  5.4099 +
  5.4100  	usage|*)
  5.4101  		# Print usage also for all unknown commands.
  5.4102 -		usage ;;
  5.4103 +		usage
  5.4104 +		;;
  5.4105  esac
  5.4106  
  5.4107  exit 0