home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
boot
/
i386
/
rescue
/
usr
/
lib
/
rpm
/
brp-symlink
< prev
next >
Wrap
Text File
|
2006-11-29
|
5KB
|
183 lines
#!/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
;;
*,/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