tazpkg diff tazpkg @ rev 803

tazpkg: fast recharge (also coming soon for Undigest repo, fails now); update pot and complete Russian translations.
author Aleksej Bobylev <al.bobylev@gmail.com>
date Sun May 10 13:33:16 2015 +0300 (2015-05-10)
parents 3dbd29398250
children e5c261e450c7
line diff
     1.1 --- a/tazpkg	Thu May 07 11:42:03 2015 +0200
     1.2 +++ b/tazpkg	Sun May 10 13:33:16 2015 +0300
     1.3 @@ -248,8 +248,7 @@
     1.4  
     1.5  # Check if dir exists
     1.6  
     1.7 -check_dir()
     1.8 -{
     1.9 +check_dir() {
    1.10  	if ! [ -d "$1" ]; then
    1.11  		action 'Creating folder "%s"...' "$1"
    1.12  		mkdir -p "$1"
    1.13 @@ -259,11 +258,10 @@
    1.14  }
    1.15  
    1.16  
    1.17 -# Check if the directories and files used by TazPKG
    1.18 -# exist. If not and user is root we create them.
    1.19 -
    1.20 -check_base_dir()
    1.21 -{
    1.22 +# Check if the directories and files used by TazPkg exist.
    1.23 +# If not and user is root we create them.
    1.24 +
    1.25 +check_base_dir() {
    1.26  	if [ "$(id -u)" = "0" ]; then
    1.27  		check_dir $1$CACHE_DIR
    1.28  		check_dir $1$INSTALLED
    1.29 @@ -279,8 +277,7 @@
    1.30  
    1.31  # Check for a package name on cmdline.
    1.32  
    1.33 -check_for_package_on_cmdline()
    1.34 -{
    1.35 +check_for_package_on_cmdline() {
    1.36  	if [ -z "$PACKAGE" ]; then
    1.37  		newline
    1.38  		_ 'Please specify a package name on the command line.'
    1.39 @@ -292,8 +289,7 @@
    1.40  
    1.41  # Check if the package (*.tazpkg) exists before installing or extracting.
    1.42  
    1.43 -check_for_package_file()
    1.44 -{
    1.45 +check_for_package_file() {
    1.46  	if [ ! -f "$PACKAGE_FILE" ]; then
    1.47  		newline
    1.48  		_ 'Unable to find file "%s"' $PACKAGE_FILE
    1.49 @@ -305,8 +301,7 @@
    1.50  
    1.51  # Check for the receipt of an installed package.
    1.52  
    1.53 -check_for_receipt()
    1.54 -{
    1.55 +check_for_receipt() {
    1.56  	if [ ! -f "$1$INSTALLED/$PACKAGE/receipt" ]; then
    1.57  		newline
    1.58  		_ 'Unable to find the receipt "%s"' "$1$INSTALLED/$PACKAGE/receipt"
    1.59 @@ -320,8 +315,7 @@
    1.60  # In this files, undigest are called by their name and main mirror
    1.61  # by main. Sort order: priority
    1.62  
    1.63 -look_for_priority()
    1.64 -{
    1.65 +look_for_priority() {
    1.66  	[ -s $PKGS_DB/priority ] && priority=$(cat $PKGS_DB/priority)
    1.67  	for rep in main $(ls $PKGS_DB/undigest 2>/dev/null); do
    1.68  		if [ ! -s $PKGS_DB/priority ] || \
    1.69 @@ -342,8 +336,7 @@
    1.70  
    1.71  # Get package name in a directory
    1.72  
    1.73 -package_fullname_in_dir()
    1.74 -{
    1.75 +package_fullname_in_dir() {
    1.76  	[ -f $1/receipt ] || return
    1.77  	EXTRAVERSION=""
    1.78  	. $1/receipt
    1.79 @@ -353,8 +346,7 @@
    1.80  
    1.81  # Get package name that is already installed.
    1.82  
    1.83 -get_installed_package_pathname()
    1.84 -{
    1.85 +get_installed_package_pathname() {
    1.86  	for i in $2$INSTALLED/${1%%-*}*; do
    1.87  		[ -d $i ] || continue
    1.88  		if [ "$1" = "$(package_fullname_in_dir $i)" ]; then
    1.89 @@ -367,8 +359,7 @@
    1.90  
    1.91  # Check if a package is already installed.
    1.92  
    1.93 -check_for_installed_package()
    1.94 -{
    1.95 +check_for_installed_package() {
    1.96  	if [ -n "$(get_installed_package_pathname $PACKAGE $1)" ]; then
    1.97  		newline
    1.98  		_ '"%s" package is already installed.' $(colorize 34 $PACKAGE)
    1.99 @@ -381,8 +372,7 @@
   1.100  
   1.101  # Check for packages.list to download and install packages.
   1.102  
   1.103 -check_for_packages_list()
   1.104 -{
   1.105 +check_for_packages_list() {
   1.106  	list_path="$PKGS_DB/packages.list"
   1.107  	if [ ! -f "$list_path" ]; then
   1.108  		if test $(id -u) = 0 ; then
   1.109 @@ -403,8 +393,7 @@
   1.110  # Check for installed.info - local file with format of packages.info
   1.111  # "installed.info" is absent on not clean installs; check it and re-generate if needed.
   1.112  
   1.113 -check_for_installed_info()
   1.114 -{
   1.115 +check_for_installed_info() {
   1.116  	info_path="$ROOT$PKGS_DB/installed.info"
   1.117  	if [ ! -f "$info_path" ]; then
   1.118  		if [ "$(id -u)" == "0" ]; then
   1.119 @@ -427,8 +416,7 @@
   1.120  }
   1.121  
   1.122  
   1.123 -get_cache_dir()
   1.124 -{
   1.125 +get_cache_dir() {
   1.126  	echo $rep > $tmp/rep
   1.127  	if [ "$rep" = "$PKGS_DB" ]; then
   1.128  		CACHE_DIR="$SAVE_CACHE_DIR/$SLITAZ_RELEASE/packages"
   1.129 @@ -445,8 +433,7 @@
   1.130  
   1.131  # get an already installed package from packages.equiv
   1.132  
   1.133 -equivalent_pkg()
   1.134 -{
   1.135 +equivalent_pkg() {
   1.136  	for i in $(grep -hs "^$1=" $PKGS_DB/packages.equiv \
   1.137  		   $PKGS_DB/undigest/*/packages.equiv | sed "s/^$1=//"); do
   1.138  		if echo $i | fgrep -q : ; then
   1.139 @@ -473,8 +460,7 @@
   1.140  
   1.141  # get a virtual package from packages.equiv
   1.142  
   1.143 -virtual_pkg()
   1.144 -{
   1.145 +virtual_pkg() {
   1.146  	for i in $(for rep in $priority; do
   1.147  		grep -hs "^$1=" $rep/packages.equiv
   1.148  		done | sed "s/^$1=//"); do
   1.149 @@ -497,8 +483,7 @@
   1.150  
   1.151  # Get package filename available on the mirror
   1.152  
   1.153 -get_package_filename()
   1.154 -{
   1.155 +get_package_filename() {
   1.156  	local pkg
   1.157  	for rep in $priority; do
   1.158  		pkg=$(grep -A 1 -sh "^$1$" $rep/packages.txt | tail -1 | sed 's/^ *//')
   1.159 @@ -528,8 +513,7 @@
   1.160  # Check for a package in packages.list. Used by get and get-install to grep
   1.161  # package basename.
   1.162  
   1.163 -check_for_package_in_list()
   1.164 -{
   1.165 +check_for_package_in_list() {
   1.166  	local filename
   1.167  	local check_only
   1.168  	check_only="$1"
   1.169 @@ -552,8 +536,7 @@
   1.170  # Log this activity
   1.171  # (there log_pkg because we have log() in libtaz.sh)
   1.172  
   1.173 -log_pkg()
   1.174 -{
   1.175 +log_pkg() {
   1.176  	local extra
   1.177  
   1.178  	[ "$1" = "Installed" ] && \
   1.179 @@ -568,8 +551,7 @@
   1.180  
   1.181  # Download a get-package script from this mirror
   1.182  
   1.183 -download_get_script()
   1.184 -{
   1.185 +download_get_script() {
   1.186  	local p
   1.187  	for p in $priority ; do
   1.188  		local i
   1.189 @@ -586,21 +568,15 @@
   1.190  
   1.191  # Download a file from this mirror
   1.192  
   1.193 -download_from()
   1.194 -{
   1.195 -	local i
   1.196 -	local mirrors
   1.197 -	mirrors="$1"
   1.198 -	shift
   1.199 +download_from() {
   1.200 +	local i mirrors="$1"; shift
   1.201  	for i in $mirrors; do
   1.202  		case "$i" in
   1.203  			# Mirror URL can have a trailing slash or not.
   1.204 -			http://*|ftp://*)
   1.205 -				busybox wget -c ${i%/}/$@ && break ;;
   1.206 -			https://*)
   1.207 -				echo 'Sorry, https not supported' ;;
   1.208 +			http://*|https://*|ftp://*)
   1.209 +				busybox wget -c -q -T 30 -U TazPkg ${i%/}/$@ 2>/dev/null && break ;;
   1.210  			*)
   1.211 -				ln -sf $i/$1 . && break ;;
   1.212 +				ln -sf ${i%/}/$1 . && break ;;
   1.213  		esac
   1.214  	done
   1.215  }
   1.216 @@ -608,8 +584,7 @@
   1.217  
   1.218  # Download a file trying all mirrors
   1.219  
   1.220 -download()
   1.221 -{
   1.222 +download() {
   1.223  	local i
   1.224  	case "$1" in
   1.225  	*.tazpkg)
   1.226 @@ -626,8 +601,7 @@
   1.227  
   1.228  # Extract a package with cpio and gzip/lzma.
   1.229  
   1.230 -extract_package()
   1.231 -{
   1.232 +extract_package() {
   1.233  	action 'Extracting package...'
   1.234  	cpio -idm --quiet < ${PACKAGE_FILE##*/} && rm -f ${PACKAGE_FILE##*/}
   1.235  	status
   1.236 @@ -639,8 +613,7 @@
   1.237  }
   1.238  
   1.239  
   1.240 -remove_with_path()
   1.241 -{
   1.242 +remove_with_path() {
   1.243  	# Avoid dirname errors by checking for argument.
   1.244  	[ "$1" ] || return
   1.245  
   1.246 @@ -654,8 +627,7 @@
   1.247  }
   1.248  
   1.249  
   1.250 -grepesc()
   1.251 -{
   1.252 +grepesc() {
   1.253  	sed 's/\[/\\[/g'
   1.254  }
   1.255  
   1.256 @@ -676,8 +648,7 @@
   1.257  
   1.258  # This function installs a package in the rootfs.
   1.259  
   1.260 -install_package()
   1.261 -{
   1.262 +install_package() {
   1.263  	ROOT=$1
   1.264  	if [ -n "$ROOT" ]; then
   1.265  		# Get absolute path
   1.266 @@ -918,8 +889,7 @@
   1.267  
   1.268  # This function may be called by a get script.
   1.269  
   1.270 -abort_package()
   1.271 -{
   1.272 +abort_package() {
   1.273  	cd $CUR_DIR
   1.274  	rm -rf $TMP_DIR
   1.275  	echo "${1:-Abort $PACKAGE.}"
   1.276 @@ -929,8 +899,7 @@
   1.277  
   1.278  # This function installs a package from a get script in the rootfs.
   1.279  
   1.280 -install_package_from_get_script()
   1.281 -{
   1.282 +install_package_from_get_script() {
   1.283  	SCRIPT="$1"
   1.284  	ROOT="$2"
   1.285  	[ -d $ROOT$INSTALLED/$PACKAGE ] && exit 1
   1.286 @@ -998,8 +967,7 @@
   1.287  
   1.288  # Check for loop in deps tree.
   1.289  
   1.290 -check_for_deps_loop()
   1.291 -{
   1.292 +check_for_deps_loop() {
   1.293  	local list
   1.294  	local pkg
   1.295  	local deps
   1.296 @@ -1029,8 +997,7 @@
   1.297  
   1.298  # Check for missing deps listed in a receipt packages.
   1.299  
   1.300 -check_for_deps()
   1.301 -{
   1.302 +check_for_deps() {
   1.303  	local saved;
   1.304  	saved=$PACKAGE
   1.305  	mkdir -p $TMP_DIR
   1.306 @@ -1071,8 +1038,7 @@
   1.307  # deps from local dir, cdrom, media or from the mirror. In case we want to
   1.308  # install packages from local, we need a packages.list to find the version.
   1.309  
   1.310 -install_deps()
   1.311 -{
   1.312 +install_deps() {
   1.313  	local root
   1.314  	root=""
   1.315  	[ -n "$1" ] && root="--root=$1"
   1.316 @@ -1084,7 +1050,7 @@
   1.317  		answer=$?
   1.318  		newline
   1.319  	fi
   1.320 -	if [ $answer = 0 ] && ! [ "$nodeps" ]; then
   1.321 +	if [ $answer == 0 ] && ! [ "$nodeps" ]; then
   1.322  		for pkgorg in $DEPENDS; do
   1.323  			pkg=$(equivalent_pkg $pkgorg $1)
   1.324  			if [ ! -d "$1$INSTALLED/$pkg" ]; then
   1.325 @@ -1130,8 +1096,7 @@
   1.326  
   1.327  # Search pattern in installed packages.
   1.328  
   1.329 -search_in_installed_packages()
   1.330 -{
   1.331 +search_in_installed_packages() {
   1.332  	_ 'Installed packages'
   1.333  	separator
   1.334  	num=0
   1.335 @@ -1152,8 +1117,7 @@
   1.336  
   1.337  # Search in packages.list for available pkgs.
   1.338  
   1.339 -search_in_packages_list()
   1.340 -{
   1.341 +search_in_packages_list() {
   1.342  	_ 'Available packages'
   1.343  	separator
   1.344  	num=0
   1.345 @@ -1180,8 +1144,7 @@
   1.346  # search --mirror: Search in packages.txt for available pkgs and give more
   1.347  # info than --list or default.
   1.348  
   1.349 -search_in_packages_txt()
   1.350 -{
   1.351 +search_in_packages_txt() {
   1.352  	_ 'Matching packages name with version and desc'
   1.353  	separator
   1.354  	num=0
   1.355 @@ -1205,8 +1168,7 @@
   1.356  
   1.357  # Install package-list from a flavor
   1.358  
   1.359 -install_flavor()
   1.360 -{
   1.361 +install_flavor() {
   1.362  	check_root $@
   1.363  
   1.364  	# Get repositories priority list.
   1.365 @@ -1258,8 +1220,7 @@
   1.366  
   1.367  # Update mirror urls
   1.368  
   1.369 -setup_mirror()
   1.370 -{
   1.371 +setup_mirror() {
   1.372  	# Backup old list.
   1.373  	if [ -f "$1/mirror" ]; then
   1.374  		cp -f $1/mirror $1/mirror.bak
   1.375 @@ -1292,8 +1253,7 @@
   1.376  
   1.377  # recursive dependencies scan
   1.378  
   1.379 -dep_scan()
   1.380 -{
   1.381 +dep_scan() {
   1.382  	for i in $1; do
   1.383  		case " $ALL_DEPS " in
   1.384  			*\ $i\ *) continue;;
   1.385 @@ -1311,8 +1271,7 @@
   1.386  
   1.387  # recursive reverse dependencies scan
   1.388  
   1.389 -rdep_scan()
   1.390 -{
   1.391 +rdep_scan() {
   1.392  	SEARCH=$1
   1.393  
   1.394  	for i in * ; do
   1.395 @@ -1349,51 +1308,61 @@
   1.396  }
   1.397  
   1.398  
   1.399 -update_desktop_database()
   1.400 -{
   1.401 +update_desktop_database() {
   1.402  	if [ -f $1/usr/bin/update-desktop-database ] && [ -n "$updatedesktopdb" ]; then
   1.403  		chroot "$1/" /usr/bin/update-desktop-database /usr/share/applications 2>/dev/null
   1.404  	fi
   1.405  }
   1.406  
   1.407  
   1.408 -update_mime_database()
   1.409 -{
   1.410 +update_mime_database() {
   1.411  	if [ -f $1/usr/bin/update-mime-database ] && [ -n "$updatemimedb" ]; then
   1.412  		chroot "$1/" /usr/bin/update-mime-database /usr/share/mime
   1.413  	fi
   1.414  }
   1.415  
   1.416  
   1.417 -update_icon_database()
   1.418 -{
   1.419 +update_icon_database() {
   1.420  	if [ -f $1/usr/bin/gtk-update-icon-cache ] && [ -n "$updateicondb" ]; then
   1.421  		chroot "$1/" /usr/bin/gtk-update-icon-cache /usr/share/icons/hicolor
   1.422  	fi
   1.423  }
   1.424  
   1.425  
   1.426 -compile_glib_schemas()
   1.427 -{
   1.428 +compile_glib_schemas() {
   1.429  	if [ -f $1/usr/bin/glib-compile-schemas ] && [ -n "$compile_schemas" ]; then
   1.430  		chroot "$1/" /usr/bin/glib-compile-schemas /usr/share/glib-2.0/schemas
   1.431  	fi
   1.432  }
   1.433  
   1.434  
   1.435 -update_kernel_modules()
   1.436 -{
   1.437 +update_kernel_modules() {
   1.438  	if [ -f $1/sbin/depmod ] && [ -n "$updatedepmod" ]; then
   1.439  		chroot "$1/" /sbin/depmod -a
   1.440  	fi
   1.441  }
   1.442  
   1.443  
   1.444 +# When recharging errors occurs
   1.445 +
   1.446 +recharging_failed() {
   1.447 +	colorize 31 "$(_ 'Recharging failed')"
   1.448 +
   1.449 +	# Restore database from bak files
   1.450 +	action 'Restoring database files...'
   1.451 +	[ -e 'ID'  -a ! -e 'ID.bak' ]  && rm ID
   1.452 +	[ -e 'IDs' -a ! -e 'IDs.bak' ] && rm IDs
   1.453 +	for file in $(ls $1/*.bak); do
   1.454 +		mv -f $file ${file%.bak}
   1.455 +	done
   1.456 +	status
   1.457 +}
   1.458 +
   1.459  
   1.460  
   1.461  
   1.462  ###################
   1.463 -# TazPKG commands #
   1.464 +# TazPkg commands #
   1.465  ###################
   1.466  
   1.467  case "$COMMAND" in
   1.468 @@ -1413,6 +1382,7 @@
   1.469  				fi
   1.470  				newline; exit 0
   1.471  				;;
   1.472 +
   1.473  			c|cat|categories)
   1.474  				# Display the list of categories.
   1.475  				title 'Packages categories'
   1.476 @@ -1428,6 +1398,7 @@
   1.477  					$num)"
   1.478  				exit 0
   1.479  				;;
   1.480 +
   1.481  			'')
   1.482  				# By default list all packages and versions.
   1.483  				title 'List of all installed packages'
   1.484 @@ -1441,6 +1412,7 @@
   1.485  					'%s packages installed.' $packages \
   1.486  					"<c 32>$packages</c>"))"
   1.487  				;;
   1.488 +
   1.489  			*)
   1.490  				# Check for an asked category.
   1.491  				ASKED_CATEGORY_I18N="$@"
   1.492 @@ -1462,6 +1434,7 @@
   1.493  				;;
   1.494  		esac ;;
   1.495  
   1.496 +
   1.497  	list-mirror|-lm)
   1.498  		# List all available packages on the mirror. Option --diff displays
   1.499  		# last mirrored packages diff (see recharge).
   1.500 @@ -1593,12 +1566,9 @@
   1.501  		title 'Search result for "%s"' $PATTERN
   1.502  		# Default is to search in installed pkgs and the raw list.
   1.503  		case "$3" in
   1.504 -			-i|--installed)
   1.505 -				search_in_installed_packages ;;
   1.506 -			-l|--list)
   1.507 -				search_in_packages_list ;;
   1.508 -			-m|--mirror)
   1.509 -				search_in_packages_txt ;;
   1.510 +			-i|--installed) search_in_installed_packages ;;
   1.511 +			-l|--list)      search_in_packages_list ;;
   1.512 +			-m|--mirror)    search_in_packages_txt ;;
   1.513  			*)
   1.514  				search_in_installed_packages
   1.515  				search_in_packages_list ;;
   1.516 @@ -2226,102 +2196,139 @@
   1.517  
   1.518  
   1.519  	recharge)
   1.520 -		# Recharge packages.list from a mirror.
   1.521 +		# Recharge packages databases from a mirror.
   1.522  		#
   1.523  		# WARNING: The 'mirrors' file has all SliTaz mirrors but 'mirror'
   1.524  		# must have only the chosen main mirror.
   1.525  		#
   1.526  		check_root $@
   1.527  
   1.528 -		ARG=$2
   1.529 -		if [ "$root" ]; then
   1.530 -			PKGS_DB=$root$PKGS_DB
   1.531 -			[ "${2#--}" != "$2" ] && ARG=$3
   1.532 +		# usage: tazpkg recharge [--root=path] [main|<repository>]
   1.533 +
   1.534 +		ARG="$2"
   1.535 +		if [ -n "$root" ]; then
   1.536 +			PKGS_DB="$root$PKGS_DB"
   1.537 +			[ "${2#--}" != "$2" ] && ARG="$3"
   1.538  		fi
   1.539 -		if [ "$ARG" = main ]; then
   1.540 -			repository_to_recharge=$PKGS_DB
   1.541 -		elif [ "$ARG" ]; then
   1.542 -			if [ -d "$PKGS_DB/undigest/$ARG" ]; then
   1.543 -				repository_to_recharge=$PKGS_DB/undigest/$ARG
   1.544 +
   1.545 +		case "$ARG" in
   1.546 +			main) repo_to_recharge="$PKGS_DB";;
   1.547 +			'')   repo_to_recharge="$PKGS_DB $PKGS_DB/undigest/*";;
   1.548 +			*)    repo_to_recharge="$PKGS_DB/undigest/$ARG"
   1.549 +				if [ ! -d "$repo_to_recharge" ]; then
   1.550 +					_ "Repository \"%s\" doesn't exist." "$repo_to_recharge" >&2
   1.551 +					exit 1
   1.552 +				fi
   1.553 +				;;
   1.554 +		esac
   1.555 +
   1.556 +		for path in $repo_to_recharge; do
   1.557 +			[ ! -f $path/mirror ] && continue	# skip
   1.558 +			cd $path
   1.559 +			mirror="$(cat mirror)"
   1.560 +
   1.561 +			# Repository name
   1.562 +			if [ "$path" == "$PKGS_DB" ]; then
   1.563 +				repo_name='Main'
   1.564  			else
   1.565 -				repo="$PKGS_DB/undigest/$ARG"
   1.566 -				_ "Repository \"%s\" doesn't exist." $repo >&2
   1.567 -				exit 1
   1.568 +				repo_name="$(_n 'Undigest %s' "$(basename $path)")"
   1.569  			fi
   1.570 -		else
   1.571 -			repository_to_recharge="$PKGS_DB $PKGS_DB/undigest/*"
   1.572 -		fi
   1.573 -		for path in $repository_to_recharge; do
   1.574 -			[ -f $path/mirror ] || continue
   1.575 -			cd $path
   1.576 -
   1.577 -			# Quietly check if recharging is needed.
   1.578 -			[ -f ID ] && mv ID ID.bak
   1.579 -			download_from "$(cat mirror)" ID >/dev/null 2>/dev/null
   1.580 -			if [ -f ID ] && fgrep -q $(cat ID.bak 2>/dev/null || echo "null") ID; then
   1.581 -				if [ "$path" = "$PKGS_DB" ]; then
   1.582 -					repository_name=Main
   1.583 -				else
   1.584 -					base_path="$(basename $path)"
   1.585 -					repository_name="$(_n 'Undigest %s' $base_path)"
   1.586 -				fi
   1.587 -				_ 'Repository "%s" is up to date.' "$repository_name"
   1.588 -				rm ID.bak
   1.589 +
   1.590 +			# Don't let ID be a symlink when using local repository.
   1.591 +			if [ -h ID  ]; then mv -f ID  ID.lnk;  cat ID.lnk  > ID;  rm ID.lnk;  fi
   1.592 +			if [ -h IDs ]; then mv -f IDs IDs.lnk; cat IDs.lnk > IDs; rm IDs.lnk; fi
   1.593 +
   1.594 +			[ -f ID ]  && mv ID  ID.bak					# Compatibility with "old" ID
   1.595 +			[ -f IDs ] && mv IDs IDs.bak
   1.596 +			download_from "$mirror" IDs
   1.597 +			[ -e 'IDs' ] && awk '{print $1}' IDs > ID	# Compatibility with "old" ID
   1.598 +
   1.599 +			# Check if recharging is needed
   1.600 +			if [ -f 'IDs' ] && cmp -s IDs IDs.bak; then
   1.601 +				_ 'Repository "%s" is up to date.' "$repo_name"
   1.602 +				rm IDs.bak ID.bak
   1.603  				continue
   1.604  			fi
   1.605  
   1.606 -			# Don't let ID be a symlink when using local repository.
   1.607 -			if [ -f ID ]; then
   1.608 -				mv -f ID ID.bak
   1.609 -				cat ID.bak > ID
   1.610 -				rm ID.bak
   1.611 +			title 'Recharging repository "%s"' "$repo_name"
   1.612 +			[ -e 'IDs' ] && _ 'Database timestamp: %s' "$(date -d "@$(awk '{print $2}' IDs)" "+%x %R")"
   1.613 +
   1.614 +			action 'Creating backup of the last packages list...'
   1.615 +			for i in packages.desc packages.$SUM packages.txt packages.list \
   1.616 +				packages.equiv files.list.lzma extra.list mirrors packages.info; do
   1.617 +				[ -f "$i" ] && mv -f $i $i.bak 2>/dev/null
   1.618 +			done
   1.619 +			status
   1.620 +
   1.621 +			# Download and extract bundle: extra.list, mirrors, files-list.md5,
   1.622 +			#   packages.{info,desc,md5,txt,list,equiv}
   1.623 +			bundle='bundle.tar.lzma'
   1.624 +			action 'Getting "%s"...' $bundle
   1.625 +			download_from "$mirror" $bundle
   1.626 +			status
   1.627 +			if [ -f "$bundle" ]; then
   1.628 +				busybox tar -xaf $bundle; rm $bundle
   1.629 +			else
   1.630 +				recharging_failed $path; continue
   1.631  			fi
   1.632  
   1.633 -			newline
   1.634 -			if [ "$path" != "$PKGS_DB" ]; then
   1.635 -				base_path="$(basename $path)"
   1.636 -				_ 'Recharging undigest %s:' $base_path
   1.637 -			fi
   1.638 -
   1.639 -			if [ -f "packages.list" ]; then
   1.640 -				action "Creating backup of the last packages list..."
   1.641 -				for i in packages.desc packages.$SUM packages.txt \
   1.642 -					packages.list packages.equiv files.list.lzma \
   1.643 -					extra.list mirrors packages.info
   1.644 -				do
   1.645 -					mv -f $i $i.bak 2>/dev/null
   1.646 -				done
   1.647 +			# Download files.list.lzma
   1.648 +			files_local='files.list.lzma'; files_remote='files-list.lzma'
   1.649 +			if [ -e "$files_local.bak" ]; then
   1.650 +				md5sum $files_local.bak | awk '{printf $1}' > files-list.md5.bak
   1.651 +				if cmp -s files-list.md5 files-list.md5.bak; then
   1.652 +					mv $files_local.bak $files_remote
   1.653 +				else
   1.654 +					action 'Getting "%s"...' $files_remote
   1.655 +					download_from "$mirror" $files_remote
   1.656 +					status
   1.657 +				fi
   1.658 +			else
   1.659 +				action 'Getting "%s"...' $files_remote
   1.660 +				download_from "$mirror" $files_remote
   1.661  				status
   1.662  			fi
   1.663  
   1.664 -			for i in desc $SUM txt list equiv; do
   1.665 -				download_from "$(cat mirror)" packages.$i
   1.666 +			if [ ! -e "$files_remote" ]; then
   1.667 +				recharging_failed $path; continue
   1.668 +			fi
   1.669 +			mv -f $files_remote $files_local
   1.670 +
   1.671 +			# Remove old database files (but packages.list.bak, extra.list.bak)
   1.672 +			for i in packages.desc packages.$SUM packages.txt packages.equiv \
   1.673 +				files.list.lzma mirrors packages.info files-list.md5; do
   1.674 +				[ -f "$i.bak" ] && rm $i.bak 2>/dev/null
   1.675  			done
   1.676 -			download_from "$(cat mirror)" files.list.lzma
   1.677 -			download_from "$(cat mirror)" extra.list
   1.678 -			download_from "$(sed 's|packages/.*||' mirror)" mirrors
   1.679 -
   1.680 -			# packages.info
   1.681 -			download_from "$(cat mirror)" packages.info.lzma
   1.682 -			lzma d packages.info.lzma packages.info
   1.683 -			rm packages.info.lzma
   1.684 -
   1.685 -			if [ -f "packages.list.bak" ]; then
   1.686 +
   1.687 +			footer "$(_ 'Last database is ready to use.')"
   1.688 +
   1.689 +			# Check diff
   1.690 +			if [ -f 'packages.list.bak' ]; then
   1.691  				diff -u packages.list.bak packages.list | grep ^+[a-z] > packages.diff
   1.692 -				[ -f "extra.list.bak" ] &&
   1.693 -				diff -u extra.list.bak extra.list | grep ^+[a-z] >> packages.diff
   1.694 +				rm packages.list.bak
   1.695 +				if [ -f 'extra.list.bak' ]; then
   1.696 +					if [ -f 'extra.list' ]; then
   1.697 +						diff -u extra.list.bak extra.list | grep ^+[a-z] >> packages.diff
   1.698 +						rm extra.list.bak
   1.699 +					else
   1.700 +						mv extra.list.bak extra.list
   1.701 +					fi
   1.702 +				fi
   1.703  				sed -i s/+// packages.diff
   1.704 -				title 'Mirrored packages diff'
   1.705 -				cat packages.diff
   1.706 +
   1.707  				new_pkgs=$(wc -l < packages.diff)
   1.708 -				footer "$(emsg "$(_p \
   1.709 +				if [ "$new_pkgs" -gt 0 ]; then
   1.710 +					title 'Mirrored packages diff'
   1.711 +					cat packages.diff
   1.712 +					footer "$(emsg "$(_p \
   1.713  					'%s new package on the mirror.' \
   1.714  					'%s new packages on the mirror.' $new_pkgs \
   1.715  					"<c 32>$new_pkgs</c>")")"
   1.716 +				fi
   1.717  			else
   1.718 -				footer "$(longline "$(_ "Last %s is ready to use. Note that \
   1.719 -next time you recharge the list, a list of differences will be displayed to \
   1.720 -show new and upgradeable packages." packages.list)")"
   1.721 +				longline "$(_ "Note that next time you recharge the \
   1.722 +list, a list of differences will be displayed to show new and upgradeable \
   1.723 +packages.")"
   1.724  			fi
   1.725  		done ;;
   1.726