#!/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

