remove trash-put support, it is too annoying
[lnf] / lnf
diff --git a/lnf b/lnf
index 3bc51523444ee9e70fadc523e088979fc69d0f20..bfb2c2a9f0b91cad4faba6f9a3ec38ff6d89a76b 100755 (executable)
--- a/lnf
+++ b/lnf
@@ -3,36 +3,39 @@
 # This program is under GPL v. 3 or later, see <http://www.gnu.org/licenses/>
 
 _lnf_existing_link() {
 # This program is under GPL v. 3 or later, see <http://www.gnu.org/licenses/>
 
 _lnf_existing_link() {
-    local target dest_file dest_dir
-    target="$1"
-    dest_file="$2"
-    dest_dir="$3"
-    if [[ -L $dest_file ]]; then
-        if [[ $(readlink $dest_file) == "$target" ]]; then
-            # Leave the link in place, but make sure it's
-            # ownership is right.
-            # already exists. links all get 777 perms, so
-            # we dun have to mess with that.
-            if [[ $(stat -L -c%a "$dest_dir") == 2* ]]; then
-                grp=$(stat -L -c%g "$dest_dir")
-            else
-                grp=$(id -g)
-            fi
-            if [[ $EUID == 0 && $(stat -c%u "$dest_file") != 0 ]]; then
-                chown 0:$grp "$dest_file"
-            elif [[ $(stat -c%g "$dest_file") != "$grp" ]]; then
-                chgrp $grp "$dest_file"
-            fi
-            return 1
-        fi
-        to_remove+=("$dest_file")
-    elif [[ -e $dest_file ]]; then
-        to_remove+=("$dest_file")
+  local target dest_file dest_dir
+  target="$1"
+  dest_file="$2"
+  dest_dir="$3"
+  if [[ -L $dest_file ]]; then
+    if [[ $(readlink $dest_file) == "$target" ]]; then
+      # Leave the link in place, but make sure it's
+      # owner & group is as if we created it.
+      # links all get 777 perms, so
+      # we already know that is right.
+
+      # test for setgid.
+      if [[ $(stat -L -c%a "$dest_dir") == 2??? ]]; then
+        grp=$(stat -L -c%g "$dest_dir") || return $?
+      else
+        grp=$(id -g) || return $?
+      fi
+      if [[ $EUID == 0 && $(stat -c%u "$dest_file") != 0 ]]; then
+        chown -h 0:$grp "$dest_file" || return $?
+      elif [[ $(stat -c%g "$dest_file") != "$grp" ]]; then
+        chgrp -h $grp "$dest_file" || return $?
+      fi
+      do_exit=true
+      return 0
     fi
     fi
-    to_link+=("$target")
+    to_remove+=("$dest_file")
+  elif [[ -e $dest_file ]]; then
+    to_remove+=("$dest_file")
+  fi
+  to_link+=("$target")
 }
 lnf() {
 }
 lnf() {
-    local help="Usage:
+  local help="Usage:
        lnf [OPTIONS] -T TARGET LINK_NAME     (1st form)
        lnf [OPTIONS] TARGET                  (2nd form)
        lnf [OPTIONS] TARGET... DIRECTORY     (3rd form)
        lnf [OPTIONS] -T TARGET LINK_NAME     (1st form)
        lnf [OPTIONS] TARGET                  (2nd form)
        lnf [OPTIONS] TARGET... DIRECTORY     (3rd form)
@@ -40,9 +43,8 @@ Create symlinks forcefully
 
 If the link already exists, make it's ownership be the same as if it was
 newly created (only chown if we are root).  Removes existing files using
 
 If the link already exists, make it's ownership be the same as if it was
 newly created (only chown if we are root).  Removes existing files using
-trash-put or rm -rf if it is not available, or if trash-put fails due to a
-limitation such as a cross-filesystem link. Create directory of link if
-needed. Slightly more restrictive arguments than ln.
+rm -rf. Create directory of link if needed. Slightly more restrictive
+arguments than ln.
 
 In the 1st form, create a link to TARGET with the name LINK_NAME.  In the 2nd
 form, create a link to TARGET in the current directory.  In the 3rd form, create
 
 In the 1st form, create a link to TARGET with the name LINK_NAME.  In the 2nd
 form, create a link to TARGET in the current directory.  In the 3rd form, create
@@ -54,126 +56,107 @@ links to each TARGET in DIRECTORY.
 "
 
 
 "
 
 
-    local temp
-    local verbose=false
-    local dry_run=false
-    local nodir
-    temp=$(getopt -l help,dry-run,verbose hnTv "$@") || usage 1
-    eval set -- "$temp"
-    while true; do
-        case $1 in
-            -n|--dry-run) dry_run=true; verbose=true; shift ;;
-            -T) nodir=-T; shift ;;
-            -v|--verbose) verbose=true; shift ;;
-            -h|--help) echo "$help"; return 0 ;;
-            --) shift; break ;;
-            *) echo "$0: Internal error! unexpected args: $*" ; exit 1 ;;
-        esac
-    done
-
-    if (( $# == 0 )); then
-        echo "$help"
-        return 1
-    fi
-
-    if [[ $nodir ]]; then
-        if (( $# != 2 )); then
-            echo "lnf: error: expected 2 arguments with -T flag. Got $#"
-            return 1
-        fi
+  local temp nodir
+  local verbose=false
+  local dry_run=false
+  local do_exit=false
+  temp=$(getopt -l help,dry-run,verbose hnTv "$@") || usage 1
+  eval set -- "$temp"
+  while true; do
+    case $1 in
+      -n|--dry-run) dry_run=true; verbose=true; shift ;;
+      -T) nodir=-T; shift ;;
+      -v|--verbose) verbose=true; shift ;;
+      -h|--help) echo "$help"; return 0 ;;
+      --) shift; break ;;
+      *) echo "$0: Internal error! unexpected args: $*" ; exit 1 ;;
+    esac
+  done
+
+  if (( $# == 0 )); then
+    echo "$help"
+    return 1
+  fi
+
+  if [[ $nodir ]]; then
+    if (( $# != 2 )); then
+      echo "lnf: error: expected 2 arguments with -T flag. Got $#"
+      return 1
     fi
     fi
+  fi
 
 
-    local reset_extglob=false
-    ! shopt extglob >/dev/null && reset_extglob=true
-    shopt -s extglob
-
-
-    local -a to_remove to_link
-    local x ret prefix dest_dir grp target
-    local mkdir=false
-
-    if [[ $nodir ]]; then
-        dest_file="$2"
-        dest_dir="$(dirname "$dest_file")"
-        _lnf_existing_link "$1" "$dest_file" "$dest_dir" || return 0
-        if [[ ! -d $dest_dir ]]; then
-            mkdir=true
-            if [[ -e $dest_dir || -L $dest_dir ]]; then
-                to_remove+=("$dest_dir")
-            fi
-        fi
-        to_link+=("$dest_file")
-    elif (( $# >= 2 )); then
-        dest_dir="${!#}"
-        if [[ -d $dest_dir ]]; then
-            prefix="$dest_dir" # last arg
-            for target in "${@:1:$(( $# - 1 ))}"; do # all but last arg
-                # Remove 1 or more trailing slashes, using.
-                dest_file="${target%%+(/)}"
-                # remove any leading directory components, add prefix
-                dest_file="$prefix/${target##*/}"
-                _lnf_existing_link "$target" "$dest_file" "$dest_dir"
-            done
-        else
-            to_link+=("${@:1:$(( $# - 1 ))}")
-            mkdir=true
-        fi
-        if (( ${#to_link[@]} == 0 )); then
-            return 0
-        fi
-        to_link+=("$dest_dir")
-    elif  [[ $# -eq 1 ]]; then
-        dest_file="${1##*/}"
-        _lnf_existing_link "$1" "$dest_file" . || return 0
-    fi
-    if (( ${#to_remove[@]} >= 1 )); then
-        if type -P trash-put >/dev/null; then
-            if $verbose; then
-                echo "lnf: trash-put -- ${to_remove[*]}"
-            fi
-            if ! $dry_run; then
-                trash-put -- "${to_remove[@]}" || ret=$?
-            fi
-            # trash-put will fail to trash a link that goes across filesystems (72),
-            # and for empty files (74)
-            # so revert to rm -rf in that case
-            if [[ $ret == 72 ]]; then
-                echo "lnf: using rm -rf to overcome cross filesystem trash-put limitation"
-                rm -rf -- "${to_remove[@]}"
-            elif [[ $ret == 74 ]]; then
-                echo "lnf: using rm -rf to overcome empty file & hardlink trash-put limitation"
-                rm -rf -- "${to_remove[@]}"
-            elif [[ $ret && $ret != 0 ]]; then
-                return $x
-            fi
-        else
-            if $verbose; then
-                echo "lnf: rm -rf -- ${to_remove[*]}"
-            fi
-            if ! $dry_run; then
-                rm -rf -- "${to_remove[@]}"
-            fi
-        fi
-    fi
+  local reset_extglob=false
+  ! shopt extglob >/dev/null && reset_extglob=true
+  shopt -s extglob
 
 
-    $reset_extglob && shopt -u extglob
 
 
-    if $mkdir; then
-        if $verbose; then
-            echo "lnf: mkdir -p $dest_dir"
-        fi
+  local -a to_remove to_link
+  local x ret prefix dest_dir grp target
+  local mkdir=false
 
 
-        if ! $dry_run && ! mkdir -p "$dest_dir"; then
-            echo "lnf error: failed to make directory $dest_dir"
-            return 1
-        fi
+  if [[ $nodir ]]; then
+    dest_file="$2"
+    dest_dir="$(dirname "$dest_file")"
+    _lnf_existing_link "$1" "$dest_file" "$dest_dir" || return $?
+    if $do_exit; then return 0; fi
+    if [[ ! -d $dest_dir ]]; then
+      mkdir=true
+      if [[ -e $dest_dir || -L $dest_dir ]]; then
+        to_remove+=("$dest_dir")
+      fi
     fi
     fi
-
+    to_link+=("$dest_file")
+  elif (( $# >= 2 )); then
+    dest_dir="${!#}"
+    if [[ -d $dest_dir ]]; then
+      prefix="$dest_dir" # last arg
+      for target in "${@:1:$(( $# - 1 ))}"; do # all but last arg
+        # Remove 1 or more trailing slashes, using.
+        dest_file="${target%%+(/)}"
+        # remove any leading directory components, add prefix
+        dest_file="$prefix/${target##*/}"
+        _lnf_existing_link "$target" "$dest_file" "$dest_dir"
+      done
+    else
+      to_link+=("${@:1:$(( $# - 1 ))}")
+      mkdir=true
+    fi
+    if (( ${#to_link[@]} == 0 )); then
+      return 0
+    fi
+    to_link+=("$dest_dir")
+  elif  [[ $# -eq 1 ]]; then
+    dest_file="${1##*/}"
+    _lnf_existing_link "$1" "$dest_file" . || return $?
+    if $do_exit; then return 0; fi
+  fi
+  if (( ${#to_remove[@]} >= 1 )); then
     if $verbose; then
     if $verbose; then
-        echo "lnf: ln -s $nodir -- ${to_link[*]}"
+      echo "lnf: rm -rf -- ${to_remove[*]}"
     fi
     if ! $dry_run; then
     fi
     if ! $dry_run; then
-        ln -s $nodir -- "${to_link[@]}"
+      rm -rf -- "${to_remove[@]}"
+    fi
+  fi
+
+  $reset_extglob && shopt -u extglob
+
+  if $mkdir; then
+    if $verbose; then
+      echo "lnf: mkdir -p $dest_dir"
+    fi
+
+    if ! $dry_run && ! mkdir -p "$dest_dir"; then
+      echo "lnf error: failed to make directory $dest_dir"
+      return 1
     fi
     fi
+  fi
+
+  if $verbose; then
+    echo "lnf: ln -s $nodir -- ${to_link[*]}"
+  fi
+  if ! $dry_run; then
+    ln -s $nodir -- "${to_link[@]}"
+  fi
 }
 lnf "$@"
 }
 lnf "$@"