ACC SHELL

Path : /usr/lib/rpm/
File Upload :
Current File : //usr/lib/rpm/brp-symlink

#!/bin/sh

# Task: go through the files in $RPM_BUILD_ROOT and
# relink symbolic links so that:
# links crossing top level directory boundaries (/usr/* -> /etc/*)
#   are absolute links
# links below one top level directory (/usr/bin/* -> /usr/lib/*)
#   are relative links
# NOTE: we're not doing this to fix a problem (as no matter how you
#   do it you fix one problem by creating another). We're doing it
#   so we can document this as policy - so you can rely on it

# Additional Task: check some usual errors arround symlinks e.g.
#   dangling symlinks or symlinks to init scripts in wrong location

# Author: Stephan Kulow <coolo@suse.de>

# If using normal root, avoid changing anything.
if [ -z "$RPM_BUILD_ROOT" ]; then
	exit 0
fi

LC_ALL=
LANG=
LC_TIME=POSIX

BASENAME=/usr/bin/basename
DIRNAME=/usr/bin/dirname
READLINK=/usr/bin/readlink

cd $RPM_BUILD_ROOT

had_errors=0

links=`find . -type l | sed -e "s,^./,/,"`
for link in $links
do
    link_dest=`$READLINK ./$link`
    orig_link_dest=$link_dest

    new_link_dest=NONE
    link_dir=`$DIRNAME $link`

    case $link_dest in
	.|..|../..) # link to current dir
	  continue ;;
	.*) # relative links up
	  link_dest="$link_dir/$link_dest"
	  ;;
        /*) # absolute links
	  ;;
        */*) # relative links down
	  link_dest="$link_dir/$link_dest"
	  ;;
	*) # the rest
	  continue
    esac

    # cleaning out double slash
    link_dest=`echo $link_dest | sed -e 's,//*,/,g; s,/\.$,/,; s,/$,,'`

    # eliminating /./ components
    link_dest=`echo $link_dest | sed -e "s,/\./,/,g"`;

    counter=0
    # eliminating back references
    while echo $link_dest | egrep -q '/\.\.'; do
       link_dest=`echo $link_dest | sed -e "s,/[^/]*/\.\.,,"`;
       case $link_dest in
	/..*) # this is very mean
	    echo "ERROR: $link points to illegal $link_dest"
	    exit 1
	    ;;
	esac
	counter=$((counter + 1))
	if test $counter -gt 10; then
	    echo "ERROR: more than 10 back references in $link?"
	    exit 1
	fi
    done

    # black list
    case "$link,$link_dest" in
	*,/var/lib/named*)
	    continue;;
	/usr/etc,*|/usr/tmp,*)
	    continue;;
	*/share/texmf/*|/usr/share/terminfo/*)
	     continue;;
	*share/automake-*)
	     echo "ERROR: link target $link points into automake directory"
	     echo " You might want to add a -c to the automake call (or just"
	     echo " skip the files from packaging)"
	     exit 1
	     ;;
	*,/opt/kde3/share/doc*/HTML/*/common) # white listed for not existant
	     ;;
	*,/usr/share/doc/kde/HTML/*/common) # white listed for not existant
	     ;;
	*,/proc/*) # links pointing into /proc file system
	     ;;
	*)
	  if test ! -L ./$link_dest && test ! -e $link_dest && test ! -e ./$link_dest; then
	    echo "ERROR: link target doesn't exist (neither in build root nor in installed system):"
	    echo "  $link -> $link_dest"
	    echo "Add the package providing the target to neededforbuild and Requires"
	    test "$NO_BRP_STALE_LINK_ERROR" != "yes" && had_errors=1
	  fi
	  ;;
    esac

    forced_absolute=0
    for prefix in /usr/X11R6/lib/X11 /usr/X11R6/include/X11 /usr/X11R6/lib/X11/app-defaults ; do
      if echo $link | grep -q "^$prefix/"; then
	 if echo $link_dest | grep -q "^$prefix/"; then
	    # if it's below it, it's fine
	    :
         else
	    forced_absolute=1
         fi
      fi
    done

    dest_dir=`$DIRNAME $link_dest`

    # figuring out (currently) correct destination
    if test "$link_dir" = "$dest_dir" || test "$dest_dir" = "."; then
	new_link_dest=`$BASENAME $link_dest`
    else
	# figuring out top level directory
	top_link=`echo $link | sed -e 's,^\(/[^/]*\)/.*,\1,'`
        top_dest=`echo $link_dest | sed -e 's,^\(/[^/]*\)/.*,\1,'`
	if test "$forced_absolute" = 0 && test "$top_link" = "$top_dest"; then # supposed to be relative

	    # first we need to cut out the common prefix
	    link_tmp=$link
	    while test "$top_link" = "$top_dest"; do
		link_orig=$link_tmp
		dest_orig=$link_dest
		link_tmp=`echo $link_tmp | sed -e 's,^\(/[^/]*\)/,/,'`
		link_dest=`echo $link_dest | sed -e 's,^\(/[^/]*\)/,/,'`
		top_link=`echo $link_tmp | sed -e 's,^\(/[^/]*\)/.*,\1,'`
		top_dest=`echo $link_dest | sed -e 's,^\(/[^/]*\)/.*,\1,'`

		if test "$top_dest" = "$dest_orig" || test "$top_link" = "$link_orig"; then
		    link_tmp=$link_orig
		    link_dest=$dest_orig
		    break
		fi
	    done

	    # now we add a .. for every directory component
	    link_tmp=`$DIRNAME $link_tmp`

	    if test "$link_tmp" = "$link_dest"; then
		new_link_dest=.
	    elif test "$link_tmp" != "/"; then # we have a directory component
		link_rel=

		while test -n "$link_tmp"; do
		    link_tmp=`echo $link_tmp | sed -e 's,^\(/[^/]*\),,'`
		    link_rel="../$link_rel"
		done

		new_link_dest=`echo $link_rel/$link_dest | sed -e "s,//*,/,g"`
	    else
		# get rid of the slash
		link_dest=`echo $link_dest | sed -e 's,^/,,'`
		new_link_dest=$link_dest
	    fi
	else
	    new_link_dest=$link_dest
	fi
    fi

    if test "$new_link_dest" != NONE && test "$new_link_dest" != "$orig_link_dest"; then
	echo "INFO: relinking $link -> $new_link_dest (was $orig_link_dest)"
	rm ./$link && ln -s $new_link_dest ./$link
    fi
done

if test "$had_errors" = 1; then
    exit 1
fi

ACC SHELL 2018