File texlive-import of Package texlive-bin

#!/bin/bash
#
# This script imports the texlive system from the same
# server from which /usr/share/texmf is mounted (nfs).
# This script works with bash only.
#
# Copyright (c) 1998,2000 SuSE GmbH Nuernberg, Germany.
# Copyright (c) 2007,2008 SuSE LINUX Products GmbH, Germany.
#
# Please submit bugfixes or comments via http://bugs.opensuse.org/
#
# Author: Werner Fink
#

unset ${!LC_*}
LANG=POSIX
export LANG

test $(id -u) -eq 0 || { echo "Permission denied" 1>&2 ; exit 1; }

#
# The texlive system, main date, variable data, fonts cache,
# and configuration data.
#
texmain=/usr/lib/texmf
texdist=/usr/share/texmf
texvars=/var/lib/texmf
texfont=/var/cache/texmf
texconf=/etc/texmf

#
# Mount options and Internal Field Separator(s)
#
mntopt="exec,nosuid,nodev,hard,bg,intr,rsize=8192,wsize=8192"
action="import"  # otherwise "remove"

#
# Remember the options given to us
#
we="${0##*/}"
tab="$(echo ${we}:| tr '[:print:]' ' ')"
argv="$@"
args=$#

#
# Place holder for the nfs server(s) of the texlive system
#
server=""
mainserv=""
distserv=""
varsserv=""
fontserv=""
confserv=""
etcfstab=""
declare -i num=0

#
# The current system: architecture, operating system, libc
#
  arch="$(uname -i| tr '[:upper:]' '[:lower:]' | sed s/ppc64/ppc/)"
system="$(uname -s| tr '[:upper:]' '[:lower:]')"
binary=${arch/i586/i?86}-${system}
#
# Test the texlive system: Something is already mounted?
#
test_system ()
{
    local IFS OLDIFS
    OLDIFS="$IFS"; IFS=$'\n'
    set -- $(df -P -t nfs)
    IFS="$OLDIFS"
    shift

    local line
    for line ; do
	case "$line" in
	    *:${texmain}*) mainserv=${line%%:*} ;;
	    *:${texdist}*) distserv=${line%%:*} ;;
	    *:${texvars}*) varsserv=${line%%:*} ;;
	    *:${texfont}*) fontserv=${line%%:*} ;;
	    *:${texconf}*) confserv=${line%%:*} ;;
	    *)  ;;
	esac
    done
}

#
# At the first time we may need a mount point,
# just do it.
#
mount_dir ()
{
    local origin=$1
    local mpoint=$2
    local rwro=$3

    test -d $mpoint || mkdir -p $mpoint
    set -- $(mount -v -t nfs -o ${rwro},$mntopt $origin $mpoint)
    set -- $1 $3 $5 ${6#"("}
    if test -n "$1" ; then
	etcfstab="${etcfstab}$(echo $1 $2 $3 ${4%')'} 0 0)\n"
	num=$((num + 1))
    fi
}

#
# Try to mount the system from the server
#
mount_system ()
{
    test_system

    local IFS OLDIFS
    OLDIFS="$IFS"; IFS=$'\n'
    set -- $(showmount -e $server)
    IFS="$OLDIFS"

    for line ; do
    fs=${server}:${line%%\ *}
	case "$line" in
	    *${texmain}\ *) test -z "$mainserv" && mount_dir ${fs} ${texdist} ro ;;
	    *${texdist}\ *) test -z "$distserv" && mount_dir ${fs} ${texmain} ro ;;
	    *${texvars}\ *) test -z "$varsserv" && mount_dir ${fs} ${texvars} ro ;;
	    *${texfont}\ *) test -z "$fontserv" && mount_dir ${fs} ${texfont} rw ;;
	    *${texconf}\ *) test -z "$confserv" && mount_dir ${fs} ${texconf} ro ;;
	    *)  ;;
	esac
    done

    test_system
    test -z "$mainserv" && echo "${we}: Warning, can not mount ${texmain}" 1>&2
    test -z "$distserv" && echo "${we}: Warning, can not mount ${texdist}" 1>&2
    test -z "$varsserv" && echo "${we}: Warning, can not mount ${texvars}" 1>&2
    test -z "$fontserv" && echo "${we}: Warning, can not mount ${texfont}" 1>&2
    test -z "$confserv" && echo "${we}: Warning, can not mount ${texconf}" 1>&2
}

