From 333e2268712e548ccd9d1d2604f95d24dc163473 Mon Sep 17 00:00:00 2001 From: Martin Winkler Date: Mon, 21 Mar 2022 22:41:54 +0100 Subject: [PATCH] Add some more special handlings Smaller updates of debug output --- rdlink.sh | 80 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/rdlink.sh b/rdlink.sh index e7a147f..03a5a11 100755 --- a/rdlink.sh +++ b/rdlink.sh @@ -21,8 +21,8 @@ rl::rdlink() { local work= local resolved=0 - info "rd::link Processing... $@" - info " pwd: $(pwd)" + info "Processing: $@" + info " with pwd: $(pwd)" subject="$(rl::cleanpath "${1:-}")" || true @@ -51,7 +51,7 @@ rl::rdlink() { # are not existing files but `readlink -f` prints result anyway # Printing result if a link was resolved at least once #if (( ! resolved )); then - info "rl::rdlink exit - invalid path ${subject}" + info "rl::rdlink exit - invalid path ${work}" printf "\n" return 1 #fi @@ -90,37 +90,65 @@ rl::canon() { local subject= local work= local bname= + local run=1 + local start= + local retval=0 - info "Canonicalize path... ${1:-}" - if work="$(cd "${1:-}" >/dev/null 2>&1 && pwd -P)" ; then - # Special: `pwd -P` returns with // as root for links starting at / - # e.g. $(readlink /proc/self/root) == "/" - # $(cd /proc/self/root/mnt && pwd -P) == "//mnt" - subject="$(rl::normalize "${work}")" - info " - directory: ${subject}" - elif work="$(cd "$(dirname -- "${1:-}")" >/dev/null 2>&1 && pwd -P)" ; then - bname="$(basename -- "${1:-}")" + start="${1:-}" + info "Canonicalize path... ${start}" - # Special: / produces // - [[ "${work}" == "/" ]] && work= + while (( run )) ; do + if work="$(cd "${start}" >/dev/null 2>&1 && pwd -P)" ; then + # Special: `pwd -P` returns with // as root for links starting at / + # e.g. $(readlink /proc/self/root) == "/" + # $(cd /proc/self/root/mnt && pwd -P) == "//mnt" + subject="$(rl::normalize "${work}")" + info "rl::canon valid directory: ${subject}" + run=0 + elif work="$(cd "$(dirname -- "${start}")" >/dev/null 2>&1 && pwd -P)" ; then + bname="$(basename -- "${start}")" - subject="${work}${bname:+"/${bname}"}" - info " - parent: ${subject}" - else - info " - no hit for: ${1:-}" - subject="${1:-}" - return 1 - fi + # Special: / produces // + [[ "${work}" == "/" ]] && work= + + subject="${work}${bname:+"/${bname}"}" + info "rl::canon valid parent: ${subject}" + # Special: Succeed with valid element after second run; see special below + # e.g. /root/. + # * /root is valid but not accessible + if (( retval )) && [ -e "${subject}" ] ;then + info "rl::canon valid element" + retval=0 + fi + run=0 + else + # Special: Some paths may be resolvable after normalization + # e.g. somedir/.. + # * base "somedir" does not exist + # * but irrelevant because of /.. + # * resolves to pwd but fails by readlink -f + work="$(rl::normalize "${start}")" + if [[ "${work}" != "${start}" ]] ; then + info "rl::canon retry with: ${work}" + start="${work}" + retval=1 + continue + fi + info "rl::canon invalid path: ${work}" + subject="${work}" + run=0 && retval=1 + fi + done printf -- "${subject}\n" - return 0 + return ${retval} } rl::cleanpath() { local work= local rex_tmp= - info "rl::cleanpath...${1:-}" + info "Cleaning path... ${1:-}" work="${1:-}" # Remove multiple / @@ -135,16 +163,16 @@ rl::cleanpath() { rl::normalize() { local work= - info "rl::normalize...${1:-}" + info "Normalizing path... ${1:-}" - work="${1:-}" + work="${1:-}" # Remove dir/.. sequences. local rex_tmp='[^/][^/]*/\.\./*' while [[ "${work}" =~ $rex_tmp ]] ; do work="${work/"${BASH_REMATCH[0]}"/}" done - # Remove /./ or /.$ sequences. + # Remove /./ and /.$ sequences. rex_tmp='/\.(/|$)' while [[ "$work" =~ $rex_tmp ]]; do work="${work/"${BASH_REMATCH[0]}"/"${BASH_REMATCH[1]/$//}"}"