138 lines
4.4 KiB
Bash
Executable File
138 lines
4.4 KiB
Bash
Executable File
#!/bin/sh
|
|
# Copyright © 2005-2007 Roger Leigh <rleigh@codelibre.net>
|
|
#
|
|
# schroot is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# schroot is distributed in the hope that it will be useful, but
|
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see
|
|
# <http://www.gnu.org/licenses/>.
|
|
#
|
|
#####################################################################
|
|
|
|
set -e
|
|
|
|
. "$SETUP_DATA_DIR/common-data"
|
|
. "$SETUP_DATA_DIR/common-functions"
|
|
. "$SETUP_DATA_DIR/common-config"
|
|
|
|
if [ "$VERBOSE" = "verbose" ]; then
|
|
CP_VERBOSE="--verbose"
|
|
fi
|
|
|
|
# Copy a file if the source and destination differ
|
|
# $1: source file
|
|
# $2: destination file
|
|
copy_file()
|
|
{
|
|
if [ -e "$1" ]; then
|
|
|
|
COPY="true"
|
|
|
|
if [ -e "$2" ]; then
|
|
|
|
# Device and inode
|
|
da=$(/usr/bin/stat --format="%d %i" "$1")
|
|
# This one can fail since it might not exist yet
|
|
db=$(/usr/bin/stat --format="%d %i" "$2" 2>/dev/null || :)
|
|
|
|
if [ "$da" = "$db" ]; then
|
|
COPY="false"
|
|
elif [ -L "$2" ]; then
|
|
# Copy if destination is a symlink
|
|
:
|
|
elif [ -f "$1" ] && [ -f "$2" ]; then
|
|
# Content
|
|
ca=$(/usr/bin/md5sum "$1" | sed -e 's/\(^[0-9a-f][0-9a-f]*\).*$/\1/')
|
|
cb=$(/usr/bin/md5sum "$2" 2>/dev/null || :)
|
|
cb=$(echo "$cb" | sed -e 's/\(^[0-9a-f][0-9a-f]*\).*$/\1/')
|
|
# Copy only if file contents differ
|
|
if [ "$ca" = "$cb" ]; then
|
|
COPY="false"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Copy only if files are different
|
|
if [ "$COPY" = "true" ]; then
|
|
mkdir -p $(dirname $2)
|
|
if [ -f "$1" ]; then
|
|
cp --remove-destination --preserve=all $CP_VERBOSE "$1" "$2"
|
|
else
|
|
# Copy non-regular file directly
|
|
cp --remove-destination -a $CP_VERBOSE "$1" "$2"
|
|
fi
|
|
fi
|
|
|
|
else
|
|
fatal "Not copying nonexistent file: $1"
|
|
fi
|
|
}
|
|
|
|
# Resolve a relative path inside the chroot to its absolute path on the host
|
|
# $1: base path of the chroot
|
|
# $2: relative path to resolve
|
|
resolve_path()
|
|
{
|
|
base_path="$(realpath "$1")"
|
|
relative_destination="${2#/}"
|
|
absolute_destination="$base_path"
|
|
|
|
while [ -n "$relative_destination" ]; do
|
|
first_component="${relative_destination%%/*}"
|
|
relative_destination="${relative_destination#$first_component}"
|
|
relative_destination="${relative_destination#/}"
|
|
|
|
# If the first component is a link
|
|
if link="$(readlink "$absolute_destination/$first_component")"; then
|
|
# If the first component is a relative link
|
|
if [ "${link#/}" = "$link" ]; then
|
|
relative_destination="$link/$relative_destination"
|
|
else
|
|
absolute_destination="$base_path"
|
|
relative_destination="${link#/}/$relative_destination"
|
|
fi
|
|
else
|
|
absolute_destination="$(realpath "$absolute_destination/$first_component")"
|
|
|
|
# If the absolute destination gets out of the chroot
|
|
if [ "${absolute_destination#$base_path}" = "$absolute_destination" ]; then
|
|
absolute_destination="$base_path"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
echo "$absolute_destination"
|
|
}
|
|
|
|
if [ $STAGE = "setup-start" ] || [ $STAGE = "setup-recover" ]; then
|
|
|
|
if [ -n "$SETUP_COPYFILES" ]; then
|
|
if [ -f "$SETUP_COPYFILES" ]; then
|
|
while read src dst; do
|
|
: ${dst:=$src}
|
|
if echo "$src" | grep -Eq '^(#|$)' ; then
|
|
continue
|
|
fi
|
|
if echo "$src" | grep -q '^/' &&
|
|
echo "$dst" | grep -q '^/'; then
|
|
copy_file "$src" "$(resolve_path "${CHROOT_PATH}" "$dst")"
|
|
else
|
|
warn "Not copying file with relative path: $src -> $dst"
|
|
fi
|
|
done < "$SETUP_COPYFILES"
|
|
else
|
|
fatal "copyfiles file '$SETUP_COPYFILES' does not exist"
|
|
fi
|
|
fi
|
|
|
|
fi
|
|
|