#!/usr/bin/env sh
#!/bin/sh -x
#!/usr/bin/env sh
#
# Author: Bryan Ritter
# BryanFRitt@HotMail.com
#
##############################################################################
# Somehow this computer '/' in links got replaced with '\'
# this is an attempt to fix this problem
# Still don't know what caused this issue, but this script fixed it.
#
# Modified from it's original form when it was created/used
# Like spelling changes, `` to $(), removal of commented out code, exit on `cd` failure, `stat` instead of `ls`, etc...
# The file with these minor changes haven't been tested, but I still have the original code, if needed
#
# Goals I had when making this program:
# Have this program fix all links with the '\' on the first run
# No links left unfixed that could be fixed, including links to links
# Don't change anything unless the changes will make the link point to a file
# Backup changed links before doing any changes
#
# Making a script to do this for one link (to make this easier to test)
# NOTE: this reaches out to wherever these links go, it doesn't stay restricted to a certain area
# BUG: forever loop when the corrected link(s) would point to itself, or in a cycle!
# "All answers using -prune are wrong." 
# http://stackoverflow.com/questions/4210042/exclude-directory-from-find-command/15736463#15736463

# Links don't have permissions: "This file is a link and does not have permissions" 
# looks this editor doesn't have spell check!, so sorry for any spelling errors! # UPDATE: now spell checked
#
# Guessing
# to take care of different interpretations of '~'
# ideally run first as a normal user with sudo
# then once finished, retry as other sudo nonroot users, 
# then as root
# UPDATE: none of the bad links have '~' in them! don't have to worry about that!
# UPDATE: this script doesn't work with '~' after all(the readlink command doesn't expand '~', otherwise it would work) :(, not that it needs to.
# seams the '~' isn't expanding in here!
# a search like `sudo find '/' -type l  -exec sh -c "readlink '{}' | grep '\\\' | grep '~'"  \;`
#               only found the link I created so, I guess I don't have to worry about that.
# This also doesn't expand to check paths like using one word to execute stuff in /bin
# This also doesn't expand stuff link $HOME, and $USER
##############################################################################
# Script below WORKS to run this !!! TESTED!!!
#sudo find / -type l -not -path "/home/bryan/tmp/*" -exec sudo /FixLink.sh "{}" \;
##############################################################################

# Script to Backup links...
#sudo find '/' -type l  -not -path "/home/bryan/tmp/*" -exec sh -c "readlink '{}' | grep '\\\' > /dev/null && cp -P -p --parents '{}' '/home/bryan/tmp/bkup3/' && echo -n '.'" \;

# Show which links could be fixed
#sudo find '/' -type l  -not -path "/home/bryan/tmp/*" -exec sh -c "readlink '{}' | grep '\\\' && echo {}" \;
#sudo find '.' -type l  -not -path "./bkup*"           -exec sh -c "readlink '{}' | grep '\\\' > /dev/null && echo {}" \;

# Script to reverse the '\' to '/' (in output only so far)
#sudo find '/' -type l  -not -path "/home/bryan/tmp/*" -exec sh -c "readlink '{}' | grep '\\\'| tr '\\ ' '/ ' " \;
#sudo find '.' -type l  -not -path "/home/bryan/tmp/*" -exec sh -c "readlink '{}' | grep '\\\'| tr '\\\' '/' " \;
#sudo find . -type l  -not -path "./bkup*" -exec sh -c "readlink -n '{}' | grep '\\\' > /dev/null && readlink -n '{}' | grep '\\\' | tr '\\\' '/' && echo 'is the link correction from ' && readlink '{}' && echo 'in \n{}\n==='" \;

# The one  used to start my program.
#sudo find / -type l  -not -path "/home/bryan/tmp/*" -exec sudo sh -c "sudo readlink '{}' | sudo grep '\\\' > /dev/null && sudo /FixLink.sh '{}' " \;

if test -L "$1" && test ! -e "$1"; # is this a link with no final destination?
then
  STARTEDATDIR=$(pwd)
  #echo "... working on $1 ..."
  # adding in this cd and it's return back cd makes it so relative links not on the current directory tests work
  #echo "cd $(dirname "$1")"
  cd "$(dirname "$1")" || echo "failure on attempt to \`cd \"$(dirname \""$1"\")\"\`" && exit
  printf "." # aka `echo -n "."`
  ###
  #CURLINK=`readlink -n "$1"`
  # both versions of MODIFIEDLINK seam to work the same
  #MODIFIEDLINK=$("readlink -n "$1" | tr "\\\ " "/ ") 
  MODIFIEDLINK=$(readlink -n "$1"  | tr '\\' '/')

  #echo "${MODIFIEDLINK}" is the modified link

  #echo "ls -AlF ${MODIFIEDLINK}"
  #ls -AlF "${MODIFIEDLINK}"
  ############################################################################
  if test -e "${MODIFIEDLINK}"; # Does the "${MODIFIEDLINK}" have a final destination?
  then
    #echo ""
