1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
#!/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
|