#!/bin/bash
#
# Zapewne powinienem wymyslic jakas fajowska licencje czy inne cos w tym
# guscie, ale nie chce mi sie. Poza tym, do jednego prostego ;) skryptu? Bez
# przesadyzmu. Mozesz kopiowac i rozpowszechniac ten plik dowolnie dlugo
# i dowolna ilosc razy, a takze modyfikowac skrypt, byle pozostala w nim
# informacja o tym, ze ja jestem autorem pierwowzoru, jak rowniez przy kazdej
# wiekszej zmianie informacje o tym, kto jest jej autorem, o ile nie zaznaczy
# inaczej
#                                              Stach Klekot <dozzie@irc.pl>
#
# UWAGA: skrypt nie zachowuje sie do konca poprawnie dla dolinkowan do
# katalogow bedacych w tym samym drzewie katalogowym. Dla innych katalogow
# jest OK.
#
# INSTALACJA: skopiuj ten plik dokadkolwiek, byle to miejsce bylo
# przegladane podczas szukania polecen (niezlym pomyslem jest ~/bin/), a potem
# nadaj temu plikowi atrybuty wykonywalnosci poleceniem "chmod a+x chlink".
# To wszystko.
#

#----------------------------------------------------------------------------#

# funkcja przerabia dziwna sciezke /lib/../bin/././../usr/./share/../bin/diff
# na normalne krotkie /usr/bin/diff
#
# Jest to chyba jedyny slaby punkt programu, tzn. najdluzej sie wykonujacy.
# Jednak trzeba usuwac pary "katalog/../" pojedynczo, od tej, ktora jest
# nierozdzielona, bo efekty moga byc dosc... pomyslowe :). Jak znajdziesz
# sposob na usprawnienie tego to mi daj znac
# 
function zrob_normalna_sciezke()
{
echo "$1" | awk '
  {
  gsub("/(\\./)+", "/")
  while (index($0, "/../") != 0)
    sub("/[^/]+/\\.\\./", "/")
  print
  }'
}

#----------------------------------------------------------------------------#

# funkcja przerabia link symboliczny ze sciezki bezwzglednej na wzgledna
# wymagania: biezacy katalog roboczy to ten, w ktorym plik sie znajduje, link
#  wskazuje na plik o bezwzglednym polozeniu (wzgledem katalogu /)
function przerob_link()
{
# najpierw dowiem sie, na co wskazuje link...
SCIEZKA=$(zrob_normalna_sciezke `ls -l "$1" | sed 's/.*-> //'`)
# ... i gdzie sie znajduje
WDIR="$PWD/"

########echo -e "\e[31;1m$WDIR $SCIEZKA\e[0m"
# jesli zgadza sie pierwszy czlon katalgow biezacego i tego, gdzie jest plik,
# to usuwam te wspolna czesc i powtarzam sprawdzenie
while [ "${WDIR%%/*}" = "${SCIEZKA%%/*}" ]; do
  WDIR="${WDIR#*/}"
  SCIEZKA="${SCIEZKA#*/}"
done

# usuwam wszystkie nie-slashe, potem miedzy nie wstawiam ".."
KATALOG="`echo "$WDIR" | sed 's/[^\/]//g' | sed 's/\//..\//g'`"

# usuwamy plik
rm -f "$1"
# tworze dowiazanie symboliczne pliku do aktualnego polozenia na stara nazwe
# (link mogl sie nazywac inaczej, niz oryginalny plik)
ln -s "$KATALOG$SCIEZKA" "$PWD/$1"
# wypisuje, gdzie i co dowiazalem
echo -n "$1 -> $KATALOG$SCIEZKA"
}

#----------------------------------------------------------------------------#

function przejdz_do_katalogu_linka()
{
# wchodze do katalogu zawierajacego link
cd `dirname "$1"`
# przerabiam link
przerob_link `basename "$1"`
}

#----------------------------------------------------------------------------#

# chce, zeby te funkcje byly widoczne z sub-shelli
export -f przerob_link
export -f przejdz_do_katalogu_linka
export -f zrob_normalna_sciezke

#****************************************************************************#

##############################
#                            #
#    Glowna czesc skryptu    #
#                            #
##############################

#****************************************************************************#

if [ "$1" = "--help" -o "$1" = "-h" -o "$1" = "-?" ]; then
  echo "Skrypt do zamiany linkow symbolicznych z bezwzglednych na wzgledne"
  echo "Uzycie: "`basename "$0"`" [katalog z linkami]" 
  exit 0
fi

# domniemam, ze linki mam przerabiac w aktualnym katalogu
GDZIE_SZUKAMY="."
# oczywiscie moge sie mylic :)
[ $# -gt 0 ] && GDZIE_SZUKAMY="$1"

# no to jazda: szukamy w podanych katalogach pliki typu symlink, na kazdym zas
# wykonujemy wypisanie nazwy pliku, sprawdzenie, czy to link o sciezce
# bezwzglednej i w razie czego sam skrypt. Na koniec wypisanie z zejsciem do
# nowej linii
find $GDZIE_SZUKAMY -type l -exec bash -c "echo -n '{}: '
{ ls -l "{}" | grep -- '-> /' > /dev/null; } && przejdz_do_katalogu_linka {}
echo" \;