#
# Umount the texlive system
#
umount_system ()
{
    test_system
    test -n "$mainserv" && umount ${texmain}
    test -n "$distserv" && umount ${texdist}
    test -n "$varsserv" && umount ${texvars}
    test -n "$fontserv" && umount ${texfont}
    test -n "$confserv" && umount ${texconf}
}

#
# Do not overlink/remove existing files or foreign links.
#
test_file ()
{
    local tfl=$1
    local tfp=$2
    local i j
    declare -i i=0 j=0

    if test -f $tfl -a ! -L $tfl ; then
	echo "${we}: File $tfl already exists, skipping"  1>&2
	echo "${tab} $tfp"  1>&2
	return 1
    fi
    if test -L $tfl ; then
	i=$(stat -Lc '%i' $tfl)
	j=$(stat -Lc '%i' $tfp)
	if test $i -ne $j ; then
	    echo -e "${we}:\033[1m WARNING symbolic link $tfl does not have the" 1>&2
	    echo -e "${tab} source $tfp\033[m" 1>&2
	    return 1
	fi
    fi
    return 0
}

#
# Integrate the binaries, manual pages, and info descriptions
# into the normal file system hierarchy.
#
linkin ()
{
    local relbin relman relinf lprg prg lman man linf inf
    relbin=$(relpath ${texmain}/bin/$binary /usr/bin)
    for prg in ${texmain}/bin/$binary/* ; do
	lprg=/usr/bin/${prg##*/}
	test -x $prg || continue
	test_file $lprg $prg || continue
	rm -f $lprg
	ln -sf $relbin/${prg##*/} $lprg
    done
    relbin=$(relpath ${texdist}/bin/noarch /usr/bin)
    for prg in ${texmain}/bin/noarch/* ; do
	lprg=/usr/bin/${prg##*/}
	test -x $prg || continue
	test_file $lprg $prg || continue
	rm -f $lprg
	ln -sf $relbin/${prg##*/} $lprg
    done
    relman=$(relpath ${texmain}/doc/man/man1 /usr/share/man/man1)
    for man in ${texmain}/doc/man/man1/*.1* ; do
	lman=/usr/share/man/man1/${man##*/}
	test -f $man || continue
	test_file $lman $man || continue
	rm -f $lman
	ln -sf $relman/${man##*/} $lman
    done
    relinf=$(relpath ${texmain}/doc/info /usr/share/info)
    for inf in ${texmain}/doc/info/*info* ; do
	linf=/usr/share/info/${inf##*/}
	test -f $inf || continue
	test_file $linf $inf || continue
	rm -f $linf
	ln -sf $relinf/${inf##*/} $linf
    done
}

#
# Deintegrate the binaries, manual pages, and info descriptions.
#
linkout ()
{
    local lprg prg lman man linf inf
    for prg in ${texdist}/bin/$binary/* ; do
	lprg=/usr/bin/${prg##*/}
	test -x $prg || continue
	test_file $lprg $prg || continue
	rm -f $lprg
    done
    for prg in ${texmain}/bin/noarch/* ; do
	lprg=/usr/bin/${prg##*/}
	test -x $prg || continue
	test_file $lprg $prg || continue
	rm -f $lprg
    done
    for man in ${texmain}/doc/man/man1/*.1* ; do
	lman=/usr/share/man/man1/${man##*/}
	test -f $man || continue
	test_file $lman $man || continue
	rm -f $lman
    done
    for inf in ${texmain}/doc/info/*info* ; do
	linf=/usr/share/info/${inf##*/}
	test -f $inf || continue
	test_file $linf $inf || continue
	rm -f $linf
    done
}

#
# This calculates the relative path of the source path
# which depends on the destination path. The function
# takes two arguments:
#
#     the full directory path to the source file/dir
#     the full directory path to the destination file/dir
#
# both without the file or directory name its self.
#
# Author: Werner Fink
#