#    echo "$1"
#    echo "   >-- doesn't point to anything with -->"
#    readlink "$1"

    POWN=$(stat -c "%U" "$1") #POWN=$(ls -Al "$1"| awk '{print $3}')
    PGRP=$(stat -c "%G" "$1") #PGRP=$(ls -Al "$1"| awk '{print $4}')

    ###backup existing link section###########################################
#    BACKUPDIR="/home/bryan/tmp/bkup3" # where the backups go
#    DIRNAME="$(dirname "$1")" # the subfolder of BACKUPDIR where the link will be put
    #the '#.' removes the first dot

#    echo "sudo mkdir -p \"${BACKUPDIR}${DIRNAME#.}\""
#    sudo mkdir -p "${BACKUPDIR}${DIRNAME#.}"
    
#    echo ""
#    echo "${BACKUPDIR}"
#    echo "${DIRNAME}"
#    echo "${DIRNAME#.}"
#    echo ""

# old:   
#    echo "sudo cp -d \"$1\" \"${BACKUPDIR}${DIRNAME#.}\""
#    sudo cp -d "$1" "${BACKUPDIR}${DIRNAME#.}"
#    # setting the backup link permissions back to the orginal file permissions
#    echo "sudo chown -h \"${POWN}\":\"${PGRP}\" \"${BACKUPDIR}$1\""
#    sudo chown -h "${POWN}":"${PGRP}" "${BACKUPDIR}$1"

# new but untested:
#    echo "sudo cp --parents -P \"$1\" \"/home/bryan/tmp/bkup4\""
   # make sure the directory exists before running cp with --parents, or it'll error
#    mkdir -p "/home/bryan/tmp/bkup4"
#    sudo cp --parents -P "$1" "/home/bryan/tmp/bkup4"
     
    ###modify existing link section###########################################

    #echo "the link $1 can be modifed to point to something by"
    echo "sudo ln -s -f \"${MODIFIEDLINK}\" \"$1\" "
    echo "sudo chown -h \"${POWN}\":\"${PGRP}\" \"$1\" "
#    echo ""

    # running the above commands that were printed with `echo`
    # executing the making of the correction in links
    sudo ln -s -f "${MODIFIEDLINK}" "$1"
    sudo chown -h "${POWN}":"${PGRP}" "$1"

  ############################################################################
  else # "${MODIFIEDLINK}"'s final destination doesn't exist, at least yet
    #echo "The new modified link in then end doesn't point to anything, so it won't work, at least yet"
    if test -L "${MODIFIEDLINK}";
    then
#     echo "   >-- attempting to correct $1's link -->"
      "$0" "${MODIFIEDLINK}"
      if test -e "${MODIFIEDLINK}"; # does "${MODIFIEDLINK}" now have a final destination?;
      then
#        echo "   >-- correcting link's link worked, retrying correcting myself -->"
        "$0" "$1"
#      else 
#        echo "${MODIFIEDLINK} does not have a final destination, even after attempt to correct link\'s link"
        echo "   >-- failed link's link correction as \"${MODIFIEDLINK}\" -->"
#        echo  "${MODIFIEDLINK}"
      fi
#      else # "$1" is not a link to a link, and doesn't have a final destination.
      echo "   >-- failed attempt to correct link on $1 as ${MODIFIEDLINK} --|" 
      #echo "$1"
    fi
  fi
  ############################################################################
  # done with the link go back to starting directory  
  cd "${STARTEDATDIR}"  || echo "failure on attempt to \`cd \"${STARTEDATDIR}\"\`" && exit
  #else
  #if ! test -L "$1";
  #then
    #echo "\"$1\" is not a link"
    #ls -AlF "$1"
  #else
    #echo "$1"
    #echo "   >-- is a good link to -->"
    #readlink "$1"
  #fi
fi
#echo "$1"
# done... time to go back to the directory where we started from
cd "${STARTEDATDIR}" || echo "failure on attempt to \`cd \"${STARTEDATDIR}\"\`" && exit

