blob: 69d38956f92d16af445ccda60c9cd4b0738045f8 [file] [log] [blame]
#!/bin/bash
# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH}"/isolated-functions.sh || exit 1
option_r=
if [[ ___eapi_has_dosym_r && $1 == -r ]]; then
option_r=t
shift
fi
if [[ $# -ne 2 ]] ; then
__helpers_die "${0##*/}: two arguments needed"
exit 1
fi
if ! ___eapi_has_prefix_variables; then
ED=${D}
fi
if [[ ${2} == */ ]] || [[ -d ${ED%/}/${2#/} && ! -L ${ED%/}/${2#/} ]] ; then
# implicit basename not allowed by PMS (bug #379899)
__helpers_die "${0##*/}: dosym target omits basename: '${2}'"
fi
target=$1
if [[ ${option_r} ]]; then
# Transparent bash-only replacement for GNU "realpath -m -s".
# Resolve references to "/./", "/../" and remove extra "/" characters
# from <path>, without touching any actual file.
dosym_canonicalize() {
local path slash i prev out IFS=/
path=( $1 )
[[ $1 == /* ]] && slash=/
while true; do
# Find first instance of non-".." path component followed by "..",
# or as a special case, "/.." at the beginning of the path.
# Also drop empty and "." path components as we go along.
prev=
for i in ${!path[@]}; do
if [[ -z ${path[i]} || ${path[i]} == . ]]; then
unset "path[i]"
elif [[ ${path[i]} != .. ]]; then
prev=${i}
elif [[ ${prev} || ${slash} ]]; then
# Found, remove path components and reiterate
[[ ${prev} ]] && unset "path[prev]"
unset "path[i]"
continue 2
fi
done
# No (further) instance found, so we're done
break
done
out="${slash}${path[*]}"
echo "${out:-.}"
}
# Expansion makes sense only for an absolute target path
[[ ${target} == /* ]] || __helpers_die \
"${0##*/}: -r specified but no absolute target path: '${target}'"
target=$(dosym_canonicalize "${target}")
linkdir=$(dosym_canonicalize "/${2#/}")
linkdir=${linkdir%/*} # poor man's dirname(1)
linkdir=${linkdir:-/} # always keep the initial "/"
IFS=/
for comp in ${linkdir}; do
if [[ ${target%%/*} == "${comp}" ]]; then
target=${target#"${comp}"}
target=${target#/}
else
target=..${target:+/}${target}
fi
done
unset IFS
target=${target:-.}
fi
destdir=${2%/*}
[[ ! -d ${ED%/}/${destdir#/} ]] && dodir "${destdir}"
ln -snf "${target}" "${ED%/}/${2#/}"
ret=$?
[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit $ret