relpath ()
{
    local state=$- ; set +x
    local OLDIFS IFS
    local -a orgwords
    local -a locwords
    local -i relp=0
    local -i deep=0
    local p l
    local path=""

    OLDIFS="$IFS"; IFS=/
    eval orgwords=(${1// /\\\\ }) ; shift
    eval locwords=(${1// /\\\\ }) ; shift
    IFS="$OLDIFS"
    unset OLDIFS

    deep=0
    relp=0
    for l in "${locwords[@]}" ; do
        if test "$l" = ".." ; then
	    ((deep++))
	    continue
	elif test $deep -gt 0 ; then
	    while ((deep-- > 0)) ; do
		unset locwords[$((relp+deep))]
		(((relp-1)-deep < 0)) || unset locwords[$(((relp-1)-deep))]
	    done
	    continue
        fi
	((relp++))
    done
    locwords=(${locwords[@]})

    deep=0
    relp=0
    for p in "${orgwords[@]}" ; do
	if test "$p" = ".." ; then
	    ((deep++))
	    continue
	elif test $deep -gt 0 ; then
	    while ((deep-- > 0)) ; do
		unset orgwords[$((relp+deep))]
		(((relp-1)-deep < 0)) || unset orgwords[$(((relp-1)-deep))]
	    done
	    continue
	fi
	((relp++))
    done
    orgwords=(${orgwords[@]})

    deep=0
    relp=0
    for p in "${orgwords[@]}" ; do
	eval l="\${locwords[$((deep++))]}"
	if test "$l" != "$p" -o $relp -ne 0 ; then
	    ((relp++))
	    path="${path}/$p"
	    test -n "$l" || continue
		if test $relp -eq 1 ; then
		    path="..${path}"
		else
		    path="../${path}"
		fi
	 fi
    done
    unset orgwords p l

    if test $deep -lt ${#locwords[@]} ; then
	relp=0
	while test $relp -lt $deep; do
	    unset locwords[$((relp++))]
	done
	while test ${#locwords[@]} -gt 0  ; do
	    path="../${path}"
	    unset locwords[$((relp++))]
	done
    fi

    echo "$path"
    [[ $state =~ x ]] && set -x
}

#
# Usage
#
usage ()
{
    echo "${we}: Usage:" 1>&2
    echo "${tab} ${we} <NFS server of TeXLive> [-i|-d] -[o <mount options>]" 1>&2
}

#
# Option handling goes here
#
set -- $argv
if [[ "$1" =~ [^-].+ ]] ; then
    server="$1"
    shift
fi
while getopts ":o:m:idh" y ; do
    case "$y" in
    o)	mntopt=$OPTARG ;;
    m)	binary=$OPTARG ;;
    i)	action=import  ;;
    d)	action=remove  ;;
    h)	usage ; exit 0 ;;
    *)	usage ; exit 1 ;;
    esac
done
if test -z "$server" ; then
    eval server=\$\{$OPTIND\}
fi
test -n "${server}"	|| { usage ; exit 1; }
test -n "${binary%%-*}"	|| { usage ; exit 1; }
test -n "${mntopt%%-*}"	|| { usage ; exit 1; }

if    test "$action" = "import" ; then
    mount_system
    linkin
    if test -n "${etcfstab}" ; then
	echo -e "\033[1m${we}: Please add the following $num lines to /etc/fstab\033[m" 1>&2
	echo
        echo -e "${etcfstab}"
	sleep 2
    fi
elif  test "$action" = "remove" ; then
    linkout
    umount_system
    while read line ; do
	set -- $line
	case "$1 $2 $3 $4 $5 $6" in
	    *:${texdist}\ *) etcfstab="${etcfstab}$(echo $line)\n" ;;
	    *:${texmain}\ *) etcfstab="${etcfstab}$(echo $line)\n" ;;
	    *:${texvars}\ *) etcfstab="${etcfstab}$(echo $line)\n" ;;
	    *:${texfont}\ *) etcfstab="${etcfstab}$(echo $line)\n" ;;
	    *:${texconf}\ *) etcfstab="${etcfstab}$(echo $line)\n" ;;
	esac
    done < /etc/fstab
    if test -n "${etcfstab}" ; then
	echo -e "\033[1m${we}: Please remove the following lines from /etc/fstab\033[m" 1>&2
	echo
        echo -e "${etcfstab}"
	sleep 2
    fi
else
    echo "${we}: Ohmm ... something strange happens" 1>&2
    exit 1
fi

##
exit 0
openSUSE Build Service is sponsored by