cookutils rev 1090

Working with "i486", "x86_64" and "any" architecture; post-check with badges; new icons, tag cloud, and other improvements
author Aleksej Bobylev <al.bobylev@gmail.com>
date Sat Nov 24 13:28:02 2018 +0200 (2018-11-24)
parents 01e5c3e760d7
children c0b06e1eb456
files Makefile cook cook.conf cooker lighttpd/cooker-terminal.css lighttpd/cooker.css lighttpd/cooker.js lighttpd/index.cgi modules/deps modules/langdesc modules/pack modules/postcheck
line diff
     1.1 --- a/Makefile	Sat Aug 25 17:30:05 2018 +0300
     1.2 +++ b/Makefile	Sat Nov 24 13:28:02 2018 +0200
     1.3 @@ -34,7 +34,10 @@
     1.4  					modules/compressor \
     1.5  					modules/deps \
     1.6  					modules/mk_pkg_receipt \
     1.7 +					modules/pack \
     1.8  					modules/precheck \
     1.9 +					modules/postcheck \
    1.10 +					modules/langdesc \
    1.11  									 $(DESTDIR)$(PREFIX)/libexec/cookutils
    1.12  	install -m 0644 cook.conf        $(DESTDIR)/etc/slitaz
    1.13  	install -m 0644 cook.site        $(DESTDIR)/etc/slitaz
     2.1 --- a/cook	Sat Aug 25 17:30:05 2018 +0300
     2.2 +++ b/cook	Sat Nov 24 13:28:02 2018 +0200
     2.3 @@ -46,7 +46,6 @@
     2.4  $(boldify "$(_ 'Options:')")
     2.5  cook <pkg>
     2.6      --clean       -c   $(_ 'clean the package in the wok.')
     2.7 -    --install     -i   $(_ 'cook and install the package.')
     2.8      --getsrc      -gs  $(_ 'get the package source tarball.')
     2.9      --block       -b   $(_ 'block a package so cook will skip it.')
    2.10      --unblock     -ub  $(_ 'unblock a blocked package.')
    2.11 @@ -296,7 +295,7 @@
    2.12  
    2.13  # Display time.
    2.14  
    2.15 -disp_time() {
    2.16 +disp_time_old() {
    2.17  	local sec div min
    2.18  	sec="$1"
    2.19  	div=$(( ($1 + 30) / 60))
    2.20 @@ -311,13 +310,31 @@
    2.21  }
    2.22  
    2.23  
    2.24 +# Display time.
    2.25 +
    2.26 +disp_time() {
    2.27 +	local sec="$1" day hour min out=''
    2.28 +
    2.29 +	 day=$(( sec / 86400 )); sec=$(( sec % 86400 ))
    2.30 +	hour=$(( sec / 3600  )); sec=$(( sec % 3600  ))
    2.31 +	 min=$(( sec / 60    )); sec=$(( sec % 60    ))
    2.32 +
    2.33 +	[              $day  -gt 0 ] && out="${day}d "
    2.34 +	[ -n "$out" -o $hour -gt 0 ] && out="$out$(printf '%02dh ' $hour)"
    2.35 +	[ -n "$out" -o $min  -gt 0 ] && out="$out$(printf '%02dm ' $min)"
    2.36 +	[ -n "$out"                ] && out=" ~ $out$(printf '%02ds'  $sec)"
    2.37 +
    2.38 +	echo "${1}s$out"
    2.39 +}
    2.40 +
    2.41 +
    2.42  # Display cooked package summary.
    2.43  
    2.44  summary() {
    2.45 -	local arch=''
    2.46 -	case "$ARCH" in
    2.47 -		arm*|x86_64) arch="-$ARCH" ;;
    2.48 -	esac
    2.49 +#	local arch=''
    2.50 +#	case "$ARCH" in
    2.51 +#		arm*|x86_64) arch="-$ARCH" ;;
    2.52 +#	esac
    2.53  
    2.54  	set_paths
    2.55  	cd $WOK/$pkg
    2.56 @@ -325,7 +342,7 @@
    2.57  	[ -d $WOK/$pkg/source ] && srcdir=$(du -sh $WOK/$pkg/source | awk '{print $1}' 2>/dev/null)
    2.58  	[ -n "$TARBALL" ] && srcsize=$(du -sh $SRC/$TARBALL | awk '{print $1}')
    2.59  
    2.60 -	title 'Summary for: %s' "$PACKAGE $VERSION$EXTRAVERSION$arch"
    2.61 +	title 'Summary for: %s' "$PACKAGE $VERSION$EXTRAVERSION"
    2.62  
    2.63  	# L10n: keep the same width of translations to get a consistent view
    2.64  	[ -n "$TARBALL" ] && _ 'Src file    : %s' "$TARBALL"
    2.65 @@ -334,7 +351,7 @@
    2.66  	[ -n "$prod" ]    && _ 'Produced    : %s' "$prod"
    2.67  	_ 'Cook time   : %s' "$(disp_time "$time")"
    2.68  	_ 'Cook date   : %s' "$(date "$(_ '+%%F %%R')")"
    2.69 -	_ 'Target arch : %s' "$ARCH"
    2.70 +	_ 'Target arch : %s' "$(cut -d$'\t' -f2 $pkgdir/.arch | sort -u | tr '\n' ' ' | sed 's| $||; s| |, |g')"
    2.71  
    2.72  	separator -
    2.73  	_ ' # :  Packed : Compressed : Files : Package name'
    2.74 @@ -343,9 +360,10 @@
    2.75  	for i in $(all_names); do
    2.76  		version=$(awk -F$'\t' -vpkg="$i" '{
    2.77  			if ($1 == pkg) {print $2; exit}
    2.78 -		}' "$PKGS/packages.info")
    2.79 +		}' "$PKGS/packages-$ARCH.info")
    2.80  		fs=$(du -sh $WOK/$pkg/taz/$i-$VERSION$EXTRAVERSION | awk '{print $1}')
    2.81 -		pkgname="$i-$version$arch.tazpkg"
    2.82 +		arch=$(awk -F$'\t' -vi="$i" '{if ($1 == i) print $2}' $pkgdir/.arch)
    2.83 +		pkgname="$i-$version-$arch.tazpkg"
    2.84  		size=$(ls -lh $PKGS/$pkgname | awk '{print $5}')
    2.85  		files=$(wc -l < $WOK/$pkg/taz/$i-$VERSION$EXTRAVERSION/files.list)
    2.86  		printf "%2d : %7s : %10s : %5s : %s\n" "$pkgi" "$fs" "$size" "$files" "$pkgname"
    2.87 @@ -358,7 +376,7 @@
    2.88  # Display debugging error info.
    2.89  
    2.90  debug_info() {
    2.91 -	title 'Debug information'
    2.92 +	title 'Debug information %s.' "$1"
    2.93  	# L10n: specify your format of date and time (to help: man date)
    2.94  	# L10n: not bad one is '+%x %R'
    2.95  	_ 'Cook date: %s' "$(date "$(_ '+%%F %%R')")"
    2.96 @@ -489,7 +507,7 @@
    2.97  	newline
    2.98  	_n 'Build dependencies to remove:'; echo " $nb"
    2.99  	[ -n "$root" ] && echo "root=\"$root\""
   2.100 -	{
   2.101 +
   2.102  		_n 'Removing:'
   2.103  		for dep in $deps; do
   2.104  			echo -n " $dep"
   2.105 @@ -498,7 +516,7 @@
   2.106  			[ -s /aufs-umount.sh ] ||
   2.107  			echo 'y' | tazpkg remove $dep --root=$root >/dev/null
   2.108  		done
   2.109 -	} | busybox fold -sw80
   2.110 +
   2.111  	newline; newline
   2.112  	# Keep the last diff for debug and info.
   2.113  	mv -f $diff $CACHE/installed.diff
   2.114 @@ -510,6 +528,7 @@
   2.115  patchit() {
   2.116  	[ -f "$stuff/patches/series" ] || return
   2.117  
   2.118 +	local done="$pkgdir/.patch.done"
   2.119  	IFS=$'\n'
   2.120  	while read i; do
   2.121  		patchname=$(echo ${i%%#*} | cut -d' ' -f1)	# allow comments (anything after the # or space)
   2.122 @@ -518,11 +537,12 @@
   2.123  			*)    patchopts='-Np1';;
   2.124  		esac
   2.125  		[ -n "$patchname" ] || continue				# allow empty lines
   2.126 -		[ -f "$src/done.$patchname" ] && continue	# already applied (useful with `cook --continue`)
   2.127 +		touch $done
   2.128 +		grep -q "^${patchname}$" $done && continue	# already applied (useful with `cook --continue`)
   2.129  		newline
   2.130  		_ 'Applying patch %s' "$patchname"
   2.131  		patch $patchopts -i $stuff/patches/$patchname | sed 's|^|  |'
   2.132 -		touch $src/done.$patchname
   2.133 +		echo $patchname >> $done
   2.134  	done < $stuff/patches/series
   2.135  	newline
   2.136  	unset IFS
   2.137 @@ -557,6 +577,7 @@
   2.138  		libtool)
   2.139  			if [ -e 'libtool' ]; then
   2.140  				sed -i 's| -shared | -Wl,-Os,--as-needed\0|g' libtool
   2.141 +				echo "fix.libtool" >> $pkgdir/.patch.done
   2.142  			else
   2.143  				echo "fix libtool: warning: libtool absent, nothing to fix."
   2.144  			fi
   2.145 @@ -753,15 +774,13 @@
   2.146  	# Activate "instant-pack" mode
   2.147  	if [ "${COOKOPTS/instant-pack/}" != "$COOKOPTS" ]; then
   2.148  		echo " $SPLIT " | fgrep -q " $PACKAGE " || SPLIT="$PACKAGE $SPLIT"
   2.149 +		export PACKAGE
   2.150  		# determine the list of the packages belongs to the current SET...
   2.151  		echo -n $SPLIT \
   2.152  		| awk -vset="$SET" '
   2.153  			BEGIN { RS = " "; FS = ":"; }
   2.154  			{ if ($2 == set) print $1; }' \
   2.155 -		| while read SET_PKG; do
   2.156 -			# ... and then pack them
   2.157 -			packit $SET_PKG
   2.158 -		done
   2.159 +		| xargs -n1 @@PREFIX@@/libexec/cookutils/pack # ... and then pack them
   2.160  	fi
   2.161  
   2.162  	job_counter=$(($job_counter + 2))
   2.163 @@ -817,7 +836,10 @@
   2.164  	@@PREFIX@@/libexec/cookutils/precheck $receipt || exit 1 # former receipt_quality()
   2.165  
   2.166  	cd $pkgdir
   2.167 -	[ -z "$continue" ] && rm -rf source 2>/dev/null
   2.168 +	if [ -z "$continue" ]; then
   2.169 +		rm -rf source  2>/dev/null
   2.170 +		rm .patch.done 2>/dev/null
   2.171 +	fi
   2.172  	rm -rf install taz 2>/dev/null
   2.173  
   2.174  	# Disable -pipe if less than 512 MB free RAM.
   2.175 @@ -863,7 +885,7 @@
   2.176  						# Search for local package or local provided-package
   2.177  						name=$(awk -F$'\t' -vpkg="$i" '{
   2.178  						if (index(" " $1 " " $10 " ", " " pkg " ")) {print $1; exit}
   2.179 -						}' "$PKGS/packages.info")
   2.180 +						}' "$PKGS/packages-$ARCH.info")
   2.181  						if [ -z "$name" ]; then
   2.182  							# Search for package in mirror
   2.183  							name="$(awk -F$'\t' -vi="$i" '$1==i{print $1; exit}' "$root$DB/packages.info")"
   2.184 @@ -1031,265 +1053,14 @@
   2.185  	# ERROR can be echoed any time in cookit()
   2.186  	if grep -Ev "(conftest|configtest)" $LOGS/$pkg.log | \
   2.187  	   grep -Eq "(^ERROR|undefined reference to)" ; then
   2.188 -		debug_info | tee -a $LOGS/$pkg.log
   2.189 +		debug_info "cookit_quality" | tee -a $LOGS/$pkg.log
   2.190  		put_status $pkg Failed
   2.191 -		rm -f $command
   2.192 -		broken; exit 1
   2.193 +#		rm -f $command
   2.194 +#		broken; exit 1
   2.195  	fi
   2.196  }
   2.197  
   2.198  
   2.199 -# Create the package. Wanted to use TazPkg to create a tazpkg package at first,
   2.200 -# but it doesn't handle EXTRAVERSION.
   2.201 -
   2.202 -packit() {
   2.203 -	set_paths "$1"
   2.204 -	PACKAGE="${1:-$PACKAGE}"
   2.205 -
   2.206 -	# Handle cross compilation
   2.207 -	case "$ARCH" in
   2.208 -		arm*|x86_64) arch="-$ARCH" ;;
   2.209 -	esac
   2.210 -
   2.211 -	title 'Pack: %s' "$PACKAGE $VERSION$arch"
   2.212 -
   2.213 -	# Get set name for specified package from $SPLIT variable
   2.214 -	local set=$(echo -n $SPLIT \
   2.215 -				| awk -vpkg="$PACKAGE" '
   2.216 -					BEGIN { RS = " "; FS = ":"; }
   2.217 -					{ if ($1 == pkg && $2 != "") { print "-" $2; exit; } }')
   2.218 -	# Change set, make filelist and folderlist for new set
   2.219 -	export     src="$src$set"
   2.220 -	export install="$install$set"
   2.221 -	export DESTDIR="$install"
   2.222 -
   2.223 -	if grep -q ^genpkg_rules $receipt; then
   2.224 -		_ 'Executing: %s' 'genpkg_rules'
   2.225 -		set -e; cd $pkgdir; mkdir -p $fs
   2.226 -		genpkg_rules || (newline; _ 'ERROR: genpkg_rules failed'; newline) >> \
   2.227 -			$LOGS/$pkg.log
   2.228 -	else
   2.229 -		_ 'No packages rules: meta package'
   2.230 -		mkdir -p $fs
   2.231 -	fi
   2.232 -
   2.233 -	# Check CONFIG_FILES
   2.234 -	if [ -n "$CONFIG_FILES" ]; then
   2.235 -		unset IFS
   2.236 -		for i in $CONFIG_FILES; do
   2.237 -			if [ ! -e $fs$i ]; then
   2.238 -				case $i in
   2.239 -					*/) mkdir -p $fs$i ;;
   2.240 -					*)  mkdir -p $fs$(dirname $i); touch $fs$i ;;
   2.241 -				esac
   2.242 -			fi
   2.243 -		done
   2.244 -	fi
   2.245 -
   2.246 -	# First QA check to stop now if genpkg_rules failed.
   2.247 -	lerror=$(_n 'ERROR')
   2.248 -	if fgrep -q ^$lerror $LOGS/$pkg.log; then
   2.249 -		broken; exit 1
   2.250 -	fi
   2.251 -
   2.252 -	cd $taz
   2.253 -	action 'Copying "%s"...' 'receipt'
   2.254 -	export PACKAGE VERSION CATEGORY SHORT_DESC WEB_SITE DEPENDS PROVIDE SUGGESTED TAZPANEL_DAEMON TAGS CAT CONFIG_FILES
   2.255 -	@@PREFIX@@/libexec/cookutils/mk_pkg_receipt "$(realpath ../receipt)" > $pack/receipt
   2.256 -	chown 0.0 $pack/receipt; status
   2.257 -
   2.258 -	unset desc
   2.259 -	[ "$pkg" == "$PACKAGE" -a -f "../description.txt" ] && desc="../description.txt"
   2.260 -	[ -f "../description.$PACKAGE.txt" ] && desc="../description.$PACKAGE.txt"
   2.261 -	if [ -n "$desc" ]; then
   2.262 -		action 'Copying "%s"...' "$(basename "$desc")"
   2.263 -		cp -f $desc $pack/description.txt; chown 0.0 $pack/description.txt; status
   2.264 -	fi
   2.265 -
   2.266 -	copy_generic_files
   2.267 -
   2.268 -	# Strip and stuff files.
   2.269 -	export COOKOPTS ARCH HOST_SYSTEM LOCALE fs; @@PREFIX@@/libexec/cookutils/compressor fs
   2.270 -
   2.271 -	# Create files.list with redirecting find output.
   2.272 -	action 'Creating the list of files...'
   2.273 -	cd $fs
   2.274 -	find . -type f -print >  ../files.list
   2.275 -	find . -type l -print >> ../files.list
   2.276 -	cd ..; sed -i 's|^.||' files.list
   2.277 -	status
   2.278 -
   2.279 -	# Md5sum of files.
   2.280 -	action 'Creating md5sum of files...'
   2.281 -	while read file; do
   2.282 -		[ -L "fs$file" ] && continue
   2.283 -		[ -f "fs$file" ] || continue
   2.284 -		case "$file" in
   2.285 -			/lib/modules/*/modules.*|*.pyc) continue ;;
   2.286 -		esac
   2.287 -		md5sum "fs$file" | sed 's|  fs|  |'
   2.288 -	done < files.list | sort -k2 > md5sum
   2.289 -	status
   2.290 -
   2.291 -	UNPACKED_SIZE=$(du -chs fs receipt files.list md5sum description.txt \
   2.292 -		2>/dev/null | awk 'END{ print $1 }')
   2.293 -
   2.294 -	# Build cpio archive.
   2.295 -	action 'Compressing the FS...'
   2.296 -	find fs -newer $receipt -exec touch -hr $receipt '{}' \;
   2.297 -#	find fs | cpio -o -H newc --quiet | lzma-alone e fs.cpio.lzma -si
   2.298 -	find fs | cpio -o -H newc --quiet | /bin/lzma -qzeT0 >fs.cpio.lzma
   2.299 -	mv fs ../
   2.300 -	status
   2.301 -
   2.302 -	PACKED_SIZE=$(du -chs fs.cpio.lzma receipt files.list md5sum description.txt \
   2.303 -		2>/dev/null | awk 'END{ print $1 }')
   2.304 -
   2.305 -	action 'Updating receipt sizes...'
   2.306 -	sed -i '/^PACKED_SIZE=/d; /^UNPACKED_SIZE=/d' receipt
   2.307 -	sed -i "s|^PACKAGE=|PACKED_SIZE=\"$PACKED_SIZE\"\nUNPACKED_SIZE=\"$UNPACKED_SIZE\"\nPACKAGE=|" receipt
   2.308 -	status
   2.309 -
   2.310 -	# Set extra version.
   2.311 -	if [ -n "$EXTRAVERSION" ]; then
   2.312 -		action 'Updating receipt EXTRAVERSION: %s' "$EXTRAVERSION"
   2.313 -		sed -i '/^EXTRAVERSION=/d' receipt
   2.314 -		sed -i "s|^VERSION=|EXTRAVERSION=\"$EXTRAVERSION\"\nVERSION=|" receipt
   2.315 -		status
   2.316 -	fi
   2.317 -
   2.318 -	# Compress.
   2.319 -	action 'Creating full cpio archive...'
   2.320 -	find . -newer $receipt -exec touch -hr $receipt '{}' \;
   2.321 -	find . | cpio -o -H newc --quiet > ../$PACKAGE-$VERSION$EXTRAVERSION$arch.tazpkg
   2.322 -	status
   2.323 -
   2.324 -	# Restoring original package tree.
   2.325 -	mv ../fs .
   2.326 -
   2.327 -	rm fs.cpio.lzma; cd ..
   2.328 -
   2.329 -	# QA and give info.
   2.330 -	tazpkg=$(ls *.tazpkg)
   2.331 -	packit_quality
   2.332 -	footer "$(_ 'Package "%s" created' "$tazpkg")"
   2.333 -}
   2.334 -
   2.335 -
   2.336 -# Verify package quality and consistency.
   2.337 -
   2.338 -packit_quality() {
   2.339 -	local arch=''
   2.340 -	case "$ARCH" in
   2.341 -		arm*|x86_64) arch="-$ARCH" ;;
   2.342 -	esac
   2.343 -
   2.344 -	local rsum rsumold='' rsum_changed old_file
   2.345 -	local pi="$PKGS/packages.info" fl="$cache/files.list"
   2.346 -	local pkg_file="$PKGS/$PACKAGE-$VERSION$EXTRAVERSION$arch.tazpkg"
   2.347 -	local rsum_file=$(mktemp) rsum_file_old=$(mktemp) tmpdir=$(mktemp -d)
   2.348 -
   2.349 -
   2.350 -	if [ "${COOKOPTS/skip-log-errors/}" == "$COOKOPTS" ]; then
   2.351 -		# Exit if any error found in log file.
   2.352 -		if fgrep -q ^ERROR $LOGS/$pkg.log; then
   2.353 -			rm -f $command
   2.354 -			broken; exit 1
   2.355 -		fi
   2.356 -	fi
   2.357 -
   2.358 -
   2.359 -	[ -n "$CAT" ] && CATEGORY="${CAT%|*}"	# allow meta-packages in v2 receipts
   2.360 -
   2.361 -	if [ "${COOKOPTS/empty-pkg/}" == "$COOKOPTS" ]; then
   2.362 -		action 'QA: checking for empty package...'
   2.363 -		if [ ! -s "$pack/files.list" -a "$CATEGORY" != 'meta' ]; then
   2.364 -			broken
   2.365 -			rm -f $command
   2.366 -			false; status
   2.367 -			die 'ERROR: empty package'
   2.368 -		fi
   2.369 -		:; status
   2.370 -	fi
   2.371 -
   2.372 -
   2.373 -	# Calculate release checksum: usually it does not change on "just recook".
   2.374 -	# Release checksum is md5sum of file containing md5sums of:
   2.375 -	# a) all files, b) receipt, and c) description.txt.
   2.376 -	# Md5sum of the package file will change every time because of embedded timestamps;
   2.377 -	# release checksum based only on files content, and will change only when files change.
   2.378 -	# (Pitfall: ownership and permissions...)
   2.379 -
   2.380 -	# Calculate rsum for new package
   2.381 -	cp $pack/md5sum $rsum_file
   2.382 -	md5sum $pack/receipt | sed 's| [^ ]*/| |' >> $rsum_file
   2.383 -	[ -e "$pack/description.txt" ] &&
   2.384 -		md5sum $pack/description.txt | sed 's| [^ ]*/| |' >> $rsum_file
   2.385 -	rsum=$(md5sum $rsum_file | awk '{print $1}')
   2.386 -
   2.387 -	# Calculate rsum for existing previous "old" package
   2.388 -	if [ -f "$pkg_file" ]; then
   2.389 -		# don't trust database entry, check the package file
   2.390 -		cd $tmpdir
   2.391 -		cpio -F "$pkg_file" -i md5sum receipt description.txt >/dev/null 2>&1
   2.392 -		cp ./md5sum $rsum_file_old
   2.393 -		md5sum ./receipt | sed 's| [^ ]*/| |' >> $rsum_file_old
   2.394 -		[ -e "./description.txt" ] &&
   2.395 -			md5sum ./description.txt | sed 's| [^ ]*/| |' >> $rsum_file_old
   2.396 -		rsumold=$(md5sum $rsum_file_old | awk '{print $1}')
   2.397 -		cd - >/dev/null
   2.398 -	fi
   2.399 -
   2.400 -	# Clean
   2.401 -	rm $rsum_file $rsum_file_old
   2.402 -	rm -r $tmpdir
   2.403 -
   2.404 -
   2.405 -	touch $pi $broken
   2.406 -
   2.407 -
   2.408 -	# Find and remove old package only if "release checksum" has changed
   2.409 -
   2.410 -	if [ "$rsum" != "$rsumold" ]; then
   2.411 -		old_file=$(awk -F$'\t' -vname="$PACKAGE" -varch="$arch" '{
   2.412 -			if ($1 == name) printf("%s-%s%s.tazpkg", $1, $2, arch);
   2.413 -			}' $pi)		# <name>-<version><extra_version><-arch>.tazpkg
   2.414 -		if [ -f "$PKGS/$old_file" ]; then
   2.415 -			action 'Removing old package "%s"' "$old_file"
   2.416 -			rm -f "$PKGS/$old_file"
   2.417 -			status
   2.418 -		fi
   2.419 -		# package changed, substitute old package by new one
   2.420 -		mv -f $pkgdir/taz/$PACKAGE-$VERSION$EXTRAVERSION$arch.tazpkg $PKGS
   2.421 -		_ 'The release checksum has changed.'
   2.422 -	else
   2.423 -		# package not changed, remove new package
   2.424 -		rm -f $pkgdir/taz/$PACKAGE-$VERSION$EXTRAVERSION$arch.tazpkg
   2.425 -		_ 'The release checksum has not changed.'
   2.426 -	fi
   2.427 -
   2.428 -
   2.429 -	sed -i "/^${pkg}$/d" $broken
   2.430 -
   2.431 -
   2.432 -	# Update packages database every time after successful build
   2.433 -
   2.434 -	# packages.info (unsorted, located near to packages)
   2.435 -	unset_receipt; . $pack/receipt
   2.436 -	SIZES=$(echo $PACKED_SIZE $UNPACKED_SIZE | sed 's|\.0||g')
   2.437 -	DEPENDS=$(echo $DEPENDS) # remove newlines, tabs and multiple spaces from variable
   2.438 -	sed -i "/^$PACKAGE\t/d" $pi		# remove old entry
   2.439 -	cat >> $pi <<EOT
   2.440 -$PACKAGE	$VERSION$EXTRAVERSION	$CATEGORY	$SHORT_DESC	$WEB_SITE	$TAGS	$SIZES	$DEPENDS	$rsum	$PROVIDE
   2.441 -EOT
   2.442 -
   2.443 -	# files.list (uncompressed, unsorted, located in $cache)
   2.444 -	touch $fl
   2.445 -	sed -i "/^$PACKAGE: /d" $fl
   2.446 -	sed  "s/^/$PACKAGE: \0/" $pack/files.list >> $fl
   2.447 -}
   2.448 -
   2.449 -
   2.450  # Return all the names of packages bundled in this receipt
   2.451  
   2.452  all_names() {
   2.453 @@ -1319,13 +1090,15 @@
   2.454  
   2.455  packall() {
   2.456  	set_paths
   2.457 +	[ -e $pkgdir/.arch ] && rm $pkgdir/.arch
   2.458 +
   2.459  	if head -n1 "$pkgdir/receipt" | fgrep -q 'v2'; then
   2.460  		for i in $(all_names); do
   2.461  			unset TAGS DEPENDS CAT CONFIG_FILES PROVIDE SUGGESTED DATABASE_FILES TAZPANEL_DAEMON
   2.462 -			packit $i
   2.463 +			export PACKAGE; @@PREFIX@@/libexec/cookutils/pack $i
   2.464  		done
   2.465  	else
   2.466 -		packit
   2.467 +		export PACKAGE; @@PREFIX@@/libexec/cookutils/pack $PACKAGE
   2.468  	fi
   2.469  }
   2.470  
   2.471 @@ -1337,50 +1110,31 @@
   2.472  }
   2.473  
   2.474  
   2.475 -# Update chroot with freshly rebuilt package: keep env up-to-date.
   2.476 -
   2.477 -update_chroot() {
   2.478 -	local PACKAGE="$pkg"
   2.479 -	for i in $(all_names); do
   2.480 -		if [ -d "$root$INSTALLED/$i" ]; then
   2.481 -			. /etc/slitaz/cook.conf
   2.482 -			. $WOK/$pkg/taz/$i-$VERSION$EXTRAVERSION/receipt
   2.483 -			_ 'Updating %s chroot environment...' "$ARCH"
   2.484 -			_ 'Updating chroot: %s' "$i ($VERSION$EXTRAVERSION$arch)" | log
   2.485 -			cd $PKGS
   2.486 -			tazpkg -i "$PKGS/$i-$VERSION$EXTRAVERSION$arch.tazpkg" --forced --root=$root
   2.487 -		fi
   2.488 -	done
   2.489 -}
   2.490 -
   2.491 -
   2.492 -# Install package on --inst or update the chroot.
   2.493 +# Install package: update the chroot with freshly rebuilt package: keep env up-to-date.
   2.494  
   2.495  install_package() {
   2.496  	set_paths
   2.497  	case "$ARCH" in
   2.498 -		arm*)
   2.499 -			arch="-$ARCH"
   2.500 -			root="$CROSS_TREE/sysroot"
   2.501 -			;;
   2.502 -		x86_64)
   2.503 -			arch="-$ARCH"
   2.504 -			;;
   2.505 +		arm*) root="$CROSS_TREE/sysroot";;
   2.506  	esac
   2.507 -	# Install package if requested but skip install if target host doesn't
   2.508 -	# match build system or it will break the build chroot.
   2.509 -	build=$(echo $BUILD_SYSTEM | cut -d- -f1)
   2.510 -	if [ -n "$inst" -a "$build" == "$ARCH" ]; then
   2.511 -		if [ -f "$PKGS/$PACKAGE-$VERSION$EXTRAVERSION$arch.tazpkg" ]; then
   2.512 -			cd $PKGS
   2.513 -			tazpkg -i "$PKGS/$PACKAGE-$VERSION$EXTRAVERSION$arch.tazpkg" --forced
   2.514 -		else
   2.515 -			broken
   2.516 -			die 'Unable to install package, build has failed.'
   2.517 +
   2.518 +	# Process all the package names built by this receipt (defined in $SPLIT)
   2.519 +	for i in $(PACKAGE="$pkg" all_names); do
   2.520 +		if [ -d "$root$INSTALLED/$i" ]; then
   2.521 +			pkg_file=$(awk -F$'\t' -vpkg="$i" -varch="$ARCH" '{
   2.522 +				if ($1 == pkg) {
   2.523 +					pkgarch = ($11 == "0") ? "any" : arch;
   2.524 +					printf("%s-%s-%s.tazpkg", $1, $2, pkgarch);
   2.525 +					exit
   2.526 +				}
   2.527 +			}' $PKGS/packages-$ARCH.info)
   2.528 +			if [ -e "$PKGS/$pkg_file" ]; then
   2.529 +				_ 'Updating %s chroot environment...' "$ARCH"
   2.530 +				_ 'Updating chroot: %s' "${pkg_file%.tazpkg}" | log
   2.531 +				tazpkg -i "$PKGS/$pkg_file" --forced --root=$root
   2.532 +			fi
   2.533  		fi
   2.534 -	fi
   2.535 -
   2.536 -	update_chroot
   2.537 +	done
   2.538  }
   2.539  
   2.540  
   2.541 @@ -1452,14 +1206,26 @@
   2.542  # Create a XML feed for freshly built packages.
   2.543  
   2.544  gen_rss() {
   2.545 -	pubdate=$(date '+%a, %d %b %Y %X')
   2.546 +	if [ -e "$WOK/$PACKAGE/.icon.png" ]; then
   2.547 +		icon="$COOKER_URL$PACKAGE/browse/.icon.png"
   2.548 +	else
   2.549 +		icon="http://cook.slitaz.org/tazpkg.png"
   2.550 +	fi
   2.551 +
   2.552  	cat > $FEEDS/$pkg.xml <<EOT
   2.553  	<item>
   2.554  		<title>$PACKAGE $VERSION$EXTRAVERSION</title>
   2.555 -		<link>${COOKER_URL}?pkg=${PACKAGE//+/%2B}</link>
   2.556 -		<guid>$PACKAGE-$VERSION$EXTRAVERSION</guid>
   2.557 -		<pubDate>$pubdate</pubDate>
   2.558 -		<description>$(echo -n "$SHORT_DESC" | xml_ent)</description>
   2.559 +		<link>$COOKER_URL${PACKAGE//+/%2B}</link>
   2.560 +		<guid isPermaLink="false">$PACKAGE-$VERSION$EXTRAVERSION</guid>
   2.561 +		<pubDate>$(date '+%a, %d %b %Y %X GMT')</pubDate>
   2.562 +		<description><![CDATA[
   2.563 +			<table>
   2.564 +				<tr>
   2.565 +					<td vertical-align="top"><img src="$icon" alt=""/></td>
   2.566 +					<td>$(echo -n "$SHORT_DESC" | xml_ent)</td>
   2.567 +				</tr>
   2.568 +			</table>
   2.569 +		]]></description>
   2.570  	</item>
   2.571  EOT
   2.572  }
   2.573 @@ -1518,212 +1284,6 @@
   2.574  }
   2.575  
   2.576  
   2.577 -# Function to use in genpkg_rules() to copy specified files from $install to $fs
   2.578 -
   2.579 -cook_copy_files() {
   2.580 -	action 'Copying files...'
   2.581 -	cd $install
   2.582 -	local i j
   2.583 -	IFS=$'\n'
   2.584 -	for i in $@; do
   2.585 -		for j in $(find . -name $i ! -type d); do
   2.586 -			mkdir -p $fs$(dirname ${j#.})
   2.587 -			scopy $j $fs$(dirname ${j#.})
   2.588 -		done
   2.589 -	done
   2.590 -	cd - >/dev/null
   2.591 -	status
   2.592 -}
   2.593 -
   2.594 -
   2.595 -# Function to use in genpkg_rules() to copy specified folders from $install to $fs
   2.596 -
   2.597 -cook_copy_folders() {
   2.598 -	action 'Copying folders...'
   2.599 -	cd $install
   2.600 -	local i j
   2.601 -	IFS=$'\n'
   2.602 -	for i in $@; do
   2.603 -		for j in $(find . -name $i -type d); do
   2.604 -			mkdir -p $fs$(dirname ${j#.})
   2.605 -			cp -a $j $fs$(dirname ${j#.})
   2.606 -		done
   2.607 -	done
   2.608 -	cd - >/dev/null
   2.609 -	status
   2.610 -}
   2.611 -
   2.612 -
   2.613 -# Remove from current $fs files that are already packed (for receipts v2).
   2.614 -# Note: the order in $SPLIT is very important.
   2.615 -# Note 2: working in the current set.
   2.616 -
   2.617 -remove_already_packed() {
   2.618 -	local i j
   2.619 -	# $pkg is the name of the main package; $PACKAGE is the name of the current one
   2.620 -	# $pkg may (or may not) be included in the $SPLIT
   2.621 -	neighbors=$(
   2.622 -		echo $pkg $SPLIT" " \
   2.623 -		| awk -F$'\t' -vpkg="$PACKAGE" '
   2.624 -		BEGIN { RS = " "; FS = ":"; }
   2.625 -		      { set[$1] = $2; }
   2.626 -		END   {
   2.627 -		        current_set = set[pkg];
   2.628 -		        for (i in set)
   2.629 -		          { if (i != pkg && set[i] == current_set) print i; }
   2.630 -		}
   2.631 -	')
   2.632 -	IFS=$'\n'
   2.633 -	for neighbor in $neighbors; do
   2.634 -		i="$taz/$neighbor-$VERSION$EXTRAVERSION/files.list"
   2.635 -		[ -e "$i" ] || continue
   2.636 -		while read j; do
   2.637 -			[ -f $fs$j -o -h $fs$j ] || continue
   2.638 -			rm $fs$j
   2.639 -			rmdir --parents --ignore-fail-on-non-empty $fs$(dirname $j)
   2.640 -		done < $i
   2.641 -	done
   2.642 -	unset IFS
   2.643 -}
   2.644 -
   2.645 -
   2.646 -# Function to use in genpkg_rules() to copy hicolor icons in specified sizes
   2.647 -# (default: 16 and 48) from $install to $fs
   2.648 -
   2.649 -cook_copy_icons() {
   2.650 -	local sizes=$@ i j ifs="$IFS"
   2.651 -	unset IFS
   2.652 -	action 'Copying hicolor icons...'
   2.653 -	[ -d "$fs/usr/share/icons/hicolor" ] && rm -rf "$fs/usr/share/icons/hicolor"
   2.654 -	mkdir -p $fs/usr/share/icons/hicolor
   2.655 -	for i in ${sizes:-16 48}; do
   2.656 -		j="${i}x$i"; [ "$i" == 'scalable' ] && j="$i"
   2.657 -		[ ! -e "$install/usr/share/icons/hicolor/$j" ] ||
   2.658 -		scopy   $install/usr/share/icons/hicolor/$j \
   2.659 -			         $fs/usr/share/icons/hicolor
   2.660 -	done
   2.661 -	status
   2.662 -	IFS="$ifs"
   2.663 -}
   2.664 -
   2.665 -
   2.666 -# Common function to copy files, folders and patterns
   2.667 -
   2.668 -copy() {
   2.669 -	action 'Copying folders and files...'
   2.670 -	local i j k filelist=$(mktemp) folderlist=$(mktemp)
   2.671 -
   2.672 -	IFS=$'\n'
   2.673 -	cd $install
   2.674 -	find ! -type d | sed 's|\.||' > $filelist
   2.675 -	find   -type d | sed 's|\.||' > $folderlist
   2.676 -
   2.677 -	for i in $@; do
   2.678 -		case $i in
   2.679 -			@std)
   2.680 -				# Copy "standard" files (all but "developer files", man pages, documentation, translations)
   2.681 -				sed '/\.h$/d; /\.hxx$/d; /\.a$/d; /\.la$/d; /\.pc$/d; /\.pri$/d; /bin\/.*-config$/d;
   2.682 -					/\.m4$/d; /\.gir$/d; /\.typelib$/d; /\.vapi$/d; /\.deps$/d; /\.cmake$/d;
   2.683 -					/\/Makefile.*/d; /\.inc$/d; /\/include\//d;
   2.684 -					/\/share\/man\//d; /\/share\/doc\//d; /\/share\/gtk-doc\//d; /\/share\/info\//d;
   2.685 -					/\/share\/devhelp\//d; /\/share\/locale\//d;
   2.686 -					/\/share\/bash-completion\//d; /\/etc\/bash_completion\.d\//d; /\/lib\/systemd\//d;
   2.687 -					/\/fonts\.scale$/d; /\/fonts\.dir$/d;
   2.688 -					/\/share\/appdata\//d; /\/share\/help\//d; /\/share\/metainfo\//d; /\/share\/mimelnk\//d;
   2.689 -					/\/share\/icons\/hicolor\/[12356][1245][268]*x[12356][1245][268]*\//d;	# 22, 24, 32, 64, 128, 256, 512
   2.690 -					/\.so\.dbg$/d;
   2.691 -					' $filelist
   2.692 -				;;
   2.693 -			@dev)
   2.694 -				# Copy "developer files"
   2.695 -				sed -n '/\.h$/p; /\.hxx$/p; /\.a$/p; /\.pc$/p; /\.pri$/p; /bin\/.*-config$/p;
   2.696 -					/\.m4$/p; /\.gir$/p; /\.typelib$/p; /\.vapi$/p; /\.deps$/p; /\.cmake$/p;
   2.697 -					/\/Makefile.*/p; /\.inc$/p; /\/include\//p;
   2.698 -					/\.so\.dbg$/p;
   2.699 -					' $filelist
   2.700 -				;;
   2.701 -			@ruby)
   2.702 -				# Copy mandatory Ruby files
   2.703 -				gem_base="\/usr\/lib\/ruby\/gems\/.*\/${PACKAGE#*-}-$VERSION"
   2.704 -				sed -n '/\/extensions\/.*\.so$/p; /'$gem_base'\/lib\//p; /\.gemspec$/p;
   2.705 -					/\/usr\/bin\//p; /\/gems\/.*\/bin\//p;
   2.706 -					' $filelist | sed '/\/gems\/.*\/lib\/.*\.so$/d; /\/gems\/.*\/lib\/.*\.h$/d;
   2.707 -					/\/gems\/.*\/gems\/.*\.gemspec$/d;'
   2.708 -				;;
   2.709 -			@ruby-dev)
   2.710 -				sed -n '/\/ext\/.*\.h$/p; /\/ext\/.*\.pc$/p; /\/gem.build_complete$/p;
   2.711 -					/\/gems\/.*\/lib\/.*\.h$/p;
   2.712 -					' $filelist
   2.713 -				;;
   2.714 -			@rm)
   2.715 -				# Quick alias
   2.716 -				remove_already_packed
   2.717 -				;;
   2.718 -			@ico)
   2.719 -				# Quick alias
   2.720 -				cook_copy_icons >/dev/null
   2.721 -				;;
   2.722 -			*/)
   2.723 -				# Copy specified folders.
   2.724 -				i="${i%/}"
   2.725 -				find -type d -path "*/${i#/}" | sed 's|^.||'
   2.726 -				;;
   2.727 -			*)
   2.728 -				# Copy specified files.
   2.729 -				find ! -type d -path "*/${i#/}" | sed 's|^.||'
   2.730 -				;;
   2.731 -		esac \
   2.732 -		| sort -u \
   2.733 -		| while read j; do
   2.734 -			mkdir -p $fs$(dirname "$j")
   2.735 -			if [ -d "$install$j" ]; then
   2.736 -				cp -a "$install$j" $fs$(dirname "$j")
   2.737 -			else
   2.738 -				scopy "$install$j" $fs$(dirname "$j")
   2.739 -			fi
   2.740 -		done
   2.741 -		# Copy empty directories
   2.742 -		case $i in
   2.743 -			@std)
   2.744 -				while read j; do
   2.745 -					case $j in
   2.746 -						# skip empty man & doc folders
   2.747 -						*/man/*|*/doc/*) continue;;
   2.748 -					esac
   2.749 -					[ -z "$(ls -A "$install$j")" ] || continue
   2.750 -					# directory $j is empty
   2.751 -					k="$j"
   2.752 -					# make 'ladder' from directories, from root dir to $j
   2.753 -					# /a   /a/b   /a/b/c   etc.
   2.754 -					while :; do
   2.755 -						[ -z "$k" ] && break
   2.756 -						echo "$k"
   2.757 -						k="${k%/*}"
   2.758 -					done \
   2.759 -					| tac \
   2.760 -					| while read k; do
   2.761 -						# make dir if it does not exist
   2.762 -						if [ ! -d "$fs$k" ]; then
   2.763 -							# It's like "copy the directory without its underlying content".
   2.764 -							# keep original ownership/permissions, access:
   2.765 -							keepIFS="$IFS"; unset IFS
   2.766 -							install -d $(stat -c'-o%u -g%g -m%a' "$install$k") "$fs$k"
   2.767 -							# keep last-modified date:
   2.768 -							touch -r "$install$k" "$fs$k"
   2.769 -							IFS="$keepIFS"; unset keepIFS
   2.770 -						fi
   2.771 -					done
   2.772 -				done < $folderlist
   2.773 -				;;
   2.774 -		esac
   2.775 -	done
   2.776 -	cd - >/dev/null
   2.777 -	unset IFS
   2.778 -	rm $filelist $folderlist
   2.779 -	status
   2.780 -}
   2.781 -
   2.782 -
   2.783  # Update split.db once for receipt
   2.784  
   2.785  update_split_db() {
   2.786 @@ -2194,6 +1754,9 @@
   2.787  			exit 0
   2.788  		fi
   2.789  
   2.790 +		# Remove package from broken list before cooking
   2.791 +		sed -i "/^${pkg}$/d" $broken
   2.792 +
   2.793  		# Skip blocked, 3 lines also for the Cooker.
   2.794  		grep -q "^$pkg$" $blocked && [ "$2" != '--unblock' ] &&
   2.795  			die 'Package "%s" is blocked' "$pkg"
   2.796 @@ -2201,7 +1764,6 @@
   2.797  		try_aufs_chroot "$@"
   2.798  
   2.799  		# Log and source receipt.
   2.800 -		_ 'Cook started for: %s' "<a href='cooker.cgi?pkg=${pkg//+/%2B}'>$pkg</a>" | log
   2.801  		echo "cook:$pkg" > $command
   2.802  
   2.803  		[ -n "$lastcooktime" ] && echo "cook:$pkg $lastcooktime $(date +%s)" >> $cooktime
   2.804 @@ -2220,18 +1782,17 @@
   2.805  
   2.806  		# Handle --options
   2.807  		case "$2" in
   2.808 -			--install|-i)
   2.809 -				inst='yes' ;;
   2.810 -
   2.811  			--pack)
   2.812 +				_ 'Packing %s' "<a href='cooker.cgi?pkg=${pkg//+/%2B}'>$pkg</a>" | log
   2.813  				[ -d "$WOK/$pkg/install" ] || die 'Need to build "%s"' "$pkg"
   2.814  				[ ! -d "$WOK/$pkg/taz" ] || rm -rf "$WOK/$pkg/taz"
   2.815  				[ ! -f "$LOGS/$pkg-pack.log" ] || rm -f $LOGS/$pkg-pack.log
   2.816 -				sed -i '$ s|$| (packing)|' $activity
   2.817  				packall 2>&1 | tee -a $LOGS/$pkg-pack.log
   2.818 +				@@PREFIX@@/libexec/cookutils/postcheck $pkg | tee -a $LOGS/$pkg.log
   2.819  				clean_log "$pkg-pack"
   2.820  				time=$(($(date +%s) - $time))
   2.821  				summary | sed 's|^Cook |Pack |' | tee -a $LOGS/$pkg-pack.log
   2.822 +				gen_rss
   2.823  				put_status $pkg Done
   2.824  				rm -f $command
   2.825  				exit 0 ;;
   2.826 @@ -2240,6 +1801,8 @@
   2.827  				trials='yes' ;;
   2.828  		esac
   2.829  
   2.830 +		_ 'Making %s' "<a href='cooker.cgi?pkg=${pkg//+/%2B}'>$pkg</a>" | log
   2.831 +
   2.832  		# Rotate log
   2.833  		for i in $(seq 9 -1 1); do
   2.834  			j=$(($i - 1))
   2.835 @@ -2265,21 +1828,27 @@
   2.836  		done
   2.837  
   2.838  		# Cook and pack or exit on error and log everything.
   2.839 -		((((cookit $@ 2>&1; echo $? >&3) | loglimit 50 > $LOGS/$pkg.log) 3>&1) | (read rq; exit $rq))
   2.840 +		( ( ( (cookit $@ 2>&1; echo $? >&3) | loglimit 50 > $LOGS/$pkg.log) 3>&1) | (read rq; exit $rq) )
   2.841  		rq=$?	# the return code of `cookit $@` above command
   2.842  
   2.843 +		if [ $rq -eq 1 ]; then
   2.844 +			broken
   2.845 +		fi
   2.846 +
   2.847  		# Remove build dependencies both when `cookit` done or fail
   2.848  		remove_deps | tee -a $LOGS/$pkg.log
   2.849  		timestamp job27 # removing bdeps
   2.850 -		cookit_quality
   2.851 +#		cookit_quality
   2.852  		timestamp job28 # checking quality
   2.853  
   2.854  		# Log and stop if `cookit` fails
   2.855  		if [ $rq -eq 1 ]; then
   2.856 -			debug_info | tee -a $LOGS/$pkg.log
   2.857 +			debug_info "ret1" | tee -a $LOGS/$pkg.log
   2.858 +			@@PREFIX@@/libexec/cookutils/postcheck $pkg | tee -a $LOGS/$pkg.log
   2.859  			put_status $pkg Failed
   2.860  			rm -f $command
   2.861 -			broken; exit 1
   2.862 +			broken
   2.863 +			exit 1
   2.864  		fi
   2.865  
   2.866  		# Proceed only if `cookit` return code is zero-OK
   2.867 @@ -2288,13 +1857,15 @@
   2.868  		packall 2>&1 | loglimit 5 >> $LOGS/$pkg.log
   2.869  		timestamp job29 # packing
   2.870  
   2.871 +		@@PREFIX@@/libexec/cookutils/postcheck $pkg | tee -a $LOGS/$pkg.log
   2.872 +
   2.873  		clean_log
   2.874  
   2.875  		# Exit if any error in packing.
   2.876  		if [ "${COOKOPTS/skip-log-errors/}" == "$COOKOPTS" ] &&
   2.877  			grep -Ev "(/root/.cvspass|conftest|df: /|rm: can't remove)" $LOGS/$pkg.log | \
   2.878  			grep -Eq "(^ERROR|: No such file or directory|not remade because of errors|ake: \*\*\* .* Error)"; then
   2.879 -			debug_info | tee -a $LOGS/$pkg.log
   2.880 +			debug_info "packerr" | tee -a $LOGS/$pkg.log
   2.881  			put_status $pkg Failed
   2.882  			rm -f $command
   2.883  			broken; exit 1
     3.1 --- a/cook.conf	Sat Aug 25 17:30:05 2018 +0300
     3.2 +++ b/cook.conf	Sat Nov 24 13:28:02 2018 +0200
     3.3 @@ -120,7 +120,7 @@
     3.4  CONFIGURE_ARGS="--build=$BUILD_SYSTEM --host=$HOST_SYSTEM"
     3.5  
     3.6  # Mirrors URLs. To download sources near your location.
     3.7 -GNU_MIRROR="http://mirror.switch.ch/ftp/mirror/gnu"
     3.8 +GNU_MIRROR="https://ftp.igh.cnrs.fr/pub/gnu" # see https://www.gnu.org/prep/ftp.html
     3.9  SF_MIRROR="https://downloads.sourceforge.net"
    3.10  XORG_MIRROR="https://www.x.org/archive/individual"
    3.11  GNOME_MIRROR="http://ftp.gnome.org/pub/GNOME/sources"
     4.1 --- a/cooker	Sat Aug 25 17:30:05 2018 +0300
     4.2 +++ b/cooker	Sat Nov 24 13:28:02 2018 +0200
     4.3 @@ -554,7 +554,7 @@
     4.4  		done
     4.5  		strip_blocked
     4.6  		cook_order | tee $LOGS/cookorder.log
     4.7 -		echo "Packages to cook: $(wc -l < $cooklist)" | log
     4.8 +		echo "Receipts or stuff changed: $(wc -l < $cooklist)" | log
     4.9  		cook_list ;;
    4.10  
    4.11  	tasks|-T)
    4.12 @@ -716,9 +716,12 @@
    4.13  		echo "Packages to cook : $pkgs" | log_commits
    4.14  		separator | log_commits
    4.15  		newline
    4.16 -		strip_blocked
    4.17 -		cook_order | tee $LOGS/cookorder.log
    4.18 -		cook_commits
    4.19 +		# Just update the wok on --update, don't cook any package
    4.20 +		if [ -z "$update" ]; then
    4.21 +			strip_blocked
    4.22 +			cook_order | tee $LOGS/cookorder.log
    4.23 +			cook_commits
    4.24 +		fi
    4.25  		clean_exit ;;
    4.26  esac
    4.27  
     5.1 --- a/lighttpd/cooker-terminal.css	Sat Aug 25 17:30:05 2018 +0300
     5.2 +++ b/lighttpd/cooker-terminal.css	Sat Nov 24 13:28:02 2018 +0200
     5.3 @@ -229,6 +229,8 @@
     5.4  	display: block;
     5.5  }
     5.6  
     5.7 +img {display: none;}
     5.8 +
     5.9  
    5.10  /* FOLLOWING CSS HAS SOME CHANGES FOR SLITAZ COOKER! */
    5.11  
     6.1 --- a/lighttpd/cooker.css	Sat Aug 25 17:30:05 2018 +0300
     6.2 +++ b/lighttpd/cooker.css	Sat Nov 24 13:28:02 2018 +0200
     6.3 @@ -200,6 +200,9 @@
     6.4  #hdr h2 {
     6.5  	font: bold 1.3rem/1.6rem sans-serif;
     6.6  }
     6.7 +/* #hdr:hover img {
     6.8 +	filter: drop-shadow(0 0 1px rgba(0,0,0,0.5));
     6.9 +} */
    6.10  #info {
    6.11  	clear: both;
    6.12  }
    6.13 @@ -333,7 +336,8 @@
    6.14  .button.download { background-color: gold; }
    6.15  .button.source   { background-color: yellow; }
    6.16  .button.browse   { background-color: tan; }
    6.17 -.button.doc      { background-color: plum; }
    6.18 +.button.doc,
    6.19 +.button.lfs      { background-color: plum; }
    6.20  .button.log      { background-color: lightgray; }
    6.21  
    6.22  .icon::before {
    6.23 @@ -343,38 +347,123 @@
    6.24  	padding-right: 2px;
    6.25  	opacity: 0.6;
    6.26  }
    6.27 -.icon.receipt::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m6.2 2-.2 1.8-1.6.9-1.7-.8-1.8 3 1.5 1.1v1.9l-1.5 1.1 1.8 3 1.7-.8 1.6.9.2 1.8h3.6l.2-1.8 1.6-.9 1.7.8 1.8-3-1.5-1.1v-1.9l1.5-1.1-1.8-3-1.7.8-1.6-.9-.2-1.8zm1.8 5s1.9 0 2 2c-.1 2-2 2-2 2s-1.9 0-2-2c.1-2 2-2 2-2z'/></svg>"); }
    6.28 -.icon.website::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m8 2c-7 .3-7 7-7 7s0 6.7 7 7c7-.3 7-7 7-7s0-6.7-7-7zm-.3 1.9c-.8 1.9-.5 3 0 3.6-1 0-1-.8-1.8-.8-.3 0-.5.4-.5.7 0 2 4.8.8 4.8 3.3 0 1.6-1 2.6-2.7 3.2 0-1.9-.7-2.2-1.8-2.9-.3-.2-.3-.3-.2-.6.2-.6.4-.9 1-1.3-1.3-.3-2.4-.6-3.3-1.4 0-1 1.7-3.8 4.5-3.8zm4.5 2.4c.7 1 1.1 2.6.5 4.2-.6-1.1-1.7-1.7-1.7-2.5s1-1.7 1.2-1.7z'/></svg>"); }
    6.29 -.icon.files::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m5 2v1h3.4l4.6 4.6v5.4h1c1 0 1-1 1-1v-7l-4-4h-5s-1 0-1 1zm-3 3v10s0 1 1 1h8s1 0 1-1v-7l-4-4h-5s-1 0-1 1z'/></svg>"); }
    6.30 -.icon.desc::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m3 2c-2 0-2 2-2 2v10c0 2 2 2 2 2h10s2 0 2-2v-10c0-2-2-2-2-2zm1 3h8v1h-8zm0 3h8v1h-8zm0 3h6v1h-6z'/></svg>"); }
    6.31 -.icon.download::before, .icon.source::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='16'><path d='m5 2v5h-2.3l4.3 6.3 4.4-6.3h-2.4v-5zm-4 12v2h12.1v-2z'/></svg>"); }
    6.32 -.icon.browse::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m8 4s-5.4-.4-8 5c2.6 5.4 8 5 8 5s5.4.4 8-5c-2.6-5.4-8-5-8-5zm3 5c-.2 4-5.8 4-6 0 .2-4 5.8-4 6 0zm-4 0c0 1.3 2 1.3 2 0s-2-1.3-2 0z'/></svg>"); }
    6.33 -.icon.doc::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m4.5 3c-2.5 0-3.5 1-3.5 1v12.1s1-1 3.5-1 3.5 1 3.5 1 1-1 3.5-1 3.5 1 3.5 1v-12.1s-1-1-3.5-1-3.5 1-3.5 1-1-1-3.5-1zm7 1.2c1.5 0 2.5.4 2.5.4v9.7s-1-.4-2.5-.4c-2.5 0-3.5 1-3.5 1v-9.7s1-1 3.5-1z'/></svg>"); }
    6.34 -.icon.log::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m8 2c-7 .4-7 7-7 7s0 6.6 7 7c7-.4 7-7 7-7s0-6.6-7-7zm0 2c5 .3 5 5 5 5s0 4.7-5 5c-5-.3-5-5-5-5s0-4.7 5-5zm-1 1v4.4l2.8 2.8 1.4-1.4-2.2-2.2v-3.6z'/></svg>"); }
    6.35 +.icon.receipt::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m2 11v3h12v-3z' opacity='.3'/><path d='m14 0h-12s-2 0-2 2v12s0 2 2 2h12s2 0 2-2v-12s0-2-2-2zm0 14h-12v-3h2.5c1 2 3.5 2 3.5 2s2.5 0 3.5-2h2.5zm0-5h-4c0 2-2 2-2 2s-2 0-2-2h-4v-7h12z'/></svg>"); }
    6.36 +.icon.website::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m8 2h-3l-3 3v6l4 3h5l3-3v-2h-7z' opacity='.3'/><path d='m8 0c-4.5 0-8 3.5-8 8s3.5 8 8 8 8-3.5 8-8-3.5-8-8-8zm.5 2 1.4 3h-3.8l1.4-3zm-2.9.3-.9 2.7h-2.2zm4.8 0 3.1 2.7h-2.2zm-8.2 3.7h2.2l.1 4h-2.3zm3.7 0h4.2l.1 4h-4.3zm5.7 0h2.2v4h-2.2zm-6.9 5 1 2.7-3.2-2.7zm5.1 0-1.3 3h-1l-1.3-3zm3.7 0-3.1 2.7.9-2.7z'/></svg>"); }
    6.37 +.icon.files::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m6 2v9h7v-6h-3v-3z' opacity='.3'/><path d='m6 0s-2 0-2 2v9s0 2 2 2h7s2 0 2-2v-7.5l-3.5-3.5zm0 2h4v3h3v6h-7zm5-.5 2.5 2.5h-2.5zm-10 2.5v10s0 2 2 2h9v-2h-9v-10z'/></svg>"); }
    6.38 +.icon.desc::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m2 2v9h3.5l2.5 2.5 2.5-2.5h3.5v-9z' opacity='.3'/><path d='m14 0c2 0 2 2 2 2v9c0 2-2 2-2 2h-3l-3 3-3-3h-3c-2 0-2-2-2-2v-9c0-2 2-2 2-2zm-12 11h3.5l2.5 2.5 2.5-2.5h3.5v-9h-12zm11-7v2h-10v-2zm-10 3h8v2h-8z'/></svg>"); }
    6.39 +.icon.download::before, .icon.source::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m2 9v5h12v-5z' opacity='.3'/><path d='m2 0s-2 0-2 2v12s0 2 2 2h12s2 0 2-2v-12s0-2-2-2zm0 2h12v12h-12zm4 1v3h-2l4 4 4-4h-2v-3zm-3 8v2h10v-2z'/></svg>"); }
    6.40 +.icon.browse::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m2 2s-2 0-2 2v9s0 2 2 2h12s2 0 2-2v-7s0-2-2-2h-5.5l-2-2zm0 2h3.5l2 2h6.5v7h-12z'/><path d='m2 6h12v7h-12z' opacity='.3'/></svg>"); }
    6.41 +.icon.lfs::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m2.1 11.4 4-3.4 8.3 3.9h-3.3l-3 3.7-2.6-3h-2.5z' opacity='.3'/><path d='m7.2.2-1.8.6-.5 1.7.6 1.5-3.9-1-1.2 2.3-.4 3.2 1 3.4 1.9 2.1 1.1-1 1.6-.3.7 2.4 1.7.6 1.8-.6.6-2.3 1.9.2 1.4 1 1.5-2.1.3-3-2.4 1.1v-4l2.5 1.1-.3-2.8-1.8-1.8-2 .9-2.7.5.7-1.4-.5-1.7zm2.8 4.1 1.6 1.1.4 2.3-.5 2.1-1.1-.3.6-.6-.3-2.7h-1.8l-.4 1.8.2 1-1.3-1.4.5-2.3zm-6.8.2 1.4.8.4 2.3-1 .8v-2.1h-1.6l-.2 1.9.7 1.1-.8.7-1.1-1.5.5-3zm3.5 4 1.7 1.4 3.6.9v1l-2.1.1-1 2.5-1.7.1-.3-.9 2.8-1.9-.7-.8-2.4 1.7-.3-1-2.6.4-.7.6-.9-1.2 3.3-2.8z'/></svg>"); }
    6.42 +.icon.doc::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m4 2v12h9v-12h-4v7l-2-2-2 2v-7z' opacity='.3'/><path d='m3 0-1 1v14l1 1h11l1-1v-14l-1-1zm5 1v5l-1-1-1 1v-5zm5 13h-9v-12h1v7l2-2 2 2v-7h4z'/></svg>"); }
    6.43 +.icon.log::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path d='m3 3v11h10v-11z' opacity='.3'/><path d='m10 1v-1h-4v1h-3s-2 0-2 2v11s0 2 2 2h10s2 0 2-2v-11s0-2-2-2zm0 2h-4l1-1h2zm2 2v-2h1v11h-10v-11h1v2zm-8 4v-2h8v2zm6 3h-6v-2h6z'/></svg>"); }
    6.44  .icon.more::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m3 7c-2 .1-2 2-2 2s0 1.9 2 2c2-.1 2-2 2-2s0-1.9-2-2zm5 0c-2 .1-2 2-2 2s0 1.9 2 2c2-.1 2-2 2-2s0-1.9-2-2zm5 0c-2 .1-2 2-2 2s0 1.9 2 2c2-.1 2-2 2-2s0-1.9-2-2z'/></svg>"); }
    6.45  .icon.bell::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m9.6 2.7s-3.4-.2-4.5 3c-1.9 4.6-2.5 3.8-2.8 4.4-.2.6.4.8.4.8l9.3 3.3s.5.2.8-.3-.9-.5.7-5.2c1-3.5-1.6-5.1-1.6-5.1s.3-1.1-.8-1.5c-1-.4-1.5.6-1.5.6zm-2.9 11s-.4 1.4 1.3 2.2c2 .4 2.3-.9 2.3-.9z'/></svg>"); }
    6.46 -.icon.maintainers::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m6 2c-4 0-4 6 0 6s4-6 0-6zm3.9 2.2c.4 1.3-.3 2.8-1.1 3.5 0 0 .7 1.3 2.2 1.3 3.4 0 3.4-5 0-5-.5 0-1.1.2-1.1.2zm-3.9 5.8c-6 0-6 4-6 4v1h12v-1s0-4-6-4zm4.4 0c1.6 1 2.6 2.5 2.6 4h3v-1c0-1.5-1.5-3-5.6-3z'/></svg>"); }
    6.47 +.icon.maintainers::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m2 9v5h12v-4h-5v-1z' fill-opacity='.3'/><g fill='none' stroke='%23000'><circle cx='5' cy='6' r='2'/><circle cx='11' cy='7' r='2'/><path d='m6.5 14v-2.5s0-2 4.5-2c3.5 0 3.5 1 3.5 1'/><rect height='14' rx='2' stroke-width='2' width='14' x='1' y='1'/><path d='m1 10.5s0-2 4.5-2c3.5 0 3.5 1 3.5 1'/></g></svg>"); }
    6.48  .icon.actual::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m8 1c-3.8 0-7 3.2-7 7s3.2 7 7 7 7-3.2 7-7c0-1.5-.6-2.9-.6-2.9l-7.1 8.1-3.8-3.8c-.9-.9.5-2.3 1.4-1.4l2.3 2.3 6-6.9s-2-2.4-5.2-2.4z' fill='%23090'/></svg>"); }
    6.49  .icon.update::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m8 .7-2.2 2.3h-2.8v2.8l-2.3 2.2 2.3 2.2v2.8h2.8l2.2 2.3 2.2-2.3h2.8v-2.8l2.3-2.2-2.3-2.2v-2.8h-2.8zm-1 3.3h2v5h-2zm0 6h2v2h-2z' fill='%23f90'/></svg>"); }
    6.50  .icon.next::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m8.2 2-1.4 1.4 3.6 3.6h-8.4v2h8.5l-3.6 3.6 1.4 1.4 6-6z'/></svg>"); }
    6.51  .icon.prev::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m7.8 2 1.4 1.4-3.6 3.6h8.5v2h-8.5l3.6 3.6-1.4 1.4-6-6z'/></svg>"); }
    6.52  .icon.up::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m2 7.8 1.4 1.4 3.6-3.6v8.5h2v-8.5l3.6 3.6 1.4-1.4-6-6z'/></svg>"); }
    6.53 +.icon.tag::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m2.5 7.5 5-5 6 6-5 5z' opacity='.3'/><circle cx='4' cy='4' r='1'/><g fill='none' stroke='%23000'><path d='m1 1h6.5l7.5 7.5-6.5 6.5-7.5-7.5z' stroke-linejoin='round' stroke-width='2'/><path d='m5 7 3 3'/><path d='m7 5 4 4'/></g></svg>"); }
    6.54 +.icon.bug::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m8 0-2.5 1-.5 3h6l-.5-3zm6.5 3h-1l-2 2h-7l-2-2h-1l-.5.5v1l2 2v1.5h-2.5l-.5 1 .5 1h2.5l.5 2-2.5 2.5v1l.5.5h1l2-2 2.5 1v-9h2v9l2.5-1 2 2h1l .5-.5v-1l-2.5-2.5.5-2h2.5l.5-1-.5-1h-2.5v-1.5l2-2v-1z'/></svg>"); }
    6.55  
    6.56 -.bigicon-i {
    6.57 -	background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32'><path d='m16 2c-14 .7-14 14-14 14s0 13.3 14 14c14-.7 14-14 14-14s0-13.3-14-14zm0 5.5c2.5 0 2.5 2.5 2.5 2.5s0 2.5-2.5 2.5-2.5-2.5-2.5-2.5 0-2.5 2.5-2.5zm-2 6.5h4v10h-4z' fill='%2329F'/></svg>") no-repeat 0.5rem 50%;
    6.58 +.icon.tarball::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m1 2 4-1v14l-4-1z' fill='%23666'/><path d='m5 1 10 1v12l-10 1z' fill='%23333'/><path d='m10 3.5-2-.3v2l2 .1zm0 1.8v1.7h2v-1.6zm0 1.7h-2v2h2zm0 2v1.7l2-.1v-1.6zm0 1.7-2 .1v2l2-.3z' fill='%23fff'/></svg>");}
    6.59 +.icon.pkg64::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m1 2 4-1v14l-4-1z' fill='%23333'/><path d='m5 1 10 1v12l-10 1z'/><path d='m6 3v10l3-.3v-5.7h-2v-2l2 .2v-1.9zm5 .6v5.3h2v3.2l1-.1v-8l-1-.1v3.2h-1v-3.4zm-4 5.4h1v1.9l-1 .1z' fill='%2308c'/></svg>");}
    6.60 +.icon.pkg32::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m1 2 4-1v14l-4-1z' fill='%23333'/><path d='m5 1 10 1v12l-10 1z'/><path d='m6 3v2l2 .1v1.9h-2v2h2v1.9l-2 .1v2l3-.3v-9.4zm5 .6v1.7l2 .2v1.6h-2v5.3l3-.4v-1.5l-2 .1v-1.7h2v-4.9z' fill='%23f60'/></svg>");}
    6.61 +.icon.pkgany::before { content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='m1 2 4-1v14l-4-1z' fill='%23333'/><path d='m5 1 10 1v12l-10 1z'/><path d='m7 4v8h1l5-3.5v-1l-5-3.5z' fill='%230c0'/></svg>");}
    6.62 +
    6.63 +.bigicon-i::before {
    6.64 +	content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32'><path d='m16 2c-14 .7-14 14-14 14s0 13.3 14 14c14-.7 14-14 14-14s0-13.3-14-14zm0 5.5c2.5 0 2.5 2.5 2.5 2.5s0 2.5-2.5 2.5-2.5-2.5-2.5-2.5 0-2.5 2.5-2.5zm-2 6.5h4v10h-4z' fill='%2329F'/></svg>");
    6.65  }
    6.66 -.bigicon-w {
    6.67 -	background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32'><path d='m16 1.3c-.7 0-1.3.3-1.7 1l-14 24.7c-.8 1.4.2 3 1.7 3h28c1.5 0 2.5-1.6 1.7-3l-14-24.7c-.4-.7-1-1-1.7-1zm-2 6.7h4v12h-4zm0 14h4v4h-4z' fill='%23F90'/></svg>") no-repeat 0.5rem 50%;
    6.68 +.bigicon-w::before {
    6.69 +	content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32'><path d='m16 1.3c-.7 0-1.3.3-1.7 1l-14 24.7c-.8 1.4.2 3 1.7 3h28c1.5 0 2.5-1.6 1.7-3l-14-24.7c-.4-.7-1-1-1.7-1zm-2 6.7h4v12h-4zm0 14h4v4h-4z' fill='%23F90'/></svg>");
    6.70  }
    6.71 -.bigicon-e {
    6.72 -	background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32'><path d='m16 2c-14 .7-14 14-14 14s0 13.3 14 14c14-.7 14-14 14-14s0-13.3-14-14zm-2 4h4v12h-4zm0 16h4v4h-4z' fill='%23F43'/></svg>") no-repeat 0.5rem 50%;
    6.73 +.bigicon-e::before {
    6.74 +	content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32'><path d='m16 2c-14 .7-14 14-14 14s0 13.3 14 14c14-.7 14-14 14-14s0-13.3-14-14zm-2 4h4v12h-4zm0 16h4v4h-4z' fill='%23F43'/></svg>");
    6.75  }
    6.76  [class*="bigicon-"] {
    6.77  	margin: 0.5rem 0;
    6.78 -	padding: 1rem 0.8rem 1rem 3rem;
    6.79 +	padding: 0.8rem;
    6.80  	background-color: hsla(0,0%,100%,0.8);
    6.81  	box-shadow: 0 0 3px rgba(0,0,0,0.4);
    6.82  }
    6.83 +[class*="bigicon-"]::before {
    6.84 +	display: inline-block;
    6.85 +	height: 32px;
    6.86 +	width: 32px;
    6.87 +	padding: 0 0.8rem 0 0;
    6.88 +	vertical-align: middle;
    6.89 +}
    6.90 +.badge.bdbroken::before {
    6.91 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><circle cx='8' cy='8' fill='%23bcc' r='7.5' stroke='%23000'/><path d='m6 4-2 1v1l2-1zm4 0v1l2 1v-1zm-4 2v1h1v-1zm3 0v1h1v-1zm-2.5 4-2 2h1.5l1-1h2l1 1h1.5l-2-2z'/></svg>");
    6.92 +}
    6.93 +.badge.broken::before {
    6.94 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><g stroke='%23000'><path d='m8 .5c-6.5 0-6.5 6-6.5 6v5l4 1.5v2.5h5v-2.5l4-1.5v-5s0-6-6.5-6z' fill='%23bcc'/><g fill='none'><path d='m5.5 7c-1.5 0-1.5 1.5-1.5 1.5s0 1.5 1.5 1.5 1.5-1.5 1.5-1.5 0-1.5-1.5-1.5z'/><path d='m10.5 7c-1.5 0-1.5 1.5-1.5 1.5s0 1.5 1.5 1.5 1.5-1.5 1.5-1.5 0-1.5-1.5-1.5z'/></g></g><path d='m8 11-1 1v1h2v-1z'/></svg>");
    6.95 +}
    6.96 +.badge.any::before {
    6.97 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><path d='m1 2 4-1v14l-4-1z' fill='%23666'/><path d='m5 1 10 1v12l-10 1z' fill='%23333'/><path d='m7 4v8h1l5-3.5v-1l-5-3.5z' fill='%230c0'/></svg>");
    6.98 +}
    6.99 +.badge.noany::before {
   6.100 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><path d='m1 2 4-1v14l-4-1z' fill='%23666'/><path d='m5 1 10 1v12l-10 1z' fill='%23333'/><path d='m7 4v8h1l5-3.5v-1l-5-3.5z' fill='%230c0'/><path d='m1.5 0-1.5 1.5 14.5 14.5 1.5-1.5z' fill='%23fff'/><path d='m1.5 1 13.5 13.5-.5.5-13.5-13.5z'/></svg>");
   6.101 +}
   6.102 +.badge.libtool::before {
   6.103 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><rect fill='%23fff' height='14' rx='2' stroke='%23f00' stroke-linejoin='round' stroke-width='2' width='14' x='1' y='1'/><path d='m4 4v8h4v-1h-2v-7zm3 0v1h2v7h2v-7h2v-1z'/></svg>");
   6.104 +}
   6.105 +.badge.nolibtool::before {
   6.106 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><rect fill='%23fff' height='14' rx='2' stroke='%23f00' stroke-linejoin='round' stroke-width='2' width='14' x='1' y='1'/><path d='m7 4v .5l.5.5h1.5v1.5l2 2v-3.5h2v-1zm-3 2.5v5.5h4v-1h-2v-2.5zm5 5v .5h.5z'/><path d='m14.5 14-12.5-12.5v3l9.5 9.5z' fill='%23f00'/></svg>");
   6.107 +}
   6.108 +.badge.own::before {
   6.109 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><path d='m8 8.8c-2.6 0-5 1.2-5 1.2l5 5.5 5-5.5s-2.5-1.2-5-1.2z'/><path d='m8 1 6 2.5v4.5c-1 6-6 7-6 7s-5-1-6-7v-4.5z' fill='none' stroke='%23f00' stroke-width='2'/><circle cx='8' cy='6' r='2'/></svg>");
   6.110 +}
   6.111 +.badge.ownover::before {
   6.112 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><path d='m8 8.8c-2.6 0-5 1.2-5 1.2l5 5.5 5-5.5s-2.5-1.2-5-1.2z'/><path d='m8 1 6 2.5v4.5c-1 6-6 7-6 7s-5-1-6-7v-4.5z' fill='none' stroke='%2304f' stroke-width='2'/><circle cx='8' cy='6' r='2'/></svg>");
   6.113 +}
   6.114 +.badge.perm::before {
   6.115 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><path d='m8 1 6 2.5v4.5c-1 6-6 7-6 7s-5-1-6-7v-4.5z' fill='none' stroke='%23f00' stroke-width='2'/><path d='m8 4c-2 0-2 2-2 2v1h-1v4h6v-4h-1v-1s0-2-2-2zm0 1c1 0 1 1 1 1v1h-2v-1s0-1 1-1z'/></svg>");
   6.116 +}
   6.117 +.badge.permover::before {
   6.118 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><path d='m8 1 6 2.5v4.5c-1 6-6 7-6 7s-5-1-6-7v-4.5z' fill='none' stroke='%2304f' stroke-width='2'/><path d='m8 4c-2 0-2 2-2 2v1h-1v4h6v-4h-1v-1s0-2-2-2zm0 1c1 0 1 1 1 1v1h-2v-1s0-1 1-1z'/></svg>");
   6.119 +}
   6.120 +.badge.symlink::before {
   6.121 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><path d='m10 5c-7 1-10 10-10 10s4-4 10-4v3l6-6-6-6zm3.5 3-1 1c-4.5 0-7.5 1-7.5 1s2-3 7.5-3z' fill='%23f00'/></svg>");
   6.122 +}
   6.123 +.badge.ss::before {
   6.124 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><path d='m4 6c0 2 2 3 2 4s-2 1-2 1v1s4 0 4-2-2-3-2-4 2-1 2-1v-1s-4 0-4 2zm5 0c0 2 2 3 2 4s-2 1-2 1v1s4 0 4-2-2-3-2-4 2-1 2-1v-1s-4 0-4 2z'/><rect fill='none' height='14' rx='2' stroke='%2304f' stroke-width='2' width='14' x='1' y='1'/></svg>");
   6.125 +}
   6.126 +.badge.fadd::before {
   6.127 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><path d='m9 4h-2v3h-3v2h3v3h2v-3h3v-2h-3z'/><circle cx='8' cy='8' fill='none' r='7' stroke='%23f00' stroke-width='2'/></svg>");
   6.128 +}
   6.129 +.badge.frem::before {
   6.130 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><path d='m4 7v2h8v-2z'/><circle cx='8' cy='8' fill='none' r='7' stroke='%23f00' stroke-width='2'/></svg>");
   6.131 +}
   6.132 +.badge.fdup::before {
   6.133 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><path d='m4 5v2h8v-2zm0 4v2h8v-2z'/><circle cx='8' cy='8' fill='none' r='7' stroke='%23f00' stroke-width='2'/></svg>");
   6.134 +}
   6.135 +.badge.old::before {
   6.136 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><path d='m1.5 7.5s.7-6 6.5-6 6.5 6 6.5 6c1.3.3 1.5 3-.5 3 0 0-1.5 4-6 4s-6-4-6-4c-2 0-1.8-2.7-.5-3z' fill='%23ecf' stroke='%23000'/><path d='m4 1s-3 0-3 6.2l4-3.2.1-2.4zm8 0-1.1.6.1 2.4 4 3.2c0-6.2-3-6.2-3-6.2zm-7 6v1h2v-1zm4 0v1h2v-1zm-2 2v1h2v-1zm-1 2v1h4v-1z'/></svg>");
   6.137 +}
   6.138 +.badge.win::before {
   6.139 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><path d='m8 0-1.5 1.3-2-.2-.5 2-1.7 1 .7 1.9-.7 1.8 1.7 1.1.5 1.9 2-.1 1.5 1.3 1.5-1.3 2 .1.5-1.9 1.7-1.1-.7-1.8.7-1.9-1.7-1-.5-2-2 .2z' fill='%23d00'/><path d='m6 12-2 .1-.9 2.9 2.1-.7 1.2 1.7 1.1-2.7zm4 0-1.5 1.3 1.1 2.7 1.2-1.7 2.1.7-.9-2.9z' fill='%23059'/><circle cx='8' cy='6' fill='%23059' r='2.9' stroke='%23fff'/></svg>");
   6.140 +}
   6.141 +.badge.orphan::before {
   6.142 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><g stroke='%23000'><circle cx='8' cy='8' fill='%23ecf' r='7.5'/><g fill='none'><path d='m3.4 10.3s2.2-1.1 4-.5 2.9 2.8 2.9 2.8'/><path d='m3.3 6 3.9-1.4-1.5 1.5'/><path d='m13 5.9-3.9-1.3 1.5 1.5'/></g></g><path d='m12 10.2c-2.8 0 0-3.7 0-3.7s2.8 3.7 0 3.7z'/></svg>");
   6.143 +}
   6.144 +.badge.patch::before {
   6.145 +	content: url("data:image/svg+xml,<svg height='16' width='16' xmlns='http://www.w3.org/2000/svg'><path d='m3.5 0-2.5 1-1 2.5 3.5 3.5 3.5-3.5zm9 0-12.5 12.5 1 2.5 2.5 1 12.5-12.5-1-2.5zm-4.5 5h1v1h1v1h1v1h-1v1h-1v1h-1v1h-1v-1h-1v-1h-1v-1h1v-1h1v-1h1zm0 1v1h1v-1zm1 1v1h1v-1zm0 1h-1v1h1zm-1 1h-1v1h1zm-1 0v-1h-1v1zm0-1h1v-1h-1zm5.5 1-3.5 3.5 3.5 3.5 2.5-1 1-2.5z' fill='%2304c'/></svg>");
   6.146 +}
   6.147 +.badges td:nth-child(1) {
   6.148 +	vertical-align: middle;
   6.149 +	text-align: center;
   6.150 +	white-space: nowrap;
   6.151 +	width: 2rem!important;
   6.152 +}
   6.153 +var {
   6.154 +	color: #600;
   6.155 +	font-style: normal;
   6.156 +	font-family: monospace;
   6.157 +}
   6.158 +
   6.159 +
   6.160  
   6.161  
   6.162  a:target { background-color: yellow; }
   6.163 @@ -383,6 +472,7 @@
   6.164  /* Table */
   6.165  
   6.166  table { width: 100%; box-sizing: border-box; border-collapse: collapse; /*box-shadow: 0 0 4px rgba(0,0,0,0.3);*/ }
   6.167 +section.markdown table { width: unset; }
   6.168  th { /*color: rgba(0,0,0,0.6);*/ background-color: rgba(0,0,0,0.1); padding: 3px; font-weight: normal; }
   6.169  td { padding: 2px; vertical-align: top; }
   6.170  table:not(.half):not(.pkgslist) td:first-child { white-space: nowrap; width: 5rem; }
   6.171 @@ -413,6 +503,16 @@
   6.172  
   6.173  .texinfo pre { display: none; }
   6.174  .texinfo pre:target { display: block; }
   6.175 +.buttonbar {
   6.176 +	background-color: rgba(0,0,0,0.05);
   6.177 +	padding: 2px 4px;
   6.178 +	margin: -8px;
   6.179 +	border-radius: 4px;
   6.180 +	text-align: center;
   6.181 +	display: flex;
   6.182 +	justify-content: space-between;
   6.183 +}
   6.184 +.texinfo b { color: brown; }
   6.185  
   6.186  section, div.list {
   6.187  	margin: 0.6rem 0;
   6.188 @@ -469,6 +569,19 @@
   6.189  	text-align: center;
   6.190  }
   6.191  
   6.192 +.meter-small {
   6.193 +	height: 2rem;
   6.194 +	width: 10rem;
   6.195 +	vertical-align: middle;
   6.196 +}
   6.197 +.meter-small::after {
   6.198 +	content: attr(value)'%';
   6.199 +	display: inline-block;
   6.200 +	width: inherit;
   6.201 +	text-align: center;
   6.202 +	position: relative;
   6.203 +	top: -1.6rem;
   6.204 +}
   6.205  
   6.206  
   6.207  
   6.208 @@ -502,7 +615,33 @@
   6.209  
   6.210  .r.c10 del { color: gray; }
   6.211  
   6.212 -:not(pre) > code {background-color:rgba(0,0,0,.1); padding: 1px; border-radius:3px; border: 1px solid rgba(0,0,0,.15);}
   6.213 +:not(pre) > code {
   6.214 +	background-color:rgba(0,0,0,.1);
   6.215 +	padding: 1px;
   6.216 +	border-radius:3px;
   6.217 +	border: 1px solid rgba(0,0,0,.15);
   6.218 +}
   6.219 +kbd {
   6.220 +	display: inline-block;
   6.221 +	padding: 0 4px;
   6.222 +	font: monospaced;
   6.223 +	vertical-align: middle;
   6.224 +	background: #eee;
   6.225 +	color: #111;
   6.226 +	border: solid 1px rgba(0,0,0,.3);
   6.227 +	border-radius: 3px;
   6.228 +	box-shadow: 0 1px 0 #ddd, 0 0 0 1px #fff inset;
   6.229 +}
   6.230 +
   6.231 +/* Tag cloud */
   6.232 +.tags { font: 16px/20px sans-serif; text-align: center; }
   6.233 +.tags sup { font-size: 10px; }
   6.234 +.tag0 { font-size: 13px; color: #603cba; }
   6.235 +.tag1 { font-size: 15px; color: #2b5797; }
   6.236 +.tag2 { font-size: 18px; color: #00a300; }
   6.237 +.tag3 { font-size: 21px; color: #e3a21a; }
   6.238 +.tag4 { font-size: 25px; color: #b91d47; }
   6.239 +.tag5 { font-size: 31px; color: #ee1111; }
   6.240  
   6.241  
   6.242  /* FOLLOWING CSS HAS SOME CHANGES FOR SLITAZ COOKER! */
     7.1 --- a/lighttpd/cooker.js	Sat Aug 25 17:30:05 2018 +0300
     7.2 +++ b/lighttpd/cooker.js	Sat Nov 24 13:28:02 2018 +0200
     7.3 @@ -4,33 +4,38 @@
     7.4  //
     7.5  
     7.6  
     7.7 +// Updating the progress bar
     7.8 +
     7.9 +function updating(pkg) {
    7.10 +	var upct = new XMLHttpRequest();
    7.11 +	upct.onreadystatechange = function() {
    7.12 +		if (this.readyState == 4 && this.status == 200) {
    7.13 +			response = this.responseText.trim();
    7.14 +			if (response == 'reload') {
    7.15 +				// Package in question not cooked now (finished) ->
    7.16 +				// Server sends 'reload' response ->
    7.17 +				// Stop updating and reload the page
    7.18 +				clearInterval(upID);
    7.19 +				location.reload();
    7.20 +			} else {
    7.21 +				// Update text and gauge value
    7.22 +				var pct = document.getElementById('pct');
    7.23 +				if (pct !== null) pct.innerHTML = response + '%';
    7.24 +				var gauge = document.getElementById('gauge');
    7.25 +				if (gauge !== null) gauge.value = response;
    7.26 +			}
    7.27 +		}
    7.28 +	};
    7.29 +	upct.open('GET', '?pct=' + pkg, true);
    7.30 +	upct.responseType = 'text';
    7.31 +	upct.send();
    7.32 +}
    7.33 +
    7.34 +
    7.35  // Start updating percents of package completion
    7.36  
    7.37  function startUpdating(pkg) {
    7.38 -	upID = setInterval(function() {
    7.39 -		var upct = new XMLHttpRequest();
    7.40 -		upct.onreadystatechange = function() {
    7.41 -			if (this.readyState == 4 && this.status == 200) {
    7.42 -				response = this.responseText.trim();
    7.43 -				if (response == 'reload') {
    7.44 -					// Package in question not cooked now (finished) ->
    7.45 -					// Server sends 'reload' response ->
    7.46 -					// Stop updating and reload the page
    7.47 -					clearInterval(upID);
    7.48 -					location.reload();
    7.49 -				} else {
    7.50 -					// Update text and gauge value
    7.51 -					var pct = document.getElementById('pct');
    7.52 -					if (pct !== null) pct.innerHTML = response + '%';
    7.53 -					var gauge = document.getElementById('gauge');
    7.54 -					if (gauge !== null) gauge.value = response;
    7.55 -				}
    7.56 -			}
    7.57 -		};
    7.58 -		upct.open('GET', '?pct=' + pkg, true);
    7.59 -		upct.responseType = 'text';
    7.60 -		upct.send();
    7.61 -	}, 10000);
    7.62 +	upID = setInterval(function(){updating(pkg)}, 10000);
    7.63  }
    7.64  
    7.65  
    7.66 @@ -47,8 +52,10 @@
    7.67  
    7.68  // Decide whether we need to update percentages
    7.69  
    7.70 -if (typeof updatePkg !== 'undefined')
    7.71 +if (typeof updatePkg !== 'undefined') {
    7.72 +	updating(updatePkg);
    7.73  	startUpdating(updatePkg);
    7.74 +}
    7.75  
    7.76  
    7.77  // Calculate and show server date
     8.1 --- a/lighttpd/index.cgi	Sat Aug 25 17:30:05 2018 +0300
     8.2 +++ b/lighttpd/index.cgi	Sat Nov 24 13:28:02 2018 +0200
     8.3 @@ -95,7 +95,8 @@
     8.4  
     8.5  	if [ -n "$pkg" ]; then
     8.6  		case "$pkg" in
     8.7 -			~) pretitle="Tag \"$cmd\" - ";;
     8.8 +			~) if [ -z "$cmd" ]; then pretitle="Tag cloud - "; else pretitle="Tag \"$cmd\" - "; fi;;
     8.9 +			%) if [ -z "$cmd" ]; then pretitle="Badges - "; else pretitle="Badge \"$cmd\" - "; fi;;
    8.10  			*) pretitle="$pkg - ";;
    8.11  		esac
    8.12  	else
    8.13 @@ -180,21 +181,21 @@
    8.14  	date_now=$(date +%s)
    8.15  	sec_now=$(date +%S); sec_now=${sec_now#0} # remove one leading zero
    8.16  	wait_sec=$(( 60 - $sec_now ))
    8.17 -	cat <<EOT
    8.18 -</main>
    8.19 +	cat <<-EOT
    8.20 +	</main>
    8.21  
    8.22 -<footer>
    8.23 -	<a href="http://www.slitaz.org/">SliTaz Website</a>
    8.24 -	<a href="http://tank.slitaz.org/graphs.php">Server status</a>
    8.25 -	<a href="$base/doc/cookutils/cookutils.html">Documentation</a>
    8.26 -	<a href="$base/?theme">Theme</a>
    8.27 -</footer>
    8.28 -</div>
    8.29 -<script src="/cooker.js"></script>
    8.30 -<script>refreshDate(${wait_sec}000, ${date_now}000)</script>
    8.31 -</body>
    8.32 -</html>
    8.33 -EOT
    8.34 +	<footer>
    8.35 +		<a href="http://www.slitaz.org/">SliTaz Website</a>
    8.36 +		<a href="http://tank.slitaz.org/graphs.php">Server status</a>
    8.37 +		<a href="$base/doc/cookutils/cookutils.html">Documentation</a>
    8.38 +		<a href="$base/?theme">Theme</a>
    8.39 +	</footer>
    8.40 +	</div>
    8.41 +	<script src="/cooker.js"></script>
    8.42 +	<script>refreshDate(${wait_sec}000, ${date_now}000)</script>
    8.43 +	</body>
    8.44 +	</html>
    8.45 +	EOT
    8.46  }
    8.47  
    8.48  
    8.49 @@ -258,7 +259,7 @@
    8.50  # Problems:
    8.51  # 1. Function "latest packaged version" widely used here and it has no JSON API, but only SVG badge.
    8.52  # 2. So, all version comparisons can be only visual and not automated.
    8.53 -# 3. Of the thousands of badges present on the web page, many of them are broken (maybe server
    8.54 +# 3. If the thousands of badges present on the web page, many of them are broken (maybe server
    8.55  #    drops requests), while our server displays status icons well.
    8.56  # 4. Default badges are wide and not customizable.
    8.57  # Solution:
    8.58 @@ -347,7 +348,7 @@
    8.59  	# argument <pkg> is in $cmd variable
    8.60  	echo -en "Content-Type: image/svg+xml\n\n<svg xmlns='http://www.w3.org/2000/svg' height='12' width='8'><path d='"
    8.61  	# packages.info updates with each new package, so we'll find actual info here
    8.62 -	if grep -q "^$cmd"$'\t' $PKGS/packages.info; then
    8.63 +	if grep -q "^$cmd"$'\t' $PKGS/packages-$ARCH.info; then
    8.64  		echo "m1 2-1 1v8l1 1h6l1-1v-8l-1-1z' fill='#090'/></svg>"
    8.65  	else
    8.66  		echo "m0 3v8l1 1h6l1-1v-8l-1-1h-6zm3 0h2v5h-2zm0 6h2v2h-2z' fill='#d00'/></svg>"
    8.67 @@ -365,19 +366,17 @@
    8.68  		theme)
    8.69  			current=$(COOKIE theme)
    8.70  			page_header
    8.71 -			cat <<EOT
    8.72 -<section>
    8.73 -	<h2>Change theme</h2>
    8.74 -	<p>Current theme: “${current:-default}”. Select other:</p>
    8.75 -	<ul>
    8.76 -		$(
    8.77 -			for i in default emerald sky goldenrod midnight like2016 terminal; do
    8.78 -				[ "$i" == "${current:-default}" ] || echo "<li><a href=\"$base/?theme=$i&amp;ref=$ref\">$i</a></li>"
    8.79 -			done
    8.80 -		)
    8.81 -	</ul>
    8.82 -</section>
    8.83 -EOT
    8.84 +			cat <<-EOT
    8.85 +				<section>
    8.86 +					<h2>Change theme</h2>
    8.87 +					<p>Current theme: “${current:-default}”. Select other:</p>
    8.88 +					<ul>$(
    8.89 +							for i in default emerald sky goldenrod midnight like2016 terminal; do
    8.90 +								[ "$i" == "${current:-default}" ] || echo "<li><a href=\"$base/?theme=$i&amp;ref=$ref\">$i</a></li>"
    8.91 +							done
    8.92 +					)</ul>
    8.93 +				</section>
    8.94 +			EOT
    8.95  			page_footer
    8.96  			exit 0
    8.97  			;;
    8.98 @@ -426,26 +425,27 @@
    8.99  	limit=$(GET limit); limit="${limit:-12}"; [ "$limit" -gt 100 ] && limit='100'
   8.100  	pubdate=$(date -Rur$(ls -t $FEEDS/*.xml | head -n1) | sed 's|UTC|GMT|')
   8.101  	cooker_url="http://$HTTP_HOST$base/"
   8.102 -	cat <<EOT
   8.103 -Content-Type: application/rss+xml
   8.104 +	cat <<-EOT
   8.105 +		Content-Type: application/rss+xml
   8.106  
   8.107 -<?xml version="1.0" encoding="utf-8" ?>
   8.108 -<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
   8.109 -<channel>
   8.110 -	<title>$title</title>
   8.111 -	<description>The SliTaz packages cooker feed</description>
   8.112 -	<link>$cooker_url</link>
   8.113 -	<lastBuildDate>$pubdate</lastBuildDate>
   8.114 -	<pubDate>$pubdate</pubDate>
   8.115 -	<atom:link href="$cooker_url?rss" rel="self" type="application/rss+xml" />
   8.116 -EOT
   8.117 +		<?xml version="1.0" encoding="utf-8" ?>
   8.118 +		<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
   8.119 +		<channel>
   8.120 +			<title>$title</title>
   8.121 +			<description>The SliTaz packages cooker feed</description>
   8.122 +			<link>$cooker_url</link>
   8.123 +			<lastBuildDate>$pubdate</lastBuildDate>
   8.124 +			<pubDate>$pubdate</pubDate>
   8.125 +			<atom:link href="$cooker_url?rss" rel="self" type="application/rss+xml" />
   8.126 +		EOT
   8.127  	for rss in $(ls -t $FEEDS/*.xml | head -n$limit); do
   8.128 -		sed "s|http[^=]*=|$cooker_url|; s|<guid|& isPermaLink=\"false\"|g; s|</pubDate| GMT&|g" $rss
   8.129 +		sed -e "/\?pkg=/s|http[^=]*=|$cooker_url|;" \
   8.130 +			-e "s|\([0-9]\)</pubDate>|\1 GMT</pubDate>|" $rss
   8.131  	done
   8.132 -	cat <<EOT
   8.133 -</channel>
   8.134 -</rss>
   8.135 -EOT
   8.136 +	cat <<-EOT
   8.137 +		</channel>
   8.138 +		</rss>
   8.139 +	EOT
   8.140  	exit 0
   8.141  fi
   8.142  
   8.143 @@ -455,22 +455,22 @@
   8.144  # Query '/os.xml': get OpenSearch Description
   8.145  
   8.146  if [ "$pkg" == 'os.xml' ]; then
   8.147 -	cat <<EOT
   8.148 -Content-Type: application/xml; charset=UTF-8
   8.149 +	cat <<-EOT
   8.150 +		Content-Type: application/xml; charset=UTF-8
   8.151  
   8.152 -<?xml version="1.0" encoding="UTF-8"?>
   8.153 -<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
   8.154 -	<ShortName>$title</ShortName>
   8.155 -	<Description>SliTaz packages search</Description>
   8.156 -	<Image width="16" height="16" type="image/png">http://$HTTP_HOST/images/logo.png</Image>
   8.157 -	<Url type="text/html" method="GET" template="http://$HTTP_HOST$base/{searchTerms}"/>
   8.158 -	<Url type="application/x-suggestions+json" method="GET" template="http://$HTTP_HOST$base/">
   8.159 -		<Param name="oss" value="{searchTerms}"/>
   8.160 -	</Url>
   8.161 -	<SearchForm>http://$HTTP_HOST$base/</SearchForm>
   8.162 -	<InputEncoding>UTF-8</InputEncoding>
   8.163 -</OpenSearchDescription>
   8.164 -EOT
   8.165 +		<?xml version="1.0" encoding="UTF-8"?>
   8.166 +		<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
   8.167 +			<ShortName>$title</ShortName>
   8.168 +			<Description>SliTaz packages search</Description>
   8.169 +			<Image width="16" height="16" type="image/png">http://$HTTP_HOST/images/logo.png</Image>
   8.170 +			<Url type="text/html" method="GET" template="http://$HTTP_HOST$base/{searchTerms}"/>
   8.171 +			<Url type="application/x-suggestions+json" method="GET" template="http://$HTTP_HOST$base/">
   8.172 +				<Param name="oss" value="{searchTerms}"/>
   8.173 +			</Url>
   8.174 +			<SearchForm>http://$HTTP_HOST$base/</SearchForm>
   8.175 +			<InputEncoding>UTF-8</InputEncoding>
   8.176 +		</OpenSearchDescription>
   8.177 +	EOT
   8.178  	exit 0
   8.179  fi
   8.180  
   8.181 @@ -512,7 +512,9 @@
   8.182  
   8.183  info2html() {
   8.184  	sed \
   8.185 -		-e 's|&|\&amp;|g; s|<|\&lt;|g; s|>|\&gt;|g' \
   8.186 +		-e 's|&|\&amp;|g; s|<|\&lt;|g; s|>|\&gt;|g;' \
   8.187 +		-e "s|\`\([^']*\)'|<b>\1</b>|g" \
   8.188 +		-e 's|"\([A-Za-z0-9]\)|“\1|g; s|"|”|g' \
   8.189  		-e 's|^\* \(.*\)::|* <a href="#\1">\1</a>  |' \
   8.190  		-e 's|\*note \(.*\)::|<a href="#\1">\1</a>|' \
   8.191  		-e '/^File: / s|(dir)|Top|g' \
   8.192 @@ -520,7 +522,8 @@
   8.193  		-e '/^File: / s|Prev: \([^,]*\)|<a class="button icon prev" href="#\1">Prev: \1</a>|' \
   8.194  		-e '/^File: / s|Up: \([^,]*\)|<a class="button icon up" href="#\1">Up: \1</a>|' \
   8.195  		-e '/^File: / s|^.* Node: \([^,]*\), *\(.*\)$|<pre id="\1">\2|' \
   8.196 -		-e '/^<pre id=/ s|^\([^>]*>\)\(<a[^>]*>Next: [^,]*\), *\(<a[^>]*>Prev: [^,]*\), *\(<a[^>]*>Up: .*\)|\1 \3 \4 \2|' \
   8.197 +		-e '/^<pre id=/ s|^\([^>]*>\)\(<a[^>]*>Next: [^,]*\), *\(<a[^>]*>Prev: [^,]*\), *\(<a[^>]*>Up: .*\)|\1<div class="buttonbar">\3 \4 \2</div>|' \
   8.198 +		-e '/^<pre id=/ s|^\([^>]*>\)*\(<a[^>]*>Prev: [^,]*\), *\(<a[^>]*>Up: .*\)|\1<div class="buttonbar">\2 \3 <a class="button icon next" href="#">Next</a></div>|' \
   8.199  		-e '/^Tag Table:$/,/^End Tag Table$/d' \
   8.200  		-e '/INFO-DIR/,/^END-INFO-DIR/d' \
   8.201  		-e "s|https*://[^>),'\"\`’ ]*|<a href=\"&\">&</a>|g" \
   8.202 @@ -631,12 +634,18 @@
   8.203  					s|\[39m|</span>|;
   8.204  					#s|\[1m|<span class='c01'>|g;
   8.205  					s|\[1m|<span style='font-weight:bold'>|g; s|(B|</span>|g;
   8.206 -					s|\[m||g;
   8.207 -					" \
   8.208 +					s|\[m||g;" \
   8.209 +				\
   8.210  				-e "s!^|\(+.*\)!|<span class='c20'>\1</span>!;
   8.211  					s!^|\(-.*\)!|<span class='c10'>\1</span>!;
   8.212 -					s!^|\(@@.*@@\)\$!|<span class='c30'>\1</span>!;"
   8.213 +					s!^|\(@@.*@@\)\$!|<span class='c30'>\1</span>!;" \
   8.214  				\
   8.215 +				-e "s|^Successfully installed [^ ][^ ]*$|<i>\0</i>|;
   8.216 +					s|^Successfully installed .*$|<b>\0</b>|;
   8.217 +					s|^\(Requirement already satisfied: .*\) in|<i>\1</i> in|;
   8.218 +					s|^Collecting .* (from .*$|<b>\0</b>|;
   8.219 +					s|^  Could not find.*|<b>\0</b>|;
   8.220 +					s|^No matching distribution found for.*|<b>\0</b>|;"
   8.221  
   8.222  			;;
   8.223  
   8.224 @@ -697,7 +706,9 @@
   8.225  
   8.226  	if [ -f "$log" ]; then
   8.227  		if grep -q "cook:$pkg$" $command; then
   8.228 -			show_note i "The Cooker is currently building $pkg"
   8.229 +			show_note i "The Cooker is currently building $pkg" \
   8.230 +			| sed 's|>|&<progress id="gauge" class="meter-small" max="100" value="0"></progress> |'
   8.231 +			echo "<script>updatePkg = '${pkg//+/%2B}';</script>"
   8.232  		elif fgrep -q "Summary for:" $log; then
   8.233  			sed '/^Summary for:/,$!d' $log | awk '
   8.234  			BEGIN { print "<section>" }
   8.235 @@ -728,7 +739,8 @@
   8.236  			END { print "</tbody></table></section>" }
   8.237  			'
   8.238  		elif fgrep -q "Debug information" $log; then
   8.239 -			echo -e '<section>\n<h3>Debug information</h3>'
   8.240 +			# second line of log is "Cook: <package> <version>"
   8.241 +			echo -e "<section>\n<h3>Debug information for $(sed '2!d; s|.*: ||' $log)</h3>"
   8.242  			sed -e '/^Debug information/,$!d; /^===/d; /^$/d' $log | sed -n '1!p' | \
   8.243  			if [ -n "$2" ]; then
   8.244  				syntax_highlighter log | sed 's|\([^0-9 ]\)\([0-9][0-9]*\):|\1<a href="#l\2">\2</a>:|'
   8.245 @@ -754,9 +766,9 @@
   8.246  
   8.247  	echo -n "<div id=\"hdr\"><a href=\"$base/${requested_pkg:-$pkg}\">"
   8.248  	if [ -e $wok/$pkg/.icon.png ]; then
   8.249 -		echo -n "<img src=\"$base/$pkg/browse/.icon.png\"/>"
   8.250 +		echo -n "<img src=\"$base/$pkg/browse/.icon.png\" alt=\"$pkg icon\"/>"
   8.251  	else
   8.252 -		echo -n "<img src=\"/tazpkg.png\"/>"
   8.253 +		echo -n "<img src=\"/tazpkg.png\" alt=\"package icon\"/>"
   8.254  	fi
   8.255  	echo -n "</a>"
   8.256  	echo -n "<h2><a href=\"$base/${requested_pkg:-$pkg}\">${requested_pkg:-$pkg}</a>"
   8.257 @@ -792,7 +804,7 @@
   8.258  		echo "<a class='button icon desc$(active description)' href='$base/$pkg/description'>description</a>"
   8.259  
   8.260  	[ -n "$TARBALL" -a -s "$SRC/$TARBALL" -o -d "$wok/$pkg/taz" ] &&
   8.261 -		echo "<a class='button icon download' href='$base/$pkg/download'>download</a>"
   8.262 +		echo "<a class='button icon download' href='$base/$pkg/download'>downloads</a>"
   8.263  
   8.264  	echo "<a class='button icon browse' href='$base/$pkg/browse/'>browse</a>"
   8.265  
   8.266 @@ -806,7 +818,7 @@
   8.267  		echo "<a class='button icon doc$(active info)' href='$base/$pkg/info/#Top'>info</a>"
   8.268  
   8.269  	if [ -n "$LFS" ]; then
   8.270 -		printf "<a class='button icon doc' href='%s' target='_blank' rel='noopener noreferrer'>" "$LFS"
   8.271 +		printf "<a class='button icon lfs' href='%s' target='_blank' rel='noopener noreferrer'>" "$LFS"
   8.272  		[ "${LFS/blfs/}" != "$LFS" ] && printf "B"
   8.273  		printf "LFS</a>\n"
   8.274  	fi
   8.275 @@ -917,10 +929,145 @@
   8.276  			sed "/^$i\t/!d" $CACHE/split.db
   8.277  		done < $broken | cut -d$'\t' -f2 | tr ' ' '\n' | wc -l)
   8.278  
   8.279 -	cat > $webstat <<EOT
   8.280 -rtotal="$rtotal"; rcooked="$rcooked"; runbuilt="$runbuilt"; rblocked="$rblocked"; rbroken="$rbroken"
   8.281 -ptotal="$ptotal"; pcooked="$pcooked"; punbuilt="$punbuilt"; pblocked="$pblocked"; pbroken="$pbroken"
   8.282 -EOT
   8.283 +	cat > $webstat <<-EOT
   8.284 +		rtotal="$rtotal"; rcooked="$rcooked"; runbuilt="$runbuilt"; rblocked="$rblocked"; rbroken="$rbroken"
   8.285 +		ptotal="$ptotal"; pcooked="$pcooked"; punbuilt="$punbuilt"; pblocked="$pblocked"; pbroken="$pbroken"
   8.286 +	EOT
   8.287 +}
   8.288 +
   8.289 +
   8.290 +# Show badges for specified package
   8.291 +
   8.292 +show_badges() {
   8.293 +	local t p s # title problem solution
   8.294 +
   8.295 +	case $layout in
   8.296 +		table)
   8.297 +			echo "<section><h2>Badges</h2><table class=\"badges\"><thead><tr><th></th><th>Problem</th><th>Solution</th></tr></thead><tbody>"
   8.298 +			;;
   8.299 +		list)
   8.300 +			echo "<section><h2>Badges list</h2><p>Click on badge to get list of packages</p><table class=\"badges\"><thead><tr><th></th><th>Problem</th></tr></thead><tbody>"
   8.301 +			;;
   8.302 +	esac
   8.303 +
   8.304 +	for badge in $@; do
   8.305 +		case $badge in
   8.306 +			bdbroken)
   8.307 +				t="Broken bdeps"
   8.308 +				p="This package cannot be built because its creation depends on broken packages"
   8.309 +				s="Fix broken build dependencies"
   8.310 +				;;
   8.311 +			broken)
   8.312 +				t="Broken package"
   8.313 +				p="Package is broken"
   8.314 +				s="Fix package build: analyze <a href=\"log/\">logs</a>, upgrade the version, search for patches"
   8.315 +				;;
   8.316 +			any)
   8.317 +				t="“Any” arch"
   8.318 +				p="This package contains only architecture-less <a href=\"files\">files</a>, it does not make sense to make it several times in each build environment"
   8.319 +				s="Add the line <code>HOST_ARCH=\"any\"</code> to <a href=\"receipt\">receipt</a>"
   8.320 +				;;
   8.321 +			noany)
   8.322 +				t="No “any” arch"
   8.323 +				p="This package contains architecture dependent <a href=\"files\">files</a>"
   8.324 +				s="Remove the line <code>HOST_ARCH=\"any\"</code> from <a href=\"receipt\">receipt</a>"
   8.325 +				;;
   8.326 +			libtool)
   8.327 +				t="Libtool isn't fixed"
   8.328 +				p="This package use <code>libtool</code> that likes to add unnecessary dependencies to programs and libraries"
   8.329 +				s="Add the <code>fix libtool</code> command to the <a href=\"receipt\">receipt</a> between the <code>configure</code> and <code>make</code> commands invocation"
   8.330 +				;;
   8.331 +			nolibtool)
   8.332 +				t="Libtool is absent"
   8.333 +				p="This package does not use <code>libtool</code>, nothing to fix"
   8.334 +				s="Remove the command <code>fix libtool</code> from <a href=\"receipt\">receipt</a>"
   8.335 +				;;
   8.336 +			own)
   8.337 +				t="Ownership problems"
   8.338 +				p="Some files of this package have <a href=\"files\">ownership problems</a>"
   8.339 +				s="Correct the ownership or add problem files to the “<a href=\"stuff/overrides\">overrides</a>” list if you believe it is OK"
   8.340 +				;;
   8.341 +			ownover)
   8.342 +				t="Ownership overridden"
   8.343 +				p="This package contains files with <a href=\"files\">ownership problems</a> that have been overridden"
   8.344 +				s="<abbr title=\"For your information\">FYI</abbr> only, you may want to revise <a href=\"stuff/overrides\">the list</a>"
   8.345 +				;;
   8.346 +			perm)
   8.347 +				t="Permissions problems"
   8.348 +				p="Some files of this package have <a href=\"files\">unusual permissions</a>"
   8.349 +				s="Correct the permissions or add problem files to the “<a href=\"stuff/overrides\">overrides</a>” list if you believe it is OK"
   8.350 +				;;
   8.351 +			permover)
   8.352 +				t="Permissions overridden"
   8.353 +				p="This package contains files with <a href=\"files\">unusual permissions</a> that have been recorded"
   8.354 +				s="<abbr title=\"For your information\">FYI</abbr> only, you may want to revise <a href=\"stuff/overrides\">the list</a>"
   8.355 +				;;
   8.356 +			symlink)
   8.357 +				t="Broken symlink"
   8.358 +				p="This package contains one or more <a href=\"files\">broken symlinks</a>"
   8.359 +				s="Fix the symlinks destination; you may use <code>fix symlinks</code> when symlinks have absolute path"
   8.360 +				;;
   8.361 +			ss)
   8.362 +				t="Site script"
   8.363 +				p="This autotools-based building system use site script; most of paths (like <var>prefix</var>, <var>sysconfdir</var> and <var>mandir</var>) are defined there with correct default values"
   8.364 +				s="You may remove your paths from <code>configure</code> invocation"
   8.365 +				;;
   8.366 +			fadd)
   8.367 +				t="Files have been added"
   8.368 +				p="Some files absent in <var>\$install</var> was <a href=\"files#outoftree\">directly added</a> to <var>\$fs</var>"
   8.369 +				s="Rework your <code>compile_rules()</code> to add all the required files to <var>\$install</var> there"
   8.370 +				;;
   8.371 +			frem)
   8.372 +				t="Files have been removed"
   8.373 +				p="Some files existing in <var>\$install</var> <a href=\"files#orphans\">not belong to any package</a>"
   8.374 +				s="Revise <code>genpkg_rules()</code> or add files to “<a href=\"stuff/overrides\">overrides</a>” list"
   8.375 +				;;
   8.376 +			fdup)
   8.377 +				t="Files are duplicated"
   8.378 +				p="Some files existing in <var>\$install</var> was added to <a href=\"files#repeats\">more than one</a> package"
   8.379 +				s="Check your copy rules in <code>genpkg_rules()</code>"
   8.380 +				;;
   8.381 +			old)
   8.382 +				t="Oldie"
   8.383 +				p="According to Repology, this package may be <a href=\"https://repology.org/metapackage/${REPOLOGY:-$pkg}\" target=\"_blank\" rel=\"noopener noreferrer\">outdated</a>"
   8.384 +				s="Update the package"
   8.385 +				;;
   8.386 +			win)
   8.387 +				t="Winner"
   8.388 +				p="This package has no problems"
   8.389 +				s="Well done, keep it up!"
   8.390 +				;;
   8.391 +			orphan)
   8.392 +				t="Orphaned package"
   8.393 +				p="It seems that no other package depends on this one"
   8.394 +				s="See if anyone needs it"
   8.395 +				;;
   8.396 +			patch)
   8.397 +				t="Patch"
   8.398 +				p="Patch has been applied"
   8.399 +				s="<abbr title=\"For your information\">FYI</abbr> only, you may want to revise <a href=\"$base/$PACKAGE/stuff/patches/series\">the list of patches</a>"
   8.400 +				;;
   8.401 +		esac
   8.402 +		case $layout in
   8.403 +			table)
   8.404 +				echo "<tr><td><span class=\"badge $badge\" title=\"$t\"/></td><td>$p</td><td>$s</td></tr>"
   8.405 +				;;
   8.406 +			list)
   8.407 +				p=$(echo $p | sed 's|<a [^>]*>\([^<]*\)</a>|\1|g')
   8.408 +				s=$(echo $s | sed 's|<a [^>]*>\([^<]*\)</a>|\1|g|')
   8.409 +				echo "<tr><td><a href=\"$badge\"><span class=\"badge $badge\" title=\"$t\"/></a></td><td>$p</td></tr>"
   8.410 +				;;
   8.411 +			*)
   8.412 +				echo -n "<span class=\"badge $badge\" title=\"$t\"/>"
   8.413 +				;;
   8.414 +		esac
   8.415 +	done
   8.416 +
   8.417 +	case $layout in
   8.418 +		table|list)
   8.419 +			echo "</tbody></table></section>"
   8.420 +			;;
   8.421 +	esac
   8.422  }
   8.423  
   8.424  
   8.425 @@ -959,16 +1106,40 @@
   8.426  
   8.427  			pct=0; [ "$rtotal" -gt 0 ] && pct=$(( ($rcooked * 100) / $rtotal ))
   8.428  
   8.429 -			cat <<EOT
   8.430 -<div class="meter"><progress max="100" value="$pct">${pct}%</progress><span>${pct}%</span></div>
   8.431 +			cat <<-EOT
   8.432 +				<div class="meter"><progress max="100" value="$pct">${pct}%</progress><span>${pct}%</span></div>
   8.433  
   8.434 -<table class="webstat"><thead>
   8.435 -<tr><th>        </th><th>Total  </th><th>Cooked  </th><th>Unbuilt  </th><th>Blocked  </th><th>Broken  </th></tr>
   8.436 -</thead><tbody>
   8.437 -<tr><td>Receipts</td><td>$rtotal</td><td>$rcooked</td><td>$runbuilt</td><td>$rblocked</td><td>$rbroken</td></tr>
   8.438 -<tr><td>Packages</td><td>$ptotal</td><td>$pcooked</td><td>$punbuilt</td><td>$pblocked</td><td>$pbroken</td></tr>
   8.439 -</tbody></table>
   8.440 -EOT
   8.441 +				<table class="webstat">
   8.442 +					<thead>
   8.443 +						<tr>
   8.444 +							<th>        </th>
   8.445 +							<th>Total  </th>
   8.446 +							<th>Cooked  </th>
   8.447 +							<th>Unbuilt  </th>
   8.448 +							<th>Blocked  </th>
   8.449 +							<th>Broken  </th>
   8.450 +						</tr>
   8.451 +					</thead>
   8.452 +					<tbody>
   8.453 +						<tr>
   8.454 +							<td>Receipts</td>
   8.455 +							<td>$rtotal</td>
   8.456 +							<td>$rcooked</td>
   8.457 +							<td>$runbuilt</td>
   8.458 +							<td>$rblocked</td>
   8.459 +							<td>$rbroken</td>
   8.460 +						</tr>
   8.461 +						<tr>
   8.462 +							<td>Packages</td>
   8.463 +							<td>$ptotal</td>
   8.464 +							<td>$pcooked</td>
   8.465 +							<td>$punbuilt</td>
   8.466 +							<td>$pblocked</td>
   8.467 +							<td>$pbroken</td>
   8.468 +						</tr>
   8.469 +					</tbody>
   8.470 +				</table>
   8.471 +			EOT
   8.472  			if [ -z "$nojs" ]; then echo "<script>getPart('$1')</script>"; fi
   8.473  			;;
   8.474  		activity)
   8.475 @@ -977,8 +1148,18 @@
   8.476  				s|\[ Failed|<span class="r c10">Failed|;
   8.477  				s|\[ -Failed|<span class="r c10"><del>Failed</del>|;
   8.478  				s| \]|</span>|;
   8.479 -				s|%2B|\+|g' | \
   8.480 -				section $activity 12 "Activity|More activity"
   8.481 +				s|%2B|\+|g' \
   8.482 +			| while read line; do
   8.483 +				case "$line" in
   8.484 +					*data-badges=*)
   8.485 +						badges="$(echo "$line" | sed "s|.*data-badges='\([^']*\)'.*|\1|")"
   8.486 +						echo "$line" | sed "s|</a>|</a> $(show_badges "$badges")|"
   8.487 +						;;
   8.488 +					*)
   8.489 +						echo "$line"
   8.490 +						;;
   8.491 +				esac
   8.492 +			done | section $activity 12 "Activity|More activity" \
   8.493  			;;
   8.494  		cooknotes)
   8.495  			[ -s "$cooknotes" ] && tac $cooknotes | head -n12 | \
   8.496 @@ -1070,11 +1251,26 @@
   8.497  			esac
   8.498  			echo '<section id="content2">'
   8.499  			echo "<h2>DB: $list $nb</h2>"
   8.500 +
   8.501  			tac $CACHE/$list | sed 's|cooker.cgi?pkg=||; s|%2B|+|g;
   8.502  				s|\[ Done|<span class="r c20">Done|;
   8.503  				s|\[ Failed|<span class="r c10">Failed|;
   8.504  				s|\[ -Failed|<span class="r c10"><del>Failed</del>|;
   8.505 -				s| \]|</span>|' | mktable $list
   8.506 +				s| \]|</span>|;
   8.507 +				s|%2B|\+|g' \
   8.508 +			| while read line; do
   8.509 +				case "$line" in
   8.510 +					*data-badges=*)
   8.511 +						badges="$(echo "$line" | sed "s|.*data-badges='\([^']*\)'.*|\1|")"
   8.512 +						echo "$line" | sed "s|</a>|</a> $(show_badges "$badges")|"
   8.513 +						;;
   8.514 +					*)
   8.515 +						echo "$line"
   8.516 +						;;
   8.517 +				esac
   8.518 +			done \
   8.519 +			| mktable $list
   8.520 +
   8.521  			echo '</section>'
   8.522  		done
   8.523  
   8.524 @@ -1118,64 +1314,84 @@
   8.525  				fi
   8.526  				;;
   8.527  			toolchain)
   8.528 -				cat <<EOT
   8.529 -<div id="content2">
   8.530 -<section>
   8.531 -<h2>SliTaz GNU/Linux toolchain</h2>
   8.532 +				cat <<-EOT
   8.533 +					<div id="content2">
   8.534 +					<section>
   8.535 +					<h2>SliTaz GNU/Linux toolchain</h2>
   8.536  
   8.537 -<table>
   8.538 -<tr><td>Build date</td>		<td colspan="2">$(sed -n '/^Cook date/s|[^:]*: \(.*\)|\1|p' $LOGS/slitaz-toolchain.log)</td></tr>
   8.539 -<tr><td>Build duration</td>	<td colspan="2">$(sed -n '/^Cook time/s|[^:]*: \(.*\)|\1|p' $LOGS/slitaz-toolchain.log)</td></tr>
   8.540 -<tr><td>Architecture</td>	<td colspan="2">$ARCH</td></tr>
   8.541 -<tr><td>Host system</td>	<td colspan="2">$BUILD_SYSTEM</td></tr>
   8.542 -<tr><td>Target system</td>	<td colspan="2">$HOST_SYSTEM</td></tr>
   8.543 -<tr><th>Package</th><th>Version</th><th>Description</th></tr>
   8.544 -$(toolchain_version slitaz-toolchain)
   8.545 -$(toolchain_version binutils)
   8.546 -$(toolchain_version linux-api-headers)
   8.547 -$(toolchain_version gcc)
   8.548 -$(toolchain_version glibc)
   8.549 -</table>
   8.550 +					<table>
   8.551 +						<tr>
   8.552 +							<td>Build date</td>
   8.553 +							<td colspan="2">$(sed -n '/^Cook date/s|[^:]*: \(.*\)|\1|p' $LOGS/slitaz-toolchain.log)</td>
   8.554 +						</tr>
   8.555 +						<tr>
   8.556 +							<td>Build duration</td>
   8.557 +							<td colspan="2">$(sed -n '/^Cook time/s|[^:]*: \(.*\)|\1|p' $LOGS/slitaz-toolchain.log)</td>
   8.558 +						</tr>
   8.559 +						<tr>
   8.560 +							<td>Architecture</td>
   8.561 +							<td colspan="2">$ARCH</td>
   8.562 +						</tr>
   8.563 +						<tr>
   8.564 +							<td>Host system</td>
   8.565 +							<td colspan="2">$BUILD_SYSTEM</td>
   8.566 +						</tr>
   8.567 +						<tr>
   8.568 +							<td>Target system</td>
   8.569 +							<td colspan="2">$HOST_SYSTEM</td>
   8.570 +						</tr>
   8.571 +						<tr>
   8.572 +							<th>Package</th>
   8.573 +							<th>Version</th>
   8.574 +							<th>Description</th>
   8.575 +						</tr>
   8.576 +						$(toolchain_version slitaz-toolchain)
   8.577 +						$(toolchain_version binutils)
   8.578 +						$(toolchain_version linux-api-headers)
   8.579 +						$(toolchain_version gcc)
   8.580 +						$(toolchain_version glibc)
   8.581 +					</table>
   8.582  
   8.583 -<p>Toolchain documentation: <a target="_blank" rel="noopener noreferrer"
   8.584 -href="http://doc.slitaz.org/en:cookbook:toolchain">http://doc.slitaz.org/en:cookbook:toolchain</a>
   8.585 -</p>
   8.586 +					<p>Toolchain documentation: <a target="_blank" rel="noopener noreferrer"
   8.587 +					href="http://doc.slitaz.org/en:cookbook:toolchain">http://doc.slitaz.org/en:cookbook:toolchain</a>
   8.588 +					</p>
   8.589  
   8.590 -</section>
   8.591 -</div>
   8.592 -EOT
   8.593 +					</section>
   8.594 +					</div>
   8.595 +				EOT
   8.596  				;;
   8.597  			maintainer*)
   8.598  				maintainer=$(GET maintainer); maintainer=${maintainer/maintainer/}
   8.599  				regexp=$(GET regexp); regexp=${regexp/regexp/}
   8.600  				[ -n "$regexp" ] && maintainer=''
   8.601 -				cat <<EOT
   8.602 -<section>
   8.603 -	<h2>For maintainers</h2>
   8.604 -	<p>Check packages version either for specified maintainer or using regular expression:</p>
   8.605 -	<form>
   8.606 -		<select name="maintainer">
   8.607 -			<option value=''>--- select maintainer ---
   8.608 -EOT
   8.609 +				cat <<-EOT
   8.610 +					<section>
   8.611 +						<h2>For maintainers</h2>
   8.612 +						<p>Here you can <a href="%/">explore the badges</a>.</p>
   8.613 +						<p>Or see some <a href="?maintainer&amp;stats">repository statistics</a>.</p>
   8.614 +						<p>Or check packages version either for specified maintainer or using regular expression:</p>
   8.615 +						<form>
   8.616 +							<select name="maintainer">
   8.617 +								<option value=''>--- select maintainer ---
   8.618 +				EOT
   8.619  				cut -d$'\t' -f1 $maintdb | sort -u \
   8.620  				| awk -vm=$maintainer '{
   8.621  					selected=$0==m?"selected":""
   8.622  					printf("<option %s value=\"%s\">%s\n", selected, $0, $0)
   8.623  				}'
   8.624 -				cat <<EOT
   8.625 -
   8.626 -		</select>
   8.627 -		or
   8.628 -		<input type="text" name="regexp" value="$regexp"/>
   8.629 -		<button type="submit">Go</button>
   8.630 -	</form>
   8.631 -EOT
   8.632 +				cat <<-EOT
   8.633 +							</select>
   8.634 +							or
   8.635 +							<input type="text" name="regexp" value="$regexp"/>
   8.636 +							<button type="submit">Go</button>
   8.637 +						</form>
   8.638 +				EOT
   8.639  				if [ -n "$maintainer" -o -n "$regexp" ]; then
   8.640  					tmp_status=$(mktemp)
   8.641 -					cat <<EOT
   8.642 -	<table class="maint">
   8.643 -		<thead><tr><th>Package</th><th>Version</th><th>Repology</th></tr></thead>
   8.644 -EOT
   8.645 +					cat <<-EOT
   8.646 +						<table class="maint">
   8.647 +						<thead><tr><th>Package</th><th>Version</th><th>Repology</th></tr></thead>
   8.648 +					EOT
   8.649  					{
   8.650  						if [ -n "$maintainer" ]; then
   8.651  							awk -vm=$maintainer '{if ($1 == m) print $2}' $maintdb
   8.652 @@ -1206,13 +1422,13 @@
   8.653  							repo_info1="<a class='icon $icon' href='https://repology.org/metapackage/$REPOLOGY' target='_blank'"
   8.654  							repo_info2="rel='noopener noreferrer' title='latest packaged version(s)'>${repo_ver// /, }</a>"
   8.655  						fi
   8.656 -						cat <<EOT
   8.657 -		<tr>
   8.658 -			<td><img src="$base/s/$pkg"> <a href="$pkg">$pkg</a></td>
   8.659 -			<td>${ver:-$VERSION}</td>
   8.660 -			<td>$repo_info1 $repo_info2</td>
   8.661 -		</tr>
   8.662 -EOT
   8.663 +						cat <<-EOT
   8.664 +							<tr>
   8.665 +								<td><img src="$base/s/$pkg" alt="$pkg"> <a href="$pkg">$pkg</a></td>
   8.666 +								<td>${ver:-$VERSION}</td>
   8.667 +								<td>$repo_info1 $repo_info2</td>
   8.668 +							</tr>
   8.669 +						EOT
   8.670  					done
   8.671  
   8.672  					pkg_total=$(   wc -l      < $tmp_status)
   8.673 @@ -1228,19 +1444,19 @@
   8.674  					[ "$pkg_outdated" -eq 0 ] && pkg_outdated=''
   8.675  					[ "$pkg_unknown"  -eq 0 ] && pkg_unknown=''
   8.676  
   8.677 -					cat <<EOT
   8.678 -	</table>
   8.679 +					cat <<-EOT
   8.680 +						</table>
   8.681  
   8.682 -	<div class="meter" style="width:100%;text-align:center"><div
   8.683 -	style="display:inline-block;background-color:#090;width:$pct_actual%">$pkg_actual</div><div
   8.684 -	style="display:inline-block;background-color:#f90;width:$pct_outdated%">$pkg_outdated</div><div
   8.685 -	style="display:inline-block;background-color:#ccc;width:$pct_unknown%">$pkg_unknown</div></div>
   8.686 -EOT
   8.687 +						<div class="meter" style="width:100%;text-align:center"><div
   8.688 +						style="display:inline-block;background-color:#090;width:$pct_actual%">$pkg_actual</div><div
   8.689 +						style="display:inline-block;background-color:#f90;width:$pct_outdated%">$pkg_outdated</div><div
   8.690 +						style="display:inline-block;background-color:#ccc;width:$pct_unknown%">$pkg_unknown</div></div>
   8.691 +					EOT
   8.692  					rm $tmp_status
   8.693  				fi
   8.694 -				cat <<EOT
   8.695 -</section>
   8.696 -EOT
   8.697 +				cat <<-EOT
   8.698 +					</section>
   8.699 +				EOT
   8.700  				;;
   8.701  		esac
   8.702  		page_footer
   8.703 @@ -1258,29 +1474,29 @@
   8.704  	# Main page with summary. Count only packages included in ARCH,
   8.705  	# use 'cooker arch-db' to manually create arch.$ARCH files.
   8.706  
   8.707 -	cat <<EOT
   8.708 -<div id="content2">
   8.709 +	cat <<-EOT
   8.710 +		<div id="content2">
   8.711  
   8.712 -<section>
   8.713 -<form method="get" action="" class="search r">
   8.714 -	<input type="hidden" name="search" value="pkg"/>
   8.715 -	<button type="submit" title="Search">Search</button>
   8.716 -	<input type="search" name="q" placeholder="Package" list="packages" autocorrect="off" autocapitalize="off"/>
   8.717 -</form>
   8.718 -EOT
   8.719 +		<section>
   8.720 +		<form method="get" action="" class="search r">
   8.721 +			<input type="hidden" name="search" value="pkg"/>
   8.722 +			<button type="submit" title="Search">Search</button>
   8.723 +			<input type="search" name="q" placeholder="Package" list="packages" autocorrect="off" autocapitalize="off"/>
   8.724 +		</form>
   8.725 +	EOT
   8.726  
   8.727  	unset nojs
   8.728  	part summary
   8.729  	part webstat
   8.730  
   8.731 -	cat <<EOT
   8.732 -<p>
   8.733 -	Service logs:
   8.734 -	<a href="?cookorder.log">cookorder</a> ·
   8.735 -	<a href="?commits.log">commits</a> ·
   8.736 -	<a href="?pkgdb.log">pkgdb</a>
   8.737 -</p>
   8.738 -EOT
   8.739 +	cat <<-EOT
   8.740 +		<p>
   8.741 +			Service logs:
   8.742 +			<a href="?cookorder.log">cookorder</a> ·
   8.743 +			<a href="?commits.log">commits</a> ·
   8.744 +			<a href="?pkgdb.log">pkgdb</a>
   8.745 +		</p>
   8.746 +	EOT
   8.747  
   8.748  	if [ -e "$CACHE/cooker-request" -a ! -s $command ]; then
   8.749  		if [ "$activity" -nt "$CACHE/cooker-request" ]; then
   8.750 @@ -1290,10 +1506,11 @@
   8.751  		fi
   8.752  	fi
   8.753  
   8.754 -	cat <<EOT
   8.755 -<a class="button icon maintainers" href="?maintainer">For maintainers</a>
   8.756 -</section>
   8.757 -EOT
   8.758 +	cat <<-EOT
   8.759 +		<a class="button icon maintainers" href="?maintainer">For maintainers</a>
   8.760 +		<a class="button icon tag" href="~/">Tags</a>
   8.761 +		</section>
   8.762 +	EOT
   8.763  
   8.764  	part activity
   8.765  	part cooknotes
   8.766 @@ -1312,30 +1529,91 @@
   8.767  
   8.768  # show tag
   8.769  
   8.770 -if [ "$pkg" == '~' -a -n "$cmd" ]; then
   8.771 -	tag="$cmd"
   8.772 +if [ "$pkg" == '~' ]; then
   8.773  	page_header
   8.774 -	cat <<EOT
   8.775 -<div id="content2">
   8.776 -<section>
   8.777 -<h2>Tag “$tag”</h2>
   8.778 +	echo '<div id="content2"><section>'
   8.779  
   8.780 -<table>
   8.781 -	<thead>
   8.782 -		<tr><th>Name</th><th>Description</th><th>Category</th></tr>
   8.783 -	</thead>
   8.784 -	<tbody>
   8.785 -EOT
   8.786 -	sort $PKGS/packages.info \
   8.787 -	| awk -F$'\t' -vtag=" $tag " -vbase="$base" '{
   8.788 -		if (index(" " $6 " ", tag)) {
   8.789 -			url = base "/" $1 "/";
   8.790 -			gsub("+", "%2B", url);
   8.791 -			printf("<tr><td><img src=\"%s/s/%s\"> ", base, $1);
   8.792 -			printf("<a href=\"%s\">%s</a></td><td>%s</td><td>%s</td></tr>\n", url, $1, $4, $3);
   8.793 -		}
   8.794 -	}'
   8.795 -	echo '</tbody></table></section></div>'
   8.796 +	if [ -n "$cmd" ]; then
   8.797 +		tag="$cmd"
   8.798 +		cat <<-EOT
   8.799 +			<h2>Tag “$tag”</h2>
   8.800 +
   8.801 +			<table>
   8.802 +				<thead><tr><th>Name</th><th>Description</th><th>Category</th></tr></thead>
   8.803 +				<tbody>
   8.804 +		EOT
   8.805 +		sort $PKGS/packages-$ARCH.info \
   8.806 +		| awk -F$'\t' -vtag=" $tag " -vbase="$base/" '{
   8.807 +			if (index(" " $6 " ", tag)) {
   8.808 +				url = base $1 "/";
   8.809 +				gsub("+", "%2B", url);
   8.810 +				printf("<tr><td><img src=\"%ss/%s\" alt=\"%s\"> ", base, $1, $1);
   8.811 +				printf("<a href=\"%s\">%s</a></td><td>%s</td><td>%s</td></tr>\n", url, $1, $4, $3);
   8.812 +			}
   8.813 +		}'
   8.814 +		echo '</tbody></table>'
   8.815 +	else
   8.816 +		# Fast and nice tag cloud
   8.817 +		echo '<h2>Tag cloud</h2><p class="tags">'
   8.818 +		# Some magic in tag sizes :-) It's because of non-linear distribution
   8.819 +		# of tags. Currently 1x198 (each of 198 tags marks one package);
   8.820 +		# 2x79 (each of 79 other tags marks two packages); 3x28 (and so on);
   8.821 +		# 4x23; 5x14; 6x5; 7x9; 8x11; 9x4; 10x3; 11x5; 12x6; 13x3; 14x1; 15x1;
   8.822 +		# 16x2; 18x1; 20x3; 22x3; 23, 24, 27, 33, 39, 42, 45, 57, 59, 65, 90x1.
   8.823 +		awk -F$'\t' -vbase="$base/~/" '
   8.824 +			{
   8.825 +				split($6, tags, " ");
   8.826 +				for (i in tags) { tag[tags[i]]++; if (tag[tags[i]] > max) max = tag[tags[i]]; }
   8.827 +			}
   8.828 +		END {
   8.829 +				for (i in tag) {
   8.830 +					j = tag[i];
   8.831 +					size = (j == 1) ? 0 : (j == 2) ? 1 : (j < 5) ? 2 : (j < 9) ? 3 : (j < 18) ? 4 : 5;
   8.832 +					printf("<a href=\"%s\" class=\"tag%s\">%s<sup>%s</sup></a>\n", base i, size, i, tag[i]);
   8.833 +				}
   8.834 +			}
   8.835 +		' $PKGS/packages-$ARCH.info | sort -f # sort alphabetically case insensitive
   8.836 +	fi
   8.837 +	echo '</p></section></div>'
   8.838 +	page_footer
   8.839 +	exit 0
   8.840 +fi
   8.841 +
   8.842 +
   8.843 +# show badges
   8.844 +
   8.845 +if [ "$pkg" == '%' ]; then
   8.846 +	page_header
   8.847 +	echo '<div id="content2">'
   8.848 +
   8.849 +	if [ -n "$cmd" ]; then
   8.850 +		badge="$cmd"
   8.851 +		cat <<-EOT
   8.852 +			<section>
   8.853 +				<h2 class="badge $badge"> Badge “$badge”</h2>
   8.854 +
   8.855 +				<table>
   8.856 +					<thead><tr><th>Name</th><th>Description</th><th>Category</th></tr></thead>
   8.857 +					<tbody>
   8.858 +		EOT
   8.859 +		ls $WOK \
   8.860 +		| while read pkg; do
   8.861 +			[ -e $WOK/$pkg/.badges ] || continue
   8.862 +			grep -q "^${badge}$" $WOK/$pkg/.badges &&
   8.863 +			awk -F$'\t' -vpkg="$pkg" -vbase="$base/" '{
   8.864 +				if ($1 == pkg) {
   8.865 +					url = base $1 "/";
   8.866 +					gsub("+", "%2B", url);
   8.867 +					printf("<tr><td><img src=\"%ss/%s\" alt=\"%s\"> ", base, $1, $1);
   8.868 +					printf("<a href=\"%s\">%s</a></td><td>%s</td><td>%s</td></tr>\n", url, $1, $4, $3);
   8.869 +				}
   8.870 +			}' $PKGS/packages-$ARCH.info
   8.871 +		done
   8.872 +		echo '</tbody></table></section>'
   8.873 +	else
   8.874 +		layout='list' show_badges bdbroken broken any noany libtool nolibtool own ownover perm permover symlink ss fadd frem fdup old orphan patch win
   8.875 +	fi
   8.876 +	echo '</div>'
   8.877  	page_footer
   8.878  	exit 0
   8.879  fi
   8.880 @@ -1396,17 +1674,23 @@
   8.881  		summary "$log"
   8.882  
   8.883  
   8.884 +		# Show Cooker badges
   8.885 +		if [ -s $wok/$pkg/.badges ]; then
   8.886 +			layout='table' show_badges $(cat $wok/$pkg/.badges)
   8.887 +		fi
   8.888 +
   8.889 +
   8.890  		# Repology badge
   8.891 -		[ "$REPOLOGY" == '-' ] || cat <<EOT
   8.892 -<section>
   8.893 -	<h3>Repology</h3>
   8.894 -	<a href="https://repology.org/metapackage/${REPOLOGY:-$pkg}" target='_blank'
   8.895 -	rel='noopener noreferrer' title="latest packaged version(s) by Repology">
   8.896 -	<img src="https://repology.org/badge/latest-versions/${REPOLOGY:-$pkg}.svg" alt="latest packaged version(s)">
   8.897 -	<img src="https://repology.org/badge/tiny-repos/${REPOLOGY:-$pkg}.svg" alt="Packaging status">
   8.898 -	</a>
   8.899 -</section>
   8.900 -EOT
   8.901 +		[ "$REPOLOGY" == '-' ] || cat <<-EOT
   8.902 +			<section>
   8.903 +				<h3>Repology</h3>
   8.904 +				<a href="https://repology.org/metapackage/${REPOLOGY:-$pkg}" target='_blank'
   8.905 +				rel='noopener noreferrer' title="latest packaged version(s) by Repology">
   8.906 +				<img src="https://repology.org/badge/latest-versions/${REPOLOGY:-$pkg}.svg" alt="latest packaged version(s)">
   8.907 +				<img src="https://repology.org/badge/tiny-repos/${REPOLOGY:-$pkg}.svg" alt="Packaging status">
   8.908 +				</a>
   8.909 +			</section>
   8.910 +			EOT
   8.911  
   8.912  
   8.913  		# Show tag list
   8.914 @@ -1463,23 +1747,23 @@
   8.915  			done
   8.916  		} | sort -u > $inf/c
   8.917  
   8.918 -		cat <<EOT
   8.919 -<section>
   8.920 -	<h3>Related packages</h3>
   8.921 -	<table class="third">
   8.922 -		<thead>
   8.923 -			<tr>
   8.924 -				<th>Build dependencies</th>
   8.925 -				<th>Runtime dependencies</th>
   8.926 -				<th>Required by</th>
   8.927 -			</tr>
   8.928 -		</thead>
   8.929 -		<tbody>
   8.930 -EOT
   8.931 +		cat <<-EOT
   8.932 +			<section>
   8.933 +				<h3>Related packages</h3>
   8.934 +				<table class="third">
   8.935 +					<thead>
   8.936 +						<tr>
   8.937 +							<th>Build dependencies</th>
   8.938 +							<th>Runtime dependencies</th>
   8.939 +							<th>Required by</th>
   8.940 +						</tr>
   8.941 +					</thead>
   8.942 +					<tbody>
   8.943 +		EOT
   8.944  
   8.945  		awk -vinf="$inf" -vbase="$base" '
   8.946  			function linki(i) {
   8.947 -				if (i) return sprintf("<img src=\"%s/s/%s\"> <a href=\"%s/%s\">%s</a>", base, i, base, i, i);
   8.948 +				if (i) return sprintf("<img src=\"%s/s/%s\" alt=\"%s\"> <a href=\"%s/%s\">%s</a>", base, i, i, base, i, i);
   8.949  			}
   8.950  			BEGIN{
   8.951  				do {
   8.952 @@ -1490,11 +1774,11 @@
   8.953  					printf("<tr><td>%s </td><td>%s </td><td>%s </td></tr>", linki(a), linki(b), linki(c));
   8.954  				} while ( a b c )
   8.955  			}'
   8.956 -		cat <<EOT
   8.957 -		</tbody>
   8.958 -	</table>
   8.959 -</section>
   8.960 -EOT
   8.961 +		cat <<-EOT
   8.962 +					</tbody>
   8.963 +				</table>
   8.964 +			</section>
   8.965 +		EOT
   8.966  		# Clean
   8.967  		rm -r $inf
   8.968  
   8.969 @@ -1539,6 +1823,7 @@
   8.970  			case $file in
   8.971  				*.desktop|*.theme)   class="ini" ;;
   8.972  				*.patch|*.diff|*.u)  class="diff" ;;
   8.973 +				*/patches/series)    class="bash";;
   8.974  				*.sh)                class="bash" ;;
   8.975  				*.conf*|*.ini)
   8.976  					class="bash"
   8.977 @@ -1572,7 +1857,7 @@
   8.978  			# Display image
   8.979  			case $file in
   8.980  				*.png|*.svg|*.jpg|*.jpeg|*.ico)
   8.981 -					echo "<img src='$base/$pkg/browse/stuff/$arg' style='display: block; max-width: 100%; margin: auto'/>"
   8.982 +					echo "<img src='$base/$pkg/browse/stuff/$arg' style='display: block; max-width: 100%; margin: auto' alt=''/>"
   8.983  					;;
   8.984  			esac
   8.985  
   8.986 @@ -1672,17 +1957,17 @@
   8.987  						esac
   8.988  						echo -e '\t<ul>'
   8.989  						echo "$pkgsofset" | sed 'p' | xargs printf "\t\t<li><a href='#%s'>%s</a></li>\n"
   8.990 -						cat <<EOT
   8.991 -		<li id='li-repeats$set' style='display:none'>
   8.992 -			<a href='#repeats$set'>repeatedly packaged files</a></li>
   8.993 -		<li id='li-empty$set' style='display:none'>
   8.994 -			<a href='#empty$set'>unpackaged empty folders</a></li>
   8.995 -		<li id='li-outoftree$set' style='display:none'>
   8.996 -			<a href='#outoftree$set'>out-of-tree files</a></li>
   8.997 -		<li id='li-orphans$set' style='display:none'>
   8.998 -			<a href='#orphans$set'>unpackaged files</a>
   8.999 -			<span id='orphansTypes$set'></span></li>
  8.1000 -EOT
  8.1001 +						cat <<-EOT
  8.1002 +							<li id='li-repeats$set' style='display:none'>
  8.1003 +								<a href='#repeats$set'>repeatedly packaged files</a></li>
  8.1004 +							<li id='li-empty$set' style='display:none'>
  8.1005 +								<a href='#empty$set'>unpackaged empty folders</a></li>
  8.1006 +							<li id='li-outoftree$set' style='display:none'>
  8.1007 +								<a href='#outoftree$set'>out-of-tree files</a></li>
  8.1008 +							<li id='li-orphans$set' style='display:none'>
  8.1009 +								<a href='#orphans$set'>unpackaged files</a>
  8.1010 +								<span id='orphansTypes$set'></span></li>
  8.1011 +						EOT
  8.1012  						echo -e '\t</ul>'
  8.1013  						[ -n "$splitsets" ] && echo "</li>"
  8.1014  						;;
  8.1015 @@ -1697,7 +1982,7 @@
  8.1016  						for p in $pkgsofset; do
  8.1017  							namever="$(awk -F$'\t' -vp="$p" '{
  8.1018  								if ($1==p) {printf("%s-%s\n", $1, $2); exit}
  8.1019 -								}' $PKGS/packages.info)"
  8.1020 +								}' $PKGS/packages-$ARCH.info)"
  8.1021  							if [ -d "$wok/$p/taz/$p-$ver" ]; then
  8.1022  								indir=$p
  8.1023  							elif [ -d "$wok/$main/taz/$p-$ver" ]; then
  8.1024 @@ -1739,10 +2024,12 @@
  8.1025  						repeats=$(mktemp)
  8.1026  						sort $packaged | uniq -d > $repeats
  8.1027  						if [ -s "$repeats" ]; then
  8.1028 -							echo
  8.1029 -							echo "<script>document.getElementById('li-repeats$set').style.display = 'list-item'</script>"
  8.1030 -							echo "<section id='repeats$set'>"
  8.1031 -							echo "	<h3>Repeatedly packaged files$set_description:</h3>"
  8.1032 +							cat <<-EOT
  8.1033 +
  8.1034 +								<script>document.getElementById('li-repeats$set').style.display = 'list-item'</script>
  8.1035 +								<section id='repeats$set'>
  8.1036 +									<h3>Repeatedly packaged files$set_description:</h3>
  8.1037 +							EOT
  8.1038  							cd $install
  8.1039  
  8.1040  							IFS=$'\n'
  8.1041 @@ -1753,8 +2040,10 @@
  8.1042  								| syntax_highlighter files \
  8.1043  								| sed 's|>\./|>/|'
  8.1044  							done < $repeats
  8.1045 -							echo '</pre>'
  8.1046 -							echo '</section>'
  8.1047 +							cat <<-EOT
  8.1048 +								</pre>
  8.1049 +								</section>
  8.1050 +							EOT
  8.1051  							unset IFS
  8.1052  						fi
  8.1053  						rm $repeats
  8.1054 @@ -1790,15 +2079,19 @@
  8.1055  						done > $emptydirs
  8.1056  						unset IFS
  8.1057  						if [ -s "$emptydirs" ]; then
  8.1058 -							echo
  8.1059 -							echo "<script>document.getElementById('li-empty$set').style.display = 'list-item'</script>"
  8.1060 -							echo "<section id='empty$set'>"
  8.1061 -							echo "	<h3>Unpackaged empty folders$set_description:</h3>"
  8.1062 +							cat <<-EOT
  8.1063 +
  8.1064 +								<script>document.getElementById('li-empty$set').style.display = 'list-item'</script>
  8.1065 +								<section id='empty$set'>
  8.1066 +									<h3>Unpackaged empty folders$set_description:</h3>
  8.1067 +							EOT
  8.1068  							echo -n '	<pre class="files">'
  8.1069  							echo -en '<span class="underline">permissions·lnk·user    ·group   ·     size·date &amp; time ·name\n</span>'
  8.1070  							cat $emptydirs
  8.1071 -							echo '</pre>'
  8.1072 -							echo '</section>'
  8.1073 +							cat <<-EOT
  8.1074 +								</pre>
  8.1075 +								</section>
  8.1076 +							EOT
  8.1077  						fi
  8.1078  						rm $emptydirs
  8.1079  						# ------------------------------------------------------
  8.1080 @@ -1892,7 +2185,9 @@
  8.1081  							/\.h$/ || /\.a$/ || /\.pc$/ || /\/bin\/.*-config$/ ||
  8.1082  								/\/Makefile.*$/ { tag("dev", 3); next }
  8.1083  							/\/share\/help\// || /\/share\/appdata\// ||
  8.1084 -							/\/share\/metainfo\// { tag("gnm", 6); next }
  8.1085 +							/\/share\/metainfo\// || /\/share\/application-registry\// ||
  8.1086 +							/\/share\/mime-info\// || /\/share\/gnome\/help\// || /\/share\/omf\// {
  8.1087 +								tag("gnm", 6); next }
  8.1088  							{ tag("???", 1) }
  8.1089  							' "$orphans" > $table
  8.1090  
  8.1091 @@ -2042,7 +2337,7 @@
  8.1092  		# disable next `sed` for the 'like2016' theme
  8.1093  		theme=$(COOKIE theme); theme=${theme:-default}; [ "$theme" != 'like2016' ] && theme=''
  8.1094  		cat $logfile | syntax_highlighter log | \
  8.1095 -		sed -e "/(pkg\/local$theme):/ s|: \([^<]*\)|<img src='$base/i/$blog/\1'> \1|" | \
  8.1096 +		sed -e "/(pkg\/local$theme):/ s|: \([^<]*\)|<img src='$base/i/$blog/\1' alt=''> \1|" | \
  8.1097  		awk '
  8.1098  		BEGIN { print "<pre class=\"log\">"; }
  8.1099  		      { printf("<span id=\"l%d\">%s</span><a href=\"#l%d\"></a>\n", NR, $0, NR); }
  8.1100 @@ -2138,14 +2433,14 @@
  8.1101  								wok/*) page="${arg#wok/}"; page="$base/$pkg/browse/${page#*/}";;
  8.1102  								*)     page="$base/$pkg/browse/install/usr/share/$cmd/$arg";;
  8.1103  							esac
  8.1104 -							cat <<EOT
  8.1105 -<object id="idoc" data="$page" width="100%" height="100%" type="application/pdf" style="min-height: 600px">
  8.1106 -	$(show_note w "Missing PDF plugin.<br/>Get the file <a href="$page">$(basename "$page")</a>.")
  8.1107 -</object>
  8.1108 -EOT
  8.1109 +							cat <<-EOT
  8.1110 +								<object id="idoc" data="$page" width="100%" height="100%" type="application/pdf" style="min-height: 600px">
  8.1111 +									$(show_note w "Missing PDF plugin.<br/>Get the file <a href="$page">$(basename "$page")</a>.")
  8.1112 +								</object>
  8.1113 +							EOT
  8.1114  							;;
  8.1115  						*.md|*.markdown)
  8.1116 -							echo '<section>'
  8.1117 +							echo '<section class="markdown">'
  8.1118  							$md2html "$tmp" | sed 's|class="|class="language-|g'
  8.1119  							echo '</section>'
  8.1120  							;;
  8.1121 @@ -2204,7 +2499,7 @@
  8.1122  
  8.1123  		if [ -n "$TARBALL" -a -s "$SRC/$TARBALL" ]; then
  8.1124  			files_header
  8.1125 -			echo "<tr><td><a href='$base/src/$TARBALL'>$TARBALL</a></td>"
  8.1126 +			echo "<tr><td><a href='$base/src/$TARBALL' class='icon tarball'>$TARBALL</a></td>"
  8.1127  			ls -lh "$SRC/$TARBALL" | awk '{printf("<td>%sB</td>", $5)}'
  8.1128  			echo "<td>Sources for building the package “$pkg”</td></tr>"
  8.1129  			show=1
  8.1130 @@ -2214,19 +2509,25 @@
  8.1131  			[ "$show" -eq 1 ] || files_header
  8.1132  
  8.1133  			common_version=$VERSION
  8.1134 -			for i in $(all_names); do
  8.1135 +			for i in $(all_names | tr ' ' '\n' | sort); do
  8.1136  				[ -e "$wok/$pkg/taz/$i-$common_version$EXTRAVERSION/receipt" ] || continue
  8.1137  				. $wok/$pkg/taz/$i-$common_version$EXTRAVERSION/receipt
  8.1138  
  8.1139 -				for filename in "$PACKAGE-$VERSION$EXTRAVERSION.tazpkg" "$PACKAGE-$VERSION$EXTRAVERSION-$ARCH.tazpkg"; do
  8.1140 -					[ -f "$PKGS/$filename" ] &&
  8.1141 -						cat <<EOT
  8.1142 -<tr>
  8.1143 -<td><a href="$base/get/$filename">$filename</a></td>
  8.1144 -<td>$(ls -lh ./packages/$filename | awk '{printf("%sB", $5)}')</td>
  8.1145 -<td>$SHORT_DESC</td>
  8.1146 -</tr>
  8.1147 -EOT
  8.1148 +				for filename in "$PACKAGE-$VERSION$EXTRAVERSION.tazpkg" "$PACKAGE-$VERSION$EXTRAVERSION-$ARCH.tazpkg" "$PACKAGE-$VERSION$EXTRAVERSION-any.tazpkg"; do
  8.1149 +					[ -f "$PKGS/$filename" ] || continue
  8.1150 +
  8.1151 +					case $filename in
  8.1152 +						*-x86_64.tazpkg) class='pkg64';;
  8.1153 +						*-any.tazpkg)    class='pkgany';;
  8.1154 +						*)               class='pkg32';;
  8.1155 +					esac
  8.1156 +					cat <<-EOT
  8.1157 +						<tr>
  8.1158 +							<td><a href="$base/get/$filename" class='icon $class'>$filename</a></td>
  8.1159 +							<td>$(ls -lh ./packages/$filename | awk '{printf("%sB", $5)}')</td>
  8.1160 +							<td>$SHORT_DESC</td>
  8.1161 +						</tr>
  8.1162 +					EOT
  8.1163  				done
  8.1164  			done
  8.1165  			show=1
     9.1 --- a/modules/deps	Sat Aug 25 17:30:05 2018 +0300
     9.2 +++ b/modules/deps	Sat Nov 24 13:28:02 2018 +0200
     9.3 @@ -179,6 +179,7 @@
     9.4  				s("freetype-dev", "freetype-infinality-dev");
     9.5  				s("nspr", "webian-shell");
     9.6  				s("nss", "webian-shell");
     9.7 +				s("libxml2", "libxml2-min");
     9.8  
     9.9  				# if called with "--incl": show all deps including glibc-base,
    9.10  				# gcc-lib-base, glibc-dev and gcc; otherwise hide them
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/modules/langdesc	Sat Nov 24 13:28:02 2018 +0200
    10.3 @@ -0,0 +1,110 @@
    10.4 +#!/bin/sh
    10.5 +#
    10.6 +# langdesc - module of the SliTaz Cook
    10.7 +# Copyright (C) SliTaz GNU/Linux - GNU GPL v3
    10.8 +#
    10.9 +
   10.10 +# Information source: iso-codes package
   10.11 +
   10.12 +langdesc() {
   10.13 +	local i
   10.14 +	case $1 in
   10.15 +		af) i='Afrikaans';;
   10.16 +		am) i='Amharic';;
   10.17 +		ar) i='Arabic';;
   10.18 +		ast) i='Asturian';;
   10.19 +		az) i='Azerbaijani';;
   10.20 +		be) i='Belarusian';;
   10.21 +		be@latin) i='Belarusian (Latin script)';;
   10.22 +		bg) i='Bulgarian';;
   10.23 +		bn) i='Bengali';;
   10.24 +		bn_IN) i='Bengali (India)';;
   10.25 +		br) i='Breton';;
   10.26 +		bs) i='Bosnian';;
   10.27 +		ca) i='Catalan';;
   10.28 +		da) i='Danish';;
   10.29 +		de) i='German';;
   10.30 +		el) i='Greek';;
   10.31 +		en) i='English';;
   10.32 +		en_GB) i='English (British)';;
   10.33 +		en_ZA) i='English (South African)';;
   10.34 +		eo) i='Esperanto';;
   10.35 +		es) i='Spanish';;
   10.36 +		et) i='Estonian';;
   10.37 +		eu) i='Basque';;
   10.38 +		fa) i='Persian';;
   10.39 +		fi) i='Finnish';;
   10.40 +		fr) i='French';;
   10.41 +		ga) i='Irish';;
   10.42 +		gd) i='Scottish Gaelic';;
   10.43 +		gl) i='Galician';;
   10.44 +		gu) i='Gujarati';;
   10.45 +		he) i='Hebrew';;
   10.46 +		hi) i='Hindi';;
   10.47 +		hr) i='Croatian';;
   10.48 +		hu) i='Hungarian';;
   10.49 +		hy) i='Armenian';;
   10.50 +		ia) i='Interlingua';;
   10.51 +		id) i='Indonesian';;
   10.52 +		is) i='Icelandic';;
   10.53 +		it) i='Italian';;
   10.54 +		ja) i='Japanese';;
   10.55 +		ka) i='Georgian';;
   10.56 +		kk) i='Kazakh';;
   10.57 +		kn) i='Kannada';;
   10.58 +		ko) i='Korean';;
   10.59 +		ku) i='Kurdish';;
   10.60 +		ky) i='Kirghiz';;
   10.61 +		lg) i='Luganda';;
   10.62 +		lo) i='Lao';;
   10.63 +		lt) i='Lithuanian';;
   10.64 +		lv) i='Latvian';;
   10.65 +		mk) i='Macedonian';;
   10.66 +		ml) i='Malayalam';;
   10.67 +		mn) i='Mongolian';;
   10.68 +		mr) i='Marathi';;
   10.69 +		ms) i='Malay';;
   10.70 +		mt) i='Maltese';;
   10.71 +		nb) i='Norwegian Bokmål';;
   10.72 +		nds) i='Low German';;
   10.73 +		ne) i='Nepali';;
   10.74 +		nl) i='Dutch';;
   10.75 +		nn) i='Norwegian Nynorsk';;
   10.76 +		pa) i='Punjabi';;
   10.77 +		pl) i='Polish';;
   10.78 +		ps) i='Pashto';;
   10.79 +		pt) i='Portuguese';;
   10.80 +		pt_BR) i='Brazilian Portuguese';;
   10.81 +		ro) i='Romanian';;
   10.82 +		ru) i='Russian';;
   10.83 +		rw) i='Kinyarwanda';;
   10.84 +		sk) i='Slovak';;
   10.85 +		sl) i='Slovenian';;
   10.86 +		so) i='Somali';;
   10.87 +		sq) i='Albanian';;
   10.88 +		sr) i='Serbian';;
   10.89 +		sv) i='Swedish';;
   10.90 +		sw) i='Swahili';;
   10.91 +		ta) i='Tamil';;
   10.92 +		te) i='Telugu';;
   10.93 +		tg) i='Tajik';;
   10.94 +		th) i='Thai';;
   10.95 +		tr) i='Turkish';;
   10.96 +		uk) i='Ukrainian';;
   10.97 +		ur) i='Urdu';;
   10.98 +		vi) i='Vietnamese';;
   10.99 +		wa) i='Walloon';;
  10.100 +		zh) i='Chinese';;
  10.101 +		zh_CN) i='Chinese (simplified)';;
  10.102 +		zh_HK) i='Chinese (Hong Kong)';;
  10.103 +		zh_TW) i='Chinese (traditional)';;
  10.104 +	esac
  10.105 +
  10.106 +	case $2 in
  10.107 +		'') echo "$i";;
  10.108 +		-)  echo "$i" | sed 's|(|- |; s|)||';;
  10.109 +	esac
  10.110 +}
  10.111 +
  10.112 +# langdesc en_GB      -> 'English (British)'
  10.113 +# langdesc en_GB -    -> 'English - British'
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/modules/pack	Sat Nov 24 13:28:02 2018 +0200
    11.3 @@ -0,0 +1,865 @@
    11.4 +#!/bin/sh
    11.5 +#
    11.6 +# pack - module of the SliTaz Cook
    11.7 +# Copyright (C) SliTaz GNU/Linux - GNU GPL v3
    11.8 +#
    11.9 +
   11.10 +. /usr/lib/slitaz/libcook.sh
   11.11 +
   11.12 +
   11.13 +######################################################
   11.14 +# BEGIN: Functions may be used in the genpkg_rules() #
   11.15 +######################################################
   11.16 +
   11.17 +
   11.18 +# A bit smarter function than the classic `cp` command
   11.19 +
   11.20 +scopy() {
   11.21 +	if [ "$(stat -c %h -- "$1")" -eq 1 ]; then
   11.22 +		cp -a  "$1" "$2"	# copy generic files
   11.23 +	else
   11.24 +		cp -al "$1" "$2"	# copy hardlinks
   11.25 +	fi
   11.26 +}
   11.27 +
   11.28 +
   11.29 +# Copy specified files from $install to $fs
   11.30 +
   11.31 +cook_copy_files() {
   11.32 +	action 'Copying files...'
   11.33 +	cd $install
   11.34 +	local i j
   11.35 +	IFS=$'\n'
   11.36 +	for i in $@; do
   11.37 +		for j in $(find . -name $i ! -type d); do
   11.38 +			mkdir -p $fs$(dirname ${j#.})
   11.39 +			scopy $j $fs$(dirname ${j#.})
   11.40 +		done
   11.41 +	done
   11.42 +	cd - >/dev/null
   11.43 +	status
   11.44 +}
   11.45 +
   11.46 +
   11.47 +# Copy specified folders from $install to $fs
   11.48 +
   11.49 +cook_copy_folders() {
   11.50 +	action 'Copying folders...'
   11.51 +	cd $install
   11.52 +	local i j
   11.53 +	IFS=$'\n'
   11.54 +	for i in $@; do
   11.55 +		for j in $(find . -name $i -type d); do
   11.56 +			mkdir -p $fs$(dirname ${j#.})
   11.57 +			cp -a $j $fs$(dirname ${j#.})
   11.58 +		done
   11.59 +	done
   11.60 +	cd - >/dev/null
   11.61 +	status
   11.62 +}
   11.63 +
   11.64 +
   11.65 +# Remove from current $fs files that are already packed (for receipts v2).
   11.66 +# Note: the order in $SPLIT is very important.
   11.67 +# Note 2: working in the current set.
   11.68 +
   11.69 +remove_already_packed() {
   11.70 +	local i j
   11.71 +	# $pkg is the name of the main package; $PACKAGE is the name of the current one
   11.72 +	# $pkg may (or may not) be included in the $SPLIT
   11.73 +	neighbors=$(
   11.74 +		echo $basepkg $SPLIT" " \
   11.75 +		| awk -F$'\t' -vpkg="$thispkg" '
   11.76 +		BEGIN { RS = " "; FS = ":"; }
   11.77 +		      { set[$1] = $2; }
   11.78 +		END   {
   11.79 +		        current_set = set[pkg];
   11.80 +		        for (i in set)
   11.81 +		          { if (i != pkg && set[i] == current_set) print i; }
   11.82 +		}
   11.83 +	')
   11.84 +	IFS=$'\n'
   11.85 +	for neighbor in $neighbors; do
   11.86 +		i="$taz/$neighbor-$VERSION$EXTRAVERSION/files.list"
   11.87 +		[ -e "$i" ] || continue
   11.88 +		while read j; do
   11.89 +			[ -f $fs$j -o -h $fs$j ] || continue
   11.90 +			rm $fs$j
   11.91 +			rmdir --parents --ignore-fail-on-non-empty $fs$(dirname $j)
   11.92 +		done < $i
   11.93 +	done
   11.94 +	unset IFS
   11.95 +}
   11.96 +
   11.97 +
   11.98 +# Copy hicolor icons in specified sizes (default: 16 and 48) from $install to $fs
   11.99 +
  11.100 +cook_copy_icons() {
  11.101 +	local sizes=$@ i j ifs="$IFS"
  11.102 +	unset IFS
  11.103 +	action 'Copying hicolor icons...'
  11.104 +	[ -d "$fs/usr/share/icons/hicolor" ] && rm -rf "$fs/usr/share/icons/hicolor"
  11.105 +	mkdir -p $fs/usr/share/icons/hicolor
  11.106 +	for i in ${sizes:-16 48}; do
  11.107 +		j="${i}x$i"; [ "$i" == 'scalable' ] && j="$i"
  11.108 +		[ ! -e "$install/usr/share/icons/hicolor/$j" ] ||
  11.109 +		scopy   $install/usr/share/icons/hicolor/$j \
  11.110 +			         $fs/usr/share/icons/hicolor
  11.111 +	done
  11.112 +	status
  11.113 +	IFS="$ifs"
  11.114 +}
  11.115 +
  11.116 +
  11.117 +# Common function to copy files, folders and patterns
  11.118 +
  11.119 +copy() {
  11.120 +	action 'Copying folders and files...'
  11.121 +	local i j k filelist=$(mktemp) folderlist=$(mktemp)
  11.122 +
  11.123 +	IFS=$'\n'
  11.124 +	cd $install
  11.125 +	find ! -type d | sed 's|\.||' > $filelist
  11.126 +	find   -type d | sed 's|\.||' > $folderlist
  11.127 +
  11.128 +	for i in $@; do
  11.129 +		case $i in
  11.130 +			@std)
  11.131 +				# Copy "standard" files (all but "developer files", man pages, documentation, translations)
  11.132 +				sed '/\.h$/d; /\.hxx$/d; /\.a$/d; /\.la$/d; /\.pc$/d; /\.pri$/d; /bin\/.*-config$/d;
  11.133 +					/\.m4$/d; /\.gir$/d; /\.typelib$/d; /\.vapi$/d; /\.deps$/d; /\.cmake$/d;
  11.134 +					/\/Makefile.*/d; /\.inc$/d; /\/include\//d;
  11.135 +					/\/share\/man\//d; /\/share\/doc\//d; /\/share\/gtk-doc\//d; /\/share\/info\//d;
  11.136 +					/\/share\/devhelp\//d; /\/share\/locale\//d;
  11.137 +					/\/share\/bash-completion\//d; /\/etc\/bash_completion\.d\//d; /\/lib\/systemd\//d;
  11.138 +					/\/fonts\.scale$/d; /\/fonts\.dir$/d;
  11.139 +					/\/share\/appdata\//d; /\/share\/help\//d; /\/share\/metainfo\//d; /\/share\/mimelnk\//d;
  11.140 +					/\/share\/application-registry\//d; /\/share\/mime-info\//d;
  11.141 +					/\/share\/gnome\/help\//d; /\/share\/omf\//d;
  11.142 +					/\/share\/icons\/hicolor\/[12356][1245][268]*x[12356][1245][268]*\//d;	# 22, 24, 32, 64, 128, 256, 512
  11.143 +					/\.so\.dbg$/d;
  11.144 +					' $filelist
  11.145 +				;;
  11.146 +			@dev)
  11.147 +				# Copy "developer files"
  11.148 +				sed -n '
  11.149 +					/\/share\/doc\//d;
  11.150 +					/\.h$/p; /\.hxx$/p; /\.a$/p; /\.pc$/p; /\.pri$/p; /bin\/.*-config$/p;
  11.151 +					/\.m4$/p; /\.gir$/p; /\.typelib$/p; /\.vapi$/p; /\.deps$/p; /\.cmake$/p;
  11.152 +					/\/Makefile.*/p; /\.inc$/p; /\/include\//p;
  11.153 +					/\.so\.dbg$/p;
  11.154 +					' $filelist
  11.155 +				;;
  11.156 +			@ruby)
  11.157 +				# Copy mandatory Ruby files
  11.158 +				gem_base="\/usr\/lib\/ruby\/gems\/.*\/${PACKAGE#*-}-$VERSION"
  11.159 +				sed -n '/\/extensions\/.*\.so$/p; /'$gem_base'\/lib\//p; /\.gemspec$/p;
  11.160 +					/\/usr\/bin\//p; /\/gems\/.*\/bin\//p;
  11.161 +					' $filelist | sed '/\/gems\/.*\/lib\/.*\.so$/d; /\/gems\/.*\/lib\/.*\.h$/d;
  11.162 +					/\/gems\/.*\/gems\/.*\.gemspec$/d;'
  11.163 +				;;
  11.164 +			@ruby-dev)
  11.165 +				sed -n '/\/ext\/.*\.h$/p; /\/ext\/.*\.pc$/p; /\/gem.build_complete$/p;
  11.166 +					/\/gems\/.*\/lib\/.*\.h$/p;
  11.167 +					' $filelist
  11.168 +				;;
  11.169 +			@rm)
  11.170 +				# Quick alias
  11.171 +				remove_already_packed
  11.172 +				;;
  11.173 +			@ico)
  11.174 +				# Quick alias
  11.175 +				cook_copy_icons >/dev/null
  11.176 +				;;
  11.177 +			*/)
  11.178 +				# Copy specified folders.
  11.179 +				i="${i%/}"
  11.180 +				find -type d -path "*/${i#/}" | sed 's|^.||'
  11.181 +				;;
  11.182 +			*)
  11.183 +				# Copy specified files.
  11.184 +				find ! -type d -path "*/${i#/}" | sed 's|^.||'
  11.185 +				;;
  11.186 +		esac \
  11.187 +		| sort -u \
  11.188 +		| while read j; do
  11.189 +			mkdir -p $fs$(dirname "$j")
  11.190 +			if [ -d "$install$j" ]; then
  11.191 +				cp -a "$install$j" $fs$(dirname "$j")
  11.192 +			else
  11.193 +				scopy "$install$j" $fs$(dirname "$j")
  11.194 +			fi
  11.195 +		done
  11.196 +		# Copy empty directories
  11.197 +		case $i in
  11.198 +			@std)
  11.199 +				while read j; do
  11.200 +					case $j in
  11.201 +						# skip empty man & doc folders
  11.202 +						*/man/*|*/doc/*) continue;;
  11.203 +					esac
  11.204 +					[ -z "$(ls -A "$install$j")" ] || continue
  11.205 +					# directory $j is empty
  11.206 +					k="$j"
  11.207 +					# make 'ladder' from directories, from root dir to $j
  11.208 +					# /a   /a/b   /a/b/c   etc.
  11.209 +					while :; do
  11.210 +						[ -z "$k" ] && break
  11.211 +						echo "$k"
  11.212 +						k="${k%/*}"
  11.213 +					done \
  11.214 +					| tac \
  11.215 +					| while read k; do
  11.216 +						# make dir if it does not exist
  11.217 +						if [ ! -d "$fs$k" ]; then
  11.218 +							# It's like "copy the directory without its underlying content".
  11.219 +							# keep original ownership/permissions, access:
  11.220 +							keepIFS="$IFS"; unset IFS
  11.221 +							install -d $(stat -c'-o%u -g%g -m%a' "$install$k") "$fs$k"
  11.222 +							# keep last-modified date:
  11.223 +							touch -r "$install$k" "$fs$k"
  11.224 +							IFS="$keepIFS"; unset keepIFS
  11.225 +						fi
  11.226 +					done
  11.227 +				done < $folderlist
  11.228 +				;;
  11.229 +		esac
  11.230 +	done
  11.231 +	cd - >/dev/null
  11.232 +	unset IFS
  11.233 +	rm $filelist $folderlist
  11.234 +	status
  11.235 +}
  11.236 +
  11.237 +####################################################
  11.238 +# END: Functions may be used in the genpkg_rules() #
  11.239 +####################################################
  11.240 +
  11.241 +
  11.242 +
  11.243 +
  11.244 +# Receipt used for cooking the package is redundant to be included into package.
  11.245 +# This script will strip the original receipt to bare minimum: variables,
  11.246 +# {pre,post}_{install,remove} functions.
  11.247 +
  11.248 +mk_pkg_receipt() {
  11.249 +	orig_receipt="$1"
  11.250 +
  11.251 +	# 1. Main package.
  11.252 +	#    By default it has no dependencies.
  11.253 +	#    You can write or omit DEPENDS="" for indicating package have no
  11.254 +	#    dependencies.
  11.255 +	# 2. Split package (excluding *-dev).
  11.256 +	#    By default every split package depends on the main package.
  11.257 +	#    Unfortunately, in the shell script (receipt is the shell script too),
  11.258 +	#    every undeclared variable has empty value, so there's no difference if
  11.259 +	#    you wrote DEPENDS="" or omit it - result will be the same empty value.
  11.260 +	#    If you want to define the split package has no dependencies - you need
  11.261 +	#    to to put single space between the quotes: DEPENDS=" ".
  11.262 +	# 3. Development split package.
  11.263 +	#    Installing *-dev package should install all the files produced during
  11.264 +	#    compilation and then were separated to the different packages, so
  11.265 +	#    by default (if you wrote DEPENDS="" or omit it) *-dev package depends
  11.266 +	#    on the main package and all the split packages (excluding the itself).
  11.267 +	[ "$DEPENDS" == ' ' ] && DEPENDS='@EMPTY@'
  11.268 +
  11.269 +	# Receipt's signature is important, although some receipts may miss it
  11.270 +	signature=$(head -n1 "$orig_receipt")
  11.271 +	[ "${signature:0:1}" == '#' ] || signature='# SliTaz package receipt.'
  11.272 +
  11.273 +	save="$(mktemp)"
  11.274 +	# `$(echo ...)`: normalize whitespace (space, tab, newline and their
  11.275 +	# combinations and repeats)
  11.276 +	cat > $save <<EOT
  11.277 +PACKAGE="$PACKAGE"; DEPENDS="$(echo $DEPENDS)"; PROVIDE="$(echo $PROVIDE)"
  11.278 +SUGGESTED="$(echo $SUGGESTED)"; TAZPANEL_DAEMON="$TAZPANEL_DAEMON"
  11.279 +TAGS="$(echo $TAGS)"; VERSION="$VERSION"; SHORT_DESC="$SHORT_DESC"
  11.280 +WEB_SITE="$WEB_SITE"; CATEGORY="$CATEGORY"
  11.281 +EOT
  11.282 +	unset_receipt
  11.283 +	. "$orig_receipt"
  11.284 +	MAIN_PACKAGE="$PACKAGE"
  11.285 +	. $save; rm $save # restore values
  11.286 +
  11.287 +	# Manage split packages
  11.288 +	SPLIT=" $SPLIT "
  11.289 +	if [ "$PACKAGE" != "$MAIN_PACKAGE"   -a   "$SPLIT" != '  ' ] &&
  11.290 +		echo "$SPLIT" | fgrep -q " $PACKAGE "; then
  11.291 +		# For packages with empty $DEPENDS
  11.292 +		if [ -z "$DEPENDS" ]; then
  11.293 +			case $PACKAGE in
  11.294 +				*-dev)
  11.295 +					# main package and all the split packages but this *-dev itself
  11.296 +					DEPENDS=$(echo "$MAIN_PACKAGE $SPLIT " | sed "s| $PACKAGE | |; s| *$||");;
  11.297 +				*)
  11.298 +					DEPENDS="$MAIN_PACKAGE";;
  11.299 +			esac
  11.300 +		fi
  11.301 +
  11.302 +		# Default $CAT
  11.303 +		[ -z "$CAT" ] &&
  11.304 +		case $PACKAGE in
  11.305 +			*-dev) CAT="development|development files" ;;
  11.306 +		esac
  11.307 +	fi
  11.308 +
  11.309 +	# Manage two-in-one $CAT="$CATEGORY|$SHORT_DESC_ADDITION"
  11.310 +	if [ -n "$CAT" ]; then
  11.311 +		CATEGORY="${CAT%|*}"
  11.312 +		SHORT_DESC="$SHORT_DESC (${CAT#*|})"
  11.313 +	fi
  11.314 +
  11.315 +	# escape quotes for receipt
  11.316 +	SHORT_DESC="${SHORT_DESC//\"/\\\"}"
  11.317 +
  11.318 +	# Mandatory variables
  11.319 +	cat <<EOF
  11.320 +$signature
  11.321 +
  11.322 +PACKAGE="$PACKAGE"
  11.323 +VERSION="$VERSION"
  11.324 +EOF
  11.325 +	[ -n "$EXTRAVERSION"    ] && echo "EXTRAVERSION=\"$EXTRAVERSION\""
  11.326 +	cat <<EOF
  11.327 +CATEGORY="$CATEGORY"
  11.328 +SHORT_DESC="$SHORT_DESC"
  11.329 +MAINTAINER="$MAINTAINER"
  11.330 +LICENSE="$LICENSE"
  11.331 +WEB_SITE="$WEB_SITE"
  11.332 +EOF
  11.333 +
  11.334 +	# Optional variables
  11.335 +	[ -n "$TAGS"            ] && echo "TAGS=\"$TAGS\""                 | tr -ds '\t' ' '
  11.336 +	case "x$DEPENDS" in
  11.337 +		x|x@EMPTY@) ;;
  11.338 +		*)                       echo "DEPENDS=\"$DEPENDS\""           | tr -ds '\t' ' ';;
  11.339 +	esac
  11.340 +	[ -n "$PROVIDE"         ] && echo "PROVIDE=\"$PROVIDE\""           | tr -ds '\t' ' '
  11.341 +	[ -n "$CONFIG_FILES"    ] && echo "CONFIG_FILES=\"$CONFIG_FILES\"" | tr -ds '\t' ' '
  11.342 +	[ -n "$SUGGESTED"       ] && echo "SUGGESTED=\"$SUGGESTED\""       | tr -ds '\t' ' '
  11.343 +	[ -n "$DATABASE_FILES"  ] && echo "DATABASE_FILES=\"$DATABASE_FILES\""
  11.344 +	[ -n "$TAZPANEL_DAEMON" ] && echo "TAZPANEL_DAEMON=\"$TAZPANEL_DAEMON\""
  11.345 +
  11.346 +	# Extract {pre,post}_{install,remove} functions;
  11.347 +	# post_install()      will be copied for both main and all the split packages
  11.348 +	# post_install_gtk_() will be copied as post_install() for gtk+ package only
  11.349 +	#
  11.350 +	# restricted name (gtk+ -> gtk_; acl-dev -> acl_dev)
  11.351 +	rname=$(echo -n $PACKAGE | tr -c 'a-zA-Z0-9' '_')
  11.352 +	for i in pre post; do
  11.353 +		for j in install remove; do
  11.354 +			sed    "/^${i}_${j}()/,/^}/!d"        "$orig_receipt"
  11.355 +			sed    "/^${i}_${j}_$rname()/,/^}/!d" "$orig_receipt" \
  11.356 +			| sed "s|^${i}_${j}_$rname()|${i}_${j}()|"
  11.357 +		done
  11.358 +	done
  11.359 +}
  11.360 +
  11.361 +
  11.362 +# Copy all generic files (locale, pixmaps, .desktop) from $install to $fs.
  11.363 +# We use standard paths, so some packages need to copy these files with the
  11.364 +# receipt and genpkg_rules.
  11.365 +# This function executes inside the packaging process, before compressor call.
  11.366 +
  11.367 +copy_generic_files() {
  11.368 +	# $LOCALE is set in cook.conf
  11.369 +	if [ -n "$LOCALE" -a -z "$WANTED" ]; then
  11.370 +		if [ -d "$install/usr/share/locale" ]; then
  11.371 +			mkdir -p "$fs/usr/share/locale"
  11.372 +			for i in $LOCALE; do
  11.373 +				if [ -d  "$install/usr/share/locale/$i" ]; then
  11.374 +					cp -r $install/usr/share/locale/$i $fs/usr/share/locale
  11.375 +				fi
  11.376 +			done
  11.377 +		fi
  11.378 +	fi
  11.379 +
  11.380 +	# Generic pixmaps copy can be disabled with COOKOPTS="!pixmaps" (or GENERIC_PIXMAPS="no")
  11.381 +	if [ "${COOKOPTS/!pixmaps/}" == "$COOKOPTS" -a "$GENERIC_PIXMAPS" != 'no' ]; then
  11.382 +		if [ -d "$install/usr/share/pixmaps" ]; then
  11.383 +			mkdir -p "$fs/usr/share/pixmaps"
  11.384 +			for i in png xpm; do
  11.385 +				[ -f "$install/usr/share/pixmaps/$PACKAGE.$i" -a ! -f "$fs/usr/share/pixmaps/$PACKAGE.$i" ] &&
  11.386 +				cp -r $install/usr/share/pixmaps/$PACKAGE.$i $fs/usr/share/pixmaps
  11.387 +			done
  11.388 +		fi
  11.389 +	fi
  11.390 +
  11.391 +	# Desktop entry (.desktop).
  11.392 +	# Generic desktop entry copy can be disabled with COOKOPTS="!menus" (or GENERIC_MENUS="no")
  11.393 +	if [ "${COOKOPTS/!menus/}" == "$COOKOPTS" -a "$GENERIC_MENUS" != 'no' ]; then
  11.394 +		if [ -d "$install/usr/share/applications" -a -z "$WANTED" ]; then
  11.395 +			mkdir -p "$fs/usr/share"
  11.396 +			cp -r $install/usr/share/applications $fs/usr/share
  11.397 +		fi
  11.398 +	fi
  11.399 +}
  11.400 +
  11.401 +
  11.402 +# Determine package architecture
  11.403 +# Input: $1 = $fs; output string: i486 | x86_64 | any
  11.404 +
  11.405 +determine_pkg_arch() {
  11.406 +	action 'Determining package architecture...' >&2
  11.407 +
  11.408 +	if [ "${COOKOPTS/force-arch/}" != "$COOKOPTS" ]; then
  11.409 +		arch="$ARCH"
  11.410 +	else
  11.411 +		archs="$(
  11.412 +			IFS=$'\n'
  11.413 +			{
  11.414 +				# examine all the executables and static libs (*.a)
  11.415 +				busybox find "$1" -type f \( -perm +111 -o -name '*.a' \) \
  11.416 +				| while read i; do
  11.417 +					readelf -Wh "$i" 2>/dev/null \
  11.418 +					| sed '/Machine:/!d; s|.* ||'
  11.419 +				done
  11.420 +
  11.421 +				# examine compressed kernel modules (we use exclusively *.ko.xz)
  11.422 +				tmpko=$(mktemp)
  11.423 +				find "$1" -type f -name '*.ko.xz' \
  11.424 +				| while read i; do
  11.425 +					unxz -kc $i >$tmpko
  11.426 +					readelf -Wh "$tmpko" 2>/dev/null \
  11.427 +					| sed '/Machine:/!d; s|.* ||'
  11.428 +				done
  11.429 +				rm $tmpko
  11.430 +
  11.431 +				# examine Guile *.go files (Machine: None, so check Class)
  11.432 +				find "$1" -type f -name '*.go' \
  11.433 +				| while read i; do
  11.434 +					readelf -Wh "$i" 2>/dev/null \
  11.435 +					| sed '/Class:/!d; s|.* ||'
  11.436 +				done \
  11.437 +				| sed 's|ELF32|80386|; s|ELF64|X86-64|'
  11.438 +			} | sort -u
  11.439 +		)"
  11.440 +
  11.441 +		case $archs in
  11.442 +			80386)  arch='i486';   echo ' i486'   >&2;;
  11.443 +			X86-64) arch='x86_64'; echo ' x86_64' >&2;;
  11.444 +			'')     arch='any';    echo ' any'    >&2;;
  11.445 +			*)      arch="$ARCH";  echo ' ' $archs >&2
  11.446 +			        echo "Warning: weird architecture found, forced to use $ARCH for now." >&2
  11.447 +			        ;;
  11.448 +		esac
  11.449 +	fi
  11.450 +
  11.451 +	touch $pkgdir/.arch
  11.452 +	sed -i "/^$PACKAGE	/d" $pkgdir/.arch	# remove previous entry
  11.453 +	echo "$PACKAGE	$arch" >> $pkgdir/.arch	# put new one
  11.454 +
  11.455 +	echo $arch
  11.456 +}
  11.457 +
  11.458 +
  11.459 +# Find the variables inside receipt
  11.460 +
  11.461 +find_vars() {
  11.462 +	# You can define variables in the root of the receipt describing
  11.463 +	# the dependencies (tags, config files, etc.) for each sub-package.
  11.464 +	# Example:
  11.465 +	#   PACKAGE="cool"
  11.466 +	#   SPLIT="$PACKAGE-extra libcool $PACKAGE-dev"
  11.467 +	#
  11.468 +	#   DEPENDS_cool       or DEPENDS_std   # latter is the universal name for main package deps
  11.469 +	#   DEPENDS_cool_extra or DEPENDS_extra # you can skip "$PACKAGE" at the start
  11.470 +	#   DEPENDS_libcool                     # name not starts with "$PACKAGE" so no "short" name
  11.471 +	#   DEPENDS_cool_dev   or DEPENDS_dev
  11.472 +
  11.473 +	local out
  11.474 +	local var=$1
  11.475 +	local pkg=$(echo -n $2       | tr -c 'a-zA-Z0-9' '_')
  11.476 +	local end=$(echo -n ${2#$basepkg-} | tr -c 'a-zA-Z0-9' '_')
  11.477 +	if [ "$pkg" == "$basepkg" ]; then
  11.478 +		eval out="\$${var}_$pkg"
  11.479 +		[ -n "$out" ] || eval out="\$${var}_std"
  11.480 +	else
  11.481 +		eval out="\$${var}_$pkg"
  11.482 +		[ -n "$out" ] || eval out="\$${var}_$end"
  11.483 +	fi
  11.484 +	echo "$out"
  11.485 +}
  11.486 +
  11.487 +
  11.488 +# Create the package
  11.489 +
  11.490 +packit() {
  11.491 +	basepkg="$PACKAGE"
  11.492 +	thispkg="$1"
  11.493 +
  11.494 +	pkgdir="$WOK/$basepkg"
  11.495 +	receipt="$pkgdir/receipt"
  11.496 +	. $receipt
  11.497 +
  11.498 +	title 'Pack: %s' "$thispkg $VERSION"
  11.499 +
  11.500 +
  11.501 +	#
  11.502 +	# Set variables
  11.503 +	#
  11.504 +
  11.505 +	# Determine set name for specified package from $SPLIT variable
  11.506 +	local set=$(echo -n $SPLIT \
  11.507 +				| awk -vpkg="$thispkg" '
  11.508 +					BEGIN { RS = " "; FS = ":"; }
  11.509 +					{ if ($1 == pkg && $2 != "") { print "-" $2; exit; } }')
  11.510 +
  11.511 +	# Set paths
  11.512 +	export   stuff="$pkgdir/stuff"
  11.513 +	export     src="$pkgdir/source/$basepkg-$VERSION$set"
  11.514 +	export install="$pkgdir/install$set"
  11.515 +	export DESTDIR="$install"
  11.516 +	export     taz="$pkgdir/taz"
  11.517 +	export    pack="$taz/$thispkg-$VERSION$EXTRAVERSION"
  11.518 +	export      fs="$pack/fs"
  11.519 +
  11.520 +	export PACKAGE=$thispkg
  11.521 +
  11.522 +
  11.523 +	#
  11.524 +	# Execute genpkg_rules()
  11.525 +	#
  11.526 +
  11.527 +	if grep -q ^genpkg_rules $receipt; then
  11.528 +		_ 'Executing: %s' 'genpkg_rules'
  11.529 +		set -e; cd $pkgdir; mkdir -p $fs
  11.530 +		genpkg_rules || (newline; _ 'ERROR: genpkg_rules failed'; newline) >> \
  11.531 +			$LOGS/$pkg.log
  11.532 +	else
  11.533 +		cd $pkgdir
  11.534 +		mkdir -p $fs
  11.535 +		if [ "$CATEGORY" == 'meta' -a "$thispkg" == "$basepkg" ]; then
  11.536 +			_ 'No packages rules: meta package'
  11.537 +		else
  11.538 +			# Auto-packing
  11.539 +			for i in DEPENDS SUGGESTED PROVIDE CONFIG_FILES TAGS CAT COPY; do
  11.540 +				eval $i="\$(find_vars $i $thispkg)"
  11.541 +			done
  11.542 +
  11.543 +			[ -n "$COPY" ] ||
  11.544 +			case "$thispkg" in
  11.545 +				$basepkg)    COPY='@std @rm';;
  11.546 +				*-dev)       COPY='@dev @rm';;
  11.547 +				lib$basepkg) COPY='*.so*';;
  11.548 +			esac
  11.549 +			[ -n "$COPY" ] || die "ERROR: COPY_$thispkg rules undefined"
  11.550 +			copy $COPY
  11.551 +		fi
  11.552 +	fi
  11.553 +
  11.554 +
  11.555 +	#
  11.556 +	# Check CONFIG_FILES
  11.557 +	#
  11.558 +
  11.559 +	if [ -n "$CONFIG_FILES" ]; then
  11.560 +		unset IFS
  11.561 +		for i in $CONFIG_FILES; do
  11.562 +			if [ ! -e $fs$i ]; then
  11.563 +				case $i in
  11.564 +					*/) mkdir -p $fs$i ;;
  11.565 +					*)  mkdir -p $fs$(dirname $i); touch $fs$i ;;
  11.566 +				esac
  11.567 +			fi
  11.568 +		done
  11.569 +	fi
  11.570 +
  11.571 +	# First QA check to stop now if genpkg_rules failed.
  11.572 +	if fgrep -q '^ERROR' $LOGS/$basepkg.log; then
  11.573 +		broken; exit 1
  11.574 +	fi
  11.575 +
  11.576 +
  11.577 +	#
  11.578 +	# Copy receipt and description
  11.579 +	#
  11.580 +
  11.581 +	cd $taz
  11.582 +	action 'Copying "%s"...' 'receipt'
  11.583 +	mk_pkg_receipt "$(realpath ../receipt)" > $pack/receipt
  11.584 +	chown 0:0 $pack/receipt
  11.585 +	status
  11.586 +
  11.587 +	unset desc
  11.588 +	# description common to all the sub-packages
  11.589 +	[ -f "../description.txt" ] && desc="../description.txt"
  11.590 +	# description for specified sub-package
  11.591 +	[ -f "../description.$thispkg.txt" ] && desc="../description.$thispkg.txt"
  11.592 +	if [ -n "$desc" ]; then
  11.593 +		action 'Copying "%s"...' "$(basename "$desc")"
  11.594 +		cp -f $desc $pack/description.txt
  11.595 +		chown 0:0 $pack/description.txt
  11.596 +		status
  11.597 +	fi
  11.598 +
  11.599 +
  11.600 +	#
  11.601 +	# Copy generic files
  11.602 +	#
  11.603 +
  11.604 +	# Proceed only for "main" package (for v2), and for any packages (v1)
  11.605 +	[ "$thispkg" == "$mainpkg" ] && copy_generic_files
  11.606 +
  11.607 +
  11.608 +	#
  11.609 +	# Strip / compress files
  11.610 +	#
  11.611 +
  11.612 +	arch="$(determine_pkg_arch $fs)"
  11.613 +
  11.614 +	export COOKOPTS ARCH HOST_SYSTEM LOCALE fs; @@PREFIX@@/libexec/cookutils/compressor fs
  11.615 +
  11.616 +
  11.617 +	#
  11.618 +	# Make lists
  11.619 +	#
  11.620 +
  11.621 +	# Create files.list
  11.622 +	action 'Creating the list of files...'
  11.623 +	cd $fs
  11.624 +	find . \( -type f -o -type l \) | sed 's|^.||' > ../files.list
  11.625 +	cd ..
  11.626 +	status
  11.627 +
  11.628 +	# Md5sum of files.
  11.629 +	action 'Creating md5sum of files...'
  11.630 +	while read file; do
  11.631 +		[ -L "fs$file" ] && continue
  11.632 +		[ -f "fs$file" ] || continue
  11.633 +		case "$file" in
  11.634 +			/lib/modules/*/modules.*|*.pyc) continue ;;
  11.635 +		esac
  11.636 +		md5sum "fs$file" | sed 's|  fs|  |'
  11.637 +	done < files.list | sort -k2 > md5sum
  11.638 +	status
  11.639 +
  11.640 +
  11.641 +	#
  11.642 +	# Calculate release checksum
  11.643 +	#
  11.644 +
  11.645 +	# Usually it does not change on "just recook".
  11.646 +	# Md5sum of the *.tazpkg will change every time because of embedded timestamps;
  11.647 +	# on the other hand release checksum don't relies on the timestamps, but
  11.648 +	# only on files content and their permissions.
  11.649 +
  11.650 +	# Calculate rsum for new package
  11.651 +	RSUM=$(
  11.652 +	{
  11.653 +		# a) md5sums of all files
  11.654 +		cat $pack/md5sum
  11.655 +		# b) md5sum of receipt
  11.656 +		md5sum $pack/receipt | sed 's| [^ ]*/| |'
  11.657 +		# c) md5sum of description.txt
  11.658 +		[ -e "$pack/description.txt" ] &&
  11.659 +			md5sum $pack/description.txt | sed 's| [^ ]*/| |'
  11.660 +		# d) md5sum of list of permissions and ownership of all the files and
  11.661 +		#    folders of the package
  11.662 +		#    stat line example: -rwsr-xr-x 0:0 ./bin/busybox
  11.663 +		{
  11.664 +			cd $fs
  11.665 +			find . -print0 | sort -z | xargs -0rn 1 stat -c '%A %g:%u %N' | md5sum
  11.666 +		}
  11.667 +	} | md5sum $rsum_file | awk '{print $1}')
  11.668 +
  11.669 +
  11.670 +	#
  11.671 +	# Compressing
  11.672 +	#
  11.673 +
  11.674 +	UNPACKED_SIZE=$(du -cks fs receipt files.list md5sum description.txt \
  11.675 +		2>/dev/null | awk 'END{ print $1 "K"}')
  11.676 +
  11.677 +	# Build fs cpio archive
  11.678 +	action 'Compressing the FS...'
  11.679 +	find fs -newer $receipt -exec touch -hr $receipt '{}' \;
  11.680 +#	find fs | cpio -o -H newc --quiet | lzma-alone e fs.cpio.lzma -si
  11.681 +	find fs | cpio -o -H newc --quiet | /bin/lzma -qzeT0 >fs.cpio.lzma
  11.682 +	mv fs ../
  11.683 +	status
  11.684 +
  11.685 +	PACKED_SIZE=$(du -cks fs.cpio.lzma receipt files.list md5sum description.txt \
  11.686 +		2>/dev/null | awk 'END{ print $1 "K"}')
  11.687 +
  11.688 +
  11.689 +	#
  11.690 +	# Add variables to the receipt
  11.691 +	#
  11.692 +
  11.693 +	# Store sizes
  11.694 +	sed -i '/^PACKED_SIZE=/d; /^UNPACKED_SIZE=/d' receipt
  11.695 +	sed -i "s|^PACKAGE=|PACKED_SIZE=\"$PACKED_SIZE\"\nUNPACKED_SIZE=\"$UNPACKED_SIZE\"\nPACKAGE=|" receipt
  11.696 +
  11.697 +	# Store RSUM
  11.698 +	sed -i "s|^PACKAGE=|RSUM=\"$RSUM\"\nPACKAGE=|" receipt
  11.699 +
  11.700 +	# Set extra version
  11.701 +	if [ -n "$EXTRAVERSION" ]; then
  11.702 +		sed -i '/^EXTRAVERSION=/d' receipt
  11.703 +		sed -i "s|^VERSION=|EXTRAVERSION=\"$EXTRAVERSION\"\nVERSION=|" receipt
  11.704 +	fi
  11.705 +
  11.706 +
  11.707 +	#
  11.708 +	# Build *.tazpkg
  11.709 +	#
  11.710 +
  11.711 +	action 'Creating full cpio archive...'
  11.712 +	find . -newer $receipt -exec touch -hr $receipt '{}' \;
  11.713 +	find . | cpio -o -H newc --quiet > ../$PACKAGE-$VERSION$EXTRAVERSION-$arch.tazpkg
  11.714 +	status
  11.715 +
  11.716 +	# Restoring original package tree.
  11.717 +	mv ../fs .
  11.718 +
  11.719 +	rm fs.cpio.lzma; cd ..
  11.720 +
  11.721 +	tazpkg=$(ls *.tazpkg)
  11.722 +
  11.723 +
  11.724 +	#
  11.725 +	# Verify package quality and consistency
  11.726 +	#
  11.727 +
  11.728 +	# Preferrable way is to combine the commands chain in the compile_rules()
  11.729 +	# using '&&': when any of the chunk broke, process will stop and function
  11.730 +	# will return non-zero return code.
  11.731 +	# On the other hand some old receipts don't use '&&' but depends on the
  11.732 +	# error messages on the log.
  11.733 +	# Sometimes it produce false positives on the configuration stage.
  11.734 +	# In this case we can use the "skip-log-errors".
  11.735 +	if [ "${COOKOPTS/skip-log-errors/}" == "$COOKOPTS" ]; then
  11.736 +		# Exit if any error found in log file.
  11.737 +		if fgrep -q ^ERROR $LOGS/$basepkg.log; then
  11.738 +			rm -f $command
  11.739 +			broken; exit 1
  11.740 +		fi
  11.741 +	fi
  11.742 +
  11.743 +
  11.744 +	# Allow meta-packages in v2 receipts
  11.745 +	[ -n "$CAT" ] && CATEGORY="${CAT%|*}"
  11.746 +
  11.747 +	if [ "${COOKOPTS/empty-pkg/}" == "$COOKOPTS" ]; then
  11.748 +		action 'QA: checking for empty package...'
  11.749 +		if [ ! -s "$pack/files.list" -a "$CATEGORY" != 'meta' ]; then
  11.750 +			broken
  11.751 +			rm -f $command
  11.752 +			false; status
  11.753 +			die 'ERROR: empty package'
  11.754 +		fi
  11.755 +		:; status
  11.756 +	fi
  11.757 +
  11.758 +
  11.759 +	#
  11.760 +	# Get RSUM from the old package
  11.761 +	#
  11.762 +
  11.763 +	pkg_file="$PKGS/$PACKAGE-$VERSION$EXTRAVERSION-$arch.tazpkg"
  11.764 +	if [ -f "$pkg_file" ]; then
  11.765 +		# don't trust database entry, check the package file
  11.766 +		tmpdir=$(mktemp -d)
  11.767 +		cd $tmpdir
  11.768 +		cpio -F "$pkg_file" -i receipt >/dev/null 2>&1
  11.769 +		RSUM_OLD=$(. receipt; echo $RSUM)
  11.770 +		cd - >/dev/null
  11.771 +		rm -r $tmpdir
  11.772 +	else
  11.773 +		unset RSUM_OLD
  11.774 +	fi
  11.775 +
  11.776 +
  11.777 +	#
  11.778 +	# Removing unhandled old packages
  11.779 +	#
  11.780 +
  11.781 +	if [ $ARCH == 'i486' -a -e $PKGS/$PACKAGE-$VERSION$EXTRAVERSION.tazpkg ]; then
  11.782 +		action 'Removing old i486 package without arch specifier'
  11.783 +		rm -f $PKGS/$PACKAGE-$VERSION$EXTRAVERSION.tazpkg
  11.784 +		status
  11.785 +	fi
  11.786 +
  11.787 +	# For example, if *-dev package contains *.a static libs, it will be either
  11.788 +	# i486 or x86_64 arch; otherwise it will be "any" arch. This transition
  11.789 +	# may be done forth and back depending on you disable static libs or not.
  11.790 +	case $arch in
  11.791 +		any)
  11.792 +			if [ -e $PKGS/$PACKAGE-$VERSION$EXTRAVERSION-$ARCH.tazpkg ]; then
  11.793 +				action "Removing old $ARCH package because it arch-less now"
  11.794 +				rm -f $PKGS/$PACKAGE-$VERSION$EXTRAVERSION-$ARCH.tazpkg
  11.795 +				status
  11.796 +			fi
  11.797 +			;;
  11.798 +		*)
  11.799 +			if [ -e $PKGS/$PACKAGE-$VERSION$EXTRAVERSION-any.tazpkg ]; then
  11.800 +				action "Removing old arch-less package because it $ARCH now"
  11.801 +				rm -f $PKGS/$PACKAGE-$VERSION$EXTRAVERSION-any.tazpkg
  11.802 +				status
  11.803 +			fi
  11.804 +			;;
  11.805 +	esac
  11.806 +
  11.807 +	# Find and remove old package only if "release checksum" has changed
  11.808 +
  11.809 +	pi="$PKGS/packages-$ARCH.info"
  11.810 +	touch $pi
  11.811 +
  11.812 +	if [ "$RSUM" != "$RSUM_OLD" ]; then
  11.813 +		old_file=$(awk -F$'\t' -vname="$PACKAGE" -varch="$arch" '{
  11.814 +			if ($1 == name) printf("%s-%s-%s.tazpkg", $1, $2, arch);
  11.815 +			}' $pi)		# <name>-<version><extra_version>-<arch>.tazpkg
  11.816 +		if [ -f "$PKGS/$old_file" ]; then
  11.817 +			action 'Removing old package "%s"' "$old_file"
  11.818 +			rm -f "$PKGS/$old_file"
  11.819 +			status
  11.820 +		fi
  11.821 +		# package changed, substitute old package by new one
  11.822 +		mv -f $pkgdir/taz/$PACKAGE-$VERSION$EXTRAVERSION-$arch.tazpkg $PKGS
  11.823 +		_ 'The release checksum has changed.'
  11.824 +	else
  11.825 +		# package not changed, remove new package
  11.826 +		rm -f $pkgdir/taz/$PACKAGE-$VERSION$EXTRAVERSION-$arch.tazpkg
  11.827 +		_ 'The release checksum has not changed.'
  11.828 +	fi
  11.829 +
  11.830 +
  11.831 +	#
  11.832 +	# Package isn't broken anymore
  11.833 +	#
  11.834 +
  11.835 +	touch $broken
  11.836 +	sed -i "/^${thispkg}$/d" $broken
  11.837 +
  11.838 +
  11.839 +	#
  11.840 +	# Update packages database every time after successful build
  11.841 +	#
  11.842 +
  11.843 +	# packages-arch.info (unsorted, located near to packages)
  11.844 +	unset_receipt; . $pack/receipt
  11.845 +	SIZES=$(echo $PACKED_SIZE $UNPACKED_SIZE | sed 's|\.0||g')
  11.846 +	DEPENDS=$(echo $DEPENDS) # remove newlines, tabs and multiple spaces from variable
  11.847 +	case $arch in
  11.848 +		i?86)   arch_code='3';; # 3 for 32-bit
  11.849 +		x86_64) arch_code='6';; # 6 for 64-bit
  11.850 +		any)    arch_code='0';; # 0 for any arch
  11.851 +	esac
  11.852 +
  11.853 +	sed -i "/^$PACKAGE\t/d" $pi		# remove old entry
  11.854 +	cat >> $pi <<EOT
  11.855 +$PACKAGE	$VERSION$EXTRAVERSION	$CATEGORY	$SHORT_DESC	$WEB_SITE	$TAGS	$SIZES	$DEPENDS	$rsum	$PROVIDE	$arch_code
  11.856 +EOT
  11.857 +
  11.858 +	# files.list (uncompressed, unsorted, located in $cache)
  11.859 +	fl="$cache/files.list"
  11.860 +	touch $fl
  11.861 +	sed -i "/^$PACKAGE: /d" $fl
  11.862 +	sed  "s/^/$PACKAGE: \0/" $pack/files.list >> $fl
  11.863 +
  11.864 +	footer "$(_ 'Package "%s" created' "$tazpkg")"
  11.865 +}
  11.866 +
  11.867 +
  11.868 +packit "$1"
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/modules/postcheck	Sat Nov 24 13:28:02 2018 +0200
    12.3 @@ -0,0 +1,263 @@
    12.4 +#!/bin/sh
    12.5 +#
    12.6 +# postcheck - module of the SliTaz Cook
    12.7 +# Copyright (C) SliTaz GNU/Linux - GNU GPL v3
    12.8 +#
    12.9 +# Check for different cases at the end and add badges
   12.10 +
   12.11 +. /usr/lib/slitaz/libcook.sh
   12.12 +. /etc/slitaz/cook.conf
   12.13 +. $WOK/$1/receipt
   12.14 +
   12.15 +data="$(mktemp -d)" # temporary data for post-checking
   12.16 +
   12.17 +repologydb="$CACHE/repology.db"
   12.18 +
   12.19 +badges="$WOK/$1/.badges"
   12.20 +echo -n > $badges # clean badges
   12.21 +
   12.22 +overrides="$WOK/$1/stuff/overrides"
   12.23 +overrides_exp="$data/overrides_exp"
   12.24 +fail="$data/fail" # file used as flag, if will be empty if no fails were found
   12.25 +
   12.26 +sets=$(echo -n $SPLIT | awk 'BEGIN { RS = " "; FS = ":"; }
   12.27 +	{ if ($2 && ! set[$2]) { printf("%s ", $2); set[$2] = "1"; } }')
   12.28 +
   12.29 +# Format of stuff/overrides:
   12.30 +# <rule> {<rule> ...} <fil[e]*>
   12.31 +# One or more rules may indicate:
   12.32 +#   - ownership in form '80:80' (numeric UID:GID) or 'www:www' (string UID:GID)
   12.33 +#   - permissions in form '0600' (four octal digits)
   12.34 +# File is space free string specified one (or more - using placeholders) files
   12.35 +
   12.36 +
   12.37 +# Expand overrides to the simple form: <rule><tab><file>
   12.38 +
   12.39 +if [ -e "$overrides" ]; then
   12.40 +	IFS=$'\n'
   12.41 +	while read line; do
   12.42 +		rules=${line% *}; file=${line##* }
   12.43 +
   12.44 +		for set in '' $sets; do
   12.45 +			install="$WOK/$1/install"
   12.46 +			[ -z "$set" ] || install="$install-$set"
   12.47 +			[ -d "$install" ] || continue
   12.48 +			for file in $(ls -d $install$file); do
   12.49 +				for rule in $rules; do
   12.50 +					echo "$rule	${file#$install}" >> $overrides_exp
   12.51 +				done
   12.52 +			done
   12.53 +		done
   12.54 +	done < $overrides
   12.55 +	unset IFS
   12.56 +fi
   12.57 +
   12.58 +
   12.59 +# Get latest packaged version from Repology
   12.60 +
   12.61 +repology_get() {
   12.62 +	local found versions day=$(date +%j)		# %j is the number of the day in the year
   12.63 +	found=$(awk -F$'\t' -vpkg="$1" -vday="$day" '{
   12.64 +		if ($1 == pkg && $2 == day) { print $3; exit; }
   12.65 +	}' $repologydb)
   12.66 +	if [ -n "$found" ]; then
   12.67 +		echo "$found"
   12.68 +	else
   12.69 +		# set HOST_WGET in cook.conf
   12.70 +		versions=$($HOST_WGET -q -T 20 -O- https://repology.org/badge/latest-versions/$1.svg \
   12.71 +		| sed '/<text /!d; /fill/d; /latest/d; s|.*>\(.*\)<.*|\1|; s|, | |g') # space separated list
   12.72 +		if [ -n "$versions" ]; then
   12.73 +			sed -i "/^$1	/d" $repologydb
   12.74 +			echo -e "$1\t$day\t$versions" >> $repologydb
   12.75 +			echo $versions
   12.76 +		fi
   12.77 +	fi
   12.78 +}
   12.79 +
   12.80 +
   12.81 +# Add the specified badge, set the fail flag and return false status
   12.82 +
   12.83 +function add() {
   12.84 +	! grep -q "^${1}$" $badges && echo "$1" >> $badges
   12.85 +	case $1 in
   12.86 +		ss|old|win|patch) return 0;;
   12.87 +		*) echo 'yes' > $fail; false;;
   12.88 +	esac
   12.89 +}
   12.90 +
   12.91 +
   12.92 +function docheck() {
   12.93 +	action 'Checking build...'
   12.94 +	if grep -q "^$PACKAGE$" $broken; then
   12.95 +		if grep -q '^ERROR: unknown dep' $LOGS/$1.log; then
   12.96 +			add 'bdbroken'
   12.97 +		else
   12.98 +			add 'broken'
   12.99 +		fi
  12.100 +		status; return # no more tests since package is broken
  12.101 +	fi
  12.102 +	status
  12.103 +
  12.104 +
  12.105 +	if [ -e $WOK/$1/.arch ]; then
  12.106 +		action "Checking 'any' arch..."
  12.107 +		if [ "$(cut -d$'\t' -f2 $WOK/$1/.arch | sort -u)" == 'any' ]; then
  12.108 +			if [ "$HOST_ARCH" != 'any' ]; then
  12.109 +				add 'any'
  12.110 +			fi
  12.111 +		else
  12.112 +			if [ "$HOST_ARCH" == 'any' ]; then
  12.113 +				add 'noany'
  12.114 +			fi
  12.115 +		fi
  12.116 +		status
  12.117 +	fi
  12.118 +
  12.119 +
  12.120 +	if [ -e $WOK/$1/.patch.done ]; then
  12.121 +		# consider 'fix libtool' as no patch here
  12.122 +		if [ -n "$(grep -v 'fix.libtool' $WOK/$1/.patch.done)" ]; then
  12.123 +			add 'patch'
  12.124 +		fi
  12.125 +	fi
  12.126 +
  12.127 +
  12.128 +	for set in '' $sets; do
  12.129 +		src=$WOK/$1/source/$PACKAGE-$VERSION
  12.130 +		[ -z "$set" ] || src="$src-$set"
  12.131 +		[ -d "$src" ] || continue
  12.132 +
  12.133 +		action "Checking libtool in ${src#$WOK/$1/}..."
  12.134 +		if [ -e "$src/libtool" ]; then
  12.135 +			if ! grep -q '^fix.libtool$' $WOK/$1/.patch.done 2>/dev/null; then
  12.136 +				add 'libtool'
  12.137 +			fi
  12.138 +		else
  12.139 +			if grep -q '^fix.libtool$' $WOK/$1/.patch.done 2>/dev/null; then
  12.140 +				add 'nolibtool'
  12.141 +			fi
  12.142 +		fi
  12.143 +		status
  12.144 +
  12.145 +		action "Checking site script in ${src#$WOK/$1/}..."
  12.146 +		if fgrep -q 'configure: loading site script /etc/slitaz/cook.site' $LOGS/$PACKAGE.log; then
  12.147 +			for i in bindir datadir datarootdir docdir dvidir htmldir includedir infodir libdir \
  12.148 +			libexecdir localedir localstatedir mandir oldincludedir pdfdir psdir sbindir \
  12.149 +			sharedstatedir sysconfdir; do
  12.150 +				if fgrep -q -e "--$i=" $WOK/$1/receipt; then
  12.151 +					add 'ss'
  12.152 +					break
  12.153 +				fi
  12.154 +			done
  12.155 +		fi
  12.156 +		status
  12.157 +	done
  12.158 +
  12.159 +
  12.160 +	for set in '' $sets; do
  12.161 +		install="$WOK/$1/install"
  12.162 +		[ -z "$set" ] || install="$install-$set"
  12.163 +		[ -d "$install" ] || continue
  12.164 +
  12.165 +		action "Checking ownership in ${install#$WOK/$1/}..."
  12.166 +
  12.167 +		IFS=$'\n'
  12.168 +		bad_own="$(find $install -type f \( ! -user 0 -a ! -group 0 \))"
  12.169 +		if [ -n "$bad_own" ]; then
  12.170 +			if [ -e $overrides_exp ]; then
  12.171 +				# There may be mix of overridden and not-overridden ownership
  12.172 +				# in the package. Return status 'Done' only if all the ownership
  12.173 +				# was overridden.
  12.174 +				result=''
  12.175 +				for i in $bad_own; do
  12.176 +					if  fgrep -q "$(stat -c %u:%g "$i")	${i#$install}" $overrides_exp ||
  12.177 +						fgrep -q "$(stat -c %U:%G "$i")	${i#$install}" $overrides_exp; then
  12.178 +						add 'ownover'
  12.179 +					else
  12.180 +						add 'own'
  12.181 +						result='bad'
  12.182 +					fi
  12.183 +				done
  12.184 +				[ "$result" == '' ] # OK, all was overridden
  12.185 +			else
  12.186 +				add 'own'
  12.187 +			fi
  12.188 +		fi
  12.189 +		status
  12.190 +		unset IFS
  12.191 +
  12.192 +
  12.193 +		action "Checking permissions in ${install#$WOK/$1/}..."
  12.194 +
  12.195 +		bad_files="$(find $install -type f \( ! -perm 644 -a ! -perm 755 \))"
  12.196 +		bad_dirs="$(find $install -type d ! -perm 755)"
  12.197 +		list=''
  12.198 +		if [ -n "$bad_files$bad_dirs" ]; then
  12.199 +			if [ -e $overrides_exp ]; then
  12.200 +				# There may be mix of overridden and not-overridden permissions
  12.201 +				# in the package. Return status 'Done' only if all the permissions
  12.202 +				# was overridden.
  12.203 +				result=''
  12.204 +				for i in $bad_files; do
  12.205 +					if  fgrep -q "$(printf "%04d\t%s" "$(stat -c%a "$i")" "${i#$install}")" $overrides_exp; then
  12.206 +						add 'permover'
  12.207 +					else
  12.208 +						add 'perm'
  12.209 +						list="$list$(printf "\n  %04d %s" "$(stat -c %a "$i")" "${i#$install}")"
  12.210 +						result='bad'
  12.211 +					fi
  12.212 +				done
  12.213 +				for i in $bad_dirs; do
  12.214 +					if  fgrep -q "$(printf "%04d" $(stat -c %a "$i"))	${i#$install}/" $overrides_exp; then
  12.215 +						add 'permover'
  12.216 +					else
  12.217 +						add 'perm'
  12.218 +						list="$list$(printf "\n  %04d %s" "$(stat -c %a "$i")" "${i#$install}/")"
  12.219 +						result='bad'
  12.220 +					fi
  12.221 +				done
  12.222 +				[ "$result" == '' ] # OK, all was overridden
  12.223 +			else
  12.224 +				add 'perm'
  12.225 +			fi
  12.226 +		fi
  12.227 +		status
  12.228 +		[ -n "$list" ] && echo -e "  Problems found:$list"
  12.229 +
  12.230 +		action "Checking broken symlinks in ${install#$WOK/$1/}..."
  12.231 +		bad_sl=$(find $install -type l ! -exec test -e '{}' \; -print)
  12.232 +		if [ -n "$bad_sl" ]; then
  12.233 +			add 'symlink'
  12.234 +		fi
  12.235 +		status
  12.236 +	done
  12.237 +
  12.238 +	if [ "$REPOLOGY" != '-' ]; then
  12.239 +		action 'Querying Repology...'
  12.240 +		repo_ver=$(repology_get ${REPOLOGY:-$PACKAGE})
  12.241 +		if [ "$repo_ver" != '-' -a ! -s $fail ]; then
  12.242 +			if echo " $repo_ver " | fgrep -q " $VERSION "; then
  12.243 +				add 'win'
  12.244 +			else
  12.245 +				add 'old'
  12.246 +			fi
  12.247 +		fi
  12.248 +		status
  12.249 +	fi
  12.250 +}
  12.251 +
  12.252 +
  12.253 +title 'Post-check'
  12.254 +docheck $1
  12.255 +
  12.256 +
  12.257 +# Put badges into activity log: <a href='...' data-badges='...'>...</a>
  12.258 +
  12.259 +action 'Updating activity log...'
  12.260 +badges_log=$(tr '\n' ' ' <$badges | sed 's| $||')
  12.261 +sed -i "s|>$1</a>$| data-badges='$badges_log'&|" $activity
  12.262 +status
  12.263 +
  12.264 +footer
  12.265 +
  12.266 +rm -r $data # clean